【android bluetooth 协议分析 01】【HCI 层介绍 8】【ReadLocalVersionInformation命令介绍】
1. HCI_Read_Local_Version_Information 命令介绍
1. 功能(Description)
HCI_Read_Local_Version_Information
命令用于读取本地 Bluetooth Controller 的版本信息,包括 HCI 和 LMP 层的版本,以及厂商 ID 和子版本号。
这类信息用于 Host 识别当前控制器的 功能支持范围、厂商来源 及其具体的实现版本,通常用于以下场景:
- 协议栈 兼容性判断
- 对应厂商定制功能 条件启用
- 调试定位 版本差异导致的问题
2.命令参数(Command Parameters)
11 2025-04-24 15:55:53.353695 host controller HCI_CMD 4 Sent Read Local Version InformationBluetooth HCI Command - Read Local Version InformationCommand Opcode: Read Local Version Information (0x1001)0001 00.. .... .... = Opcode Group Field: Informational Parameters (0x04).... ..00 0000 0001 = Opcode Command Field: Read Local Version Information (0x001)Parameter Total Length: 0[Response in frame: 12][Command-Response Delta: 0.572ms]
无参数
只需发送命令,不带任何附加内容。
3.返回参数(Return Parameters)
12 2025-04-24 15:55:53.354267 controller host HCI_EVT 15 Rcvd Command Complete (Read Local Version Information)Bluetooth HCI Event - Command CompleteEvent Code: Command Complete (0x0e)Parameter Total Length: 12Number of Allowed Command Packets: 1Command Opcode: Read Local Version Information (0x1001)0001 00.. .... .... = Opcode Group Field: Informational Parameters (0x04).... ..00 0000 0001 = Opcode Command Field: Read Local Version Information (0x001)Status: Success (0x00)HCI Version: 5.3 (0x0c)HCI Revision: 0LMP Version: 5.3 (0x0c)Manufacturer Name: Qualcomm (0x001d)LMP Subversion: 29337[Command in frame: 11][Command-Response Delta: 0.572ms]
参数名 | 大小 | 描述 |
---|---|---|
Status | 1 字节 | 表示命令执行结果,0x00 表示成功 |
HCI_Version | 1 字节 | 控制器 HCI 层的版本号 |
HCI_Subversion | 2 字节 | 控制器厂商定义的 HCI 子版本号 |
LMP_Version | 1 字节 | LMP(Link Manager Protocol)版本号 |
Company_Identifier | 2 字节 | 控制器厂商 ID,定义于 Bluetooth SIG |
LMP_Subversion | 2 字节 | 厂商自定义的 LMP 子版本号 |
4. 事件
成功后,Controller 会通过
HCI_Command_Complete
事件返回这些参数。
2. aosp 中如何使用
1. 字段作用与 AOSP 中的意义
下面我们逐个解释这些字段在 AOSP 蓝牙协议栈(如 stack/bt) 中的用途和意义:
1. HCI_Version
(1 byte)
- 定义:控制器实现的 HCI 层版本
- 可能值:
值 | 含义 |
---|---|
0x06 | Bluetooth 4.0 |
0x07 | Bluetooth 4.1 |
0x08 | Bluetooth 4.2 |
0x09 | Bluetooth 5.0 |
0x0A | Bluetooth 5.1 |
… | 持续增长 |
- 在 AOSP 中的作用:
- 用于判断是否支持某些 HCI 命令或功能,比如 Extended Advertising(需要 BT5.0+)
- 控制某些 feature 的使能与 fallback(降级)策略
2. HCI_Subversion
(2 bytes)
- 定义:控制器厂商定义的子版本号(可能代表固件版本)
- 在 AOSP 中的作用:
- 主要用于 调试 和 厂商定制功能的兼容适配
- 某些厂商驱动层(如 Qualcomm 或 Broadcom)可能会用这个字段判断是否加载特定补丁
3. LMP_Version
(1 byte)
-
定义:Link Manager Protocol 的版本号,用于表示底层链路控制协议的版本
-
常见值:
值 | LMP 版本 | 标准版本 |
---|---|---|
0x06 | LMP 6 | BT 2.0 |
0x07 | LMP 7 | BT 2.1 |
0x08 | LMP 8 | BT 3.0 |
0x09 | LMP 9 | BT 4.0 |
… | … | … |
- 在 AOSP 中的作用:
- 判断是否支持特性如 eSCO、Secure Simple Pairing、LE、BR/EDR coexistence
- 某些协议或逻辑的 fallback 依据
4. Company_Identifier
(2 bytes)
- 定义:厂商 ID,由 Bluetooth SIG 分配
- 例子:
ID | 厂商 |
---|---|
0x000F | Broadcom |
0x000C | CSR |
0x001D | Apple |
0x003D | Intel |
0x0001 | Cambridge Silicon Radio (CSR) |
- 在 AOSP 中的作用:
- 用于厂商特定补丁加载
- 在 log 中标记设备来源
- 控制 chipset-specific workarounds
5. LMP_Subversion
(2 bytes)
- 定义:LMP 层的子版本号,由厂商定义
- 在 AOSP 中的作用:
- 仅对特定厂商驱动有用
- 通常用于识别固件版本差异
- 与
HCI_Subversion
一起,辅助调试判断“是否为某个具体平台”
2.这些版本信息“能干啥”?意义在哪里?
用途 | 说明 |
---|---|
功能判断 | 判断 Controller 是否支持特定协议功能,如 LE Extended Advertising、Secure Connections 等 |
厂商识别 | 确定芯片是 Broadcom、Qualcomm、Intel 还是其他,从而决定加载哪些定制行为 |
平台兼容 | 在 AOSP 中决定是否使用某些 vendor hooks 或者是否 fallback 某些功能 |
调试分析 | 蓝牙功能异常时用于判断是否为固件版本问题 |
日志可读性 | 蓝牙连接日志中可以清晰显示 Controller 的版本与厂商,方便排查 |
3. aosp 中的例子
// system/gd/hci/controller.ccstruct Controller::impl {void Start(hci::HciLayer* hci) {
...hci_->EnqueueCommand(ReadLocalVersionInformationBuilder::Create(),handler->BindOnceOn(this, &Controller::impl::read_local_version_information_complete_handler));...
}
在 Controller::impl::Start 函数中,我们会获取 本地蓝牙控制器的版本信息。
当我们获取到内容后,回调 read_local_version_information_complete_handler
1. read_local_version_information_complete_handler
// system/gd/hci/controller.ccvoid read_local_version_information_complete_handler(CommandCompleteView view) {auto complete_view = ReadLocalVersionInformationCompleteView::Create(view);ASSERT(complete_view.IsValid());ErrorCode status = complete_view.GetStatus();ASSERT_LOG(status == ErrorCode::SUCCESS, "Status 0x%02hhx, %s", status, ErrorCodeText(status).c_str());local_version_information_ = complete_view.GetLocalVersionInformation();bluetooth::os::LogMetricBluetoothLocalVersions(local_version_information_.manufacturer_name_,static_cast<uint8_t>(local_version_information_.lmp_version_),local_version_information_.lmp_subversion_,static_cast<uint8_t>(local_version_information_.hci_version_),local_version_information_.hci_revision_);}
- 最终将 controller 获取到的版本信息,保存在 local_version_information_ 中。
LocalVersionInformation Controller::GetLocalVersionInformation() const {return impl_->local_version_information_;
}
- 通过 Controller::GetLocalVersionInformation 来获取版本信息
看看如何使用
// system/main/shim/controller.cc
static const char GD_CONTROLLER_MODULE[] = "gd_controller_module";EXPORT_SYMBOL extern const module_t gd_controller_module = {.name = GD_CONTROLLER_MODULE,.start_up = start_up, // 这里};static future_t* start_up(void) {LOG_INFO("%s Starting up", __func__);data_.ready = true;if (gd_rust_is_enabled()) {} else {// 获取 mac 地址std::string string_address = GetController()->GetMacAddress().ToString();RawAddress::FromString(string_address, data_.raw_address);data_.le_supported_states =bluetooth::shim::GetController()->GetLeSupportedStates();// 获取 localVersionInfoauto local_version_info =bluetooth::shim::GetController()->GetLocalVersionInformation();data_.bt_version.hci_version =static_cast<uint8_t>(local_version_info.hci_version_);data_.bt_version.hci_revision = local_version_info.hci_revision_;data_.bt_version.lmp_version =static_cast<uint8_t>(local_version_info.lmp_version_);data_.bt_version.lmp_subversion = local_version_info.lmp_subversion_;data_.bt_version.manufacturer = local_version_info.manufacturer_name_;LOG_INFO("Mac address:%s", string_address.c_str());}
在 gd_controller_module 模块的 start_up 函数中,我们会将 local version info 信息放置在 data_.bt_version 中
// system/main/shim/controller.cc
static const RawAddress* get_address(void) { return &data_.raw_address; }static const bt_version_t* get_bt_version(void) { return &data_.bt_version; }
2. 使用案例
1. BTM_SetBleDataLength
// system/stack/btm/btm_ble.cc
tBTM_STATUS BTM_SetBleDataLength(const RawAddress& bd_addr,uint16_t tx_pdu_length) {
...if (controller_get_interface()->get_bt_version()->hci_version >=HCI_PROTO_VERSION_5_0)tx_time = BTM_BLE_DATA_TX_TIME_MAX;...}
根据 hci_version 来调整 ble 数据发送最大时间。
2.BTM_CreateSco
// system/stack/btm/btm_sco.cctBTM_STATUS BTM_CreateSco(const RawAddress* remote_bda, bool is_orig,uint16_t pkt_types, uint16_t* p_sco_inx,tBTM_SCO_CB* p_conn_cb, tBTM_SCO_CB* p_disc_cb) {...if (controller_get_interface()->get_bt_version()->hci_version >=HCI_PROTO_VERSION_2_0) {p_setup->packet_types |=(pkt_types & BTM_SCO_EXCEPTION_PKTS_MASK) |(btm_cb.btm_sco_pkt_types_supported & BTM_SCO_EXCEPTION_PKTS_MASK);}
...
}
3.l2cu_set_acl_priority 和 l2cu_set_acl_latency
// system/stack/l2cap/l2c_utils.cc
bool l2cu_set_acl_priority(const RawAddress& bd_addr, tL2CAP_PRIORITY priority,bool reset_after_rs) {...if ((!reset_after_rs && (priority != p_lcb->acl_priority)) ||(reset_after_rs && p_lcb->acl_priority == L2CAP_PRIORITY_HIGH)) {/* Use vendor specific commands to set the link priority */switch (controller_get_interface()->get_bt_version()->manufacturer) {case LMP_COMPID_BROADCOM:l2cu_set_acl_priority_latency_brcm(p_lcb, priority);break;case LMP_COMPID_SYNAPTICS:l2cu_set_acl_priority_syna(p_lcb->Handle(), priority);break;default:/* Not supported/required for other vendors */break;}}...
}bool l2cu_set_acl_latency(const RawAddress& bd_addr, tL2CAP_LATENCY latency) {
.../* only change controller's latency when stream using latency mode */if (p_lcb->use_latency_mode && p_lcb->is_high_priority() &&latency != p_lcb->acl_latency) {switch (controller_get_interface()->get_bt_version()->manufacturer) {case LMP_COMPID_BROADCOM:l2cu_set_acl_latency_brcm(p_lcb, latency);break;default:/* Not supported/required for other vendors */break;}p_lcb->set_latency(latency);}
...
}
根据不同的厂商做不同的处理
相关文章:

【android bluetooth 协议分析 01】【HCI 层介绍 8】【ReadLocalVersionInformation命令介绍】
1. HCI_Read_Local_Version_Information 命令介绍 1. 功能(Description) HCI_Read_Local_Version_Information 命令用于读取本地 Bluetooth Controller 的版本信息,包括 HCI 和 LMP 层的版本,以及厂商 ID 和子版本号。 这类信息用…...

esp32课设记录(四)摩斯密码的实现 并用mqtt上传
摩斯密码(Morse Code)是一种通过点(.)和划(-)组合来表示字符的编码系统。下面我将在esp32上实现摩斯密码的输入,并能够发送到mqtt的broker。 先捋一下逻辑,首先esp32的按键已经编写了短按与长按功能,这将是输出摩斯密码点和划的基础。然后当2…...

「HHT(希尔伯特黄变换)——ECG信号处理-第十三课」2025年5月19日
一、引言 心电信号(ECG)是反映心脏电活动的重要生理信号,其特征提取对于心脏疾病的诊断和监测具有关键意义。Hilbert - Huang Transform(HHT)作为一种强大的信号处理工具,在心电信号特征提取领域得到了广泛…...

前端(vue)学习笔记(CLASS 6):路由进阶
1、路由的封装抽离 将之前写在main.js文件中的路由配置与规则抽离出来,放置在router/index.js文件中,再将其导入回main.js文件中,即可实现路由的封装抽离 例如 //index.js import { createMemoryHistory, createRouter } from vue-routerim…...

GPT-4.1特点?如何使用GPT-4.1模型,GPT-4.1编码和图像理解能力实例展示
几天前,OpenAI在 API 中推出了三个新模型:GPT-4.1、GPT-4.1 mini 和 GPT-4.1 nano。这些模型的性能全面超越 GPT-4o 和 GPT-4o mini(感觉这个GPT-4.1就是GPT-4o的升级迭代版本),主要在编码和指令跟踪方面均有显著提升。还拥有更大的上下文窗口…...
使用Python和FastAPI构建网站爬虫:Oncolo医疗文章抓取实战
使用Python和FastAPI构建网站爬虫:Oncolo医疗文章抓取实战 前言项目概述技术栈代码分析1. 导入必要的库2. 初始化FastAPI应用3. 定义请求模型4. 核心爬虫功能4.1 URL验证和准备4.2 设置HTTP请求4.3 发送请求和解析HTML4.4 提取文章内容4.5 保存结果和返回数据 5. AP…...
写一段图片平移的脚本
问题描述: 写一段图片平移的脚本。 平移就是将对象换一个位置。如果你要沿方向移动,移动的距离是,你可以以下面的方式构建移动矩阵:。 你可以使用Numpy 数组构建这个矩阵(数据类型是np.float32)…...

【C++】哈希的概念与实现
1.哈希概念 通过某种函数使元素的存储位置与它的关键码之间能够建立一一映射的关系,可以不经过任何比较,一次直接从表中得到要搜索的元素。 当向该结构中: 插入元素: 根据待插入元素的关键码,以此函数计算出该元素的…...

Yocto和Buildroot功能和区别
一.介绍 Yocto 和 Buildroot 都是用于嵌入式 Linux 系统开发的工具集,它们的目的是帮助开发者轻松构建定制的 Linux 系统镜像,以便在嵌入式设备上运行。 二.对比 1.Yocto Yocto 是一个开源的嵌入式 Linux 构建系统,它允许开发者创建自定义…...
物联网数据湖架构
物联网海量数据湖分析架构(推荐实践) ┌──────────────┐ │ IoT设备端 │ └──────┬───────┘│(MQTT/HTTP)▼ ┌──────────────┐ │ EMQX等 │ 可选(也可…...

详解RabbitMQ工作模式之发布订阅模式
目录 发布订阅模式 概念 概念介绍 特点和优势 应用场景 注意事项 代码案例 引入依赖 常量类 编写生产者代码 编写消费者1代码 运行代码 发布订阅模式 概念 RabbitMQ的发布订阅模式(Publish/Subscribe)是一种消息传递模式,它允许消…...
什么是子网委派?
Azure 子网委派的概念 子网委托使您能够为所选的 Azure PaaS 服务指定一个特定的子网,并将其注入到您的虚拟网络中。子网委托为客户提供了完全的控制权,可以管理 Azure 服务与其虚拟网络的集成。 当您将子网委托给 Azure 服务时,您允许该服务为该子网建立一些基本的网络配…...

微信学习之导航功能
先看这个功能的效果: 然后开始学习吧。 一、我们这里用的是vant的Grid控件,首先我们导入: { "usingComponents": {"van-search": "vant/weapp/search/index","my-swiper":"../../components…...

城市内涝监测预警系统守护城市安全
一、系统背景 城市内涝是指由于强降水或连续性降水超过城市排水能力,导致城市内产生积水灾害的现象。随着气候变化和城市化进程的加快,城市内涝现象愈发频繁和严重。传统的城市排水系统已难以满足当前的城市排水需求,特别是在暴雨等极端天气条…...

用 CodeBuddy 搭建「MiniGoal 小目标打卡器」:一次流畅的 UniApp 开发体验
我正在参加CodeBuddy「首席试玩官」内容创作大赛,本文所使用的 CodeBuddy 免费下载链接:腾讯云代码助手 CodeBuddy - AI 时代的智能编程伙伴 在日常生活中,我们总是希望能够坚持一些小习惯,比如每天锻炼十分钟、读一页书、早睡十分…...

Web技术与Nginx网站环境部署
目录 一.web基础 1.域名和DNS (1).域名的概念 (2).hosts文件 (3).DNS (4).域名注册 2.网页与HTML (1).网页简介 (2).HTML &a…...

AI移动监测:仓储环境安全的“全天候守护者”
AI移动监测在仓储方面的应用:技术赋能与场景突破 一、背景:仓储环境的“隐形威胁”与AI破局 仓储行业长期面临设备损坏、货物损失、卫生隐患等风险。传统监控依赖人工巡检或固定摄像头,难以实时捕捉动态风险。例如: 动物入侵&a…...
【数据库】数据库故障排查指南
数据库故障排查指南 数据库连接问题 检查数据库服务是否正常运行,确认网络连接是否畅通,验证数据库配置文件的正确性,确保防火墙或安全组规则允许数据库端口的访问。 性能问题 分析慢查询日志,优化SQL语句,检查索引…...
mariadb 升级 (通过yum)
* 注意下 服务名, 有的服务器上是mysql,有的叫mariadb,mysqld的 #停止 systemctl stop mysql #修改源 vi /etc/yum.repos.d/MariaDB.repo baseurl http://yum.mariadb.org/11.4/centos7-amd64 #卸载 yum remove mysql #安装 yum install MariaDB-server galera-4 MariaDB-…...

2025年5月华为H12-821新增题库带解析
IS-IS核心知识 四台路由器运行IS-IS且已经建立邻接关系,区域号和路由器的等级如图中标记,下列说法中正确的有? R2和R3都会产生ATT置位的Level-1的LSPR1没有R4产生的LSP,因此R1只通过缺省路由和R4通信R2和R3都会产生ATT置位的Leve1-2的LSPR2和…...

用 python 编写的一个图片自动分类小程序(三)
图片自动分类识别小程序记录 2025/5/18 0:38修改程序界面,增加一些功能 用 python 编写的一个图片自动识别分类小程序。 操作系统平台:Microsoft Windows 11 编程语言和 IDE:python 3.10 Visual studio code 一:图片自动分…...
用户行为日志分析的常用架构
## 1. 经典Lambda架构 Lambda架构是一种流行的大数据处理架构,特别适合用户行为日志分析场景。 ### 1.1 架构组成 Lambda架构包含三层: - **批处理层(Batch Layer)**: 存储全量数据并进行离线批处理 - **实时处理层(Speed Layer)**: 处理最新数据&…...

初识 java
目录 前言 一、jdk,JRE和JVM之间的关系 二、JVM的内存划分 前言 初步了解 jdk,JRE,JVM 之间的关系,JVM 的内存划分。 一、jdk,JRE和JVM之间的关系 jdk 是 java 开发工具集,包含JRE; JRE 是…...
3D 数据交换格式(.3DXML)简介
3DXML 是一种基于 XML 的 3D 数据交换格式,由达索系统(Dassault Systmes)开发,主要用于其 CATIA、SOLIDWORKS 和 3DEXPERIENCE 等产品中。 基本概述 全称:3D XML开发者:达索系统主要用途:3D…...

frida 配置
1.环境 1.1 下载 frida-server firda-server github下载地址 这边推荐使用最新版的上一个版本 根据虚拟机自行选择版本 我使用这个版本 frida-server-16.7.17-android-x86_64 1.2 启动 frida-server-16.7.17-android-x86_64 将文件解压至虚拟机目录 使用adb命令执行 chmo…...

16-看门狗和RTC
一、独立看门狗 1、独立看门狗概述 在由单片机构成的微型计算机系统中,由于单片机的工作常常会受到来自外界电磁场的干扰,造成程序的跑飞(不按照正常程序进行运行,如程序重启,但是如果我们填加看门狗的技术࿰…...

【AI论文】用于评估和改进大型语言模型中指令跟踪的多维约束框架
摘要:接下来的指令评估了大型语言模型(LLMs)生成符合用户定义约束的输出的能力。 然而,现有的基准测试通常依赖于模板化的约束提示,缺乏现实使用的多样性,并限制了细粒度的性能评估。 为了填补这一空白&…...
AUTOSAR图解==>AUTOSAR_SRS_TimeService
AUTOSAR TimeService模块详解 AUTOSAR经典平台时间服务分析与图解 目录 1. 概述2. TimeService架构分析 2.1 模块位置与组件关系2.2 模块功能职责3. TimeService组件结构 3.1 预定义定时器类型3.2 时间函数功能3.3 与GPT驱动关系4. TimeService定时器实例 4.1 实例数据结构4.2 …...
设计模式的原理及深入解析
创建型模式 创建型模式主要关注对象的创建过程,旨在通过不同的方式创建对象,以满足不同的需求。 工厂方法模式 定义:定义一个创建对象的接口,让子类决定实例化哪一个类。 解释:工厂方法模式通过定义一个创建对象的…...

Chromium 浏览器核心生命周期剖析:从 BrowserProcess 全局管理到 Browser 窗口实例
在 Chromium 浏览器架构中,BrowserProcess 和 Browser 是两个核心类,分别管理 浏览器进程的全局状态 和 单个浏览器窗口的实例。它们的生命周期设计直接影响浏览器的稳定性和资源管理。以下是它们的详细生命周期分析: 1. BrowserProcess 的生…...