一、概述
HCI (Host Controller Interface) 数据包是蓝牙通信中主机与控制器之间交换信息的基本单元。主机控制器传输层提供HCI特定信息的透明交换。这些传输机制为主机提供发送HCI命令、接收HCI事件以及向控制器发送和接收数据的能力。它提供了一种标准的接口和协议,使得蓝牙设备(如手机、计算机、耳机、音响等)能够通过主机控制器接口进行通信。
HCI数据包主要有以下几种:
①HCI Command Packet
②HCI ACL Data Packet
③HCI Synchronous Packet
④HCI Event Packet
⑤HCI ISO Data Packet
二、HCI Packet
1. HCI Command Packet(0x01)
(1)概述
HCI命令包用于从主机(Host)向控制器(Controller)发送命令。
(2)数据包格式
HCI命令包的格式如下图所示。
(3)数据包详解
下面解释下每个字段的定义:
字段名 | 长度(bit) | 定义 |
---|---|---|
Opcode(操作码) | 16 | 用于不同命令的唯一标识,由 操作码组字段(OGF)和操作码命令字段(OCF)组成,OGF占用高6bit、OCF占用剩余10bit。 |
Parameter Total Length | 8 | 所有参数的长度 |
Parameter 0 - N | 8 | 每个命令对应不同参数 |
(4)注意事项
- 特殊OGF值:① 0x3E保留供将来使用(用于规范开发目的)②0x3F为特定供应商的调试命令保留的;
(5)示例解析
例1:01 05 04 0d 06 d8 68 1c e6 78 18 cc 02 00 00 00 01
①确定包类型
通过蓝牙核心规范可以查询到,0x01表示HCI命令包
②确定指令类型:
首先opcode为0x0405,转换为二进制形式0b0000010000000101,通过查核心规范,我们能得到如下信息:
OGF为0b000001,即0x01,对应Link Control commands
OCF为0b0000000101,即0x0005,对应Create Connection command
③确定数据长度
0x0d表示指令参数为13byte,剩余数据正好满足。
④解析数据
06 d8 68 1c e6 78 18 cc 02 00 00 00 01
参数 | 长度(byte) | 解析 |
---|---|---|
BD_ADDR | 6 | 设备地址为78:E6:1C:68:D8:06 |
Packet_Type | 2 | 表示支持的包类型,每个bit对应1种类型,0xcc18可以理解为支持多种数据包类型 |
Page_Scan_Repetition_Mode | 1 | 设置Page Scan重复模式,0x02对应模式为R2,表示重复扫描2次。 |
Reserved | 1 | 预留 |
Clock_Offset | 2 | 指定本地时钟与远端时钟的偏移值,具体查看核心规范。 |
Allow_Role_Switch | 1 | 0x01表示本地设备在建立连接时,允许来自远端设备的主从切换请求 |
⑤总结
简单的来讲,这是一条由设备地址为78:E6:1C:68:D8:06的远端设备发起的建立连接的指令。
2. HCI ACL Data Packet(0x02)
(1)概述
HCI ACL(Asynchronous Connection-Link)数据包用于在蓝牙主机(Host)与控制器(Controller)之间传输异步数据,例如文件传输、传感器数据等非实时性业务。
具有两种不同的刷新策略:Automatically-Flushable(可自动刷新)、Non-Automatically-Flushable(不可自动刷新)。
通俗来讲,上层协议的数据(L2CAP、SDP、RFCOMM、AVDTP、AVCTP、HFP、AT、A2DP、AVRCP、PBAP、MAP、BNEP、HID等)都是透过这个packets传的,数据包是指主机和控制器之间传输的应用数据,控制器接收来自主机的数据包,将其传给对端设备,对端设备收到数据之后,将其从控制器发往主机。
(2)数据包格式
HCI ACL数据包的格式如图5.2所示。
(3)数据包详解
字段名 | 长度(bits) | 定义 | 详细 |
---|---|---|---|
Handle | 12 | 连接句柄,用于通过控制器传输数据包或数据段。 | 有三种类型的句柄用于标识主机和控制器之间的逻辑通道: ①Connection Handles:在主机和主控制器之间传输数据包或数据段。 ②Logical Link Handles:在主机和AMP控制器之间传输数据包。 ③Physical Link Handles |
PB_Flag | 2 | 数据边界标志(Packet Boundary Flag),表示当前数据包是一个完整数据包的开头片段或中间片段。 | 各取值含义请查看核心规范Vol4→Part E→5.4.2 |
BC_Flag | 2 | 广播标志(Broadcast Flag),表示当前数据包的广播类型 | 取值0b01仅允许在以下两种场景中使用:
处于Sniff(嗅探)模式的从设备(Peripheral)仅在广播数据包恰好在其实时监听嗅探时隙(Sniff Slot)期间发送时,才会接收到该广播数据包。 |
Data Total Length | 16 | 有效数据长度 | |
Data | Data Total Length | 有效数据 |
(4)示例解析
例2:02 82 20 13 00 0f 00 43 00 9b ef 17 0d 0a 2b 42 43 53 3a 20 32 0d 0a 27
①确定包类型
通过蓝牙核心规范可以查询到,0x02表示HCI ACL数据包
②确定参数
首先参数段为0x2082,转换为二进制形式0b0010000010000010,:
- Handle为0b000010000010,即0x0082;
- PB_Flag为0b10,表示自动刷新的数据包的开始,即 L2CAP PDU 的开始部分;
- BC_Flag为0b00,表示是点对点通信,并非广播数据包。
③确定数据长度
0x0013表示ACL有效数据长度为19byte。
④总结
简单来说
3. HCI Synchronous Packet(0x03)
(1)概述
HCI同步数据包用于在主机和控制器之间交换同步数据(SCO和eSCO)。SCO (Synchronous Connection-Oriented) 和 eSCO (Extended Synchronous Connection-Oriented) 是蓝牙中的两种同步连接模式,专门用于音频和实时数据传输,它们通常用于语音传输、音频流以及其他低延迟、稳定的数据流。
(2)数据包格式
HCI同步数据包的格式如图5.3所示,前3字节为包头。
(3)数据包详解
(a) 数据包状态标志位(Packet_Status_Flag)
主机(Host)行为规则:
主机必须将
Packet_Status_Flag
设置为0b00
。
控制器(Controller)行为规则:
若同步连接创建时 Erroneous_Data_Reporting
参数设为禁用(Disabled):
控制器必须将
Packet_Status_Flag
设为0b00
;是否在未收到有效(e)SCO数据包时提供数据未作规定(实现相关)。
若同步连接创建时 Erroneous_Data_Reporting
参数设为启用(Enabled):
控制器必须根据下表设置
Packet_Status_Flag
:
值 | 参数描述 |
---|---|
0b00 | 正确接收的数据:有效载荷数据属于基带(Baseband)标记为“良好数据”(good data)的已接收eSCO或SCO数据包。 |
0b01 | 可能无效的数据:在对应HCI同步数据包的eSCO时间间隔内,至少有一个eSCO数据包被基带标记为“可能存在错误的数据”(data with possible errors),其余数据包均标记为“良好数据”。 |
0b10 | 未接收到数据:在对应HCI同步数据包的(e)SCO时间间隔内,基带将所有接收数据标记为“丢失数据”(lost data),此时有效载荷数据八位组应全置为0。 |
0b11 | 数据部分丢失:在对应HCI同步数据包的(e)SCO时间间隔内,并非所有(但至少一个)(e)SCO数据包被基带标记为“丢失数据”。对于缺失的(e)SCO数据包,其对应的有效载荷数据八位组应置为0。 |
(4)注意事项
某些HCI传输层(HCI transports)和/或控制器实现(Controller implementations)会将HCI同步数据包(HCI Synchronous Data Packet)与(e)SCO基带数据包(Baseband Packet)严格对齐,以便通过 Packet_Status_Flag
字段明确标记数据完整性。
对于未保持此对齐关系的HCI传输层或控制器实现,Packet_Status_Flag
中的信息可能存在歧义(无法准确反映实际数据状态)。
(5)示例解析
暂未接触过相关数据,后续补充完善。
4. HCI Event Packet(0x04)
(1)概述
HCI事件包(Event Packet)用于蓝牙控制器(Controller)主动向主机(Host)通知事件,例如连接状态变化、指令执行结果、错误告警等。
(2)数据包格式
HCI事件数据包的格式如图5.4所示,包头为前2个字节。
(3)数据包详解
8bits | 8bits | Parameter_total_Length |
Event_code | Parameter_total_Length | Event_Parameter 0 - N |
(a) Event_Code(事件码)
每个事件被分配1个字节的事件代码,用于唯一标识不同的事件。详细的事件码可以在vol4→PartE→7.7中进行查看,如下图所示。
(4)注意事项
数据长度限制
主机需支持最大255字节的参数数据(不含包头)。
保留字段
0xFE
:保留用于蓝牙规范未来扩展,主机应兼容但暂不处理。0xFF
:保留用于厂商自定义调试事件(如芯片内部状态日志),解析逻辑由厂商定义。
LE特殊事件规则
统一事件码 :
0x3E
(LE Meta Event)。(参考vol4→PartE→7.7.65)首个参数为子事件码(Subevent Code),用于区分具体事件类型(如
0x01
表示LE Connection Complete
)。禁止复用保留码:LE子事件码不得使用
0xFE
或0xFF
。
(5)示例解析
例5:04 04 0a 7b af 28 00 22 22 0c 02 5a 01
①确定包类型
通过蓝牙核心规范可以查询到,0x04表示HCI事件包
②确定事件类型
Event_code为0x04,通过查看核心规范vol4→PartE→7.7.4,可确定事件类型为Connection Request event,如下图所示。
③确定数据长度
0x0a表示指令参数为10byte。
④解析事件参数
参数 | 长度(byte) | 解析 |
---|---|---|
BD_ADDR | 6 | 设备地址为22:22:00:28:AF:7B |
Class_Of_Device | 3 | 设备类型,0x5a020c,通过网上查询标识为手机/智能手机” |
Link_Type | 1 | 连接类型,0x01表示ACL连接请求 |
⑤总结
简单来说,这是由设备地址为“22:22:00:28:AF:7B”的“手机/智能手机”发起的ACL连接请求事件。
5. HCI ISO Data Packet(0x05)
(1)概述
HCI 等时数据包(Isochronous)用于在蓝牙主机(Host)与控制器(Controller)之间传输等时数据流(如LE Audio音频流),支持低延迟、高同步性的数据传输。
(2)数据包格式
HCI ISO数据包的格式如图5.5所示,包头为前4字节。
(3)数据包详解
字段 | 长度(bits) |
定义 |
---|---|---|
Connection_Handle | 12 | 连接句柄 |
PB_Flag | 2 | |
TS_Flag | 1 | 表示数据包中是否包含Time_Stamp字段。0表示不包含,1表示包含。 |
RFU | 1 | 预留 |
Data_Total_Length | 14 | |
RFU | 2 | 预留 |
Time_Stamp | 32 | 时间戳,单位为μs |
Packet_Sequence_Number | 16 | SDU序列号 |
ISO_SDU_Length | 12 | SDU数据长度 |
RFU | 2 | 预留 |
Packet_Status_Flag | 2 | Packet_Status_Flag字段指示控制器通过ISO物理信道接收的数据包的状态。Packet_Status_Flag字段仅在由控制器发送的HCI ISO数据包中有效,并保留用于将来由主机发送的数据包 |
ISO_SDU_Fragment | ISO_SDU_Fragment字段应包含isoclonal数据(SDU或SDU的片段)。该字段可以为空。当从控制器到主机的数据包中Packet_Status_Flag设置为0b10时,没有数据,PB_Flag应设置为0b10,ISO_SDU_Length应设置为零。 |
(4)注意事项
缓冲区管理
若主机发送的SDU长度超过控制器缓冲区容量,控制器将不允许向做主机发送SDU,直到满足以下条件之一:
所有分片(PDU)均已接收完成。
分片传输超时(超过最后接收机会)。
分片独立
HCI层的SDU分片与ISOAL(ISO Adaptation Layer)的分片逻辑无关。
(5)示例解析
暂未遇到相关数据,后续补充完善。