Files
blinky/docs/dongle-peripheral-design.md
skiinder 88ee4da089 docs: 添加Blinky键盘2.4G端详细设计文档
- 定义了键盘外设固件内实现2.4G端的设计方案
- 描述了基于专用local identity的dongle peer设计方案
- 详细说明了身份规划和模块职责分工
- 包含了行为模型、状态事件设计和UI设计
- 提供了分阶段实施建议和风险评估
2026-05-06 18:36:39 +08:00

477 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Blinky 键盘 2.4G 端详细设计稿
## 1. 背景
当前 `C:\projects\blinky` 已经完成了外设侧多槽 BLE 基础能力:
- `Slot 1~3` 对应普通 BLE 主机
- `identity 4` 预留为 `Dongle Slot`
- `mode_policy_module` 已经区分:
- `MODE_SWITCH_BLE -> BLE_PROFILE_POLICY_GENERAL`
- `MODE_SWITCH_24G -> BLE_PROFILE_POLICY_DONGLE`
但目前 `identity 4` 还只是“预留位”,没有真正落成完整的 dongle peer 行为。
本设计稿的目标,是定义如何在**键盘外设固件内**实现“2.4G 端”,参考 `nrf_desktop` 的外围设备侧 dongle peer 设计。
这里的“2.4G 端”在第一阶段的实现语义不是 ESB 或私有无线协议,而是:
- 键盘继续作为 BLE Peripheral
- 通过专用 local identity 与自家 dongle 建立专用连接
- 在产品层把该模式呈现为“2.4G”
这和 `nrf_desktop``dongle peer` 设计方向一致。
## 2. 设计目标
本方案的目标如下:
- 在当前键盘固件内实现专用 `dongle peer`
- `MODE_SWITCH_24G` 时固定使用专用 `identity 4`
- `MODE_SWITCH_BLE` 时继续使用普通 BLE 槽位 `identity 1/2/3`
- `dongle peer` 与普通 BLE 槽位完全隔离
- `dongle peer` 有独立 bond 和独立状态显示
- Swift Pair 对普通 BLE 开启,对 `dongle peer` 默认关闭
- 后续为自家 dongle 识别准备一个最小 `dev_descr` 风格自定义 GATT 服务
本设计稿不包含“dongle central 固件”的实现,只定义键盘外设侧。
## 3. 参考基线
本设计主要参考本地 `nrf_desktop` 的外围设备侧设计:
- `c:\ncs\v3.2.3\nrf\applications\nrf_desktop\doc\ble_bond.rst`
- `c:\ncs\v3.2.3\nrf\applications\nrf_desktop\doc\dev_descr.rst`
- `c:\ncs\v3.2.3\nrf\applications\nrf_desktop\doc\qos.rst`
- `c:\ncs\v3.2.3\nrf\applications\nrf_desktop\src\modules\dev_descr.c`
- `c:\ncs\v3.2.3\nrf\applications\nrf_desktop\src\modules\qos.c`
参考结论:
- `dongle peer` 的核心不是新的无线协议,而是**专用 Bluetooth local identity**
- 外设与 dongle 的专用配对要和普通 BLE peer 隔离
- `dev_descr` 是未来 dongle 识别外设的关键入口
- `QoS` 是增强项,不是第一阶段前置条件
## 4. 当前工程现状
当前工程已经具备实现 `dongle peer` 的关键基础:
- `ble_bond_multi_module` 已支持固定 identity 多槽
- `identity 1/2/3` 已用于普通 BLE 槽位
- `identity 4` 已预留为 `Dongle Slot`
- `mode_policy_module` 已输出 `BLE_PROFILE_POLICY_GENERAL / DONGLE`
- Swift Pair 已默认开启,并且在 `identity 4` 上默认关闭
相关文件:
- `C:\projects\blinky\src\ble_bond_multi_module.c`
- `C:\projects\blinky\src\mode_policy_module.c`
- `C:\projects\blinky\inc\events\transport_policy_event.h`
- `C:\projects\blinky\src\swift_pair_module.c`
当前缺失点:
- `MODE_SWITCH_24G` 没有真正强制切到 `identity 4`
- `dongle peer` 没有独立 UI 状态
- 没有 `dev_descr` 风格自定义服务
- 没有独立的 dongle 管理接口
## 5. 总体设计
## 5.1 核心设计结论
采用 `nrf_desktop` 风格的“专用 dongle peer”设计
- 保持当前键盘为 BLE Peripheral
- 使用 `identity 4` 作为专用 dongle identity
-`MODE_SWITCH_24G` 作为选择 `dongle peer` 的产品模式
- 普通 BLE 槽位 `1/2/3``dongle peer` 独立管理
也就是说:
- `2.4G` 是产品语义
- 第一阶段实现仍然是 BLE Peripheral + 专用 identity
## 5.2 identity 规划
identity 规划继续固定如下:
| Identity | 角色 | 用途 |
| --- | --- | --- |
| `0` | 默认 identity | 不使用 |
| `1` | BLE Slot 1 | 普通 BLE |
| `2` | BLE Slot 2 | 普通 BLE |
| `3` | BLE Slot 3 | 普通 BLE |
| `4` | Dongle Slot | 专用 2.4G / dongle peer |
设计原则:
- `identity 4` 不参与普通槽位轮换
- `identity 4` 不参与普通 BLE 设置页
- `identity 4` 有独立 bond 和独立状态
## 6. 模块职责分工
## 6.1 `mode_policy_module`
职责保持不变:
- 根据拨杆位置输出 transport policy
当前定义:
- `MODE_SWITCH_BLE -> BLE_PROFILE_POLICY_GENERAL`
- `MODE_SWITCH_24G -> BLE_PROFILE_POLICY_DONGLE`
它不直接管理 bond只输出“当前应该走哪种 BLE profile”。
## 6.2 `ble_bond_multi_module`
这是本方案第一阶段的主修改模块。
需要扩展职责:
- 支持根据 `BLE_PROFILE_POLICY_DONGLE` 固定选择 `identity 4`
- 普通 BLE 与 `dongle peer` 分开管理
- 提供 `dongle peer` 独立状态输出
- 提供 `dongle peer` 独立擦除操作
仍然保留已有职责:
- 普通 BLE 三槽切换
- 普通 BLE 三槽擦除
- slot meta 持久化
## 6.3 `swift_pair_module`
职责保持:
- 普通 BLE 槽位启用 Swift Pair
- `dongle peer` 默认关闭 Swift Pair payload
这和 `nrf_desktop` 的思路一致。
## 6.4 新增 `dev_descr_module`
建议新增一个最小版 `dev_descr` 风格服务。
目标:
- 给未来的 dongle 提供外设识别信息
- 不依赖设备名做唯一识别
第一阶段最小字段:
- `caps`
- `hwid`
后续可扩展:
- `role`
- `product type`
- `firmware revision`
## 6.5 `qos_module`
第一阶段不做。
理由:
- `nrf_desktop` 已明确说明自家 dongle 不依赖外围设备 QoS
- 当前先做 `dongle peer` identity 和识别就足够
## 7. 行为模型
## 7.1 普通 BLE 模式
条件:
- `MODE_SWITCH_BLE`
- `BLE_PROFILE_POLICY_GENERAL`
行为:
- 当前 active slot 只能为 `1/2/3`
- UI 显示普通 BLE 三槽
- 允许普通 BLE 切槽和擦除
- Swift Pair 默认开启
## 7.2 2.4G / Dongle 模式
条件:
- `MODE_SWITCH_24G`
- `BLE_PROFILE_POLICY_DONGLE`
行为:
- 当前 active identity 固定为 `4`
- 当前 bond 只属于 `identity 4`
- 不允许普通 BLE 三槽逻辑影响 `identity 4`
- Swift Pair 默认关闭
- UI 应显示:
- `Dongle Searching`
- `Dongle Paired`
- `Dongle Connected`
- `Dongle Empty`
## 7.3 模式切换语义
### BLE -> 24G
1. `mode_policy_module` 发布 `BLE_PROFILE_POLICY_DONGLE`
2. `ble_bond_multi_module` 切 active identity 到 `4`
3. 提交 `PEER_OPERATION_SELECTED`
4. CAF `ble_adv` 切到 `identity 4`
5. 当前连接断开
6. 使用 `identity 4` 广播
7. dongle 重连
### 24G -> BLE
1. `mode_policy_module` 发布 `BLE_PROFILE_POLICY_GENERAL`
2. `ble_bond_multi_module` 恢复普通 BLE 当前槽位 `1/2/3`
3. 提交 `PEER_OPERATION_SELECTED`
4. CAF `ble_adv` 切回对应 identity
5. 当前连接断开
6. 使用普通 BLE 槽位广播
## 8. 状态与事件设计
## 8.1 当前已有事件
可继续复用:
- `transport_policy_event`
- `ble_peer_event`
- `ble_peer_operation_event`
- `ble_bond_multi_event`
## 8.2 建议扩展 `ble_bond_multi_event`
建议增加字段或语义:
- `active_profile`
- `GENERAL`
- `DONGLE`
- `dongle_slot_meta`
- `occupied`
- `last_peer_addr`
- `display_name`
- `current_identity`
如果不想改现有事件结构,也可以新增一个独立事件:
- `ble_dongle_state_event`
推荐字段:
- `state`
- `EMPTY`
- `SEARCHING`
- `PAIRED`
- `CONNECTED`
- `identity_id`
- `display_name`
## 8.3 UI 状态来源
主界面与设置页可以通过以下信息判断:
- 当前 `mode`
- 当前 `active_identity_id`
- `identity 4` 是否有 bond
- 当前是否有连接且该连接属于 `identity 4`
## 9. `dev_descr` 设计
## 9.1 目标
最小化模仿 `nrf_desktop dev_descr`
- 为 dongle 提供一个稳定可读的识别服务
- 避免仅靠设备名判断
## 9.2 服务内容
建议服务包含两个 characteristic
### Characteristic 1: `caps`
建议字节布局:
- bit0: `supports_llpm`
- bit1: `supports_dongle_peer`
- bit2: `is_keyboard`
第一阶段只要能读出:
- 这个设备支持 dongle peer
- 这是 keyboard 类型
### Characteristic 2: `hwid`
固定长度硬件 ID
- 用于以后让 dongle 唯一识别这把键盘
- 也可用于配置通道映射
## 9.3 权限建议
建议与 `nrf_desktop` 保持一致:
- `BT_GATT_PERM_READ_ENCRYPT`
原因:
- 避免未加密链路上暴露识别信息
## 9.4 依赖
需要:
- `CONFIG_HWINFO`
- 固件内已有或新增 `hwid_get()` 辅助逻辑
## 10. Settings 设计
继续沿用现有 namespace
- `ble_multi/current_slot`
- `ble_multi/meta/1`
- `ble_multi/meta/2`
- `ble_multi/meta/3`
- `ble_multi/meta/4`
其中 `meta/4` 现在正式用于 dongle peer。
建议 `meta/4` 字段仍保持:
- `occupied`
- `last_peer_addr`
- `display_name`
显示策略:
- 有真实名字则显示名字
- 否则显示 MAC 地址
- 无 bond 显示 `Empty`
## 11. UI 设计
## 11.1 主界面
当前主界面可新增或扩展显示:
- 当前模式 `USB / BLE / 24G`
- 如果 `24G` 模式:
- 右上角额外状态位显示:
- searching
- connected
现有 BLE LINK 状态位可以复用,但语义建议细化:
- BLE 模式下:表示普通 BLE 当前槽状态
- 24G 模式下:表示 dongle peer 状态
## 11.2 设置页
建议新增二级入口:
- `Bluetooth`
- Slot 1
- Slot 2
- Slot 3
- Erase Current
- `Dongle`
- Status
- Erase Dongle Bond
第一阶段如果不想扩菜单,至少要做到:
- 主界面显示 dongle peer 状态
- 设置页不把 `identity 4` 混入 Slot 1~3
## 12. 分阶段实施建议
## 阶段 1Dongle Slot 真正接线
内容:
- `ble_bond_multi_module` 支持 `BLE_PROFILE_POLICY_DONGLE`
- `MODE_SWITCH_24G` 时固定切到 `identity 4`
- `identity 4` 独立 bond 和独立状态
- Swift Pair 在 `identity 4` 默认关闭
交付标准:
- 24G 模式和 BLE 模式切换时 identity 正确切换
- `identity 4``1/2/3` 完全隔离
## 阶段 2UI / 状态管理
内容:
- 增加 dongle 状态显示
- 增加独立擦除 dongle bond 入口
- 不把 dongle 混入普通 BLE 三槽 UI
交付标准:
- 用户可以明确区分:
- 普通 BLE 槽位
- 2.4G / dongle peer
## 阶段 3最小 `dev_descr`
内容:
- 实现最小自定义 GATT service
- 提供 `caps + hwid`
交付标准:
- 未来 dongle 可稳定识别这把键盘
## 阶段 4后续增强非当前范围
可选项:
- QoS
- 更强的 dongle 配对约束
- 生产预绑定
- 更明确的 dongle selector/恢复流程
## 13. 风险与边界
## 13.1 “2.4G” 实际仍然是 BLE
第一阶段产品语义是 2.4G,链路实现仍是 BLE。
这没有问题,但必须在代码和文档中明确,避免后续和真正私有 2.4G 链路混淆。
## 13.2 `dev_descr` 与未来 dongle 要对齐
如果未来 dongle 端也参考 `nrf_desktop central`,那这里的 UUID 和字段应该尽量稳定,不要后面再频繁改。
## 13.3 `identity 4` 与普通 UI 必须隔离
一旦 `identity 4` 被误混入普通三槽,就会造成用户理解混乱:
- 不知道哪个是普通蓝牙
- 哪个是 2.4G
这是 UI 设计上最需要避免的问题。
## 14. 结论
本方案建议把当前键盘的“2.4G 端”实现为:
- `BLE Peripheral + 专用 Dongle identity`
- `MODE_SWITCH_24G` 时固定走 `identity 4`
- 与普通 BLE 三槽完全隔离
- 第一阶段先打通 identity / bond / UI 状态
- 第二阶段补最小 `dev_descr`
- `QoS` 暂缓
这条路径与 `nrf_desktop` 外设侧的 dongle peer 设计一致,也与当前工程已有的 `transport_policy_event` 语义完全匹配。