深入理解 LE Read Remote Features 命令與事件響應
在藍牙低功耗(BLE)通信中,設備特性(LE Features)協商是連接過程中的一個關鍵環節。本文將詳細介紹 HCI 層的命令 LE_Read_Remote_Features
及其對應的事件響應 LE_Read_Remote_Features_Complete
,并結合 AOSP 源碼和實際日志案例深入分析其使用流程與失敗原因。
1. 背景與作用
LE_Read_Remote_Features
命令用于查詢遠程 BLE 設備支持的功能能力,這些能力以 bitmask(8 字節)表示,涵蓋了加密支持、長距離 PHY、擴展廣播等關鍵特性。
🔍 該命令通常在 BLE 連接建立成功之后發出,用于決定是否啟用高級特性(如 DLE、2M PHY、Coded PHY 等)。
2. HCI 命令結構
1.HCI_LE_Read_Remote_Features
(命令)
字段 | 內容 |
---|---|
Opcode | 0x2016 (OGF: 0x08, OCF: 0x0016) |
參數 | Connection_Handle (2 字節,低 12 位有效) |
返回值 | 無 |
事件響應 | HCI_Command_Status ,隨后跟 LE_Read_Remote_Features_Complete |
2. 用途說明
這個命令的目的是:
向 Controller 發送請求,讀取指定
Connection_Handle
上遠程設備所支持的 LE(Low Energy)功能特性(如:LE Encryption, Extended Advertising, 2M PHY 等)。
用于:
-
Central 讀取 Peripheral 的特性(或反過來)
-
動態判斷遠端設備支持哪些 BLE 功能
-
連接后才能用(基于
Connection_Handle
)
3. 命令參數
參數名稱 | 大小 | 說明 |
---|---|---|
Connection_Handle | 2 字節(只有低 12 位有效) | 當前 ACL 連接的句柄(連接編號) 范圍: 0x0000 到 0x0EFF |
?? 注意:高 4 位是保留位或標志位,需屏蔽(代碼中使用
handle & 0x0FFF
)
4. 返回參數
無返回參數(命令本身不直接返回結果)
但 事件(Event)機制 會異步返回兩個事件:
5. 事件流程說明
當 Host 發出 LE Read Remote Features
命令后,HCI 控制器將生成以下事件:
1. HCI_Command_Status
(立即返回)
-
告知主機該命令是否被 Controller 接收成功
-
不包含讀取結果,僅表示“命令執行中”或“命令無法執行”
2?. HCI_LE_Read_Remote_Features_Complete
(最終完成)
-
當 Controller 讀取遠程特性成功后,發此事件
-
包含字段:
-
Status
:命令執行是否成功 -
Connection_Handle
-
LE_Features
:8 字節的 Feature Bitmap(代表遠端支持的特性)
-
? 這是你需要在上層軟件中接收和解析的主要數據
6. 注意事項(規范原文中的 Note)
該命令不會通過
HCI_Command_Complete
表示完成,而是通過HCI_LE_Read_Remote_Features_Complete
來表示命令已完成。
即:你不應該監聽Command_Complete
來處理結果,而是監聽對應的 LE 事件。
7.典型使用場景
場景 | 描述 |
---|---|
ATT 服務等連接后檢查遠端是否支持特定 BLE 特性 | 如 LE Secure Connections、2M PHY、Data Length Extension |
BLE 連接后做版本兼容性判斷 | 動態適配不同設備 |
藍牙自動化測試 | 驗證設備間 BLE 特性匹配 |
Android BLE Stack 中 | btm_ble_read_remote_features_complete() 回調處理該事件數據并記錄到連接上下文中 |
8. 小結
關鍵點 | 內容 |
---|---|
命令名 | HCI_LE_Read_Remote_Features |
Opcode | 0x2016 |
參數 | Connection_Handle (12-bit) |
返回 | 無,結果通過事件返回 |
主要事件 | HCI_LE_Read_Remote_Features_Complete |
特性位數 | 8 字節 bitmap |
使用目的 | 獲取遠程設備支持的 BLE 特性 |
3. HCI 事件響應結構
1. 事件基本信息
項目 | 內容 |
---|---|
事件名稱 | HCI_LE_Read_Remote_Features_Complete |
事件碼 (Event Code) | 0x3E (即 LE Meta Event 的 Event Code) |
子事件碼 (Subevent Code) | 0x04 表示這是 “Read Remote Features Complete” 子事件 |
作用 | 表示控制器完成了遠程 BLE 設備的特性查詢。 |
2. 事件結構解析
Event 格式結構:
Event Code (1 Byte) = 0x3E
Parameter Total Length (1 Byte)└─ Subevent_Code (1 Byte) = 0x04Status (1 Byte)Connection_Handle (2 Bytes, 12 bits meaningful)LE_Features (8 Bytes)
字段 | 大小 | 說明 |
---|---|---|
Subevent_Code | 1 字節 | 值為 0x04 ,代表是該子事件 |
Status | 1 字節 | 0 表示成功,非 0 為失敗(如設備不支持) |
Connection_Handle | 2 字節(低 12 位有效) | 標識當前連接 |
LE_Features | 8 字節 | 遠程設備支持的 BLE 功能(bitmask) |
3. LE_Features Bitmask 功能對照表
Bit | 名稱 | 功能說明 | 實際應用 |
---|---|---|---|
0 | LE Encryption | 支持 AES-CCM 加密 | 安全配對 |
1 | Conn Param Req Procedure | 支持 LLCP 參數更新流程 | 降功耗 |
5 | Data Length Extension (DLE) | 支持數據包擴展 | BLE Audio |
6 | LL Privacy | 支持隱私地址與解析器 | 防跟蹤 |
8 | LE 2M PHY | 支持 2 Mbps PHY | 提速 |
11 | LE Coded PHY | 支持遠距離傳輸(S=2, S=8) | 車鑰匙 |
12 | Extended Advertising | 廣播內容支持 > 31 字節 | BLE 廣播 |
13 | Periodic Advertising | 周期廣播 | AoA/AoD |
14 | Channel Selection Algorithm #2 | 更佳抗干擾選擇算法 | BLE Mesh |
你可以在代碼中根據這些位判斷遠端設備支持哪些高級功能,比如是否支持 LE 2M PHY(高傳輸速率)或 DLE(Data Length Extension)。 |
完整位定義請參考《Bluetooth Core Spec Vol 6, Part B, Section 4.6》。
4.使用建議
使用階段 | 推薦操作 |
---|---|
BLE 連接建立后 | 立即發送 LE Read Remote Features 命令 |
收到 Complete 事件后 | 根據 LE_Features 結果,更新連接能力或適配策略 |
多次連接相同設備 | 可復用之前的能力緩存(如規范中建議) |
5. 總結
項目 | 內容 |
---|---|
命令 | HCI_LE_Read_Remote_Features (0x2016) |
事件 | HCI_LE_Read_Remote_Features_Complete (0x3E / Subevent 0x04) |
事件內容 | status + handle + 8字節LE特性bitmask |
代碼位置 | btm_ble_read_remote_features_complete() 函數中處理 |
應用場景 | 特性協商、能力判斷、自適應控制、BLE測試等 |
4. AOSP 源碼解析
1.btm_ble_read_remote_features_complete
-
用途:當主機通過 HCI 向控制器發出
LE Read Remote Features
命令后,控制器會返回命令完成事件,此函數用于解析該事件并根據結果更新連接狀態、記錄遠程設備支持的特性等。 -
入口參數:
p
: 指向事件參數的指針length
: 參數長度
-
system/stack/btm/btm_ble_gap.cc
/********************************************************************************* Function btm_ble_read_remote_features_complete** Description This function is called when the command complete message* is received from the HCI for the read LE remote feature* supported complete event.** Returns void*******************************************************************************/
void btm_ble_read_remote_features_complete(uint8_t* p, uint8_t length) {uint16_t handle;uint8_t status;/*如果事件數據長度小于 3 字節,則認為格式非法,跳轉到錯誤處理。最少需要:status (1字節) + handle (2字節) = 3 字節*/if (length < 3) {goto err_out;}/*使用宏從 p 中按順序讀取:status: HCI 命令執行結果狀態碼handle: ACL 鏈路句柄(16位)*/STREAM_TO_UINT8(status, p);STREAM_TO_UINT16(handle, p);// HCI 句柄只有低 12 位有意義,高 4 位為保留或標志位,需屏蔽。handle = handle & 0x0FFF; // only 12 bits meaningful/*如果讀取失敗(非 HCI_SUCCESS):如果失敗原因不是“不支持讀取遠程特征”,則打印錯誤日志并退出否則記錄警告日志說明遠端設備不支持該命令(但流程可以繼續)*/if (status != HCI_SUCCESS) {if (status != HCI_ERR_UNSUPPORTED_REM_FEATURE) {LOG_ERROR("Failed to read remote features status:%s",hci_error_code_text(static_cast<tHCI_STATUS>(status)).c_str());return;}LOG_WARN("Remote does not support reading remote feature");}// 如果讀取成功,則還需要確保后續還有 BD_FEATURES_LEN 字節數據,用于保存遠程設備支持的功能位(Bit Field)if (status == HCI_SUCCESS) {// BD_FEATURES_LEN additional bytes are read// in acl_set_peer_le_features_from_handleif (length < 3 + BD_FEATURES_LEN) {goto err_out;}/*嘗試將 p 所指的特性數據記錄到已有的連接對象中如果找不到對應的連接(句柄無效或連接已斷開),打印錯誤并退出*/if (!acl_set_peer_le_features_from_handle(handle, p)) {LOG_ERROR("Unable to find existing connection after read remote features");return;}}/*無論是否支持遠程特性,最終都會向控制器發送一個 遠程版本信息請求(Remote Version Request),以進一步獲取控制器支持的協議版本等信息。*/btsnd_hcic_rmt_ver_req(handle);return;err_out:LOG_ERROR("bogus event packet, too short");
}
步驟 | 邏輯 |
---|---|
讀取 status + connection_handle(前 3 字節) | |
- | 判斷 status 是否為 HCI_SUCCESS (0x00) |
- | 如果成功,從指針 p 繼續讀取 8 字節 features 并寫入到 ACL 連接 |
- | 如果失敗(如 0x3E),輸出錯誤并終止處理 |
5. 結語
BLE 中的 LE_Read_Remote_Features
是了解遠程設備能力的關鍵命令,正確地處理該命令及其響應事件,有助于提升連接質量、支持更復雜的 BLE 特性(如 BLE Audio、Mesh、AoA 等)。連接失敗時,如遇到 0x3E
錯誤碼,應首先檢查 BLE 連接是否建立,排查廣播、地址解析與鏈路層資源等問題。
這里分享一個 真實的案例:
【android bluetooth 協議分析 05】【藍牙連接詳解1】【連接錯誤碼-0x3E】