深入理解 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】