wangfq
|
e3eaa111fe
|
fix(mqtt): 修复 loop_data>512B 溢出发垃圾包致 broker RST 重连风暴 (现场P0)
根因(非平台推测的环形缓冲/event_report队列):
mqtt_publish 的 mqttBuf=512B < loop_data(4通道)604B
→ MQTTSerialize_publish 返回 -2 不写 buf
→ len 为 uint32_t, -2 变 42.9亿
→ WCHNET 把清零缓冲+越界相邻全局(temp_guide=report_config→report_c)
当 520B 垃圾包发出 → broker 见非法类型0x00 RST → 重连风暴
修复(net_srv.c):
- MAX_MQTTBUF_LEN 512→1024 (容纳 604B loop_data)
- mqtt_publish: len uint32→int + 守卫 if(len<=0)return (序列化失败绝不发残缓冲)
- keepalive 9→60 (报告建议, 9s过激)
event_report 协议违规修复(iot_mqtt_srv.c):
- 重连重发保持原 msg_id/ts (V1.04 §5.3-2), 不再作废换号致平台去重失效
验证: tests/test_mqtt_publish_overflow.c 复现旧垃圾包+验证守卫/大缓冲;
tests/test_event_report.c T8 断言重连同 msg_id. 均全过.
遗留: ts=上电秒数非Unix时间戳, 待定方案(设备无RTC/SNTP)
Refs: docs/incidents/2026-07-15-DC045A49718F-protocol-error.md
|
2026-07-15 14:58:03 +08:00 |
|
wangfq
|
4112b7cbbf
|
feat(iot_mqtt): 实现 event_report 平台必答+设备重发 (协议 V1.04); 时间单位统一 50ms
时间单位:
- 串口协议 V1.06 / TCP JSON 协议: 杂项时间量、事件 value 由 5ms 修正为
50ms, 对齐 Loop 固件 50ms tick 实现 (TMR15 5ms×10)
event_report (iot_mqtt_srv.c + net_srv.c):
- 沿检测双路汇聚: Step1 消费路径 + lup 回调覆盖 uart_srv 路径, 不漏帧
- 16 深环形队列, 事件仅 ACK(code=0) 后出队; 溢出丢最旧
- 5s 超时重发同 msg_id/原始 ts ×3 次, 耗尽挂起, 新事件/重连沿合并补报
- 帧消费提前至 READY/enable 之前: 断网期间事件入队, 重连补报
- 线圈断开期间屏蔽 car 沿; loop_restore value=本地计时/50
- msg_id 独立 uint32 计数 (g_iot_msg_id 为 uint8 混用会破坏去重窗口)
- net_srv.c ACK 路由: cmd=event_report 回显帧确认出队, 不回 unsupported
- gcc 隔离单测 8 组全过 (tests/test_event_report.c), 单包 6 条实测 317B
|
2026-07-15 12:27:22 +08:00 |
|