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

【Bluedriod】蓝牙协议栈 btm_init 源码解析

本文深入剖析蓝牙协议栈中 BTM(Bluetooth Manager)模块的初始化机制,以 Android 开源项目(AOSP)代码为例,详细解读 BTM 初始化过程、核心控制块(tBTM_CB)的结构设计、蓝牙经典与低功耗模式(BLE)的状态管理、安全模块初始化(BTM_Sec_Init)以及基于 RSSI 的设备搜索策略。通过剖析关键数据结构(如 tBTM_DEVCB、tBTM_BLE_CB、tBTM_SEC_CB)和回调机制,揭示蓝牙协议栈在设备发现、连接管理、安全配对等核心流程中的底层逻辑,为理解蓝牙通信的稳定性与安全性提供技术视角。

一、概述

1.1 BTM 初始化流程与核心控制块

BTM 子系统的初始化以btm_init函数为入口,主要完成三项核心任务:

  • 全局控制块初始化:通过tBTM_CB结构体(包含传统蓝牙控制块tBTM_DEVCB和 BLE 控制块tBTM_BLE_CB)管理设备状态、扫描参数、定时器及回调,确保内存清零和子模块动态资源分配。

  • 安全模块初始化:调用BTM_Sec_Init设置安全模式(SC 或 SP),根据硬件能力和配置动态调整配对策略,保障通信安全。

  • 平台适配:针对 Floss 平台特殊需求,通过btm_inq_db_set_inq_by_rssi配置基于 RSSI 的设备搜索标志,优化设备发现逻辑。

1.2 蓝牙设备状态与连接管理

①传统蓝牙(Classic)

  • 通过tBTM_DEVCB管理异步操作(如读取设备名称、RSSI)的定时器与回调,支持厂商私有事件处理。

  • 设备查询(Inquiry)由tBTM_INQUIRY_VAR_ST控制,包含扫描窗口、周期、结果回调等参数,确保发现流程的低功耗与高效性。

②低功耗蓝牙(BLE):

  • tBTM_BLE_CB作为核心控制块,整合扫描(tBTM_BLE_INQ_CB)、广播、连接状态(BLE_CONN_IDLE等枚举)及隐私模式(随机地址管理tBTM_LE_RANDOM_CB)。

  • 预定义扫描与广播参数(如BTM_BLE_GAP_DISC_SCAN_INT)平衡功耗与发现效率,支持扩展扫描和厂商特定功能(tBTM_BLE_VSC_CB)。

1.3 安全机制与回调接口

①安全模式选择:

  • BTM_Sec_Init根据配置选择安全连接(SC)或简单配对(SP):SC 模式通过 ECDH 密钥交换提升安全性,SP 模式兼容旧设备但存在中间人攻击风险。

  • tBTM_SEC_CB存储密钥(如 IRK、DHKey)、IO 能力(tBTM_IO_CAP)和认证策略(tBTM_AUTH_REQ),确保配对流程的动态安全控制。

②回调与上层交互:通过tBTM_APPL_INFO注册回调(如 PIN 码输入tBTM_PIN_CALLBACK、密钥管理tBTM_LINK_KEY_CALLBACK),实现协议栈与应用层的事件通知与数据交互。

1.4 系统属性与动态配置

通过osi_property_get_bool读取系统属性(如persist.bluetooth.inq_by_rssi),动态控制功能开关(如基于 RSSI 的搜索策略),无需重新编译即可适应不同硬件平台和场景需求,提升协议栈的灵活性与可配置性。

BTM初始化:btm_init

packages/modules/Bluetooth/system/stack/btm/btm_main.cc
/********************************************************************************* Function         btm_init** Description      This function is called at BTM startup to allocate the*                  control block (if using dynamic memory), and initializes the*                  tracing level.  It then initializes the various components*                  of btm.** Returns          void*******************************************************************************/
tBTM_CB btm_cb;void btm_init(void) {btm_cb.Init();get_security_client_interface().BTM_Sec_Init();#ifdef TARGET_FLOSS// Need to set inquery by rssi flag for Floss since Floss doesn't do// btm_inq_db_initbtm_inq_db_set_inq_by_rssi();
#endif
}

主要完成以下任务:

  1. 初始化全局控制块 btm_cb,为模块运行提供状态存储基础;

  2. 初始化安全模块,确保后续通信的安全性;

  3. 针对 Floss 平台的特殊需求,补充设置查询标志,保证设备发现功能的正确性。

btm_cb.Init

packages/modules/Bluetooth/system/stack/btm/btm_int_types.h
/* Define a structure to hold all the BTM data
*/
typedef struct tBTM_CB {/*******************************************************      Control block for local device*****************************************************/// 1. 设备控制块(传统蓝牙与 BLE)// 传统蓝牙设备的核心控制块,存储本地设备信息(如蓝牙地址、支持的功能、连接状态等)tBTM_DEVCB devcb;/*******************************************************      Control block for local LE device*****************************************************/tBTM_BLE_CB ble_ctr_cb; // 低功耗蓝牙的核心控制块,管理 BLE 设备的扫描、广播、连接等状态public:tBTM_BLE_VSC_CB cmn_ble_vsc_cb; //BLEVendor-Specific Command(厂商自定义命令)的公共控制块,用于处理厂商私有协议/* Packet types supported by the local device */uint16_t btm_sco_pkt_types_supported{0};// 2. 功能模块控制块/*******************************************************      Inquiry*****************************************************/tBTM_INQUIRY_VAR_ST btm_inq_vars; // 蓝牙设备查询(Inquiry)功能的状态变量,存储查询过程中的参数(如查询时长、结果列表等)/*******************************************************      SCO Management*****************************************************/tSCO_CB sco_cb; //语音链路(SCO,Synchronous Connection Oriented)的控制块,管理语音通话的连接参数(如编码方式、数据包类型)#define BTM_SEC_MAX_RMT_NAME_CALLBACKS 2// 远程设备名称查询的回调函数指针数组,用于异步获取设备名称tBTM_RMT_NAME_CALLBACK* p_rmt_name_callback[BTM_SEC_MAX_RMT_NAME_CALLBACKS];uint16_t disc_handle{0};          /* for legacy devices */uint8_t disc_reason{0};           /* for legacy devices */// 安全请求的待处理队列(如配对请求、加密协商),确保安全操作按顺序处理fixed_queue_t* sec_pending_q{nullptr}; /* pending sequrity requests intBTM_SEC_QUEUE_ENTRY format */// 蓝牙质量报告(BQE,Bluetooth Quality Engine)的接收指针,用于统计链路质量// BQR ReceivertBTM_BT_QUALITY_REPORT_RECEIVER* p_bqr_report_receiver{nullptr};#define BTM_CODEC_TYPE_MAX_RECORDS 32tBTM_BT_DYNAMIC_AUDIO_BUFFER_CBdynamic_audio_buffer_cb[BTM_CODEC_TYPE_MAX_RECORDS];tACL_CB acl_cb_; // 异步链路的控制块,管理数据传输的异步链路状态// 带时间戳的环形日志缓冲区,用于记录蓝牙模块的关键操作日志(如初始化、连接事件)std::shared_ptr<TimestampedStringCircularBuffer> history_{nullptr};// 记录传统蓝牙查询(classic_inquiry)、BLE 扫描(le_scan)等操作的耗时和结果struct {struct {long long start_time_ms;unsigned long results;} classic_inquiry, le_scan, le_inquiry, le_observe, le_legacy_scan;std::unique_ptr<bluetooth::common::TimestampedCircularBuffer<tBTM_INQUIRY_CMPL>>inquiry_history_ = std::make_unique<bluetooth::common::TimestampedCircularBuffer<tBTM_INQUIRY_CMPL>>(kMaxInquiryScanHistory);} neighbor;void Init() {// 清零基础数据结构memset(&devcb, 0, sizeof(devcb));memset(&ble_ctr_cb, 0, sizeof(ble_ctr_cb));memset(&cmn_ble_vsc_cb, 0, sizeof(cmn_ble_vsc_cb));memset(&btm_inq_vars, 0, sizeof(btm_inq_vars));memset(&sco_cb, 0, sizeof(sco_cb));memset(p_rmt_name_callback, 0, sizeof(p_rmt_name_callback));// 初始化复合结构体acl_cb_ = {};neighbor = {};// 初始化子控制块的动态逻辑/* Initialize BTM component structures */btm_inq_vars.Init(); /* Inquiry Database and Structures */sco_cb.Init();       /* SCO Database and Structures (If included) */devcb.Init();history_ = std::make_shared<TimestampedStringCircularBuffer>(kBtmLogHistoryBufferSize);CHECK(history_ != nullptr);history_->Push(std::string("Initialized btm history"));}void Free() {history_.reset();devcb.Free();sco_cb.Free();btm_inq_vars.Free();}
} tBTM_CB;

Init() 是蓝牙模块启动的 “初始化枢纽”,其核心目标是:

  • 内存清零:确保所有基础数据结构从 “全 0” 状态开始,避免残留数据干扰。

  • 子模块初始化:调用子控制块的 Init 方法,完成动态资源分配(如内存、计数器)和默认参数设置。

  • 日志系统就绪:创建日志缓冲区并记录初始化事件,为后续问题定位提供关键日志。

tBTM_DEVCB devcb

packages/modules/Bluetooth/system/stack/include/btm_api_types.h
/***************************************************  Device Control and General Callback Functions**************************************************/
/* Callback function for when a vendor specific event occurs. The length and* array of returned parameter bytes are included. This asynchronous event* is enabled/disabled by calling BTM_RegisterForVSEvents().
*/
// 用于处理蓝牙芯片或协议栈厂商自定义的私有事件(如特定型号芯片的扩展功能)
//当蓝牙模块接收到厂商私有指令(如通过 HCI Vendor Specific Command)时,通过此回调通知上层应用处理
typedef void(tBTM_VS_EVT_CB)(uint8_t len, const uint8_t* p);/* Define a structure to hold all the BTM data
*/packages/modules/Bluetooth/system/types/raw_address.h
/* General callback function for notifying an application that a synchronous* BTM function is complete. The pointer contains the address of any returned* data.*/
// 通知上层应用某个同步操作(如读取设备属性)已完成
typedef void(tBTM_CMPL_CB)(void* p1);/** Bluetooth Address */
class RawAddress final {public:static constexpr unsigned int kLength = 6;uint8_t address[kLength];RawAddress() = default;RawAddress(const uint8_t (&addr)[kLength]);RawAddress(const std::array<uint8_t, kLength> array);bool operator<(const RawAddress& rhs) const {return (std::memcmp(address, rhs.address, sizeof(address)) < 0);}bool operator==(const RawAddress& rhs) const {return (std::memcmp(address, rhs.address, sizeof(address)) == 0);}bool operator>(const RawAddress& rhs) const { return (rhs < *this); }bool operator<=(const RawAddress& rhs) const { return !(*this > rhs); }bool operator>=(const RawAddress& rhs) const { return !(*this < rhs); }bool operator!=(const RawAddress& rhs) const { return !(*this == rhs); }bool IsEmpty() const { return *this == kEmpty; }// TODO (b/258090765): remove it and// replace its usage with ToColonSepHexStringstd::string ToString() const;// Return a string representation in the form of// hexadecimal string separated by colon (:), e.g.,// "12:34:56:ab:cd:ef"std::string ToColonSepHexString() const;// same as ToColonSepHexStringstd::string ToStringForLogging() const;// Similar with ToColonHexString, ToRedactedStringForLogging returns a// colon separated hexadecimal reprentation of the address but, with the// leftmost 4 bytes masked with "xx", e.g., "xx:xx:xx:xx:ab:cd".std::string ToRedactedStringForLogging() const;// Converts |string| to RawAddress and places it in |to|. If |from| does// not represent a Bluetooth address, |to| is not modified and this function// returns false. Otherwise, it returns true.static bool FromString(const std::string& from, RawAddress& to);// Copies |from| raw Bluetooth address octets to the local object.// Returns the number of copied octets - should be always RawAddress::kLengthsize_t FromOctets(const uint8_t* from);std::array<uint8_t, kLength> ToArray() const;static bool IsValidAddress(const std::string& address);static const RawAddress kEmpty;  // 00:00:00:00:00:00static const RawAddress kAny;    // FF:FF:FF:FF:FF:FF
};packages/modules/Bluetooth/system/stack/btm/btm_int_types.h
/* Define the Device Management control structure*/
// 负责管理本地设备属性的异步操作(如读名称、读 RSSI)的定时器和回调
typedef struct tBTM_DEVCB {// 厂商特定事件回调数组tBTM_VS_EVT_CB* p_vend_spec_cb[BTM_MAX_VSE_CALLBACKS]; /* Register for vendorspecific events  */alarm_t* read_local_name_timer; /* Read local name timer */tBTM_CMPL_CB* p_rln_cmpl_cb;    /* Callback function to be called when  *//* read local name function complete    */alarm_t* read_rssi_timer;     /* Read RSSI timer */tBTM_CMPL_CB* p_rssi_cmpl_cb; /* Callback function to be called when  *//* read RSSI function completes */alarm_t* read_failed_contact_counter_timer; /* Read Failed Contact Counter *//* timer */tBTM_CMPL_CB* p_failed_contact_counter_cmpl_cb; /* Callback function to be *//* called when read Failed Contact Counter function completes */alarm_t*read_automatic_flush_timeout_timer; /* Read Automatic Flush Timeout *//* timer */tBTM_CMPL_CB* p_automatic_flush_timeout_cmpl_cb; /* Callback function to be *//* called when read Automatic Flush Timeout function completes */alarm_t* read_link_quality_timer;tBTM_CMPL_CB* p_link_qual_cmpl_cb; /* Callback function to be called when  *//* read link quality function completes */alarm_t* read_tx_power_timer;     /* Read tx power timer */tBTM_CMPL_CB* p_tx_power_cmpl_cb; /* Callback function to be called       */DEV_CLASS dev_class; /* Local device class                   */tBTM_CMPL_CB*p_le_test_cmd_cmpl_cb; /* Callback function to be called whenLE test mode command has been sent successfully */RawAddress read_tx_pwr_addr; /* read TX power target address     */void Init() {// 创建定时器实例read_local_name_timer = alarm_new("btm.read_local_name_timer");read_rssi_timer = alarm_new("btm.read_rssi_timer");read_failed_contact_counter_timer =alarm_new("btm.read_failed_contact_counter_timer");read_automatic_flush_timeout_timer =alarm_new("btm.read_automatic_flush_timeout_timer");read_link_quality_timer = alarm_new("btm.read_link_quality_timer");read_tx_power_timer = alarm_new("btm.read_tx_power_timer");}void Free() {alarm_free(read_local_name_timer);alarm_free(read_rssi_timer);alarm_free(read_failed_contact_counter_timer);alarm_free(read_automatic_flush_timeout_timer);alarm_free(read_link_quality_timer);alarm_free(read_tx_power_timer);}
} tBTM_DEVCB;

tBTM_DEVCB 包含多组 alarm_t*(定时器)和 tBTM_CMPL_CB*(完成回调),每组对应一个设备属性的异步读取操作:

成员变量功能描述
read_local_name_timer读本地设备名称操作的定时器(超时后触发回调)
p_rln_cmpl_cb读本地名称完成的回调(成功或超时后调用)
read_rssi_timer读 RSSI(接收信号强度)操作的定时器
p_rssi_cmpl_cb读 RSSI 完成的回调
read_failed_contact_counter_timer读 “失败联系计数器”(记录连接失败次数)的定时器
p_failed_contact_counter_cmpl_cb读失败联系计数器完成的回调
read_automatic_flush_timeout_timer读 “自动刷新超时”(ACL 链路数据缓存的超时时间)的定时器
p_automatic_flush_timeout_cmpl_cb读自动刷新超时完成的回调
read_link_quality_timer读链路质量(如误码率)的定时器
p_link_qual_cmpl_cb读链路质量完成的回调
read_tx_power_timer读发射功率(TX Power)的定时器
p_tx_power_cmpl_cb读发射功率完成的回调

tBTM_BLE_CB ble_ctr_cb

packages/modules/Bluetooth/system/stack/btm/neighbor_inquiry.h
/* Callback function for notifications when the BTM gets inquiry response.* First param is inquiry results database, second is pointer of EIR.*/
// 设备发现过程中,上层应用通过此回调获取周围 BLE 设备的信息(如智能手表、传感器)
typedef void(tBTM_INQ_RESULTS_CB)(tBTM_INQ_RESULTS* p_inq_results,const uint8_t* p_eir, uint16_t eir_len);packages/modules/Bluetooth/system/stack/btm/btm_ble_int_types.h
/* scanning enable status */
#define BTM_BLE_SCAN_ENABLE 0x01
#define BTM_BLE_SCAN_DISABLE 0x00/* advertising enable status */
#define BTM_BLE_ADV_ENABLE 0x01
#define BTM_BLE_ADV_DISABLE 0x00#define BTM_BLE_AD_DATA_LEN 31#define BTM_BLE_DUPLICATE_ENABLE 1
#define BTM_BLE_DUPLICATE_DISABLE 0/* Interval(scan_int) = 11.25 ms= 0x0010 * 0.625 ms */
#define BTM_BLE_GAP_DISC_SCAN_INT 18
/* scan_window = 11.25 ms= 0x0010 * 0.625 ms */
#define BTM_BLE_GAP_DISC_SCAN_WIN 18
/* Tgap(gen_disc) = 1.28 s= 512 * 0.625 ms */
#define BTM_BLE_GAP_ADV_INT 512
/* Tgap(lim_timeout) = 180s max */
#define BTM_BLE_GAP_LIM_TIMEOUT_MS (180 * 1000)
/* Interval(scan_int) = 100ms= 160 * 0.625 ms */
#define BTM_BLE_LOW_LATENCY_SCAN_INT 160
/* scan_window = 100ms= 160 * 0.625 ms */
#define BTM_BLE_LOW_LATENCY_SCAN_WIN 160/* TGAP(adv_fast_interval1) = 30(used) ~ 60 ms  = 48 *0.625 */
#define BTM_BLE_GAP_ADV_FAST_INT_1 48
/* TGAP(adv_fast_interval2) = 100(used) ~ 150 ms = 160 * 0.625 ms */
#define BTM_BLE_GAP_ADV_FAST_INT_2 160
/* Tgap(adv_slow_interval) = 1.28 s= 512 * 0.625 ms */
#define BTM_BLE_GAP_ADV_SLOW_INT 2048
/* Tgap(dir_conn_adv_int_max) = 500 ms = 800 * 0.625 ms */
#define BTM_BLE_GAP_ADV_DIR_MAX_INT 800
/* Tgap(dir_conn_adv_int_min) = 250 ms = 400 * 0.625 ms */
#define BTM_BLE_GAP_ADV_DIR_MIN_INT 400#define BTM_BLE_GAP_FAST_ADV_TIMEOUT_MS (30 * 1000)#define BTM_VSC_CHIP_CAPABILITY_L_VERSION 55
#define BTM_VSC_CHIP_CAPABILITY_M_VERSION 95
#define BTM_VSC_CHIP_CAPABILITY_S_VERSION 98// 存储本地设备的 BLE 广播数据(符合蓝牙核心规范的 31 字节限制)
typedef struct {uint16_t data_mask;uint8_t* p_flags;uint8_t ad_data[BTM_BLE_AD_DATA_LEN];uint8_t* p_pad;
} tBTM_BLE_LOCAL_ADV_DATA;#define BTM_BLE_ISVALID_PARAM(x, min, max) \(((x) >= (min) && (x) <= (max)) || ((x) == BTM_BLE_CONN_PARAM_UNDEF))typedef struct {uint16_t discoverable_mode; // 可发现模式(如通用发现、受限发现)uint16_t connectable_mode;  // 可连接模式(是否允许发起连接)uint16_t scan_window; // 扫描窗口(ms,决定扫描持续时间)uint16_t scan_interval; // 扫描间隔(ms,决定扫描周期)// 扫描类型(主动扫描/被动扫描)uint8_t scan_type;             /* current scan type: active or passive */// 广播过滤策略(如仅接受白名单设备)tBTM_BLE_AFP afp; /* advertising filter policy */// 扫描过滤策略(如过滤重复设备)tBTM_BLE_SFP sfp; /* scanning filter policy */// 广播地址类型(公共地址/随机地址)tBLE_ADDR_TYPE adv_addr_type;uint8_t evt_type;uint8_t adv_mode;void enable_advertising_mode() { adv_mode = BTM_BLE_ADV_ENABLE; }void disable_advertising_mode() { adv_mode = BTM_BLE_ADV_DISABLE; }bool is_advertising_mode_enabled() const {return (adv_mode == BTM_BLE_ADV_ENABLE);}tBLE_BD_ADDR direct_bda;tBTM_BLE_EVT directed_conn;// 快速广播定时器(超时后切换为慢速广播)bool fast_adv_on;alarm_t* fast_adv_timer;/* inquiry BD addr database */// 本地广播数据tBTM_BLE_LOCAL_ADV_DATA adv_data;tBTM_BLE_ADV_CHNL_MAP adv_chnl_map;alarm_t* inquiry_timer;bool scan_rsp;uint8_t state; /* Current state that the inquiry process is in */
} tBTM_BLE_INQ_CB;/* random address resolving complete callback */
typedef void(tBTM_BLE_RESOLVE_CBACK)(void* match_rec, void* p);typedef void(tBTM_BLE_ADDR_CBACK)(const RawAddress& static_random, void* p);//  随机地址管理结构体
// 支持 BLE 的隐私功能(Bluetooth Privacy),通过定期刷新随机地址避免设备被追踪
/* random address management control block */
typedef struct {/* 本地设备LE地址类型(公共/随机) */tBLE_ADDR_TYPE own_addr_type; /* local device LE address type *//* 当前使用的私有随机地址 */RawAddress private_addr;/* 随机地址刷新定时器(定期更换地址) */alarm_t* refresh_raddr_timer;
} tBTM_LE_RANDOM_CB;/* acceptlist using state as a bit mask */
constexpr uint8_t BTM_BLE_WL_IDLE = 0;
constexpr uint8_t BTM_BLE_ACCEPTLIST_INIT = 1;/* resolving list using state as a bit mask */
enum : uint8_t {BTM_BLE_RL_IDLE = 0,BTM_BLE_RL_INIT = (1 << 0),BTM_BLE_RL_SCAN = (1 << 1),BTM_BLE_RL_ADV = (1 << 2),
};
typedef uint8_t tBTM_BLE_RL_STATE;typedef struct { void* p_param; } tBTM_BLE_CONN_REQ;/* LE state request */
#define BTM_BLE_STATE_INVALID 0
#define BTM_BLE_STATE_INIT 2
#define BTM_BLE_STATE_MAX 11#define BTM_BLE_STATE_CONN_ADV_BIT 0x0001
#define BTM_BLE_STATE_INIT_BIT 0x0002
#define BTM_BLE_STATE_CENTRAL_BIT 0x0004
#define BTM_BLE_STATE_PERIPHERAL_BIT 0x0008
#define BTM_BLE_STATE_LO_DUTY_DIR_ADV_BIT 0x0010
#define BTM_BLE_STATE_HI_DUTY_DIR_ADV_BIT 0x0020
#define BTM_BLE_STATE_NON_CONN_ADV_BIT 0x0040
#define BTM_BLE_STATE_PASSIVE_SCAN_BIT 0x0080
#define BTM_BLE_STATE_ACTIVE_SCAN_BIT 0x0100
#define BTM_BLE_STATE_SCAN_ADV_BIT 0x0200
typedef uint16_t tBTM_BLE_STATE_MASK;#define BTM_BLE_STATE_ALL_MASK 0x03ff
#define BTM_BLE_STATE_ALL_ADV_MASK                                  \(BTM_BLE_STATE_CONN_ADV_BIT | BTM_BLE_STATE_LO_DUTY_DIR_ADV_BIT | \BTM_BLE_STATE_HI_DUTY_DIR_ADV_BIT | BTM_BLE_STATE_SCAN_ADV_BIT)
#define BTM_BLE_STATE_ALL_CONN_MASK \(BTM_BLE_STATE_CENTRAL_BIT | BTM_BLE_STATE_PERIPHERAL_BIT)typedef struct {RawAddress* resolve_q_random_pseudo{nullptr};uint8_t* resolve_q_action{nullptr};uint8_t q_next;uint8_t q_pending;
} tBTM_BLE_RESOLVE_Q;/* BLE privacy mode */
#define BTM_PRIVACY_NONE 0 /* BLE no privacy */
#define BTM_PRIVACY_1_1 1  /* BLE privacy 1.1, do not support privacy 1.0 */
#define BTM_PRIVACY_1_2 2  /* BLE privacy 1.2 */
#define BTM_PRIVACY_MIXED \3 /* BLE privacy mixed mode, broadcom propietary mode */
typedef uint8_t tBTM_PRIVACY_MODE;/* Define BLE Device Management control structure
*/
constexpr uint8_t kBTM_BLE_INQUIRY_ACTIVE = 0x10;
constexpr uint8_t kBTM_BLE_OBSERVE_ACTIVE = 0x80;
constexpr size_t kCentralAndPeripheralCount = 2;typedef struct {private:uint8_t scan_activity_; /* LE scan activity mask */public:bool is_ble_inquiry_active() const {return (scan_activity_ & kBTM_BLE_INQUIRY_ACTIVE);}bool is_ble_observe_active() const {return (scan_activity_ & kBTM_BLE_OBSERVE_ACTIVE);}void set_ble_inquiry_active() { scan_activity_ |= kBTM_BLE_INQUIRY_ACTIVE; }void set_ble_observe_active() { scan_activity_ |= kBTM_BLE_OBSERVE_ACTIVE; }void reset_ble_inquiry() { scan_activity_ &= ~kBTM_BLE_INQUIRY_ACTIVE; }void reset_ble_observe() { scan_activity_ &= ~kBTM_BLE_OBSERVE_ACTIVE; }bool is_ble_scan_active() const {return (is_ble_inquiry_active() || is_ble_observe_active());}/*******************************************************      BLE Inquiry*****************************************************/tBTM_BLE_INQ_CB inq_var;/* observer callback and timer */// 观察者模式支持tBTM_INQ_RESULTS_CB* p_obs_results_cb;   // 观察者模式结果回调tBTM_CMPL_CB* p_obs_cmpl_cb;             // 观察者模式完成回调alarm_t* observer_timer;                 // 观察者模式定时器(超时停止)/* opportunistic observer */tBTM_INQ_RESULTS_CB* p_opportunistic_obs_results_cb;/* target announcement observer */tBTM_INQ_RESULTS_CB* p_target_announcement_obs_results_cb;private:enum : uint8_t { /* BLE connection state */BLE_CONN_IDLE = 0,BLE_CONNECTING = 2,BLE_CONN_CANCEL = 3,} conn_state_{BLE_CONN_IDLE};public:bool is_connection_state_idle() const { return conn_state_ == BLE_CONN_IDLE; }bool is_connection_state_connecting() const {return conn_state_ == BLE_CONNECTING;}bool is_connection_state_cancelled() const {return conn_state_ == BLE_CONN_CANCEL;}void set_connection_state_idle() { conn_state_ = BLE_CONN_IDLE; }void set_connection_state_connecting() { conn_state_ = BLE_CONNECTING; }void set_connection_state_cancelled() { conn_state_ = BLE_CONN_CANCEL; }/* random address management control block */tBTM_LE_RANDOM_CB addr_mgnt_cb;tBTM_PRIVACY_MODE privacy_mode;    /* privacy mode */uint8_t resolving_list_avail_size; /* resolving list available size */tBTM_BLE_RESOLVE_Q resolving_list_pend_q; /* Resolving list queue */tBTM_BLE_RL_STATE suspended_rl_state;     /* Suspended resolving list state *//* IRK list availability mask, up to max entry bits */uint8_t* irk_list_mask{nullptr};tBTM_BLE_RL_STATE rl_state; /* Resolving list state *//* current BLE link state */tBTM_BLE_STATE_MASK cur_states; /* bit mask of tBTM_BLE_STATE */uint8_t link_count[kCentralAndPeripheralCount]; /* total link count centraland peripheral*/
} tBTM_BLE_CB;

tBTM_BLE_CB 是 BLE 模块的 “总控中心”,整合了扫描、广播、连接、隐私等所有核心状态。

扫描与广播的时间参数

宏定义含义对应蓝牙规范要求
BTM_BLE_GAP_DISC_SCAN_INT通用发现模式扫描间隔(18 × 0.625ms = 11.25ms)蓝牙核心规范中通用发现扫描的最小间隔
BTM_BLE_GAP_DISC_SCAN_WIN通用发现模式扫描窗口(11.25ms)扫描窗口需 ≤ 扫描间隔,确保不遗漏广播包
BTM_BLE_GAP_ADV_INT通用广播间隔(512 × 0.625ms = 320ms)通用广播的默认间隔范围(20ms~10.24s)
BTM_BLE_LOW_LATENCY_SCAN_INT低延迟扫描间隔(160 × 0.625ms = 100ms)用于需要快速发现设备的场景(如连接配对)
BTM_BLE_GAP_ADV_FAST_INT_1快速广播间隔 1(48 × 0.625ms = 30ms)快速广播的最小间隔(30ms~60ms)

状态与模式标志:

  • BTM_BLE_SCAN_ENABLE/BTM_BLE_SCAN_DISABLE:扫描启用 / 禁用状态。

  • BTM_BLE_ADV_ENABLE/BTM_BLE_ADV_DISABLE:广播启用 / 禁用状态。

  • BTM_BLE_DUPLICATE_ENABLE/BTM_BLE_DUPLICATE_DISABLE:是否过滤重复的广播包(避免重复通知上层)

tBTM_BLE_VSC_CB cmn_ble_vsc_cb

packages/modules/Bluetooth/system/stack/include/btm_ble_api_types.h
/* adv tx power in dBm */
typedef struct {// 控制器支持的最大广播实例数(蓝牙 5.0 + 扩展广播特性)。每个广播实例可独立配置参数(如间隔、数据),适用于多角色设备(如同时广播为传感器和信标)。上层创建广播实例时需不超过此值(例如若为 3,则最多同时运行 3 个广播实例)uint8_t adv_inst_max; /* max adv instance supported in controller */// 控制器内部可存储的扫描结果总数。当主机(Host)处理扫描结果较慢时,控制器会暂存新的广播包,避免数据丢失。此值越大,扫描容错能力越强(如主机繁忙时仍能保留更多结果uint8_t rpa_offloading;)uint16_t tot_scan_results_strg;// 控制器支持的最大 IRK(身份解析密钥)列表大小。IRK 用于解析 RPA,设备配对后会将对方的 IRK 存入此列表。此值决定了隐私模式下可解析的设备数量(例如若为 8,则最多存储 8 个配对设备的 IRK)uint8_t max_irk_list_sz;// 是否支持解析私有地址(RPA)卸载。RPA 是 BLE 隐私规范中的动态随机地址(可通过 IRK 解析为真实身份)。若控制器支持卸载,RPA 的生成与解析将由控制器硬件完成,减轻主机 CPU 负担(例如手机的蓝牙芯片直接处理 RPA,无需 AP 侧计算)uint8_t filter_support;uint8_t max_filter;uint8_t energy_support;// 标记是否已通过厂商特定命令(VSC)从控制器读取能力参数。协议栈启动时会发送 HCI Vendor-Specific Command 查询控制器能力,成功读取后设置此标志为true,确保后续操作基于真实硬件能力bool values_read;// 控制器支持的厂商特定功能版本号。用于协议栈与控制器的版本兼容性检查(例如协议栈 V3.0 需与控制器 V2.0 及以上兼容)uint16_t version_supported;uint16_t total_trackable_advertisers;// 是否支持扩展扫描(蓝牙 5.0 + 特性)。扩展扫描允许更灵活的参数配置(如更大的扫描窗口、多过滤器组合),提升扫描效率(例如支持扫描不同物理信道的广播包)uint8_t extended_scan_support;// 是否支持调试日志功能。若为true,控制器可生成详细的 HCI 命令 / 事件日志(如广播包内容、连接状态变化),用于开发阶段的问题排查uint8_t debug_logging_supported;// 是否支持LE 地址生成卸载。LE 地址(如随机地址)的生成通常由主机完成,若控制器支持卸载,地址生成将由硬件处理,提升效率(例如快速生成大量随机地址)uint8_t le_address_generation_offloading_support;// A2DP源端卸载能力掩码。不同位代表支持的音频编码格式(如 SBC、AAC、aptX),若某一位为 1,表示控制器可硬件处理该编码的音频流(无需主机编码,降低延迟和功耗)uint32_t a2dp_source_offload_capability_mask;uint8_t quality_report_support;// 是否支持动态音频缓冲区调整。蓝牙音频传输中,缓冲区大小需适应网络延迟变化(如数据包丢失时增大缓冲区)。此功能允许控制器动态调整缓冲区,提升音频播放的稳定性uint32_t dynamic_audio_buffer_support;// 扩展广播过滤功能的能力掩码(位掩码)。每一位代表一种过滤特性(如基于厂商数据(Manufacturer Data)的过滤、基于服务 UUID 的过滤),协议栈可根据此掩码启用特定过滤规则uint16_t adv_filter_extended_features_mask;// 是否支持A2DP 卸载 V2 版本。V2 可能包含新特性(如更高音质的编码、更低延迟的传输),此标志用于兼容新旧硬件uint8_t a2dp_offload_v2_support;
} tBTM_BLE_VSC_CB;

存储蓝牙控制器(Controller)支持的扩展功能与硬件能力,帮助协议栈(Host)根据实际硬件能力动态调整行为,确保功能兼容性和性能优化。

tBTM_BLE_VSC_CB 是 BLE 协议栈与硬件控制器之间的 “能力桥梁”,通过存储控制器的厂商特定功能参数,协议栈能够:

  • 安全适配硬件:避免发送超出控制器能力的命令,降低硬件错误风险。

  • 优化功能体验:根据硬件能力启用高级特性(如 RPA 卸载、A2DP 硬件编码),提升性能与功耗表现。

  • 兼容多厂商芯片:通过版本号和能力掩码适配不同厂商的控制器,确保跨平台兼容性。

这一设计是蓝牙协议栈 “硬件无关性” 的关键体现,使得同一套协议栈代码能够运行在不同厂商的蓝牙芯片上,同时充分发挥硬件的最佳性能。

tBTM_INQUIRY_VAR_ST btm_inq_vars

packages/modules/Bluetooth/system/stack/btm/neighbor_inquiry.h
// 远程设备名称查询完成回调
typedef void(tBTM_NAME_CMPL_CB)(const tBTM_REMOTE_DEV_NAME*);/* General callback function for notifying an application that a synchronous* BTM function is complete. The pointer contains the address of any returned* data.*/
//  通用完成回调 
typedef void(tBTM_CMPL_CB)(void* p1);/*****************************************  Device Discovery Callback Functions****************************************/
/* Callback function for notifications when the BTM gets inquiry response.* First param is inquiry results database, second is pointer of EIR.*/
// 查询结果回调 
typedef void(tBTM_INQ_RESULTS_CB)(tBTM_INQ_RESULTS* p_inq_results,const uint8_t* p_eir, uint16_t eir_len);// 查询参数结构体
typedef struct /* contains the parameters passed to the inquiry functions */
{uint8_t mode;     /* general or limited */uint8_t duration; /* duration of the inquiry (1.28 sec increments) */
} tBTM_INQ_PARMS;// 查询完成结果结构体
/* Structure returned with inquiry complete callback */
typedef struct {// Possible inquiry completion statusenum STATUS {CANCELED,      // Expected user API cancelTIMER_POPPED,  // Expected controller initiated timeoutNOT_STARTED,   // Unexpected controller unable to execute inquiry commandSSP_ACTIVE,    // Unexpected secure simple pairing is operational};STATUS status;tHCI_STATUS hci_status;uint8_t num_resp; /* Number of results from the current inquiry */unsigned resp_type[kMaxNumberInquiryResults];long long start_time_ms;
} tBTM_INQUIRY_CMPL;// 蓝牙经典查询过程的核心,管理查询的参数、状态、定时器和回调,确保设备发现流程的有序执行
struct tBTM_INQUIRY_VAR_ST {// 回调与定时器管理tBTM_NAME_CMPL_CB* p_remname_cmpl_cb;  /* 远程设备名称查询完成回调 */alarm_t* remote_name_timer; /* 远程名称查询定时器(超时触发) */alarm_t* classic_inquiry_timer; /* 经典查询定时器(控制查询时长) */uint16_t discoverable_mode;uint16_t connectable_mode;uint16_t page_scan_window;    /* 寻呼扫描窗口(决定寻呼持续时间,单位:0.625ms) */uint16_t page_scan_period;    /* 寻呼扫描周期(寻呼的时间间隔,单位:0.625ms) */uint16_t inq_scan_window;     /* 查询扫描窗口(查询的持续时间,单位:0.625ms) */uint16_t inq_scan_period;     /* 查询扫描周期(查询的时间间隔,单位:0.625ms) */uint16_t inq_scan_type;uint16_t page_scan_type; /* current page scan type */RawAddress remname_bda; /* Name of bd addr for active remote name request */
#define BTM_RMT_NAME_EXT 0x1 /* Initiated through API */bool remname_active; /* State of a remote name request by external API */tBTM_CMPL_CB* p_inq_cmpl_cb;tBTM_INQ_RESULTS_CB* p_inq_results_cb;uint32_t inq_counter; /* Counter incremented each time an inquiry completes *//* Used for determining whether or not duplicate devices *//* have responded to the same inquiry */tBTM_INQ_PARMS inqparms; /* Contains the parameters for the current inquiry */tBTM_INQUIRY_CMPLinq_cmpl_info; /* Status and number of responses from the last inquiry */uint16_t per_min_delay; /* Current periodic minimum delay */uint16_t per_max_delay; /* Current periodic maximum delay *//* inquiry that has been cancelled*/uint8_t inqfilt_type; /* Contains the inquiry filter type (BD ADDR, COD, orClear) */#define BTM_INQ_INACTIVE_STATE 0
#define BTM_INQ_ACTIVE_STATE \3 /* Actual inquiry or periodic inquiry is in progress */uint8_t state;      /* Current state that the inquiry process is in */uint8_t inq_active; /* Bit Mask indicating type of inquiry is active */bool no_inc_ssp;    /* true, to stop inquiry on incoming SSP */bool registered_for_hci_events;void Init() {p_remname_cmpl_cb = nullptr;alarm_free(remote_name_timer);alarm_free(classic_inquiry_timer);remote_name_timer = alarm_new("btm_inq.remote_name_timer");classic_inquiry_timer = alarm_new("btm_inq.classic_inquiry_timer");discoverable_mode = BTM_NON_DISCOVERABLE;connectable_mode = BTM_NON_CONNECTABLE;page_scan_window = HCI_DEF_PAGESCAN_WINDOW;page_scan_period = HCI_DEF_PAGESCAN_INTERVAL;inq_scan_window = HCI_DEF_INQUIRYSCAN_WINDOW;inq_scan_period = HCI_DEF_INQUIRYSCAN_INTERVAL;inq_scan_type = BTM_SCAN_TYPE_STANDARD;page_scan_type = HCI_DEF_SCAN_TYPE;remname_bda = {};remname_active = false;p_inq_cmpl_cb = nullptr;p_inq_results_cb = nullptr;inq_counter = 0;inqparms = {};inq_cmpl_info = {};per_min_delay = 0;per_max_delay = 0;state = BTM_INQ_INACTIVE_STATE;inq_active = 0;no_inc_ssp = BTM_NO_SSP_ON_INQUIRY;registered_for_hci_events = false;}void Free() {alarm_free(remote_name_timer);alarm_free(classic_inquiry_timer);}
};

tBTM_INQUIRY_VAR_ST 及关联结构体的设计体现了蓝牙设备发现的状态集中管理和低功耗优化两大核心目标:

①状态集中管理

所有查询相关的参数(扫描窗口、持续时间)、状态(活跃 / 非活跃)、资源(定时器、回调)被整合到一个结构体中,确保:

  • 原子性操作:通过stateinq_active防止并发操作(如同时启动两个查询)。

  • 快速故障排查:通过inq_cmpl_info记录查询完成状态(如超时、用户取消),便于定位问题。

低功耗优化

  • 扫描参数动态配置:通过page_scan_windowinq_scan_period平衡发现速度与功耗(如配对时增大窗口,待机时减小窗口)。

  • 定时器控制classic_inquiry_timer 确保查询不会无限持续(由duration参数限制),避免不必要的功耗浪费。

tSCO_CB sco_cb

typedef uint16_t tBTM_SCO_CODEC_TYPE; //标识 SCO/eSCO 连接使用的音频编解码器类型(如 CVSD、mSBC、LC3)/* Define the structure that contains (e)SCO data */
typedef struct {/* eSCO事件回调(如连接完成、断开) */tBTM_ESCO_CBACK* p_esco_cback; /* Callback for eSCO events     *//* eSCO参数(如编码格式、传输间隔) */enh_esco_params_t setup;/* 连接完成后的详细信息(如链路参数) */tBTM_ESCO_DATA data; /* Connection complete information */uint8_t hci_status;
} tBTM_ESCO_INFO;/* Define the structures needed by sco */
typedef enum : uint16_t {SCO_ST_UNUSED = 0,          // 未使用(初始状态)SCO_ST_LISTENING = 1,       // 监听状态(等待对端发起连接)SCO_ST_W4_CONN_RSP = 2,     // 等待连接响应(已发送连接请求,等待控制器回复)SCO_ST_CONNECTING = 3,      // 连接中(控制器正在建立物理链路)SCO_ST_CONNECTED = 4,       // 已连接(链路建立完成,可传输数据)SCO_ST_DISCONNECTING = 5,   // 断开中(正在终止链路)SCO_ST_PEND_UNPARK = 6,     // 等待解除暂停(蓝牙Park模式恢复)SCO_ST_PEND_ROLECHANGE = 7, // 等待角色切换(主从角色变更)SCO_ST_PEND_MODECHANGE = 8, // 等待模式切换(如从活动模式切换到节能模式)
} tSCO_STATE;/* Define the structure used for SCO Management */
typedef struct {// eSCO连接的配置与状态信息tBTM_ESCO_INFO esco;    /* Current settings             */// 连接完成回调(链路建立成功时触发)tBTM_SCO_CB* p_conn_cb; /* Callback for when connected  */// 断开完成回调(链路终止时触发)tBTM_SCO_CB* p_disc_cb; /* Callback for when disconnect */// 当前连接状态(由tSCO_STATE枚举定义)tSCO_STATE state;       /* The state of the SCO link    */uint16_t hci_handle;    /* HCI Handle                   */public:bool is_active() const { return state != SCO_ST_UNUSED; }bool is_inband() const {return esco.setup.input_data_path == ESCO_DATA_PATH_HCI;}tBTM_SCO_CODEC_TYPE get_codec_type() const {switch (esco.setup.coding_format) {case ESCO_CODING_FORMAT_CVSD:return BTM_SCO_CODEC_CVSD;case ESCO_CODING_FORMAT_MSBC:return BTM_SCO_CODEC_MSBC;case ESCO_CODING_FORMAT_LC3:return BTM_SCO_CODEC_LC3;default:return BTM_SCO_CODEC_NONE;}}uint16_t Handle() const { return hci_handle; }bool is_orig;           /* true if the originator       */bool rem_bd_known;      /* true if remote BD addr known */} tSCO_CONN;/* SCO Management control block */
typedef struct {tSCO_CONN sco_db[BTM_MAX_SCO_LINKS]; // SCO连接数组(最多支持BTM_MAX_SCO_LINKS条链路)enh_esco_params_t def_esco_parms; // 默认eSCO参数(新连接的初始配置)// 是否支持eSCO(由硬件能力决定)bool esco_supported;        /* true if 1.2 cntlr AND supports eSCO links */tSCO_CONN* get_sco_connection_from_index(uint16_t index) {return (index < kMaxScoLinks) ? (&sco_db[index]) : nullptr;}tSCO_CONN* get_sco_connection_from_handle(uint16_t handle) {tSCO_CONN* p_sco = sco_db;for (uint16_t xx = 0; xx < kMaxScoLinks; xx++, p_sco++) {if (p_sco->hci_handle == handle) {return p_sco;}}return nullptr;}void Init();void Free();// 获取连接在数组中的索引(用于资源释放或状态同步)uint16_t get_index(const tSCO_CONN* p_sco) const {CHECK(p_sco != nullptr);const tSCO_CONN* p = sco_db;for (uint16_t xx = 0; xx < kMaxScoLinks; xx++, p++) {if (p_sco == p) {return xx;}}return 0xffff;}} tSCO_CB;

蓝牙 SCO/eSCO 连接管理的核心实现,通过状态机、多链路存储和高效查找方法,确保了语音 / 音频传输的稳定性和可靠性,是蓝牙音频功能(如耳机通话、语音助手)的底层支撑。

为什么需要区分 SCO 和 eSCO?

  • SCO 是蓝牙经典的同步连接(用于语音),但抗丢包能力弱;

  • eSCO(增强型)通过重传、可变传输间隔等优化,提升了音质和稳定性,适用于更高质量的语音或音频流(如音乐)。esco_supported标志用于判断硬件是否支持 eSCO,确保功能兼容性。

BTM_Sec_Init

packages/modules/Bluetooth/system/stack/btm/btm_sec_cb.cc
// 蓝牙安全模块的核心控制结构,存储蓝牙设备的安全配置、配对信息、密钥管理等状态
tBTM_SEC_CB btm_sec_cb;// 初始化蓝牙安全模块,设置安全模式(Secure Connection 或 Simple Pairing)
void BTM_Sec_Init() {// 查询配置接口,判断是否启用 “仅安全连接模式”(通常由系统配置或测试模式决定)btm_sec_cb.Init(stack_config_get_interface()->get_pts_secure_only_mode()? BTM_SEC_MODE_SC: BTM_SEC_MODE_SP);
}

安全控制块 tBTM_SEC_CB 的实例化和安全模式的设置。

两种安全模式对比:

模式核心特性安全性兼容性
BTM_SEC_MODE_SC- 使用椭圆曲线 Diffie-Hellman(ECDH)密钥交换
- 支持 LE Secure Connections(蓝牙 4.2+)
仅支持蓝牙 4.2 + 设备
BTM_SEC_MODE_SP- 使用基于 PIN 码或 Just Works 的配对
- 依赖传统对称密钥交换
兼容所有蓝牙设备
  • SP 模式风险:传统简单配对(如 Just Works)易受中间人攻击(MITM),且密钥生成过程不够安全(如 PIN 码长度不足)。

  • SC 模式优势:通过 ECDH 生成会话密钥,结合认证和加密,大幅提升安全性,是蓝牙 5.0 + 设备的默认配对方式。

模式选择的应用场景:

  • 强制 SC 模式(get_pts_secure_only_mode() == true):

    • 安全性要求高的场景(如医疗设备、支付终端)。

    • 测试环境(如蓝牙协议一致性测试 PTS,要求使用安全连接)。

  • 兼容 SP 模式(get_pts_secure_only_mode() == false):

    • 需兼容旧设备的场景(如与蓝牙 2.1 设备配对)。

    • 普通消费级设备(如耳机、音箱),在安全性和兼容性间平衡。

tBTM_SEC_CB::Init

packages/modules/Bluetooth/system/stack/btm/btm_sec_cb.cc
void tBTM_SEC_CB::Init(uint8_t initial_security_mode) {// 内存初始化:清零关键数据结构memset(&cfg, 0, sizeof(cfg));memset(&devcb, 0, sizeof(devcb));memset(&enc_rand, 0, sizeof(enc_rand));memset(&api, 0, sizeof(api));memset(&pin_code, 0, sizeof(pin_code));memset(sec_serv_rec, 0, sizeof(sec_serv_rec));connecting_bda = RawAddress::kEmpty;memset(&connecting_dc, 0, sizeof(connecting_dc));// 资源分配:创建队列和定时器// 存储待处理的安全请求(如配对请求、加密协商),确保安全操作按顺序执行,避免并发冲突(如同时处理多个配对请求导致密钥混乱)sec_pending_q = fixed_queue_new(SIZE_MAX);// 检测配对冲突(如多个设备同时发起配对请求时触发超时,避免资源竞争)sec_collision_timer = alarm_new("btm.sec_collision_timer");// 控制配对流程的超时时间(如等待对端响应的最大时间,默认约 60 秒)pairing_timer = alarm_new("btm.pairing_timer");// 等待安全操作执行完成(如密钥生成或加密启动的超时控制)execution_wait_timer = alarm_new("btm.execution_wait_timer");// 安全模式初始化security_mode = initial_security_mode;pairing_bda = RawAddress::kAny;  // 通配符地址,表示可与任意设备配对// 存储所有配对过的设备的安全记录(如链路密钥、设备地址、加密参数)sec_dev_rec = list_new([](void* ptr) {// Invoke destructor for all record objects and reset to default// initialized value so memory may be properly freed*((tBTM_SEC_DEV_REC*)ptr) = {};osi_free(ptr);});
}

完成安全模块的状态清零、资源分配和参数初始化

tBTM_CFG cfg

packages/modules/Bluetooth/system/stack/btm/btm_sec_int_types.h
// 以字节数组形式存储设备名称
typedef uint8_t tBTM_LOC_BD_NAME[BTM_MAX_LOC_BD_NAME_LEN + 1];typedef uint8_t PIN_CODE[PIN_CODE_LEN]; /* Pin Code (upto 128 bits) MSB is 0 *//** Local device configuration*/
typedef struct {tBTM_LOC_BD_NAME bd_name; /* local Bluetooth device name */bool pin_type;            /* true if PIN type is fixed */uint8_t pin_code_len;     /* Bonding information */PIN_CODE pin_code;        /* PIN CODE if pin type is fixed */
} tBTM_CFG;

tBTM_CFG 是蓝牙安全模块中本地设备配置的核心结构体,其设计体现了以下原则:

  1. 兼容性:支持固定 PIN 和动态 PIN 两种模式,兼容不同类型的蓝牙设备(外设与主机)。

  2. 安全性:通过长度限制和动态生成机制降低 PIN 码泄露风险。

  3. 易用性:设备名称直接影响用户体验,固定 PIN 模式简化了外设的配对流程。

此结构体是蓝牙配对和设备发现的基础,确保安全模块能根据设备类型和用户配置灵活调整安全策略。

tBTM_SEC_DEVCB devcb

packages/modules/Bluetooth/system/stack/btm/btm_sec_int_types.h
/* General callback function for notifying an application that a synchronous* BTM function is complete. The pointer contains the address of any returned* data.*/
typedef void(tBTM_CMPL_CB)(void* p1); // 通知上层应用安全相关的同步操作(如密钥读取、存储、删除)已完成using Octet16 = std::array<uint8_t, kOctet16Length>; // 存储密钥、随机数等 128 位数据typedef uint8_t tBTM_IO_CAP;
typedef uint8_t tBTM_AUTH_REQ;typedef struct {Octet16 ir;    // 身份解析随机数(Identity Resolving Random)Octet16 irk;   // 身份解析密钥(Identity Resolving Key)Octet16 dhk;   // Diffie-Hellman公共密钥(用于安全连接)
} tBTM_BLE_LOCAL_ID_KEYS;/* Define the Device Management control structure*/
typedef struct tBTM_SEC_DEVCB {tBTM_CMPL_CB*p_stored_link_key_cmpl_cb; /* Read/Write/Delete stored link key    */tBTM_BLE_LOCAL_ID_KEYS id_keys;   /* local BLE ID keys */Octet16 ble_encryption_key_value; /* BLE encryption key */tBTM_IO_CAP loc_io_caps;    /* IO capability of the local device */tBTM_AUTH_REQ loc_auth_req; /* the auth_req flag  */
} tBTM_SEC_DEVCB;

tBTM_SEC_DEVCB 是蓝牙安全模块的核心数据结构,其设计体现了以下关键目标:

  • 密钥安全存储:通过固定长度数组(Octet16)确保密钥长度正确,避免内存错误。

  • 动态安全策略:根据设备 IO 能力和认证需求(loc_io_capsloc_auth_req)灵活调整配对流程,平衡安全性与用户体验。

  • 隐私与认证的统一:结合 BLE 隐私地址和安全连接机制,确保设备在可识别的同时防止追踪和攻击。

此结构体是蓝牙配对、密钥管理和数据加密的基础,为蓝牙通信提供了从设备发现到数据传输的全流程安全保障。

  • 不同 IO 能力的配对方式:

IO 能力配对方式安全性
仅显示用户确认配对码(设备显示,用户输入到对端)高(防 MITM)
显示 + 确认自动比较配对码(双方显示相同码)
仅键盘用户输入配对码(对端显示,本地输入)
无 IOJust Works(无认证,易受攻击)
  • 认证请求标志的作用:loc_auth_req包含BTM_AUTHREQ_MITM_PROTECTION,则强制使用 ECDH 密钥交换,确保配对过程中密钥不被中间人窃取。

BT_OCTET8 enc_rand

packages/modules/Bluetooth/system/stack/include/bt_octets.h
#define BT_OCTET8_LEN 8
typedef uint8_t BT_OCTET8[BT_OCTET8_LEN]; /* octet array: size 16 */

tBTM_APPL_INFO api

packages/modules/Bluetooth/system/stack/include/security_client_callbacks.h
/* Get PIN for the connection.  Parameters are*              BD Address of remote*              Device Class of remote*              BD Name of remote*              Flag indicating the minimum pin code length to be 16 digits*/
// PIN 码管理回调
typedef uint8_t(tBTM_PIN_CALLBACK)(const RawAddress& bd_addr,DEV_CLASS dev_class,const tBTM_BD_NAME bd_name,bool min_16_digit);/* New Link Key for the connection.  Parameters are*              BD Address of remote*              Link Key*              Key Type: Combination, Local Unit, or Remote Unit*/
// 链路密钥管理回调
typedef uint8_t(tBTM_LINK_KEY_CALLBACK)(const RawAddress& bd_addr,DEV_CLASS dev_class,tBTM_BD_NAME bd_name,const LinkKey& key, uint8_t key_type,bool is_ctkd);/* Authentication complete for the connection.  Parameters are*              BD Address of remote*              Device Class of remote*              BD Name of remote**/
// 认证完成回调
typedef void(tBTM_AUTH_COMPLETE_CALLBACK)(const RawAddress& bd_addr,DEV_CLASS dev_class,tBTM_BD_NAME bd_name,tHCI_REASON reason);/* Bond Cancel complete. Parameters are*              Result of the cancel operation*
*/
// 绑定取消回调
typedef void(tBTM_BOND_CANCEL_CMPL_CALLBACK)(tBTM_STATUS result);/* Simple Pairing Events.  Called by the stack when Simple Pairing related* events occur.
*/
// 简单配对事件回调
typedef tBTM_STATUS(tBTM_SP_CALLBACK)(tBTM_SP_EVT event,tBTM_SP_EVT_DATA* p_data);/* Simple Pairing Events.  Called by the stack when Simple Pairing related* events occur.*/
// LE 安全事件回调
typedef uint8_t(tBTM_LE_CALLBACK)(tBTM_LE_EVT event, const RawAddress& bda,tBTM_LE_EVT_DATA* p_data);                       //  BLE 本地身份密钥结构体
typedef struct {Octet16 ir;   // 身份解析随机数(Identity Resolving Random)Octet16 irk;  // 身份解析密钥(Identity Resolving Key)Octet16 dhk;  // Diffie-Hellman密钥(用于安全连接)
} tBTM_BLE_LOCAL_ID_KEYS;/* New LE identity key for local device.*/
// LE 密钥生成回调
typedef void(tBTM_LE_KEY_CALLBACK)(uint8_t key_type,tBTM_BLE_LOCAL_KEYS* p_key);/* Request SIRK verification for found member. Parameters are*              BD Address of remote*/
//  SIRK 验证回调
typedef uint8_t(tBTM_SIRK_VERIFICATION_CALLBACK)(const RawAddress& bd_addr);struct tBTM_APPL_INFO {tBTM_PIN_CALLBACK* p_pin_callback{nullptr};tBTM_LINK_KEY_CALLBACK* p_link_key_callback{nullptr};tBTM_AUTH_COMPLETE_CALLBACK* p_auth_complete_callback{nullptr};tBTM_BOND_CANCEL_CMPL_CALLBACK* p_bond_cancel_cmpl_callback{nullptr};tBTM_SP_CALLBACK* p_sp_callback{nullptr};tBTM_LE_CALLBACK* p_le_callback{nullptr};tBTM_LE_KEY_CALLBACK* p_le_key_callback{nullptr};tBTM_SIRK_VERIFICATION_CALLBACK* p_sirk_verification_callback{nullptr};
};

蓝牙安全模块与上层应用之间的回调接口,是蓝牙协议栈中安全机制的核心通信桥梁。

PIN_CODE pin_code

packages/modules/Bluetooth/system/stack/include/bt_octets.h
#define PIN_CODE_LEN 16
typedef uint8_t PIN_CODE[PIN_CODE_LEN]; /* Pin Code (upto 128 bits) MSB is 0 */

tBTM_SEC_SERV_REC sec_serv_rec[BTM_SEC_MAX_SERVICE_RECORDS]

packages/modules/Bluetooth/system/stack/btm/security_device_record.h
/* Maximum length of the service name. */
#ifndef BT_MAX_SERVICE_NAME_LEN
#define BT_MAX_SERVICE_NAME_LEN 21
#endiftypedef struct {uint32_t mx_proto_id;     /* Service runs over this multiplexer protocol */uint32_t orig_mx_chan_id; /* Channel on the multiplexer protocol    */uint32_t term_mx_chan_id; /* Channel on the multiplexer protocol    */uint16_t psm;             /* L2CAP PSM value */uint16_t security_flags;  /* Bitmap of required security features */uint8_t service_id;       /* Passed in authorization callback */uint8_t orig_service_name[BT_MAX_SERVICE_NAME_LEN + 1];uint8_t term_service_name[BT_MAX_SERVICE_NAME_LEN + 1];
} tBTM_SEC_SERV_REC;

安全模块中与服务安全记录相关的数据结构tBTM_SEC_SERV_REC,用于存储蓝牙服务的安全配置和通道信息。

管理蓝牙服务(如 SPP、HID、A2DP 等)的安全策略,确保不同服务在通信时满足特定的安全要求(如加密等级、认证方式)。

DEV_CLASS connecting_dc

packages/modules/Bluetooth/system/stack/include/bt_dev_class.h
constexpr size_t kDevClassLength = 3;
typedef std::array<uint8_t, kDevClassLength> DEV_CLASS; /* Device class */

蓝牙设备类(Device Class,简称 COD,Class of Device)的数据结构DEV_CLASS,用于标识蓝牙设备的类型和功能。

蓝牙核心规范规定,设备类由 3 字节(24 位)组成,分为三个部分:

  1. 主设备类(Major Device Class,8 位):标识设备的大类(如手机、耳机、电脑)。

  2. 次设备类(Minor Device Class,8 位):在大类下进一步细分(如手机中的 “智能手机”“普通手机”)。

  3. 服务类别掩码(Service Class Mask,8 位):标识设备支持的服务(如电话服务、网络服务)。

btm_inq_db_set_inq_by_rssi

packages/modules/Bluetooth/system/stack/btm/btm_inq.cc
struct {bool inq_by_rssi{false}; // 标志位,指示是否启用基于 RSSI 的设备搜索策略
} internal_;#ifndef PROPERTY_INQ_BY_RSSI
#define PROPERTY_INQ_BY_RSSI "persist.bluetooth.inq_by_rssi" // 持久化系统属性,用于动态控制搜索策略
#endifvoid btm_inq_db_set_inq_by_rssi(void) {internal_.inq_by_rssi = osi_property_get_bool(PROPERTY_INQ_BY_RSSI, false);
}

基于 RSSI的设备搜索功能配置,通过系统属性persist.bluetooth.inq_by_rssi控制是否启用基于 RSSI 的搜索。这种设计允许设备厂商根据具体场景优化蓝牙体验,在连接速度、稳定性和功耗之间取得平衡。

osi_property_get_bool

packages/modules/Bluetooth/system/osi/src/properties.cc
bool osi_property_get_bool(const char* key, bool default_value) {std::optional<std::string> result = bluetooth::os::GetSystemProperty(key);if (result) {return *result == std::string("true");} else {return default_value;}
}

从系统属性中读取布尔值的功能,是蓝牙协议栈与操作系统之间的关键接口。

三、流程图

1. BTM 初始化流程图

2. BTM 初始化时序图

3. tBTM_CB 初始化子模块流程图

4. 安全模块初始化时序图

四、总结

BTM 子系统的设计充分体现了蓝牙协议栈的分层解耦与硬件适配能力:

①模块化设计:BTM 初始化通过分层控制块(如 tBTM_CBtBTM_SEC_CB)实现功能解耦,各子模块(设备管理、安全、语音链路)独立初始化,提升代码可维护性。

②安全性与兼容性平衡

  1. Secure Connection 模式优先保障通信安全,Simple Pairing 模式兼容旧设备。

  2. 密钥存储与动态生成机制(如 IRK、DHK)兼顾隐私保护和连接效率。

③性能优化

  1. 环形日志缓冲区减少内存占用,支持快速故障排查。

  2. 基于 RSSI 的设备发现策略减少无效扫描,降低功耗。

④扩展性

  1. 厂商特定命令(VSC)支持硬件能力适配(如 RPA 卸载、扩展广播)。

  2. 条件编译和系统属性(如 persist.bluetooth.inq_by_rssi)实现平台差异化配置。

⑤动态配置:系统属性驱动的功能开关,使协议栈能根据硬件能力和用户需求灵活调整行为,是蓝牙设备跨平台适配的关键。

蓝牙协议栈在启动阶段完成从底层硬件适配到上层安全策略的全链路初始化,为多设备连接、数据传输和语音通信提供可靠基础。


相关文章:

  • 【生产实践】Kibana控制台暴露风险:Nginx反向代理+权限控制实战方案(附避坑指南)
  • 一种经济实用的尖峰电压防护-PCB放电齿
  • GC1267F单相全波风扇电机预驱动器芯片详解
  • 【ArcGIS Pro微课1000例】0071:将无人机照片生成航线、轨迹点、坐标高程、方位角
  • Spring Boot 启动流程深度解析:从源码到实践
  • 高温炉制造企业Odoo ERP实施规划与深度分析报告
  • 免杀二 内存函数与加密
  • 影响沉金价格的因素如何体现在多层电路板制造上?
  • 智警杯备赛--数据库管理与优化
  • 基于stm32风速风向温湿度和瓦斯检测(仿真+代码)
  • 2025.05.28【读书笔记】|如何用SILVA和RFAM数据库高效去除rRNA污染
  • C++11:系统类型增强
  • Redis keydb dragonfly skytable
  • uni-app开发特殊社交APP
  • 人工智能在智慧物流中的创新应用与未来趋势
  • Flask集成pyotp生成动态口令
  • 时序数据库IoTDB如何快速高效地存储时序数据
  • 深兰科技陈海波率队考察南京,加速AI医诊大模型区域落地应用
  • Android 缓存应用冻结器(Cached Apps Freezer)
  • 深兰科技董事长陈海波率队考察南京,加速AI大模型区域落地应用
  • 太原网站建设乛薇/策划是做什么的
  • 网址搜索栏/seo网站分析
  • 手机微网站开发/cpa游戏推广联盟
  • .net 网站优化/微信朋友圈广告投放代理
  • python做网站的好处/推广app赚钱项目
  • 网站开发的语言/互联网营销师培训费用是多少