【Bluedroid】蓝牙启动之btm_ble_init源码分析
本文围绕BLE协议栈的核心模块展开,重点解析 btm_ble_init
初始化函数、供应商能力管理(tBTM_BLE_VSC_CB
)、广播过滤功能(btm_ble_adv_filter_init
)及动态配置机制(ble_vnd_is_included
)的实现逻辑。通过分析关键数据结构(如 tBTM_BLE_ADV_FILTER_CB
控制块)、硬件能力获取接口(BTM_BleGetVendorCapabilities
)及支持性检查(is_filtering_supported
),揭示了 BLE 协议栈如何通过状态重置、资源动态分配、硬件能力适配实现功能的稳定运行与灵活扩展。
一、概述
BLE协议栈的高效运行依赖于核心模块的初始化、硬件能力适配及功能动态配置。本文涉及的核心模块包括:
1.1 BLE 控制块初始化(btm_ble_init
)
作为 BLE 功能启动的基础,btm_ble_init
负责:
-
资源清理与重置:释放旧定时器资源,通过
memset
清零 BLE 控制块(tBTM_BLE_CB
)和供应商能力控制块(tBTM_BLE_VSC_CB
),确保初始状态的 “干净”。 -
关键资源初始化:创建新定时器(如观察者模式定时器、快速广播定时器),配置 BLE 功能默认参数(广播通道、滤波策略、连接模式等)。
-
扩展功能触发:根据
ble_vnd_is_included
判断是否启用供应商扩展功能(如广播过滤),实现运行时动态开关。
1.2 供应商能力管理(tBTM_BLE_VSC_CB
与 BTM_BleGetVendorCapabilities
)
btm_ble_init
初始化阶段通过与硬件控制器交互(如 HCI 命令)填充 tBTM_BLE_VSC_CB
结构体,存储 BLE 控制器的关键能力(如最大广播实例数、过滤条目数、音频卸载能力等)。BTM_BleGetVendorCapabilities
接口封装了全局能力参数的访问,为其他模块(如广播过滤)提供硬件能力的只读访问,确保功能与硬件限制匹配。
1.3 广播过滤功能实现(btm_ble_adv_filter_init
与 tBTM_BLE_ADV_FILTER_CB
)
广播过滤是 BLE 核心功能之一(如白名单、黑名单),其初始化流程包括:
-
控制块重置:清零
tBTM_BLE_ADV_FILTER_CB
控制块,存储过滤规则的启用状态、操作类型及目标地址。 -
硬件能力检查:通过
is_filtering_supported
判断控制器是否支持过滤类型(filter_support
)及过滤条目容量(max_filter
),避免为不支持的功能分配资源。 -
动态内存分配:根据
max_filter
动态分配tBTM_BLE_PF_COUNT
数组(记录单个地址的过滤匹配计数),实现资源按需使用。
1.4 动态配置机制(ble_vnd_is_included
)
通过读取系统属性(bluetooth.ble.vnd.included
)替代传统编译宏,允许在不重新编译代码的情况下动态启用 / 禁用供应商扩展功能(如厂商私有广播格式),提升协议栈的灵活性与设备适配性。
二、源码分析
btm_ble_init
packages/modules/Bluetooth/system/stack/btm/btm_ble_gap.cc
/* Global BTM control block structure
*/
tBTM_CB btm_cb;/* advertising channel map */
#define BTM_BLE_ADV_CHNL_37 (0x01 << 0)
#define BTM_BLE_ADV_CHNL_38 (0x01 << 1)
#define BTM_BLE_ADV_CHNL_39 (0x01 << 2)/*d efault advertising channel map */
#ifndef BTM_BLE_DEFAULT_ADV_CHNL_MAP
#define BTM_BLE_DEFAULT_ADV_CHNL_MAP \(BTM_BLE_ADV_CHNL_37 | BTM_BLE_ADV_CHNL_38 | BTM_BLE_ADV_CHNL_39)
#endif/* advertising filter policy */
#define AP_SCAN_CONN_ALL 0x00 /* default */
#define AP_SCAN_WL_CONN_ALL 0x01
#define AP_SCAN_ALL_CONN_WL 0x02
#define AP_SCAN_CONN_WL 0x03
#define AP_SCAN_CONN_POLICY_MAX 0x04
typedef uint8_t tBTM_BLE_AFP;/* default advertising filter policy */
#ifndef BTM_BLE_DEFAULT_AFP
#define BTM_BLE_DEFAULT_AFP AP_SCAN_CONN_ALL
#endif/* scanning filter policy */
/* 0: accept adv packet from all, directed adv pkt not directed */
/* to local device is ignored */
#define SP_ADV_ALL 0x00typedef uint8_t tBTM_BLE_SFP;#ifndef BTM_BLE_DEFAULT_SFP
#define BTM_BLE_DEFAULT_SFP SP_ADV_ALL
#endif/********************************************************************************* Function btm_ble_init** Description Initialize the control block variable values.** Returns void*******************************************************************************/
void btm_ble_init(void) {log::verbose("");// 1. 资源清理:释放旧定时器alarm_free(btm_cb.ble_ctr_cb.observer_timer);alarm_free(btm_cb.ble_ctr_cb.inq_var.fast_adv_timer);// 2. 控制块状态重置:内存清零memset(&btm_cb.ble_ctr_cb, 0, sizeof(tBTM_BLE_CB));memset(&(btm_cb.cmn_ble_vsc_cb), 0, sizeof(tBTM_BLE_VSC_CB));btm_cb.cmn_ble_vsc_cb.values_read = false;// 3. 关键资源初始化:创建定时器 & BLE 功能默认参数配置btm_cb.ble_ctr_cb.observer_timer = alarm_new("btm_ble.observer_timer");btm_cb.ble_ctr_cb.cur_states = 0;btm_cb.ble_ctr_cb.inq_var.adv_mode = BTM_BLE_ADV_DISABLE; // 广播模式:禁用btm_cb.ble_ctr_cb.inq_var.scan_type = BTM_BLE_SCAN_MODE_NONE; // 扫描类型:无扫描btm_cb.ble_ctr_cb.inq_var.adv_chnl_map = BTM_BLE_DEFAULT_ADV_CHNL_MAP; // 广播通道:默认 37/38/39 通道btm_cb.ble_ctr_cb.inq_var.afp = BTM_BLE_DEFAULT_AFP; // 广播滤波策略btm_cb.ble_ctr_cb.inq_var.sfp = BTM_BLE_DEFAULT_SFP; // 扫描滤波策略:默认(接受所有扫描请求)btm_cb.ble_ctr_cb.inq_var.connectable_mode = BTM_BLE_NON_CONNECTABLE; // 不可连接模式btm_cb.ble_ctr_cb.inq_var.discoverable_mode = BTM_BLE_NON_DISCOVERABLE; // 不可发现模式btm_cb.ble_ctr_cb.inq_var.fast_adv_timer =alarm_new("btm_ble_inq.fast_adv_timer");btm_cb.ble_ctr_cb.inq_var.inquiry_timer =alarm_new("btm_ble_inq.inquiry_timer");btm_cb.ble_ctr_cb.inq_var.evt_type = BTM_BLE_NON_CONNECT_EVT; // 事件类型:非连接事件btm_cb.ble_ctr_cb.addr_mgnt_cb.refresh_raddr_timer =alarm_new("btm_ble_addr.refresh_raddr_timer");btm_ble_pa_sync_cb = {};sync_timeout_alarm = alarm_new("btm.sync_start_task");// 4. 扩展功能初始化(可选)if (!ble_vnd_is_included()) {btm_ble_adv_filter_init();}
}
负责BLE 控制块(Control Block)的状态重置、关键资源(定时器)初始化及默认参数配置,是 BLE 功能(如广播、扫描、连接)启动的基础。
tBTM_CB 类分析见【Bluedriod】蓝牙协议栈 btm_init 源码解析-CSDN博客
ble_vnd_is_included
packages/modules/Bluetooth/system/stack/btm/btm_ble_gap.cc
// 运行时判断供应商功能是否启用
bool ble_vnd_is_included() {// replace build time config BLE_VND_INCLUDED with runtimereturn GET_SYSPROP(Ble, vnd_included, true);
}packages/modules/Bluetooth/sysprop/ble.sysprop
prop {api_name: "vnd_included" // 属性的 API 名称(供代码调用)type: Booleanscope: Internal // 作用域:仅蓝牙模块内部使用access: Readonlyprop_name: "bluetooth.ble.vnd.included"
}
BLE供应商特定功能的运行时动态开关控制。通过读取系统属性(System Property),结合 ble.sysprop
定义的属性元数据,允许在不重新编译代码的情况下,动态决定是否启用供应商自定义的 BLE 扩展功能(如厂商私有协议、定制化广播数据格式等)。
传统做法:通过编译宏(如
#define BLE_VND_INCLUDED 1
)在编译时固定是否包含供应商代码,灵活性差。改进做法:通过
GET_SYSPROP
宏读取运行时系统属性(bluetooth.ble.vnd.included
),实现动态配置。
btm_ble_adv_filter_init
packages/modules/Bluetooth/system/stack/btm/btm_ble_adv_filter.cc
tBTM_BLE_ADV_FILTER_CB btm_ble_adv_filt_cb;
tBTM_BLE_VSC_CB cmn_ble_vsc_cb;/********************************************************************************* Function btm_ble_adv_filter_init** Description This function initializes the adv filter control block** Parameters** Returns status*******************************************************************************/
void btm_ble_adv_filter_init(void) {// 1. 控制块状态重置:内存清零memset(&btm_ble_adv_filt_cb, 0, sizeof(tBTM_BLE_ADV_FILTER_CB));// 2. 获取供应商能力BTM_BleGetVendorCapabilities(&cmn_ble_vsc_cb);// 3. 功能支持检查if (!is_filtering_supported()) return;// 4. 动态内存分配:根据最大过滤数分配计数数组if (cmn_ble_vsc_cb.max_filter > 0) {btm_ble_adv_filt_cb.p_addr_filter_count = (tBTM_BLE_PF_COUNT*)osi_malloc(sizeof(tBTM_BLE_PF_COUNT) * cmn_ble_vsc_cb.max_filter);}
}
负责广播过滤控制块(tBTM_BLE_ADV_FILTER_CB
)的状态重置、供应商能力获取及资源动态分配,是 BLE 广播过滤功能(如白名单、黑名单、地址过滤)运行的基础。
tBTM_BLE_ADV_FILTER_CB
packages/modules/Bluetooth/system/types/ble_address_with_type.h
// 表示设备地址及其类型的核心结构体
struct tBLE_BD_ADDR {tBLE_ADDR_TYPE type;RawAddress bda;bool AddressEquals(const RawAddress& other) const { return other == bda; }bool IsPublicDeviceType() const { return type == kBleAddressPublicDevice; }bool IsRandomDeviceType() const { return type == kBleAddressRandomDevice; }bool IsPublicIdentityType() const {return type == kBleAddressPublicIdentity;}bool lsRandomIdentityType() const {return type == kBleAddressRandomIdentity;}bool IsAddressResolvable() const {return ((bda.address)[0] & kResolvableAddressMask) == kResolvableAddressMsb;}bool IsPublic() const { return !(type & 0x01); }bool IsResolvablePrivateAddress() const {return IsAddressResolvable() && IsRandomDeviceType();}bool IsIdentityType() const {return IsPublicIdentityType() || lsRandomIdentityType();}bool TypeWithoutIdentityEquals(const tBLE_ADDR_TYPE other) const {return (other & ~kBleAddressIdentityBit) ==(type & ~kBleAddressIdentityBit);}std::string ToString() const {return std::string(bda.ToString() + "[" + AddressTypeText(type) + "]");}std::string ToStringForLogging() const {return bda.ToStringForLogging() + "[" + AddressTypeText(type) + "]";}std::string ToRedactedStringForLogging() const {return bda.ToRedactedStringForLogging() + "[" + AddressTypeText(type) + "]";}bool operator==(const tBLE_BD_ADDR rhs) const {return rhs.type == type && rhs.bda == bda;}bool operator!=(const tBLE_BD_ADDR rhs) const { return !(*this == rhs); }
};packages/modules/Bluetooth/system/stack/include/btm_ble_api_types.h
// 记录单个地址的过滤规则匹配计数的结构体
typedef struct {bool in_use;RawAddress bd_addr;// 按过滤条件类型(如白名单、黑名单)记录匹配次数的数组uint8_t pf_counter[BTM_BLE_PF_TYPE_MAX]; /* number of filter indexed bytBTM_BLE_PF_COND_TYPE */
} tBTM_BLE_PF_COUNT;// 广播过滤功能的控制块
typedef struct {bool enable; // 广播过滤功能是否启用uint8_t op_type; // 当前过滤操作类型(如添加、删除、修改过滤规则)tBTM_BLE_PF_COUNT* p_addr_filter_count; /* per BDA filter array */// 当前操作的目标地址(如待添加 / 删除的过滤地址及其类型)tBLE_BD_ADDR cur_filter_target;
} tBTM_BLE_ADV_FILTER_CB;
tBTM_BLE_ADV_FILTER_CB
是BLE 广播过滤功能的核心控制块,用于管理过滤规则的启用状态、操作类型、当前目标地址及过滤计数数组,是广播过滤功能运行的状态仓库。
应用场景示例:白名单过滤
假设设备需要仅接收白名单设备的广播包,广播过滤功能的运行流程如下:
1. 初始化阶段:btm_ble_adv_filter_init
调用后,p_addr_filter_count
数组被分配(大小为 max_filter
),所有 tBTM_BLE_PF_COUNT
的 in_use
初始化为 false
。
2. 添加白名单条目:上层调用 btm_ble_add_filter(BD_ADDR_WHITELIST, target_addr)
,其中 target_addr
是 tBLE_BD_ADDR
类型(如公共设备地址)。
-
cur_filter_target
被设置为target_addr
。 -
在
p_addr_filter_count
数组中找到第一个in_use=false
的条目,将其bd_addr
设置为target_addr.bda
,in_use
设为true
,pf_counter[BTM_BLE_PF_WHITELIST]
初始化为 0。
3. 接收广播包时的过滤:BLE 控制器接收到广播包后,提取发送方地址(tBLE_BD_ADDR
类型),遍历 p_addr_filter_count
数组:
-
若找到
bd_addr
匹配且in_use=true
的条目,且pf_counter[BTM_BLE_PF_WHITELIST]
未超限,则允许接收该广播包,并递增计数。 -
若未找到匹配条目(或属于黑名单),则丢弃该广播包。
tBTM_BLE_VSC_CB
packages/modules/Bluetooth/system/stack/include/btm_ble_api_types.h
/* adv tx power in dBm */
typedef struct {uint8_t adv_inst_max; /* max adv instance supported in controller */uint8_t rpa_offloading;uint16_t tot_scan_results_strg;uint8_t max_irk_list_sz;uint8_t filter_support;uint8_t max_filter;uint8_t energy_support;bool values_read;uint16_t version_supported;uint16_t total_trackable_advertisers;uint8_t extended_scan_support;uint8_t debug_logging_supported;uint8_t le_address_generation_offloading_support;uint32_t a2dp_source_offload_capability_mask;uint8_t quality_report_support;uint32_t dynamic_audio_buffer_support;uint16_t adv_filter_extended_features_mask;uint8_t a2dp_offload_v2_support;
} tBTM_BLE_VSC_CB;
tBTM_BLE_VSC_CB
(BLE Vendor-Specific Capabilities Control Block)是协议栈与硬件控制器之间的 “能力桥梁”。协议栈通过 BTM_BleGetVendorCapabilities
(前文提及)从控制器读取能力参数并填充此结构体,后续功能(如广播过滤、地址管理、音频传输)均基于这些参数动态配置,确保功能不超出硬件限制。同时为协议栈提供动态配置依据,确保功能与硬件能力匹配。
1. 广播与扫描核心能力
字段 | 类型 | 说明 |
adv_inst_max | uint8_t | 控制器支持的最大广播实例数(BLE 5.0+ 扩展广播特性)。 每个广播实例可独立配置(如不同的广播数据、间隔),支持多设备同时广播(如智能手表同时广播时间和运动数据)。 |
tot_scan_results_strg | uint16_t | 控制器扫描结果缓存容量(单位:条目数)。 扫描时,控制器会缓存接收到的广播包信息(如地址、数据),该值决定了最多可缓存的扫描结果数量(避免主机处理不及时导致数据丢失)。 |
total_trackable_advertisers | uint16_t | 可跟踪的广播设备总数。 用于扫描时持续跟踪多个广播设备(如商场中的多个信标),避免因设备数量过多导致跟踪失效。 |
extended_scan_support | uint8_t | 是否支持扩展扫描(BLE 5.0+ 特性)。 扩展扫描允许更大的扫描窗口(最长 10240ms)和更灵活的参数配置(如扫描间隔),提升扫描效率。 |
2. 隐私与地址管理能力
字段 | 类型 | 说明 |
rpa_offloading | uint8_t | 是否支持可解析私有地址(RPA)卸载。 RPA 是设备生成的临时地址(用于隐私保护),卸载表示控制器可自动生成 / 解析 RPA,无需主机参与(降低主机负载)。 |
max_irk_list_sz | uint8_t | 身份解析密钥(IRK)列表的最大容量。 IRK 用于解析对端设备的 RPA(需预先交换 IRK),该值决定了可存储的 IRK 数量(影响可解析的 RPA 设备数量)。 |
le_address_generation_offloading_support | uint8_t | 是否支持LE 地址生成卸载。 控制器可自动生成随机地址(如非解析私有地址),减轻主机的地址管理负担。 |
3. 广播过滤与数据处理能力
字段 | 类型 | 说明 |
filter_support | uint8_t | 广播过滤支持的功能位掩码。 每一位表示一种过滤类型(如白名单、黑名单、基于名称的过滤),协议栈通过位运算判断支持的过滤方式。 |
max_filter | uint8_t | 控制器支持的最大广播过滤条目数。 在 btm_ble_adv_filter_init 中,该值用于动态分配过滤计数数组(p_addr_filter_count)的大小。 |
adv_filter_extended_features_mask | uint16_t | 扩展广播过滤功能掩码。 表示对复杂过滤条件的支持(如基于制造商数据、服务 UUID 的过滤),扩展传统过滤的灵活性。 |
4. 音频与性能优化能力
字段 | 类型 | 说明 |
a2dp_source_offload_capability_mask | uint32_t | A2DP 源卸载能力掩码。 指示控制器支持的音频编码格式(如 SBC、AAC、aptX),卸载表示控制器直接处理音频编码 / 解码(降低主机 CPU 占用)。 |
quality_report_support | uint8_t | 是否支持连接质量报告。 控制器可上报连接质量参数(如 RSSI、丢包率),用于优化音频传输(如动态调整编码速率)。 |
dynamic_audio_buffer_support | uint32_t | 是否支持动态音频缓冲区调整。 根据网络状况动态调整音频缓冲区大小(如网络延迟高时增大缓冲区,减少卡顿)。 |
a2dp_offload_v2_support | uint8_t | 是否支持A2DP 卸载 V2 版本。 可能支持新的编码格式或优化(如更低延迟的音频传输)。 |
5. 调试与辅助功能
字段 | 类型 | 说明 |
energy_support | uint8_t | 是否支持能量信息统计。 BLE 5.1 引入的定位功能,支持统计广播包的接收能量(如平均 RSSI),用于距离估算或室内定位。 |
debug_logging_supported | uint8_t | 是否支持调试日志输出。 控制器可生成详细的调试日志(如广播 / 扫描事件的时间戳、错误信息),辅助开发调试。 |
6. 通用状态标记
字段 | 类型 | 说明 |
values_read | bool | 标记能力值是否已读取。 初始化时为 false,协议栈读取控制器能力后设为 true,避免重复查询(提升初始化效率)。 |
version_supported | uint16_t | 控制器支持的BLE 协议版本(如 BLE 5.0、5.2)。 高位表示主版本,低位表示次版本(如 0x0502 表示 BLE 5.2)。 |
BTM_BleGetVendorCapabilities
packages/modules/Bluetooth/system/stack/btm/btm_ble_gap.cc
/********************************************************************************* Function BTM_BleGetVendorCapabilities** Description This function reads local LE features** Parameters p_cmn_vsc_cb : Locala LE capability structure** Returns void*******************************************************************************/
void BTM_BleGetVendorCapabilities(tBTM_BLE_VSC_CB* p_cmn_vsc_cb) {if (NULL != p_cmn_vsc_cb) {// 通过结构体赋值(逐字段复制),确保调用者获得与全局控制块完全一致的能力参数*p_cmn_vsc_cb = btm_cb.cmn_ble_vsc_cb;}
}
获取本地 BLE 硬件 / 控制器供应商特定能力的接口。将全局存储的 BLE 能力参数(如广播实例数、过滤条目数等)传递给调用者,为其他模块(如广播过滤、地址管理)提供硬件能力的动态配置依据。
is_filtering_supported
/packages/modules/Bluetooth/system/stack/btm/btm_ble_adv_filter.cc
static bool is_filtering_supported() {return cmn_ble_vsc_cb.filter_support != 0 && cmn_ble_vsc_cb.max_filter != 0;
}
通过检查硬件的过滤类型支持能力和过滤条目容量,确保广播过滤功能仅在硬件具备必要条件时启用。
三、流程图
四、btm_ble_init
与 btm_ble_adv_filter_init
时序图
五、总结
BLE协议栈的核心设计围绕硬件适配性、资源高效管理、功能动态配置展开:
-
硬件适配:通过
tBTM_BLE_VSC_CB
存储控制器能力参数,BTM_BleGetVendorCapabilities
提供能力访问接口,确保功能不超出硬件限制。 -
资源管理:
btm_ble_init
的状态重置与定时器管理、btm_ble_adv_filter_init
的动态内存分配,避免资源浪费与功能异常。 -
动态配置:
ble_vnd_is_included
结合系统属性实现运行时开关,is_filtering_supported
检查硬件能力,支撑协议栈的灵活扩展。
这些设计共同保障了 BLE 协议栈在不同硬件环境(如消费级设备、工业传感器)中的稳定运行与高效性能,是 BLE 技术广泛应用的关键基础。