文件
phonerail/firmware/HANDOFF.md
T
zhou yang和Claude Opus 5.5 a32fa06c43 固件:A12 命令处理器 + A13 USB 分帧 + A14 WiFi/MQTT(含 C1 配网)
- A12 单一命令处理器(cmd*.c):一行 JSON 进出、seq 全局判重(32 条按值)、
  限幅 / 空槽一律拒 / 拒绝记事件;命令号与错误码冻结(进 flash)。新增 power 命令,
  fan 改为只抬不压的下限(t_thermal_set_floor)。rail_set_mv 注明不拿锁,调用方包 xact。
- A13 USB-Serial-JTAG 分帧(ulink*.c):@C / @R 前缀 + CRC-16,日志行首 @ 垫空格,
  任意切块可切;关掉 USB 副控制台(它绕开驱动写 FIFO)。PC 端客户端 tools/prlink.py。
- A14 + C1(netcfg / mlink / cmd_net):topic phonerail/<mac>/{cmd,rsp,tele,state},
  mqtts(evse-ca 编进固件)、1 s 遥测、遗嘱离线;wifi / mqtt 配置只收 USB、存 NVS,
  net 永不回显密码。
- 协议定稿写进需求文档 §10.8(A12 / A13 / A14 三节);N7 撤销改 D7(机架管理前后端)。

宿主机 23 个 ctest / 400 例全绿;板 B 已烧 0.1.0-a14,经 WiFi → 公网 → 8883 TLS 真连网验过。
固件 0xE2220 / 1 MB 分区只剩 12%,C2 前要重排分区表。

Co-Authored-By: Claude Opus 5.5 <[email protected]>
2026-09-27 12:33:18 +08:00

3.8 KiB
原始文件 Blame 文件历史

交接

更新:2026-09-27 完成 A14 + C1(WiFi/MQTT 链路 + 经 USB 配网,需求 §10.8「A14 定稿的 MQTT 链路」)

一句话现状

板 B(b81f3fc9c8bc)经 WiFi CANBOX-5G → 公网 → home 服务器 mosquitto 8883(TLS)真连网跑通: retained state、1 s 遥测、命令 / 判重 / link / empty / parse 回应全对。两条链路(USB + MQTT)都已上板。 23 个 ctest、400 个用例全绿,idf.py build 通过(0xE2220,分区只剩 12%)。板 B 烧的是 0.1.0-a14,配置已存 NVS。

下一步

固件还欠 A15(启动顺序 + 降级矩阵)/ A16(风扇闭环接进 t_thermal 任务体)。 或者转服务器侧前后端(需求 D7):后端以 phonerail-backend 订阅 phonerail/+/rsp|tele|state,经 <base>/cmd 下发。

本次新增/修改的文件

  • main/netcfg.{h,c} 新 — 配置校验 / 持有 / 存储回调;网络状态;「密码永不外泄」
  • main/mlink.{h,c} 新 — topic、入站消息校验、WiFi 退避、遥测节拍、上线消息
  • main/cmd_net.c 新 — wifi / mqtt(只收 USB)/ net 三条命令;新增错误码 link(11)、命令号 10~12(冻结)
  • main/mlink_esp.{h,c} 新(只进 IDF)— NVS、WiFi STA、esp-mqtt(TLS,enqueue 不阻塞)、遥测
  • main/certs/evse_ca.pem 新 — 服务器 mosquitto 的自签 CA(公钥证书),EMBED_TXTFILES
  • main/cmd_json.h — 字符串上限 32 → 65(WPA2 口令 63)
  • main/app_main.c / CMakeLists.txt — 接线;REQUIRES 加 wifi / netif / event / timer / nvs / mqtt
  • test/test_net.c(10 例)新;test_cmd.c 冻结编号更新;版本号 0.1.0-a14

服务器上改了什么(home 服务器,mosquitto 1.6.9,evse 项目共用)

  • evse.passwd 加用户 b81f3fc9c8bc、phonerail-backend;evse.acl 末尾追加 phonerail 段(pattern … phonerail/%u/…)。
  • ⛔ 修了 evse 原有的漏洞:8883 listener 缺 cafile ⇒ TLS 根本没生效、公网明文。补 cafile /etc/mosquitto/certs/ca.crt 后重启; 改前 8883 上零成功连接(日志自 09-24 起),evse-backend 走本机 1884,重启后 5 s 自动重连。
  • 三个文件都有 .bak-20260927-* 备份。口令在 /root/phonerail/mqtt.env(700 目录,仅 root)。

验收命令与结果

$ bash host/test.sh                      # 100% tests passed, 0 tests failed out of 23(400 例)
$ python tools/prlink.py COM5 net        # "wifi":"up","ip":"192.168.8.108","mqtt":"up"
服务器:mosquitto_sub -h 127.0.0.1 -p 1884 -u phonerail-backend … -t 'phonerail/#' -v

注错验证过:放开「只收 USB」、去掉 JSON 字符串清洗 → 各自有用例变红。

踩到的坑(只写会再犯的)

  • ⛔ openssl s_client … | grep "Verify return code" 不能证明 TLS 通了:握手失败、没拿到证书时它也打 0 (ok)。要看 Cipher is / Protocol。
  • ⛔ mosquitto 1.6:listener 只有 certfile/keyfile、没有 cafile/capath ⇒ 静默退化成明文。TLS 选项改动要 restart,HUP 不生效。
  • esp-tls 的「Certificate verified.」在握手失败时也会打,别被它带偏;服务器抓包(tcpdump 看 RST 时机)最快。
  • 服务器 pid 文件不在 /var/run/mosquitto.pid,HUP 用 pgrep -x mosquitto。mosquitto_passwd -b(1.6.9)会把文件内容打到终端,不是出错。
  • 本机(192.168.8.x)与服务器(10.5.5.x)不同网段,板子只能走公网 home.example:8883;明文 mqtt:// 只许用在同一局域网。
  • 固件 0xE2220 / 1 MB:WiFi + MQTT + TLS ≈ 600 KB。C2(OTA 双分区)前必须重排分区表(模组是 16 MB,sdkconfig 只按 8 MB 用)。
  • WiFi 断开原因码 3(AUTH_LEAVE)是重配网时我们主动断的,不是故障;201 = 找不到 AP(比如只有 5 GHz)。