HCI 功能规范【5. HCI data formats】(3/5)
这部分内容属于HCI data formats → IDs and Handles,主要讲的是:
HCI 中的 ID 和 Handle 是什么、有什么区别、由谁分配、用于什么范围,以及常见 Controller Handle 的编号空间规则。
这部分可以分成三层理解:
第一层:HCI 里有两类标识符:ID 和 Handle 第二层:Controller Handle 包括 Connection_Handle、Sync_Handle、Advertising_Handle、BIG_Handle 第三层:Broadcast Connection_Handle 是 BR/EDR 里的一个特殊情况一、5.3 IDs and Handles:ID 和 Handle 的基本区别
这一节首先说明:
HCI commands 和 events 中使用两类 identifiers: 1. ID 2. Handle它们都可以理解为“标识符”,也就是用一个数字代表某个对象。
但是ID 和 Handle 的作用范围不同。
关键信息 1:ID 是 Host 分配的,用于两个设备之间,并且会出现在空口 PDU 中
原文说:
IDs, assigned by the Host, are identifiers used between two peer devices and sent over the air in PDUs.意思是:
ID 由 Host 分配,用于两个 peer devices 之间,并且会通过 PDU 发到空口。
也就是说,ID 不只是本机 Host 和 Controller 内部使用,它会参与两个蓝牙设备之间的协议交互。
可以理解为:
Host 分配 ID ↓ Controller 在空口 PDU 中带上这个 ID ↓ 对端设备也能看到这个 ID ↓ 双方通过这个 ID 识别某个对象这里的 “over the air” 就是指通过蓝牙无线链路发送出去。
关键信息 2:不同类型的 ID 有不同编号空间
原文说:
Each different type of ID has a separate number space.意思是:
不同类型的 ID 有各自独立的编号空间。
也就是说:
A 类型 ID = 0x01 B 类型 ID = 0x01它们不一定冲突,因为它们属于不同 ID 类型。
可以类比为:
一班的 1 号学生 二班的 1 号学生两个都是 1 号,但因为班级不同,所以不会混淆。
关键信息 3:CIS_ID 在每个 CIG_ID 下都有独立编号空间
原文特别举例:
The CIS_ID has a separate number space for each CIG_ID.意思是:
每个 CIG_ID 下面,都有自己独立的一套 CIS_ID 编号空间。
这里涉及 LE Isochronous / LE Audio 相关概念:
CIG:Connected Isochronous Group CIS:Connected Isochronous Stream一个 CIG 中可以包含多个 CIS。
所以可以出现:
CIG_ID = 1 ├── CIS_ID = 0 └── CIS_ID = 1 CIG_ID = 2 ├── CIS_ID = 0 └── CIS_ID = 1这里两个CIS_ID = 0不冲突,因为它们属于不同的CIG_ID。
二、Handle 的含义:用于 Host 和 Controller 之间,不发到空口
原文说:
Handles, assigned by either the Host in a command or by the Controller in an event, are identifiers used between the Host and the Controller but not sent over the air.意思是:
Handle 可以由 Host 在 command 中分配,也可以由 Controller 在 event 中分配。Handle 用于 Host 和 Controller 之间,不会发送到空口。
这是 ID 和 Handle 最重要的区别。
可以总结为:
ID:设备和设备之间使用,会出现在空口 PDU 中 Handle:Host 和 Controller 之间使用,不会出现在空口 PDU 中关键信息 4:Handle 是本机 Host 和 Controller 之间的对象编号
例如 BLE 中最常见的是:
Connection_Handle当手机连接一个 BLE 外设后,Controller 会分配一个Connection_Handle,然后通过 HCI Event 告诉 Host。
之后 Host 要操作这条连接,就通过Connection_Handle指定目标连接。
例如:
Host -> Controller: HCI_Disconnect Connection_Handle = 0x000B意思是:
请断开 Connection_Handle 为 0x000B 的这条连接但是这个0x000B只是本机 Host 和 Controller 之间使用的编号。
它不是对端设备地址,也不会直接发到空口让对端设备知道。
关键信息 5:Handle 有些共享编号空间,有些有独立编号空间
原文说:
Some handles share the same number spaces and others have separate number spaces.意思是:
有些 Handle 共享同一个编号空间,有些 Handle 使用不同编号空间。
所以不能简单认为:
只要两个 Handle 数值一样,就一定冲突要看它们是不是同一种 Handle,或者是不是处在同一个 number space。
例如:
Connection_Handle = 0x0001 Advertising_Handle = 0x01它们数值看起来一样,但不一定冲突,因为它们属于不同 Handle 类型。
三、ID / Handle 分配时不能和当前对象冲突
原文说:
When a device allocates an ID or Handle for a new object ... it shall not use a handle that is currently allocated to another object in the same number space.意思是:
当设备为一个新对象分配 ID 或 Handle 时,在同一个编号空间中,不能使用已经被其他对象占用的值。
例如 Controller 已经有一条连接:
连接 A:Connection_Handle = 0x000B如果又建立一条新的 ACL 连接,就不能再分配:
连接 B:Connection_Handle = 0x000B因为这两个连接属于同一个 Connection_Handle 编号空间。
否则 Host 后续发送命令时就无法区分:
Connection_Handle = 0x000B 到底表示连接 A 还是连接 B?正确做法应该是:
连接 A:Connection_Handle = 0x000B 连接 B:Connection_Handle = 0x000C四、ID / Handle 删除后可以复用
原文说:
After a device deletes an ID or Handle ... it may reuse the ID or Handle.意思是:
当某个 ID 或 Handle 对应的对象被删除后,这个 ID 或 Handle 可以被重新使用。
例如:
10:00:00 建立连接 A,Connection_Handle = 0x000B 10:00:10 连接 A 断开,Connection_Handle = 0x000B 被释放 10:00:20 建立连接 B,Connection_Handle = 0x000B这是允许的。
所以Connection_Handle不是永久唯一的。
它只在当前对象存在期间有效。
分析 HCI 日志时要特别注意:
同一个 Connection_Handle 在不同时间段,可能代表不同连接。不能只看到相同的 Handle,就判断它一定是同一条连接。
五、5.3.1 Controller handles:常见 Controller Handle
这一节列出了几类 Controller Handle:
Connection_Handle Sync_Handle Advertising_Handle BIG_Handle它们都用于标识 Host 和 Controller 之间的 logical channel。
这里的 logical channel 可以理解为 Host 和 Controller 之间为了管理某个对象而使用的逻辑编号。
六、Connection_Handle:连接或逻辑传输的 Handle
原文说:
Connection_Handles are assigned by the Controller when a new logical transport is created or reserved...意思是:
Connection_Handle 通常由 Controller 分配。
当新的 logical transport 被创建或预留时,Controller 会分配一个Connection_Handle,然后通过相应的 HCI Event 上报给 Host。
常见事件包括:
HCI_Connection_Complete HCI_Synchronous_Connection_Complete HCI_LE_Connection_Complete HCI_LE_Enhanced_Connection_Complete HCI_LE_CIS_Request HCI_LE_Create_BIG_Complete HCI_LE_BIG_Sync_Established HCI_Command_Complete对于你当前学习 BLE 来说,最常见的是:
HCI_LE_Connection_Complete HCI_LE_Enhanced_Connection_Complete当 BLE 连接建立完成后,Controller 会通过这些 event 告诉 Host:
连接建立结果是什么 Connection_Handle 是多少 对端设备地址是什么 连接间隔是多少 连接延迟是多少 监督超时时间是多少之后 Host 再对这条连接发送 ACL Data、断开连接、更新连接参数,都需要使用这个Connection_Handle。
七、Sync_Handle:周期广播同步对象的 Handle
原文说:
Sync_Handles are assigned by the Controller when a new logical transport is created and reported to the Host in the HCI_LE_Periodic_Advertising_Sync_Established event.意思是:
Sync_Handle 由 Controller 分配,用于 Periodic Advertising Sync。
流程可以理解为:
Host 让 Controller 去同步某个周期广播 ↓ Controller 成功同步 ↓ Controller 分配 Sync_Handle ↓ 通过 HCI_LE_Periodic_Advertising_Sync_Established event 告诉 Host ↓ Host 后续通过 Sync_Handle 管理这个同步对象它主要和 BLE Extended Advertising / Periodic Advertising 有关。
如果你现在重点学习 Legacy Advertising,可以先知道它是周期广播同步对象的编号,不必深挖。
八、Advertising_Handle:扩展广播集的 Handle
原文说:
Advertising_Handles are assigned by the Host when a new advertising set is created by using the HCI_LE_Set_Extended_Advertising_Parameters command.意思是:
Advertising_Handle 由 Host 分配,用于标识一个 extended advertising set。
这个概念主要出现在 Extended Advertising 中。
Legacy Advertising 时代,一般只有一组广播配置:
LE Set Advertising Parameters LE Set Advertising Data LE Set Scan Response Data LE Set Advertising Enable这些常见 Legacy Advertising 命令通常不需要Advertising_Handle。
但是 Extended Advertising 支持多个 advertising sets,所以需要用Advertising_Handle区分不同广播集。
例如:
Advertising_Handle = 0x00:普通广播集 Advertising_Handle = 0x01:周期广播相关广播集 Advertising_Handle = 0x02:厂商自定义数据广播集之后 Host 设置扩展广播参数、扩展广播数据、扩展扫描响应数据、使能扩展广播时,都可以通过Advertising_Handle指定操作哪一组广播。
九、BIG_Handle:BIG 广播等时组的 Handle
原文说:
BIG_Handles are assigned by the Host when a new BIG is created...意思是:
BIG_Handle 由 Host 分配,用于标识一个 BIG。
BIG 是:
Broadcast Isochronous Group主要和 LE Audio 的广播音频有关。
Host 创建 BIG 时,会通过相关命令指定BIG_Handle,例如:
HCI_LE_Create_BIG HCI_LE_Create_BIG_Test LE_BIG_Create_Sync对当前 BLE 基础学习来说,BIG_Handle 可以先作为了解项。
十、Controller Handle 的编号空间规则
原文说:
All connection handles that are assigned by the Controller shall be derived from the same number space. Sync handles shall be assigned by the Controller from a separate number space. Advertising handles and BIG handles are assigned by the Host from separate number spaces.意思是:
不同 Controller Handle 的编号空间规则如下:
Connection_Handle:Controller 分配,来自同一个 Connection_Handle 编号空间 Sync_Handle:Controller 分配,但使用单独的编号空间 Advertising_Handle:Host 分配,使用单独编号空间 BIG_Handle:Host 分配,使用单独编号空间所以可以出现:
Connection_Handle = 0x0001 Sync_Handle = 0x0001 Advertising_Handle = 0x01 BIG_Handle = 0x01它们数值相同,但不一定冲突,因为它们属于不同编号空间。
真正不能重复的是:
同一个编号空间内,当前正在使用的 Handle 不能重复。例如两个当前存在的连接不能使用同一个Connection_Handle。
十一、5.3.1.1 Broadcast Connection_Handles:广播连接句柄
这一节是一个特殊内容,主要针对BR/EDR broadcast场景,不是 BLE Legacy Advertising 的核心内容。
这里一定要注意:
Broadcast Connection_Handle 不是 BLE 广播包里的 AdvA,也不是 BLE 广播地址,也不是 Advertising_Handle。它讲的是 HCI ACL Data packet 中带 Broadcast_Flag 的情况。
关键信息 1:Host 第一次发送 active Peripheral broadcast 时,要选择一个未被 Controller 使用的 Connection_Handle
原文说:
The first time the Host sends an HCI ACL Data packet with Broadcast_Flag set to 0b01 ... the value of the Connection_Handle parameter shall be a value which is not currently assigned by the Controller.意思是:
上电或 reset 后,Host 第一次发送带Broadcast_Flag = 0b01的 HCI ACL Data packet 时,里面的Connection_Handle必须选择一个当前 Controller 没有使用的值。
也就是说,这个广播用的 Connection_Handle 不能和当前已有连接冲突。
关键信息 2:BR/EDR Controller 会持续使用这个 Connection_Handle 做 broadcast,直到 reset
原文说:
The BR/EDR Controller shall then continue to use the same Connection_Handle for broadcast until a reset is made.意思是:
BR/EDR Controller 后续会继续使用这个相同的Connection_Handle做 broadcast,直到发生 reset。
并且:
Controller 不应把这个已经用于 broadcast 的 Connection_Handle 重新分配给其他连接。否则就可能出现歧义:
这个 Connection_Handle 到底表示 broadcast? 还是表示某条新的 ACL connection?关键信息 3:规范考虑了极少见的冲突场景
原文说,有些情况下 Controller 可能还没来得及解释 Host 发来的 Broadcast packet,就先发出了 Connection Complete event。
这样可能出现:
Broadcast packet 中的 Connection_Handle 和 Connection Complete event 中的新连接 Connection_Handle 相同也就是同一个 Handle 临时同时指向了 broadcast 和新连接。
规范说这种冲突要这样处理:
如果 Host 收到 Connection Complete event, 发现其中的 Connection_Handle 正好是 broadcast 正在使用的 handle, 那么 Host 不能马上给新连接发送数据。Host 要先等待:
Number Of Completed Packets event这个事件表明该Connection_Handle下已经没有 pending broadcast packets。
然后 Host 要把 broadcast 使用的Connection_Handle改成另一个当前没有被 Controller 分配的值。
之后,Connection Complete event 中的那个Connection_Handle才用于新连接。
关键信息 4:这样做是为了区分 broadcast message 和新连接
这个处理流程的目的,是让 Controller 能够区分:
Host 之前发出的 broadcast message和:
新建立的 connection即使它们一度使用了相同的Connection_Handle,也可以通过等待旧 broadcast 数据处理完、然后更换 broadcast handle 的方式,避免混淆。
可以理解为:
旧 broadcast 数据还没处理完 ↓ 新连接碰巧使用了同一个 Connection_Handle ↓ Host 先不要马上用这个 Handle 给新连接发数据 ↓ 等 Number Of Completed Packets 表明旧 broadcast 数据处理完 ↓ Host 更换 broadcast 使用的 Connection_Handle ↓ 这个 Handle 才正式归新连接使用关键信息 5:Controller 发给 Host 的 Broadcast_Flag = 01 的 ACL Data,Connection_Handle 应该填发送 broadcast 的 Central 对应 ACL connection handle
原文说:
For an HCI ACL Data packet sent from the Controller to the Host where the Broadcast_Flag is 01, the Connection_Handle parameter should contain the Connection_Handle for the ACL connection to the Central that sent the broadcast.意思是:
如果 Controller 向 Host 发送 HCI ACL Data packet,并且Broadcast_Flag = 01,那么其中的Connection_Handle应该填写发送该 broadcast 的 Central 对应的 ACL connection handle。
这仍然是 BR/EDR broadcast 语境下的规则,不要和 BLE 广播扫描结果混在一起。
关键信息 6:Connectionless Peripheral Broadcast 不分配 Connection_Handle
原文最后说:
For Connectionless Peripheral Broadcast, no Connection_Handle is assigned.意思是:
对于Connectionless Peripheral Broadcast,不分配Connection_Handle。
也就是说,不是所有 broadcast 都会有 Connection_Handle。是否有 Handle,取决于具体 broadcast 类型。
十二、这部分最重要的学习重点
如果你的目标是掌握 BLE,尤其是 BLE 的 HCI Command、HCI Event、连接、广播、扫描,那么这部分最应该抓住的是:
1. ID 和 Handle 不是一回事。 2. ID 会用于两个 peer device 之间,并可能出现在空口 PDU 中。 3. Handle 用于 Host 和 Controller 之间,不会发送到空口。 4. Connection_Handle 是最重要的 Handle,用于标识一条连接。 5. Advertising_Handle 主要用于 Extended Advertising,用来标识一个 advertising set。 6. Sync_Handle 主要用于 Periodic Advertising Sync。 7. BIG_Handle 主要用于 LE Audio / BIG。 8. 同一个编号空间内,正在使用的 Handle 不能重复。 9. 对象删除后,Handle 可以复用。 10. Broadcast Connection_Handle 主要是 BR/EDR 特殊规则,学习 BLE 时可以先了解,不必作为重点。十三、容易混淆的点
1. Connection_Handle 不是蓝牙地址
Connection_Handle只是 Host 和 Controller 之间标识某条连接的本地编号。
它不是:
Public Device Address Random Device Address Resolvable Private Address Identity Address例如:
外设地址:DC:0D:30:00:06:F6 Connection_Handle:0x000B这两个不是一类东西。
2. Advertising_Handle 不是广播地址
Advertising_Handle是 Extended Advertising 中 Host 给 advertising set 分配的编号。
它不是:
AdvA 广播设备地址 蓝牙 MAC 地址它只是用来区分多个广播集。
3. BLE Legacy Advertising 通常不用 Advertising_Handle
你之前看的这些命令:
LE Set Advertising Parameters LE Set Advertising Data LE Set Scan Response Data LE Set Advertising Enable属于 Legacy Advertising 常见命令,它们通常没有Advertising_Handle。
Advertising_Handle主要出现在:
HCI_LE_Set_Extended_Advertising_Parameters HCI_LE_Set_Extended_Advertising_Data HCI_LE_Set_Extended_Scan_Response_Data HCI_LE_Set_Extended_Advertising_Enable4. Broadcast Connection_Handle 不是 BLE 广播中的 “广播句柄”
看到Broadcast Connection_Handles这个标题,不要理解成 BLE Advertising 里面有一个广播连接句柄。
这部分讲的是 BR/EDR 的 broadcast 相关规则,和 BLE Legacy Advertising 的ADV_IND、ADV_NONCONN_IND、SCAN_REQ、SCAN_RSP不是一回事。
十四、这部分可以总结为
这部分内容讲的是HCI 中 ID 和 Handle 的概念、区别、分配规则和编号空间规则。
核心结论是:
ID: - 由 Host 分配 - 用于两个 peer devices 之间 - 会出现在空口 PDU 中 - 不同类型 ID 有各自独立编号空间 Handle: - 可由 Host 分配,也可由 Controller 分配 - 用于 Host 和 Controller 之间 - 不会发送到空口 - 不同 Handle 可能共享编号空间,也可能使用独立编号空间 - 同一编号空间内,当前使用的值不能重复 - 对象删除后,Handle 可以复用对 BLE 学习来说,最重要的是理解:
Connection_Handle 是 Host 和 Controller 之间标识某条连接的本地编号; Advertising_Handle 是 Extended Advertising 中标识某个 advertising set 的编号; Sync_Handle 是 Periodic Advertising Sync 的编号; BIG_Handle 是 Broadcast Isochronous Group 的编号; 它们都不是蓝牙设备地址,也不是永久唯一标识。所以后面看 HCI 日志时,只要看到Connection_Handle,就要把它理解成:
当前本机 Host 和 Controller 之间,用来操作某条连接的临时编号。而不是把它理解成设备地址、蓝牙 MAC,或者空口里的永久身份标识。
