【Bluedroid】蓝牙启动之核心模块(startProfiles )初始化与功能源码解析
本文深入解析Android蓝牙协议栈中
start_profiles
函数及其调用的核心模块初始化逻辑,涵盖 BNEP、PAN、A2DP、AVRC、HID Host、BTA_AR 等关键配置文件和应用层模块。通过代码分析与流程梳理,阐述各模块如何通过全局控制块、状态机、回调机制实现功能初始化、连接管理及数据交互,揭示蓝牙设备在音频传输、网络共享、设备控制等场景下的底层实现原理。
一、概述
1.1 start_profiles
start_profiles
是蓝牙协议栈启动阶段的核心函数,通过 编译宏开关(如 BNEP_INCLUDED
、HID_HOST_INCLUDED
)动态加载所需功能模块。核心逻辑包括:
-
条件编译:根据硬件能力与产品需求选择性初始化模块(如仅支持音频功能的设备可禁用 BNEP/PAN)。
-
顺序初始化:按依赖关系初始化模块(如先初始化 BNEP 再初始化 PAN,因 PAN 依赖 BNEP 的网络传输能力)。
1.2 核心模块功能与初始化逻辑
①BNEP(基本网络封装协议)
-
功能:在蓝牙链路上封装 IP 数据报,为网络连接提供底层传输支持。
-
初始化:通过
BNEP_Init
清零全局控制块bnep_cb
,初始化连接池、回调指针及 L2CAP 配置。 -
关键组件:
-
tBNEP_CB
:存储全局状态(如连接池、回调函数)。 -
tBNEP_CONN
:管理单个连接的状态机、过滤规则及数据缓存。 -
回调机制:通过
p_conn_ind_cb
等回调与上层 PAN 模块交互,处理连接请求、数据接收等事件。
-
②PAN(个人区域网络)
-
功能:基于 BNEP 实现蓝牙设备间局域网连接(如手机共享网络至笔记本)。
-
初始化:通过
PAN_Init
清零全局控制块pan_cb
,配置角色(NAP/GN/U)及 SDP 服务句柄。 -
关键组件:
-
tPAN_CB
:管理角色状态、连接池及桥接请求回调(pan_bridge_req_cb
)。 -
与 BNEP 的协作:通过 BNEP 传输 IP 数据,PAN 负责解析数据并与系统网络栈交互。
-
③A2DP(高级音频分发配置文件)
-
功能:实现高质量音频流传输(如蓝牙耳机播放手机音乐)。
-
初始化:通过
A2DP_Init
清零全局控制块a2dp_cb
,设置 AVDTP 协议版本(如0x0103
)。 -
关键组件:
-
tA2DP_CB
:管理 SDP 服务发现回调(tA2DP_FIND_CBACK
)及协议版本兼容性。 -
SDP 服务发现:通过查询
tSDP_DISCOVERY_DB
验证远程设备是否支持 A2DP 服务。
-
④AVRC(音视频远程控制配置文件)
-
功能:支持设备间音视频控制(如耳机调节手机音量)。
-
初始化:通过
AVRC_Init
清零全局控制块avrc_cb
,初始化命令队列与分片重组机制。 -
关键组件:
-
tAVRC_CONN_INT_CB
:管理命令序列化与超时定时器(tle
)。 -
消息处理:通过
tAVRC_FRAG_CB
和tAVRC_RASM_CB
处理大消息分片,确保指令可靠传输。
-
⑤HID Host(人机接口设备主机模式)
-
功能:作为主机连接 HID 外设(如蓝牙键盘、鼠标)。
-
初始化:通过
HID_HostInit
清零全局控制块hh_cb
,配置 L2CAP 通道与设备连接池。 -
关键组件:
-
tHID_HOST_DEV_CTB
:管理单个设备的连接状态、重试次数及中断通道数据。 -
SDP 能力协商:通过
tHID_DEV_SDP_INFO
验证设备子类(如键盘 / 鼠标)及协议版本。
-
⑥BTA_AR(音频路由应用层模块)
-
功能:管理音频流连接与路由切换(如手机与耳机的音频协商)。
-
初始化:通过
bta_ar_init
清零全局控制块bta_ar_cb
,注册至 AVDT/AVCT 协议。 -
关键组件:
-
tBTA_AR_CB
:存储协议注册状态(avdt_registered
)、SDP 句柄及音频类别(ct_categories
)。 -
流控制流程:通过
p_av_conn_cback
回调处理 AVDT 连接请求,协商音频参数后建立流通道。
-
二、源码解析
start_profiles
packages/modules/Bluetooth/system/btif/src/bluetooth.cc
static void start_profiles() {
// BNEP(Basic Network Encapsulation Protocol,基本网络封装协议):用于在蓝牙链路上封装和传输 IP 数据报,是蓝牙实现网络连接的基础协议
#if (BNEP_INCLUDED == TRUE)BNEP_Init();
// PAN(Personal Area Network,个人区域网络配置文件):基于 BNEP 实现蓝牙设备间的局域网(PAN)连接(如手机通过蓝牙共享网络给笔记本)
#if (PAN_INCLUDED == TRUE)PAN_Init();
#endif /* PAN */
#endif /* BNEP Included */A2DP_Init();AVRC_Init();
#if (HID_HOST_INCLUDED == TRUE)HID_HostInit();
#endif// 音频路由初始化bta_ar_init();
}
根据项目编译配置(通过宏定义控制),初始化蓝牙协议栈中需要启用的功能模块(配置文件)。这些模块是蓝牙设备实现具体功能(如音频传输、网络连接、设备控制等)的基础。
实际项目中,这些宏定义(如 BNEP_INCLUDED
)通常由编译时的配置文件(bt_target.h
)或编译选项决定,可根据设备硬件能力(如是否支持蓝牙 5.0+)或产品需求(如是否需要音频功能)启用或禁用特定模块。
BNEP_Init
packages/modules/Bluetooth/system/stack/bnep/bnep_api.cc
/********************************************************************************* Function BNEP_Init** Description This function initializes the BNEP unit. It should be called* before accessing any other APIs to initialize the control* block.** Returns void*******************************************************************************/
void BNEP_Init(void) {memset(&bnep_cb, 0, sizeof(tBNEP_CB));
}packages/modules/Bluetooth/system/stack/bnep/bnep_main.cc
/******************************************************************************/
/* G L O B A L B N E P D A T A */
/******************************************************************************/
tBNEP_CB bnep_cb; // BNEP 模块的全局控制块,存储整个 BNEP 模块的运行状态和配置packages/modules/Bluetooth/system/stack/bnep/bnep_int.h
// 单个 BNEP 连接的控制块
// 每个 BNEP 连接(如手机与笔记本的蓝牙网络连接)对应一个 tBNEP_CONN 实例
// 存储该连接的详细状态和参数
/* Define the BNEP Connection Control Block
*/
typedef struct {
#define BNEP_STATE_IDLE 0
#define BNEP_STATE_CONN_START 1
#define BNEP_STATE_CFG_SETUP 2
#define BNEP_STATE_CONN_SETUP 3
#define BNEP_STATE_SEC_CHECKING 4
#define BNEP_STATE_SETUP_RCVD 5
#define BNEP_STATE_CONNECTED 6uint8_t con_state;#define BNEP_FLAGS_IS_ORIG 0x01
#define BNEP_FLAGS_HIS_CFG_DONE 0x02
#define BNEP_FLAGS_MY_CFG_DONE 0x04
#define BNEP_FLAGS_L2CAP_CONGESTED 0x08
#define BNEP_FLAGS_FILTER_RESP_PEND 0x10
#define BNEP_FLAGS_MULTI_RESP_PEND 0x20
#define BNEP_FLAGS_SETUP_RCVD 0x40
#define BNEP_FLAGS_CONN_COMPLETED 0x80uint8_t con_flags;BT_HDR* p_pending_data; // 未处理的待接收数据指针(临时缓存未完成解析的数据包)uint16_t l2cap_cid;RawAddress rem_bda;alarm_t* conn_timer;fixed_queue_t* xmit_q;uint16_t sent_num_filters;uint16_t sent_prot_filter_start[BNEP_MAX_PROT_FILTERS];uint16_t sent_prot_filter_end[BNEP_MAX_PROT_FILTERS];uint16_t sent_mcast_filters;RawAddress sent_mcast_filter_start[BNEP_MAX_MULTI_FILTERS];RawAddress sent_mcast_filter_end[BNEP_MAX_MULTI_FILTERS];uint16_t rcvd_num_filters;uint16_t rcvd_prot_filter_start[BNEP_MAX_PROT_FILTERS];uint16_t rcvd_prot_filter_end[BNEP_MAX_PROT_FILTERS];uint16_t rcvd_mcast_filters;RawAddress rcvd_mcast_filter_start[BNEP_MAX_MULTI_FILTERS];RawAddress rcvd_mcast_filter_end[BNEP_MAX_MULTI_FILTERS];uint16_t bad_pkts_rcvd;uint8_t re_transmits;uint16_t handle;bluetooth::Uuid prv_src_uuid;bluetooth::Uuid prv_dst_uuid;bluetooth::Uuid src_uuid;bluetooth::Uuid dst_uuid;} tBNEP_CONN;// 定义了 7 类回调函数指针,用于与上层模块(如 PAN Profile)交互
// 上层模块通过注册这些回调,处理具体的业务逻辑(如接收网络数据后转发到系统网络栈)
/* Connection indication callback prototype. Parameters are* BD Address of remote, remote UUID and local UUID* and flag to indicate role change and handle to the connection* When BNEP calls this function profile should* use BNEP_ConnectResp call to accept or reject the request
*/
typedef void(tBNEP_CONNECT_IND_CB)(uint16_t handle, const RawAddress& bd_addr,const bluetooth::Uuid& remote_uuid,const bluetooth::Uuid& local_uuid,bool is_role_change);/* Connection state change callback prototype. Parameters are* Connection handle* BD Address of remote* Connection state change result* BNEP_SUCCESS indicates connection is success* All values are used to indicate the reason for failure* Flag to indicate if it is just a role change
*/
typedef void(tBNEP_CONN_STATE_CB)(uint16_t handle, const RawAddress& rem_bda,tBNEP_RESULT result, bool is_role_change);/* Data received indication callback prototype. Parameters are* Handle to the connection* Source BD/Ethernet Address* Dest BD/Ethernet address* Protocol* Pointer to the beginning of the data* Length of data* Flag to indicate whether extension headers to be forwarded are* present*/
typedef void(tBNEP_DATA_IND_CB)(uint16_t handle, const RawAddress& src,const RawAddress& dst, uint16_t protocol,uint8_t* p_data, uint16_t len,bool fw_ext_present);/* Data buffer received indication callback prototype. Parameters are* Handle to the connection* Source BD/Ethernet Address* Dest BD/Ethernet address* Protocol* Pointer to the buffer* Flag to indicate whether extension headers to be forwarded are* present*/
typedef void(tBNEP_DATA_BUF_CB)(uint16_t handle, const RawAddress& src,const RawAddress& dst, uint16_t protocol,BT_HDR* p_buf, bool fw_ext_present);/* Filters received indication callback prototype. Parameters are* Handle to the connection* true if the cb is called for indication* Ignore this if it is indication, otherwise it is the result* for the filter set operation performed by the local* device* Number of protocol filters present* Pointer to the filters start. Filters are present in pairs* of start of the range and end of the range.* They will be present in big endian order. First* two bytes will be starting of the first range and* next two bytes will be ending of the range.
*/
typedef void(tBNEP_FILTER_IND_CB)(uint16_t handle, bool indication,tBNEP_RESULT result, uint16_t num_filters,uint8_t* p_filters);/* Multicast Filters received indication callback prototype. Parameters are* Handle to the connection* true if the cb is called for indication* Ignore this if it is indication, otherwise it is the result* for the filter set operation performed by the local* device* Number of multicast filters present* Pointer to the filters start. Filters are present in pairs* of start of the range and end of the range.* First six bytes will be starting of the first range and* next six bytes will be ending of the range.
*/
typedef void(tBNEP_MFILTER_IND_CB)(uint16_t handle, bool indication,tBNEP_RESULT result, uint16_t num_mfilters,uint8_t* p_mfilters); /* Flow control callback for TX data. Parameters are* Handle to the connection* Event flow status
*/
typedef void(tBNEP_TX_DATA_FLOW_CB)(uint16_t handle, tBNEP_RESULT event);/* The main BNEP control block
*/
typedef struct {tL2CAP_CFG_INFO l2cap_my_cfg; /* My L2CAP config */tBNEP_CONN bcb[BNEP_MAX_CONNECTIONS]; // 连接池(存储所有活跃的 BNEP 连接)tBNEP_CONNECT_IND_CB* p_conn_ind_cb;tBNEP_CONN_STATE_CB* p_conn_state_cb;tBNEP_DATA_IND_CB* p_data_ind_cb;tBNEP_DATA_BUF_CB* p_data_buf_cb;tBNEP_FILTER_IND_CB* p_filter_ind_cb;tBNEP_MFILTER_IND_CB* p_mfilter_ind_cb;tBNEP_TX_DATA_FLOW_CB* p_tx_data_flow_cb;tL2CAP_APPL_INFO reg_info; // L2CAP 应用注册信息(BNEP 作为 L2CAP 的上层应用,需要向 L2CAP 注册自己的回调和配置)bool profile_registered; /* true when we got our BD addr */} tBNEP_CB;
BNEP(Basic Network Encapsulation Protocol,基本网络封装协议)模块 主要负责在蓝牙链路上封装和传输 IP 数据报,是蓝牙设备实现网络连接(如 PAN 个人区域网络)的基础。
BNEP 模块通过 回调函数 与上层(如 PAN Profile)解耦,典型流程如下:
-
连接请求:远程设备发起 BNEP 连接时,BNEP 模块通过
p_conn_ind_cb
通知上层(如 PAN),上层决定是否接受(通过BNEP_ConnectResp
响应)。 -
连接状态变化:连接建立成功或失败时,BNEP 模块通过
p_conn_state_cb
通知上层当前状态(如BNEP_SUCCESS
表示连接成功)。 -
数据接收:收到蓝牙链路数据后,BNEP 模块解析封装的 IP 数据报,通过
p_data_ind_cb
或p_data_buf_cb
将数据传递给上层(如 PAN 转发到系统网络栈)。 -
过滤规则协商:双方设备协商允许传输的协议或多播地址时,BNEP 模块通过
p_filter_ind_cb
/p_mfilter_ind_cb
通知上层过滤结果。
BNEP 模块是蓝牙协议栈中实现网络数据传输的核心组件,通过 tBNEP_CONN
管理单个连接状态,通过 tBNEP_CB
管理全局配置,通过 回调接口 与上层(如 PAN)交互。BNEP_Init
初始化全局状态后,模块即可处理连接建立、数据传输、过滤协商等操作,为蓝牙设备间的网络通信(如共享互联网)提供基础支持。
PAN_Init
packages/modules/Bluetooth/system/stack/pan/pan_api.cc
tPAN_CB pan_cb;
/********************************************************************************* Function PAN_Init** Description This function initializes the PAN module variables** Parameters: none** Returns none*******************************************************************************/
void PAN_Init(void) {memset(&pan_cb, 0, sizeof(tPAN_CB));
}// 单个 PAN 连接的控制块
// 每个 PAN 连接(如手机与笔记本的蓝牙网络共享)对应一个 tPAN_CONN 实例,存储该连接的详细状态和参数
/* Define the PAN Connection Control Block*/
typedef struct {tPAN_STATE con_state;#define PAN_FLAGS_CONN_COMPLETED 0x01uint8_t con_flags;uint16_t handle;RawAddress rem_bda;uint16_t bad_pkts_rcvd;// 本地与远程设备的 UUID(标识 PAN 服务,确保两端服务匹配)uint16_t src_uuid;uint16_t dst_uuid; uint16_t prv_src_uuid;uint16_t prv_dst_uuid;uint16_t ip_addr_known;uint32_t ip_addr;// 记录发送 / 接收的流量统计,用于监控连接质量struct {size_t octets{0};size_t packets{0};size_t errors{0};size_t drops{0};} write, read;} tPAN_CONN;packages/modules/Bluetooth/system/stack/pan/pan_int.htypedef uint8_t tPAN_ROLE;// 定义了 7 类回调函数指针,用于与上层(如系统网络栈)或下层(如 BNEP)交互
/* This is call back function used to report connection status* to the application. The second parameter true means* to create the bridge and false means to remove it.
*/
typedef void(tPAN_CONN_STATE_CB)(uint16_t handle, const RawAddress& bd_addr,tPAN_RESULT state, bool is_role_change,uint8_t src_role, uint8_t dst_role);/* This is call back function used to create bridge for the* Connected device. The parameter "state" indicates* whether to create the bridge or remove it. true means* to create the bridge and false means to remove it.
*/
typedef void(tPAN_BRIDGE_REQ_CB)(const RawAddress& bd_addr, bool state);/* Data received indication callback prototype. Parameters are* Source BD/Ethernet Address* Dest BD/Ethernet address* Protocol* Address of buffer (or data if non-GKI)* Length of data (non-GKI)* ext is flag to indicate whether it has aby extension headers* Flag used to indicate to forward on LAN* false - Use it for internal stack* true - Send it across the ethernet as well
*/
typedef void(tPAN_DATA_IND_CB)(uint16_t handle, const RawAddress& src,const RawAddress& dst, uint16_t protocol,uint8_t* p_data, uint16_t len, bool ext,bool forward);/* Data buffer received indication callback prototype. Parameters are* Source BD/Ethernet Address* Dest BD/Ethernet address* Protocol* pointer to the data buffer* ext is flag to indicate whether it has aby extension headers* Flag used to indicate to forward on LAN* false - Use it for internal stack* true - Send it across the ethernet as well
*/
typedef void(tPAN_DATA_BUF_IND_CB)(uint16_t handle, const RawAddress& src,const RawAddress& dst, uint16_t protocol,BT_HDR* p_buf, bool ext, bool forward);/* Filters received indication callback prototype. Parameters are* Handle to the connection* true if the cb is called for indication* Ignore this if it is indication, otherwise it is the result* for the filter set operation performed by the local* device* Number of protocol filters present* Pointer to the filters start. Filters are present in pairs* of start of the range and end of the range.* They will be present in big endian order. First* two bytes will be starting of the first range and* next two bytes will be ending of the range.
*/
typedef void(tPAN_FILTER_IND_CB)(uint16_t handle, bool indication,tPAN_RESULT result, uint16_t num_filters,uint8_t* p_filters);/* Multicast Filters received indication callback prototype. Parameters are* Handle to the connection* true if the cb is called for indication* Ignore this if it is indication, otherwise it is the result* for the filter set operation performed by the local* device* Number of multicast filters present* Pointer to the filters start. Filters are present in pairs* of start of the range and end of the range.* First six bytes will be starting of the first range and* next six bytes will be ending of the range.
*/
typedef void(tPAN_MFILTER_IND_CB)(uint16_t handle, bool indication,tPAN_RESULT result, uint16_t num_mfilters,uint8_t* p_mfilters);/* Flow control callback for TX data. Parameters are* Handle to the connection* Event flow status
*/
typedef void(tPAN_TX_DATA_FLOW_CB)(uint16_t handle, tPAN_RESULT event);// PAN 模块的全局控制块, 存储整个 PAN 模块的运行状态和配置
/* The main PAN control block*/
typedef struct {tPAN_ROLE role; // 设备的 PAN 角色(如 NAP 网络访问点、GN 网关、U 用户设备)tPAN_ROLE active_role;tPAN_ROLE prv_active_role;tPAN_CONN pcb[MAX_PAN_CONNS];tPAN_CONN_STATE_CB* pan_conn_state_cb; /* Connection state callback */tPAN_BRIDGE_REQ_CB* pan_bridge_req_cb;tPAN_DATA_IND_CB* pan_data_ind_cb;tPAN_DATA_BUF_IND_CB* pan_data_buf_ind_cb;tPAN_FILTER_IND_CB*pan_pfilt_ind_cb; /* protocol filter indication callback */tPAN_MFILTER_IND_CB*pan_mfilt_ind_cb; /* multicast filter indication callback */tPAN_TX_DATA_FLOW_CB* pan_tx_data_flow_cb;// 不同角色对应的服务名称(用于蓝牙 SDP 服务发现,远程设备通过名称识别 PAN 服务)char* user_service_name;char* gn_service_name;char* nap_service_name;// SDP 服务句柄(标识本地设备注册的 PAN 服务,用于与远程设备交互)uint32_t pan_user_sdp_handle;uint32_t pan_gn_sdp_handle;uint32_t pan_nap_sdp_handle;uint8_t num_conns; // 当前已建立的连接数(用于限制最大连接数)
} tPAN_CB;
PAN(Personal Area Network,个人区域网络)模块 主要基于 BNEP 协议实现蓝牙设备间的局域网连接(如手机通过蓝牙共享网络给笔记本)。
PAN 模块通过 回调函数 与上层(如系统网络栈)、下层(如 BNEP)解耦,典型交互场景如下:
①连接状态通知(tPAN_CONN_STATE_CB
)
当 PAN 连接状态变化(如建立成功、断开、角色切换)时,通过 pan_conn_state_cb
通知上层,上层(如手机系统)可根据状态更新 UI(如显示 “网络已共享”)或调整网络配置(如分配 IP 地址)。
②桥接请求通知(tPAN_BRIDGE_REQ_CB
)
当需要在蓝牙链路与以太网之间创建 / 移除桥接时(如手机作为 NAP 共享移动网络),通过 pan_bridge_req_cb
通知上层,上层(如 Linux 系统的 bridge-utils
)创建虚拟网口,将蓝牙链路与以太网桥接,实现网络共享。
③数据接收通知(tPAN_DATA_IND_CB
/tPAN_DATA_BUF_IND_CB
)
收到蓝牙链路数据后,PAN 模块解析封装的 IP 数据报,通过这两个回调将数据传递给上层,上层(如系统网络栈)将数据转发到目标 IP 地址,或通过桥接发送到以太网(实现手机网络共享给笔记本)。
④过滤规则通知(tPAN_FILTER_IND_CB
/tPAN_MFILTER_IND_CB
)
与远程设备协商协议过滤或多播过滤规则时,通过这两个回调通知上层过滤结果,上层可根据过滤规则限制数据传输(如仅允许 IPv4 数据通过)。
PAN 与 BNEP 的关系
PAN 是 基于 BNEP 的上层应用,依赖 BNEP 实现蓝牙链路的 IP 数据封装与传输:
-
底层传输:PAN 的数据通过 BNEP 封装为蓝牙 L2CAP 数据包,由 BNEP 处理底层链路的连接管理(如连接状态机、过滤协商)。
-
解耦设计:PAN 模块通过 BNEP 提供的回调(如
BNEP_DATA_IND_CB
)接收数据,再通过自身回调(如tPAN_DATA_IND_CB
)传递给上层,实现 “蓝牙链路 → BNEP → PAN → 系统网络栈” 的完整数据路径。
PAN 模块是蓝牙协议栈中实现个人区域网络的核心组件,通过
tPAN_CONN
管理单个连接状态,通过tPAN_CB
管理全局配置和角色,通过 回调机制 与上层(网络栈)、下层(BNEP)交互。PAN_Init
初始化全局状态后,模块即可处理连接建立、网络桥接、数据传输等操作,最终实现蓝牙设备间的网络共享(如手机作为热点通过蓝牙连接笔记本)。
A2DP_Init
packages/modules/Bluetooth/system/stack/a2dp/a2dp_api.cc
/****************************************************************************** Global data****************************************************************************/
// A2DP 模块的全局控制块,存储模块的核心状态和配置
tA2DP_CB a2dp_cb;/********************************************************************************* Function A2DP_Init** Description This function is called to initialize the control block* for this layer. It must be called before accessing any* other API functions for this layer. It is typically called* once during the start up of the stack.** Returns void*******************************************************************************/
void A2DP_Init(void) {memset(&a2dp_cb, 0, sizeof(tA2DP_CB));a2dp_cb.avdt_sdp_ver = AVDT_VERSION;
}packages/modules/Bluetooth/system/internal_include/bt_target.h
#ifndef AVDT_VERSION
#define AVDT_VERSION 0x0103
#endifpackages/modules/Bluetooth/system/stack/a2dp/a2dp_int.h
// 服务发现回调函数,当 A2DP 模块完成 SDP 服务发现(查找远程设备是否支持 A2DP 服务)时,通过此回调通知上层
/* This is the callback to notify the result of the SDP discovery process. */
typedef void(tA2DP_FIND_CBACK)(bool found, tA2DP_Service* p_service,const RawAddress& peer_address);/* Control block used by A2DP_FindService(). */
typedef struct {// 服务发现回调函数指针,用于通知上层服务发现结果(如是否找到远程 A2DP 服务)tA2DP_FIND_CBACK* p_cback; /* pointer to application callback */// SDP 发现数据库指针,存储从远程设备获取的服务信息tSDP_DISCOVERY_DB* p_db; /* pointer to discovery database */// 待搜索的服务 UUID(用于过滤 SDP 记录,仅查找 A2DP 服务)uint16_t service_uuid; /* service UUID of search */
} tA2DP_FIND_CB;typedef struct {tA2DP_FIND_CB find; /* find service control block */uint16_t avdt_sdp_ver; /* AVDTP version */
} tA2DP_CB;packages/modules/Bluetooth/system/stack/sdp/sdp_discovery_db.h
// 表示服务的具体属性(如协议版本、支持的编码)
typedef struct t_sdp_disc_attr {struct t_sdp_disc_attr* p_next_attr; /* Addr of next linked attr */uint16_t attr_id; /* Attribute ID */uint16_t attr_len_type; /* Length and type fields */tSDP_DISC_ATVAL attr_value; /* Variable length entry data */
} tSDP_DISC_ATTR;// 表示一条完整的 SDP 服务记录
typedef struct t_sdp_disc_rec {tSDP_DISC_ATTR* p_first_attr; /* First attribute of record */struct t_sdp_disc_rec* p_next_rec; /* Addr of next linked record */uint32_t time_read; /* The time the record was read */RawAddress remote_bd_addr; /* Remote BD address */
} tSDP_DISC_REC;// SDP 发现数据库:A2DP 模块通过 SDP 协议查询远程设备的服务信息,结果存储在 tSDP_DISCOVERY_DB
typedef struct {// 数据库总内存和剩余内存(避免内存溢出)uint32_t mem_size; /* Memory size of the DB */uint32_t mem_free; /* Memory still available */// 指向第一个服务记录的指针,每个记录对应远程设备的一个服务(如 A2DP、AVRCP)tSDP_DISC_REC* p_first_rec; /* Addr of first record in DB */uint16_t num_uuid_filters; /* Number of UUIds to filter */bluetooth::Uuid uuid_filters[SDP_MAX_UUID_FILTERS]; /* UUIDs to filter */uint16_t num_attr_filters; /* Number of attribute filters */// 属性过滤列表(仅保留需要的服务属性,如协议版本、编码格式)uint16_t attr_filters[SDP_MAX_ATTR_FILTERS]; /* Attributes to filter */// 指向空闲内存和原始 SDP 数据的指针(存储未解析的服务记录)uint8_t* p_free_mem; /* Pointer to free memory */uint8_t*raw_data; /* Received record from server. allocated/released by client */uint32_t raw_size; /* size of raw_data */uint32_t raw_used; /* length of raw_data used */
} tSDP_DISCOVERY_DB;
A2DP 模块是蓝牙协议栈中实现高质量音频传输的核心组件,其核心逻辑包括:
-
初始化:通过
A2DP_Init
初始化全局控制块并设置 AVDTP 协议版本。 -
服务发现:依赖 SDP 协议和
tSDP_DISCOVERY_DB
查找远程设备的 A2DP 服务,通过tA2DP_FIND_CBACK
通知上层结果。 -
协议兼容性:通过
avdt_sdp_ver
确保与远程设备使用相同的 AVDTP 版本,避免因协议不兼容导致连接失败。
为 A2DP 音频传输奠定了基础,后续的连接建立、音频编码协商、数据传输等操作均依赖这些初始化和服务发现的结果。
A2DP 与 SDP 的服务发现流程
A2DP 模块依赖 SDP 协议发现远程设备的音频服务,典型流程如下:
①发起服务发现: 上层(如手机音频应用)调用 A2DP 的服务发现接口(如
A2DP_FindService
),传入目标设备的蓝牙地址和待搜索的 UUID(如 A2DP 服务 UUID)。②查询 SDP 发现数据库: A2DP 模块通过
a2dp_cb.find.p_db
访问tSDP_DISCOVERY_DB
,遍历其中的服务记录(tSDP_DISC_REC
)和属性条目(tSDP_DISC_ATTR
):
过滤 UUID:仅保留
uuid_filters
中包含 A2DP 服务 UUID 的记录。解析属性:检查属性条目中的
attr_id
(如协议版本、编码格式),提取关键能力信息(如是否支持 AAC 编码)。③通知服务发现结果: 找到符合条件的服务后,A2DP 模块通过
a2dp_cb.find.p_cback
(即tA2DP_FIND_CBACK
回调)通知上层:
若
found
为true
,上层可继续执行连接流程(如通过 AVDTP 建立音频传输通道)。若
found
为false
,上层提示用户 “设备不支持 A2DP 音频”。
AVRC_Init
packages/modules/Bluetooth/system/stack/avrc/avrc_sdp.cc
// 存储模块的全局状态和配置
tAVRC_CB avrc_cb;/********************************************************************************* Function AVRC_Init** Description This function is called at stack startup to allocate the* control block (if using dynamic memory), and initializes the* control block and tracing level.** Returns void*******************************************************************************/
void AVRC_Init(void) {memset(&avrc_cb, 0, sizeof(tAVRC_CB));
}packages/modules/Bluetooth/system/stack/avrc/avrc_int.h
// 用于处理大消息的分片传输和重组(蓝牙 L2CAP 层有 MTU 限制,大消息需拆分为多个分片)
// 分片控制块
/* type for Metadata fragmentation control block */
typedef struct {BT_HDR* p_fmsg; /* the fragmented message */uint8_t frag_pdu; /* the PDU ID for fragmentation */bool frag_enabled; /* fragmentation flag */
} tAVRC_FRAG_CB;// 重组控制块
/* type for Metadata re-assembly control block */
typedef struct {BT_HDR* p_rmsg; /* the received message */uint16_t rasm_offset; /* re-assembly flag, the offset of the start fragment */uint8_t rasm_pdu; /* the PDU ID for re-assembly */
} tAVRC_RASM_CB;// AVRC 模块内部管理连接的核心结构体,处理命令序列化和超时
/* AVRC internal connection control block */
typedef struct {// 用于序列化厂商特定的控制命令(如音量调节、曲目切换),避免多个命令并发导致的冲突fixed_queue_t*cmd_q; /* Command queue for serializing vendor specific commands */// 存储连接状态标志,辅助状态机判断uint8_t flags; /* See AVRC_CB_FLAGS_* definitions */// 监控控制命令的响应超时(如发送 “下一曲” 指令后,若超时未收到响应则触发错误回调)alarm_t* tle; /* Command timeout timer */
} tAVRC_CONN_INT_CB;/* This callback function returns service discovery information to the* application after the AVRC_FindService() API function is called. The* implementation of this callback function must copy the p_service_name* and p_provider_name parameters passed to it as they are not guaranteed* to remain after the callback function exits. */
using tAVRC_FIND_CBACK = base::Callback<void(uint16_t status)>;typedef struct {// 应用层连接控制块数组(AVCT_NUM_CONN 定义最大同时连接数),每个元素对应一个 AVRC 连接tAVRC_CONN_CBccb[AVCT_NUM_CONN]; /* Connection control block from AVRC_Open API */// 内部连接控制块数组,与 ccb 一一对应,管理连接的内部状态tAVRC_CONN_INT_CBccb_int[AVCT_NUM_CONN]; /* Internal connection control block */// 分片 / 重组控制块数组,每个连接独立管理消息分片和重组tAVRC_FRAG_CB fcb[AVCT_NUM_CONN];tAVRC_RASM_CB rcb[AVCT_NUM_CONN];// 服务发现回调,通知应用层远程设备是否支持 AVRC 服务tAVRC_FIND_CBACK find_cback; /* sdp discovery callback */// SDP 发现数据库指针,存储远程设备的服务信息tSDP_DISCOVERY_DB* p_db; /* pointer to discovery database */// 待搜索的 AVRC 服务 UUID(用于 SDP 过滤,仅查找支持 AVRC 的设备)uint16_t service_uuid; /* service UUID to search */
} tAVRC_CB;packages/modules/Bluetooth/system/stack/include/avrc_api.h
/* This is the control callback function. This function passes events* listed in Table 20 to the application. */
using tAVRC_CTRL_CBACK =base::Callback<void(uint8_t handle, uint8_t event, uint16_t result,const RawAddress* peer_addr)>;/* This is the message callback function. It is executed when AVCTP has* a message packet ready for the application. The implementation of this* callback function must copy the tAVRC_MSG structure passed to it as it* is not guaranteed to remain after the callback function exits. */
using tAVRC_MSG_CBACK = base::Callback<void(uint8_t handle, uint8_t label,uint8_t opcode, tAVRC_MSG* p_msg)>;// 用于应用层配置 AVRC 连接的参数和回调,是应用层与 AVRC 模块交互的核心结构体
typedef struct {// 控制事件回调(如连接状态变化、命令执行结果)tAVRC_CTRL_CBACK ctrl_cback; /* application control callback */// 消息接收回调(如接收到远程设备的控制指令)tAVRC_MSG_CBACK msg_cback; /* application message callback */// 本地设备的公司 ID(如蓝牙 SIG 分配的厂商代码,用于标识设备类型)uint32_t company_id; /* the company ID */// 连接角色(发起方 / 接收方),决定连接建立的主动权uint8_t conn; /* Connection role (Initiator/acceptor) */// 控制角色(控制方 / 目标方),决定谁有权发起控制指令(如手机是控制方,耳机是目标方)uint8_t control; /* Control role (Control/Target) */
} tAVRC_CONN_CB;
AVRC 模块是蓝牙协议栈中实现音视频设备远程控制的核心组件,其核心逻辑包括:
-
初始化:通过
AVRC_Init
初始化全局控制块,确保模块状态正确。 -
连接管理:通过
tAVRC_CONN_CB
(应用层)和tAVRC_CONN_INT_CB
(内部)管理多连接状态,支持并发控制多个设备。 -
消息处理:通过
tAVRC_FRAG_CB
和tAVRC_RASM_CB
处理大消息的分片与重组,确保控制指令可靠传输。 -
回调交互:通过
tAVRC_CTRL_CBACK
和tAVRC_MSG_CBACK
与应用层解耦,支持灵活的控制逻辑(如手机音乐 APP 响应耳机的切歌指令)。
为蓝牙设备间的远程控制功能(如耳机控制手机音乐)提供了底层支持,是蓝牙音频生态的重要组成部分。
模块交互:AVRC 的消息处理与控制流程
AVRC 模块通过 回调机制 与应用层交互,典型流程如下:
1. 连接建立
应用层调用
AVRC_Open
接口,传入tAVRC_CONN_CB
配置(包含ctrl_cback
和msg_cback
):
AVRC 模块通过
ccb
存储应用层配置,通过ccb_int
初始化内部连接状态(如创建命令队列cmd_q
、启动超时定时器tle
)。若连接成功,通过
ctrl_cback
通知应用层(event
参数为连接成功事件)。2. 控制命令发送
应用层发起控制指令(如 “音量 +”):
指令被加入
ccb_int[handle].cmd_q
队列(确保顺序执行)。通过 AVCTP(音视频控制传输协议)封装为蓝牙 L2CAP 数据包,发送到远程设备。
启动
tle
定时器监控响应,若超时未收到回复,通过ctrl_cback
通知应用层错误。3. 消息接收与处理
远程设备返回控制响应或主动发送指令(如 “当前音量”):
AVRC 模块接收 L2CAP 数据包,若消息过大则通过
rcb[handle]
重组分片(根据rasm_pdu
和rasm_offset
拼接完整消息)。解析后通过
msg_cback
通知应用层(opcode
参数标识指令类型,p_msg
包含具体数据)。4. 服务发现
应用层调用
AVRC_FindService
查找远程设备的 AVRC 服务:
AVRC 模块通过
p_db
访问 SDP 发现数据库,过滤service_uuid
匹配的服务记录。若找到服务,通过
find_cback
通知应用层(status
参数为成功),应用层可继续建立连接;否则提示 “设备不支持远程控制”。
HID_HostInit
packages/modules/Bluetooth/system/stack/hid/hidh_api.cc
tHID_HOST_CTB hh_cb; // 存储模块的全局状态和配置/********************************************************************************* Function HID_HostInit** Description This function initializes the control block and trace* variable** Returns void*******************************************************************************/
void HID_HostInit(void) {memset(&hh_cb, 0, sizeof(tHID_HOST_CTB));
}packages/modules/Bluetooth/system/stack/hid/hidh_int.h
typedef void(tHID_HOST_DEV_CALLBACK)(uint8_t dev_handle, const RawAddress& addr,uint8_t event, /* Event from HID-DEVICE. */uint32_t data, /* Integer data corresponding to the event.*/BT_HDR* p_buf); /* Pointer data corresponding to the event. */typedef void(tHID_HOST_SDP_CALLBACK)(uint16_t result, uint16_t attr_mask,tHID_DEV_SDP_INFO* sdp_rec);// 每个 HID 设备对应一个 tHID_HOST_DEV_CTB 实例,存储该设备的详细状态
typedef struct per_device_ctb {bool in_use;RawAddress addr; /* BD-Addr of the host device */uint16_t attr_mask; /* 0x01- virtual_cable; 0x02- normally_connectable; 0x03-reconn_initiate;0x04- sdp_disable; */uint8_t state; /* Device state if in HOST-KNOWN mode */uint8_t conn_tries; /* Remembers the number of connection attempts whileCONNECTING */tHID_CONN conn; /* L2CAP channel info */
} tHID_HOST_DEV_CTB;typedef struct host_ctb {// 设备控制块数组,每个元素对应一个已连接或待连接的 HID 设备tHID_HOST_DEV_CTB devices[HID_HOST_MAX_DEVICES];// 设备事件回调(如连接成功、断开、数据接收),通知应用层设备状态变化tHID_HOST_DEV_CALLBACK* callback; /* Application callbacks */// L2CAP 层配置参数(如 MTU 最大传输单元、重传策略),用于与底层 L2CAP 协议交互tL2CAP_CFG_INFO l2cap_cfg;#define MAX_SERVICE_DB_SIZE 4000// SDP 发现忙标志(避免并发发起多个 SDP 请求)bool sdp_busy; // SDP 发现结果回调(通知应用层远程设备的 HID 服务能力)tHID_HOST_SDP_CALLBACK* sdp_cback;tSDP_DISCOVERY_DB* p_sdp_db;tHID_DEV_SDP_INFO sdp_rec;bool reg_flag;} tHID_HOST_CTB;packages/modules/Bluetooth/system/stack/hid/hid_conn.h
// HID 设备通过 L2CAP 协议建立两条通道:控制通道(Control Channel) 和 中断通道(Interrupt Channel)
/* Define the HID Connection Block
*/
typedef struct hid_conn {tHID_CONN_STATE conn_state;static inline std::string state_text(const tHID_CONN_STATE& state) {switch (state) {CASE_RETURN_TEXT(HID_CONN_STATE_UNUSED);CASE_RETURN_TEXT(HID_CONN_STATE_CONNECTING_CTRL);CASE_RETURN_TEXT(HID_CONN_STATE_CONNECTING_INTR);CASE_RETURN_TEXT(HID_CONN_STATE_CONFIG);CASE_RETURN_TEXT(HID_CONN_STATE_CONNECTED);CASE_RETURN_TEXT(HID_CONN_STATE_DISCONNECTING);CASE_RETURN_TEXT(HID_CONN_STATE_SECURITY);default:return base::StringPrintf("UNKNOWN[%hhu]", state);}}#define HID_CONN_FLAGS_IS_ORIG (0x01)
#define HID_CONN_FLAGS_CONGESTED (0x20)
#define HID_CONN_FLAGS_INACTIVE (0x40)uint8_t conn_flags;uint16_t ctrl_cid;uint16_t intr_cid;uint16_t rem_mtu_size;uint16_t disc_reason; /* Reason for disconnecting (for HID_HDEV_EVT_CLOSE) */// 重新分页定时器(用于处理设备休眠后重新唤醒的场景)alarm_t* process_repage_timer;
} tHID_CONN;packages/modules/Bluetooth/system/internal_include/bt_target.h#ifndef HID_MAX_SVC_NAME_LEN
#define HID_MAX_SVC_NAME_LEN 32
#endif#ifndef HID_MAX_SVC_DESCR_LEN
#define HID_MAX_SVC_DESCR_LEN 32
#endif#ifndef HID_MAX_PROV_NAME_LEN
#define HID_MAX_PROV_NAME_LEN 32
#endif#ifndef HID_HOST_MAX_DEVICES
#define HID_HOST_MAX_DEVICES 7
#endifpackages/modules/Bluetooth/system/stack/include/hiddefs.h
typedef struct desc_info {uint16_t dl_len;uint8_t* dsc_list;
} tHID_DEV_DSCP_INFO;// 存储 HID 设备通过 SDP 协议暴露的服务能力信息,用于主机判断是否支持该设备
typedef struct sdp_info {// 服务名称、描述、厂商名称(如 “蓝牙键盘”)char svc_name[HID_MAX_SVC_NAME_LEN]; /*Service Name */char svc_descr[HID_MAX_SVC_DESCR_LEN]; /*Service Description*/char prov_name[HID_MAX_PROV_NAME_LEN]; /*Provider Name.*/uint16_t rel_num; /*Release Number */// HID 解析器版本(确保主机与设备的协议兼容性)uint16_t hpars_ver; /*HID Parser Version.*/uint16_t ssr_max_latency; /* HIDSSRHostMaxLatency value, ifHID_SSR_PARAM_INVALID not used*/uint16_tssr_min_tout; /* HIDSSRHostMinTimeout value, if HID_SSR_PARAM_INVALID notused* */uint8_t sub_class; /*Device Subclass.*/uint8_t ctry_code; /*Country Code.*/uint16_t sup_timeout; /* Supervisory Timeout */tHID_DEV_DSCP_INFO dscp_info; /* Descriptor list and Report list to be set inthe SDP record.This parameter is used ifHID_DEV_USE_GLB_SDP_REC is set to false.*/tSDP_DISC_REC* p_sdp_layer_rec;
} tHID_DEV_SDP_INFO;
HID Host 模块是蓝牙协议栈中实现主机连接 HID 设备的核心组件,其核心逻辑包括:
-
初始化:通过
HID_HostInit
初始化全局控制块,确保模块状态正确。 -
设备管理:通过
tHID_HOST_DEV_CTB
数组管理多设备连接,支持同时连接多个 HID 设备(如键盘 + 鼠标)。 -
连接状态机:通过
tHID_CONN
管理控制 / 中断通道的连接状态,确保可靠建立和维护连接。 -
SDP 服务发现:通过
tHID_DEV_SDP_INFO
提取设备能力,确保主机与设备的协议兼容性。 -
回调交互:通过
tHID_HOST_DEV_CALLBACK
和tHID_HOST_SDP_CALLBACK
与应用层解耦,支持灵活的输入处理(如键盘输入映射到系统按键)。
为蓝牙主机设备(如手机、笔记本)连接 HID 外设(如键盘、鼠标)提供了底层支持,是蓝牙人机交互生态的重要基础。
模块交互:HID Host 的设备连接与数据传输流程
HID Host 模块通过 回调机制 与应用层交互,典型流程如下:
1. 设备发现与连接
SDP 服务发现:应用层发起设备搜索,HID Host 模块通过
p_sdp_db
查询远程设备的 SDP 记录,提取tHID_DEV_SDP_INFO
中的服务信息(如设备类型、协议版本)。若发现支持 HID 的设备,通过sdp_cback
通知应用层。连接建立:应用层选择目标设备后,HID Host 模块通过
tHID_HOST_DEV_CTB
初始化设备控制块,依次建立控制通道(ctrl_cid
)和中断通道(intr_cid
),状态机从HID_CONN_STATE_CONNECTING_CTRL
过渡到HID_CONN_STATE_CONNECTED
。2. 数据接收与处理
中断通道数据:HID 设备(如鼠标)的输入数据(如移动坐标、按键状态)通过中断通道传输。HID Host 模块接收数据后,通过
tHID_HOST_DEV_CALLBACK
通知应用层(event
参数为数据接收事件,p_buf
指向数据缓冲区)。控制通道信令:控制通道用于传输控制信令(如设备休眠、唤醒、参数配置)。模块处理信令后更新设备状态(如
state
变为休眠),并通过回调通知应用层。3. 设备断开与重试
正常断开:应用层发起断开请求或设备主动断开时,模块更新
disc_reason
(如正常断开),状态机进入HID_CONN_STATE_DISCONNECTING
,最终标记设备为in_use = false
,并通过回调通知应用层。异常断开:若连接超时或 L2CAP 层报错(如拥塞),模块通过
conn_tries
记录重试次数,超过阈值后停止重试并通知应用层。
bta_ar_init
packages/modules/Bluetooth/system/bta/ar/bta_ar.cc
/* AV control block */
tBTA_AR_CB bta_ar_cb; // 存储 BTA_AR 模块的核心状态和协议关联信息/********************************************************************************* Function bta_ar_init** Description This function is called to register to AVDTP.** Returns void*******************************************************************************/
void bta_ar_init(void) {/* initialize control block */memset(&bta_ar_cb, 0, sizeof(tBTA_AR_CB));
}packages/modules/Bluetooth/system/bta/ar/bta_ar_int.h
typedef uint8_t tBTA_AV_HNDL;/* data associated with BTA_AR */
typedef struct {// AVDT 连接回调函数指针,用于接收 AVDT 层的控制事件(如连接请求、断开通知)tAVDT_CTRL_CBACK* p_av_conn_cback; /* av connection callback function */// 是否已注册到 AVDT 协议(AVDT 是蓝牙音频流传输的底层协议,BTA_AR 需注册后才能使用其接口)uint8_t avdt_registered;// 是否已注册到 AVCT(Audio/Video Control Transport Protocol,音视频控制传输协议),用于控制音频流的建立与断开uint8_t avct_registered;uint32_t sdp_tg_handle;uint32_t sdp_ct_handle;// 控制设备(Control)支持的音频类别(如音乐、语音),用于协商音频流类型uint16_t ct_categories[2];// 是否已注册为 AVDT TG 角色(目标设备通常是音频接收方,如耳机)uint8_t tg_registered;tBTA_AV_HNDL hndl; /* Handle associated with the stream that rejected theconnection. */uint16_t ct_ver;// 目标设备(Target)支持的音频类别(与控制设备的类别匹配,确保兼容性)uint16_t tg_categories[2];
} tBTA_AR_CB;packages/modules/Bluetooth/system/stack/include/avdt_api.h
/* This is the control callback function. This function passes control events* to the application. This function is required for all registered stream* endpoints and for the AVDT_DiscoverReq() and AVDT_GetCapReq() functions.*
*/
typedef void(tAVDT_CTRL_CBACK)(uint8_t handle, const RawAddress& bd_addr,uint8_t event, tAVDT_CTRL* p_data,uint8_t scb_index);
BTA_AR(Bluetooth Application Layer - Audio Routing,蓝牙应用层音频路由)模块 主要负责音频流的连接管理与控制(如蓝牙耳机与手机的音频流协商、路由切换)。其核心逻辑包括:
-
初始化:通过
bta_ar_init
清零全局控制块,确保模块状态正确。 -
协议注册:依赖 AVDT/AVCT 协议,通过注册标志(
avdt_registered
/avct_registered
)建立与底层的交互通道。 -
服务管理:通过 SDP 句柄(
sdp_tg_handle
/sdp_ct_handle
)发布和发现音频服务,确保设备间的兼容性。 -
流控制:通过
p_av_conn_cback
接收 AVDT 事件,协调音频流的建立、参数协商和断开,最终实现音频数据的可靠传输(如手机音乐流传输到耳机)。
为蓝牙设备间的音频路由提供了应用层支持,是蓝牙音频生态中 “连接 - 控制 - 传输” 流程的关键一环。
模块交互:BTA_AR 与底层协议的协作
BTA_AR 作为应用层模块,依赖底层 AVDT/AVCT 协议实现音频流的传输与控制,典型交互流程如下:
1. 协议注册
BTA_AR 启动后,通过
avdt_registered
和avct_registered
标志判断是否已注册到底层协议:
注册 AVDT:调用 AVDT 接口(如
AVDT_Register()
),传入p_av_conn_cback
作为回调,注册为音频流端点(目标或控制角色)。注册 AVCT:调用 AVCT 接口(如
AVCT_Register()
),注册控制能力(如发起连接、调整参数)。2. 服务发现与发布
发布服务:通过 SDP 协议发布本地设备的音频服务(如作为目标设备的
sdp_tg_handle
或控制设备的sdp_ct_handle
),远程设备通过 SDP 发现这些服务后,可发起连接。发现服务:BTA_AR 收到远程设备的连接请求时,通过 SDP 查询其
ct_categories
或tg_categories
,判断是否支持匹配的音频类别(如音乐流需双方都支持 “音乐” 类别)。3. 音频流控制
连接建立:远程设备(如手机)发起 AVDT 连接请求时,AVDT 层通过
p_av_conn_cback
通知 BTA_AR(event
参数为连接请求事件)。BTA_AR 检查tg_categories
匹配后,调用 AVDT 接口(如AVDT_ConnectRsp()
)接受连接,建立音频流(通过hndl
标识该流)。参数协商:连接建立后,BTA_AR 协商音频参数(如编码格式、采样率),通过 AVCT 协议发送控制指令(如
AVCT_SendCmd()
),确保双方参数一致。流断开:音频流结束(如音乐播放停止)或设备断开时,AVDT 层通过回调通知 BTA_AR(
event
参数为断开事件),BTA_AR 释放相关资源(如重置hndl
)并更新avdt_registered
状态。
三、流程图
四、初始化时序图
五、模块交互时序图(以A2DP音频传输和AVRC控制为例)
六、总结
模块 | 核心职责 | 依赖关系 | 典型应用场景 |
BNEP | IP数据报封装/传输 | L2CAP协议层 | 蓝牙网络数据传输基础 |
PAN | 设备间局域网建立 | 依赖BNEP | 手机网络共享给笔记本 |
A2DP | 高质量音频流传输 | AVDTP协议+SDP服务发现 | 手机音乐传输到蓝牙耳机 |
AVRC | 音视频设备远程控制 | AVCTP协议 | 耳机控制手机播放/暂停 |
HID Host | 人机交互设备连接管理 | HID协议+SDP | 蓝牙键盘/鼠标连接手机/电脑 |
音频路由 | 音频流建立与控制协调 | AVDT/AVCT协议 | 耳机与手机的音频流协商 |