# 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. 分阶段实施建议 ## 阶段 1:Dongle 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` 完全隔离 ## 阶段 2:UI / 状态管理 内容: - 增加 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` 语义完全匹配。