当前位置: 首页 > news >正文

【Bluedroid】蓝牙启动之BTM_reset_complete源码解析

当蓝牙控制器完成硬件重置后,协议栈需通过一系列初始化操作恢复各模块状态。本文深入分析BTM_reset_complete核心函数及其调用链,详解 L2CAP 连接清理、安全模块重置、扫描参数恢复、BLE 隐私功能初始化等关键流程,揭示蓝牙设备在重置后如何通过标准化状态恢复确保互操作性、隐私安全与连接能力。

一、概述

蓝牙控制器重置(如硬件重启、故障恢复)后,协议栈需完成以下核心初始化工作。

1.1 L2CAP 层连接状态清理

l2cu_device_reset:遍历所有 L2CAP 链路控制块(LCB),模拟物理链路断开事件,强制清理残留连接,避免逻辑链路与物理状态不一致。

关键逻辑:通过l2c_link_hci_disc_comp触发链路断开回调,确保所有活跃连接被正确释放。

1.2 安全模块与扫描参数重置

安全状态清除:通过list_foreach遍历安全设备记录,将所有设备状态置为空闲(set_sec_state_idle),清除配对密钥等敏感信息。

扫描参数恢复:重置经典蓝牙扫描窗口(inq_scan_window)、扫描间隔(inq_scan_period)等参数为默认值(如HCI_DEF_INQUIRYSCAN_WINDOW),确保设备可被发现。

1.3 BLE 连接与隐私功能初始化

BLE 连接状态重置:调用connection_manager::reset清理应用层连接跟踪记录(bgconn_dev),同步控制器接受列表(Accept List)与广播过滤配置。

隐私功能初始化:当控制器支持 BLE 隐私时,通过btm_ble_resolving_list_init初始化解析列表,并设置随机私有地址超时时间(btsnd_hcic_ble_set_rand_priv_addr_timeout),平衡隐私保护与连接稳定性。

1.4 电源管理与缓冲区配置

电源管理重置btm_pm_reset清理挂起的电源请求,通知应用层请求失败,确保功耗控制状态一致。

缓冲区初始化l2c_link_initl2c_link_processs_ble_num_bufs配置 L2CAP 层的 ACL 缓冲区数量与发送窗口,优化数据传输效率。

二、源码解析

BTM_reset_complete

packages/modules/Bluetooth/system/stack/btm/btm_devctl.cc
void BTM_reset_complete() {const controller_t* controller = controller_get_interface();// 1. 通知 L2CAP 层连接断开/* Tell L2CAP that all connections are gone */l2cu_device_reset();// 2. 清除安全模块状态/* Clear current security state */list_foreach(btm_sec_cb.sec_dev_rec, set_sec_state_idle, NULL);// 3. 重置经典蓝牙扫描参数/* After the reset controller should restore all parameters to defaults. */btm_cb.btm_inq_vars.inq_counter = 1;btm_cb.btm_inq_vars.inq_scan_window = HCI_DEF_INQUIRYSCAN_WINDOW;btm_cb.btm_inq_vars.inq_scan_period = HCI_DEF_INQUIRYSCAN_INTERVAL;btm_cb.btm_inq_vars.inq_scan_type = HCI_DEF_SCAN_TYPE;btm_cb.btm_inq_vars.page_scan_window = HCI_DEF_PAGESCAN_WINDOW;btm_cb.btm_inq_vars.page_scan_period = HCI_DEF_PAGESCAN_INTERVAL;btm_cb.btm_inq_vars.page_scan_type = HCI_DEF_SCAN_TYPE;// 4. 重置 BLE 连接状态btm_cb.ble_ctr_cb.set_connection_state_idle();connection_manager::reset(true);// 5. 电源管理模块重置btm_pm_reset();// 6. 初始化 L2CAP 链路缓冲区l2c_link_init(controller->get_acl_buffer_count_classic());// 7. 初始化随机数生成器// setup the random number generatorstd::srand(std::time(nullptr));// 8. BLE 隐私功能初始化(关键条件分支)/* Set up the BLE privacy settings */// 仅当控制器支持 BLE、BLE 隐私功能,且解析列表(Resolving List)有容量时,才初始化隐私功能if (controller->SupportsBle() && controller->SupportsBlePrivacy() &&controller->get_ble_resolving_list_max_size() > 0) {btm_ble_resolving_list_init(controller->get_ble_resolving_list_max_size());/* set the default random private address timeout */btsnd_hcic_ble_set_rand_priv_addr_timeout(btm_get_next_private_addrress_interval_ms() / 1000);} else {log::info("Le Address Resolving list disabled due to lack of controller support");}// 9. 处理 BLE ACL 缓冲区数量if (controller->SupportsBle()) {l2c_link_processs_ble_num_bufs(controller->get_acl_buffer_count_ble());}// 10. 设置 PIN 码类型BTM_SetPinType(btm_sec_cb.cfg.pin_type, btm_sec_cb.cfg.pin_code,btm_sec_cb.cfg.pin_code_len);// 11. 解码控制器能力decode_controller_support();
}

在蓝牙控制器(Controller)完成硬件重置后,将协议栈各模块(如 L2CAP、安全、扫描、BLE 隐私等)的软件状态恢复到初始默认值,确保设备在重置后:

  • 各模块状态一致,无残留连接或配置;

  • 符合蓝牙标准,具备互操作性;

  • 隐私与安全功能(如 BLE 私有地址)正确初始化;

  • 默认参数(如扫描窗口)确保基本的发现与连接能力。

l2cu_device_reset

packages/modules/Bluetooth/system/stack/l2cap/l2c_utils.cc
/* The maximum number of simultaneous links that L2CAP can support. */
#ifndef MAX_L2CAP_LINKS
#define MAX_L2CAP_LINKS 16
#endif/********************************************************************************* Function         l2cu_device_reset** Description      This function is called when reset of the device is*                  completed.  For all active connection simulate HCI_DISC** Returns          void*******************************************************************************/
void l2cu_device_reset(void) {int xx;tL2C_LCB* p_lcb = &l2cb.lcb_pool[0];for (xx = 0; xx < MAX_L2CAP_LINKS; xx++, p_lcb++) {if ((p_lcb->in_use) && (p_lcb->Handle() != HCI_INVALID_HANDLE)) {l2c_link_hci_disc_comp(p_lcb->Handle(), HCI_ERR_UNDEFINED);}}
}

蓝牙设备重置(如重启、硬件复位)时,物理链路(ACL 链路)会被断开,但 L2CAP 层可能仍保留逻辑链路的残留状态(如未完成的分段、流量控制参数)。函数的核心作用是:

  • 输入:无(由上层模块在设备重置完成时调用,如前文中的 BTM_reset_complete);

  • 处理:遍历所有 L2CAP 链路控制块(LCB),模拟物理链路断开事件,强制清理活跃连接;

  • 输出:无(通过修改 L2CAP 内部状态间接生效)。

l2c_link_hci_disc_comp单独分析。

connection_manager::reset

/packages/modules/Bluetooth/system/stack/gatt/connection_manager.cc
// 记录针对单个蓝牙设备的多应用连接请求状态
struct tAPPS_CONNECTING {// ids of clients doing background connection to given device// 通过后台连接(Background Connection)方式尝试连接该设备的应用ID集合(如音乐 APP、健康监测 APP)std::set<tAPP_ID> doing_bg_conn;// 通过目标广播连接(Targeted Announcements)方式尝试连接的应用ID集合(适用于低功耗场景,设备仅响应特定目标的广播)  std::set<tAPP_ID> doing_targeted_announcements_conn;// 标记该设备是否被加入控制器的接受列表(Accept List)(控制器会优先响应列表中设备的连接请求,提升连接速度)bool is_in_accept_list;// 通过直接连接(Direct Connection)方式尝试连接的应用ID与超时闹钟的映射(unique_alarm_ptr用于管理连接超时,避免长时间挂起)// Apps trying to do direct connection.std::map<tAPP_ID, unique_alarm_ptr> doing_direct_conn;
};// 全局跟踪 “哪些应用正在以何种方式连接哪些设备”,避免重复连接请求(如同一应用多次发起连接)或冲突(如不同应用同时请求不同连接方式)
// Maps address to apps trying to connect to it
std::map<RawAddress, tAPPS_CONNECTING> bgconn_dev;/** Reset bg device list. If called after controller reset, set |after_reset|* to true, as there is no need to wipe controller acceptlist in this case. */
void reset(bool after_reset) {bgconn_dev.clear();//  同步控制器配置(仅非控制器重置场景)if (!after_reset) {target_announcements_filtering_set(false); // 关闭目标广播过滤BTM_AcceptlistClear(); // 清除控制器接受列表}
}

清理应用层的连接跟踪状态,并根据场景同步控制器(Controller)的连接相关配置(如接受列表、广播过滤)。

状态一致性:应用层与控制器同步

蓝牙连接流程涉及应用层(如手机 APP)、协议栈(如 GATT)和控制器(硬件)三层。当应用层主动重置连接状态时(如用户手动断开所有连接),不仅需要清理应用层的跟踪记录(bgconn_dev),还需同步控制器的配置(接受列表、广播过滤),确保三者状态一致。若控制器已硬件重置(after_reset = true),其内部配置(如接受列表)已被清空,无需重复操作。

target_announcements_filtering_set

packages/modules/Bluetooth/system/stack/gatt/connection_manager.cc
void target_announcements_filtering_set(bool enable) {log::debug("enable {}", enable);BTM_LogHistory(kBtmLogTag, RawAddress::kEmpty,(enable ? "Start filtering" : "Stop filtering"));//  调用适配层接口设置过滤状态/* Safe to call as if there is no support for filtering, this call will be* ignored. */bluetooth::shim::set_target_announcements_filter(enable);// 启动 / 停止目标广播观察BTM_BleTargetAnnouncementObserve(enable,target_announcement_observe_results_cb);
}

蓝牙 BLE设备在扫描时会接收大量广播包(如周边其他设备的广告)。目标广播(BLE 5.1 引入)允许设备仅向特定目标发送广播(如耳机仅向已配对的手机发送广播),减少无关设备的干扰。核心作用是启用或禁用蓝牙控制器对 BLE 目标广播的过滤,优化设备对广播包的处理效率与功耗。

目标广播(Targeted Announcements)是 BLE 5.1 的关键特性,主要解决传统广播的两大问题:

  • 功耗浪费:设备扫描时需处理大量无关广播包(如其他设备的广告),增加 CPU 和射频的功耗;

  • 连接延迟:设备需扫描多个广播周期才能发现目标设备,导致连接时间较长。

通过目标广播过滤,设备仅处理针对自己的广播包,显著降低扫描功耗(减少 80% 以上的无关包处理),同时缩短连接时间(目标广播包的发送间隔更短)。

target_announcement_observe_results_cb
packages/modules/Bluetooth/system/stack/gatt/connection_manager.cc
static void target_announcement_observe_results_cb(tBTM_INQ_RESULTS* p_inq,const uint8_t* p_eir,uint16_t eir_len) {// 1. 检查设备是否在目标管理列表中auto addr = p_inq->remote_bd_addr;auto it = bgconn_dev.find(addr);if (it == bgconn_dev.end() ||it->second.doing_targeted_announcements_conn.empty()) {return;}// 2. 判断是否为目标通告if (!IsTargetedAnnouncement(p_eir, eir_len)) {log::debug("Not a targeted announcement for device {}",ADDRESS_TO_LOGGABLE_CSTR(addr));return;}log::info("Found targeted announcement for device {}",ADDRESS_TO_LOGGABLE_CSTR(addr));// 3. 过滤已连接或正在连接的设备if (it->second.is_in_accept_list) {log::info("Device {} is already connecting",ADDRESS_TO_LOGGABLE_CSTR(addr));return;}if (BTM_GetHCIConnHandle(addr, BT_TRANSPORT_LE) != 0xFFFF) {log::debug("Device {} already connected", ADDRESS_TO_LOGGABLE_CSTR(addr));return;}BTM_LogHistory(kBtmLogTag, addr, "Found TA from");// 4. 触发直接连接流程/* Take fist app_id and use it for direct_connect */auto app_id = *(it->second.doing_targeted_announcements_conn.begin());/* If scan is ongoing lets stop it */do_in_main_thread(FROM_HERE,base::BindOnce(schedule_direct_connect_add, app_id, addr));
}

当蓝牙控制器检测到目标设备的通告(广播包)时,通过这个回调函数判断是否需要发起连接。

IsTargetedAnnouncement

packages/modules/Bluetooth/system/stack/gatt/connection_manager.cc
bool IsTargetedAnnouncement(const uint8_t* p_eir, uint16_t eir_len) {// 1. 遍历广播数据中的服务数据字段const uint8_t* p_service_data = p_eir;uint8_t service_data_len = 0;while ((p_service_data = AdvertiseDataParser::GetFieldByType(p_service_data + service_data_len,eir_len - (p_service_data - p_eir) - service_data_len,BTM_BLE_AD_TYPE_SERVICE_DATA_TYPE, &service_data_len))) {uint16_t uuid;uint8_t announcement_type;const uint8_t* p_tmp = p_service_data;// 2. 校验服务数据长度if (service_data_len < 3) {continue;}// 3. 提取并校验服务 UUIDSTREAM_TO_UINT16(uuid, p_tmp);log::debug("Found UUID 0x{:04x}", uuid);if (uuid != 0x184E && uuid != 0x1853) {continue;}// 4. 提取并判断通告类型STREAM_TO_UINT8(announcement_type, p_tmp);log::debug("Found announcement_type 0x{:02x}", announcement_type);if (announcement_type == 0x01) {return true;}}return false;
}

根据蓝牙设备的广播数据(EIR),判断是否为 “目标通告”(仅针对特定设备的定向广播)。

schedule_direct_connect_add

packages/modules/Bluetooth/system/stack/gatt/connection_manager.cc
static void schedule_direct_connect_add(uint8_t app_id,const RawAddress& address) {direct_connect_add(app_id, address);
}

direct_connect_add单独分析。

bluetooth::shim::set_target_announcements_filter
packages/modules/Bluetooth/system/main/shim/le_scanning_manager.cc
void bluetooth::shim::set_target_announcements_filter(bool enable) {uint8_t filter_index = 0x03;LOG_DEBUG(" enable %d", enable);// 1. 删除现有过滤配置(无论是否启用)bluetooth::hci::AdvertisingFilterParameter advertising_filter_parameter = {};bluetooth::shim::GetScanning()->ScanFilterParameterSetup(bluetooth::hci::ApcfAction::DELETE, filter_index,advertising_filter_parameter);// 2. 仅启用过滤时添加新配置if (!enable) return;// 3. 核心过滤器:匹配 CAP/BAP 广播包// 通过 cap_bap_filter 定义具体的广播包内容过滤规则,目标是匹配蓝牙音频相关的 CAP(Connectionless Audio Profile)和 BAP(Broadcast Audio Profile)广播包advertising_filter_parameter.delivery_mode =bluetooth::hci::DeliveryMode::IMMEDIATE;advertising_filter_parameter.feature_selection = kAllowServiceDataFilter;advertising_filter_parameter.list_logic_type = kListLogicOr;advertising_filter_parameter.filter_logic_type = kFilterLogicAnd;advertising_filter_parameter.rssi_high_thresh = kLowestRssiValue;/* Add targeted announcements filter on index 4 */std::vector<bluetooth::hci::AdvertisingPacketContentFilterCommand>cap_bap_filter = {};// CAP 过滤器bluetooth::hci::AdvertisingPacketContentFilterCommand cap_filter{};cap_filter.filter_type = bluetooth::hci::ApcfFilterType::SERVICE_DATA;cap_filter.data = {0x53, 0x18, 0x01};cap_filter.data_mask = {0x53, 0x18, 0xFF};cap_bap_filter.push_back(cap_filter);// BAP 过滤器bluetooth::hci::AdvertisingPacketContentFilterCommand bap_filter{};bap_filter.filter_type = bluetooth::hci::ApcfFilterType::SERVICE_DATA;bap_filter.data = {0x4e, 0x18, 0x01};bap_filter.data_mask = {0x4e, 0x18, 0xFF};//  过滤器添加// 广播包只需匹配 CAP 或 BAP 中的任意一个过滤器,即被判定为目标广播包cap_bap_filter.push_back(bap_filter);bluetooth::shim::GetScanning()->ScanFilterAdd(filter_index, cap_bap_filter);bluetooth::shim::GetScanning()->ScanFilterParameterSetup(bluetooth::hci::ApcfAction::ADD, filter_index,advertising_filter_parameter);
}

通过 HCI 接口配置控制器的广告包内容过滤规则(APCF),仅接收和处理音频设备(CAP/BAP)的目标广播包。其设计点在于:

  • 功耗优化:控制器过滤无关广播包,减少主机 CPU 负载;

  • 连接加速:针对音频服务的精准过滤,缩短连接时间;

  • 兼容性:掩码设计允许同一服务的不同子类型广播包被匹配;

  • 鲁棒性:先删除旧配置再添加新规则,避免状态冲突。

AdvertisingFilterParameter

packages/modules/Bluetooth/system/gd/hci/le_scanning_callback.h
class AdvertisingFilterParameter {public:uint16_t feature_selection;uint16_t list_logic_type;uint8_t filter_logic_type;uint8_t rssi_high_thresh;DeliveryMode delivery_mode;uint16_t onfound_timeout;uint8_t onfound_timeout_cnt;uint8_t rssi_low_thresh;uint16_t onlost_timeout;uint16_t num_of_tracking_entries;
};packages/modules/Bluetooth/system/pdl/hci/hci_packets.pdl
// 举定义了控制器将符合过滤条件的广播包上报给主机(如手机 CPU)的模式
enum DeliveryMode : 8 {IMMEDIATE = 0x00,ONFOUND = 0x01,BATCHED = 0x02,
}

定义了广告包内容过滤的全局行为参数,用于控制控制器如何处理符合过滤条件的广播包。其字段对应 HCI 规范中的 “广告过滤参数”(HCI_LE_Set_Advertising_Filter_Parameter 命令参数),是 APCF 功能的核心配置项。

各字段的详细说明:

字段名类型HCI 规范对应参数含义与作用
feature_selectionuint16_tFeature Selection位掩码,用于启用特定的过滤功能(如服务数据过滤、设备地址过滤等)。例如 kAllowServiceDataFilter(0x0002)表示启用服务数据过滤。
list_logic_typeuint16_tList Logic Type多个过滤器列表(Filter List)间的逻辑关系,可选值为 kListLogicAnd(逻辑与)或 kListLogicOr(逻辑或)。例如两个列表时,OR表示任一列表匹配即生效。
filter_logic_typeuint8_tFilter Logic Type同一过滤器列表内多个过滤器(Filter)间的逻辑关系,可选值为 kFilterLogicAnd(逻辑与)或 kFilterLogicOr(逻辑或)。例如一个列表包含两个过滤器时,AND表示需同时匹配。
rssi_high_threshuint8_tRSSI High ThresholdRSSI(接收信号强度)的上限阈值(单位:dBm,取值范围 - 127~+20)。仅当广播包的 RSSI ≤ 此值时,才被判定为符合条件。
delivery_modeDeliveryModeDelivery Mode控制器上报符合条件广播包的模式(见下文DeliveryMode枚举解析)。
onfound_timeoutuint16_tOnFound Timeout仅当delivery_mode为ONFOUND时有效,表示 “首次发现广播包” 到 “上报” 的超时时间(单位:0.625ms)。
onfound_timeout_cntuint8_tOnFound Timeout Count仅当delivery_mode为ONFOUND时有效,表示触发上报前需连续接收的广播包次数(避免误报)。
rssi_low_threshuint8_tRSSI Low ThresholdRSSI 的下限阈值(单位:dBm)。仅当广播包的 RSSI ≥ 此值时,才被判定为符合条件(与rssi_high_thresh配合形成 RSSI 区间过滤)。
onlost_timeoutuint16_tOnLost Timeout仅当delivery_mode为BATCHED时有效,表示 “最后一次接收广播包” 到 “上报丢失” 的超时时间(单位:0.625ms)。
num_of_tracking_entriesuint8_tNumber of Tracking Entries控制器可同时跟踪的广播源数量(即最多同时处理多少个设备的广播包)。

广播包的 “上报策略”,其取值对应HCI 规范中的 “传递模式”(Delivery Mode),具体含义如下:

枚举值十六进制值HCI 规范定义适用场景与效果
IMMEDIATE0x00立即传递(Immediate Delivery)控制器每收到一个符合过滤条件的广播包,立即上报给主机。
特点:低延迟(适合实时性要求高的场景,如音频连接),但可能增加主机负载(频繁上报)。
ONFOUND0x01发现后传递(OnFound Delivery)控制器检测到新的广播源(设备)时,等待onfound_timeout时间或收到onfound_timeout_cnt次广播包后,再上报。
特点:减少上报次数(降低功耗),但增加延迟(适合后台扫描)。
BATCHED0x02批量传递(Batched Delivery)控制器缓存符合条件的广播包,按固定时间间隔(由onlost_timeout决定)批量上报。
特点:最低功耗(减少主机唤醒次数),但延迟最高(适合低实时性场景,如设备发现)。
BTM_BleTargetAnnouncementObserve
packages/modules/Bluetooth/system/stack/btm/btm_ble_bgconn.cc
/** Clear the acceptlist, end any pending acceptlist connections */
void BTM_AcceptlistClear() {if (!controller_get_interface()->SupportsBle()) {log::warn("Controller does not support Le");return;}bluetooth::shim::ACL_IgnoreAllLeConnections();
}

注册或注销目标广播的回调函数,使上层模块(如 GATT 连接管理器)能在控制器接收到符合条件的目标广播包时,触发自定义的处理逻辑(如发起连接)。

目标广播的完整处理流程如下:

1. 配置过滤规则(set_target_announcements_filter

控制器被配置为仅接收和处理符合特定条件的广播包(如 CAP/BAP 服务数据)。

2. 注册回调函数(BTM_BleTargetAnnouncementObserve(true, cb)

上层模块(如连接管理器)注册回调函数 cb,用于处理检测到的目标广播包。

3. 控制器检测并上报广播包

当控制器收到符合过滤条件的广播包时,将其基础信息(地址、RSSI)和 EIR 数据传递给 BTM 模块。

4. BTM 模块触发回调

BTM 模块调用注册的回调函数 cb,将广播包信息传递给上层模块。

5. 上层处理(如发起连接)

上层模块(如连接管理器)解析广播包信息(如设备地址、服务数据),触发连接请求或其他业务逻辑(如音频设备配对)。

BTM_AcceptlistClear

packages/modules/Bluetooth/system/stack/btm/btm_ble_bgconn.cc
/** Clear the acceptlist, end any pending acceptlist connections */
void BTM_AcceptlistClear() {if (!controller_get_interface()->SupportsBle()) {log::warn("Controller does not support Le");return;}bluetooth::shim::ACL_IgnoreAllLeConnections();
}

蓝牙 BLE 的接受列表(Accept List)是控制器(硬件)维护的一个设备地址白名单。控制器在扫描或监听时,会优先响应列表中设备的连接请求(如缩短连接建立时间、降低功耗)。函数的核心作用是清除控制器的接受列表,使控制器停止优先处理列表中设备的连接请求,确保连接状态的一致性。

bluetooth::shim::ACL_IgnoreAllLeConnections
packages/modules/Bluetooth/system/main/shim/acl_api.cc
void bluetooth::shim::ACL_IgnoreAllLeConnections() {return Stack::GetInstance()->GetAcl()->ClearFilterAcceptList();
}packages/modules/Bluetooth/system/main/shim/acl.cc
// 异步任务派发
void shim::legacy::Acl::ClearFilterAcceptList() {handler_->CallOn(pimpl_.get(), &Acl::impl::clear_acceptlist);
}

通过适配层接口,将上层的 “清除接受列表” 请求传递给底层控制器,确保硬件层面的接受列表被正确清理。

clear_acceptlist
packages/modules/Bluetooth/system/main/shim/acl.cc
// 本地缓存与硬件清除的协同
void clear_acceptlist() {auto shadow_acceptlist = shadow_acceptlist_.GetCopy();  // 获取本地缓存的接受列表副本size_t count = shadow_acceptlist.size();                 // 记录待清除的地址数量GetAclManager()->ClearFilterAcceptList();                // 触发硬件接受列表清除shadow_acceptlist_.Clear();                              // 清除本地缓存LOG_DEBUG("Cleared entire Le address acceptlist count:%zu", count); 
}packages/modules/Bluetooth/system/gd/hci/acl_manager.cc
// 硬件清除的异步派发
void AclManager::ClearFilterAcceptList() {// 将任务派发到蓝牙协议栈的低功耗蓝牙(LE)专用线程,避免并发问题CallOn(pimpl_->le_impl_, &le_impl::clear_filter_accept_list);
}

同步清除硬件控制器的接受列表与协议栈的本地缓存,确保软件状态与硬件状态一致。

shadow_acceptlist_ 的作用: 协议栈维护的本地接受列表缓存,存储当前添加到控制器接受列表的设备地址(如RawAddress)。其存在价值是:

  • 状态同步:当硬件接受列表被修改(如添加 / 删除地址)时,本地缓存同步更新,确保协议栈上层(如连接管理器)查询接受列表状态时,能快速获取软件缓存的结果(无需等待硬件响应);

  • 错误恢复:若硬件清除操作失败(如 HCI 命令超时),本地缓存可作为 “最后已知状态”,供上层重新尝试清除。

clear_filter_accept_list
packages/modules/Bluetooth/system/gd/hci/acl_manager/le_impl.h
bool address_manager_registered = false;void clear_filter_accept_list() {// 1. 清空本地接受列表缓存accept_list.clear();// 2. 注册地址管理器register_with_address_manager();// 3. 触发地址管理器清除硬件接受列表le_address_manager_->ClearFilterAcceptList();
}void register_with_address_manager() {// 1. 注册状态检查if (!address_manager_registered) {// 2. 注册到地址管理器le_address_manager_->Register(this);      address_manager_registered = true;// 3. 暂停连接请求pause_connection = true;}
}

同步清除本地接受列表缓存、注册地址管理器依赖,并触发地址管理器清除硬件接受列表,确保蓝牙设备的地址管理与连接过滤状态一致。

LeAddressManager::ClearFilterAcceptList
packages/modules/Bluetooth/system/gd/hci/le_address_manager.cc
void LeAddressManager::ClearFilterAcceptList() {// 1. 构造 HCI 命令包auto packet_builder = hci::LeClearFilterAcceptListBuilder::Create();// 2. 封装命令对象Command command = {CommandType::CLEAR_ACCEPT_LIST, HCICommand{std::move(packet_builder)}};// 3. 异步派发命令handler_->BindOnceOn(this, &LeAddressManager::push_command, std::move(command)).Invoke();
}

BLE接受列表硬件级清除功能的最终实现,构造 HCI(主机控制器接口)命令并发送至蓝牙控制器,触发硬件层面的接受列表清除操作。

push_command
packages/modules/Bluetooth/system/gd/hci/le_address_manager.cc
// 通过遍历注册的客户端(如连接管理器、扫描管理器),根据客户端当前状态动态调整其状态并触发暂停回调,确保客户端在 HCI 命令处理期间处于 “暂停” 状态,避免干扰命令执行
void LeAddressManager::pause_registered_clients() {for (auto& client : registered_clients_) {switch (client.second) {case ClientState::PAUSED:case ClientState::WAITING_FOR_PAUSE:break;case WAITING_FOR_RESUME:case RESUMED:client.second = ClientState::WAITING_FOR_PAUSE;client.first->OnPause();break;}}
}std::queue<Command> cached_commands_;
void LeAddressManager::push_command(Command command) {pause_registered_clients();cached_commands_.push(std::move(command));
}

将 HCI 命令缓存到队列(cached_commands_),并在缓存前调用pause_registered_clients暂停所有客户端,确保命令处理期间客户端状态稳定,避免并发操作导致的状态混乱。

  enum ClientState {WAITING_FOR_PAUSE,PAUSED,WAITING_FOR_RESUME,RESUMED,};

ClientState枚举包含的状态:

状态含义
PAUSED客户端已暂停,不处理新操作(如停止地址解析、连接请求)。
WAITING_FOR_PAUSE客户端正在等待暂停(已触发暂停请求,但尚未完成暂停操作)。
WAITING_FOR_RESUME客户端正在等待恢复(已触发恢复请求,但尚未完成恢复操作)。
RESUMED客户端已恢复,正常处理操作(如继续地址解析、发送连接请求)。

接受列表清除的完整链路如下:

connection_manager::reset(false) → BTM_AcceptlistClear() → bluetooth::shim::ACL_IgnoreAllLeConnections() → shim::legacy::Acl::ClearFilterAcceptList() → le_impl::clear_filter_accept_list() → LeAddressManager::ClearFilterAcceptList() → push_command() → 发送HCI_LE_Clear_Filter_Accept_List命令 → 控制器清除接受列表

btm_pm_reset

packages/modules/Bluetooth/system/stack/acl/btm_pm.cc
tBTM_PM_RCB pm_reg_db; /* per application/module *//********************************************************************************* Function         btm_pm_reset** Description      as a part of the BTM reset process.** Returns          void*******************************************************************************/
void btm_pm_reset(void) {// 1. 清理挂起请求的回调准备tBTM_PM_STATUS_CBACK* cb = NULL;/* clear the pending request for application */if ((pm_pend_id != BTM_PM_SET_ONLY_ID) && (pm_reg_db.mask & BTM_PM_REG_SET)) {cb = pm_reg_db.cback;}// 2. 重置注册数据库状态pm_reg_db.mask = BTM_PM_REC_NOT_USED;// 3. 通知应用层挂起请求失败if (cb != NULL && pm_pend_link != 0) {const RawAddress raw_address = pm_mode_db[pm_pend_link].bda_;(*cb)(raw_address, BTM_PM_STS_ERROR, BTM_DEV_RESET, HCI_SUCCESS);}// 4. 彻底清理状态/* no command pending */pm_pend_link = 0;          // 无挂起链路pm_mode_db.clear();        // 清空模式数据库(所有链路的电源状态)pm_pend_id = 0;            // 无挂起请求IDmemset(&pm_reg_db, 0, sizeof(pm_reg_db));  // 注册数据库内存归零log::info("reset pm");  
}

清理电源管理的挂起请求、重置注册状态,并通知应用层未完成的请求失败,确保蓝牙模块在重置后从 “干净状态” 重新启动。

1. 避免残留状态干扰

蓝牙模块重置时(如硬件重启、软件故障恢复),电源管理可能存在未完成的请求(如正在协商低功耗模式的链路)。btm_pm_reset 通过清理pm_mode_db(模式数据库)和pm_pend_link(挂起链路),避免残留状态导致后续连接出现异常(如错误地沿用旧的低功耗配置)。

2. 应用层的 “失败告知”

应用层可能正在等待电源管理请求的响应(如设置低功耗模式后等待成功通知)。通过调用cb回调,应用层可感知请求失败(原因是设备重置),并执行相应的处理(如重新初始化、提示用户)。这一设计符合 “错误透明” 原则,提升了系统的可维护性。

l2c_link_init

packages/modules/Bluetooth/system/stack/l2cap/l2c_link.cc
tL2C_CB l2cb;void l2c_link_init(const uint16_t acl_buffer_count_classic) {// 将 L2CAP 层管理的 ACL 缓冲区数量设置为传入值// 缓冲区用于临时存储待发送的 L2CAP 分组,避免因控制器处理延迟导致的数据丢失l2cb.num_lm_acl_bufs = acl_buffer_count_classic;// 将控制器的发送窗口大小设置为与缓冲区数量相同的值// 发送窗口是流量控制的核心参数,决定了控制器在未收到确认前可发送的最大分组数(窗口大小越大,吞吐量越高,但可能增加丢包风险)l2cb.controller_xmit_window = acl_buffer_count_classic;
}

初始化 L2CAP 控制块的关键参数,为后续 L2CAP 链路的数据传输和流量控制提供基础配置。

btm_ble_resolving_list_init

单独分析。

btsnd_hcic_ble_set_rand_priv_addr_timeout

packages/modules/Bluetooth/system/stack/hcic/hciblecmds.cc
/* local Bluetooth controller id for AMP HCI */
#define LOCAL_BR_EDR_CONTROLLER_ID 0
#define HCIC_PARAM_SIZE_BLE_SET_RAND_PRIV_ADDR_TIMOUT 2
#define HCI_BLE_SET_ADDR_RESOLUTION_ENABLE (0x002D | HCI_GRP_BLE_CMDS)void btsnd_hcic_ble_set_rand_priv_addr_timeout(uint16_t rpa_timout) {// 1. 内存分配:创建 HCI 命令缓冲区BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);uint8_t* pp = (uint8_t*)(p + 1);// 2. 填充 HCI 命令头p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_BLE_SET_RAND_PRIV_ADDR_TIMOUT;p->offset = 0;// 3. 构造 HCI 命令内容UINT16_TO_STREAM(pp, HCI_BLE_SET_RAND_PRIV_ADDR_TIMOUT);UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_BLE_SET_RAND_PRIV_ADDR_TIMOUT);UINT16_TO_STREAM(pp, rpa_timout);// 4. 发送 HCI 命令btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
}

构造并发送 HCI(主机控制器接口)命令,通知蓝牙控制器设置随机私有地址的超时时间,控制设备地址的更换频率,从而平衡隐私性与连接稳定性。

蓝牙 BLE 的随机私有地址(Random Private Address)是提升设备隐私性的关键机制:设备通过定期更换地址(如每 15 分钟),避免被长期跟踪。函数的作用是:

  • 输入:随机私有地址的超时时间(rpa_timout,单位:分钟);

  • 处理:构造 HCI 命令并发送到蓝牙控制器;

  • 输出:控制器根据命令设置地址更换的超时时间。

l2c_link_processs_ble_num_bufs

packages/modules/Bluetooth/system/stack/l2cap/l2c_ble.cc
/* Number of ACL buffers to assign to LE */
/** TODO: Do we need this?* It was used when the HCI buffers were shared with BR/EDR.*/
#ifndef L2C_DEF_NUM_BLE_BUF_SHARED
#define L2C_DEF_NUM_BLE_BUF_SHARED 1
#endif/********************************************************************************* Function         l2c_link_processs_ble_num_bufs** Description      This function is called when a "controller buffer size"*                  event is first received from the controller. It updates*                  the L2CAP values.** Returns          void*******************************************************************************/
void l2c_link_processs_ble_num_bufs(uint16_t num_lm_ble_bufs) {// 参数处理:默认值分配(共享缓冲区场景)if (num_lm_ble_bufs == 0) {num_lm_ble_bufs = L2C_DEF_NUM_BLE_BUF_SHARED;  // 默认分配1个缓冲区给BLEl2cb.num_lm_acl_bufs -= L2C_DEF_NUM_BLE_BUF_SHARED; // 从经典蓝牙缓冲区中扣除1个}// 更新 L2CAP 控制块参数l2cb.num_lm_ble_bufs = num_lm_ble_bufs; // 设置LE专用的ACL缓冲区数量l2cb.controller_le_xmit_window = num_lm_ble_bufs; // 设置LE的发送窗口大小
}

处理控制器上报的 BLE ACL 缓冲区数量,并动态调整 L2CAP 层的关键参数(如缓冲区数量和发送窗口)。

早期蓝牙控制器(尤其是低成本或单芯片方案)的 ACL 缓冲区是有限的硬件资源,BLE 与经典蓝牙(BR/EDR)可能共享同一组 ACL 缓冲区(而非独立分配)。此时,需要动态协调两者的缓冲区分配,避免资源竞争。

BTM_SetPinType

packages/modules/Bluetooth/system/stack/btm/btm_sec.cctBTM_SEC_CB btm_sec_cb; // 存储蓝牙安全相关的配置与状态/********************************************************************************* Function         BTM_SetPinType** Description      Set PIN type for the device.** Returns          void*******************************************************************************/
void BTM_SetPinType(uint8_t pin_type, PIN_CODE pin_code, uint8_t pin_code_len) {log::verbose("BTM_SetPinType: pin type {} [variable-0, fixed-1], code {}, length {}",pin_type, (char*)pin_code, pin_code_len);// 条件判断:是否需要同步到控制器/* If device is not up security mode will be set as a part of startup */if ((btm_sec_cb.cfg.pin_type != pin_type) &&controller_get_interface()->get_is_ready()) {btsnd_hcic_write_pin_type(pin_type);}// 更新本地安全配置btm_sec_cb.cfg.pin_type = pin_type;btm_sec_cb.cfg.pin_code_len = pin_code_len;memcpy(btm_sec_cb.cfg.pin_code, pin_code, pin_code_len);
}

设置蓝牙设备的 PIN 码类型(可变 / 固定)及具体 PIN 码值,是蓝牙配对过程中身份验证的关键配置逻辑。

在蓝牙传统配对(非 SSP 简单安全配对)流程中,PIN 码(Personal Identification Number)是设备间身份验证的核心凭证。函数的作用是:

  • 输入:PIN 类型(可变 / 固定)、PIN 码值及长度;

  • 处理:更新本地安全配置,并通过 HCI 命令同步到蓝牙控制器;

  • 输出:控制器根据配置调整配对行为(如是否提示用户输入 PIN 码)。

btsnd_hcic_write_pin_type
packages/modules/Bluetooth/system/stack/hcic/hcicmds.cc
void btsnd_hcic_write_pin_type(uint8_t type) {BT_HDR* p = (BT_HDR*)osi_malloc(HCI_CMD_BUF_SIZE);uint8_t* pp = (uint8_t*)(p + 1);p->len = HCIC_PREAMBLE_SIZE + HCIC_PARAM_SIZE_WRITE_PARAM1;p->offset = 0;UINT16_TO_STREAM(pp, HCI_WRITE_PIN_TYPE);UINT8_TO_STREAM(pp, HCIC_PARAM_SIZE_WRITE_PARAM1);UINT8_TO_STREAM(pp, type);btu_hcif_send_cmd(LOCAL_BR_EDR_CONTROLLER_ID, p);
}

在蓝牙传统配对(非 SSP 简单安全配对)中,PIN 码类型(可变 / 固定)决定了配对时的用户交互方式:

  • 可变 PIN(用户输入):控制器会提示用户输入 PIN 码(如手机弹出输入框);

  • 固定 PIN(预设值):控制器直接使用预设的 PIN 码完成配对(如智能设备默认0000)。

函数的作用是将上层配置的 PIN 类型(由BTM_SetPinType调用)转换为 HCI 命令,发送到蓝牙控制器,确保控制器按配置执行配对逻辑。

decode_controller_support

单独分析。

三、 核心流程图

四、时序图


http://www.lqws.cn/news/551809.html

相关文章:

  • GitHub Actions 实现 AWS ECS 服务的多集群安全重启方案
  • 《剖开WebAssembly 2.0:C++/Rust内存管理困局与破局》
  • 移动端日志平台EMAS
  • 接口自动化测试框架详解
  • 领域驱动设计(DDD)【22】之限定建模技术
  • 现代串口通讯UI框架性能对比
  • 【数据标注师】目标跟踪标注
  • 【MySQL数据库 | 第十篇】DCL语句----用户管理+权限控制
  • 商业秘密中经营信息的法律保护探析——以客户名册为例
  • ZooKeeper深度面试指南二
  • SpringMVC系列(七)(Restful架构风格(下))(完结篇)
  • 什么是哈希链(Hash Chain)?
  • 计算机组成原理-数据表示与运算(三)
  • 【数据结构】AVL树和红黑树的Insert(插入)(实现map.insert)
  • SpringBoot 防刷 重复提交问题 重复点击问题 注解 RequestParam RequestBody
  • 如何在 Manjaro Linux 上安装 Deepin 桌面
  • 构建证据的系统性知识体系:从理论到实践的完整指南
  • MyBatis 缓存机制详解
  • Python打卡:Day39
  • Java--数组
  • python打卡day56
  • 智能助手(利用GPT搭建智能系统)
  • Netty 的 PooledByteBuf与PooledHeapByteBuf​​
  • Day44 预训练模型
  • MySQL 连接指定端口后,为什么实际仍是 3306?
  • 【深度学习新浪潮】MoE技术入门(简要版)
  • 基于JavaWeb的校园失物招领系统设计与实现
  • 智能制造数字孪生集成交付生态链:智慧产线极速克隆,孪生重构生产周期
  • 飞牛OS安装zerotier组自己的虚拟局域网
  • 利用python实现NBA数据可视化