# BLE 通信协议明细

基于 `软件系统说明.docx` 整理。本文档用于把 BLE 通信协议推进到"可联调设计"层，把帧结构、服务、命令表和时序骨架补到足够继续细化的程度。

本文档仍然遵循一个原则：不虚构未被产品说明证实的命令字、UUID 或 payload 值。以下内容中，凡是来源仅为"推导"而非"文档原文确认"的，会标明"待确认"。

## 已确认事实

- 通信方式：`BLE 5.0 GATT`
- 协议帧格式：帧头 `0xAA 0x55`，随后是长度、类型、数据、XOR 校验
- 已知服务 UUID：
  - `FFE0`：设备信息服务
  - `FFE1`：数据通信服务
  - `FFE2`：OTA 升级服务
- 业务流程中至少存在以下设备交互阶段：连接设备、确认佩戴、自动扫描、开始治疗

## 供应商补充协议摘录（2026-05-11）

根目录新增的 `协议简述.docx` 已归档到 `docs/protocols/协议简述.docx`，解析稿见 `docs/protocols/协议简述-补充解析.md`。

补充文档主要给出 `FFE1` 数据通信相关信息：

| UUID/字段 | 名称 | 属性/说明 |
| --- | --- | --- |
| `FFE1` | 数据通信服务 / Command | 文档中同时写作服务和 Command，`Write+Read`，下发控制指令 |
| `FFE4` | Status | `Read + Notify`，设备状态及 ADC 值数据上报 |

Command 参数区被描述为 33 字节：

- IO1-IO5，每个 IO 含 4 个光强字段：红灯、红外、紫外、暖黄
- IO1-IO5，每个 IO 含 2 字节电流增益
- Byte31-Byte32：保持时间高/低字节
- Byte33：异或校验

### 与当前实现的关键差异

由于项目当前优先目标是尽快跑通真机，新补充协议先作为当前执行协议：`FFE1` 写 Command，`FFE4` 订阅 Status，Command 直接写 33 字节参数块。旧 `0xAA 0x55 | length | type | payload | XOR checksum` 帧协议暂作为历史参考和后续兼容方案保留。

需要硬件侧优先确认：

1. `FFE1`、`FFE4`、`FFE5` 的最终服务/特征分配。
2. Command 写入是否为裸 33 字节，还是仍需现有帧封装。
3. Byte33 XOR 的计算范围。
4. Byte31-Byte32 保持时间单位和字节序。
5. Status/ADC 上报的完整字节布局。

## 帧结构草案

### 帧总体格式

| 字段 | 偏移 | 长度 | 值域 | 来源 | 说明 |
| --- | --- | --- | --- | --- | --- |
| `header` | 0 | 2 字节 | `0xAA 0x55` | 文档确认 | 帧头标识 |
| `length` | 2 | 1 字节 | 待确认 | 文档确认存在，定义待补 | 数据长度 |
| `type` | 3 | 1 字节 | 待确认 | 文档确认存在，枚举待补 | 命令/数据/事件类型 |
| `payload` | 4 | N 字节 | 待确认 | 文档确认存在 | 业务载荷 |
| `checksum` | 4+N | 1 字节 | 待确认 | 文档确认为 XOR | 校验 |

### 必须补齐的帧定义

| 项目 | 当前状态 | 阻塞影响 |
| --- | --- | --- |
| `length` 是否包含 `type`、`checksum` | 未定义 | 无法正确解析帧 |
| `checksum` XOR 计算范围 | 未定义 | 无法正确校验帧 |
| 多字节字段字节序 | 未定义 | 数值解析错误 |
| 字符串编码方式 | 未定义 | 文本解析错误 |
| 最大 payload 长度 | 未定义 | 分包策略无法设计 |
| MTU 约束 | 未定义 | 传输效率与可靠性 |

### 建议帧计算规则（待确认）

以下为建议方案，非最终定义：

- `length`：建议仅表示 `payload` 的字节长度
- `checksum`：建议对 `length`、`type`、`payload` 所有字节做 XOR 运算
- 字节序：建议统一大端序（`Big-Endian`）
- 字符串：建议统一 `UTF-8`

## 服务与 characteristic 草案

### `FFE0` 设备信息服务

职责：提供设备基础信息。

建议 characteristic 划分（待确认）：

| 建议名称 | 建议属性 | 说明 |
| --- | --- | --- |
| `device_info` | `read` | 读取设备型号、固件版本、硬件版本、序列号 |
| `battery_level` | `read` / `notify` | 电量信息 |

UUID 值：待确认

### `FFE1` 数据通信服务

职责：承担主要业务通信。

建议 characteristic 划分（待确认）：

| 建议名称 | 建议属性 | 说明 |
| --- | --- | --- |
| `write_cmd` | `write` / `writeWithoutResponse` | 小程序向设备发送命令 |
| `notify_data` | `notify` | 设备向小程序上报数据和事件 |

UUID 值：待确认

### `FFE2` OTA 升级服务

职责：固件升级传输。

建议 characteristic 划分（待确认）：

| 建议名称 | 建议属性 | 说明 |
| --- | --- | --- |
| `ota_control` | `write` / `notify` | OTA 控制命令和状态通知 |
| `ota_data` | `writeWithoutResponse` | 升级包分片传输 |

UUID 值：待确认

## 命令表草案

以下命令基于业务流程推导，所有 `type` 值和 `payload` 结构都是待确认的占位。

### 设备信息类

| 建议命令名 | 建议方向 | 建议功能 | type 占位 | payload 请求 | payload 响应 | 待确认 |
| --- | --- | --- | --- | --- | --- | --- |
| `GET_DEVICE_INFO` | 小程序 -> 设备 | 读取设备型号、固件版本、序列号 | `0x??` | 空 | 设备信息结构体 | 是 |
| `GET_BATTERY` | 小程序 -> 设备 | 读取设备电量 | `0x??` | 空 | 电量值 | 是 |
| `GET_DEVICE_STATUS` | 小程序 -> 设备 | 读取设备当前状态 | `0x??` | 空 | 状态码 | 是 |

### 治疗流程类

| 建议命令名 | 建议方向 | 建议功能 | type 占位 | payload 请求 | payload 响应 | 待确认 |
| --- | --- | --- | --- | --- | --- | --- |
| `START_WEARING_CHECK` | 小程序 -> 设备 | 启动佩戴确认 | `0x??` | 空 | 佩戴检测结果 | 是 |
| `WEARING_CHECK_RESULT` | 设备 -> 小程序 | 上报佩戴确认结果 | `0x??` | 无（通知） | 佩戴状态 | 是 |
| `START_AUTO_SCAN` | 小程序 -> 设备 | 启动自动扫描 | `0x??` | 空 | 扫描结果 | 是 |
| `AUTO_SCAN_RESULT` | 设备 -> 小程序 | 上报自动扫描结果 | `0x??` | 无（通知） | 扫描数据 | 是 |
| `START_TREATMENT` | 小程序 -> 设备 | 开始治疗 | `0x??` | 治疗参数（待确认） | 确认/拒绝 | 是 |
| `PAUSE_TREATMENT` | 小程序 -> 设备 | 暂停治疗 | `0x??` | 空 | 确认 | 是 |
| `RESUME_TREATMENT` | 小程序 -> 设备 | 恢复治疗 | `0x??` | 空 | 确认 | 是 |
| `STOP_TREATMENT` | 小程序 -> 设备 | 结束治疗 | `0x??` | 空 | 治疗摘要 | 是 |
| `TREATMENT_PROGRESS` | 设备 -> 小程序 | 上报治疗进度 | `0x??` | 无（通知） | 进度数据 | 是 |
| `TREATMENT_ERROR` | 设备 -> 小程序 | 上报治疗异常 | `0x??` | 无（通知） | 错误码 | 是 |

### OTA 类

| 建议命令名 | 建议方向 | 建议功能 | type 占位 | payload 请求 | payload 响应 | 待确认 |
| --- | --- | --- | --- | --- | --- | --- |
| `OTA_START` | 小程序 -> 设备 | 启动 OTA | `0x??` | 固件版本、总大小 | 确认/拒绝 | 是 |
| `OTA_CHUNK` | 小程序 -> 设备 | 传输分片 | `0x??` | 分片序号、分片数据 | 确认 | 是 |
| `OTA_VERIFY` | 小程序 -> 设备 | 校验完整固件 | `0x??` | 校验值 | 校验结果 | 是 |
| `OTA_APPLY` | 小程序 -> 设备 | 应用新固件 | `0x??` | 空 | 结果 | 是 |
| `OTA_PROGRESS` | 设备 -> 小程序 | 上报 OTA 进度 | `0x??` | 无（通知） | 进度百分比 | 是 |

## 会话时序草案

### 连接后初始化时序（建议）

以下为建议流程，非最终定义：

1. 小程序扫描并连接设备 GATT
2. 发现 `FFE0`、`FFE1`、`FFE2` 服务
3. 订阅 `FFE1` 的 `notify_data` 通知
4. 读取 `FFE0` 的 `device_info` 获取设备基本信息
5. 根据业务需要发送后续命令

### 治疗主流程时序（建议）

1. 发送 `START_WEARING_CHECK`
2. 等待 `WEARING_CHECK_RESULT` 通知
3. 佩戴确认通过后发送 `START_AUTO_SCAN`
4. 等待 `AUTO_SCAN_RESULT` 通知
5. 扫描完成后发送 `START_TREATMENT`
6. 接收 `TREATMENT_PROGRESS` 周期通知
7. 治疗完成或用户主动停止后发送 `STOP_TREATMENT`

### 异常处理时序（建议）

- 命令超时：建议 3-5 秒未收到响应则重试，最多重试 3 次
- 断连重连：建议重连后重新订阅 notify 并查询设备当前状态
- 治疗中断：建议重连后查询是否需要恢复上次治疗会话

## ACK/NACK 机制建议

建议每个命令都存在对应的 ACK 或 NACK 响应（待确认）：

| 响应类型 | 含义 |
| --- | --- |
| ACK | 命令已接收并执行成功 |
| NACK | 命令接收失败或执行失败，附带错误码 |

建议错误码表（待确认）：

| 建议范围 | 含义 |
| --- | --- |
| `0x00` | 成功 |
| `0x01` - `0x0F` | 通用错误 |
| `0x10` - `0x1F` | 参数错误 |
| `0x20` - `0x2F` | 设备状态错误 |
| `0x30` - `0x3F` | 治疗相关错误 |
| `0x40` - `0x4F` | OTA 相关错误 |

## 分包与粘包建议

当前文档未定义，以下为建议方案（待确认）：

- 建议每个 BLE 写入操作对应一个完整帧
- 若 payload 超过 MTU 限制，建议在应用层定义分包协议
- 每个分包建议携带：帧序号、是否最后一包的标记
- 接收端建议按序号拼装，收到最后一包后校验完整性

## 待确认问题

- 设备绑定是否依赖 BLE 返回的设备唯一标识，还是依赖扫码
- "确认佩戴"由什么传感器或状态判断，是自动还是手动
- "自动扫描"具体扫描什么数据
- 治疗模式、档位、时长是否由小程序下发
- 治疗记录是否由小程序组装后上传，还是由设备通过 MQTT 直接上报云端
- OTA 是否通过小程序中转升级包
- 是否需要设备端主动发起的连接认证或握手

## 当前结论

当前说明已经足够把 BLE 协议推进到"命令表草案"层。所有标为"待确认"的命令字、payload 和 UUID 都需要在下一步被确认或修正。最优先要补齐的是 `FFE1` 下的 characteristic UUID、命令字分配、ACK/NACK 机制和帧计算规则。
