feat(vd960Air): 配置同步改用 0x8F 本机侧私有帧;MQTT 凭据外置到非跟踪文件

- readme §2.2/§3:0x7D 帧设计稿 v0.2 作废,改写为「0x7F 业务帧字节流 + 0x8F 本机侧私有帧」
  (权威源规则 / 拉取为主+推送为辅 / 帧长上限 260B / 两侧缓冲需同步扩容),依据协议 §6.9
- readme §3.1:对比表由 0x7D 改为 0x8F,保留 0x7F 帧布局参考
- config.lua / uart_app.lua:注释中的 0x7D 计划改为 0x8F 配置同步;协议版本引用 V1.13 → V1.14
- config.lua:MQTT 账号密码不再明文入库,改从 cred.lua 读取;缺失时降级为空串(匿名连接)
- 新增 .gitignore(忽略 cred.lua)+ cred.lua.example(填写模板)
  ⚠ 原明文凭据已存在于 git 历史,商用前必须更换服务器密码
- 语法:luac5.3 -p config.lua / cred.lua / uart_app.lua 全部通过
This commit is contained in:
wangfq
2026-09-10 21:46:02 +08:00
parent 2f75f5abff
commit 28418dab66
5 changed files with 79 additions and 38 deletions
@@ -0,0 +1,2 @@
# 敏感凭据(不入库) —— 见 cred.lua.example
cred.lua
@@ -6,19 +6,29 @@
vd960Air 是 Air8781P 整板(Air780EPM 核心模组)上的 LuatOS 应用,
作为 vd960DBN 车检器在有线网络失效时的 4G 兜底通道(方案 C: Air780 协议转换)。
协议依据:《DLD960_IoT_MQTT协议》V1.13(4G 通道适配方案 C,标准 JSON 命令面)
协议依据:《DLD960_IoT_MQTT协议》V1.14(4G 通道适配方案 C,标准 JSON 命令面)
]]
-- ==================== MQTT 服务器 ====================
-- 测试服务器(2026-09-10 用户提供): 110.41.131.144:1883, admin/password
-- 注: 后续 vd960DBN 更新版本后,经 BLE 设置的服务器参数会同步下发覆盖此处(配置同步, P1)
-- ⚠ 商用环境须替换为平台实际地址; 密码不应长期写死在代码里(应走 §2.2 配置同步链路)
CFG_MQTT_HOST = "110.41.131.144"
CFG_MQTT_PORT = 1883
-- 测试服务器(2026-09-10 用户提供): host/port 见下(出厂默认值)
-- 注: 后续 vd960DBN 更新版本后,经 BLE 设置的服务器参数会同步下发覆盖此处(配置同步, 协议 §6.9)
-- ⚠ 商用环境须替换为平台实际地址
--
-- 敏感凭据从非跟踪文件 cred.lua 读取(不入版本库; 模板见 cred.lua.example)
-- 缺失时为空串 -> 匿名连接(不崩, 仅 broker 侧鉴权失败后按重连逻辑重试)
-- ⚠ 2026-09-10 之前凭据曾明文写在 config.lua 并已入库(git 历史), 商用前必须更换服务器密码
local _cred_ok, _cred = pcall(require, "cred")
if not _cred_ok or type(_cred) ~= "table" then
_cred = {}
if log then log.warn("config", "cred.lua 缺失或非法 -> 凭据为空(匿名), 请复制 cred.lua.example") end
end
CFG_MQTT_HOST = _cred.mqtt_host or "110.41.131.144"
CFG_MQTT_PORT = _cred.mqtt_port or 1883
-- MQTT 鉴权(mqtt_main 调用 mqtt_client:auth; 空串表示匿名)
CFG_MQTT_USER = "admin"
CFG_MQTT_PASS = "password"
CFG_MQTT_USER = _cred.mqtt_user or ""
CFG_MQTT_PASS = _cred.mqtt_pass or ""
-- ==================== 设备标识 ====================
-- 设备序列码: 6 字节十六进制字符串(与 vd960DBN dev_serial 一致,有线/4G 同一设备)
@@ -45,7 +55,7 @@ CFG_UART_ID = 1
CFG_UART_BAUD = 115200
-- 链路帧: 0x7F 帧字节流(方案 C,数据面透传 Loop 地感协议)
-- 0x7D 帧仅用于 DBN↔Air780 配置同步/握手(P1)
-- 0x8F 本机侧私有帧用于 DBN↔Air780 配置同步(拉取+推送,协议 §6.9)(P1)
-- ==================== 上报节奏 ====================
CFG_HEARTBEAT_INTERVAL = 60 -- 心跳周期(秒,协议 §5.4 默认 60)
@@ -0,0 +1,12 @@
--[[
@module cred
@summary vd960Air 敏感凭据模板 —— 复制为同目录 cred.lua 并填写实际值
@usage cp cred.lua.example cred.lua && 编辑 cred.lua
]]--
-- ⚠ cred.lua 已列入 .gitignore, 不会入库。切勿把真实凭据写回 config.lua 或任何跟踪文件。
return {
mqtt_host = "MQTT_服务器_IP或域名",
mqtt_port = 1883,
mqtt_user = "MQTT_用户名",
mqtt_pass = "MQTT_密码",
}
@@ -53,7 +53,7 @@
**已定稿(用户决策 2026-08-31):**
-**方案 B(原始帧透传)正式采用**
-**4G 上报格式 = hex 封装**(平台友好,参照 log_query records hex 风格)
-**0x7D 帧去留**: 数据面走 0x7F 帧字节流透传(不需要 0x7D);0x7D 帧仅保留给"配置同步下发/握手"
-**0x7D 帧作废(2026-09-10 用户决策)**: 数据面走 0x7F 帧字节流透传;配置同步改用 **0x8F 本机侧私有帧**(与 BLE 同魔数,两端各自本地消费、不转发,见 §2.2)
**待确认(影响定稿):**
- [ ] 上行双通道策略: 默认 4G / 有线失效才走 4G / 双通道并存(呼应 §6 通道切换讨论)
@@ -95,7 +95,7 @@
1. 新增上行 `frame_report` + 下行 `frame_cmd` 两个命令(4G 通道专用)
2. **平台双通道格式差异说明**: 有线通道 = 标准 JSON 业务命令(loop_data/event_report);4G 通道 = frame_report/frame_cmd(hex 帧透传)——平台须按通道区分解析
3. 4G 通道网络配置类命令不适用(ssc_net_* / iot_net_* / iot_topic_*,返回 code=4 或文档标注)
4. 链路层: 数据面 0x7F 帧字节流;0x7D 帧仅 DBN↔Air780 配置同步/握手(§2.2)
4. 链路层: 数据面 0x7F 帧字节流;**0x8F 本机侧私有帧**用于 DBN↔Air780 配置同步(§2.2)
5. 平台侧新增《DLD960Loop_串口通信协议》解析依赖(hex → 帧)
**与方案 A(JSON 桥)对比:**
@@ -106,19 +106,28 @@
| Air780 侧职责 | MQTT 壳 + JSON 透传 | 0x7F 帧切包 + MQTT + 封装 |
| 平台侧 | 收标准 JSON(与有线一致) | 收 0x7F 帧/hex 封装(需解析《DLD960Loop_串口通信协议》) |
| 地感指令下行 | 经 JSON 命令中转 | **原样透传,零改造** |
| 链路帧 | 0x7D 帧(2B LEN 装 JSON) | 0x7F 帧字节流(不需要 0x7D,或仅配置用) |
| 链路帧 | 0x7D 帧(2B LEN 装 JSON) **已作废** | 0x7F 帧字节流 + 0x8F 配置同步帧(§3) |
### 2.2 服务器参数配置链路(用户决策 2026-08-31,列入 vd960DBN 开发计划)
**服务器参数(地址/端口/ClientID/账号密码/Topic)当前由小程序 BLE 蓝牙设置** 规划:
**服务器参数(地址/端口/ClientID/账号密码/Topic)由小程序 BLE 蓝牙设置,经 UART1 同步到 Air780。**(2026-09-10 定稿)
```
小程序 → BLE → vd960DBN(CH32V208) → UART1(0x7D 帧) → Air780 存储(LuatOS fskv/luadb)
小程序 → BLE → vd960DBN(CH32V208) → UART1(0x8F 本机侧私有帧) → Air780 fskv 缓存
```
- **vd960DBN 更新版本(列入计划)**: 小程序设置服务器/topic 相关参数(BLE 0x13/0x15 等)时,同步经 UART1 组帧下发 Air780
- **Air780 侧**: 新增"配置下发"UART 命令处理——收到后更新本地配置存储;`config.lua` 值降级为**出厂默认**(运行时优先读存储)
- 协议面: 在《DLD960_IoT_MQTT协议》4G 适配章节新增"配置同步下发"命令(方向 srv 语义,经 DBN 透传或 DBN 主动下发)
**权威源规则**: 配置权威源 = **DBN 侧 flash**(`IOT_NET_INFO`/`IOT_Topic`)。Air780 的 fskv **仅作启动缓存**,
唯一合法写入者 = **收到的 DBN 配置帧**;平台经 4G 下发配置一律拒绝(《DLD960_IoT_MQTT协议》§6.6 回 `code=4`)。
- **vd960DBN 侧**: BLE 写 `0x13`(SET_IOT_NET)/`0x15`(SET_IOT_TOPIC)/`0x09`(UPDATE_DEV_SERIAL) 成功后,
① 应答 Air780 的配置请求(拉取);② 链路可用时主动推送。命令复用 `0x14`(GET_IOT_NET)/`0x16`(GET_IOT_TOPIC),
载荷复用 `set_response_iot_net/topic()` 构造器 → **与 BLE 读响应逐字节同源**(零新增序列化)
- **Air780 侧**: `config.lua` 值降级为**出厂默认**;上电先读 fskv 缓存立即连接,再拉权威值校准;
配置变化 → 断开重连重订阅。`frame_parser.lua``0x8F` 分支(本地消费,不转发);
配置读取从 require 期 `local` 改为**重连时重读**;fskv **仅在值变化时写入**(littlefs 擦写磨损)
- **DBN 不维护"待同步"标志位**: 推送时链路不可用则等 Air780 下次拉取(无状态,天然自愈)
- **帧长上限**: `0x8F` 独立上限 **260B**(LEN 1B ≤255);`0x7F` 业务帧维持 70B —— **两侧帧缓冲需同步扩容**
- 协议面: 《DLD960_IoT_MQTT协议》**§6.9 4G 配置同步**
- 好处: 现场换 4G 模块/重新配对时,参数随 BLE 一次配好,不依赖 Air780 单独刷脚本
### 2.3 4G 特有字段: link 对象(用户决策 2026-08-31)
@@ -155,17 +164,24 @@
- JSON 解析失败时原样转发,不阻塞上行
- 开关: `config.lua` `CFG_LINK_ENABLE`
## 3 UART 链路帧协议(设计稿 v0.2,校验已定稿)
## 3 UART 链路帧协议(定稿: 0x7F 业务帧 + 0x8F 本机侧私有帧)
> **原"设计稿 v0.2"(0x7D 帧 / 2B 大端 LEN / PAYLOAD 装 JSON ≤2048)已作废**(2026-09-10 用户决策)。
> 实际采用 vd960DBN 侧既有帧布局的**双魔数分流**,不再自造第二套帧协议。
```
帧 = [HEAD 0x7D] [LEN_H] [LEN_L] [PAYLOAD...] [XOR] [SUM]
- HEAD: 0x7D(避开 0x7F DBN↔Loop / 0x8F DBN 专有 / 0x9F OTA 已占用魔数)
- LEN: uint16 大端, PAYLOAD(JSON) 字节数, ≤2048
- XOR: XOR 校验,从 LEN_H 起到 PAYLOAD 末字节(不含 HEAD)
- SUM: 累加和校验,范围同上
- 双向对称
[0]=MAGIC [1]=Addr [2]=LEN(1B, =1+data) [3]=CMD [4..]=DATA [-2]=XOR [-1]=SUM
帧总长 = LEN + 5; 校验范围 = 从 Addr 起 2+LEN 字节(不含 MAGIC); 双向对称
```
| 魔数 | 用途 | 帧长上限 |
|---|---|---|
| `0x7F` | 业务帧: 转发 UART2(Loop),字节流透传 | 70B(Loop 协议) |
| `0x8F` | **本机侧私有帧**: 链路两端各自本地消费,**不转发**(DBN 私有指令 / 4G 配置同步) | **260B** |
| `0x9F` | OTA(既有) | 既有 |
其他魔数: 丢弃 + 回找最近魔数 resync。
### 3.1 与 DBN↔Loop 0x7F 帧的对比(2026-08-31 代码核实)
vd960DBN 与地感 MCU 的串口逻辑(loop_uart_proto.c,UART2,0x7F 帧):
@@ -177,17 +193,18 @@ vd960DBN 与地感 MCU 的串口逻辑(loop_uart_proto.c,UART2,0x7F 帧):
校验: XOR+SUM,从 Addr 起(不含 magic)
```
| 对比项 | DBN↔Loop (0x7F) | Air780↔DBN (0x7D 本工程) |
| 对比项 | DBN↔Loop (0x7F) | DBN↔Air780 (0x8F 配置同步) |
|---|---|---|
| LEN 字段 | **1B**,Value 0~64B(协议明确上限) | **2B**,≤2048B |
| 魔数 | 0x7F | 0x7D |
| 校验 | XOR + SUM(从 Addr 起) | **XOR + SUM(从 LEN_H 起,用户决策 2026-08-31)** |
| LEN 字段 | **1B**,Value 0~64B(协议明确上限) | **1B**,LEN=1+data,**帧 ≤260B**(数据 ≤254B) |
| 魔数 | 0x7F | 0x8F |
| 校验 | XOR + SUM(从 Addr 起) | **XOR + SUM(从 Addr 起,不含魔数)** —— 与 0x7F 完全一致 |
| 状态机 | IDLE→HEADER→VALUE→CHECK | 同构(IDLE→HEAD→LEN→DATA→XOR→SUM) |
| 用途 | 命令-响应短帧 | JSON 报文流(loop_data 数百字节) |
| 用途 | 命令-响应短帧 | **本机侧配置同步**(net 229B / topic 129B) |
- 为什么不用 0x7F 帧: LEN 1B 上限 64B,装不下 MQTT JSON
- 状态机同构 + 校验统一 → vd960DBN 侧 UART1 通道可直接复用 `lup_feed_byte` 解析骨架
- **校验已定稿为 XOR+SUM**(2026-08-31 用户确认),与 0x7F 完全一致
- 为什么配置同步不用 0x7F 帧: LEN 1B 且 Loop 协议上限 70B,装不下 ClientID/密码/Topic 等长字段
`0x8F` 独立放宽到 260B;`0x7F` 纪律不变
- 状态机同构 + 校验统一 → 解析骨架可复用(注: UART1 用**独立装配器实例**,不可与全局 `g_lup_parser` 共用)
-**校验定稿为 XOR+SUM**(2026-08-31 用户确认),与 0x7F 完全一致
## 4 文件结构
@@ -243,7 +260,7 @@ vd960Air/
### 待确认(等开发文档/板级验证)
- [ ] vd960DBN UART1 帧格式是否按 §3 设计稿(0x7D 帧),或用户文档另有规定
- [x] **vd960DBN UART1 帧格式(2026-09-10 定稿)**: 按 §3 —— 0x7F 业务帧字节流 + 0x8F 本机侧私有帧(原 0x7D 设计稿作废)
- [ ] dev_serial 获取方式: config 写死 vs UART 握手动态下发(当前 config 写死)
- [x] **MQTT 服务器(2026-09-10 定)**: 测试服 `110.41.131.144:1883`,明文(非 TLS),鉴权 `admin/****`
—— 实现: `config.lua` `CFG_MQTT_HOST/PORT/USER/PASS`,`mqtt_main` 取配置传入 `mqtt:auth()`
@@ -260,14 +277,14 @@ vd960Air/
| P0 | 工程骨架 + 帧协议 + MQTT 桥接 + link 注入 | ✅ 完成 |
| **P0.5** | **方案 C MVP: 0x7F 帧解析 + 0xC0→loop_data + 沿检测→event_report + ACK 状态机 + initialize/heartbeat + 时钟校准**(2026-08-31) | ✅ 代码完成,待板级 |
| **P0.5-fix** | **上电复位修复: config.lua 漏 return + mstick 时基 + MQTT 服务器/鉴权配置**(2026-09-10) | ✅ 已修,待板级复测 |
| P1 | 下行命令转换(loop_param_*/log_*/ota_* 转 0x7F)+ 0x7D 配置同步下发 + vd960DBN UART1 通道联调 | ⏳ 待板/待 vd960DBN 版本 |
| P1 | 下行命令转换(loop_param_*/log_*/ota_* 转 0x7F)+ **0x8F 配置同步(拉取+推送)** + vd960DBN UART1 通道联调 | ⏳ 待板/待 vd960DBN 版本 |
| P2 | 板级联调: 帧校验、背压、掉线重连、看门狗 | ⏳ 待板 |
| P3 | 通道切换(策略待讨论)+ 脱机日志/OTA 走 4G | ⏳ 规划 |
**vd960DBN 侧开发计划(2026-08-31 用户确认列入):**
- [ ] UART1(PB6/PB7)通道: 帧收发 + 0x7F 帧魔数分流(0x7F → UART2 透传 / 0x8F → 本地)
- [ ] **UART2↔UART1 双向透传(方案 B)**: Loop 传感数据(0xC0)转发 Air780;4G 下行地感指令转发 Loop(复用 manage_dbn_ble_transparent 模式)
- [ ] BLE 设置服务器/topic 参数时(0x13/0x15 等),同步经 UART1 下发 Air780 配置
- [x] UART1(PB6/PB7)通道: 帧收发 + 魔数分流(0x7F → UART2 透传 / 0x8F → 本地) —— **已实现**(`d4d57f6` + `c879ed0`, 2026-09-10)
- [x] **UART2↔UART1 双向透传(方案 B)**: Loop 传感数据(0xC0)转发 Air780;4G 下行地感指令转发 Loop(复用 manage_dbn_ble_transparent 模式) —— **已实现**(`d4d57f6`, 2026-09-10)
- [ ] BLE 设置服务器/topic 参数时(0x13/0x15/0x09 等),同步经 UART1 下发 Air780 配置 —— **协议已定稿**(《DLD960_IoT_MQTT协议》§6.9),待两侧实现
- [ ] 通道切换策略(待讨论: 动态自动 vs 人工设置;暂定默认 4G)
## 8 板级问题修复记录
@@ -12,7 +12,7 @@
下行链路:
MQTT 标准 JSON 命令 → (P1: 转 0x7F 帧) → UART1 → vd960DBN → vd960Loop
MVP 范围: 上行(initialize/loop_data/event_report/heartbeat)+ report_config 时钟校准;
下行命令转换与 0x7D 配置同步列入 P1。
下行命令转换与 0x8F 配置同步(拉取+推送)列入 P1。
]]
-- 依赖