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

【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_CBBTM_BleGetVendorCapabilities

btm_ble_init 初始化阶段通过与硬件控制器交互(如 HCI 命令)填充 tBTM_BLE_VSC_CB 结构体,存储 BLE 控制器的关键能力(如最大广播实例数、过滤条目数、音频卸载能力等)。BTM_BleGetVendorCapabilities 接口封装了全局能力参数的访问,为其他模块(如广播过滤)提供硬件能力的只读访问,确保功能与硬件限制匹配。

1.3 广播过滤功能实现(btm_ble_adv_filter_inittBTM_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_COUNTin_use 初始化为 false

2. 添加白名单条目:上层调用 btm_ble_add_filter(BD_ADDR_WHITELIST, target_addr),其中 target_addrtBLE_BD_ADDR 类型(如公共设备地址)。

  • cur_filter_target 被设置为 target_addr

  • p_addr_filter_count 数组中找到第一个 in_use=false 的条目,将其 bd_addr 设置为 target_addr.bdain_use 设为 truepf_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_maxuint8_t控制器支持的最大广播实例数(BLE 5.0+ 扩展广播特性)。
每个广播实例可独立配置(如不同的广播数据、间隔),支持多设备同时广播(如智能手表同时广播时间和运动数据)。
tot_scan_results_strguint16_t控制器扫描结果缓存容量(单位:条目数)。
扫描时,控制器会缓存接收到的广播包信息(如地址、数据),该值决定了最多可缓存的扫描结果数量(避免主机处理不及时导致数据丢失)。
total_trackable_advertisersuint16_t可跟踪的广播设备总数。
用于扫描时持续跟踪多个广播设备(如商场中的多个信标),避免因设备数量过多导致跟踪失效。
extended_scan_supportuint8_t是否支持扩展扫描(BLE 5.0+ 特性)。
扩展扫描允许更大的扫描窗口(最长 10240ms)和更灵活的参数配置(如扫描间隔),提升扫描效率。

2. 隐私与地址管理能力

字段类型说明
rpa_offloadinguint8_t是否支持可解析私有地址(RPA)卸载。
RPA 是设备生成的临时地址(用于隐私保护),卸载表示控制器可自动生成 / 解析 RPA,无需主机参与(降低主机负载)。
max_irk_list_szuint8_t身份解析密钥(IRK)列表的最大容量。
IRK 用于解析对端设备的 RPA(需预先交换 IRK),该值决定了可存储的 IRK 数量(影响可解析的 RPA 设备数量)。
le_address_generation_offloading_supportuint8_t是否支持LE 地址生成卸载。
控制器可自动生成随机地址(如非解析私有地址),减轻主机的地址管理负担。

3. 广播过滤与数据处理能力

字段类型说明
filter_supportuint8_t广播过滤支持的功能位掩码。
每一位表示一种过滤类型(如白名单、黑名单、基于名称的过滤),协议栈通过位运算判断支持的过滤方式。
max_filteruint8_t控制器支持的最大广播过滤条目数。
在 btm_ble_adv_filter_init 中,该值用于动态分配过滤计数数组(p_addr_filter_count)的大小。
adv_filter_extended_features_maskuint16_t扩展广播过滤功能掩码。
表示对复杂过滤条件的支持(如基于制造商数据、服务 UUID 的过滤),扩展传统过滤的灵活性。

4. 音频与性能优化能力

字段类型说明
a2dp_source_offload_capability_maskuint32_tA2DP 源卸载能力掩码。
指示控制器支持的音频编码格式(如 SBC、AAC、aptX),卸载表示控制器直接处理音频编码 / 解码(降低主机 CPU 占用)。
quality_report_supportuint8_t是否支持连接质量报告。
控制器可上报连接质量参数(如 RSSI、丢包率),用于优化音频传输(如动态调整编码速率)。
dynamic_audio_buffer_supportuint32_t是否支持动态音频缓冲区调整。
根据网络状况动态调整音频缓冲区大小(如网络延迟高时增大缓冲区,减少卡顿)。
a2dp_offload_v2_supportuint8_t是否支持A2DP 卸载 V2 版本。
可能支持新的编码格式或优化(如更低延迟的音频传输)。

5. 调试与辅助功能

字段类型说明
energy_supportuint8_t是否支持能量信息统计。
BLE 5.1 引入的定位功能,支持统计广播包的接收能量(如平均 RSSI),用于距离估算或室内定位。
debug_logging_supporteduint8_t是否支持调试日志输出。
控制器可生成详细的调试日志(如广播 / 扫描事件的时间戳、错误信息),辅助开发调试。

6. 通用状态标记

字段类型说明
values_readbool标记能力值是否已读取。
初始化时为 false,协议栈读取控制器能力后设为 true,避免重复查询(提升初始化效率)。
version_supporteduint16_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_initbtm_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 技术广泛应用的关键基础。


相关文章:

  • java综合项目开发一课一得
  • Linux 用户层 和 内核层锁的实现
  • 跟我学c++中级篇——多线程中的文件处理
  • 《前端面试题:JavaScript 闭包深度解析》
  • DAY 43 训练
  • Tavily 技术详解:为大模型提供实时搜索增强的利器
  • 《最短路(Dijkstra+Heap)》题集
  • 跟进一下目前最新的大数据技术
  • 《算法复杂度:数据结构世界里的“速度与激情”》
  • 【Redis/2】核心特性、应用场景与安装配置
  • Langgraph实战-自省式RAG: Self-RAG
  • 分类数据集 - 场景分类数据集下载
  • 【本地AI大模型部署+可视化界面图文教程】Ollama+Qwen3
  • Unity中的transform.up
  • 【创新算法】改进深度优先搜索算法配合二进制粒子群的配电网故障恢复重构研究
  • 嵌入式学习--江协stm32day5
  • uni-app学习笔记二十九--数据缓存
  • 【ArcGIS Pro微课1000例】0072:如何自动保存编辑内容及保存工程?
  • OD 算法题 B卷【模拟工作队列】
  • 【threejs】每天一个小案例讲解:创建基本的3D场景
  • 犬舍网站怎么做/站长工具综合查询官网
  • wordpress成品网站yunbuluo/武汉网络推广公司排名
  • 安徽工程建设信息网站/软文云
  • 为什么自己做的网站别人打不开/电商seo搜索优化
  • 免费ppt模板在线下载/seo内容优化方法
  • 网站建设教程所需文字/境外电商有哪些平台