【android bluetooth 协议分析 01】【HCI 层介绍 30】【hci_event和le_meta_event如何上报到btu层】

一、引言

在蓝牙协议栈中,HCI EventLE 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 Result
    Event Code: Extended Inquiry Result (0x2f) // 1 Byte
    Parameter Total Length: 255                // 2 Byte

// Parameters 255 Byte
    Number of responses: 1                     
    BD_ADDR: Apple_01:e1:07 (74:8f:3c:01:e1:07)
    Page Scan Repetition Mode: R1 (0x01)
    Reserved: 0x00
    Class of Device: 0x240418 (Audio/Video:Headphones - services: Rendering Audio)
    .101 0001 0101 0001 = Clock Offset: 0x5151
    RSSI: -45 dBm
    Extended Inquiry Response Data

3. 常见的 HCI Event 类型:

Event Code (十六进制)名称描述
0x01Inquiry Complete设备搜索完成
0x03Connection CompleteBR/EDR 连接完成
0x05Disconnection Complete连接断开
0x0ECommand Complete命令执行完成的反馈
0x0FCommand Status命令状态反馈(可能还没执行完成)
0x2CRead 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 Meta
    Event Code: LE Meta (0x3e)
    Parameter Total Length: 43
    Sub Event: LE Advertising Report (0x02)
    Num Reports: 1
    Event 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: 31
    Advertising Data
    RSSI: -77 dBm



3. 常见的 Subevent(SubeventCode)类型:

Subevent Code (十六进制)名称描述
0x01LE Connection CompleteBLE 连接建立完成
0x02LE Advertising Report广播报告(扫描到的设备信息)
0x03LE Connection Update Complete连接参数更新完成
0x08LE PHY Update CompletePHY(物理层)更新完成(1M ↔ 2M ↔ Coded)
0x0ALE Extended Advertising Report扩展广播报告(用于 BLE 5.0 以上)
0x0ELE CTE Request Failed定向定位失败

特征:

  • 所有 BLE 事件都通过一个统一的 Event Code = 0x3E 入口上报

  • 通过 SubeventCode 进一步细分事件类型

  • BLE 特有机制(如定向广播、周期性广告、LE Audio)事件都在此定义


1.3 总结

项目HCI EventLE Meta Event
Event Code多种(如 0x0E、0x0F、0x05)固定为 0x3E
用途BR/EDR 和通用事件专用于 BLE 事件
区分子事件方式不需要(每种 EventCode 独立)使用 Subevent Code(第1字节)
示例Command Complete, DisconnectionLE Connection Complete, Adv Report

二、aosp 协议栈该如何上报处理

在 引言部分,介绍了基础内容,那协议栈中该如何上报处理???

2.1 Stack::StartEverything

我们先来看看 协议栈在初始化时都做了那些事情。

这里我们先回顾一下, 【android bluetooth 框架分析 02】【Module详解 2】【gd_shim_module 模块介绍】 中介绍的内容。


// system/main/shim/stack.cc

void 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.cc

void 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 SubeventLE 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 hci
      return false;
  }
  return false;
};
  • 此函数用于在 HCI Reset 完成后,对 所有合法事件码 进行注册。

  • 表中 true 的事件都是标准 BR/EDR/LE HCI Event,被上层逻辑接收处理。

  • false 的事件表示当前不处理或已由其他路径(如 LE Subevent 或 Vendor Handler)处理。

#Event Code EnumEvent Code (Hex)含义(来源于 Bluetooth Core)
1INQUIRY_COMPLETE0x01设备发现过程完成
2INQUIRY_RESULT0x02返回发现到的设备信息(不带 RSSI)
3CONNECTION_COMPLETE0x03与远端设备的连接结果(成功或失败)
4CONNECTION_REQUEST0x04收到远端设备请求连接
5DISCONNECTION_COMPLETE0x05与设备的连接断开
6AUTHENTICATION_COMPLETE0x06链路级认证完成
7REMOTE_NAME_REQUEST_COMPLETE0x07远程设备名称请求响应
8ENCRYPTION_CHANGE0x08加密状态改变(启用/禁用)
9CHANGE_CONNECTION_LINK_KEY_COMPLETE0x09链路密钥更换完成
10CENTRAL_LINK_KEY_COMPLETE0x0A中央设备链路密钥完成(少见)
11READ_REMOTE_SUPPORTED_FEATURES_COMPLETE0x0B返回对方支持的 BR/EDR 功能
12READ_REMOTE_VERSION_INFORMATION_COMPLETE0x0C远端控制器版本信息
13QOS_SETUP_COMPLETE0x0DQoS 服务质量设置结果
14COMMAND_COMPLETE0x0EHCI 命令执行完成并返回
15COMMAND_STATUS0x0FHCI 命令正在处理中(异步通知)
16HARDWARE_ERROR0x10控制器报告硬件故障
17FLUSH_OCCURRED0x11已请求的 flush 操作完成(清除缓存数据)
18ROLE_CHANGE0x12BR/EDR 主从角色发生变化
19NUMBER_OF_COMPLETED_PACKETS0x13指定连接下已完成的数据包数量
20MODE_CHANGE0x14节能模式改变(如 Sniff、Hold)
21RETURN_LINK_KEYS0x15返回多个已配对设备的链路密钥
22PIN_CODE_REQUEST0x16请求用户输入 PIN 码(旧版配对)
23LINK_KEY_REQUEST0x17请求链路密钥(设备重连)
24LINK_KEY_NOTIFICATION0x18新链路密钥生成通知
25LOOPBACK_COMMAND0x19测试环回命令回应
26DATA_BUFFER_OVERFLOW0x1A控制器内部缓冲区溢出
27MAX_SLOTS_CHANGE0x1B最大可用时隙数改变(影响吞吐)
28READ_CLOCK_OFFSET_COMPLETE0x1C时钟偏移读取完成
29CONNECTION_PACKET_TYPE_CHANGED0x1D连接使用的数据包类型发生变化
30QOS_VIOLATION0x1E发生 QoS 违规情况
31PAGE_SCAN_REPETITION_MODE_CHANGE0x20远程设备的 Page Scan 模式变化通知
32FLOW_SPECIFICATION_COMPLETE0x21新版流规范设置结果(替代 QoS)
33INQUIRY_RESULT_WITH_RSSI0x22设备发现结果(包含 RSSI)
34READ_REMOTE_EXTENDED_FEATURES_COMPLETE0x23返回远端设备的扩展特性(超出基本 feature set)
35SYNCHRONOUS_CONNECTION_COMPLETE0x2CSCO/eSCO 音频连接建立完成
36SYNCHRONOUS_CONNECTION_CHANGED0x2DSCO/eSCO 音频连接参数变化
37SNIFF_SUBRATING0x2ESniff 子速率通知(省电优化)
38EXTENDED_INQUIRY_RESULT0x2F扩展设备发现结果(支持 EIR)
39ENCRYPTION_KEY_REFRESH_COMPLETE0x30加密密钥刷新完成(蓝牙安全增强)
40IO_CAPABILITY_REQUEST0x31请求 IO 能力(SSP 配对)
41IO_CAPABILITY_RESPONSE0x32IO 能力响应
42USER_CONFIRMATION_REQUEST0x33用户确认配对请求(SSP Numeric Comparison)
43USER_PASSKEY_REQUEST0x34用户输入配对码请求
44REMOTE_OOB_DATA_REQUEST0x35请求 Out Of Band 数据(如 NFC)
45SIMPLE_PAIRING_COMPLETE0x36安全简单配对完成
46LINK_SUPERVISION_TIMEOUT_CHANGED0x38超时设置变更通知
47ENHANCED_FLUSH_COMPLETE0x39增强型 flush 操作完成
48USER_PASSKEY_NOTIFICATION0x3B显示配对码给用户
49KEYPRESS_NOTIFICATION0x3C输入状态通知(用户正在输入)
50REMOTE_HOST_SUPPORTED_FEATURES_NOTIFICATION0x3D远程主机支持特性通知
51NUMBER_OF_COMPLETED_DATA_BLOCKS0x48LE 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 EnumSubevent Code (Hex)含义(根据 Bluetooth Core)
1CONNECTION_COMPLETE0x01LE 连接建立完成
2CONNECTION_UPDATE_COMPLETE0x03连接参数更新完成(间隔、超时等)
3DATA_LENGTH_CHANGE0x07数据包长度/时间改变(更长更高效)
4ENHANCED_CONNECTION_COMPLETE0x0A建立带地址类型的 LE 连接(支持隐私)
5PHY_UPDATE_COMPLETE0x0CPHY 更新完成(1M/2M/Coded PHY)
6READ_REMOTE_FEATURES_COMPLETE0x0B远程设备支持的 LE 特性
7REMOTE_CONNECTION_PARAMETER_REQUEST0x06对方请求修改连接参数
8READ_LOCAL_P256_PUBLIC_KEY_COMPLETE0x08本地 P-256 公钥生成完成(LE Secure Connections)
9GENERATE_DHKEY_COMPLETE0x09Diffie-Hellman 密钥生成完成(LE Secure Connections)
10DIRECTED_ADVERTISING_REPORT0x0B接收到 directed 广播(定向广告)
11EXTENDED_ADVERTISING_REPORT0x0D扩展广播数据报告(支持更多字段)
12PERIODIC_ADVERTISING_SYNC_ESTABLISHED0x0E成功同步周期性广播
13PERIODIC_ADVERTISING_REPORT0x0F周期性广播数据报告
14PERIODIC_ADVERTISING_SYNC_LOST0x10周期性广播同步丢失
15SCAN_TIMEOUT0x11扫描操作超时,无设备发现
16ADVERTISING_SET_TERMINATED0x12广播集终止
17SCAN_REQUEST_RECEIVED0x13收到 SCAN_REQ 请求(用于扫描响应)
18CHANNEL_SELECTION_ALGORITHM0x14通道选择算法设置通知
19CONNECTIONLESS_IQ_REPORT0x15AoA/AoD 连接无关 IQ 报告(方向查找)
20CONNECTION_IQ_REPORT0x16AoA/AoD 连接相关 IQ 报告
21CTE_REQUEST_FAILED0x17方向查找中的 CTE 请求失败
22PERIODIC_ADVERTISING_SYNC_TRANSFER_RECEIVED0x18从其他设备接收到同步周期性广播
23CIS_ESTABLISHED0x19ISO 数据通道 (CIS) 建立完成(LE Audio)
24CIS_REQUEST0x1A请求建立 ISO 数据流(CIS)
25CREATE_BIG_COMPLETE0x1B创建 BIG(Broadcast ISO Group)完成
26TERMINATE_BIG_COMPLETE0x1CBIG 广播终止
27BIG_SYNC_ESTABLISHED0x1DBIG 同步建立成功
28BIG_SYNC_LOST0x1EBIG 同步丢失
29REQUEST_PEER_SCA_COMPLETE0x1F请求远程设备的时钟准确度
30PATH_LOSS_THRESHOLD0x20接收信号路径损耗超出阈值通知
31TRANSMIT_POWER_REPORTING0x21发射功率状态报告(事件通知)
32BIG_INFO_ADVERTISING_REPORT0x22BIG 广播信息报告
33ADVERTISING_REPORT0x02普通广播数据报告(Legacy 广播)
34LONG_TERM_KEY_REQUEST0x05加密过程中的 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.cc

static 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.cc

void 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.cc

void on_hci_event(EventView event) {
	...
	event_handlers_[event_code].Invoke(event); // 根据 event, 调用不同的 回调
}
2. event_callback

当 有 hci_event 事件上来时,就会 调用到这里。

// system/main/shim/hci_layer.cc

static 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.cc

static 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.cc

void 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_EVTBT_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.cc

static 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.cc

void 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_callbackevent_callback 向上回调的逻辑都是一样的,都是通过 send_data_upwards 并且 都是 MSG_HC_TO_STACK_HCI_EVT,
所以最终也会 回调到 btu_hci_msg_process 中。

subevent_callbackevent_callback 区别就是向上回调传递的参数类型是不一样的。

三、btu 层处理

hci_event 和 le_meta_event 最终都会调用到 btu_hci_msg_processBT_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 size
  if (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.h
        case HCI_BLE_CONN_COMPLETE_EVT:  // SubeventCode::CONNECTION_COMPLETE
        case HCI_BLE_ENHANCED_CONN_COMPLETE_EVT:  // SubeventCode::ENHANCED_CONNECTION_COMPLETE
        default:
          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 module
    case HCI_NUM_COMPL_DATA_PKTS_EVT:  // EventCode::NUMBER_OF_COMPLETED_PACKETS
    case HCI_CONNECTION_COMP_EVT:  // EventCode::CONNECTION_COMPLETE
    case HCI_READ_RMT_FEATURES_COMP_EVT:  // EventCode::READ_REMOTE_SUPPORTED_FEATURES_COMPLETE
    case HCI_READ_RMT_VERSION_COMP_EVT:  // EventCode::READ_REMOTE_VERSION_INFORMATION_COMPLETE
    case HCI_ROLE_CHANGE_EVT:            // EventCode::ROLE_CHANGE
    default:
      LOG_ERROR(
          "Unexpectedly received event_code:0x%02x that should not be "
          "handled here",
          hci_evt_code);
      break;
  }
}

这里不再展开讲解了, 后面如果有机会介绍 某一个特定事件时, 在展开讲述。


📢 写到这里,已经掏心掏肺了,如果你看到这,说明你真的很有耐心!

如果这篇文章对你有一点点启发、哪怕只是让你少踩了一个坑,欢迎点个赞支持一下,让我知道这些分享是有价值的!

有疑问?有不同看法?或者有更骚的姿势?评论区欢迎你开麦!

顺手转发给你的同行、朋友、搭档、实习生、老板,没准哪天就用上了!

别光看不留言、别光学不点赞——不然你都不好意思从我博客页面退出啊,真的😉

### HCI_EVENT_LE_META 元事件概述 HCI (Host Controller Interface) 是蓝牙协议栈中的一个重要组成部分,负责在主机控制器之间传递数据指令。`HCI_EVENT_LE_Meta` 是一种特殊的元事件,属于低功耗蓝牙(Bluetooth Low Energy, BLE)的一部分[^1]。 #### `HCI_EVENT_LE_META` 的定义 `HCI_EVENT_LE_META` 是一个容器类事件,用于封装多个与低功耗蓝牙相关的子事件。这些子事件提供了关于 LE 设备状态变化、连接建立以及其他操作的结果反馈。通过设置 `LE Event Mask` 可以控制哪些具体的 LE 子事件被报告给主机[^2]。 --- ### Bluetooth Protocol Stack 中的 HCI Low Energy 事件列表 以下是常见的 HCI Low Energy 事件及其功能描述: 1. **LE Connection Complete (`0x01`)** - 表示两个设备之间的 LE 连接已成功完成。 - 提供连接句柄、角色以及链路参数等信息。 2. **LE Advertising Report (`0x02`)** - 报告扫描到的一个或多个广播包的内容。 - 包含广告设备的地址、RSSI 值以及广告数据。 3. **LE Connection Update Complete (`0x03`)** - 表明连接更新过程已完成。 - 返回新的连接间隔其他相关参数[^1]。 4. **LE Read Remote Used Features Complete (`0x04`)** - 当读取远程设备支持的功能完成后触发此事件。 - 列举了远程设备所支持的所有特性。 5. **LE Long Term Key Request (`0x05`)** - 请求加密所需的长期密钥(LTK),通常发生在安全连接过程中。 - 主机需响应提供有效的 LTK 或拒绝请求[^1]。 6. **LE Random Address Changed (`0x0D`)** - 如果本地随机地址发生变化,则会发送此通知。 - 新旧地址均会被包含在此消息中。 7. **LE Data Length Change (`0x0E`)** - 发生当最大传输单元大小或者有效负载长度改变时发出的通知。 - 描述新设定的最大 PDU 长度及 TX/RX 数据量限制。 8. **LE Enhanced Connection Complete (`0x0A`)** - 类似于标准连接完成事件,但它包含了更多细节比如 PHY 使用情况等附加字段[^1]。 9. **LE Direct Advertisement Report (`0x1B`)** - 特定类型的通告检测结果汇报;仅适用于定向扩展广告模式下匹配条件的目标发现情形. 10. **LE Scan Timeout (`0x0C`)** - 扫描活动超时时产生的信号提示用户采取进一步行动来维持预期行为正常运行[^1]. 以上列举并非详尽无遗,实际应用还可能存在其他特定用途的新加入项依据不同版本规范有所增减调整可能性存在. --- ### 示例代码展示如何解析 `HCI_EVENT_LE_META` 下面是一个简单的 Python 实现片段演示如何解码收到的数据流并提取其中嵌入的具体子类型: ```python def parse_le_meta_event(event_data): subevent_code = event_data[0] if subevent_code == 0x01: # LE Connection Complete status = event_data[1] connection_handle = int.from_bytes(event_data[2:4], byteorder='little') role = event_data[4] peer_address_type = event_data[5] peer_address = ':'.join(f'{byte:02X}' for byte in reversed(event_data[6:12])) print(f"Connection Status: {status}, Handle: {connection_handle}") print(f"Role: {'Master' if role == 0 else 'Slave'}, Peer Addr Type: {peer_address_type}") print(f"Peer Address: {peer_address}") # Example usage with dummy data dummy_event_data = bytes([0x01, 0x00, 0xCD, 0xAB, 0x00, 0x01, 0x11, 0x22, 0x33, 0x44, 0x55]) parse_le_meta_event(dummy_event_data) ``` --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值