【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]
參數名大小描述
Status1 字節表示命令執行結果,0x00 表示成功
HCI_Version1 字節控制器 HCI 層的版本號
HCI_Subversion2 字節控制器廠商定義的 HCI 子版本號
LMP_Version1 字節LMP(Link Manager Protocol)版本號
Company_Identifier2 字節控制器廠商 ID,定義于 Bluetooth SIG
LMP_Subversion2 字節廠商自定義的 LMP 子版本號

4. 事件

成功后,Controller 會通過 HCI_Command_Complete 事件返回這些參數。


2. aosp 中如何使用

1. 字段作用與 AOSP 中的意義

下面我們逐個解釋這些字段在 AOSP 藍牙協議棧(如 stack/bt) 中的用途和意義:


1. HCI_Version(1 byte)

  • 定義:控制器實現的 HCI 層版本
  • 可能值
含義
0x06Bluetooth 4.0
0x07Bluetooth 4.1
0x08Bluetooth 4.2
0x09Bluetooth 5.0
0x0ABluetooth 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 版本標準版本
0x06LMP 6BT 2.0
0x07LMP 7BT 2.1
0x08LMP 8BT 3.0
0x09LMP 9BT 4.0
  • 在 AOSP 中的作用
    • 判斷是否支持特性如 eSCO、Secure Simple Pairing、LE、BR/EDR coexistence
    • 某些協議或邏輯的 fallback 依據

4. Company_Identifier(2 bytes)

  • 定義:廠商 ID,由 Bluetooth SIG 分配
  • 例子
ID廠商
0x000FBroadcom
0x000CCSR
0x001DApple
0x003DIntel
0x0001Cambridge 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);}
...
}

根據不同的廠商做不同的處理

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/83805.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/83805.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/83805.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

React底層架構深度解析:從虛擬DOM到Fiber的演進之路

一、虛擬DOM&#xff1a;性能優化的基石 1.1 核心工作原理 React通過JSX語法將組件轉換為輕量級JavaScript對象&#xff08;即虛擬DOM&#xff09;&#xff0c;而非直接操作真實DOM。這一過程由React.createElement()實現&#xff0c;其結構包含元素類型、屬性和子節點等信息&a…

從AlphaGo到ChatGPT:AI技術如何一步步改變世界?

從AlphaGo到ChatGPT&#xff1a;AI技術如何一步步改變世界&#xff1f; 這里給大家分享一個人工智能學習網站。點擊跳轉到網站。 https://www.captainbed.cn/ccc 前言 在科技發展的歷史長河中&#xff0c;人工智能&#xff08;AI&#xff09;技術無疑是最為璀璨的明珠之一。從…

關于在Unity項目中使用Post Processing插件打包到web端出現的問題

關于在Unity項目中使用Post Processing插件打包到web端出現的問題 解決方法&#xff1a;是不激活攝像機上的Post Processing有關組件&#xff0c;拉低場景中的Directional Light平行光的強度進行web端打包。 &#xff08;烘焙燈光時是可以激活。&#xff09; web端支持這個Pos…

MySQL - 如何突破單庫性能瓶頸

數據庫服務器硬件優化 我們來看看對數據庫所在的服務器是如何進行優化的&#xff0c;服務器是數據庫的宿主&#xff0c;其性能直接影響了數據庫的性能&#xff0c;所以服務器的優化也是數據庫優化的第一步。 數據庫服務器通常是從 CPU、內存、磁盤三個角度進行硬件優化的&…

用 CodeBuddy 搭建「MiniGoal 小目標打卡器」:一次流暢的 UniApp 開發體驗

我正在參加CodeBuddy「首席試玩官」內容創作大賽&#xff0c;本文所使用的 CodeBuddy 免費下載鏈接&#xff1a;騰訊云代碼助手 CodeBuddy - AI 時代的智能編程伙伴 在日常生活中&#xff0c;我們總是希望能夠堅持一些小習慣&#xff0c;比如每天鍛煉十分鐘、讀一頁書、早睡十分…

OpenCV 環境搭建與概述

// //OpenCV-4.11.0 C VS2019 // 一、OpenCV學習路線 1、入門: OpenCV圖像讀寫、視頻讀寫、基本像素處理、基本卷積處理、基本C開發知識。 2、初級: OpenCV自定義卷積操作、圖像梯度、邊緣提取、二值分析、視頻分析、形態學處理、幾何變換與透視變換。 3、中級: 角點查找、BL…

如何快速更換電腦瀏覽器ip:教程與注意事項

無論是為了訪問地域限制內容、保護隱私&#xff0c;還是解決網絡問題&#xff0c;快速更換瀏覽器IP地址的需求日益增多。以下是快速更換電腦瀏覽器IP地址的幾種常用方法及注意事項&#xff0c;結合了多種場景下的解決方案&#xff1a; 一、快速更換瀏覽器IP的方法 1. 代理服務…

【kafka】kafka概念,使用技巧go示例

1. Kafka基礎概念 1.1 什么是Kafka&#xff1f; Kafka是一個分布式流處理平臺&#xff0c;用于構建實時數據管道和流式應用。核心特點&#xff1a; 高吞吐量&#xff1a;每秒可處理百萬級消息持久化存儲&#xff1a;消息按Topic分區存儲在磁盤分布式架構&#xff1a;支持水平…

掌握Git:版本控制與高效協作指南

一、初始Git 提出問題&#xff1a;無論是在工作還是學習&#xff0c;我們在編寫各種文檔的時候&#xff0c;更改失誤&#xff0c;失誤后恢復到原來版本&#xff0c;不得不復制出一個副本。 每個版本由各自的內容&#xff0c;但最終只有一個報告需要被我們使用。 但在此之前的…

【生活相關-日語-日本-東京-搬家后-引越(ひっこし)(3)-踩坑點:國民健康保險】

【生活相關-日語-日本-東京-搬家后-引越&#xff08;ひっこし&#xff09;&#xff08;3&#xff09;-注意點&#xff1a;國民健康保險】 1、前言2、情況說明&#xff08;1&#xff09;問題說明&#xff08;2&#xff09;情況說明&#xff08;1&#xff09;收到情況&#xff08…

linux——mysql故障排查與生產環境優化

目錄 一&#xff0c;mysql數據庫常見的故障 1&#xff0c;故障現象1 2&#xff0c;故障現象2 3&#xff0c;故障現象3 &#xff14;&#xff0c;故障現象&#xff14; &#xff15;&#xff0c;故障現象&#xff15; &#xff16;&#xff0c;故障現象&#xff16; 二&…

【C#】用 DevExpress 創建帶“下拉子表”的參數表格視圖

展示如何用 DevExpress 創建帶“下拉子表”的參數表格視圖。主表為 參數行 ParamRow&#xff0c;子表為 子項 ChildParam。 一、創建模型類 public class ParamRow {public string Pn { get; set; }public string DisplayName { get; set; }public string Value { get; set; }…

【JavaScript】用 Proxy 攔截對象屬性

目錄 一、Proxy 的基本結構&#xff08;打地基&#xff09; 二、最常用的兩個攔截方法&#xff1a;get 和 set 1. get(target, key) 2. set(target, key, value) 三、說到這&#xff0c;那就可以回到題目來 四、什么是 Reflect&#xff1f; 總結不易&#xff0c;本章節對…

[IMX] 02.GPIO 寄存器

目錄 手冊對應章節 1.GPIO 復用&#xff08;引腳功能選擇&#xff09;- IOMUXC_SW_MUX_CTL_PAD_xxx 2.GPIO 電氣特性 - IOMUXC_SW_PAD_CTL_PAD_xxx 3.GPIO 數據與控制寄存器 3.1.數據 - DR 3.2.輸入/輸出選擇 - GDIR 3.3.狀態 - PSR 3.4.中斷觸發控制 - ICR 3.5.中斷使…

Tomcat 配置 HTTPS 訪問全攻略(CentOS 環境)

Tomcat 配置 HTTPS 訪問全攻略&#xff08;CentOS 環境&#xff09; 一、環境說明 操作系統&#xff1a;CentOS Tomcat 版本&#xff1a;Apache Tomcat/9.0.105 服務器 IP&#xff1a;192.168.1.35 目標&#xff1a;將 Tomcat 默認的 HTTP 訪問升級為 HTTPS&#xff0c;提…

Flink 運維監控與指標采集實戰(Prometheus + Grafana 全流程)

一、引言:為什么 Flink 運維監控如此重要? 在實時計算場景中,Flink 作業 724 小時運行,對性能、資源、故障感知、狀態變化的實時監控非常關鍵。沒有有效的運維可觀測體系: 不知道任務是否在穩定運行 發生問題難以快速定位 無法感知背壓、延遲、反壓等狀態 因此,構建完善…

【prometheus+Grafana篇】基于Prometheus+Grafana實現Oracle數據庫的監控與可視化

&#x1f4ab;《博主主頁》&#xff1a; &#x1f50e; CSDN主頁 &#x1f50e; IF Club社區主頁 &#x1f525;《擅長領域》&#xff1a;擅長阿里云AnalyticDB for MySQL(分布式數據倉庫)、Oracle、MySQL、Linux、prometheus監控&#xff1b;并對SQLserver、NoSQL(MongoDB)有了…

【數據倉庫面試題合集③】實時數倉建模思路與實踐詳解

實時數據倉庫已經成為各大企業構建核心指標監控與業務實時洞察的基礎能力。面試中,關于實時建模的題目頻繁出現,尤其聚焦于建模思路、寬表設計、狀態管理、亂序處理等方面。本文整理典型題目及答題思路,幫助你應對相關考察。 一、建模原則與數倉分層認知 1. 實時數倉與離線…

鴻蒙PC操作系統:從Linux到自研微內核的蛻變

鴻蒙PC操作系統是否基于Linux內核,需要結合其技術架構、發展階段和官方聲明綜合分析。以下從多個角度展開論述: 一、鴻蒙操作系統的多內核架構設計 多內核混合架構 根據資料,鴻蒙操作系統(HarmonyOS)采用分層多內核架構,內核層包含Linux內核、LiteOS-m內核、LiteOS-a內核…

LabVIEW數據庫使用說明

介紹LabVIEW如何在數據庫中插入記錄以及執行 SQL 查詢&#xff0c;適用于對數據庫進行數據管理和操作的場景。借助 Database Connectivity Toolkit&#xff0c;可便捷地與指定數據庫交互。 各 VI 功能詳述 左側 VI 功能概述&#xff1a;實現向數據庫表中插入數據的操作。當輸入…