diff --git a/README.md b/README.md index fceb9c4..6e4d646 100644 --- a/README.md +++ b/README.md @@ -60,7 +60,7 @@ DLD960 是一款基于环形线圈检测原理的四通道车辆检测器,支 | [DLD960_串口通信协议.md](docs/DLD960_串口通信协议.md) | V1.01 | 整机 TTL 串口 | 设备管理、参数配置、数据上报 | | [DLD960_TCP_JSON协议.md](docs/DLD960_TCP_JSON协议.md) | V1.03 | 以太网 TCP :5960 | 鉴权 + 命令 + event_report 客户端必答 + 脱机日志(事件/快照流) | | [DLD960_IoT_MQTT协议.md](docs/DLD960_IoT_MQTT协议.md) | V1.10 | 云平台 MQTT | 双主题 `{sn}/srv`+`{sn}/dev`、initialize、event_report 平台必答、设备时钟同步、脱机日志(事件/快照流)、Loop 远程 OTA(ota_* 命令,先存后刷) | -| [DLD960_BLE协议.md](docs/DLD960_BLE协议.md) | V1.02 | 蓝牙 BLE | 帧格式 + 分包 + 脱机日志(OFFLOG_STAT/QUERY/CLEAR)+ 传感快照(SNAP_STAT/QUERY/CLEAR,0x28/0x29/0x2A),与 MQTT/TCP 同语义 | +| [DLD960_BLE协议.md](docs/DLD960_BLE协议.md) | V1.03 | 蓝牙 BLE | 帧格式 + 分包 + 配置命令全表(0x09~0x24/0x31/0x8A/0x92/0xC5,未实现如实标注)+ 脱机日志(OFFLOG_STAT/QUERY/CLEAR)+ 传感快照(SNAP_STAT/QUERY/CLEAR)+ 透传(0x7F/0x9F) | | [DLD960硬件资源.md](docs/DLD960硬件资源.md) | — | 硬件 | 双 MCU IO 分配、继电器、指示灯、拨码 | ## 开发文档 diff --git a/docs/DLD960_BLE协议.md b/docs/DLD960_BLE协议.md index e95e9ac..1a3f086 100644 --- a/docs/DLD960_BLE协议.md +++ b/docs/DLD960_BLE协议.md @@ -1,15 +1,13 @@ -# DLD960 BLE 通信协议(脱机事件日志 + 传感快照) +# DLD960 BLE 通信协议 -> 版本: V1.02(2026-08-12,新增传感快照 3 命令;分包上限随协商 MTU 动态) +> 版本: V1.03(2026-08-31,命令总表补齐既有配置命令 0x09~0xC5 + 透传通道;未实现命令如实标注) > 适用: vd960DBN(CH32V208,WCH BLE 协议栈) -> 用途: 小程序/APP 经蓝牙读取设备本地 W25Qxx 环形日志(离线取证:事件流区分真复位 vs MQTT 断连重连;快照流回放 0xC0 传感波形) +> 用途: 小程序/APP 经蓝牙对 vd960DBN 进行**配置管理、参数查询、脱机日志/传感快照读取**(离线取证:事件流区分真复位 vs MQTT 断连重连;快照流回放 0xC0 传感波形) --- ## 1 帧格式 -与既有 BLE 配置命令一致: - ``` Magic | Header | Data | CheckByte | Addr/Sub Len CMD | | Xor Sum @@ -18,11 +16,21 @@ Magic | Header | Data | CheckByte - `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) -- 本命令族 Magic = `0x8F`(MAGIC_BYTE_DBN_DEFAULT) +- 校验实现:`check_pkg()` / `compute_ckb()`(dbn_ble_srv.c) -### 分包(长响应) +### 1.1 魔数(Magic) -响应单包数据上限**随协商 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`。 +| 魔数 | 名称 | 用途 | +|------|------|------| +| `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 | 整包最大长度 | |---------|-------------|-------------| @@ -36,22 +44,256 @@ Magic | Header | Data | CheckByte --- -## 2 命令码 +## 2 命令总表 -| 命令码 | 名称 | 方向 | 说明 | -|--------|------|------|------| -| `0x25` | `OFFLOG_STAT` | APP→设备 | 查询脱机事件日志统计(分页定位) | -| `0x26` | `OFFLOG_QUERY` | APP→设备 | 按全局序号分页拉取日志记录 | -| `0x27` | `OFFLOG_CLEAR` | APP→设备 | 清除日志(审计留痕) | -| `0x28` | `SNAP_STAT` | APP→设备 | 查询传感快照统计(分页定位) | -| `0x29` | `SNAP_QUERY` | APP→设备 | 按全局序号分页拉取快照记录 | -| `0x2A` | `SNAP_CLEAR` | APP→设备 | 清除快照(审计写入事件流) | +| 命令码 | 名称 | 方向 | 实现状态 | +|--------|------|------|---------| +| `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 V1.06 / TCP JSON V1.02 的 `log_stat` / `log_query` / `log_clear` 语义一致,通道不同。 +> 与 MQTT / TCP JSON 的 `log_stat` / `log_query` / `log_clear` 语义一致,通道不同(V1.02 起)。 --- -## 3 查询日志统计 `OFFLOG_STAT` (0x25) +## 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 字节)。 @@ -61,10 +303,10 @@ Magic | Header | Data | CheckByte |------|------|------|------| | 0 | 1 | `status` | `0x00`=OK;`0x01`=日志未启用(Flash 初始化失败) | | 1 | 2 | `boot_seq` | 当前启动序号(每次上电 +1,区分复位段) | -| 3 | 4 | `count` | 有效记录条数(0~8064,环形覆盖后 < capacity) | -| 7 | 4 | `capacity` | 容量上限(8064) | | 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): @@ -77,7 +319,7 @@ Magic | Header | Data | CheckByte --- -## 4 分页拉取日志 `OFFLOG_QUERY` (0x26) +## 7 分页拉取日志 `OFFLOG_QUERY` (0x26) **请求 data(5B):** @@ -92,7 +334,7 @@ Magic | Header | Data | CheckByte |------|------|------|------| | 0 | 1 | `status` | `0x00`=OK;`0x01`=日志未启用;`0x02`=请求帧过短 | | 1 | 1 | `count` | 本次实际返回记录条数(0~4) | -| 2 | N×32 | 记录 | `count` 条 OfflogEvt 原始结构(小端,见 §6) | +| 2 | N×32 | 记录 | `count` 条 OfflogEvt 原始结构(小端,见 §10) | 记录顺序 = 逻辑序号升序(与 `start_seq` 一致)。越界/空日志:`count=0`。 @@ -109,7 +351,7 @@ Magic | Header | Data | CheckByte --- -## 5 清除日志 `OFFLOG_CLEAR` (0x27) +## 8 清除日志 `OFFLOG_CLEAR` (0x27) **请求 data:** 无。 @@ -123,17 +365,17 @@ Magic | Header | Data | CheckByte --- -## 6 传感快照日志(0x28/0x29/0x2A,V1.02 新增) +## 9 传感快照日志(0x28/0x29/0x2A,V1.02 新增) **用途**:0xC0 传感帧(4 线圈波形)按上报节奏落盘,与事件日志**分区独立**(快照区 = 总容量 − 固定区 576KB − 事件区)。断网期间波形照常记录,可离线回放。 **线程语义(设备侧)**:采集路径(USART2 中断)只做打包 + RAM 暂存(8 深,满丢新),主循环每轮 `snap_flush()` 落盘——QUERY 读到的是已落盘记录。 -### 6.1 查询快照统计 `SNAP_STAT` (0x28) +### 9.1 查询快照统计 `SNAP_STAT` (0x28) **请求 data:** 无(`Len=1`)。 -**响应 data(19B,全小端):** 与 §3 `OFFLOG_STAT` 布局相同: +**响应 data(19B,全小端):** 与 §6 `OFFLOG_STAT` 布局相同: | 偏移 | 长度 | 字段 | 说明 | |------|------|------|------| @@ -144,7 +386,7 @@ Magic | Header | Data | CheckByte | 11 | 4 | `seq_first` | 最早一条全局序号(count=0 时=0) | | 15 | 4 | `seq_last` | 最新一条全局序号 | -### 6.2 分页拉取快照 `SNAP_QUERY` (0x29) +### 9.2 分页拉取快照 `SNAP_QUERY` (0x29) **请求 data(5B):** @@ -159,11 +401,11 @@ Magic | Header | Data | CheckByte |------|------|------|------| | 0 | 1 | `status` | `0x00`=OK;`0x01`=快照未启用;`0x02`=请求帧过短 | | 1 | 1 | `count` | 本次实际返回记录条数(0~2) | -| 2 | N×64 | 记录 | `count` 条 SnapRec 原始结构(小端,见 §6.4) | +| 2 | N×64 | 记录 | `count` 条 SnapRec 原始结构(小端,见 §9.4) | 记录顺序 = 逻辑序号升序。QUERY 响应最大 130B:MTU=96 时 2 包(87+43 dat);MTU≥103 时 2 包(94+36 dat)。 -### 6.3 清除快照 `SNAP_CLEAR` (0x2A) +### 9.3 清除快照 `SNAP_CLEAR` (0x2A) **请求 data:** 无。**响应 data(1B):** `status`:`0x00`=OK。 @@ -172,7 +414,7 @@ Magic | Header | Data | CheckByte 成功后 `SNAP_STAT` 的 `count` 归 0,`seq_last` 继续递增(序号不复位)。 -### 6.4 快照记录格式(SnapRec,64B 定长,小端) +### 9.4 快照记录格式(SnapRec,64B 定长,小端) | 偏移 | 长度 | 字段 | 说明 | |------|------|------|------| @@ -200,7 +442,7 @@ Magic | Header | Data | CheckByte --- -## 7 记录格式(OfflogEvt,32B 定长,小端) +## 10 记录格式(OfflogEvt,32B 定长,小端) | 偏移 | 长度 | 字段 | 说明 | |------|------|------|------| @@ -234,10 +476,11 @@ Magic | Header | Data | CheckByte --- -## 8 版本历史 +## 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 上报未实现) | diff --git a/vd960DBN/docs/devlog.md b/vd960DBN/docs/devlog.md index d0765ec..607b745 100644 --- a/vd960DBN/docs/devlog.md +++ b/vd960DBN/docs/devlog.md @@ -4,6 +4,46 @@ > > 项目定位: DLD960 通信板 — BLE 配网、TCP JSON 协议服务、Loop MCU 串口桥接 +## 2026-08-31 — BLE 协议文档补全 V1.03:配置命令全表 + 未实现如实标注 + +> **本次为文档补录**(固件代码未变,不升固件版本):对照 `dbn_ble_srv.c`(GBK+CRLF)逐命令梳理,`DLD960_BLE协议.md` 由 V1.02(仅脱机日志/快照 6 命令)补齐为完整 BLE 协议。 + +### 背景 + +`DLD960_BLE协议.md` 此前只覆盖 0x25~0x2A(OFFLOG/SNAP 6 命令),既有的 BLE 配置命令(0x09~0x24 等)没有文档——小程序/APP 对接无从下手。本次从代码反向梳理全部命令。 + +### 文档补全内容 + +| 命令码 | 名称 | 实现状态(代码核实) | +|--------|------|---------------------| +| 0x09/0x10/0x11/0x12 | 序列码/设备信息/SSC 网络读写 | ✅ manage_dbn_ble_default | +| 0x13/0x14/0x15/0x16 | IoT 网络/Topic 读写 | ✅ unpack_packs(字符串数组 0x00 分隔) | +| 0x1C/0x1D | 验证/修改密码 | ✅ unpack_packs(0x1D 不在 switch,分包收尾处理) | +| 0x1E/0x92 | 出厂初始化 | ✅ 回 [0] + factory_dev_info() | +| 0x1F | 设备复位 | ✅ 无响应直接 NVIC_SystemReset | +| 0x22 | 子功能码 | ✅ 2B LE,无响应 | +| 0x23/0x24 | 车检器参数读写 | ⚠ 空壳(0x23 仅回 [0] 不处理参数;0x24 空响应) | +| 0x31 | UART 波特率读写 | ✅(⚠ 写响应多 1B 重复低字节,文档已标注) | +| 0x8A | Loop 灵敏度列表 | ⚠ 空响应 | +| 0xC5 | 传感上报使能 | ✅ 设置生效无响应;⚠ report_sens_acs 无定义 → 0xC0 上报未实现 | +| 0x17/0x18/0x20/0x21/0x87/0x88/0x89 | 交通参数/通知/Loop 采样等 | ⚠ 头文件有定义,switch 无 case(未实现) | +| 0x7F/0x9F | 透传通道 | ✅ UART2 原样转发 / OTA 透传 | + +### 关键发现 + +- **0x1D MODIFY_PASS 实际已实现**:不在 manage_dbn_ble_default 的 switch,而在 unpack_packs 分包收尾分支(头文件有定义、switch 无 case ≠ 未实现,须看 unpack_packs) +- **0xC0 BLE 主动上报已废弃**:`report_sens_acs()` 仅 dbn_ble_srv.h 声明,全工程无定义无调用;0xC5 使能后无上报动作(上报走 MQTT/TCP) +- **0x31 写响应固件 bug**:`tmp_ble_buf[i++] = g_storage_uart_baud;` 后紧跟 `tmp_ble_buf[i++] = (uint8_t)g_storage_uart_baud;` 重复写低字节,响应 10B 而非 9B——文档按语义描述 + 标注实际多 1B,待板级联调时确认是否修固件 +- 请求分包(unpack_packs)与响应分包(set_response_to_notify)格式一致:header 高 4 位=包数、低 4 位=序号(从 1 起) + +### 同步 + +- `README.md` 文档索引 BLE 协议 V1.02 → V1.03(描述更新为完整命令表) +- CHANGELOG 历史发布条目(V1.02 不变)保留不动 +- 待板级:0x31 写响应长度、0xC5 使能后无上报是否符合预期 + +--- + ## 2026-08-21 — MQTT 协议 V1.10 代码落地:网络上报携带地感版本(loop_ver/loop_hw_ver) > **固件版本:归入 vd960DBN V1.02.05 发布**(2026-08-21 升版,cmcng.h 三段式一致:FIRMWARE_VER="1.02.05" + MAIN=1/SUB=2/SUBSUB=5)。V1.02.05 涵盖 8-20 联网稳定性修复系列(SocketSend 0x11 / OTA hex 空格 / union 合并 / 刷写状态语义)+ 本次 V1.10 协议实现。