米米的博客

做了一点微小的工作

中兴 F410GV9 恢复出厂设置后,Web 管理仍然可以正常访问,但 Telnet 会回到关闭状态。临时进入 FactoryMode 虽然能够取得 root shell,却只在当前运行周期内有效;设备重启或 FactoryMode 超时后,临时账号和 Telnet 服务都可能失效。

如果后续需要备份配置、排查服务或研究设备内部数据,更方便的做法是先通过 FactoryMode 开启一次临时 Telnet,再把 LAN 侧 Telnet 配置写入设备数据库。这样重启后可以使用自己设置的账号密码重新登录。

本文记录一次在 F410GV9 上实际验证成功的配置过程。Telnet 只对局域网开放,WAN 侧开关始终保持关闭。操作修改前建议备份现有配置。

环境与准备

本次设备和网络状态如下:

项目实测值
型号F410GV9
管理地址192.168.1.1
Web 管理HTTP 80
FactoryMode 服务HTTP 8080
Telnet 端口TCP 23
初始 Telnet 状态关闭
系统BusyBox 1.17.2
内核Linux 4.1.25,ARMv7
固件构建时间2021-08-19

电脑需要连接到光猫 LAN 侧,并与 192.168.1.1 处于同一网段。可以先确认设备在线,以及 Telnet 尚未开放:

1
2
ping 192.168.1.1
nc -vz 192.168.1.1 23

开启临时 Telnet 使用 zteOnu。准备好 Go 环境后直接使用上游源码即可:

1
2
3
git clone https://github.com/Septrum101/zteOnu.git
cd zteOnu
go test ./...

开启临时 FactoryMode Telnet

F410GV9 的普通 Web 管理位于 80,FactoryMode 接口位于 8080zteOnu 默认端口就是 8080,下面仍显式写出端口,避免把两个服务混淆。

本机实测可用的 FactoryMode 用户名是 factorymode,密码是 nE%jA@5b。这组凭据来自公开项目 zte_modem_tools 内置的默认候选表,并不是设备独有的密码,也不是 Web 管理账号。不同运营商和固件可能使用其他组合。

执行:

1
2
3
4
5
go run . \
--ip 192.168.1.1 \
--port 8080 \
--user factorymode \
--pass 'nE%jA@5b'

握手成功时,工具会依次完成 FactoryMode 复位、随机数交换、认证和模式切换,并返回一组临时 Telnet 凭据:

1
2
3
4
5
6
7
step [0] reset factory: ok
step [1] request factory mode: ok
step [2] send sq: ok
step [3] check login auth: ok
step [4] enter factory mode: ok
user: <TEMP_USER>
pass: <TEMP_PASSWORD>

输出中的 <TEMP_USER><TEMP_PASSWORD> 由设备为本次 FactoryMode 会话动态生成,每次运行都可能不同。这组账号也不是准备写入数据库的持久账号。FactoryMode 可能在数分钟后超时,拿到凭据后应尽快继续。

使用临时账号连接光猫:

1
telnet 192.168.1.1 23

成功后会看到设备型号和 BusyBox shell。先用只读命令确认权限:

1
2
id
uname -a

实测结果为:

1
2
uid=0(root) gid=0(root)
Linux F410GV9 4.1.25 #1 Thu Aug 19 13:16:08 CST 2021 armv7l GNU/Linux
阅读全文 »

家里的电信光猫使用路由模式,由光猫完成 PPPoE 拨号,下游再连接自己的路由器。这样的配置方式 IPv4 使用起来没什么问题,IPv6 也可以拿到地址,但是实际使用时却发现了一个问题:光猫已经从电信获得了一个/60 IPv6 前缀,直连光猫的设备也有 IPv6,但下游 OpenWrt 只能在 WAN 口获得一个/64地址,LAN 侧始终没有公网 IPv6 前缀。换句话说,光猫默认没有启用下游 IPv6 PD 前缀分发。这对于 Tailscale 之类需要打洞的场景不友好:OpenWrt 的 LAN 侧只能使用 ULA、NAT66 或 IPv6 Relay,也失去了利用原生 IPv6 进行 Tailscale 直连的条件。

把光猫改成桥接、由主路由拨号当然可以解决 IPv6 前缀分配问题,但 XG-140G-TF 本身的转发性能足够,而主路由是软路由,PPPoE 本身也非常吃单核性能,所以我还是希望保留光猫拨号。进一步检查后发现,XG-140G-TF 的固件中其实包含下游 DHCPv6-PD Server,只是电信配置默认没有开启对应的产品级开关。

本文记录如何在保留光猫拨号的情况下,开启 XG-140G-TF 的 IPv6 PD 前缀分发。光猫的管理员登录、Telnet 开启和 root 密码获取方法,请先参考配置 XG-140G-TF 光猫

问题现象

光猫的 IPv6 状态显示,WAN 连接已经通过 Prefix Delegation 从电信取得了/60前缀,例如:

1
2001:db8:1234:690::/60

一个/60可以划分为 16 个/64子网。在这个例子中,范围是:

1
2
3
4
2001:db8:1234:690::/64
2001:db8:1234:691::/64
……
2001:db8:1234:69f::/64

光猫使用第一个690::/64作为自己的 LAN 网段,通过 RA 广播给直连设备。但在修改前,下游 OpenWrt 的 WAN6 状态只有一个地址:

1
2001:db8:1234:690:6c59:4eff:fecb:61f4/64

容易产生误解的是,这只是 OpenWrt WAN 接口通过 SLAAC 获得的一个 IPv6 地址,并不是可供 OpenWrt 继续划分给 LAN 的前缀。检查 WAN6 状态时可以看到:

1
"ipv6-prefix": []

由于没有获得 IA_PD,OpenWrt 的 LAN 只能继续使用 ULA 地址,日志中还会出现:

1
A default route is present but there is no public prefix on lan
阅读全文 »

家里开通了电信 IPTV,但套餐只包含了一台机顶盒,家中有多台电视时使用起来并不方便。很早以前我就知道可以通过 igmpproxy 转发组播,再配合 udpxy 将组播转换为普通 HTTP 单播,但此前一直没有配置成功。

最近重新梳理了一遍光猫、机顶盒和组播之间的关系,终于实现了以下目标:

  • 原装 IPTV 机顶盒继续正常使用,直播和点播均不受影响;
  • 局域网中的其他设备(电视、电脑、手机等)可以收看直播。

本文记录的是我在湖北武汉电信网络中的实际配置。不同地区的 VLAN 和认证方式都可能不同,请不要直接照抄参数。修改光猫前,建议先备份配置,并记录每一处原始设置。

原始网络结构

光猫中原本有两项主要业务:

  1. 上网业务,采用路由模式,本文不讨论;
  2. iTV 业务,采用桥接模式,仅绑定到光猫的 LAN2 口。

iTV 桥接连接的关键参数如下:

项目原始设置
业务类型OTHER
连接模式桥接
IP 模式IPv4
业务 VLAN ID3542
端口绑定LAN2(iTV 口)

在这一结构下,电信机顶盒连接 LAN2,并由机顶盒自己进行 PPPoE 拨号。机顶盒的网络设置中可以看到 IPTV 账号,但密码通常不会直接显示。

这里有一个容易踩的坑:IPTV 密码可能由机房或装维系统下发。即使通过 10000 客服重置或查询到了一个密码,也不一定能在现网环境中成功拨号。如果确认账号无误但始终认证失败,最好直接联系当地装维人员,获取当前线路实际使用的 IPTV 密码。

失败的尝试:让两个设备分别拨号

我最初的思路很直接:在光猫的 iTV 桥接连接中,除 LAN2 外再绑定一个 LAN3,让原装机顶盒连接 LAN2,另一个路由器或小主机连接 LAN3。两台设备分别使用同一组 IPTV 账号、密码拨号,小主机负责运行 igmpproxy,就可以实现局域网组播。

实际测试发现,这种方式行不通:只要其中一台设备已经拨号成功,第二台设备的拨号就会被拒绝。至少在我的线路上,同一个 IPTV 账号无法同时建立两个 PPPoE 会话。这意味着如果光猫桥接,让下游设备拨号,原装机顶盒和独立组播代理只能二选一。

关键调整:改由光猫拨号

进一步查看机顶盒设置时,我发现它除了 PPPoE,还支持 DHCP 联网。由此可以换一种思路:

不再让机顶盒直接拨号,而是让光猫建立 IPTV PPPoE 连接,再通过 DHCP 给 LAN2、LAN3 下游设备分配地址。

我将光猫中的 iTV 连接从桥接模式改为路由模式,填写 IPTV PPPoE 账号和密码,并同时绑定 LAN2、LAN3。

修改后,光猫成功获得了运营商 IPTV 网络中的 10.x.x.x 地址,机顶盒改为 DHCP 后也能取得光猫下发的局域网地址。

此时测试结果如下:

  • IPTV 平台登录正常;
  • 菜单和业务页面正常;
  • 点播节目可以播放;
  • 直播频道仍然黑屏

这个现象很有价值。它说明 PPPoE 认证、DHCP 和普通 IP 通信已经正常,机顶盒也没有被限制为必须自行拨号;但直播所需的组播链路尚未打通。点播通常走普通单播,而直播依赖 IGMP 和运营商的组播 VLAN,因此两者完全可能出现一个正常、另一个黑屏的情况。

阅读全文 »

过去几年里,大模型把语音助手的想象空间重新打开了。我们已经习惯了在手机、网页和电脑上和 AI 对话,但家里的智能音箱却常常还停留在比较固定的指令式体验里:问天气、放音乐、控制设备可以,但想要更自然的连续对话、更灵活的工具调用,或者接入自己选择的大模型服务,就没那么顺手了。

xiaoai-agent 想解决的正是这个问题:让小爱音箱不只是一个云端语音入口,而是变成一台可以常驻运行的端侧语音 Agent 设备。

项目地址:github.com/stevenjoezhang/xiaoai-agent

背景:小爱音箱还有很多潜力

小爱音箱本身是一类很适合承载语音 Agent 的设备。它有麦克风阵列,有扬声器,有唤醒能力,也有成熟的音频播放和 TTS 链路。换句话说,它的硬件形态已经非常接近「家里的 AI 入口」。

但现实使用中会遇到几个限制:

  • 原生小爱同学的对话能力和可扩展性有限,很难按自己的偏好接入新的大模型、ASR 或工具。
  • 一些改造方案需要额外部署服务器或桥接服务,链路变长,维护成本也会变高。
  • 原生小爱同学仍然可能监听麦克风,出现抢麦、抢答,甚至触发小米云端控制的情况。
  • 音频体验很难做好,比如唤醒、录音、回声消除、连续对话、中途打断等细节,任何一个环节不稳都会影响日常可用性。

xiaoai-agent 的方向,是尽量把这些能力收回到音箱端侧,让音箱自己完成唤醒、录音、识别、思考、工具调用和回复。

现有方案与不足

xiaoai-agent 之前,已经有不少项目尝试把小爱音箱和大模型连接起来。这些探索证明了小爱音箱的可玩性,也把很多底层路径跑通了。

比如原生小爱同学提供了稳定的唤醒、TTS、设备控制和生态接入能力,适合普通用户日常使用。但它的对话能力、模型选择和工具扩展都比较固定,用户很难把自己的 ASR、大模型或智能家居工作流接进去。

Open-XiaoAI 这类项目则打开了更底层的设备改造路径,让音箱具备 SSH、启动脚本和自定义部署的可能。它解决的是「能不能进入设备、能不能运行自己的东西」的问题,为后续折腾提供了基础。

MiGPT 等桥接类方案则更进一步,把大模型对话接入到小爱音箱体验里,让用户可以用自然语言和 AI 聊天。这类方案的优势是思路清晰、上手相对友好,但通常需要额外服务端或桥接层来承载 Agent 逻辑,音箱本身更像前端入口。

这些方案各有价值,但也留下了一些共同痛点:语音链路复杂、部署组件偏多、原生小爱可能抢麦或抢答、云端控制可能被误触发,音频细节也容易受多层转发影响。xiaoai-agent 正是在这些探索之上,尝试把 Agent 主流程进一步收回到音箱端侧。

它解决了什么痛点

xiaoai-agent 最核心的价值,是把小爱音箱改造成一个更开放、更可控的语音 Agent 载体。

首先,它避免了「两个助手同时工作」的混乱。项目会让原生小爱同学的麦克风输入静音,由 xiaoai-agent 接管真实麦克风音频。这样可以减少抢麦、抢答,以及误触发小米云端控制的问题。

其次,它降低了长期运行的复杂度。传统方案常常需要在局域网里额外跑一个服务,音箱和服务之间再做消息转发。xiaoai-agent 选择直接在音箱端侧运行 Agent,部署链路更短,也更像一台独立设备。

第三,它复用了音箱原本已经做好的音频能力。唤醒、VPM 音频回调、TTS 播报、播放控制等能力都来自设备原生系统,日常交互会更接近「真正的音箱体验」,而不是把音箱当作一个简单的外设。

最后,它给用户留下了足够多的选择空间。ASR 可以使用兼容 OpenAI POST /v1/audio/transcriptions 的服务,大模型也可以接入 OpenAI-compatible API。你可以按自己的预算、延迟和隐私偏好选择服务,而不是被固定在单一路径里。

主要特性

xiaoai-agent 是一个非官方技术研究项目,核心 Agent 使用 Rust 编写,运行在小爱音箱端侧。目前项目已经在 Xiaomi 智能音箱 Pro(OH2P)固件 1.62.2 上测试成功。

它目前已经具备一套完整的语音 Agent 闭环:

  • 端侧常驻运行:Agent 直接运行在音箱上,不需要额外部署专门服务端。
  • 完整语音流程:支持唤醒、录音、ASR、大模型对话、工具调用和 TTS 回复。
  • 更自然的交互:支持连续对话、VAD、中途打断、回声消除和播放时录音。
  • 开放模型接入:ASR 和 LLM 均可配置为兼容 OpenAI API 的服务。
  • 工具与设备控制:内置时间、天气、音乐播放等工具,并可通过 Home Assistant MCP 控制智能家居。
  • 保留部分系统能力:语音对话由 Agent 接管,但蓝牙网关等非语音服务不应受到影响。
  • 可自定义体验:可以调整唤醒响应、LED 状态、音乐服务和运行参数。

项目仓库中也包含补丁固件制作、刷机辅助、示例配置和部署说明,方便用户从设备准备一路走到 Agent 常驻运行。需要特别说明的是,它不是官方项目,也不是面向所有型号的一键通用方案;现阶段更适合愿意折腾、理解刷机风险,并且手上有对应设备的用户尝试。

这套能力组合起来,小爱音箱就不再只是一个固定功能的智能音箱,而更像是家里可以听、可以说、可以调用工具的 AI 节点。

阅读全文 »

背景

笔者很久以前在 Mac 上通过 Boot Camp 安装了 Windows 系统,最近计划将这个系统迁移到 ESXi 虚拟机中使用。笔者首先使用同一机器上 macOS 系统安装的 VMware Fusion 来将 Boot Camp 的 Windows 转化为虚拟机,这一步转化是成功的,虚拟机可以启动。但是进一步导出 OVF 模板并在 ESXi 上导入时,结果发现虚拟机无法启动。经过分析,发现问题的根源在于磁盘扇区大小不匹配。

Mac 上通过 Boot Camp 安装的 Windows,磁盘默认使用 4Kn(4K Native) 扇区格式——物理扇区和逻辑扇区均为 4096 字节。这种格式的磁盘在正常使用时是无感的,但是在需要迁移系统到其他磁盘(比如转成 ESXi 虚拟机)时,就会碰到麻烦:大多数虚拟化平台的虚拟磁盘只支持 512 字节扇区(512n 或 512e)。

这个问题其实并不好解决。扇区大小不匹配,那么直接克隆必然失败,很多常见的硬盘分区、数据恢复工具,包括声称支持不同扇区大小之间的克隆转换的 Clonezilla,都无法解决这个问题。

真正可行的方案:DISM

经过测试,微软自带的 DISM(Deployment Image Servicing and Management) 工具可以完美解决这个问题。

原因很简单——DISM 的工作方式是文件级别的:

  • 备份时:把系统分区的所有文件打包成一个 .wim 镜像
  • 还原时:把 .wim 镜像中的文件逐个释放到目标分区

整个过程完全不涉及扇区结构。它不关心源盘是 4Kn 还是 512,也不关心目标盘是什么格式。扇区大小的差异在文件级操作面前根本不是问题。

大致流程:

  1. 在 WinPE 环境下,用 DISM 将 Boot Camp 的 Windows 系统捕获为 .wim 文件
  2. 在虚拟机中创建一个 512 扇区的虚拟磁盘,手动建好 ESP 分区和系统分区
  3. 用 DISM 将 .wim 释放到虚拟磁盘的系统分区
  4. 写入引导,完成

Dism++ 同样可以

如果你不喜欢敲命令行,Dism++ 是 DISM 的图形化前端,底层调用的是同样的 API,同样是文件级操作。用它来备份和还原效果完全一样,只是操作更直观。

唯一需要注意的是:无论用 DISM 还是 Dism++,都需要你事先在目标磁盘上手动建好分区(包括 ESP 分区),它们只负责释放文件和写入引导,不会自动帮你分区。

小结

在 4Kn 到 512 的系统迁移场景下,凡是涉及扇区级操作的工具都可能翻车。而 DISM / Dism++ 因为是纯文件级的备份还原,天然绕过了扇区大小的问题,是目前最简单可靠的方案。

0%