docs: 新增蓝牙通信协议文档,训练任务书蓝牙协议改为引用
This commit is contained in:
+3
-251
@@ -33,17 +33,6 @@
|
||||
- [A.4 主控命令帧](#a4-主控命令帧)
|
||||
- [A.5 常用命令示例](#a5-常用命令示例)
|
||||
- [附录 B:蓝牙通信协议](#附录-b蓝牙通信协议)
|
||||
- [B.1 总体设计](#b1-总体设计)
|
||||
- [B.2 GATT 服务与特征](#b2-gatt-服务与特征)
|
||||
- [B.3 帧格式](#b3-帧格式)
|
||||
- [B.4 Notify 分包与重组](#b4-notify-分包与重组)
|
||||
- [B.5 命令码](#b5-命令码)
|
||||
- [B.6 TLV 编码](#b6-tlv-编码)
|
||||
- [B.7 TLV 类型](#b7-tlv-类型)
|
||||
- [B.8 结果码](#b8-结果码)
|
||||
- [B.9 设备状态码](#b9-设备状态码)
|
||||
- [B.10 主要命令交互](#b10-主要命令交互)
|
||||
- [B.11 异步长命令模型](#b11-异步长命令模型)
|
||||
|
||||
---
|
||||
|
||||
@@ -323,245 +312,8 @@ CHECKSUM = (sum(frame[0] .. frame[帧长-4])) & 0xFF // 位于 frame[帧长
|
||||
|
||||
## 附录 B:蓝牙通信协议
|
||||
|
||||
### B.1 总体设计
|
||||
蓝牙通信协议(GATT 服务与特征、帧格式、TLV 编码、命令码、结果码、状态码、主动推送、客户端接入要求等)统一见同目录文档:
|
||||
|
||||
1. 所有业务数据统一封装为 TLV 二进制帧,通过 GATT Notify 分包发送。
|
||||
2. 客户端必须先按特征 UUID 分流,再按命令字 `CMD` 解析。
|
||||
3. `b1/b2` 为一问一答通道:客户端写 `b1`,设备从 `b2` 通知响应。
|
||||
4. `a1/a2/b3` 为主动推送通道,不参与请求响应匹配。
|
||||
5. 命令结果只以 `TLV_RESULT_CODE` 为准。
|
||||
6. 状态变化通过 `b3` 推送,与命令结果解耦。
|
||||
### [`蓝牙通信协议.md`](蓝牙通信协议.md)
|
||||
|
||||
### B.2 GATT 服务与特征
|
||||
|
||||
**Radar Data Service**:`a8c1e5c0-3d5d-4a9d-8d5e-7c8b6a4e2f1a`
|
||||
|
||||
| 名称 | UUID | 属性 | 方向 | 职责 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| a1 | `beb5483e-36e1-4688-b7f5-ea07361b26a1` | NOTIFY | 设备→客户端 | 连续雷达数据推送 |
|
||||
| a2 | `beb5483e-36e1-4688-b7f5-ea07361b26a2` | NOTIFY | 设备→客户端 | 雷达状态推送 |
|
||||
|
||||
**Device Config Service**:`a8c1e5c0-3d5d-4a9d-8d5e-7c8b6a4e2f1b`
|
||||
|
||||
| 名称 | UUID | 属性 | 方向 | 职责 |
|
||||
| --- | --- | --- | --- | --- |
|
||||
| b1 | `beb5483e-36e1-4688-b7f5-ea07361b26b1` | WRITE | 客户端→设备 | 命令写入 |
|
||||
| b2 | `beb5483e-36e1-4688-b7f5-ea07361b26b2` | NOTIFY | 设备→客户端 | 命令响应 |
|
||||
| b3 | `beb5483e-36e1-4688-b7f5-ea07361b26b3` | NOTIFY | 设备→客户端 | 设备信息 / 状态推送 |
|
||||
|
||||
### B.3 帧格式
|
||||
|
||||
```
|
||||
SOF1 SOF2 VERSION CMD SEQ LEN_H LEN_L PAYLOAD CRC_H CRC_L
|
||||
AA 55 01 xx xx xx xx ... xx xx
|
||||
```
|
||||
|
||||
| 字段 | 长度 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| SOF1 / SOF2 | 2 | 固定 `0xAA 0x55` |
|
||||
| VERSION | 1 | 协议版本,当前 `0x01` |
|
||||
| CMD | 1 | 命令码 |
|
||||
| SEQ | 1 | 命令请求序列号;主动推送由设备侧决定(`b3`、`a2` 固定为 `0`,`a1` 连续推送为设备侧自增),客户端对主动推送不按 `seq` 匹配 |
|
||||
| LEN | 2 | PAYLOAD 长度,大端 |
|
||||
| PAYLOAD | N | TLV 数据区 |
|
||||
| CRC | 2 | CRC16-CCITT,大端 |
|
||||
|
||||
- **CRC 计算范围**:从 VERSION 到 PAYLOAD 末尾,不含 SOF1/SOF2 与 CRC 本身。
|
||||
- **CRC 参数**:多项式 `0x1021`,初值 `0xFFFF`,输入/输出不反转,无最终异或(CRC16-CCITT-FALSE)。
|
||||
- **最小帧长**:9 字节(空载荷)。
|
||||
|
||||
### B.4 Notify 分包与重组
|
||||
|
||||
Notify 单包可能小于整帧,设备按固定 **20 字节**分片发送。客户端必须为 `a1 / a2 / b2 / b3` **各维护一个重组缓冲区**,按帧头 + LEN + CRC 提取完整帧。
|
||||
|
||||
### B.5 命令码
|
||||
|
||||
| 命令 | 值 | 通道 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| CMD_PING | `0x01` | b1/b2 | Ping |
|
||||
| CMD_QUERY_STATUS | `0x10` | b1/b2 | 查询设备状态 |
|
||||
| CMD_QUERY_RADAR | `0x12` | b1/b2 | 查询雷达快照 |
|
||||
| CMD_START_CONTINUOUS | `0x14` | b1/b2 | 启动连续推送 |
|
||||
| CMD_STOP_CONTINUOUS | `0x16` | b1/b2 | 停止连续推送 |
|
||||
| CMD_RADAR_SLEEP_QUERY | `0x17` | b1/b2 | 雷达睡眠查询开关 |
|
||||
| CMD_CONTINUOUS_PUSH | `0x18` | a1 | 连续数据主动推送 |
|
||||
| CMD_DEVICE_INFO_PUSH | `0x19` | b3 | 设备信息 / 状态推送 |
|
||||
| CMD_RADAR_STATUS_PUSH | `0x1A` | a2 | 雷达状态推送 |
|
||||
| CMD_WIFI_SCAN | `0x20` | b1/b2 | WiFi 扫描 |
|
||||
| CMD_WIFI_CONFIG | `0x22` | b1/b2 | WiFi 配网 |
|
||||
| CMD_GET_SAVED_WIFI | `0x24` | b1/b2 | 查询已保存 WiFi |
|
||||
| CMD_DELETE_SAVED_WIFI | `0x26` | b1/b2 | 删除已保存 WiFi |
|
||||
| CMD_ERROR_RESP | `0x7E` | b2 | 协议层错误响应 |
|
||||
|
||||
### B.6 TLV 编码
|
||||
|
||||
```
|
||||
TYPE(1) LEN_H(1) LEN_L(1) VALUE(N)
|
||||
```
|
||||
|
||||
### B.7 TLV 类型
|
||||
|
||||
**设备信息**
|
||||
|
||||
| TLV | 值 | 类型 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| TLV_RESULT_CODE | `0x02` | uint8 | 结果码 |
|
||||
| TLV_TIMESTAMP | `0x04` | uint32 | 时间戳(ms) |
|
||||
| TLV_PROTOCOL_VERSION | `0x05` | string | 协议版本 |
|
||||
| TLV_DEVICE_SN | `0x06` | uint64 | 设备序列号 |
|
||||
| TLV_FIRMWARE_VERSION | `0x07` | string | 固件版本 |
|
||||
| TLV_DEVICE_TYPE | `0x08` | string | 设备类型 |
|
||||
| TLV_MAC_ADDRESS | `0x09` | string | MAC 地址 |
|
||||
|
||||
**雷达数据**
|
||||
|
||||
| TLV | 值 | 类型 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| TLV_HEART_RATE_X10 | `0x10` | uint16 | 心率 ×10 |
|
||||
| TLV_BREATH_RATE_X10 | `0x11` | uint16 | 呼吸率 ×10 |
|
||||
| TLV_PRESENCE | `0x12` | uint8 | 人体存在 |
|
||||
| TLV_MOTION | `0x13` | uint8 | 运动状态 |
|
||||
| TLV_SLEEP_STATE | `0x14` | uint8 | 睡眠状态 |
|
||||
| TLV_DISTANCE_CM | `0x15` | uint16 | 距离(cm) |
|
||||
| TLV_POS_X_MM | `0x16` | int16 | X 坐标(mm) |
|
||||
| TLV_POS_Y_MM | `0x17` | int16 | Y 坐标(mm) |
|
||||
| TLV_POS_Z_MM | `0x18` | int16 | Z 坐标(mm) |
|
||||
| TLV_BODY_MOVEMENT | `0x19` | uint8 | 体动 |
|
||||
|
||||
**WiFi**
|
||||
|
||||
| TLV | 值 | 类型 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| TLV_SSID | `0x20` | string | WiFi 名称 |
|
||||
| TLV_PASSWORD | `0x21` | string | WiFi 密码 |
|
||||
| TLV_WIFI_COUNT | `0x22` | uint16 | WiFi 数量 |
|
||||
| TLV_WIFI_ITEM | `0x23` | block | WiFi 列表项 |
|
||||
| TLV_RSSI | `0x24` | int8 | 信号强度 |
|
||||
| TLV_SECURITY | `0x25` | uint8 | 加密类型 |
|
||||
|
||||
**控制与状态**
|
||||
|
||||
| TLV | 值 | 类型 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| TLV_INTERVAL_MS | `0x31` | uint16 | 推送间隔(ms) |
|
||||
| TLV_RADAR_SLEEP_ENABLED | `0x32` | uint8 | 雷达睡眠查询开关 |
|
||||
| TLV_DEVICE_STATUS | `0x33` | uint8 | b3 状态推送 |
|
||||
| TLV_WIFI_STATUS | `0x34` | uint8 | WiFi 状态 |
|
||||
| TLV_MQTT_STATUS | `0x35` | uint8 | MQTT 状态 |
|
||||
| TLV_RADAR_SLEEP_STATUS | `0x36` | uint8 | 雷达睡眠查询状态 |
|
||||
| TLV_LED_ENABLED | `0x37` | uint8 | 指示灯开关 |
|
||||
|
||||
**通用**
|
||||
|
||||
| TLV | 值 | 类型 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| TLV_IP_ADDRESS | `0x41` | string | IP 地址 |
|
||||
| TLV_WIFI_CONFIGURED | `0x42` | uint8 | 是否已保存 WiFi |
|
||||
| TLV_WIFI_CONNECTED | `0x43` | uint8 | WiFi 是否连接 |
|
||||
| TLV_ECHO_CONTENT | `0x44` | string | 回显内容 |
|
||||
|
||||
**波形**
|
||||
|
||||
| TLV | 值 | 类型 | 说明 |
|
||||
| --- | --- | --- | --- |
|
||||
| TLV_HEART_WAVEFORM | `0x60` | uint8 | 心跳波形(原值 + 128) |
|
||||
| TLV_BREATH_WAVEFORM | `0x61` | uint8 | 呼吸波形(原值 + 128) |
|
||||
|
||||
### B.8 结果码
|
||||
|
||||
| 结果码 | 值 | 说明 |
|
||||
| --- | --- | --- |
|
||||
| SUCCESS | `0x00` | 成功 |
|
||||
| PROCESSING | `0x01` | 已接收,处理中 |
|
||||
| ERR_PROTO_CMD_UNKNOWN | `0x13` | 未知命令 |
|
||||
| ERR_PROTO_PARAM_MISSING | `0x14` | 参数缺失 |
|
||||
| ERR_PROTO_PARAM_INVALID | `0x15` | 参数非法 |
|
||||
| ERR_PROTO_BUSY | `0x16` | 设备忙 |
|
||||
| ERR_PROTO_FRAME_TOO_LARGE | `0x18` | 帧过大 |
|
||||
| ERR_WIFI_SCAN_TIMEOUT | `0x20` | 扫描超时 |
|
||||
| ERR_WIFI_SSID_NOT_FOUND | `0x21` | 未找到 SSID |
|
||||
| ERR_WIFI_WRONG_PASSWORD | `0x22` | 密码错误 |
|
||||
| ERR_WIFI_SIGNAL_WEAK | `0x25` | 信号弱 |
|
||||
| ERR_WIFI_BUSY | `0x26` | WiFi 忙 |
|
||||
| ERR_DEV_STATE_INVALID | `0x40` | 状态不允许 |
|
||||
| ERR_DEV_STORAGE_FAIL | `0x41` | 存储失败 |
|
||||
| ERR_DEV_QUEUE_FULL | `0x42` | 队列已满 |
|
||||
|
||||
### B.9 设备状态码
|
||||
|
||||
用于 `TLV_DEVICE_STATUS` / `TLV_WIFI_STATUS` / `TLV_MQTT_STATUS` / `TLV_RADAR_SLEEP_STATUS`:
|
||||
|
||||
| 状态 | 值 |
|
||||
| --- | --- |
|
||||
| WIFI_DISCONNECTED | `0x10` |
|
||||
| WIFI_CONNECTING | `0x11` |
|
||||
| WIFI_CONNECTED | `0x12` |
|
||||
| WIFI_FAILED | `0x13` |
|
||||
| DEV_MQTT_DISCONNECTED | `0x20` |
|
||||
| DEV_MQTT_CONNECTING | `0x21` |
|
||||
| DEV_MQTT_CONNECTED | `0x22` |
|
||||
| DEV_MQTT_FAILED | `0x23` |
|
||||
| RADAR_SLEEP_QUERY_DISABLED | `0x30` |
|
||||
| RADAR_SLEEP_QUERY_ENABLED | `0x31` |
|
||||
| LED_DISABLED | `0x32` |
|
||||
| LED_ENABLED | `0x33` |
|
||||
|
||||
### B.10 主要命令交互
|
||||
|
||||
**CMD_QUERY_STATUS(0x10)**
|
||||
|
||||
- 请求:无载荷。
|
||||
- 响应(b2):`TLV_RESULT_CODE` + 设备信息 TLV(`TLV_PROTOCOL_VERSION`、`TLV_FIRMWARE_VERSION`、`TLV_DEVICE_TYPE`、`TLV_MAC_ADDRESS`,存在 SN 时附 `TLV_DEVICE_SN`)+ `TLV_WIFI_CONFIGURED`、`TLV_WIFI_CONNECTED`、`TLV_IP_ADDRESS`(已连接时)、`TLV_SSID`(已连接时)、`TLV_WIFI_STATUS`、`TLV_MQTT_STATUS`、`TLV_RADAR_SLEEP_STATUS`、`TLV_LED_ENABLED`。
|
||||
|
||||
**CMD_QUERY_RADAR(0x12)**
|
||||
|
||||
- 请求:无载荷。
|
||||
- 响应(b2):`TLV_RESULT_CODE` + `TLV_PRESENCE`、`TLV_HEART_RATE_X10`、`TLV_BREATH_RATE_X10`、`TLV_MOTION`、`TLV_DISTANCE_CM`、`TLV_POS_X_MM`、`TLV_POS_Y_MM`、`TLV_POS_Z_MM`、`TLV_BODY_MOVEMENT`;`seq` 与请求一致。
|
||||
|
||||
**CMD_START_CONTINUOUS(0x14)**
|
||||
|
||||
- 请求:`TLV_INTERVAL_MS`(有效范围 100~10000 ms)。
|
||||
- 响应:`TLV_RESULT_CODE`,成功时附 `TLV_INTERVAL_MS`;参数缺失/非法返回对应错误码。
|
||||
- 启动后设备按间隔通过 `a1` 推送 `CMD_CONTINUOUS_PUSH(0x18)` 帧。
|
||||
|
||||
**CMD_STOP_CONTINUOUS(0x16)**
|
||||
|
||||
- 请求无载荷;停止推送,幂等操作,始终返回 `SUCCESS`。
|
||||
|
||||
**CMD_CONTINUOUS_PUSH(0x18,a1 推送)**
|
||||
|
||||
- 载荷:`TLV_TIMESTAMP`、`TLV_PRESENCE`、`TLV_HEART_RATE_X10`、`TLV_BREATH_RATE_X10`、`TLV_MOTION`、`TLV_DISTANCE_CM` 等。
|
||||
|
||||
**CMD_WIFI_SCAN(0x20)**
|
||||
|
||||
- 请求无载荷。先回 `PROCESSING`;完成后回 `TLV_RESULT_CODE` + `TLV_WIFI_COUNT` + 多个 `TLV_WIFI_ITEM`(每项含 `TLV_SSID`、`TLV_RSSI`、`TLV_SECURITY`)。
|
||||
|
||||
**CMD_WIFI_CONFIG(0x22)**
|
||||
|
||||
- 请求:`TLV_SSID`、`TLV_PASSWORD`。
|
||||
- 先回 `PROCESSING`(可含 `TLV_SSID`);完成后回 `SUCCESS` + `TLV_SSID` + `TLV_IP_ADDRESS`,失败回对应错误码。
|
||||
|
||||
**CMD_GET_SAVED_WIFI(0x24)**
|
||||
|
||||
- 响应:`TLV_RESULT_CODE` + `TLV_WIFI_COUNT` + 多个 `TLV_WIFI_ITEM`。
|
||||
|
||||
**CMD_DELETE_SAVED_WIFI(0x26)**
|
||||
|
||||
- 请求:`TLV_SSID`;响应:`TLV_RESULT_CODE`。
|
||||
|
||||
**CMD_DEVICE_INFO_PUSH(0x19,b3 推送)**
|
||||
|
||||
- `seq = 0`;载荷为 `TLV_DEVICE_STATUS`,或设备信息 TLV(`TLV_RESULT_CODE`、协议版本、固件版本、设备类型、MAC、SN 等)。仅在状态变化时推送。
|
||||
|
||||
### B.11 异步长命令模型
|
||||
|
||||
适用于 `CMD_WIFI_SCAN`、`CMD_WIFI_CONFIG`:
|
||||
|
||||
```
|
||||
客户端 --b1--> 请求
|
||||
设备 --b2--> 原命令码, 原 seq, RESULT_CODE = PROCESSING(0x01)
|
||||
... 后台处理 ...
|
||||
设备 --b2--> 原命令码, 原 seq, RESULT_CODE = SUCCESS 或 ERR_XXX + 业务 TLV
|
||||
```
|
||||
|
||||
运行状态(WiFi 等)通过 `b3` 的 `CMD_DEVICE_INFO_PUSH(0x19)` + `TLV_DEVICE_STATUS` 推送。
|
||||
本文不再重复协议细节,实现时以上述文档为准。
|
||||
|
||||
Reference in New Issue
Block a user