

这部分内容讲的是 HCI_LE_Read_PHY command ,也就是 BLE 中用于读取当前连接所使用 PHY 类型 的 HCI 命令。
它的核心作用是:Host 通过 Connection_Handle 指定一条 BLE 连接,然后向 Controller 查询这条连接当前发送方向和接收方向分别使用的 PHY。
一、原文翻译
7.8.47 LE Read PHY command
命令概览
| 项目 | 内容 |
|---|---|
| Command | HCI_LE_Read_PHY |
| OCF | 0x0030 |
| Command Parameters | Connection_Handle |
| Return Parameters | Status、Connection_Handle、TX_PHY、RX_PHY |
也就是说,这条命令名称是:
HCI_LE_Read_PHY
它的 OCF 是:
0x0030
命令参数只有一个:
Connection_Handle
返回参数有四个:
Status
Connection_Handle
TX_PHY
RX_PHY
二、Description 翻译
原文:
This command is used to read the current transmitter PHY and receiver PHY on the connection identified by the Connection_Handle.
翻译:
该命令用于读取由 Connection_Handle 标识的连接上,当前正在使用的发送 PHY 和接收 PHY。
换句话说,Host 通过这条命令问 Controller:
这条 BLE 连接当前发送数据时用的是什么 PHY?
这条 BLE 连接当前接收数据时用的是什么 PHY?
三、Command Parameters 翻译
Connection_Handle
大小:2 octets,也就是 2 字节,其中 12 bit 有实际意义。
| Value | Parameter Description |
|---|---|
| 0xXXXX | Connection_Handle,范围是 0x0000 到 0x0EFF |
Connection_Handle 用于指定要查询哪一条 BLE 连接。
因为一个设备可能同时连接多个 BLE 外设,所以 Host 必须通过 Connection_Handle 告诉 Controller:
我要读取的是哪一条连接的 PHY。
四、Return Parameters 翻译
1. Status
大小:1 octet,也就是 1 字节。
| Value | Parameter Description |
|---|---|
| 0x00 | HCI_LE_Read_PHY command 执行成功。 |
| 0x01 to 0xFF | HCI_LE_Read_PHY command 执行失败。具体错误码需要查看 [Vol 1] Part F 中的错误码说明。 |
Status 表示这条命令是否执行成功。
0x00:成功
0x01 ~ 0xFF:失败
如果失败,可能是连接句柄无效、当前连接不存在、Controller 状态不允许等原因。
2. Connection_Handle
大小:2 octets,也就是 2 字节,其中 12 bit 有实际意义。
| Value | Parameter Description |
|---|---|
| 0xXXXX | Connection_Handle,范围是 0x0000 到 0x0EFF |
返回参数中的 Connection_Handle 用来说明:
这个读取结果对应的是哪一条 BLE 连接。
3. TX_PHY
大小:1 octet,也就是 1 字节。
| Value | Parameter Description |
|---|---|
| 0x01 | 当前连接的发送 PHY 是 LE 1M |
| 0x02 | 当前连接的发送 PHY 是 LE 2M |
| 0x03 | 当前连接的发送 PHY 是 LE Coded |
| All other values | 保留,供未来使用 |
TX_PHY 表示当前连接上 本端发送方向 使用的 PHY。
也就是说:
本地 Controller 发数据给对端时,使用的是哪种 PHY。
4. RX_PHY
大小:1 octet,也就是 1 字节。
| Value | Parameter Description |
|---|---|
| 0x01 | 当前连接的接收 PHY 是 LE 1M |
| 0x02 | 当前连接的接收 PHY 是 LE 2M |
| 0x03 | 当前连接的接收 PHY 是 LE Coded |
| All other values | 保留,供未来使用 |
RX_PHY 表示当前连接上 本端接收方向 使用的 PHY。
也就是说:
本地 Controller 接收对端数据时,使用的是哪种 PHY。
五、Event generated 翻译
除非事件被 mask 掉,否则会生成以下事件。
当 HCI_LE_Read_PHY command 完成后,会生成:
HCI_Command_Complete event
也就是说,这条命令的执行结果会通过 HCI_Command_Complete event 返回给 Host。
六、这部分内容表述了哪些知识
这部分主要讲了 5 个知识点。
1. HCI_LE_Read_PHY 是读取当前连接 PHY 的命令
它不是用来设置 PHY 的,而是用来读取当前 PHY 状态的。
它查询的是指定连接上的:
TX_PHY
RX_PHY
也就是当前发送方向和接收方向分别使用的 PHY。
2. 这条命令必须基于已经存在的连接
命令参数里只有一个:
Connection_Handle
这说明它是针对连接的命令。
也就是说,只有 BLE 连接建立之后,Host 才能通过这条命令读取该连接的 PHY。
它不是读取广播 PHY,也不是读取扫描 PHY。
3. TX_PHY 和 RX_PHY 是分开的
这点很关键。
返回参数中不是只有一个 PHY,而是分成:
TX_PHY
RX_PHY
原因是 BLE 连接中的发送方向和接收方向,在规范表达上是可以分别描述的。
从本地设备角度看:
TX_PHY:我发给对方时使用的 PHY
RX_PHY:我接收对方发来的数据时使用的 PHY
所以分析 HCI log 时,不要把 TX_PHY 和 RX_PHY 混成一个概念。
4. PHY 类型主要有 LE 1M、LE 2M、LE Coded
表中列出了三种取值:
0x01:LE 1M
0x02:LE 2M
0x03:LE Coded
它们大致可以这样理解:
LE 1M:BLE 默认常见 PHY,速率和兼容性较均衡
LE 2M:更高空口速率,适合提升吞吐
LE Coded:更强覆盖能力,适合远距离,但速率更低
5. 命令完成后只生成 HCI_Command_Complete event
这条命令是读取类命令,所以完成后生成:
HCI_Command_Complete event
它不像 HCI_LE_Set_PHY 那样涉及 PHY 更新过程,也不像某些连接参数变化命令那样会额外产生专门的变化事件。
这条命令的结果就在 HCI_Command_Complete event 的返回参数里。
七、必要 Tip
Tip 1:Read PHY 只是读取,不会改变连接参数
HCI_LE_Read_PHY 的作用是查询当前 PHY。
它不会主动切换 PHY,也不会请求对端更新 PHY。
如果要发起 PHY 切换,相关命令是:
HCI_LE_Set_PHY
所以这两个命令要区分:
HCI_LE_Read_PHY:读取当前 PHY
HCI_LE_Set_PHY:请求设置/更新 PHY
Tip 2:TX_PHY 和 RX_PHY 是从本地 Controller 角度看的
这一点非常重要。
比如 Host 收到:
TX_PHY = 0x02
RX_PHY = 0x01
含义是:
本地发送方向使用 LE 2M
本地接收方向使用 LE 1M
不是说"对端的 TX_PHY 是 0x02"。
所有 HCI 命令返回的 TX/RX,通常都要站在本地 Controller 的角度理解。
Tip 3:PHY 影响吞吐、距离和稳定性
PHY 是 BLE 空口物理层相关能力,会影响实际通信表现。
简单理解:
LE 1M:默认常用,兼容性好
LE 2M:空口速率更高,有利于提升吞吐
LE Coded:通信距离更远,抗干扰/覆盖能力更强,但吞吐更低
所以在做 BLE 透传、OTA、文件传输时,读取 PHY 可以帮助判断当前链路是否处在更适合高速传输的状态。
如果当前是:
TX_PHY = LE 2M
RX_PHY = LE 2M
通常更有利于高吞吐传输。
如果当前是:
TX_PHY = LE Coded
RX_PHY = LE Coded
通常更偏向远距离连接,而不是高吞吐。
Tip 4:读取到 LE 2M 不代表 GATT 一定高速
PHY 只是影响 BLE 传输能力的一个因素。
实际 GATT 吞吐还会受到很多因素影响,例如:
ATT MTU
Data Length
Connection Interval
Connection Event 中可发送包数量
手机系统调度
App 写入方式
对端处理能力
是否启用 Notification / Write Without Response
所以不能简单认为:
PHY = LE 2M,所以 GATT 速度一定很快。
更准确的理解是:
LE 2M 提供了更高的物理层传输能力,但最终吞吐还要看整条 BLE 链路和上层协议配置。
Tip 5:Read PHY 常用于确认当前链路状态
在实际调试中,HCI_LE_Read_PHY 可以用来确认:
当前连接是否仍然是 LE 1M
是否已经切换到 LE 2M
是否处于 LE Coded
Set PHY 之后是否真的切换成功
尤其是在分析 btsnoop 日志时,可以通过这条命令和返回事件判断当前连接的 PHY 状态。
八、哪些是关键信息
关键信息 1:Command 名称和 OCF
Command:HCI_LE_Read_PHY
OCF:0x0030
这说明它是一个标准的 HCI LE Controller Command。
在分析 HCI log 时,可以通过 Command 名称、OCF 或 Opcode 找到这条命令。
关键信息 2:Connection_Handle
Connection_Handle
Size:2 octets
Range:0x0000 ~ 0x0EFF
12 bits meaningful
这是本命令唯一的命令参数。
它说明 HCI_LE_Read_PHY 必须作用于某一条具体 BLE 连接。
所以使用场景是:
BLE 连接已经建立
Host 拿到了 Connection_Handle
Host 读取该连接当前 PHY
关键信息 3:TX_PHY
TX_PHY
Size:1 octet
取值含义:
0x01:LE 1M
0x02:LE 2M
0x03:LE Coded
它表示本地 Controller 当前发送方向使用的 PHY。
重点是:TX 是本地发送方向,不是对端发送方向。
关键信息 4:RX_PHY
RX_PHY
Size:1 octet
取值含义:
0x01:LE 1M
0x02:LE 2M
0x03:LE Coded
它表示本地 Controller 当前接收方向使用的 PHY。
重点是:RX 是本地接收方向,也就是对端发过来的数据,本地用什么 PHY 接收。
关键信息 5:Status
Status
Size:1 octet
取值:
0x00:命令执行成功
0x01 ~ 0xFF:命令执行失败
只有当 Status = 0x00 时,后面的 TX_PHY 和 RX_PHY 才有正常解释意义。
如果 Status 表示失败,就应该优先查看错误码原因。
关键信息 6:只生成 HCI_Command_Complete event
命令完成后生成:
HCI_Command_Complete event
这个事件会携带返回参数:
Status
Connection_Handle
TX_PHY
RX_PHY
所以 Host 想知道读取结果,就要看 HCI_Command_Complete event 中的 return parameters。
九、整体理解
HCI_LE_Read_PHY command 可以理解为一个查询命令。
它的完整流程是:
BLE 连接已经建立
↓
Host 发送 HCI_LE_Read_PHY command
↓
命令参数携带 Connection_Handle
↓
Controller 查询该连接当前 PHY 状态
↓
Controller 通过 HCI_Command_Complete event 返回结果
↓
Host 从返回参数中读取 TX_PHY 和 RX_PHY
它最终回答的问题是:
这条 BLE 连接当前发送方向使用什么 PHY?
这条 BLE 连接当前接收方向使用什么 PHY?
一句话总结:
HCI_LE_Read_PHY 是 Host 用来读取指定 BLE 连接当前 TX_PHY 和 RX_PHY 的 HCI 命令。
它常用于 BLE 链路调试、吞吐分析、PHY 切换验证、OTA 速度分析等场景。