# DLD960 BLE 通信协议 > 版本: V1.03(2026-08-31,命令总表补齐既有配置命令 0x09~0xC5 + 透传通道;未实现命令如实标注) > 适用: vd960DBN(CH32V208,WCH BLE 协议栈) > 用途: 小程序/APP 经蓝牙对 vd960DBN 进行**配置管理、参数查询、脱机日志/传感快照读取**(离线取证:事件流区分真复位 vs MQTT 断连重连;快照流回放 0xC0 传感波形) --- ## 1 帧格式 ``` Magic | Header | Data | CheckByte | Addr/Sub Len CMD | | Xor Sum 1 Byte | 1B 1B 1B | xx | 1B 1B ``` - `Len = len(CMD) + len(Data)`(即 `pkg[2] = 1 + data_len`) - 校验:`Xor = XOR(pkg[1..Len+2])`,`Sum = SUM(pkg[1..Len+2])`,覆盖 header + cmd + data(不含 magic) - 校验实现:`check_pkg()` / `compute_ckb()`(dbn_ble_srv.c) ### 1.1 魔数(Magic) | 魔数 | 名称 | 用途 | |------|------|------| | `0x8F` | MAGIC_BYTE_DBN_DEFAULT | 设备配置/查询/日志/快照命令族(本协议主体) | | `0x7F` | MAGIC_BYTE_DBN_TRANSPARENT | 透传:显示屏协议、地感协议、探头协议等 → 原样转发 UART2(Loop MCU 口) | | `0x9F` | MAGIC_BYTE_DBN_SUB_OTA | 透传子设备 OTA 升级(g_flag_counter_ota.flag 时进入透传模式) | ### 1.2 分包(请求与响应) **请求分包**(unpack_packs,0x13/0x15/0x1C/0x1D/0x22 等长请求):header 字节高 4 位 = 总包数,低 4 位 = 序号(从 1 递增);首包初始化重组缓冲,中间包校验 `amount/cmd/seq 连续`,末包 `amount == seq` 触发处理。校验失败丢弃整包。 **响应分包**(set_response_to_notify):单包 data 上限**随协商 MTU 动态**(V1.01,修复"Too large noti 丢包"):`chunk = min(peripheralMTU - 9, 94)`(整包 = 帧头4 + dat + ckb2,须 ≤ MTU-3 且 ≤ 本地缓冲 100B)。分包时 header 字节 = `(pkg_amount << 4) | pkg_seq`,`pkg_seq` 从 1 递增;收端按 `pkg_amount`/`pkg_seq` 重组,最后一片 `pkg_amount == pkg_seq`。 | 协商 MTU | 单包最大 dat | 整包最大长度 | |---------|-------------|-------------| | 23(未协商) | 14 | 20 | | 96(常见 Android) | 87 | 93 | | 185(iOS 常见) | 94 | 100 | 脱机日志 QUERY 响应最大 130B:MTU=96 时 2 包(87+43 dat);MTU≥103 时 2 包(94+36 dat)。 > 分包发送由 `performPeriodicTask`(50ms TMOS 周期)主动续传,两包间隔 ≤50ms,不依赖收包事件(2026-08-12 修复)。 --- ## 2 命令总表 | 命令码 | 名称 | 方向 | 实现状态 | |--------|------|------|---------| | `0x09` | UPDATE_DEV_SERIAL | APP→设备 | ✅ §3.1 | | `0x10` | GET_DEV_INFO | APP→设备 | ✅ §3.2 | | `0x11` | SET_LSSC_NET | APP→设备 | ✅ §3.3 | | `0x12` | GET_LSSC_NET | APP→设备 | ✅ §3.4 | | `0x13` | SET_IOT_NET | APP→设备 | ✅ §3.5 | | `0x14` | GET_IOT_NET | APP→设备 | ✅ §3.6 | | `0x15` | SET_IOT_TOPIC | APP→设备 | ✅ §3.7 | | `0x16` | GET_IOT_TOPIC | APP→设备 | ✅ §3.8 | | `0x17` | SET_SUB_TRAFFIC_PARAM | APP→设备 | ⚠ 未实现(头文件定义,无 case) | | `0x18` | GET_SUB_TRAFFIC_PARAM | APP→设备 | ⚠ 未实现(头文件定义,无 case) | | `0x1C` | CHECK_PASS | APP→设备 | ✅ §4.1 | | `0x1D` | MODIFY_PASS | APP→设备 | ✅ §4.2 | | `0x1E` | SET_FACTORY | APP→设备 | ✅ §4.3 | | `0x1F` | RESET_DEV | APP→设备 | ✅ §4.4 | | `0x20` | SET_NOTIFY | APP→设备 | ⚠ 未实现(头文件定义,无 case) | | `0x21` | SET_NOTIFY_LOOP | APP→设备 | ⚠ 未实现(头文件定义,无 case) | | `0x22` | SET_SUB_CODE | APP→设备 | ✅ §4.5 | | `0x23` | SET_CJQ_PARAM | APP→设备 | ⚠ 空壳(仅回 [0],参数未处理)§4.6 | | `0x24` | GET_CJQ_PARAM | APP→设备 | ⚠ 空响应(无数据)§4.7 | | `0x25` | OFFLOG_STAT | APP→设备 | ✅ §6 | | `0x26` | OFFLOG_QUERY | APP→设备 | ✅ §7 | | `0x27` | OFFLOG_CLEAR | APP→设备 | ✅ §8 | | `0x28` | SNAP_STAT | APP→设备 | ✅ §9 | | `0x29` | SNAP_QUERY | APP→设备 | ✅ §9 | | `0x2A` | SNAP_CLEAR | APP→设备 | ✅ §9 | | `0x31` | RW_UART_BAUD | APP→设备 | ✅ §4.8 | | `0x87` | LOOP_SAMPLE_PARAM | APP→设备 | ⚠ 未实现(头文件定义,无 case) | | `0x88` | LOOP_BALANCE_PARAM | APP→设备 | ⚠ 未实现(头文件定义,无 case) | | `0x89` | LOOP_RELEASE_PLANB | APP→设备 | ⚠ 未实现(头文件定义,无 case) | | `0x8A` | LOOP_SENS_LIST | APP→设备 | ⚠ 空响应(无数据)§4.9 | | `0x92` | SET_CJQ_FACTORY | APP→设备 | ✅ §4.10 | | `0xC0` | SUB_SENS_REPORT | 设备→APP | ⚠ 未实现(report_sens_acs 仅声明无定义;0xC5 使能后无上报动作) | | `0xC5` | SENS_ACS_ENABLE | APP→设备 | ✅(设置生效,无响应)§4.11 | > 与 MQTT / TCP JSON 的 `log_stat` / `log_query` / `log_clear` 语义一致,通道不同(V1.02 起)。 --- ## 3 设备配置命令 ### 3.1 更改设备序列码 `UPDATE_DEV_SERIAL` (0x09) **请求 data(6B):** 新序列码(6 字节,g_dev_number 更新源为 `alter_dev_serila()`)。 **响应 data(1B):** `status`:`0x01`=成功。 ### 3.2 查询设备信息 `GET_DEV_INFO` (0x10) **请求 data:** 无(`Len=1`)。 **响应 data(19 + N 字节):** | 偏移 | 长度 | 字段 | 说明 | |------|------|------|------| | 0 | 6 | `mac` | 设备 MAC 地址(gMacAddr) | | 6 | 1 | `hw_ver_main` | 硬件版本主 | | 7 | 1 | `hw_ver_sub` | 硬件版本次 | | 8 | 1 | `fw_ver_main` | 固件版本主 | | 9 | 1 | `fw_ver_sub` | 固件版本次 | | 10 | 1 | `model_len` | 型号字符串长度 N | | 11 | N | `model` | 产品型号(PRODUCT_MODEL,ASCII) | | 11+N | 6 | `dev_number` | 设备编号(6B) | | 17+N | 1 | `sub_code_lo` | 子功能码低字节(当前恒 0) | | 18+N | 1 | `sub_code_hi` | 子功能码高字节(当前恒 0) | | 19+N | 1 | `bus1_amount` | 总线1 设备数(当前恒 0) | | 20+N | 1 | `bus2_amount` | 总线2 设备数(当前恒 0) | > `sub_code` / `bus_amount` 字段代码中为占位(注释掉的旧逻辑),恒 0。 ### 3.3 设置 SSC 网络配置 `SET_LSSC_NET` (0x11) **请求 data(30B):** | 偏移 | 长度 | 字段 | 说明 | |------|------|------|------| | 0 | 4 | `lip` | 本机 IP | | 4 | 4 | `subnet_mask` | 子网掩码 | | 8 | 4 | `route_ip` | 网关 | | 12 | 4 | `lssc_ip` | 中心 IP | | 16 | 4 | `dns` | DNS(代码未读入,保留位) | | 20 | 2 | `port_ssc_tcp` | SSC TCP 端口(小端) | | 22 | 2 | `port_ssc_udp` | SSC UDP 端口(小端) | | 24 | 2 | `port_ssc_udp_message` | SSC UDP 消息端口(小端) | | 26 | 2 | `port_dev_tcp` | 设备 TCP 端口(小端) | | 28 | 2 | `port_dev_udp` | 设备 UDP 端口(小端) | **响应 data(1B):** `status`:`0x00`=成功(配置写入 Flash)。 ### 3.4 查询 SSC 网络配置 `GET_LSSC_NET` (0x12) **请求 data:** 无。 **响应 data(30B):** 与请求布局一致:`lip(4)+sub(4)+gw(4)+lssc_ip(4)+dns(4)+` 5×端口(2B 小端)。注意响应含 `dns`(读 local_net_cfg.dns)。 ### 3.5 设置 IoT 网络配置 `SET_IOT_NET` (0x13) **请求 data:** 字符串数组,`0x00` 分隔(支持分包,见 §1.2): ``` \0\0\0\0\0 ``` - `host`:MQTT 服务器地址 - `port`:MQTT 端口(ASCII 十进制,代码逐字符换算) - `client_id`:ClientID;**单字节 `0x20`(空格)表示使用本地序列号** - `username` / `password`:MQTT 鉴权 **响应 data(1B):** `status`:`0x00`=成功(写入 Flash)。 ### 3.6 查询 IoT 网络配置 `GET_IOT_NET` (0x14) **请求 data:** 无。 **响应 data:** 字符串数组,`0x00` 分隔(同 §3.5 布局):`\0\0\0\0\0`。 ### 3.7 设置设备 Topic `SET_IOT_TOPIC` (0x15) **请求 data:** 字符串数组,`0x00` 分隔(支持分包): ``` \0\0\0 ``` - `clientid_enable`:ASCII 数值,解析时减 `0x30` 还原 **响应 data(1B):** `status`:`0x00`=成功(写入 Flash)。 ### 3.8 查询设备 Topic `GET_IOT_TOPIC` (0x16) **请求 data:** 无。 **响应 data:** | 偏移 | 长度 | 字段 | 说明 | |------|------|------|------| | 0 | 1 | `clientid_enable` | `g_iot_topic.clientid_enable + 0x30` | | 1 | 1 | `rsvd` | 保留(0) | | 2 | N | `topic_pub` | 发布主题(`\0` 结尾) | | 2+N+1 | M | `topic_sub` | 订阅主题(`\0` 结尾) | --- ## 4 安全与控制命令 ### 4.1 验证密码 `CHECK_PASS` (0x1C) **请求 data(6B):** 密码明文(ASCII)。 **响应 data(1B):** `status`:`0x00`=通过;`0x01`=失败(或长度≠6)。 ### 4.2 修改密码 `MODIFY_PASS` (0x1D) **请求 data(12B):** 旧密码(6B)+ 新密码(6B)。 **响应 data(1B):** `status`:`0x00`=成功(旧密码校验通过并写入);`0x01`=失败(长度≠12 或旧密码错误)。 > 实现位置:`unpack_packs()`(switch 无 case,属分包收尾处理),V1.03 文档补录。 ### 4.3 设备出厂初始化 `SET_FACTORY` (0x1E) **请求 data:** 无。 **响应 data(1B):** `status`:`0x00`(先回包后执行 `factory_dev_info()` 写默认参数)。⚠ 未整机复位(代码 TODO:仅复位蓝牙以外部分)。 ### 4.4 设备复位 `RESET_DEV` (0x1F) **请求 data:** 无。**无响应**(直接 `NVIC_SystemReset()`)。 ### 4.5 设置子功能码 `SET_SUB_CODE` (0x22) **请求 data(2B):** `code_set`(小端,bit 定义如下)。**无响应**(生效并持久化 `update_sub_code_enable()`)。 | bit | 子功能 | bit | 子功能 | |-----|--------|-----|--------| | 0 | net_enable(SSC 网络) | 6 | radar_enable(雷达) | | 1 | iot_enable(IoT MQTT) | 9 | laser_enable(激光) | | 2 | custom_enable(自定义) | 15 | lora_enable(LoRa) | | 3 | loop_enable(地感) | | | | 4 | dgdus_enable(地感采集器) | | | | 5 | wbdus_enable(称重采集器) | | | ### 4.6 设置车检器参数 `SET_CJQ_PARAM` (0x23) **⚠ 空壳:** 代码中参数解析被注释(`unpack_pkg_set_cjq_param` 未调用),仅返回 `[0x00]` 伪成功。**参数实际未写入。** ### 4.7 读取车检器参数 `GET_CJQ_PARAM` (0x24) **⚠ 空响应:** 仅构造响应帧,data 长度 = 0。**无有效数据返回。** ### 4.8 读写 UART 波特率 `RW_UART_BAUD` (0x31) **请求 data:** `rw(1B)` + 数据(`rw≠0` 时):`uart_num(1B) + baud(3B 小端)`。 - `rw=0`:读。 **读响应 data(10B):** | 偏移 | 长度 | 字段 | 说明 | |------|------|------|------| | 0 | 1 | `rw` | 0(读) | | 1 | 1 | `status` | 0x01 | | 2 | 1 | `idle_timeout` | BLE 空闲超时(g_max_counter_bt_min) | | 3 | 3 | `baud_1` | UART1 波特率(3B 小端) | | 6 | 1 | `idx_2` | 0x02(第二组标识) | | 7 | 3 | `baud_2` | 第二组波特率(3B 小端) | - `rw≠0`:写。`alter_dev_baud(&pkg[5])` + 更新 `g_storage_uart_num/baud`。 **写响应 data(9B 语义):** `rw(1B) + status(1B) + baud(3B 小端) + reserved(4B)`。 > ⚠ **固件实际多发 1B**(baud 低字节重复写入,共 10B):接收端以前 3B(offset 2..4)为准。 ### 4.9 读取 Loop 灵敏度列表 `LOOP_SENS_LIST` (0x8A) **⚠ 空响应:** case 仅 `memset` 无组包。**无有效数据返回。** ### 4.10 车检器出厂初始化 `SET_CJQ_FACTORY` (0x92) 与 §4.3 `SET_FACTORY`(0x1E)合并处理:响应 `[0x00]` + 执行 `factory_dev_info()`。 ### 4.11 传感主动上报使能 `SENS_ACS_ENABLE` (0xC5) **请求 data(3B):** | 偏移 | 长度 | 字段 | 说明 | |------|------|------|------| | 0 | 1 | `enable` | 0=关闭;非0=开启 | | 1 | 1 | `interval` | 上报间隔系数(实际 = 值 × 0x7F,单位 tick 待确认) | | 2 | 1 | `timeout_min` | 超时分钟数(timeout_counter = 值 × 60 × 100 tick) | **无响应。** ⚠ 即使使能,`report_sens_acs()` 无定义无调用,**当前无 0xC0 BLE 主动上报**(上报走 MQTT/TCP 通道)。 --- ## 5 透传通道 ### 5.1 通用透传 (0x7F) Magic=`0x7F` 的整帧(含校验)→ `manage_dbn_ble_transparent()` → **原样转发 UART2**(Loop MCU 口)。用于显示屏协议、地感协议、探头协议等。响应分包时 header 的 Addr/Sub 字节 = pkg_seq(见 set_response_to_notify 单包分支)。 ### 5.2 子设备 OTA 透传 (0x9F) `g_flag_counter_ota.flag != 0` 时所有 BLE 接收直接走透传 → UART2。用于 Loop MCU OTA(0x9F A5/A6/A7 帧透传,协议见《DLD960Loop 串口通信协议》OTA 章节)。 --- ## 6 查询日志统计 `OFFLOG_STAT` (0x25) **请求 data:** 无(`Len=1`,仅 cmd 字节)。 **响应 data(19B,全小端):** | 偏移 | 长度 | 字段 | 说明 | |------|------|------|------| | 0 | 1 | `status` | `0x00`=OK;`0x01`=日志未启用(Flash 初始化失败) | | 1 | 2 | `boot_seq` | 当前启动序号(每次上电 +1,区分复位段) | | 3 | 4 | `count` | 有效记录条数(0~capacity,环形覆盖后 < capacity) | | 7 | 4 | `capacity` | 容量上限(**随存储芯片动态**:W25Q32=16256 / W25Q64=32640 / W25Q128=65408 / W25Q256=130944) | | 11 | 4 | `seq_first` | 最早一条全局序号(count=0 时=0) | | 15 | 4 | `seq_last` | 最新一条全局序号 | 示例(boot_seq=2, count=1234, capacity=16256, seq_first=100, seq_last=1333): ``` 8F 00 14 25 00 02 00 D2 04 00 00 00 80 3F 00 00 00 64 00 00 00 35 05 00 00 00 XX XX -- -- -- -- -------------------- -------------------- -------------------- ----- | | | | status count=1234 capacity=16256 seq_first=100 | | | | cmd=0x25 boot_seq=2 seq_last=1333 ``` --- ## 7 分页拉取日志 `OFFLOG_QUERY` (0x26) **请求 data(5B):** | 偏移 | 长度 | 字段 | 说明 | |------|------|------|------| | 0 | 4 | `start_seq` | 起始全局序号(小端,含);越界(< seq_first 或 > seq_last)返回 0 条 | | 4 | 1 | `count` | 拉取条数,**上限 4**,超限按 4;0 按 4 处理 | **响应 data:** | 偏移 | 长度 | 字段 | 说明 | |------|------|------|------| | 0 | 1 | `status` | `0x00`=OK;`0x01`=日志未启用;`0x02`=请求帧过短 | | 1 | 1 | `count` | 本次实际返回记录条数(0~4) | | 2 | N×32 | 记录 | `count` 条 OfflogEvt 原始结构(小端,见 §10) | 记录顺序 = 逻辑序号升序(与 `start_seq` 一致)。越界/空日志:`count=0`。 请求示例(start_seq=1330, count=4): ``` 8F 00 06 26 32 05 00 00 04 XX XX -- -- -- -- -- -- -- -- --- | | | | | | | | count=4 | | | | +--+--+--+ start_seq=1330 (LE) | | | cmd=0x26 | | Len=5+1=6 ``` --- ## 8 清除日志 `OFFLOG_CLEAR` (0x27) **请求 data:** 无。 **响应 data(1B):** `status`:`0x00`=OK。 > ⚠ **高风险操作**:清除动作本身写入事件流(`log_clear` 审计——留痕不可清除)。设备侧应做权限控制(与 MQTT `log_clear` 同语义)。 > > ⚠ **阻塞 ~2.8s**:63 个数据扇区 SPI 擦除(~45ms/扇区),期间主循环阻塞。若设备 IoT MQTT 在线,此期间 WCHNET 无法轮询,可能导致断连重连(60s keepalive 内可恢复)。请勿高频调用。 成功后 `OFFLOG_STAT` 的 `count` 归 1(仅剩审计记录),`seq_last` 继续递增(序号不复位)。 --- ## 9 传感快照日志(0x28/0x29/0x2A,V1.02 新增) **用途**:0xC0 传感帧(4 线圈波形)按上报节奏落盘,与事件日志**分区独立**(快照区 = 总容量 − 固定区 576KB − 事件区)。断网期间波形照常记录,可离线回放。 **线程语义(设备侧)**:采集路径(USART2 中断)只做打包 + RAM 暂存(8 深,满丢新),主循环每轮 `snap_flush()` 落盘——QUERY 读到的是已落盘记录。 ### 9.1 查询快照统计 `SNAP_STAT` (0x28) **请求 data:** 无(`Len=1`)。 **响应 data(19B,全小端):** 与 §6 `OFFLOG_STAT` 布局相同: | 偏移 | 长度 | 字段 | 说明 | |------|------|------|------| | 0 | 1 | `status` | `0x00`=OK;`0x01`=快照未启用 | | 1 | 2 | `boot_seq` | 当前启动序号 | | 3 | 4 | `count` | 有效记录条数(0~capacity) | | 7 | 4 | `capacity` | 容量上限(**随芯片动态**:W25Q32=48064 / W25Q64=105408 / W25Q128=220096 / W25Q256=449472) | | 11 | 4 | `seq_first` | 最早一条全局序号(count=0 时=0) | | 15 | 4 | `seq_last` | 最新一条全局序号 | ### 9.2 分页拉取快照 `SNAP_QUERY` (0x29) **请求 data(5B):** | 偏移 | 长度 | 字段 | 说明 | |------|------|------|------| | 0 | 4 | `start_seq` | 起始全局序号(小端,含);越界返回 0 条 | | 4 | 1 | `count` | 拉取条数,**上限 2**(64B×2+2=130B ≤ 单包缓冲),超限按 2;0 按 2 | **响应 data:** | 偏移 | 长度 | 字段 | 说明 | |------|------|------|------| | 0 | 1 | `status` | `0x00`=OK;`0x01`=快照未启用;`0x02`=请求帧过短 | | 1 | 1 | `count` | 本次实际返回记录条数(0~2) | | 2 | N×64 | 记录 | `count` 条 SnapRec 原始结构(小端,见 §9.4) | 记录顺序 = 逻辑序号升序。QUERY 响应最大 130B:MTU=96 时 2 包(87+43 dat);MTU≥103 时 2 包(94+36 dat)。 ### 9.3 清除快照 `SNAP_CLEAR` (0x2A) **请求 data:** 无。**响应 data(1B):** `status`:`0x00`=OK。 > ⚠ **高风险操作**:清除动作本身写入**事件流** `log_clear` 审计(payload[0]=2=快照流,不可清除)。 > 阻塞 ~45ms:逻辑清除(count=0 旧数据立即不可读)+ 只擦写指针起点扇区,其余扇区由环形写覆盖时自动擦(原擦全部 751 扇区 ~34s,会触发 IWDG 4s 复位——2026-08-12 修复)。 成功后 `SNAP_STAT` 的 `count` 归 0,`seq_last` 继续递增(序号不复位)。 ### 9.4 快照记录格式(SnapRec,64B 定长,小端) | 偏移 | 长度 | 字段 | 说明 | |------|------|------|------| | 0 | 1 | `magic` | `0xA6`(区别于事件 `0xA5`) | | 1 | 1 | `len` | 线圈数据有效长度 = coil_count×12(0~48) | | 2 | 1 | `flags` | bit0=分包帧(预留) | | 3 | 1 | `rsvd` | 保留(0) | | 4 | 4 | `seq` | 全局序号(跨 boot 递增) | | 8 | 4 | `ts_ms` | boot 内相对时间(ms,采集时刻) | | 12 | 2 | `boot_seq` | 所属启动段 | | 14 | 2 | `rsvd2` | 保留(0) | | 16 | 48 | `coils` | 4×12B 线圈数据,与 0xC0 线上格式一致 | **线圈 12B 单元**(与 0xC0 帧内每路线圈完全一致): | 偏移(单元内) | 长度 | 字段 | 说明 | |------|------|------|------| | 0 | 1 | `cfg` | freq_level(2) + direction(1) + freq_type(1) + sensitivity(4) | | 1 | 1 | `cond` | condition(4) + loop_state(1) + car_state(1) + misc_type(2) | | 2 | 3 | `freq` | 频率,3B 小端无符号 | | 5 | 3 | `variation` | 变化量,3B 小端有符号补码(= Origin − CAPVD) | | 8 | 4 | `misc` | 杂项 4B 小端(misc_type=0 时=通过时间,50ms 单位) | > 绝对时间回算:用事件流 `time_anchor`(boot_seq ↔ unix_ts 映射)+ 本记录 `boot_seq`/`ts_ms`。未同步段仅相对时间。 --- ## 10 记录格式(OfflogEvt,32B 定长,小端) | 偏移 | 长度 | 字段 | 说明 | |------|------|------|------| | 0 | 1 | `magic` | `0xA5` | | 1 | 1 | `type` | 事件类型(下表) | | 2 | 1 | `len` | payload 有效字节数(0~12) | | 3 | 1 | `flags` | bit0=1 → `unix_ts` 有效 | | 4 | 4 | `seq` | 全局序号(跨 boot 递增) | | 8 | 4 | `ts_ms` | boot 内相对时间(ms,断电归零) | | 12 | 4 | `unix_ts` | 已同步 Unix 秒;`flags.bit0=0` → 0/无效(未同步段仅相对时间) | | 16 | 2 | `boot_seq` | 所属启动段 | | 18 | 2 | `rsvd` | 保留(0) | | 20 | 12 | `payload` | 事件参数(下表) | ### 事件类型与 payload | type | 事件 | payload | 说明 | |------|------|---------|------| | `0x01` | boot | `[4]` 复位原因寄存器原始值(大端),位解析:bit31=LPWR bit30=WWDG bit29=IWDG(看门狗) bit28=软件复位 bit27=POR(真断电) bit26=NRST引脚 | 上电/复位 | | `0x10` | iot_connect | — | MQTT TCP 连接成功 | | `0x11` | iot_ready | — | MQTT 订阅完成 → 发 initialize(重复上线直接证据) | | `0x12` | iot_disconnect | `[1]` reason:1=断开 2=超时 3=CONNACK拒绝 4=连接超时 | MQTT 断连 | | `0x13` | iot_reconn | `[4]` 重连退避 ms(大端) | 重连退避 | | `0x30` | evt_retry | `[5]` msg_id(大端4) + retry(1) | event_report ACK 超时重发 | | `0x31` | evt_giveup | `[4]` msg_id(大端) | event_report 重试耗尽挂起 | | `0x40` | coil | `[6]` sub(1) + ch(1) + value(大端4, 50ms 单位) | 线圈事件;sub:1=car_enter 2=car_leave 3=loop_cut 4=loop_restore | | `0x50` | time_anchor | —(`unix_ts` 即平台下发值,严格一致) | 时钟同步锚点 | | `0x70` | log_clear | — | 日志清除(审计,不可清除) | > payload 内多字节为**大端**(与 offlog 写入侧一致),OfflogEvt 其余字段为**小端**(CPU 原生序,直接 memcpy)。 --- ## 11 版本历史 | 版本 | 日期 | 说明 | |------|------|------| | V1.00 | 2026-08-10 | 脱机事件日志 3 命令:OFFLOG_STAT / OFFLOG_QUERY / OFFLOG_CLEAR | | V1.01 | 2026-08-12 | 分包上限改为随协商 MTU 动态:`chunk = min(MTU-9, 94)`;修复 Too large noti 丢包 | | V1.02 | 2026-08-12 | 新增传感快照 3 命令:SNAP_STAT / SNAP_QUERY / SNAP_CLEAR(0x28/0x29/0x2A) | | V1.03 | 2026-08-31 | 命令总表补齐既有配置命令(0x09~0x24、0x31、0x8A、0x92、0xC5)+ 透传通道(0x7F/0x9F);对照 dbn_ble_srv.c 如实标注未实现命令(0x17/0x18/0x20/0x21/0x87/0x88/0x89 无 case;0x23/0x24/0x8A 空壳;0xC0 上报未实现) |