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

【Bluedroid】蓝牙启动之核心模块(startProfiles )初始化与功能源码解析

本文深入解析Android蓝牙协议栈中 start_profiles 函数及其调用的核心模块初始化逻辑,涵盖 BNEP、PAN、A2DP、AVRC、HID Host、BTA_AR 等关键配置文件和应用层模块。通过代码分析与流程梳理,阐述各模块如何通过全局控制块、状态机、回调机制实现功能初始化、连接管理及数据交互,揭示蓝牙设备在音频传输、网络共享、设备控制等场景下的底层实现原理。


一、概述

1.1 start_profiles

start_profiles 是蓝牙协议栈启动阶段的核心函数,通过 编译宏开关(如 BNEP_INCLUDEDHID_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_CBtAVRC_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)解耦,典型流程如下:

  1. 连接请求:远程设备发起 BNEP 连接时,BNEP 模块通过 p_conn_ind_cb 通知上层(如 PAN),上层决定是否接受(通过 BNEP_ConnectResp 响应)。

  2. 连接状态变化:连接建立成功或失败时,BNEP 模块通过 p_conn_state_cb 通知上层当前状态(如 BNEP_SUCCESS 表示连接成功)。

  3. 数据接收:收到蓝牙链路数据后,BNEP 模块解析封装的 IP 数据报,通过 p_data_ind_cbp_data_buf_cb 将数据传递给上层(如 PAN 转发到系统网络栈)。

  4. 过滤规则协商:双方设备协商允许传输的协议或多播地址时,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 回调)通知上层:

  • foundtrue,上层可继续执行连接流程(如通过 AVDTP 建立音频传输通道)。

  • foundfalse,上层提示用户 “设备不支持 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_CBtAVRC_RASM_CB 处理大消息的分片与重组,确保控制指令可靠传输。

  • 回调交互:通过 tAVRC_CTRL_CBACKtAVRC_MSG_CBACK 与应用层解耦,支持灵活的控制逻辑(如手机音乐 APP 响应耳机的切歌指令)。

为蓝牙设备间的远程控制功能(如耳机控制手机音乐)提供了底层支持,是蓝牙音频生态的重要组成部分。

模块交互:AVRC 的消息处理与控制流程

AVRC 模块通过 回调机制 与应用层交互,典型流程如下:

1. 连接建立

应用层调用 AVRC_Open 接口,传入 tAVRC_CONN_CB 配置(包含 ctrl_cbackmsg_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_pdurasm_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_CALLBACKtHID_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_registeredavct_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_categoriestg_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控制为例)

六、总结

模块核心职责依赖关系典型应用场景
BNEPIP数据报封装/传输L2CAP协议层蓝牙网络数据传输基础
PAN设备间局域网建立依赖BNEP手机网络共享给笔记本
A2DP高质量音频流传输AVDTP协议+SDP服务发现手机音乐传输到蓝牙耳机
AVRC音视频设备远程控制AVCTP协议耳机控制手机播放/暂停
HID Host人机交互设备连接管理HID协议+SDP蓝牙键盘/鼠标连接手机/电脑
音频路由音频流建立与控制协调AVDT/AVCT协议耳机与手机的音频流协商

七、模块交互全景图

http://www.xdnf.cn/news/1044793.html

相关文章:

  • 性能优化 - 案例篇:11种优化接口性能的通用方案
  • pion/webrtc v4.1.2版本深度解析与应用指南
  • 纺织行业SAP解决方案:无锡哲讯科技助力企业智能化升级
  • docker(学习笔记第一课) 使用nginx +https + wordpress
  • Flutter包管理与插件开发完全指南
  • springboot速通
  • 国产操作系统-银河麒麟本地化部署Ollama国产开源的AI大模型Qwen3
  • 【MFC】树控件的使用详解
  • Spring Framework 7.0发布
  • C++问题:纯虚函数和抽象类
  • C语言进阶:深度解剖数据在内存中的存储(浮点型在内存中的存储)
  • 某网站极验4滑块验证码逆向分析
  • vue2中setTimeout中调用methods方法问题
  • BEV 感知算法评价指标简介
  • 安卓9.0系统修改定制化____安卓 9.0系统修改固件 自动开启USB调试教程 开搞篇 六
  • 【Linux】基于策略模式的简单日志设计
  • Spring Boot Web 应用开发
  • 如何用AI绘画工具创作出属于你的拉布布(泡泡玛特)形象?
  • leetcode146-LRU缓存
  • rv1126+opencv多线程同时对视频进行膨胀和腐蚀
  • java 设计模式_行为型_20中介者模式
  • HTML的最基础入门知识,从零开始逐步讲解,适合为后续爬虫技术打基础:
  • Windows下Docker一键部署Dify教程
  • htmlcss考核
  • WebAssembly 2.0:超越浏览器的全栈计算革命
  • 【Zephyr 系列 26】跨平台测试框架设计:CLI + 自动脚本 + OTA 校验一体化方案
  • NVIDIA Isaac GR00T N1.5 人形机器人强化学习入门教程(四)Lerobot、宇树 G1 等不同形态机器人微调教程
  • Spring Boot的Security安全控制——应用SpringSecurity!
  • Java面试题022:一文深入了解微服务网关Gateway
  • 微软azure抢跑aws和谷歌云的区别