3. 蓝牙核心规范与互操作测试依据

做 Nordic nRF 蓝牙互操作测试,第一步不是打开 nRF Connect 或抓包器,而是先弄清楚“依据是什么”。蓝牙核心规范(Bluetooth Core Specification)把协议栈拆成若干层,每一层都同时定义了强制要求(Mandatory,M)和可选特性(Optional,O)。互操作测试的本质,就是验证被测设备(DUT)在某一层是否满足它“声称支持”的那部分要求,并且在与不同厂商设备交互时行为一致。规范里没有“大概支持”这种说法:一个特性要么声明支持并必须按规范行为,要么声明不支持并必须正确拒绝或忽略。

从测试视角看,核心规范可以分成两条主线。第一条是“连接与链路”主线:LL(Link Layer)、L2CAP、SMP,负责设备如何被发现、建立链路、加密和分配信道。第二条是“数据与服务”主线:ATT、GATT、GAP,负责数据如何组织、读写、通知,以及设备如何广播和连接。互操作问题往往不是单层出错,而是跨层传导——例如 LL 的连接参数更新被拒绝,会表现为 GATT 操作超时;SMP 配对失败,会让需要加密的特征读写直接返回错误。

蓝牙核心规范分层与互操作测试关注点 Host(主机) GAP 广播/扫描/发起连接、角色、可发现模式 M:LE 广播格式、连接建立流程 GATT 服务/特征/描述符组织、发现、读写、通知 M:Service Discovery、Read/Write 基本流程 ATT 属性句柄、MTU 协商、PDU 请求/响应 M:ATT_MTU 默认 23、错误响应码 SMP 配对、密钥分发、加密启动、身份解析 M:Pairing Request/Response、加密流程 L2CAP 信道复用、信令、分段重组、固定/动态信道 M:LE 信令信道、ATT 固定信道 CID=0x0004 Controller(控制器) LL(Link Layer) 广播/扫描/连接状态机、信道选择、跳频 M:状态机、连接参数更新、加密启动 HCI 主机与控制器命令/事件接口 M:命令完成事件、LE 元事件 PHY / 射频 1M / 2M / Coded PHY、发射功率、灵敏度 M:1M PHY;O:2M、Coded ISO / LE Audio(可选) 等时信道、CIS/BIS、LC3 编解码 O:需声明并验证互操作 测试关注 连接参数、加密、MTU、广播兼容性 跨厂商交互一致性 HCI HCI HCI HCI HCI

先看 GAP。GAP 定义了四种角色:Broadcaster、Observer、Peripheral、Central。互操作测试中最常见的争议点是广播数据格式和连接参数。规范强制要求 LE 广播包中的 AD 结构必须符合“长度+类型+数据”的格式,且 Flags AD 类型(0x01)在可连接广播中必须存在。可选特性包括扩展广播(Extended Advertising)、周期性广播(Periodic Advertising)和 LE 功率控制。如果 DUT 声明支持扩展广播,就必须能正确解析和发送扩展广播头,否则与只支持传统广播的设备交互时会出现扫描不到的问题。

GATT 和 ATT 是互操作问题最集中的地方。ATT 是底层协议,规定了属性句柄、操作码和错误码;GATT 在其上定义了服务发现、特征读写和通知/指示的语义。强制要求包括:ATT_MTU 默认至少为 23 字节;Exchange MTU Request 必须能被正确响应;Read By Group Type 和 Find Information 请求必须返回规范定义的响应格式。可选特性包括长属性读/写(Prepare Write + Execute Write)、通知与指示、以及服务变更特征(Service Changed)。测试时经常遇到的一个互操作问题是:客户端发送 Exchange MTU Request 请求 247 字节,服务端返回 23 字节,此时客户端必须按 23 字节继续工作,而不是直接断开。这个“降级兼容”行为就是强制要求的一部分。

L2CAP 在 LE 上主要承担信道复用和信令。强制要求是 LE 信令信道 CID=0x0005 必须支持,ATT 固定信道 CID=0x0004 必须存在。可选特性包括 LE 信用基于流控模式(LE Credit Based Flow Control)和增强信用基于流控模式(Enhanced Credit Based Flow Control),后者常用于 CoC(Connection-oriented Channels)。互操作测试中,如果 DUT 声明支持 CoC,就必须正确实现信令命令的拒绝和参数协商,否则与不同厂商的 CoC 实现对接时会卡在连接建立阶段。

SMP 负责配对和密钥分发。强制要求包括 Pairing Request/Response 的交换、加密启动流程、以及密钥分发格式。可选特性包括 LE Secure Connections、MITM 保护、以及密钥长度协商。一个典型的互操作场景是:Central 发起配对请求,要求 MITM 保护,Peripheral 只支持 Just Works。此时 Peripheral 必须返回正确的 Pairing Response,将 MITM 标志置为 0,而不是直接拒绝。如果 DUT 错误地拒绝了配对请求,就会导致后续需要加密的 GATT 操作全部失败。

LL 是链路层,直接决定连接能否建立和维持。强制要求包括广播、扫描、发起连接的状态机行为,以及连接参数更新流程。可选特性包括 LE 2M PHY、LE Coded PHY、周期性广播同步传输等。互操作测试中,连接参数更新是最容易出问题的环节:Central 发送 Connection Parameter Update Request,Peripheral 可以接受或拒绝。如果拒绝,必须发送带有正确原因码的 Response,而不是静默丢弃。静默丢弃会导致 Central 一直等待,最终连接超时断开。

测试依据的落地方法:在 nRF Connect SDK 中,可以通过 bt_gatt_service_register() 注册服务,通过 bt_le_adv_start() 启动广播。测试时先用 nRF Connect for Mobile 作为 Central,观察服务发现是否完整、MTU 协商结果、通知是否按预期到达。再用另一台不同厂商的手机作为 Central 重复同样操作,对比行为差异。差异点就是互操作测试需要重点记录和判定的对象。

把上述规范要求整理成一张可执行的检查表,比泛泛阅读规范更有效。下面给出一个针对 GAP/GATT/ATT/SMP/LL 的互操作测试检查表示例,字段和判定依据均来自核心规范的强制/可选划分。

协议层 测试项 强制/可选 预期行为 判定依据
GAP 可连接广播包含 Flags AD 强制 广播包中存在 0x01 类型 AD 结构 扫描响应可被不同厂商 Central 解析
GAP 扩展广播 可选 声明支持时能正确收发扩展广播头 与只支持传统广播的设备交互不崩溃
ATT MTU 协商降级 强制 请求 247 返回 23 时按 23 继续 后续读写不因 MTU 变小而失败
GATT 服务发现完整性 强制 所有 Primary Service 可被 Read By Group Type 发现 不同 Central 发现结果一致
SMP MITM 降级 强制 不支持 MITM 时返回 MITM=0 的 Pairing Response 配对流程不中断,加密可继续
LL 连接参数更新拒绝 强制 拒绝时发送带原因码的 Response Central 不因等待超时而断开
L2CAP CoC 信令拒绝 可选 声明支持时正确返回拒绝原因 与不同厂商 CoC 实现对接不卡死

需要特别强调的是,规范中的“可选”不等于“可以不做”。一旦设备在广播、服务声明或配对请求中声称支持某个可选特性,它就必须按照规范完整实现该特性的行为。互操作测试的判定逻辑是:先确认 DUT 声明了什么,再验证它是否做到了声明的内容,最后验证它在与不同厂商设备交互时是否保持一致。这三步缺一不可。

在实际项目中,建议把上述检查表与 nRF Connect SDK 的日志结合使用。打开 CONFIG_BT_DEBUG_LOG=y 和 CONFIG_BT_ATT_DEBUG=y,可以在串口日志中看到 ATT PDU 的收发方向、操作码和错误码。例如看到 ATT_OP_ERROR_RSP 时,对照规范中的错误码表判断是“属性未找到”还是“权限不足”。日志中的 HCI 事件则能反映 LL 层的连接参数更新是否被接受。把日志、抓包和检查表三者对照,才能把“规范要求”真正落到“互操作判定”上。