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

【android bluetooth 协议分析 02】【bluetooth hal 层详解 6】【bt_vendor_opcode_t 介绍】

bt_vendor_opcode_t 介绍

在 AOSP 的 Bluetooth Vendor 接口中,bt_vendor_opcode_t 定义了一组供上层调用的操作指令。这些操作在蓝牙初始化、使用和关闭过程中由协议栈(如 Bluedroid)驱动调用,按照一定的顺序执行。

这些枚举项代表 Vendor Interface API 的操作码,协议栈通过调用 vendor_call() 接口并传入这些 opcodes 来控制蓝牙芯片的底层行为。其设计目的在于:

  • 平台差异适配(如不同 SoC 的上电、串口打开方式)
  • 硬件加速支持(如 A2DP offload)
  • 功耗优化(如 LPM 控制)
  • 音频子系统协同(如 SCO、音频状态)

1. 详解介绍

  • hidl_hci/1.0/default/bt_vendor_lib.h

/** Vendor specific operations OPCODE */
typedef enum {/*  [operation]*      Power on or off the BT Controller.*  [input param]*      A pointer to int type with content of bt_vendor_power_state_t.*      Typecasting conversion: (int *) param.*  [return]*      0 - default, don't care.*  [callback]*      None.*/BT_VND_OP_POWER_CTRL,/*  [operation]*      Perform any vendor specific initialization or configuration*      on the BT Controller. This is called before stack initialization.*  [input param]*      None.*  [return]*      0 - default, don't care.*  [callback]*      Must call fwcfg_cb to notify the stack of the completion of vendor*      specific initialization once it has been done.*/BT_VND_OP_FW_CFG,/*  [operation]*      Perform any vendor specific SCO/PCM configuration on the BT* Controller.*      This is called after stack initialization.*  [input param]*      None.*  [return]*      0 - default, don't care.*  [callback]*      Must call scocfg_cb to notify the stack of the completion of vendor*      specific SCO configuration once it has been done.*/BT_VND_OP_SCO_CFG,/*  [operation]*      Open UART port on where the BT Controller is attached.*      This is called before stack initialization.*  [input param]*      A pointer to int array type for open file descriptors.*      The mapping of HCI channel to fd slot in the int array is given in*      bt_vendor_hci_channels_t.*      And, it requires the vendor lib to fill up the content before* returning*      the call.*      Typecasting conversion: (int (*)[]) param.*  [return]*      Numbers of opened file descriptors.*      Valid number:*          1 - CMD/EVT/ACL-In/ACL-Out via the same fd (e.g. UART)*          2 - CMD/EVT on one fd, and ACL-In/ACL-Out on the other fd*          4 - CMD, EVT, ACL-In, ACL-Out are on their individual fd*  [callback]*      None.*/BT_VND_OP_USERIAL_OPEN,/*  [operation]*      Close the previously opened UART port.*  [input param]*      None.*  [return]*      0 - default, don't care.*  [callback]*      None.*/BT_VND_OP_USERIAL_CLOSE,/*  [operation]*      Get the LPM idle timeout in milliseconds.*      The stack uses this information to launch a timer delay before it*      attempts to de-assert LPM WAKE signal once downstream HCI packet*      has been delivered.*  [input param]*      A pointer to uint32_t type which is passed in by the stack. And, it*      requires the vendor lib to fill up the content before returning*      the call.*      Typecasting conversion: (uint32_t *) param.*  [return]*      0 - default, don't care.*  [callback]*      None.*/BT_VND_OP_GET_LPM_IDLE_TIMEOUT,/*  [operation]*      Enable or disable LPM mode on BT Controller.*  [input param]*      A pointer to uint8_t type with content of bt_vendor_lpm_mode_t.*      Typecasting conversion: (uint8_t *) param.*  [return]*      0 - default, don't care.*  [callback]*      Must call lpm_cb to notify the stack of the completion of LPM*      disable/enable process once it has been done.*/BT_VND_OP_LPM_SET_MODE,/*  [operation]*      Assert or Deassert LPM WAKE on BT Controller.*  [input param]*      A pointer to uint8_t type with content of bt_vendor_lpm_wake_state_t.*      Typecasting conversion: (uint8_t *) param.*  [return]*      0 - default, don't care.*  [callback]*      None.*/BT_VND_OP_LPM_WAKE_SET_STATE,/*  [operation]*      Perform any vendor specific commands related to audio state changes.*  [input param]*      a pointer to bt_vendor_op_audio_state_t indicating what audio state is*      set.*  [return]*      0 - default, don't care.*  [callback]*      None.*/BT_VND_OP_SET_AUDIO_STATE,/*  [operation]*      The epilog call to the vendor module so that it can perform any*      vendor-specific processes (e.g. send a HCI_RESET to BT Controller)*      before the caller calls for cleanup().*  [input param]*      None.*  [return]*      0 - default, don't care.*  [callback]*      Must call epilog_cb to notify the stack of the completion of vendor*      specific epilog process once it has been done.*/BT_VND_OP_EPILOG,/*  [operation]*      Call to the vendor module so that it can perform all vendor-specific*      operations to start offloading a2dp media encode & tx.*  [input param]*      pointer to bt_vendor_op_a2dp_offload_start_t containing elements*      required for VND FW to setup a2dp offload.*  [return]*      0  - default, dont care.*  [callback]*      Must call a2dp_offload_start_cb to notify the stack of the*      completion of vendor specific setup process once it has been done.*/BT_VND_OP_A2DP_OFFLOAD_START,/*  [operation]*      Call to the vendor module so that it can perform all vendor-specific*      operations to suspend offloading a2dp media encode & tx.*  [input param]*      pointer to bt_vendor_op_a2dp_offload_t containing elements*      required for VND FW to setup a2dp offload.*  [return]*      0  - default, dont care.*  [callback]*      Must call a2dp_offload_cb to notify the stack of the*      completion of vendor specific setup process once it has been done.*/BT_VND_OP_A2DP_OFFLOAD_STOP,} bt_vendor_opcode_t;
枚举项作用说明触发时机典型应用场合
BT_VND_OP_POWER_CTRL控制蓝牙芯片上电/断电蓝牙开启或关闭前后控制 BT SoC 电源,如初始化前上电,退出前下电
BT_VND_OP_FW_CFG执行厂商特有的固件初始化配置蓝牙协议栈初始化前加载 firmware patch、设置特有寄存器等,完成后调用 fwcfg_cb 通知上层
BT_VND_OP_SCO_CFG执行厂商特定的 SCO/PCM 音频配置协议栈初始化之后(有 SCO 功能时)设置 HCI SCO 路径,配置 PCM 接口参数,完成后需调用 scocfg_cb
BT_VND_OP_USERIAL_OPEN打开串口或类似物理连接接口,用于 HCI 通信初始化前为主控和 BT 控制器之间建立 HCI 通道(如 UART),返回 fd 列表供上层使用
BT_VND_OP_USERIAL_CLOSE关闭串口或物理连接接口清理蓝牙前关闭 UART、SPI、USB 接口文件描述符
BT_VND_OP_GET_LPM_IDLE_TIMEOUT获取低功耗空闲超时(单位 ms)启用 LPM 功能后,发送数据后启动 idle 计时器控制下行数据发送后 LPM WAKE deassert 的延迟时间,避免频繁切换
BT_VND_OP_LPM_SET_MODE设置是否启用低功耗模式(LPM)蓝牙初始化后,根据策略动态设置进入低功耗模式(例如未连接时)、退出低功耗(如开始通信时),需调用 lpm_cb
BT_VND_OP_LPM_WAKE_SET_STATE设置 WAKE 状态:assert 或 deassertLPM 状态切换时,通常由协议栈驱动控制 LPM 的 WAKE GPIO,保持通信或释放资源
BT_VND_OP_SET_AUDIO_STATE通知音频状态变化以执行特定命令音频连接或断开时比如 HFP 通话开始/结束,通知底层做相关设置
BT_VND_OP_EPILOG蓝牙关闭前的收尾工作cleanup() 调用前发出 HCI_RESET 等命令,释放资源,完成后调用 epilog_cb
BT_VND_OP_A2DP_OFFLOAD_START启动 A2DP 硬件 offload(编码和传输)开始播放 A2DP 音乐时将音频流交给底层硬件加速处理,完成后调用 a2dp_offload_start_cb
BT_VND_OP_A2DP_OFFLOAD_STOP停止 A2DP offload暂停或停止音乐播放时通知底层停止 offload 模块,完成后调用 a2dp_offload_cb

2. 如何触发调用

例如:

ALOGI("Turn On BT power");powerstate = BT_VND_PWR_ON;ret = lib_interface_->op(BT_VND_OP_POWER_CTRL, &powerstate);
/** Bluetooth Host/Controller VENDOR Interface*/
typedef struct {/** Set to sizeof(bt_vndor_interface_t) */size_t size;/** Functions need to be implemented in Vendor libray (libbt-vendor.so).*//*** Caller will open the interface and pass in the callback routines* to the implemenation of this interface.*/int (*init)(const bt_vendor_callbacks_t* p_cb, unsigned char* local_bdaddr);/**  Vendor specific operations */int (*op)(bt_vendor_opcode_t opcode, void* param);/** Closes the interface */void (*cleanup)(void);
} bt_vendor_interface_t;

2. 案例赏析

1. 一般蓝牙操作流程

下面是一个典型的蓝牙开启、使用、关闭的完整流程,配合 Vendor 操作指令说明。


1. 蓝牙初始化阶段(Bluetooth Turn ON)

顺序操作opcode描述
1打开串口BT_VND_OP_USERIAL_OPEN打开与 BT 芯片通信的物理接口(如 UART)
2芯片上电BT_VND_OP_POWER_CTRL通知 vendor 上电;若芯片已供电则可能为 no-op
3固件配置BT_VND_OP_FW_CFG执行固件加载或寄存器配置,完成后需调用 fwcfg_cb()
4低功耗模式设置BT_VND_OP_LPM_SET_MODE启用或禁用 LPM(低功耗)模式,完成后调用 lpm_cb()
5获取 LPM 超时BT_VND_OP_GET_LPM_IDLE_TIMEOUT获取 LPM 模式下的空闲超时时间

⚠️ 有 SCO 功能设备还会执行:

  • BT_VND_OP_SCO_CFG:设置 PCM 参数,完成后调用 scocfg_cb()

2. 音频使用阶段(如通话、播放音乐)

情况操作opcode描述
开始通话(HFP)BT_VND_OP_SET_AUDIO_STATE通知底层开始 SCO 语音传输
播放音乐(A2DP)BT_VND_OP_A2DP_OFFLOAD_START启动音频硬件 offload
暂停音乐BT_VND_OP_A2DP_OFFLOAD_STOP停止 A2DP 硬件 offload
通信中BT_VND_OP_LPM_WAKE_SET_STATE发送数据前 deassert WAKE;空闲后再 assert

3. 蓝牙关闭阶段(Bluetooth Turn OFF)

顺序操作opcode描述
1执行 epilog 清理流程BT_VND_OP_EPILOG可能发送 HCI_RESET 或其他定制命令,完成后需调用 epilog_cb()
2关闭串口BT_VND_OP_USERIAL_CLOSE关闭 UART、SPI 或 USB 接口
3芯片断电BT_VND_OP_POWER_CTRL通知 Vendor 关闭 BT 电源(如果支持)

Bluetooth ON 流程:┌───────────────────────────────┐│ USERIAL_OPEN                  ││ POWER_CTRL (ON)               ││ FW_CFG → fwcfg_cb             ││ SCO_CFG → scocfg_cb (可选)    ││ LPM_SET_MODE → lpm_cb         ││ GET_LPM_IDLE_TIMEOUT          │└───────────────────────────────┘使用过程:┌───────────────────────────────┐│ SET_AUDIO_STATE               ││ A2DP_OFFLOAD_START / STOP     ││ LPM_WAKE_SET_STATE            │└───────────────────────────────┘Bluetooth OFF 流程:┌───────────────────────────────┐│ EPILOG → epilog_cb            ││ USERIAL_CLOSE                 ││ POWER_CTRL (OFF)              │└───────────────────────────────┘

3. 补充说明

  • 所有 *_cb() 结尾的操作都需要在异步完成后由 vendor 层手动调用回调通知协议栈。
  • vendor lib 是一个中间层,负责将这些操作转换为实际硬件控制动作(如 ioctl、GPIO 控制、UART 操作等)。
  • 上层 bt_vendor_interface_t->op() 接口在 vendor.c 中实现,内部 switch-case 匹配这些 opcode。

typedef struct {/** set to sizeof(bt_vendor_callbacks_t) */size_t size;/** Callback and callout functions have implemented in HCI libray* (libbt-hci.so).*//* notifies caller result of firmware configuration request */cfg_result_cb fwcfg_cb;/* notifies caller result of sco configuration request */cfg_result_cb scocfg_cb;/* notifies caller result of lpm enable/disable */cfg_result_cb lpm_cb;/* notifies the result of codec setting */cfg_result_cb audio_state_cb;/* buffer allocation request */malloc_cb alloc;/* buffer deallocation request */mdealloc_cb dealloc;/* hci command packet transmit request */cmd_xmit_cb xmit_cb;/* notifies caller completion of epilog process */cfg_result_cb epilog_cb;/* notifies status of a2dp offload cmd's */cfg_a2dp_cb a2dp_offload_cb;
} bt_vendor_callbacks_t;

相关文章:

  • Ad Hoc
  • 源的企业级网络安全检测工具Prism X(棱镜X)
  • flutter项目迁移空安全
  • 欧盟MID认证,助力全球新能源高效计量与管理
  • Seata 面试题解析
  • 软考 系统架构设计师之考试感悟3
  • ubuntu 安装上传的 ffmpeg_7.1.1.orig.tar.xz并使用
  • 深入理解 SELinux:通过 Nginx 和 SSH 服务配置实践安全上下文与端口策略
  • 动态规划-931.下降路径最小和-力扣(LeetCode)
  • 高端装备制造企业如何选择适配的项目管理系统提升项目执行效率?附选型案例
  • 制造企业生产数据分析全解析:5大类数据定义、分析方法与落地指南
  • 阿里通义实验室突破空间音频新纪元!OmniAudio让360°全景视频“声”临其境
  • 制造企业搭建AI智能生产线怎么部署?
  • C++:栈帧、命名空间、引用
  • 人工智能浪潮下,制造企业如何借力DeepSeek实现数字化转型?
  • 学习黑客小故事理解 Metasploit 的 Meterpreter
  • 酷派Cool20/20S/30/40手机安装Play商店-谷歌三件套-GMS方法
  • NUMA 架构科普:双路 CPU 系统是如何构建的?
  • 如何给老旧 iOS App 添加安全保护?用 Ipa Guard 对 IPA 文件混淆加固实录
  • ComfyUI+阿里Wan2.1+内网穿透技术:本地AI视频生成系统搭建实战
  • 注册网站页面跳转错误/seo类目链接优化
  • 成品影视app开发工具/长沙专业seo优化公司
  • 微信管理系统在哪里找/seo优化网站教程
  • 常用网站开发技术/山东济南最新事件
  • web端商城网站开发/百度热门排行榜
  • 开网店视频教程/沈阳百度seo