Files
story/docs/device-ota-recovery-20260922.md
T

40 lines
3.6 KiB
Markdown
Raw Normal View History

# COM6 OTA 故障恢复与当前验收状态
## 当前交付
后续连接状态及命令回执修复已将 COM6 更新至 `1.7.0-controls.8`,保留本文 OTA 修复;最新烧录、诊断和主动重启离线/重连证据见 [COM6 总记录](com6-controls-progress-20260922.md)。下述 controls.6 为此次 OTA 修复的首次交付及语音回归记录。
2026-09-22,COM6 已通过 USB 更新活动应用槽至 `1.7.0-controls.6`。应用大小 3,753,536 字节,SHA256 为 `25f2b93354b6f30492ab68a5c179359601da4cc4710852397366b699e772a0a9`。
更新前核对设备 MAC、云端绑定数 1、无活动通话/升级,以及 OTA 数据指向已确认的 `ota_0`(0x10000)。只写该应用槽,esptool 校验成功;未修改 NVS、出厂身份、分区表或 OTA 数据。记录位于本机受限证据目录 `.local-evidence/com6-controls-20260922/flash-controls6.json`。
这次 USB 更新不构成在线 OTA、实际 A/B 切换或 bootloader 回滚验收。
## 修复
- 安装版本元数据按 OTA 槽分别保存,保留旧版单槽记录兼容回退。候选固件确认失败时,旧固件的版本号不会被新版本记录覆盖。
- 新固件健康检查计时器创建或启动失败时,立即请求回退;不再忽略失败并留下未确认固件。
- 版本号、大小和时间戳在浮点转整数前检查有限、非负、整数及 JSON 安全整数范围,拒绝溢出或小数输入。
- 无记录与记录损坏/读取失败分别处理。升级日志或安装版本记录无法可靠读取时,不开放 OTA;待确认固件的健康超时保护仍保留。
## 自动验证
`tests/device-ota-host.cjs` 把生产 `main/device_ota.c`、ESP-IDF cJSON 和 `tests/device-ota-host.c` 组合为独立 C 程序。SHA256 使用真实 OpenSSL 实现;ESP 分区、HTTP、NVS、计时器和重启使用故障注入替身。
最终源码在 GCC 的 AddressSanitizer、UndefinedBehaviorSanitizer 和 float-cast-overflow 检查下运行全部场景,返回 `PASS production OTA: all`、退出码 0。覆盖正常下载/启动确认、重复任务、型号/版本/大小/有效期校验、下载摘要错误、重定向和截断、写入中断、启动确认失败、两槽交替升级后的版本恢复、计时器故障及记录损坏。ESP-IDF 5.5.1 实际固件编译通过。
故障注入证明生产 C 状态机在所列替身条件下的行为,不证明真实断电、Flash 硬件故障或 bootloader 回退。
## 更新后实机检查
- `voice-20260922T034336Z.log`:固定测试语句产生持续下行 PCM 和播放器写入,观察到的解码/写入错误为 0,结束通话收到 `chat end acknowledged=1`。未采集聊天文本。
- 通话中串口显示 `mqtt=1 speaker=60 revision=12 ota=1`;socket 使用 10/16,RTC 任务存在。
- 03:43:56 UTC 云端上报为 `1.7.0-controls.6`,绑定数 1,期望/实际音量均 60,期望/实际配置版本均 12,MQTT 已连接,未完成命令 0。
- 平台固件版本代码仍为 0,符合当前仅经 USB 烧录、尚未完成正式 OTA 的状态。
## 剩余验收
需要通过已登录、有管理权限的家属端发起真实 OTA,并观察下载、槽切换、启动确认和平台成功回执;失败回滚另需受控实物验收。不得通过创建登录令牌、放开 MQTT 权限或空实现 Publish 来替代原操作路径。
蓝牙添加、重新配网、更换老人、解绑后恢复出厂及重新绑定仍需现场设备确认。恢复出厂清除真实 Wi-Fi 和用户设置,尚未得到本次清除测试的答复,因此没有执行。小程序正式发布及真机页面操作、扬声器听感和麦克风收音也仍待完成。