docs(BLE): DLD960_BLE协议 V1.02→V1.03 — 命令总表补齐 + 未实现如实标注
对照 dbn_ble_srv.c(GBK+CRLF) 逐命令梳理,补齐既有配置命令: - 0x09/0x10/0x11/0x12: 序列码/设备信息/SSC网络读写 - 0x13/0x14/0x15/0x16: IoT网络/Topic读写(字符串数组 0x00 分隔) - 0x1C/0x1D: 密码验证/修改(0x1D 在 unpack_packs,不在 switch) - 0x1E/0x92/0x1F/0x22: 出厂/复位/子功能码 - 0x31: UART波特率读写(⚠ 写响应多 1B 重复低字节) - 0xC5: 传感上报使能(⚠ report_sens_acs 无定义,0xC0 上报未实现) - 透传通道 0x7F/0x9F 未实现如实标注: 0x17/0x18/0x20/0x21/0x87/0x88/0x89 无 case; 0x23/0x24/0x8A 空壳/空响应 同步: README 文档索引 V1.03 + devlog 置顶条目(2026-08-31)
This commit is contained in:
@@ -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 分配、继电器、指示灯、拨码 |
|
||||
|
||||
## 开发文档
|
||||
|
||||
+276
-33
@@ -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):
|
||||
|
||||
```
|
||||
<host>\0<port(ascii)>\0<client_id>\0<username>\0<password>\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 布局):`<remote_addr>\0<port(ascii)>\0<client_id>\0<username>\0<password>\0`。
|
||||
|
||||
### 3.7 设置设备 Topic `SET_IOT_TOPIC` (0x15)
|
||||
|
||||
**请求 data:** 字符串数组,`0x00` 分隔(支持分包):
|
||||
|
||||
```
|
||||
<clientid_enable+0x30>\0<topic_pub>\0<topic_sub>\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 上报未实现) |
|
||||
|
||||
@@ -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 协议实现。
|
||||
|
||||
Reference in New Issue
Block a user