【android bluetooth 协议分析 01】【HCI 层介绍 30】【hci_event和le_meta_event如何上报到btu层】
一、引言
在蓝牙协议栈中,HCI Event
和 LE Meta Event
是控制器(Controller)向主机(Host)报告事件的两种形式,它们属于 HCI(Host Controller Interface)层。这是主机和控制器之间通信的标准接口。 那你清楚 这些 事件是怎么一层层上报到 协议栈, 协议栈有是如何去处理的吗?
1.1 什么是 HCI Event(传统事件)
1. 定义:
HCI Event
是 Controller 主动发送给 Host 的消息,用于告知状态、响应命令、通知连接变化等。
2. 格式:
+------------+------------+----------------------+
| Event Code | Length | Parameters |
+------------+------------+----------------------+
| 1 byte | 1 byte | Variable length |
+------------+------------+----------------------+
567 2025-01-05 21:10:13.070497 controller host HCI_EVT 258 Rcvd Extended Inquiry Result Beats Flex Frame 567: 258 bytes on wire (2064 bits), 258 bytes captured (2064 bits)
Bluetooth
Bluetooth HCI H4
Bluetooth HCI Event - Extended Inquiry ResultEvent Code: Extended Inquiry Result (0x2f) // 1 ByteParameter Total Length: 255 // 2 Byte// Parameters 255 ByteNumber of responses: 1 BD_ADDR: Apple_01:e1:07 (74:8f:3c:01:e1:07)Page Scan Repetition Mode: R1 (0x01)Reserved: 0x00Class of Device: 0x240418 (Audio/Video:Headphones - services: Rendering Audio).101 0001 0101 0001 = Clock Offset: 0x5151RSSI: -45 dBmExtended Inquiry Response Data
3. 常见的 HCI Event 类型:
Event Code (十六进制) | 名称 | 描述 |
---|---|---|
0x01 | Inquiry Complete | 设备搜索完成 |
0x03 | Connection Complete | BR/EDR 连接完成 |
0x05 | Disconnection Complete | 连接断开 |
0x0E | Command Complete | 命令执行完成的反馈 |
0x0F | Command Status | 命令状态反馈(可能还没执行完成) |
0x2C | Read Remote Features Complete | 远端设备功能读取完成 |
特征:
-
事件类型丰富,适用于 BR/EDR(经典蓝牙)
-
每个事件用唯一的
Event Code
标识 -
LE(低功耗)事件的统一入口是
LE_META_EVENT
(详见下节)
1.2 什么是 LE Meta Event(低功耗蓝牙元事件)
1. 定义:
LE Meta Event 是专门用于 低功耗蓝牙(BLE) 的 HCI 事件类型。
-
它的 Event Code 是固定的
0x3E
-
所有 BLE 相关的事件都会通过它来传输
-
为了区分具体事件类型,使用一个
Subevent Code
字段
2. 格式:
+------------+------------+-----------------------------+
| Event Code | Length | Parameters |
| (0x3E) | | |
+------------+------------+-----------------------------+↓+------------------------+| Subevent Code (1 byte) || BLE-specific params |+------------------------+
574 2025-01-05 21:10:14.359021 controller host HCI_EVT 46 Rcvd LE Meta (LE Advertising Report) Frame 574: 46 bytes on wire (368 bits), 46 bytes captured (368 bits)
Bluetooth
Bluetooth HCI H4
Bluetooth HCI Event - LE MetaEvent Code: LE Meta (0x3e)Parameter Total Length: 43Sub Event: LE Advertising Report (0x02)Num Reports: 1Event Type: Non-Connectable Undirected Advertising (0x03)Peer Address Type: Random Device Address (0x01)BD_ADDR: 27:fb:9b:b7:db:4f (27:fb:9b:b7:db:4f)Data Length: 31Advertising DataRSSI: -77 dBm
3. 常见的 Subevent(SubeventCode)类型:
Subevent Code (十六进制) | 名称 | 描述 |
---|---|---|
0x01 | LE Connection Complete | BLE 连接建立完成 |
0x02 | LE Advertising Report | 广播报告(扫描到的设备信息) |
0x03 | LE Connection Update Complete | 连接参数更新完成 |
0x08 | LE PHY Update Complete | PHY(物理层)更新完成(1M ↔ 2M ↔ Coded) |
0x0A | LE Extended Advertising Report | 扩展广播报告(用于 BLE 5.0 以上) |
0x0E | LE CTE Request Failed | 定向定位失败 |
特征:
-
所有 BLE 事件都通过一个统一的
Event Code = 0x3E
入口上报 -
通过
SubeventCode
进一步细分事件类型 -
BLE 特有机制(如定向广播、周期性广告、LE Audio)事件都在此定义
1.3 总结
项目 | HCI Event | LE Meta Event |
---|---|---|
Event Code | 多种(如 0x0E、0x0F、0x05) | 固定为 0x3E |
用途 | BR/EDR 和通用事件 | 专用于 BLE 事件 |
区分子事件方式 | 不需要(每种 EventCode 独立) | 使用 Subevent Code (第1字节) |
示例 | Command Complete, Disconnection | LE Connection Complete, Adv Report |
二、aosp 协议栈该如何上报处理
在 引言部分,介绍了基础内容,那协议栈中该如何上报处理???
2.1 Stack::StartEverything
我们先来看看 协议栈在初始化时都做了那些事情。
这里我们先回顾一下, 【android bluetooth 框架分析 02】【Module详解 2】【gd_shim_module 模块介绍】 中介绍的内容。
// system/main/shim/stack.ccvoid Stack::StartEverything() {...LOG_INFO("%s Starting Gd stack", __func__);ModuleList modules;modules.add<metrics::CounterMetrics>();modules.add<hal::HciHal>();modules.add<hci::HciLayer>();modules.add<storage::StorageModule>();modules.add<shim::Dumpsys>();modules.add<hci::VendorSpecificEventManager>();modules.add<hci::Controller>();modules.add<hci::AclManager>();
...if (!common::init_flags::gd_core_is_enabled()) {bluetooth::shim::hci_on_reset_complete(); // 重点}...}
当协议栈加载完 各个模块后, 将 调用 bluetooth::shim::hci_on_reset_complete
2.2 shim::hci_on_reset_complete
这是 shim
层中的回调函数,作用是当控制器完成 HCI Reset 命令之后,通知上层完成一些 事件注册和初始化工作。
shim
层是 Google Gabeldorsche(GD)架构迁移中的中间层,承担旧系统与新 Rust/C++ 架构的桥接。
// system/main/shim/hci_layer.ccvoid bluetooth::shim::hci_on_reset_complete() {/*断言 send_data_upwards 函数指针不为空,这个函数通常用来将数据向上发送到 stack 上层(ACL/HCI 事件等),必须先初始化。
*/ASSERT(send_data_upwards);// gd 协议栈暂时没有启用 rust,跳过if (bluetooth::common::init_flags::gd_rust_is_enabled()) {::rust::hci_on_reset_complete();}/*注册所有合法 HCI EventCode遍历 0x00 ~ 0xFF 范围的所有可能的 HCI EventCode(256种),转换为 EventCode 枚举类型。
*/for (uint16_t event_code_raw = 0; event_code_raw < 0x100; event_code_raw++) {auto event_code = static_cast<bluetooth::hci::EventCode>(event_code_raw);// 跳过无效的事件码(如保留字段),确保只处理合法事件。if (!is_valid_event_code(event_code)) {continue;}// 逐层检查事件是否已经在某个模块注册过(ACL、Controller、HCI、LE 广播、LE 扫描等),避免重复注册。if (event_already_registered_in_acl_layer(event_code)) {continue;} else if (event_already_registered_in_controller_layer(event_code)) {continue;} else if (event_already_registered_in_hci_layer(event_code)) {continue;} else if (event_already_registered_in_le_advertising_manager(event_code)) {continue;} else if (event_already_registered_in_le_scanning_manager(event_code)) {continue;}// 根据当前是否启用 Rust,选择用 Rust 或 C++ 的方式注册事件处理回调。if (bluetooth::common::init_flags::gd_rust_is_enabled()) {::rust::register_event(event_code);} else {cpp::register_event(event_code); // 重点分析}}// 注册所有合法 HCI SubeventCode(子事件)for (uint16_t subevent_code_raw = 0; subevent_code_raw < 0x100;subevent_code_raw++) {auto subevent_code =static_cast<bluetooth::hci::SubeventCode>(subevent_code_raw);// 过滤无效或已注册的子事件。if (!is_valid_subevent_code(subevent_code)) {continue;}if (subevent_already_registered_in_le_hci_layer(subevent_code)) {continue;}// 根据是否启用 Rust,注册子事件的回调处理逻辑。if (bluetooth::common::init_flags::gd_rust_is_enabled()) {::rust::register_le_event(subevent_code);} else {cpp::register_le_event(subevent_code); // 重点分析}}// 处理 Vendor Specific Event(厂商事件)if (!bluetooth::common::init_flags::gd_rust_is_enabled()) {// 获取 shim 层的调度 Handler(基于 thread/message loop 的事件处理)。auto handler = bluetooth::shim::GetGdShimHandler();// 注册对 BQR_EVENT(蓝牙质量报告)的处理回调,绑定到 shim 的线程中。该事件用于监听蓝牙底层通信质量指标。bluetooth::shim::GetVendorSpecificEventManager()->RegisterEventHandler(bluetooth::hci::VseSubeventCode::BQR_EVENT,handler->Bind(cpp::vendor_specific_event_callback));}// 注册 SCO 音频事件(同步连接)if (bluetooth::common::init_flags::gd_rust_is_enabled()) {::rust::register_for_sco();} else {// 注册 SCO(同步连接,例如语音通话)相关的事件,按 Rust/C++ 路径分别处理。cpp::register_for_sco();}// 注册 ISO 数据通道(用于 BLE Audio)if (bluetooth::common::init_flags::gd_rust_is_enabled()) {::rust::register_for_iso();} else {// 注册 ISO(Isochronous)通道,BLE Audio 中的核心传输通道,用于低延迟、高同步音频传输(如 LE Audio)。cpp::register_for_iso();}
}
步骤 | 功能 | 条件 |
---|---|---|
1 | 确认数据上传接口初始化 | 必须有 send_data_upwards |
2 | 调用 Rust 初始化流程(如果启用) | gd_rust_is_enabled() |
3 | 遍历注册合法 HCI Event | 如果未在其他层注册 |
4 | 遍历注册合法 HCI Subevent | LE Meta Events 子事件 |
5 | 注册 BQR 厂商事件 | 仅限 C++ shim 模式 |
6 | 注册 SCO 音频事件 | Rust/C++ 路径 |
7 | 注册 ISO BLE 音频事件 | Rust/C++ 路径 |
设计意义与架构背景
-
shim 层的职责:适配老 C++ 代码与新 Rust 模块,实现平滑过渡。
-
Rust/C++ 双路径兼容性:Google 正逐步将
bluedroid
的 HCI 层迁移到 Rust(如 Gabeldorsche 项目),但仍保留 fallback 到 C++ 的能力。 -
事件注册的模块化:避免重复注册事件,精细划分 ACL/HCI/LE 层职责。
1. 有效的 HCI Event 表
bool is_valid_event_code(bluetooth::hci::EventCode event_code) {switch (event_code) {case bluetooth::hci::EventCode::INQUIRY_COMPLETE:case bluetooth::hci::EventCode::INQUIRY_RESULT:case bluetooth::hci::EventCode::CONNECTION_COMPLETE:case bluetooth::hci::EventCode::CONNECTION_REQUEST:case bluetooth::hci::EventCode::DISCONNECTION_COMPLETE:case bluetooth::hci::EventCode::AUTHENTICATION_COMPLETE:case bluetooth::hci::EventCode::REMOTE_NAME_REQUEST_COMPLETE:case bluetooth::hci::EventCode::ENCRYPTION_CHANGE:case bluetooth::hci::EventCode::CHANGE_CONNECTION_LINK_KEY_COMPLETE:case bluetooth::hci::EventCode::CENTRAL_LINK_KEY_COMPLETE:case bluetooth::hci::EventCode::READ_REMOTE_SUPPORTED_FEATURES_COMPLETE:case bluetooth::hci::EventCode::READ_REMOTE_VERSION_INFORMATION_COMPLETE:case bluetooth::hci::EventCode::QOS_SETUP_COMPLETE:case bluetooth::hci::EventCode::COMMAND_COMPLETE:case bluetooth::hci::EventCode::COMMAND_STATUS:case bluetooth::hci::EventCode::HARDWARE_ERROR:case bluetooth::hci::EventCode::FLUSH_OCCURRED:case bluetooth::hci::EventCode::ROLE_CHANGE:case bluetooth::hci::EventCode::NUMBER_OF_COMPLETED_PACKETS:case bluetooth::hci::EventCode::MODE_CHANGE:case bluetooth::hci::EventCode::RETURN_LINK_KEYS:case bluetooth::hci::EventCode::PIN_CODE_REQUEST:case bluetooth::hci::EventCode::LINK_KEY_REQUEST:case bluetooth::hci::EventCode::LINK_KEY_NOTIFICATION:case bluetooth::hci::EventCode::LOOPBACK_COMMAND:case bluetooth::hci::EventCode::DATA_BUFFER_OVERFLOW:case bluetooth::hci::EventCode::MAX_SLOTS_CHANGE:case bluetooth::hci::EventCode::READ_CLOCK_OFFSET_COMPLETE:case bluetooth::hci::EventCode::CONNECTION_PACKET_TYPE_CHANGED:case bluetooth::hci::EventCode::QOS_VIOLATION:case bluetooth::hci::EventCode::PAGE_SCAN_REPETITION_MODE_CHANGE:case bluetooth::hci::EventCode::FLOW_SPECIFICATION_COMPLETE:case bluetooth::hci::EventCode::INQUIRY_RESULT_WITH_RSSI:case bluetooth::hci::EventCode::READ_REMOTE_EXTENDED_FEATURES_COMPLETE:case bluetooth::hci::EventCode::SYNCHRONOUS_CONNECTION_COMPLETE:case bluetooth::hci::EventCode::SYNCHRONOUS_CONNECTION_CHANGED:case bluetooth::hci::EventCode::SNIFF_SUBRATING:case bluetooth::hci::EventCode::EXTENDED_INQUIRY_RESULT:case bluetooth::hci::EventCode::ENCRYPTION_KEY_REFRESH_COMPLETE:case bluetooth::hci::EventCode::IO_CAPABILITY_REQUEST:case bluetooth::hci::EventCode::IO_CAPABILITY_RESPONSE:case bluetooth::hci::EventCode::USER_CONFIRMATION_REQUEST:case bluetooth::hci::EventCode::USER_PASSKEY_REQUEST:case bluetooth::hci::EventCode::REMOTE_OOB_DATA_REQUEST:case bluetooth::hci::EventCode::SIMPLE_PAIRING_COMPLETE:case bluetooth::hci::EventCode::LINK_SUPERVISION_TIMEOUT_CHANGED:case bluetooth::hci::EventCode::ENHANCED_FLUSH_COMPLETE:case bluetooth::hci::EventCode::USER_PASSKEY_NOTIFICATION:case bluetooth::hci::EventCode::KEYPRESS_NOTIFICATION:case bluetooth::hci::EventCode::REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION:case bluetooth::hci::EventCode::NUMBER_OF_COMPLETED_DATA_BLOCKS:return true;case bluetooth::hci::EventCode::VENDOR_SPECIFIC:case bluetooth::hci::EventCode::LE_META_EVENT: // Private to hcireturn false;}return false;
};
-
此函数用于在
HCI Reset
完成后,对所有合法事件码
进行注册。 -
表中
true
的事件都是标准 BR/EDR/LE HCI Event,被上层逻辑接收处理。 -
false
的事件表示当前不处理或已由其他路径(如 LE Subevent 或 Vendor Handler)处理。
# | Event Code Enum | Event Code (Hex) | 含义(来源于 Bluetooth Core) |
---|---|---|---|
1 | INQUIRY_COMPLETE | 0x01 | 设备发现过程完成 |
2 | INQUIRY_RESULT | 0x02 | 返回发现到的设备信息(不带 RSSI) |
3 | CONNECTION_COMPLETE | 0x03 | 与远端设备的连接结果(成功或失败) |
4 | CONNECTION_REQUEST | 0x04 | 收到远端设备请求连接 |
5 | DISCONNECTION_COMPLETE | 0x05 | 与设备的连接断开 |
6 | AUTHENTICATION_COMPLETE | 0x06 | 链路级认证完成 |
7 | REMOTE_NAME_REQUEST_COMPLETE | 0x07 | 远程设备名称请求响应 |
8 | ENCRYPTION_CHANGE | 0x08 | 加密状态改变(启用/禁用) |
9 | CHANGE_CONNECTION_LINK_KEY_COMPLETE | 0x09 | 链路密钥更换完成 |
10 | CENTRAL_LINK_KEY_COMPLETE | 0x0A | 中央设备链路密钥完成(少见) |
11 | READ_REMOTE_SUPPORTED_FEATURES_COMPLETE | 0x0B | 返回对方支持的 BR/EDR 功能 |
12 | READ_REMOTE_VERSION_INFORMATION_COMPLETE | 0x0C | 远端控制器版本信息 |
13 | QOS_SETUP_COMPLETE | 0x0D | QoS 服务质量设置结果 |
14 | COMMAND_COMPLETE | 0x0E | HCI 命令执行完成并返回 |
15 | COMMAND_STATUS | 0x0F | HCI 命令正在处理中(异步通知) |
16 | HARDWARE_ERROR | 0x10 | 控制器报告硬件故障 |
17 | FLUSH_OCCURRED | 0x11 | 已请求的 flush 操作完成(清除缓存数据) |
18 | ROLE_CHANGE | 0x12 | BR/EDR 主从角色发生变化 |
19 | NUMBER_OF_COMPLETED_PACKETS | 0x13 | 指定连接下已完成的数据包数量 |
20 | MODE_CHANGE | 0x14 | 节能模式改变(如 Sniff、Hold) |
21 | RETURN_LINK_KEYS | 0x15 | 返回多个已配对设备的链路密钥 |
22 | PIN_CODE_REQUEST | 0x16 | 请求用户输入 PIN 码(旧版配对) |
23 | LINK_KEY_REQUEST | 0x17 | 请求链路密钥(设备重连) |
24 | LINK_KEY_NOTIFICATION | 0x18 | 新链路密钥生成通知 |
25 | LOOPBACK_COMMAND | 0x19 | 测试环回命令回应 |
26 | DATA_BUFFER_OVERFLOW | 0x1A | 控制器内部缓冲区溢出 |
27 | MAX_SLOTS_CHANGE | 0x1B | 最大可用时隙数改变(影响吞吐) |
28 | READ_CLOCK_OFFSET_COMPLETE | 0x1C | 时钟偏移读取完成 |
29 | CONNECTION_PACKET_TYPE_CHANGED | 0x1D | 连接使用的数据包类型发生变化 |
30 | QOS_VIOLATION | 0x1E | 发生 QoS 违规情况 |
31 | PAGE_SCAN_REPETITION_MODE_CHANGE | 0x20 | 远程设备的 Page Scan 模式变化通知 |
32 | FLOW_SPECIFICATION_COMPLETE | 0x21 | 新版流规范设置结果(替代 QoS) |
33 | INQUIRY_RESULT_WITH_RSSI | 0x22 | 设备发现结果(包含 RSSI) |
34 | READ_REMOTE_EXTENDED_FEATURES_COMPLETE | 0x23 | 返回远端设备的扩展特性(超出基本 feature set) |
35 | SYNCHRONOUS_CONNECTION_COMPLETE | 0x2C | SCO/eSCO 音频连接建立完成 |
36 | SYNCHRONOUS_CONNECTION_CHANGED | 0x2D | SCO/eSCO 音频连接参数变化 |
37 | SNIFF_SUBRATING | 0x2E | Sniff 子速率通知(省电优化) |
38 | EXTENDED_INQUIRY_RESULT | 0x2F | 扩展设备发现结果(支持 EIR) |
39 | ENCRYPTION_KEY_REFRESH_COMPLETE | 0x30 | 加密密钥刷新完成(蓝牙安全增强) |
40 | IO_CAPABILITY_REQUEST | 0x31 | 请求 IO 能力(SSP 配对) |
41 | IO_CAPABILITY_RESPONSE | 0x32 | IO 能力响应 |
42 | USER_CONFIRMATION_REQUEST | 0x33 | 用户确认配对请求(SSP Numeric Comparison) |
43 | USER_PASSKEY_REQUEST | 0x34 | 用户输入配对码请求 |
44 | REMOTE_OOB_DATA_REQUEST | 0x35 | 请求 Out Of Band 数据(如 NFC) |
45 | SIMPLE_PAIRING_COMPLETE | 0x36 | 安全简单配对完成 |
46 | LINK_SUPERVISION_TIMEOUT_CHANGED | 0x38 | 超时设置变更通知 |
47 | ENHANCED_FLUSH_COMPLETE | 0x39 | 增强型 flush 操作完成 |
48 | USER_PASSKEY_NOTIFICATION | 0x3B | 显示配对码给用户 |
49 | KEYPRESS_NOTIFICATION | 0x3C | 输入状态通知(用户正在输入) |
50 | REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION | 0x3D | 远程主机支持特性通知 |
51 | NUMBER_OF_COMPLETED_DATA_BLOCKS | 0x48 | LE ACL 包完成统计(LE ISO 传输时可能用) |
2. 有效的 HCI LE Subevent 表格
这些 subevent 都是属于 LE_META_EVENT
(主事件码 0x3E
)的子事件,用于处理 Bluetooth LE 的各种异步事件。
bool is_valid_subevent_code(bluetooth::hci::SubeventCode subevent_code) {switch (subevent_code) {case bluetooth::hci::SubeventCode::CONNECTION_COMPLETE:case bluetooth::hci::SubeventCode::CONNECTION_UPDATE_COMPLETE:case bluetooth::hci::SubeventCode::DATA_LENGTH_CHANGE:case bluetooth::hci::SubeventCode::ENHANCED_CONNECTION_COMPLETE:case bluetooth::hci::SubeventCode::PHY_UPDATE_COMPLETE:case bluetooth::hci::SubeventCode::READ_REMOTE_FEATURES_COMPLETE:case bluetooth::hci::SubeventCode::REMOTE_CONNECTION_PARAMETER_REQUEST:case bluetooth::hci::SubeventCode::READ_LOCAL_P256_PUBLIC_KEY_COMPLETE:case bluetooth::hci::SubeventCode::GENERATE_DHKEY_COMPLETE:case bluetooth::hci::SubeventCode::DIRECTED_ADVERTISING_REPORT:case bluetooth::hci::SubeventCode::EXTENDED_ADVERTISING_REPORT:case bluetooth::hci::SubeventCode::PERIODIC_ADVERTISING_SYNC_ESTABLISHED:case bluetooth::hci::SubeventCode::PERIODIC_ADVERTISING_REPORT:case bluetooth::hci::SubeventCode::PERIODIC_ADVERTISING_SYNC_LOST:case bluetooth::hci::SubeventCode::SCAN_TIMEOUT:case bluetooth::hci::SubeventCode::ADVERTISING_SET_TERMINATED:case bluetooth::hci::SubeventCode::SCAN_REQUEST_RECEIVED:case bluetooth::hci::SubeventCode::CHANNEL_SELECTION_ALGORITHM:case bluetooth::hci::SubeventCode::CONNECTIONLESS_IQ_REPORT:case bluetooth::hci::SubeventCode::CONNECTION_IQ_REPORT:case bluetooth::hci::SubeventCode::CTE_REQUEST_FAILED:case bluetooth::hci::SubeventCode::PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED:case bluetooth::hci::SubeventCode::CIS_ESTABLISHED:case bluetooth::hci::SubeventCode::CIS_REQUEST:case bluetooth::hci::SubeventCode::CREATE_BIG_COMPLETE:case bluetooth::hci::SubeventCode::TERMINATE_BIG_COMPLETE:case bluetooth::hci::SubeventCode::BIG_SYNC_ESTABLISHED:case bluetooth::hci::SubeventCode::BIG_SYNC_LOST:case bluetooth::hci::SubeventCode::REQUEST_PEER_SCA_COMPLETE:case bluetooth::hci::SubeventCode::PATH_LOSS_THRESHOLD:case bluetooth::hci::SubeventCode::TRANSMIT_POWER_REPORTING:case bluetooth::hci::SubeventCode::BIG_INFO_ADVERTISING_REPORT:case bluetooth::hci::SubeventCode::ADVERTISING_REPORT:case bluetooth::hci::SubeventCode::LONG_TERM_KEY_REQUEST:return true;default:return false;}
}
# | Subevent Code Enum | Subevent Code (Hex) | 含义(根据 Bluetooth Core) |
---|---|---|---|
1 | CONNECTION_COMPLETE | 0x01 | LE 连接建立完成 |
2 | CONNECTION_UPDATE_COMPLETE | 0x03 | 连接参数更新完成(间隔、超时等) |
3 | DATA_LENGTH_CHANGE | 0x07 | 数据包长度/时间改变(更长更高效) |
4 | ENHANCED_CONNECTION_COMPLETE | 0x0A | 建立带地址类型的 LE 连接(支持隐私) |
5 | PHY_UPDATE_COMPLETE | 0x0C | PHY 更新完成(1M/2M/Coded PHY) |
6 | READ_REMOTE_FEATURES_COMPLETE | 0x0B | 远程设备支持的 LE 特性 |
7 | REMOTE_CONNECTION_PARAMETER_REQUEST | 0x06 | 对方请求修改连接参数 |
8 | READ_LOCAL_P256_PUBLIC_KEY_COMPLETE | 0x08 | 本地 P-256 公钥生成完成(LE Secure Connections) |
9 | GENERATE_DHKEY_COMPLETE | 0x09 | Diffie-Hellman 密钥生成完成(LE Secure Connections) |
10 | DIRECTED_ADVERTISING_REPORT | 0x0B | 接收到 directed 广播(定向广告) |
11 | EXTENDED_ADVERTISING_REPORT | 0x0D | 扩展广播数据报告(支持更多字段) |
12 | PERIODIC_ADVERTISING_SYNC_ESTABLISHED | 0x0E | 成功同步周期性广播 |
13 | PERIODIC_ADVERTISING_REPORT | 0x0F | 周期性广播数据报告 |
14 | PERIODIC_ADVERTISING_SYNC_LOST | 0x10 | 周期性广播同步丢失 |
15 | SCAN_TIMEOUT | 0x11 | 扫描操作超时,无设备发现 |
16 | ADVERTISING_SET_TERMINATED | 0x12 | 广播集终止 |
17 | SCAN_REQUEST_RECEIVED | 0x13 | 收到 SCAN_REQ 请求(用于扫描响应) |
18 | CHANNEL_SELECTION_ALGORITHM | 0x14 | 通道选择算法设置通知 |
19 | CONNECTIONLESS_IQ_REPORT | 0x15 | AoA/AoD 连接无关 IQ 报告(方向查找) |
20 | CONNECTION_IQ_REPORT | 0x16 | AoA/AoD 连接相关 IQ 报告 |
21 | CTE_REQUEST_FAILED | 0x17 | 方向查找中的 CTE 请求失败 |
22 | PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED | 0x18 | 从其他设备接收到同步周期性广播 |
23 | CIS_ESTABLISHED | 0x19 | ISO 数据通道 (CIS) 建立完成(LE Audio) |
24 | CIS_REQUEST | 0x1A | 请求建立 ISO 数据流(CIS) |
25 | CREATE_BIG_COMPLETE | 0x1B | 创建 BIG(Broadcast ISO Group)完成 |
26 | TERMINATE_BIG_COMPLETE | 0x1C | BIG 广播终止 |
27 | BIG_SYNC_ESTABLISHED | 0x1D | BIG 同步建立成功 |
28 | BIG_SYNC_LOST | 0x1E | BIG 同步丢失 |
29 | REQUEST_PEER_SCA_COMPLETE | 0x1F | 请求远程设备的时钟准确度 |
30 | PATH_LOSS_THRESHOLD | 0x20 | 接收信号路径损耗超出阈值通知 |
31 | TRANSMIT_POWER_REPORTING | 0x21 | 发射功率状态报告(事件通知) |
32 | BIG_INFO_ADVERTISING_REPORT | 0x22 | BIG 广播信息报告 |
33 | ADVERTISING_REPORT | 0x02 | 普通广播数据报告(Legacy 广播) |
34 | LONG_TERM_KEY_REQUEST | 0x05 | 加密过程中的 LTK 请求(低功耗配对) |
-
这些 subevent 都是 LE META Event (
0x3E
) 的子事件码,用于表示各种低功耗蓝牙控制器事件。 -
本函数用于确认哪些 Subevent 是“合法且应处理”的事件。
-
它涵盖了从基本连接到广播、方向查找(AoA/AoD)、LE Audio(如 BIG、CIS)等 Bluetooth 5.x/5.2 的特性。
-
若传入其他未被明确定义的子事件(比如未来新增的或厂商自定义的),将返回
false
。
3. register_event
函数名为 register_event
,作用是向 HCI 层注册一个事件处理器。
它的参数是 event_code
,类型是 bluetooth::hci::EventCode
,表示一个具体的 HCI 事件代码。
// system/main/shim/hci_layer.ccstatic void register_event(bluetooth::hci::EventCode event_code) {auto handler = bluetooth::shim::GetGdShimHandler();bluetooth::shim::GetHciLayer()->RegisterEventHandler(event_code, handler->Bind(event_callback));
}
调用 GetGdShimHandler()
函数,获取一个 Handler
对象的指针或引用,并赋值给变量 handler
。
bluetooth::shim
是一个 shim 层(适配层),用于在 legacy Bluedroid 和 Gabeldorsche(GD)新架构之间桥接。Handler
是一个任务调度器,用于在线程中异步处理回调(类似线程消息循环的 handler)。
✅
handler
将用于绑定一个事件回调函数,以便将事件委托给正确线程中的处理逻辑。
-
调用
GetHciLayer()
得到 HCI 层的接口对象。 -
调用
RegisterEventHandler()
方法,将特定的event_code
注册一个处理函数。 -
handler->Bind(event_callback)
表示将函数event_callback
绑定到handler
上,形成一个可调度的回调任务,这样当事件到来时,HCI 层会通过 handler 异步地调用这个回调函数。
1. HciLayer::RegisterEventHandler
// system/gd/hci/hci_layer.ccvoid HciLayer::RegisterEventHandler(EventCode event, ContextualCallback<void(EventView)> handler) {CallOn(impl_, &impl::register_event, event, handler);
}void register_event(EventCode event, ContextualCallback<void(EventView)> handler) {ASSERT_LOG(event != EventCode::LE_META_EVENT,"Can not register handler for %02hhx (%s)",EventCode::LE_META_EVENT,EventCodeText(EventCode::LE_META_EVENT).c_str());ASSERT_LOG(event_handlers_.count(event) == 0, "Can not register a second handler for %02hhx (%s)", event,EventCodeText(event).c_str());event_handlers_[event] = handler; // 将 每个 hci event 事件的 回调函数都注册进 event_handlers_}
可以参考 下面的文章, 来梳理 当 收到 hci event 时,如何回调到 hci_layer.cc::event_callback
中。
【android bluetooth 框架分析 02】【Module详解 5】【HciLayer 模块介绍】
// system/gd/hci/hci_layer.ccvoid on_hci_event(EventView event) {...event_handlers_[event_code].Invoke(event); // 根据 event, 调用不同的 回调
}
2. event_callback
当 有 hci_event 事件上来时,就会 调用到这里。
// system/main/shim/hci_layer.ccstatic void event_callback(bluetooth::hci::EventView event_packet_view) {if (!send_data_upwards) {return;}LOG_INFO("debug_inquiry %s %d", __func__, __LINE__);send_data_upwards.Run(FROM_HERE, WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_EVT /*关注一下这里*/,&event_packet_view));
}
- 将 hci_event 通过
send_data_upwards
继续上报。
在 bte_main_init->set_data_cb
中 将 post_to_main_message_loop
函数赋值给 send_data_upwards
, 也就是这里的 send_data_upwards == post_to_main_message_loop
// system/main/shim/hci_layer.ccstatic void set_data_cb(base::Callback<void(const base::Location&, BT_HDR*)> send_data_cb) {send_data_upwards = std::move(send_data_cb);
}static hci_t interface = {.set_data_cb = set_data_cb,.transmit_command = transmit_command,.transmit_command_futured = transmit_command_futured,.transmit_downward = transmit_downward};const hci_t* bluetooth::shim::hci_layer_get_interface() {packet_fragmenter = packet_fragmenter_get_interface();packet_fragmenter->init(&packet_fragmenter_callbacks);return &interface;
}
// system/main/bte_main.ccvoid bte_main_init(void) {hci = bluetooth::shim::hci_layer_get_interface();if (!hci) {LOG_ERROR("%s could not get hci layer interface.", __func__);return;}hci->set_data_cb(base::Bind(&post_to_main_message_loop));
}/******************************************************************************** Function post_to_hci_message_loop** Description Post an HCI event to the main thread** Returns None******************************************************************************/
static void post_to_main_message_loop(const base::Location& from_here,BT_HDR* p_msg) {if (do_in_main_thread(from_here, base::Bind(&btu_hci_msg_process, p_msg)) !=BT_STATUS_SUCCESS) {LOG(ERROR) << __func__ << ": do_in_main_thread failed from "<< from_here.ToString();}
}
这里在 main_thread 中将 hci_event 事件继续传递到 btu 层
3.btu_hci_msg_process
处理所有从 HCI(Host Controller Interface)上来的消息,包括事件、ACL/SCO/ISO数据、命令、L2CAP传输完成通知等。
参数 p_msg
是指向 BT_HDR
的指针,表示一个通用的蓝牙数据包结构。
void btu_hci_msg_process(BT_HDR* p_msg) {/* 使用掩码 BT_EVT_MASK(通常是高 8 位,0xFF00)提取消息类型,进入具体的 case 分支处理。 */switch (p_msg->event & BT_EVT_MASK) {case BT_EVT_TO_BTU_HCI_ACL:// 这是 ACL 数据包(异步连接逻辑链路,Asynchronous Connection-Less)/* All Acl Data goes to ACL */acl_rcv_acl_data(p_msg); // 通常是传给 L2CAP 进行协议解包或数据传递。break;case BT_EVT_TO_BTU_L2C_SEG_XMIT:/* L2CAP segment transmit complete */// L2CAP 数据段发送完成通知。// 通知 L2CAP 层,之前分段的 ACL 包已发送完成,可能用于继续发送剩余段acl_link_segments_xmitted(p_msg);break;case BT_EVT_TO_BTU_HCI_SCO:// 这是 SCO 音频数据包, 将音频数据转发到相应音频处理路径。btm_route_sco_data(p_msg);break;case BT_EVT_TO_BTU_HCI_EVT/*关注一下这里*/:/*这是一个 HCI Event(事件包),例如设备连接完成、命令执行完成等。p_msg->event & BT_SUB_EVT_MASK 提取事件的低字节(通常为具体事件码);调用 btu_hcif_process_event() 进行分发处理;最后释放 p_msg 内存(事件包只读,无需传递)。*/btu_hcif_process_event((uint8_t)(p_msg->event & BT_SUB_EVT_MASK), p_msg); // 这是主事件处理入口,是大部分 HCI 事件(如连接成功、命令完成等)传入处理的通道。osi_free(p_msg);break;case BT_EVT_TO_BTU_HCI_CMD:// 这是一个待发送的 HCI 命令。btu_hcif_send_cmd((uint8_t)(p_msg->event & BT_SUB_EVT_MASK), p_msg); // 通常执行对控制器的指令(如:发起连接、设置参数等)。break;case BT_EVT_TO_BTU_HCI_ISO:IsoManager::GetInstance()->HandleIsoData(p_msg); //ISO(Isochronous)数据包,用于 LE Audio, 交由 IsoManager 管理器处理 ISO 数据,然后释放数据包。osi_free(p_msg);break;default:osi_free(p_msg);break;}
}
这里关注一下, MSG_HC_TO_STACK_HCI_EVT
和 BT_EVT_TO_BTU_HCI_EVT
之间的映射关系。
// system/hci/include/hci_layer.h/* Message event ID passed from Host/Controller lib to stack */
#define MSG_HC_TO_STACK_HCI_ACL 0x1100 /* eq. BT_EVT_TO_BTU_HCI_ACL */
#define MSG_HC_TO_STACK_HCI_SCO 0x1200 /* eq. BT_EVT_TO_BTU_HCI_SCO */
#define MSG_HC_TO_STACK_HCI_ERR 0x1300 /* eq. BT_EVT_TO_BTU_HCIT_ERR */
#define MSG_HC_TO_STACK_HCI_ISO 0x1700 /* eq. BT_EVT_TO_BTU_HCI_ISO */
#define MSG_HC_TO_STACK_HCI_EVT 0x1000 /* eq. BT_EVT_TO_BTU_HCI_EVT *//* Message event ID passed from stack to vendor lib */
#define MSG_STACK_TO_HC_HCI_ACL 0x2100 /* eq. BT_EVT_TO_LM_HCI_ACL */
#define MSG_STACK_TO_HC_HCI_SCO 0x2200 /* eq. BT_EVT_TO_LM_HCI_SCO */
#define MSG_STACK_TO_HC_HCI_ISO 0x2d00 /* eq. BT_EVT_TO_LM_HCI_ISO */
#define MSG_STACK_TO_HC_HCI_CMD 0x2000 /* eq. BT_EVT_TO_LM_HCI_CMD */
// system/stack/include/bt_types.h/* HCI Event */
#define BT_EVT_TO_BTU_HCI_EVT 0x1000
/* ACL Data from HCI */
#define BT_EVT_TO_BTU_HCI_ACL 0x1100
/* SCO Data from HCI */
#define BT_EVT_TO_BTU_HCI_SCO 0x1200
/* HCI Transport Error */
#define BT_EVT_TO_BTU_HCIT_ERR 0x1300/* Serial Port Data */
#define BT_EVT_TO_BTU_SP_DATA 0x1500/* HCI command from upper layer */
#define BT_EVT_TO_BTU_HCI_CMD 0x1600/* ISO Data from HCI */
#define BT_EVT_TO_BTU_HCI_ISO 0x1700/* L2CAP segment(s) transmitted */
#define BT_EVT_TO_BTU_L2C_SEG_XMIT 0x1900/* To LM */
/************************************/
/* HCI Command */
#define BT_EVT_TO_LM_HCI_CMD 0x2000
/* HCI ACL Data */
#define BT_EVT_TO_LM_HCI_ACL 0x2100
/* HCI SCO Data */
#define BT_EVT_TO_LM_HCI_SCO 0x2200
/* HCI ISO Data */
#define BT_EVT_TO_LM_HCI_ISO 0x2d00#define BT_EVT_HCISU 0x5000
4. register_le_event
// system/main/shim/hci_layer.ccstatic void register_le_event(bluetooth::hci::SubeventCode subevent_code) {auto handler = bluetooth::shim::GetGdShimHandler();bluetooth::shim::GetHciLayer()->RegisterLeEventHandler(subevent_code, handler->Bind(subevent_callback));
}
// system/gd/hci/hci_layer.ccvoid HciLayer::RegisterLeEventHandler(SubeventCode event, ContextualCallback<void(LeMetaEventView)> handler) {CallOn(impl_, &impl::register_le_event, event, handler);
}void register_le_event(SubeventCode event, ContextualCallback<void(LeMetaEventView)> handler) {ASSERT_LOG(subevent_handlers_.count(event) == 0, "Can not register a second handler for %02hhx (%s)", event,SubeventCodeText(event).c_str());subevent_handlers_[event] = handler; // 注册进 subevent_handlers_}
1. subevent_callback
// system/gd/hci/hci_layer.cc// 当有 le_mate event 上报时,就会 回调void on_le_meta_event(EventView event) {LeMetaEventView meta_event_view = LeMetaEventView::Create(event);ASSERT(meta_event_view.IsValid());SubeventCode subevent_code = meta_event_view.GetSubeventCode();if (subevent_handlers_.find(subevent_code) == subevent_handlers_.end()) {LOG_WARN("Unhandled le subevent of type 0x%02hhx (%s)", subevent_code, SubeventCodeText(subevent_code).c_str());return;}subevent_handlers_[subevent_code].Invoke(meta_event_view);}
最终调用到 hci_layer.cc::subevent_callback
// system/main/shim/hci_layer.cc
static void subevent_callback(bluetooth::hci::LeMetaEventView le_meta_event_view) {if (!send_data_upwards) {return;}LOG_INFO("debug_inquiry %s %d", __func__, __LINE__);send_data_upwards.Run(FROM_HERE, WrapPacketAndCopy(MSG_HC_TO_STACK_HCI_EVT,&le_meta_event_view));
}
subevent_callback
和 event_callback
向上回调的逻辑都是一样的,都是通过 send_data_upwards
并且 都是 MSG_HC_TO_STACK_HCI_EVT
,
所以最终也会 回调到 btu_hci_msg_process
中。
subevent_callback
和 event_callback
区别就是向上回调传递的参数类型是不一样的。
三、btu 层处理
hci_event 和 le_meta_event 最终都会调用到 btu_hci_msg_process
的 BT_EVT_TO_BTU_HCI_EVT
case 中。
void btu_hci_msg_process(BT_HDR* p_msg) {/* 使用掩码 BT_EVT_MASK(通常是高 8 位,0xFF00)提取消息类型,进入具体的 case 分支处理。 */switch (p_msg->event & BT_EVT_MASK) {...case BT_EVT_TO_BTU_HCI_EVT/*关注一下这里*/:/*这是一个 HCI Event(事件包),例如设备连接完成、命令执行完成等。p_msg->event & BT_SUB_EVT_MASK 提取事件的低字节(通常为具体事件码);调用 btu_hcif_process_event() 进行分发处理;最后释放 p_msg 内存(事件包只读,无需传递)。*/btu_hcif_process_event((uint8_t)(p_msg->event & BT_SUB_EVT_MASK), p_msg); // 这是主事件处理入口,是大部分 HCI 事件(如连接成功、命令完成等)传入处理的通道。osi_free(p_msg);break;...}
}
3.1 btu_hcif_process_event
所有的事件 处理 最终都会在 btu_hcif_process_event 中。
// system/stack/btu/btu_hcif.cc/********************************************************************************* Function btu_hcif_process_event** Description This function is called when an event is received from* the Host Controller.** Returns void*******************************************************************************/
void btu_hcif_process_event(UNUSED_ATTR uint8_t controller_id,const BT_HDR* p_msg) {uint8_t* p = (uint8_t*)(p_msg + 1) + p_msg->offset;uint8_t hci_evt_code, hci_evt_len;uint8_t ble_sub_code;STREAM_TO_UINT8(hci_evt_code, p);STREAM_TO_UINT8(hci_evt_len, p);// validate event sizeif (hci_evt_len < hci_event_parameters_minimum_length[hci_evt_code]) {HCI_TRACE_WARNING("%s: evt:0x%2X, malformed event of size %hhd", __func__,hci_evt_code, hci_evt_len);return;}btu_hcif_log_event_metrics(hci_evt_code, p);LOG_INFO("debug_inquiry %s %d hci_evt_code=%#x", __func__, __LINE__, hci_evt_code);switch (hci_evt_code) {case HCI_INQUIRY_COMP_EVT:btu_hcif_inquiry_comp_evt(p);break;case HCI_INQUIRY_RESULT_EVT:btm_process_inq_results(p, hci_evt_len, BTM_INQ_RESULT_STANDARD);break;case HCI_INQUIRY_RSSI_RESULT_EVT:btm_process_inq_results(p, hci_evt_len, BTM_INQ_RESULT_WITH_RSSI);break;case HCI_EXTENDED_INQUIRY_RESULT_EVT:btm_process_inq_results(p, hci_evt_len, BTM_INQ_RESULT_EXTENDED);break;case HCI_CONNECTION_REQUEST_EVT:btu_hcif_connection_request_evt(p);break;case HCI_DISCONNECTION_COMP_EVT:btu_hcif_disconnection_comp_evt(p);break;case HCI_AUTHENTICATION_COMP_EVT:btu_hcif_authentication_comp_evt(p);break;case HCI_RMT_NAME_REQUEST_COMP_EVT:btu_hcif_rmt_name_request_comp_evt(p, hci_evt_len);break;case HCI_ENCRYPTION_CHANGE_EVT:btu_hcif_encryption_change_evt(p);break;case HCI_ENCRYPTION_KEY_REFRESH_COMP_EVT:btu_hcif_encryption_key_refresh_cmpl_evt(p);break;case HCI_READ_RMT_EXT_FEATURES_COMP_EVT:btu_hcif_read_rmt_ext_features_comp_evt(p, hci_evt_len);break;case HCI_COMMAND_COMPLETE_EVT:LOG_ERROR("%s should not have received a command complete event. ""Someone didn't go through the hci transmit_command function.",__func__);break;case HCI_COMMAND_STATUS_EVT:LOG_ERROR("%s should not have received a command status event. ""Someone didn't go through the hci transmit_command function.",__func__);break;case HCI_HARDWARE_ERROR_EVT:btu_hcif_hardware_error_evt(p);break;case HCI_MODE_CHANGE_EVT:btu_hcif_mode_change_evt(p);break;case HCI_PIN_CODE_REQUEST_EVT:btm_sec_pin_code_request(p);break;case HCI_LINK_KEY_REQUEST_EVT:btm_sec_link_key_request(p);break;case HCI_LINK_KEY_NOTIFICATION_EVT:btu_hcif_link_key_notification_evt(p);break;case HCI_READ_CLOCK_OFF_COMP_EVT:btu_hcif_read_clock_off_comp_evt(p);break;case HCI_ESCO_CONNECTION_COMP_EVT:btu_hcif_esco_connection_comp_evt(p);break;case HCI_ESCO_CONNECTION_CHANGED_EVT:btu_hcif_esco_connection_chg_evt(p);break;case HCI_SNIFF_SUB_RATE_EVT:btm_pm_proc_ssr_evt(p, hci_evt_len);break;case HCI_RMT_HOST_SUP_FEAT_NOTIFY_EVT:btm_sec_rmt_host_support_feat_evt(p);break;case HCI_IO_CAPABILITY_REQUEST_EVT:btu_hcif_io_cap_request_evt(p);break;case HCI_IO_CAPABILITY_RESPONSE_EVT:btm_io_capabilities_rsp(p);break;case HCI_USER_CONFIRMATION_REQUEST_EVT:btm_proc_sp_req_evt(BTM_SP_CFM_REQ_EVT, p);break;case HCI_USER_PASSKEY_REQUEST_EVT:btm_proc_sp_req_evt(BTM_SP_KEY_REQ_EVT, p);break;case HCI_REMOTE_OOB_DATA_REQUEST_EVT:btm_rem_oob_req(p);break;case HCI_SIMPLE_PAIRING_COMPLETE_EVT:btm_simple_pair_complete(p);break;case HCI_USER_PASSKEY_NOTIFY_EVT:btm_proc_sp_req_evt(BTM_SP_KEY_NOTIF_EVT, p);break;case HCI_BLE_EVENT: {STREAM_TO_UINT8(ble_sub_code, p);uint8_t ble_evt_len = hci_evt_len - 1;switch (ble_sub_code) {case HCI_BLE_ADV_PKT_RPT_EVT: /* result of inquiry */btm_ble_process_adv_pkt(ble_evt_len, p);break;case HCI_BLE_LL_CONN_PARAM_UPD_EVT:btu_ble_ll_conn_param_upd_evt(p, ble_evt_len);break;case HCI_BLE_READ_REMOTE_FEAT_CMPL_EVT:btm_ble_read_remote_features_complete(p, ble_evt_len);break;case HCI_BLE_LTK_REQ_EVT: /* received only at peripheral device */btu_ble_proc_ltk_req(p, ble_evt_len);break;case HCI_BLE_RC_PARAM_REQ_EVT:btu_ble_rc_param_req_evt(p, ble_evt_len);break;case HCI_BLE_DATA_LENGTH_CHANGE_EVT:btu_ble_data_length_change_evt(p, hci_evt_len);break;case HCI_BLE_PHY_UPDATE_COMPLETE_EVT:btm_ble_process_phy_update_pkt(ble_evt_len, p);break;case HCI_LE_EXTENDED_ADVERTISING_REPORT_EVT:btm_ble_process_ext_adv_pkt(hci_evt_len, p);break;case HCI_LE_ADVERTISING_SET_TERMINATED_EVT:btm_le_on_advertising_set_terminated(p, hci_evt_len);break;case HCI_BLE_REQ_PEER_SCA_CPL_EVT:btm_acl_process_sca_cmpl_pkt(ble_evt_len, p);break;case HCI_BLE_PERIODIC_ADV_SYNC_EST_EVT:btm_ble_process_periodic_adv_sync_est_evt(ble_evt_len, const_cast<const uint8_t*>(p));break;case HCI_BLE_PERIODIC_ADV_REPORT_EVT:btm_ble_process_periodic_adv_pkt(ble_evt_len,const_cast<const uint8_t*>(p));break;case HCI_BLE_PERIODIC_ADV_SYNC_LOST_EVT:btm_ble_process_periodic_adv_sync_lost_evt(ble_evt_len, p);break;case HCI_BLE_CIS_EST_EVT:case HCI_BLE_CREATE_BIG_CPL_EVT:case HCI_BLE_TERM_BIG_CPL_EVT:case HCI_BLE_CIS_REQ_EVT:case HCI_BLE_BIG_SYNC_EST_EVT:case HCI_BLE_BIG_SYNC_LOST_EVT:IsoManager::GetInstance()->HandleHciEvent(ble_sub_code, p,ble_evt_len);break;case HCI_LE_PERIODIC_ADV_SYNC_TRANSFERE_RECEIVED_EVT:btm_ble_periodic_adv_sync_tx_rcvd(p, hci_evt_len);break;case HCI_LE_BIGINFO_ADVERTISING_REPORT_EVT:btm_ble_biginfo_adv_report_rcvd(p, hci_evt_len);break;// Events are now captured by gd/hci/le_acl_connection_interface.hcase HCI_BLE_CONN_COMPLETE_EVT: // SubeventCode::CONNECTION_COMPLETEcase HCI_BLE_ENHANCED_CONN_COMPLETE_EVT: // SubeventCode::ENHANCED_CONNECTION_COMPLETEdefault:LOG_ERROR("Unexpectedly received LE sub_event_code:0x%02x that should not ""be handled here",ble_sub_code);break;}} break;case HCI_VENDOR_SPECIFIC_EVT:btm_vendor_specific_evt(const_cast<const uint8_t*>(p), hci_evt_len);break;// Events now captured by gd::hci_layer modulecase HCI_NUM_COMPL_DATA_PKTS_EVT: // EventCode::NUMBER_OF_COMPLETED_PACKETScase HCI_CONNECTION_COMP_EVT: // EventCode::CONNECTION_COMPLETEcase HCI_READ_RMT_FEATURES_COMP_EVT: // EventCode::READ_REMOTE_SUPPORTED_FEATURES_COMPLETEcase HCI_READ_RMT_VERSION_COMP_EVT: // EventCode::READ_REMOTE_VERSION_INFORMATION_COMPLETEcase HCI_ROLE_CHANGE_EVT: // EventCode::ROLE_CHANGEdefault:LOG_ERROR("Unexpectedly received event_code:0x%02x that should not be ""handled here",hci_evt_code);break;}
}
这里不再展开讲解了, 后面如果有机会介绍 某一个特定事件时, 在展开讲述。
📢 写到这里,已经掏心掏肺了,如果你看到这,说明你真的很有耐心!
如果这篇文章对你有一点点启发、哪怕只是让你少踩了一个坑,欢迎点个赞支持一下,让我知道这些分享是有价值的!
有疑问?有不同看法?或者有更骚的姿势?评论区欢迎你开麦!
顺手转发给你的同行、朋友、搭档、实习生、老板,没准哪天就用上了!
别光看不留言、别光学不点赞——不然你都不好意思从我博客页面退出啊,真的😉