网站建设信息在哪儿发布,wordpress api 小程序,深圳有哪些传媒公司,黄骅港鑫海化工招聘本文深入解析Android蓝牙协议栈中 start_profiles 函数及其调用的核心模块初始化逻辑#xff0c;涵盖 BNEP、PAN、A2DP、AVRC、HID Host、BTA_AR 等关键配置文件和应用层模块。通过代码分析与流程梳理#xff0c;阐述各模块如何通过全局控制块、状态机、回调机制实现功能初始… 本文深入解析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() {
// BNEPBasic Network Encapsulation Protocol基本网络封装协议用于在蓝牙链路上封装和传输 IP 数据报是蓝牙实现网络连接的基础协议
#if (BNEP_INCLUDED TRUE)BNEP_Init();
// PANPersonal 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;BNEPBasic 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;
PANPersonal 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、AVRCPtSDP_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::Callbackvoid(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::Callbackvoid(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::Callbackvoid(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;// 是否已注册到 AVCTAudio/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_ARBluetooth 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_ARevent 参数为连接请求事件。BTA_AR 检查 tg_categories 匹配后调用 AVDT 接口如 AVDT_ConnectRsp()接受连接建立音频流通过 hndl 标识该流。 参数协商连接建立后BTA_AR 协商音频参数如编码格式、采样率通过 AVCT 协议发送控制指令如 AVCT_SendCmd()确保双方参数一致。 流断开音频流结束如音乐播放停止或设备断开时AVDT 层通过回调通知 BTA_ARevent 参数为断开事件BTA_AR 释放相关资源如重置 hndl并更新 avdt_registered 状态。 三、流程图 四、初始化时序图 五、模块交互时序图以A2DP音频传输和AVRC控制为例 六、总结
模块核心职责依赖关系典型应用场景BNEPIP数据报封装/传输L2CAP协议层蓝牙网络数据传输基础PAN设备间局域网建立依赖BNEP手机网络共享给笔记本A2DP高质量音频流传输AVDTP协议SDP服务发现手机音乐传输到蓝牙耳机AVRC音视频设备远程控制AVCTP协议耳机控制手机播放/暂停HID Host人机交互设备连接管理HID协议SDP蓝牙键盘/鼠标连接手机/电脑音频路由音频流建立与控制协调AVDT/AVCT协议耳机与手机的音频流协商
七、模块交互全景图