13 协议栈能力

对于不同的软件包、不同的芯片系列,协议栈能力不同,汇总65于表 13.1,表 13.2 和 表 13.3

表 13.1: {typical, extension, exp} 软件包协议栈能力
系列 广播集数目 连接数目 白名单容量 CTE 最大 MTU
ING9188X \(8\) \(8\) \(16\) \(\checkmark\) \(247\)
ING9187X \(8\) \(8\) \(16\) \(247\)
ING9168X \(5\) \(5\) \(8\) \(\checkmark\) \(247\)
表 13.2: {mass_conn} 软件包协议栈能力
系列 广播集数目 连接数目 白名单容量 CTE 最大 MTU
ING9188X \(8\) \(26\) \(24\) \(\checkmark\) \(247\)
ING9187X \(8\) \(26\) \(24\) \(247\)
ING9168X \(5\) \(10\) \(10\) \(\checkmark\) \(247\)
表 13.3: {mini} 软件包协议栈能力
系列 广播集数目 连接数目 白名单容量 CTE 最大 MTU
ING9188X \(1\) \(1\) \(4\) \(\checkmark\) \(247\)
ING9187X \(1\) \(1\) \(4\) \(247\)
ING9168X \(1\) \(1\) \(4\) \(\checkmark\) \(247\)

通过 ll_get_capabilitiesbtstack_get_capabilities 可分别获取链路层和 Host 的协议栈能力66

13.1 “非标”扩展

软件包 extensionexp 包含一系列“非标”扩展。这些扩展多为放松参数限制,可供开发者测试、对比。 使用这些“非标”扩展将带来兼容性问题,故需谨慎,并遵循相关管理规定。

以下扩展功能各型号芯片皆可支持,具体表现依赖于芯片本身的处理能力:

  1. 允许广播最小间隔小于 \(20ms\),最小间隔取决于数据包空口时长;

  2. 允许连接间隔小于 \(7.5ms\),最小间隔取决于时间单位(默认 \(1.25ms\))、芯片处理能力及数据包空口时长;

  3. 自定义连接间隔的时间单位;

    void ll_set_conn_interval_unit(
      uint16_t unit);   // 自定义的时间单位(微秒)
  4. 在扩展广播上附着 CTE67

    int ll_attach_cte_to_adv_set(
      uint8_t adv_hdl,  // 广播集句柄
      uint8_t cte_type, // CTE 类型(0 为 AoA)
      uint8_t cte_len,  // CTE 长度
      // 用于 AoD 发送的天线切换模板的长度
      uint8_t switching_pattern_len,
      // 用于 AoD 发送的天线切换模板
      const uint8_t *switching_pattern);
  5. 锁频68

    // 锁频
    void ll_lock_frequency(
      int freq_mhz);    // 频点(单位:MHz)
    
    // 解锁
    void ll_unlock_frequency(void);
  6. Raw Packet;

    详见 Controller API Reference。

以下扩展功能不适用于 ING918 芯片家族:

  1. 允许传统广播数据长度超过 \(31\) 字节,最大 \(249\) 字节;

  2. 自定义数据白化初值;

    void ll_override_whitening_init_value(
      uint8_t override, // 是否启用
      uint8_t value);   // 自定义的初值
  3. 自定义广播数据包 PDU 类型;

    void ll_allow_nonstandard_adv_type(
      uint8_t allowed,  // 是否允许
      uint8_t type);    // 自定义的PDU 类型
  4. 自定义 CTE 比特。

    void ll_set_cte_bit(
      uint8_t bit);     // CTE 比特(默认为 1)

  1. https://www.bluetooth.com/↩︎

  2. https://ingchips.github.io/application-notes/an_aoa/index.html↩︎

  3. 如无特殊说明,本文档中的 App 皆指运行在芯片上的蓝牙程序。↩︎

  4. 指示服务器端主动报告特征的值。↩︎

  5. https://www.bluetooth.com/16-bit-uuids-for-sdos/↩︎

  6. 私有事件(如 HCI_SUBEVENT_LE_VENDOR_PRO_CONNECTIONLESS_IQ_REPORT)除外。↩︎

  7. Core Specification Supplement, Part B, Common Profile and Service Error Codes↩︎

  8. 更准确地说,只是把一条 HCI 消息放入消息队列。↩︎

  9. https://ingchips.github.io/blog/2021-01-25-zig-async/↩︎

  10. 地址改变后,曾与之配对的设备无法自动重连。↩︎

  11. 参照蓝牙核心规范。↩︎

  12. ING918 芯片家族不支持此特性。↩︎

  13. 称为一个 PDU 队列(train)。↩︎

  14. AuxPtr 里的时间偏移略有不同。↩︎

  15. 将原始编号再映射到当前的信道集合得到实际的信道号。↩︎

  16. Periodic Advertising Sync Transfer。↩︎

  17. PAwR 每个子事件、每个响应都只包含一个数据包,不支持 PDU 队列。↩︎

  18. https://github.com/ingchips/ING918XX_SDK_SOURCE/blob/75cbf9928711c39e0b234ae11796bc1696111998/bundles/typical/inc/platform_api.h#L265↩︎

  19. 广播间隔小于 \(3.75ms\)↩︎

  20. 在不引起混淆的前提下,本手册混用“广播”、“广播集”这两个名词。↩︎

  21. 请参阅 SDK 用户手册。↩︎

  22. 关闭之后,其它设备无法再与该周期广播建立同步。↩︎

  23. 后两种策略在规范中称为 Extended filter policy。ING916 和 ING918 不支持后两种策略。↩︎

  24. 即周期性地接收周期广播。↩︎

  25. 需要连接多个设备,使用白名单方式效率更高。↩︎

  26. 参考 《Controller API Reference》。↩︎

  27. 对于 v8.2 以下版本,这个函数仅用于主角色, 从角色需要使用 l2cap_request_connection_parameter_update 请求更新。↩︎

  28. 调用之前建议先检查对方是否支持此特性。此 API 无论主从角色都可以调用。↩︎

  29. 在不引起混淆的前提下,本手册混用 ATT 服务器、GATT 服务器,代码里也用 att_server 代指 gatt_server↩︎

  30. 事实上,这几件事已由 Wizard 工具代劳。↩︎

  31. 在手册、工具、代码的不同位置可能使用了不同的名词,如 Profile 数据库、GATT 数据库、GATT 数据等。↩︎

  32. 协议栈里称为“会话”,规范里称为“队列”。↩︎

  33. 仅适用于有响应的写入,无响应的写入无效。↩︎

  34. 解决方法参考 L2CAP 传输队列↩︎

  35. 解决方法参考 L2CAP 传输队列↩︎

  36. 以及转发过来的 L2CAP_EVENT_CAN_SEND_NOW 事件。↩︎

  37. SDK v8.4.23 及以上版本。↩︎

  38. SDK v8.4.23 及以上版本。↩︎

  39. 5.1 及更低版本里称为 LE_PSM↩︎

  40. 整个 SDU 只占用一个 K 帧↩︎

  41. 整个 SDU 占用多个 K 帧 这个事件对应其中一个 K 帧↩︎

  42. 指进入链路层发送队列。↩︎

  43. 当信用点用完或者链路层队列已满时,会出现此情况↩︎

  44. att_server_request_can_send_now_event 是基于 att_dispatch_server_request_can_send_now_event 实现的。↩︎

  45. 生成时需要保证具有足够高的熵。↩︎

  46. IRK、DHK、LTK、CSRK 等的具体含义及作用请参考蓝牙核心规范。↩︎

  47. 以及给予用户必要的提示的能力。↩︎

  48. 没必要过于频繁地更新地址。尤其是对于可解析地址,每更新一次,就意味着泄露了一点关于 IRK 的消息。↩︎

  49. 注意:当该广播是可连接的并且正在广播时,不允许修改地址。↩︎

  50. https://www.bluetooth.com/learn-about-bluetooth/key-attributes/bluetooth-security/method-vulnerability/↩︎

  51. dx.doi.org/10.6028/NIST.FIPS.186-4↩︎

  52. BLUETOOTH CORE SPECIFICATION Version 5.4 | Vol 3, Part H, 2.3.6↩︎

  53. 参考《Application Note: Direction Finding Solution》。↩︎

  54. 参考《Controller API Reference》。↩︎

  55. 参考《Controller API Reference》。↩︎

  56. 为防止与 Media Access Controller 混淆,蓝牙规范使用 MIC 代替 MAC。↩︎

  57. https://ingchips.github.io/blog/2021-06-02-sdk-6/#%E5%85%BC%E5%AE%B9%E6%80%A7↩︎

  58. 只能在 app_main 就调用。↩︎

  59. 对于 v8.4.12 或更旧的版本,所能存储的设备个数等于软件包所支持的连接数目。↩︎

  60. 为多个连接创建多个同步执行器的优势在于多个 GATT 客户端上的会话可以并发。↩︎

  61. 由规范规定。↩︎

  62. https://www.bluetooth.com/specifications/assigned-numbers/↩︎

  63. 这个函数的原始版本不是严格意义上的异步操作。考虑到在一个同步执行体内可能既会用到有响应的写入,也会用到无响应的写入,加入这个 API 可以带来便利。↩︎

  64. 可以使用 btstack_push_user_runnable↩︎

  65. 依据 SDK v8.3.7。ING916XX 协议栈能力可能发生变化。↩︎

  66. 限 SDK v8.4.13 或更高版本。↩︎

  67. 仅限支持 CTE 的芯片型号。↩︎

  68. 将所有射频行为固定在一个指定的信道。↩︎


  1. 依据 SDK v8.3.7。ING916XX 协议栈能力可能发生变化。↩︎

  2. 限 SDK v8.4.13 或更高版本。↩︎

  3. 仅限支持 CTE 的芯片型号。↩︎

  4. 将所有射频行为固定在一个指定的信道。↩︎