概念
HCI 层是在蓝牙协议栈中的主机 (Host) 和控制器 (Controller) 之间传输命令、事件和数据的标准接口。它定义了一套标准化的命令、事件与数据传输机制,使得上层应用可以通过统一接口控制蓝牙硬件,而无需关心芯片厂商的底层实现细节。
在 Linux 蓝牙协议栈中,HCI 层通过 AF_BLUETOOTH 类型的 raw socket 与内核蓝牙子系统交互。用户空间程序通过该 socket 发送 HCI 命令(如设置广播参数、发起连接),并接收来自内核的 HCI 事件(如连接完成、断开通知)。收到事件后,HCI 层会进行解包和解析,并将结果交给上层协议栈或应用程序处理。
架构层次
+------------------+ ← Application
| GATT / ATT |
+------------------+ ← Host
| L2CAP |
+------------------+
| HCI |
+------------------+ ← Controller
| Link Layer (LL) |
| Physical Layer |
+------------------+
数据包格式
HCI包有三种类型
- 命令包 (Command Packet)
- 事件包 (Event Packet)
- 异步数据包 (Asynchronous Data Packet)
+--------------------------+----------------------------------+
| Packet Type Indicator (1)| Packet Data |
| (Byte) | (Variable) |
+--------------------------+----------------------------------+
Packet Type Indicator (包类型指示符):
- 0x01: HCI 命令包 (HCI Command Packet)
- 0x02: HCI 异步数据包 (HCI ACL Data Packet)
- 0x03: HCI 同步数据包 (HCI Synchronous Data Packet) - 在 BLE 中不使用
- 0x04: HCI 事件包 (HCI Event Packet)
HCI 命令包 (HCI Command Packet)
由主机发送给控制器,用于请求执行特定操作
┌─────────────┬───────────────┬──────────────┬─────────────────────┐
│ Packet Type │ Opcode (2B) │ Param Length │ Parameters (N Bytes)│
│ 0x01 │ │ 1 Byte │ │
└─────────────┴───────────────┴──────────────┴─────────────────────┘
Length表示后续 Parameters 区域的长度,不包括 Packet Type、Opcode、本身
Opcode分为两部分
+-----------------+-----------------+
| OGF (6) | OCF (10) |
| (Bits) | (Bits) |
+-----------------+-----------------+`
- OGF:6位,定义命令的组
- OCF:10位,定义组内的具体命令
HCI 命令组 (OGF - Opcode Group Field)
| OGF (十六进制) | OGF (二进制) | 命令组名称 (Group Name) | 描述 |
|---|---|---|---|
0x01 | 000001 | Link Control Commands | 链路控制命令:管理设备间的连接、认证和加密。 |
0x02 | 000010 | Link Policy Commands | 链路策略命令:管理电源模式和角色切换。 |
0x03 | 000011 | Controller & Baseband Commands | 控制器与基带命令:控制蓝牙控制器、读取状态和版本信息。 |
0x04 | 000100 | Informational Parameters | 信息参数命令:读取控制器的静态信息,如蓝牙地址。 |
0x05 | 000101 | Status Parameters | 状态参数命令:读取动态变化的状态信息,如RSSI。 |
0x06 | 000110 | Testing Commands | 测试命令:用于设备在生产和认证期间的测试。 |
0x08 | 001000 | LE Controller Commands | 低功耗 (LE) 控制器命令:所有BLE专用功能的核心命令。 |
0x3F | 111111 | Vendor Specific Commands | 厂商自定义命令:供芯片制造商实现其私有功能。 |
HCI 具体命令 (OCF - Opcode Command Field)
OGF = 0x01: Link Control Commands (链路控制命令)
| OCF (十六进制) | 命令名称 | 功能描述 |
|---|---|---|
0x0001 | HCI_Inquiry | 搜索周边的BR/EDR设备。 |
0x0002 | HCI_Inquiry_Cancel | 取消当前的Inquiry过程。 |
0x0005 | HCI_Create_Connection | 创建一个到BR/EDR设备的ACL连接。 |
0x0006 | HCI_Disconnect | 断开一个已存在的连接。 |
0x0009 | HCI_Accept_Connection_Request | 接受一个传入的连接请求。 |
0x000A | HCI_Reject_Connection_Request | 拒绝一个传入的连接请求。 |
0x0011 | HCI_Authentication_Requested | 启动对指定连接的认证(配对)过程。 |
0x0019 | HCI_Set_Connection_Encryption | 对指定的连接启用或禁用链路层加密。 |
0x001D | HCI_Remote_Name_Request | 请求获取远端设备的名称。 |
OGF = 0x03: Controller & Baseband Commands (控制器与基带命令)
| OCF (十六进制) | 命令名称 | 功能描述 |
|---|---|---|
0x0001 | HCI_Set_Event_Mask | 设置控制器应向主机上报哪些事件(不含LE事件)。 |
0x0003 | HCI_Reset | (常用) 复位控制器和HCI层,所有状态恢复到默认值。 |
0x001A | HCI_Read_Local_Name | 读取本地设备的名称。 |
0x001C | HCI_Write_Local_Name | 设置本地设备的名称。 |
0x0033 | HCI_Write_Class_of_Device | 设置本设备的设备类型(Class of Device, CoD)。 |
0x003A | HCI_Host_Buffer_Size | (主机->控制器)通知控制器主机的缓冲区大小。 |
0x003B | HCI_Host_Number_Of_Completed_Packets | (主机->控制器)通知控制器主机已处理完多少个数据包。 |
0x0063 | HCI_Set_Event_Mask_Page_2 | 设置事件掩码的第二页。 |
| 0x006D | HCI_Write_LE_Host_Support | 开启/关闭 LE 支持标志 |
HCI_Set_Event_Mask
与LE_Set_Event_Mask一样,它的参数也是一个64位的位掩码。每一位对应一个或多个经典蓝牙的HCI事件
些最基础的HCI事件是永远不能被这个掩码屏蔽掉的
- Command Complete Event (0x0E)
- Command Status Event (0x0F)
- Hardware Error Event (0x10)
- Number Of Completed Packets Event (0x13) (为了保证流控正常工作)
OGF = 0x04: Informational Parameters (信息参数命令)
| OCF (十六进制) | 命令名称 | 功能描述 | 返回 |
|---|---|---|---|
0x0001 | HCI_Read_Local_Version_Information | (常用) 读取本地控制器的版本信息,如HCI版本、LMP版本。 | **** |
0x0002 | HCI_Read_Local_Supported_Commands | 读取控制器支持的所有HCI命令。 | |
0x0003 | HCI_Read_Local_Supported_Features | 读取控制器支持的本地特性(如加密、跳频等)。 | |
0x0005 | HCI_Read_Buffer_Size | 读取控制器的ACL和SCO数据包缓冲区大小。 | + ACL_Data_Packet_Length ACL 数据包最大长度(单位:字节) + SCO_Data_Packet_Length:SCO 数据包最大长度 + Total_Num_ACL_Data_Packets:ACL 数据包缓冲区数量 + Total_Num_SCO_Data_Packets:SCO 数据包缓冲区数量 |
0x0009 | HCI_Read_BD_ADDR | (常用) 读取本设备的蓝牙地址(BD_ADDR)。 | **** |
OGF = 0x05: Status Parameters (状态参数命令)
| OCF (十六进制) | 命令名称 | 功能描述 |
|---|---|---|
0x0003 | HCI_Read_Link_Quality | 读取指定连接的链路质量。 |
0x0005 | HCI_Read_RSSI | 读取指定连接句柄的RSSI(接收信号强度指示)。 |
OGF = 0x08: LE Controller Commands (低功耗控制器命令)
1. 通用与设置 (General & Setup)
| OCF (Hex) | 命令名称 (Command Name) | 功能描述 (Description) | 返回 |
|---|---|---|---|
0x0001 | LE_Set_Event_Mask | (核心) 设置控制器需要上报的LE相关事件。 | **** |
0x0002 | LE_Read_Buffer_Size | 读取LE数据包的缓冲区大小和总数。 | + Status 1B + LE_ACL_Data_Packet_Length 2B 描述单个 LE ACL 包(不含 HCI 4B ACL 头)的最大数据负载长度 + Total_Num_LE_ACL_Data_Packets 表示 Controller 内部 LE 接收队列容量(以包为单位) |
0x0003 | LE_Read_Local_Supported_Features | 读取控制器支持的LE特性。 | |
0x0005 | LE_Set_Random_Address | 设置控制器要使用的静态随机地址或非可解析私有地址。 |
LE_Set_Event_Mask 事件掩码位
这个命令只有一个参数:一个64位的位掩码(bitmask)。这个掩码的每一位都对应着一个特定的 LE Meta Event 的子事件。
要让 LE 事件真正上报,还需要在 主事件掩码(Set_Event_Mask) 中打开 LE Meta Event 位,否则即使 LE_Event_Mask 配好了,也不会有任何 LE 事件上来
- 如果某一位被设置为
1,表示主机希望接收对应的事件。 - 如果某一位被设置为
0,表示主机不关心对应的事件,控制器将不会上报它。
| 位 (Bit) | 掩码值 (Hex) | 控制的 LE Meta Subevent (事件码 0x3E 的子事件) | 功能描述 |
|---|---|---|---|
| 0 | 0x0000000000000001 | LE Connection Complete (Subevent 0x01) | 连接建立成功或失败。 |
| 1 | 0x0000000000000002 | LE Advertising Report (Subevent 0x02) | 扫描时发现了广播设备。 |
| 2 | 0x0000000000000004 | LE Connection Update Complete (Subevent 0x03) | 连接参数更新完成。 |
| 3 | 0x0000000000000008 | LE Read Remote Features Complete (Subevent 0x04) | 读取远端设备支持的特性完成。 |
| 4 | 0x0000000000000010 | LE Long Term Key Request (Subevent 0x05) | 控制器请求主机提供长期密钥(LTK)。 |
| 5 | 0x0000000000000020 | LE Remote Connection Parameter Request (Subevent 0x06) | 远端设备请求更新连接参数。 |
| 6 | 0x0000000000000040 | LE Data Length Change (Subevent 0x07) | 连接的数据长度(DLE)发生改变。 |
| 7 | 0x0000000000000080 | LE Read Local P-256 Public Key Complete (Subevent 0x08) | 读取本地P-256公钥完成。 |
| 8 | 0x0000000000000100 | LE Generate DHKey Complete (Subevent 0x09) | 生成DHKey完成。 |
| 9 | 0x0000000000000200 | LE Enhanced Connection Complete (Subevent 0x0A) | 增强型连接建立完成。 |
| 10 | 0x0000000000000400 | LE Directed Advertising Report (Subevent 0x0B) | 发现了定向广播设备。 |
| 11 | 0x0000000000000800 | LE PHY Update Complete (Subevent 0x0C) | 连接的物理层(PHY)更新完成。 |
| 12 | 0x0000000000001000 | LE Extended Advertising Report (Subevent 0x0D) | 发现了扩展广播设备。 |
| 13 | 0x0000000000002000 | LE Periodic Advertising Sync Established (Subevent 0x0E) | 与周期性广播建立同步。 |
| 14 | 0x0000000000004000 | LE Periodic Advertising Report (Subevent 0x0F) | 收到了周期性广播的数据。 |
| 15 | 0x0000000000008000 | LE Periodic Advertising Sync Lost (Subevent 0x10) | 与周期性广播的同步丢失。 |
| 16 | 0x0000000000010000 | LE Scan Timeout (Subevent 0x11) | 扫描超时。 |
| 17 | 0x0000000000020000 | LE Advertising Set Terminated (Subevent 0x12) | 广播集终止。 |
| 18 | 0x0000000000040000 | LE Scan Request Received (Subevent 0x13) | 本地广播收到了扫描请求。 |
| 19 | 0x0000000000080000 | LE Channel Selection Algorithm (Subevent 0x14) | 通知主机连接使用了何种信道选择算法。 |
| 20 | 0x0000000000100000 | LE Connectionless IQ Report (Subevent 0x15) | (AoA/AoD)上报无连接IQ采样报告。 |
| 21 | 0x0000000000200000 | LE Connection IQ Report (Subevent 0x16) | (AoA/AoD)上报面向连接IQ采样报告。 |
| 22 | 0x0000000000400000 | LE CTE Request Failed (Subevent 0x17) | (AoA/AoD)CTE请求失败。 |
| 23 | 0x0000000000800000 | LE Periodic Advertising Sync Transfer Received (Subevent 0x18) | 收到周期性广播同步转移信息。 |
| 24 | 0x0000000001000000 | LE CIS Established (Subevent 0x19) | (LE Audio)已建立一个CIS(连接同步流)。 |
| 25 | 0x0000000002000000 | LE CIS Request (Subevent 0x1A) | (LE Audio)收到一个CIS请求。 |
| 26 | 0x0000000004000000 | LE Create BIG Complete (Subevent 0x1B) | (LE Audio)创建一个BIG(广播同步组)完成。 |
| 27 | 0x0000000008000000 | LE Terminate BIG Complete (Subevent 0x1C) | (LE Audio)终止一个BIG完成。 |
| 28 | 0x0000000010000000 | LE BIG Sync Established (Subevent 0x1D) | (LE Audio)与一个BIG建立同步。 |
| 29 | 0x0000000020000000 | LE BIG Sync Lost (Subevent 0x1E) | (LE Audio)与一个BIG的同步丢失。 |
| 30 | 0x0000000040000000 | LE Request Peer SCA Complete (Subevent 0x1F) | (LE Audio)请求对端SCA(睡眠时钟精度)完成。 |
| 31 | 0x0000000080000000 | LE Path Loss Threshold (Subevent 0x20) | 路径损耗超过阈值。 |
| 32 | 0x0000000100000000 | LE Transmit Power Reporting (Subevent 0x21) | 发射功率报告。 |
| 33 | 0x0000000200000000 | LE BIGInfo Advertising Report (Subevent 0x22) | (LE Audio)收到了一个包含BIGInfo的广播报告。 |
| 34-63 | - | Reserved for Future Use | 保留以备将来使用。 |
2. 传统广播与扫描 (Legacy Advertising & Scanning - BLE 4.x)
| OCF (Hex) | 命令名称 (Command Name) | 功能描述 (Description) |
|---|---|---|
0x0006 | LE_Set_Advertising_Parameters | (核心) 设置传统广播的参数(广播间隔、类型、信道等)。 |
0x0007 | LE_Read_Advertising_Channel_Tx_Power | 读取广播信道的发射功率。 |
0x0008 | LE_Set_Advertising_Data | (核心) 设置传统广播的广播负载数据(最多31字节)。 |
0x0009 | LE_Set_Scan_Response_Data | (核心) 设置传统广播的扫描响应数据(最多31字节)。 |
0x000A | LE_Set_Advertise_Enable | (核心) 启用或禁用传统广播。 |
0x000B | LE_Set_Scan_Parameters | (核心) 设置传统扫描的参数(主动/被动、扫描窗口/间隔)。 |
0x000C | LE_Set_Scan_Enable | (核心) 启用或禁用传统扫描。 |
3. 连接与白名单 (Connection & White List)
| OCF (Hex) | 命令名称 (Command Name) | 功能描述 (Description) |
|---|---|---|
0x000D | LE_Create_Connection | (核心) 使用传统广播参数创建一个LE连接。 |
0x000E | LE_Create_Connection_Cancel | 取消正在进行的 LE_Create_Connection 操作。 |
0x000F | LE_Read_White_List_Size | 读取白名单中可以存储的条目总数。 |
0x0010 | LE_Clear_White_List | 清空白名单中的所有设备。 |
0x0011 | LE_Add_Device_To_White_List | 向白名单中添加一个设备。 |
0x0012 | LE_Remove_Device_From_White_List | 从白名单中移除一个设备。 |
4. 连接后管理与安全 (Post-Connection Management & Security)
| OCF (Hex) | 命令名称 (Command Name) | 功能描述 (Description) |
|---|---|---|
0x0013 | LE_Connection_Update | (主设备)发起一个连接参数更新请求。 |
0x0014 | LE_Set_Host_Channel_Classification | (主设备)设置要使用的信道图(用于跳频)。 |
0x0015 | LE_Read_Channel_Map | (主从均可)读取指定连接正在使用的信道图。 |
0x0016 | LE_Read_Remote_Features | 读取远端设备支持的LE特性。 |
0x0017 | LE_Encrypt | 使用给定的密钥和明文数据,请求控制器进行AES-128加密。 |
0x0018 | LE_Rand | 请求控制器生成一个128位的随机数。 |
0x0019 | LE_Start_Encryption | (主设备)在一个已建立的LE连接上启动加密。 |
0x001A | LE_Long_Term_Key_Request_Reply | (安全核心) 对控制器请求LTK的事件进行肯定回复(提供LTK)。 |
0x001B | LE_Long_Term_Key_Request_Negative_Reply | (安全核心) 对控制器请求LTK的事件进行否定回复。 |
0x0020 | LE_Remote_Connection_Parameter_Request_Reply | 同意由远端设备发起的连接参数更新请求。 |
0x0021 | LE_Remote_Connection_Parameter_Request_Negative_Reply | 拒绝由远端设备发起的连接参数更新请求。 |
5. 数据长度扩展 (Data Length Extension - DLE - BLE 4.2)
| OCF (Hex) | 命令名称 (Command Name) | 功能描述 (Description) |
|---|---|---|
0x0022 | LE_Set_Data_Length | 设置连接的数据包有效负载长度和时间。 |
0x0023 | LE_Read_Suggested_Default_Data_Length | 读取控制器建议的默认数据长度值。 |
0x0024 | LE_Write_Suggested_Default_Data_Length | 向控制器写入建议的默认数据长度值。 |
6. 安全连接与隐私 (Secure Connections & Privacy - BLE 4.2 / 5.0)
| OCF (Hex) | 命令名称 (Command Name) | 功能描述 (Description) |
|---|---|---|
0x0025 | LE_Read_Local_P-256_Public_Key | 读取本地设备生成的用于安全连接的P-256公钥。 |
0x0026 | LE_Generate_DHKey | [V1] 基于本地私钥和远端公钥生成Diffie-Hellman密钥。 |
0x0027 | LE_Add_Device_To_Resolving_List | 向可解析列表中添加一个设备(用于解析RPA)。 |
0x0028 | LE_Remove_Device_From_Resolving_List | 从可解析列表中移除一个设备。 |
0x0029 | LE_Clear_Resolving_List | 清空可解析列表。 |
0x002A | LE_Read_Resolving_List_Size | 读取可解析列表的大小。 |
0x002B | LE_Read_Peer_Resolvable_Address | 读取对端设备在可解析列表中的可解析私有地址(RPA)。 |
0x002C | LE_Read_Local_Resolvable_Address | 读取本地设备在可解析列表中的可解析私有地址(RPA)。 |
0x002D | LE_Set_Address_Resolution_Enable | 启用或禁用地址解析功能。 |
0x002E | LE_Set_Resolvable_Private_Address_Timeout | 设置可解析私有地址(RPA)的更新超时时间。 |
7. 物理层管理 (PHY Management - BLE 5.0)
| OCF (Hex) | 命令名称 (Command Name) | 功能描述 (Description) |
|---|---|---|
0x002F | LE_Read_Maximum_Data_Length | 读取控制器支持的最大数据包负载长度和时间。 |
0x0030 | LE_Read_PHY | 读取当前连接使用的发射(TX)和接收(RX)物理层(1M, 2M, Coded)。 |
0x0031 | LE_Set_Default_PHY | 设置默认的物理层偏好。 |
0x0032 | LE_Set_PHY | 在一个已存在的连接上协商更改物理层。 |
8. 扩展广播 (Extended Advertising - BLE 5.0)
| OCF (Hex) | 命令名称 (Command Name) | 功能描述 (Description) |
|---|---|---|
0x0035 | LE_Set_Advertising_Set_Random_Address | 为指定的广播集设置随机地址。 |
0x0036 | LE_Set_Extended_Advertising_Parameters | (核心) 设置扩展广播的参数(比传统广播更丰富)。 |
0x0037 | LE_Set_Extended_Advertising_Data | (核心) 设置扩展广播的数据(可分片,最多1650字节)。 |
0x0038 | LE_Set_Extended_Scan_Response_Data | (核心) 设置扩展广播的扫描响应数据。 |
0x0039 | LE_Set_Extended_Advertise_Enable | (核心) 启用或禁用一个或多个扩展广播集。 |
0x003A | LE_Read_Maximum_Advertising_Data_Length | 读取控制器支持的最大广播数据长度。 |
0x003B | LE_Read_Number_of_Supported_Advertising_Sets | 读取控制器支持的广播集总数。 |
0x003C | LE_Remove_Advertising_Set | 移除一个广播集。 |
0x003D | LE_Clear_Advertising_Sets | 移除所有广播集。 |
9. 周期性广播 (Periodic Advertising - BLE 5.0)
| OCF (Hex) | 命令名称 (Command Name) | 功能描述 (Description) |
|---|---|---|
0x003E | LE_Set_Periodic_Advertising_Parameters | 设置周期性广播的参数。 |
0x003F | LE_Set_Periodic_Advertising_Data | 设置周期性广播的数据。 |
0x0040 | LE_Set_Periodic_Advertising_Enable | 启用或禁用周期性广播。 |
10. 扩展与周期性扫描和连接 (Extended & Periodic Scanning & Connection - BLE 5.0)
| OCF (Hex) | 命令名称 (Command Name) | 功能描述 (Description) |
|---|---|---|
0x0041 | LE_Set_Extended_Scan_Parameters | 设置扩展扫描的参数。 |
0x0042 | LE_Set_Extended_Scan_Enable | 启用或禁用扩展扫描。 |
0x0043 | LE_Extended_Create_Connection | 使用扩展扫描参数来创建连接。 |
0x0044 | LE_Periodic_Advertising_Create_Sync | 尝试与一个正在进行周期性广播的设备同步。 |
0x0045 | LE_Periodic_Advertising_Create_Sync_Cancel | 取消正在进行的同步过程。 |
0x0046 | LE_Periodic_Advertising_Terminate_Sync | 终止一个已建立的周期性广播同步。 |
0x0047 | LE_Add_Device_To_Periodic_Advertiser_List | 向周期性广播列表中添加一个设备。 |
0x0048 | LE_Remove_Device_From_Periodic_Advertiser_List | 从周期性广播列表中移除一个设备。 |
0x0049 | LE_Clear_Periodic_Advertiser_List | 清空周期性广播列表。 |
0x004A | LE_Read_Periodic_Advertiser_List_Size | 读取周期性广播列表的大小。 |
11. 发射功率与路径损耗 (Transmit Power & Path Loss - BLE 5.1/5.2)
| OCF (Hex) | 命令名称 (Command Name) | 功能描述 (Description) |
|---|---|---|
0x004B | LE_Read_Transmit_Power | 读取当前的最小/最大发射功率。 |
0x004C | LE_Read_RF_Path_Compensation | 读取用于计算路径损耗的RF路径补偿值。 |
0x004D | LE_Write_RF_Path_Compensation | 写入RF路径补偿值。 |
0x004E | LE_Set_Privacy_Mode | 为列表中的特定设备设置隐私模式(网络隐私或设备隐私)。 |
0x004F | LE_Read_Remote_Transmit_Power_Level | 读取远端设备在指定PHY上的发射功率。 |
0x0077 | LE_Set_Path_Loss_Reporting_Parameters | 设置路径损耗报告的参数。 |
0x0078 | LE_Set_Path_Loss_Reporting_Enable | 启用或禁用路径损耗报告。 |
0x0079 | LE_Set_Transmit_Power_Reporting_Enable | 启用或禁用远端和本地发射功率报告。 |
12. 连接定向通道 (Connection-Oriented Channels - L2CAP CoC - BLE 5.2)
| OCF (Hex) | 命令名称 (Command Name) | 功能描述 (Description) |
|---|---|---|
0x006A | LE_Set_Host_Feature | 主机用来设置或清除控制器中某个支持的特性位。 |
13. 测试命令 (Testing Commands)
| OCF (Hex) | 命令名称 (Command Name) | 功能描述 (Description) |
|---|---|---|
0x001D | LE_Receiver_Test | 进入LE接收机测试模式。 |
0x001E | LE_Transmitter_Test | 进入LE发射机测试模式。 |
0x001F | LE_Test_End | 结束当前的LE测试。 |
0x0033 | LE_Receiver_Test | 功能增强的接收机测试模式。 |
0x0034 | LE_Transmitter_Test | 功能增强的发射机测试模式。 |
0x0050 | LE_Generate_DHKey | 功能增强的DHKey生成命令。 |
HCI 事件包(HCI Event Packet)
由控制器发送给主机,用于通知已发生的事件或对某个命令的响应。
┌─────────────┬──────────────┬──────────────┬─────────────────────┐
│ Packet Type │ Event Code │ Param Length │ Parameters (N Bytes)│
│ 0x04 │ 1 Byte │ 1 Byte │ │
└─────────────┴──────────────┴──────────────┴─────────────────────┘
EventCode 标准事件
| Event Code (Hex) | 事件名称 (Event Name) | 功能描述 (Description) |
|---|---|---|
0x01 | Inquiry Complete | BR/EDR的Inquiry过程完成。 |
0x02 | Inquiry Result | BR/EDR的Inquiry过程发现了一个设备。 |
0x03 | Connection Complete | 一个BR/EDR的ACL连接已建立。 |
0x04 | Connection Request | 收到一个远程设备发来的BR/EDR连接请求。 |
0x05 | Disconnection Complete | (核心) 一个连接(BR/EDR或LE)已断开。 |
0x06 | Authentication Complete | BR/EDR的认证过程完成。 |
0x07 | Remote Name Request Complete | 获取远端设备名称的请求已完成。 |
0x08 | Encryption Change | (核心) 连接的加密状态发生了变化(如加密启动或暂停) |
0x09 | Change Connection Link Key Complete | 更改连接链路密钥的操作已完成。 |
0x0A | Master Link Key Complete | 主链路密钥交换过程完成。 |
0x0B | Read Remote Supported Features Complete | 读取远端设备支持的特性列表已完成。 |
0x0C | Read Remote Version Information Complete | 读取远端设备的版本信息已完成。 |
0x0D | QoS Setup Complete | 服务质量(QoS)设置完成。 |
0x0E | Command Complete | (****核心) 一个HCI命令已快速执行并完成,包含返回值。 |
0x0F | Command Status | (核心) 一个耗时的HCI命令已被控制器接受,作为临时回执。 |
0x10 | Hardware Error | 控制器检测到硬件故障。 |
0x11 | Flush Occurred | 数据包因超时被控制器丢弃。 |
0x12 | Role Change | 设备在连接中的角色(主/从)发生了改变。 |
0x13 | Number Of Completed Packets | (核心) (控制器→主机)用于流量控制,通知主机控制器已处理完多少数据包。 |
0x14 | Mode Change | 连接进入了不同的电源模式(如Sniff, Park)。 |
0x15 | Return Link Keys | 控制器返回存储的链路密钥。 |
0x16 | PIN Code Request | (安全)控制器请求主机提供PIN码。 |
0x17 | Link Key Request | (安全)控制器请求主机提供链路密钥。 |
0x18 | Link Key Notification | 控制器通知主机一个新的链路密钥。 |
0x19 | Loopback Command | 环回命令的返回数据。 |
0x1A | Data Buffer Overflow | 主机或控制器的数据缓冲区溢出。 |
0x1B | Max Slots Change | 连接中可用的最大时隙数发生变化。 |
0x1C | Read Clock Offset Complete | 读取时钟偏移量完成。 |
0x1D | Connection Packet Type Changed | 连接的数据包类型已更改。 |
0x22 | Page Scan Repetition Mode Change | 页面扫描重复模式发生改变。 |
0x23 | Flow Specification Complete | 流量规范设置完成。 |
0x2C | Read Remote Extended Features Complete | 读取远端设备支持的扩展特性完成。 |
0x3E | LE Meta Event | (BLE核心) 这是一个“容器”事件,所有LE相关的特定事件都封装在其中。 |
0xFF | Vendor Specific Event | (厂商定制) 这是一个厂商自定义事件,其内容由芯片制造商定义。 |
Complete Event
Event Code: 0x0E
方向: Controller → Host
| 字段 (Field) | 长度 (Length) | 描述 (Description) |
|---|---|---|
Event Code | 1 字节 (octet) | 事件类型码。对于“命令完成事件”,此值固定为 0x0E。 |
Parameter Total Length | 1 字节 (octet) | 剩余所有字段的总字节数。其值为 1 + 2 + N。 |
Num_HCI_Command_Packets | 1 字节 (octet) | 用于流量控制。告知主机(Host)控制器现在可以接收多少个新的HCI命令。 |
Command_OpCode | 2 字节 (octets) | 触发此事件的原始HCI命令的操作码(OpCode)。用于将事件与命令关联。采用小端字节序(Little-Endian)。 |
Return_Parameters | N 字节 (octets) | 命令的返回值。其结构和长度(N)完全由 Command_OpCode 字段所对应的命令定义。第一个字节通常是状态码 (Status)。 |
示例:
Host发
HCI Command:
OpCode: 0x2002 (LE Read Buffer Size)
Length: 0
Controller回
Event Code: 0x0E
Param Length: 7
Num_HCI_Command_Packets: 1
Command_OpCode: 0x2002
Return Parameters:
Status: 0x00
LE_ACL_Data_Packet_Length: 0x001B
Total_Num_LE_ACL_Data_Packets: 0x0A
Status Event
Event Code: 0x0F
方向: Controller → Host
| 字段 (Field) | 长度 (Length) | 描述 (Description) |
|---|---|---|
Event Code | 1 字节 (octet) | 事件类型码。对于“命令状态事件”,此值固定为 0x0F。 |
Parameter Total Length | 1 字节 (octet) | 剩余字段的总长度。对于此事件,该值固定为 4 字节。 |
Status | 1 字节 (octet) | 命令接收状态。0x00 表示命令已被成功接受并正在处理 (Pending);非零值表示命令因格式或状态错误而被立即拒绝。 |
Num_HCI_Command_Packets | 1 字节 (octet) | 用于流量控制。告知主机(Host)控制器现在可以接收多少个新的HCI命令。 |
Command_OpCode | 2 字节 (octets) | 触发此事件的原始HCI命令的操作码(OpCode)。用于将事件与命令关联。采用小端字节序(Little-Endian)。 |
示例:
host发
HCI Command:
OpCode: 0x200D (LE Create Connection)
Length: 0x19
Parameters: ...
Controller回
Event Code: 0x0F
Param Length: 4
Status: 0x00
Num_HCI_Command_Packets: 1
Command_OpCode: 0x200D
等建立连接成功后
Event Code: 0x3E (LE Meta Event)
Subevent: 0x01 (LE Connection Complete)
...
Subevent Code 子事件
当主机收到一个事件码为0x3E的包时,它必须检查其参数的第一个字节,即子事件码 (Subevent Code),来确定具体是哪一个LE事件。
| 子事件码 (Subevent Code) | 事件名称 (Event Name) | 功能描述 (Description) |
|---|---|---|
0x01 | LE Connection Complete | (核心) 一个LE连接已成功建立或失败。 |
0x02 | LE Advertising Report | (核心) 上报一个或多个通过传统扫描发现的广播设备信息。 |
0x03 | LE Connection Update Complete | 一个LE连接的参数更新过程已完成。 |
0x04 | LE Read Remote Features Complete | 读取远端LE设备支持的特性列表已完成。 |
0x05 | LE Long Term Key Request | (安全核心) 控制器请求主机提供长期密钥(LTK)来加密连接。 |
0x06 | LE Remote Connection Parameter Request | (协商核心) 通知主机,远端设备请求更改连接参数。 |
0x07 | LE Data Length Change | 连接的数据包有效负载长度(DLE)已发生改变。 |
0x08 | LE Read Local P-256 Public Key Complete | 读取本地P-256公钥的操作完成。 |
0x09 | LE Generate DHKey Complete | 生成Diffie-Hellman密钥的操作完成。 |
0x0A | LE Enhanced Connection Complete | 功能增强的连接完成事件,提供更多角色信息。 |
0x0B | LE Directed Advertising Report | 上报一个通过定向广播发现的设备信息。 |
0x0C | LE PHY Update Complete | 连接的物理层(PHY)更新协商已完成。 |
0x0D | LE Extended Advertising Report | (核心) 上报一个或多个通过扩展扫描发现的广播设备信息。 |
0x0E | LE Periodic Advertising Sync Established | 与周期性广播成功建立同步。 |
0x0F | LE Periodic Advertising Report | 上报一个通过同步接收到的周期性广播数据。 |
0x10 | LE Periodic Advertising Sync Lost | 与周期性广播的同步已丢失。 |
0x11 | LE Scan Timeout | 扫描在指定时间内未能发现任何设备而超时。 |
0x12 | LE Advertising Set Terminated | 一个广播集因为超时或连接建立而终止。 |
0x13 | LE Scan Request Received | 控制器收到了一个针对本地广播的扫描请求。 |
0x14 | LE Channel Selection Algorithm | 通知主机连接使用了哪种信道选择算法(#1或#2)。 |
0x15 | LE Connectionless IQ Report | (AoA/AoD)上报一个无连接的IQ采样报告。 |
0x16 | LE Connection IQ Report | (AoA/AoD)上报一个面向连接的IQ采样报告。 |
0x17 | LE CTE Request Failed | (AoA/AoD)CTE(Constant Tone Extension)请求失败。 |
0x18 | LE Periodic Advertising Sync Transfer Received | 通过一个已建立的连接,收到了一个周期性广播的同步信息。 |
0x1B | LE Path Loss Threshold | 路径损耗超过了设定的阈值。 |
0x1C | LE Transmit Power Reporting | 上报本地或远端的发射功率等级。 |
HCI 异步数据包 (HCI ACL Data Packet)
用于在主机和控制器之间传输面向连接的异步 (Asynchronous Connection-Less, ACL) 数据。
ACL包负责传输业务数据,所有GATT的通知、读写等操作,最终都是封装在ACL包中的
包结构
┌─────────────┬──────────────┬──────────────┬─────────────────────┐
│ Packet Type │ Handle+Flags │ Data Length │ Payload (N Bytes) │
│ 0x02 │ 2 Bytes │ 2 Bytes │ │
└─────────────┴──────────────┴──────────────┴─────────────────────┘
[H4 Transport Layer - UART framing]
+--------------+-------------------------------------------------------+
| Packet Type | HCI ACL Data Packet |
| (1 byte) | |
+--------------+-------------------------------------------------------+
[HCI Layer - ACL Data Packet Header]
+----------------+----------------+
| Handle & Flags | Data Length(2) |
| (2 B) | (2 B) |
+----------------+----------------+
[L2CAP Layer - Signaling/Data Header]
+----------------+----------------+
| L2CAP Length | Channel ID |
| (2 B) | (2 B) |
+----------------+----------------+
[L2CAP Payload / Higher Layer]
+---------------------------------+
| Protocol-specific Payload ... |
| (ATT, SDP, RFCOMM, etc.) |
+---------------------------------+
Header
- Handle & Flags(2B)
- Handle: bits 0–11,连接句柄,标识数据包所属的逻辑连接
- PB Flag: bits 12–13(Packet Boundary)标志用于指示数据包是分片数据的开始还是延续
- 00:后续分片
- 01:起始分片
- 10:完整、未分片
- BC Flag: bits 14–15(Broadcast Flag,通常 00)
- DataLength (2B)
- HCI 层数据段长度(不含本字段与 Handle 字段)
- 最大值由 ACL_Data_Packet_Length 决定
Payload
这部分就是真正要传输的数据。它通常是一个完整的 L2CAP 包,而L2CAP包内部又可能封装了 ATT、SMP或其他协议的数据。
如,一个L2CAP Packet
| L2CAP Length | 2B | L2CAP Payload 总长度(不含 L2CAP Header 自己的 4B) |
|---|---|---|
| L2CAP Channel ID | 2B | 指示该 PDU 属于哪个 L2CAP 信道 如 0x0004: ATT (GATT 协议) |
| L2CAP Payload | NB | 上层协议数据,如 ATT Request/Response等 |