
下面根据这份真实 HCI 日志来手动解析。先给结论HCI Command 原始数据 09 10 00 含义 Read Device Address / Read BD_ADDR 读取本地 Controller 的蓝牙设备地址。 HCI Event 原始数据 0E 0A 01 09 10 00 9E A0 94 1E 86 8C 含义 Command Complete Event 表示 Read Device Address 命令执行成功并返回本地蓝牙地址 8C:86:1E:94:A0:9E这里继续按前面确认的规则原始数据不包含 HCI Packet Type 字节。所以 Command 从 Opcode 开始解析Event 从 Event Code 开始解析。一、先解析 HCI Command09 10 001. 查看规范中的 HCI Command Packet 格式查看蓝牙核心规范Vol 4, Part E, Host Controller Interface Functional Specification先看 HCI Command Packet 的通用格式Opcode 2 octets Parameter_Total_Length 1 octet Command_Parameters 0~255 octets原始 Command 是09 10 00按照 HCI Command Packet 格式切分09 10 | 00 │ │ │ └── Parameter_Total_Length └── Opcode2. 解析 Opcode09 10Opcode 是 2 字节并且 HCI 多字节字段按小端序解析。所以原始字节09 10 小端解析0x1009因此Opcode 0x10093. 拆 OpcodeOGF 和 OCFHCI Command Opcode 由两部分组成bit 15 ~ bit 10OGF占 6 bit bit 9 ~ bit 0 OCF占 10 bit计算公式OGF Opcode 10 OCF Opcode 0x03FF代入Opcode 0x1009 OGF 0x1009 10 0x04 OCF 0x1009 0x03FF 0x0009所以Opcode 0x1009 OGF 0x04 OCF 0x0009截图中工具显示的内容也是Opcode: 0x1009 OGF: 0x04 OCF: 0x094. 根据 OGF 查命令组在 HCI Command 的命令组中OGF 0x04对应Informational Parameters commands也就是信息参数类命令这类命令主要用于读取 Controller 的基础信息比如本地版本信息 本地支持的命令 本地支持的特性 本地设备地址所以这条命令不是 LE Controller Commands而是 HCI 通用信息查询命令。5. 根据 OCF 查具体命令在规范的Vol 4, Part E 7.4 Informational Parameters Commands里面找OCF 0x0009对应的命令是Read BD_ADDR有些工具会显示为Read Device Address截图中显示[1009] Read Device Address本质上就是读取本地 Controller 的 Bluetooth Device Address。6. 解析 Parameter_Total_LengthCommand 的最后 1 字节是00这是Parameter_Total_Length 0x00表示Command_Parameters 长度为 0也就是说这条命令不需要输入参数。这也符合规范中对Read BD_ADDR / Read Device Address的定义这个命令只是让 Controller 返回本地蓝牙地址不需要 Host 额外传入参数。7. Command 最终解析结果09 10 Opcode小端序 0x1009 OGF 0x04OCF 0x0009 Informational Parameters / Read Device Address 00 Parameter_Total_Length 0 没有 Command Parameters所以09 10 00 HCI_Read_BD_ADDR / HCI_Read_Device_Address它的含义是Host → Controller 请告诉我你的本地蓝牙设备地址。二、再解析 HCI Event0E 0A 01 09 10 00 9E A0 94 1E 86 8C原始 Event 数据是0E 0A 01 09 10 00 9E A0 94 1E 86 8C注意这里不包含 HCI Packet Type。如果包含 HCI Packet TypeHCI Event 前面通常会有04。但你现在这条数据是从0E开始所以0E是 Event Code不是 Packet Type。1. 查看规范中的 HCI Event Packet 格式HCI Event Packet 通用格式是Event_Code 1 octet Parameter_Total_Length 1 octet Event_Parameters 0~255 octets按照这个格式切分0E | 0A | 01 09 10 00 9E A0 94 1E 86 8C │ │ │ │ │ └── Event_Parameters │ └── Parameter_Total_Length └── Event_Code2. 解析 Event_Code0E第 1 字节0E表示Event_Code 0x0E在 HCI Event 中0x0E Command Complete Event所以这条 Event 是Command Complete Event它的作用是Controller 告诉 Host某条 HCI Command 已经执行完成并且返回执行结果。3. 解析 Parameter_Total_Length0A第 2 字节0A表示Parameter_Total_Length 0x0A换算成十进制0x0A 10所以后面 Event Parameters 一共有 10 字节01 09 10 00 9E A0 94 1E 86 8C数一下01 | 09 10 | 00 | 9E A0 94 1E 86 8C 1字节 2字节 1字节 6字节总共1 2 1 6 10 bytes长度匹配。三、解析 Command Complete Event 的公共字段Command Complete Event 的 Event Parameters 格式是Num_HCI_Command_Packets 1 octet Command_Opcode 2 octets Return_Parameters variable所以01 09 10 00 9E A0 94 1E 86 8C继续切分为01 | 09 10 | 00 9E A0 94 1E 86 8C │ │ │ │ │ └── Return_Parameters │ └── Command_Opcode └── Num_HCI_Command_Packets1. Num_HCI_Command_Packets0101表示Num_HCI_Command_Packets 0x01含义是Controller 当前允许 Host 再发送 1 个 HCI Command Packet。这个字段和 HCI Command 流控有关。可以简单理解为 Controller 告诉 Host我现在还能接收 1 条 HCI Command。2. Command_Opcode09 10接下来 2 字节09 10小端解析原始字节09 10 实际数值0x1009所以Command_Opcode 0x1009这说明这个 Command Complete Event 是对 Opcode 0x1009 的命令响应。也就是对前面这条命令的响应09 10 00继续拆OGF 0x1009 10 0x04 OCF 0x1009 0x03FF 0x0009所以Command_Opcode 0x1009 Informational Parameters / Read Device Address四、解析 Return_Parameters剩余字节是 Return Parameters00 9E A0 94 1E 86 8C因为 Command_Opcode 是Read Device Address / Read BD_ADDR所以 Return Parameters 要去看这个命令自己的返回参数定义。这个命令的返回参数格式是Status 1 octet BD_ADDR 6 octets所以继续切分00 | 9E A0 94 1E 86 8C │ │ │ └── BD_ADDR └── Status1. 解析 Status0000表示Status 0x00在 HCI Status Code 中0x00 Success所以这条命令执行成功。2. 解析 BD_ADDR9E A0 94 1E 86 8C接下来 6 字节9E A0 94 1E 86 8C这是 Controller 返回的蓝牙设备地址。这里要特别注意显示顺序。HCI 返回的 BD_ADDR 原始字节顺序是低字节在前也就是9E A0 94 1E 86 8C但我们平时看到的蓝牙地址通常按高字节到低字节显示成8C:86:1E:94:A0:9E所以原始返回字节 9E A0 94 1E 86 8C 显示成蓝牙地址 8C:86:1E:94:A0:9E这就是为什么截图中工具显示Bluetooth Device Address: 8C:86:1E:94:A0:9E而原始数据里最后 6 字节是9E A0 94 1E 86 8C二者并不矛盾只是显示习惯不同。五、Event 最终解析结果原始 Event0E 0A 01 09 10 00 9E A0 94 1E 86 8C完整解析0E Event_Code Command Complete Event 0A Parameter_Total_Length 10 bytes 01 Num_HCI_Command_Packets Controller 当前允许 Host 再发送 1 条 HCI Command 09 10 Command_Opcode小端序 0x1009 Read Device Address / Read BD_ADDR 00 Status Success 9E A0 94 1E 86 8C BD_ADDR 原始字节 8C:86:1E:94:A0:9E 按常见蓝牙地址格式显示后的地址六、这条 Command 和 Event 到底表达了什么这组日志表达的是一次完整的 HCI 命令交互Host → Controller 09 10 00 请告诉我你的本地蓝牙设备地址。 Controller → Host 0E 0A 01 09 10 00 9E A0 94 1E 86 8C 命令执行成功 你的本地蓝牙设备地址是 8C:86:1E:94:A0:9E。换成人话就是Host 问 Controller你的蓝牙地址是多少 Controller 回答我的地址是 8C:86:1E:94:A0:9E。七、这条地址是什么地址这条命令读到的是本地 Controller 的 Bluetooth Device Address也就是 BD_ADDR。在实际 BLE 分析中要注意区分几个概念本地 Controller 地址 对端设备地址 广播包里的 AdvA 连接请求里的 InitA / AdvA 随机地址 Public Device Address Resolvable Private Address Non-resolvable Private Address这条Read Device Address读出来的是本机 Controller 的蓝牙设备地址不是扫描到的对端设备地址也不是某个广播包里面携带的地址。在日志里这个地址是8C:86:1E:94:A0:9E截图左侧 Addr 列也显示了这个地址8C:86:1E:94:A0:9E说明抓包工具把这个 Command Complete Event 返回的 BD_ADDR 也提取出来显示到了 Addr 列。八、手动查规范时应该怎么查这类日志可以按下面路径查规范。第一步确认包类型根据工具 Type 列HCI Command HCI Event或者根据原始数据结构判断。这里的原始数据不包含 HCI Packet Type所以Command 从 Opcode 开始 Event 从 Event_Code 开始第二步查 HCI Command Packet / HCI Event Packet 格式查看Vol 4, Part E Host Controller Interface Functional Specification找到 HCI Command Packet 格式Opcode Parameter_Total_Length Command_Parameters找到 HCI Event Packet 格式Event_Code Parameter_Total_Length Event_Parameters第三步解析 Opcode对 Command09 10 00先取前 2 字节09 10小端解析Opcode 0x1009再拆OGF 0x04 OCF 0x0009第四步根据 OGF 找命令章节OGF 0x04所以去看7.4 Informational Parameters Commands第五步根据 OCF 找具体命令在Informational Parameters Commands中找OCF 0x0009对应Read BD_ADDR / Read Device Address然后查看该命令的Command Parameters Return Parameters Generated Events第六步解析 Command Complete EventEvent 原始数据0E 0A 01 09 10 00 9E A0 94 1E 86 8C先看0E Command Complete Event然后按 Command Complete Event 格式解析Num_HCI_Command_Packets Command_Opcode Return_Parameters其中Command_Opcode 0x1009说明这个 Event 是对Read Device Address的响应。第七步根据具体 Command 解析 Return Parameters因为它响应的是Read Device Address / Read BD_ADDR所以 Return Parameters 按该命令的定义解析Status 1 octet BD_ADDR 6 octets于是00 Status Success 9E A0 94 1E 86 8C BD_ADDR 原始字节 显示为 8C:86:1E:94:A0:9E九、这条日志的关键点这条日志最关键的地方有 5 个。第一原始 Command09 10 00不是HCI Packet Type 0x09因为原始数据不包含 HCI Packet Type。这里09 10是 Opcode。第二Opcode 要小端解析09 10 0x1009第三Opcode 要拆成OGF 0x04 OCF 0x0009第四OGF 0x04表示Informational Parameters commands所以这条命令是信息查询类命令不是 LE Controller Commands。第五返回的地址字节需要反过来显示原始字节9E A0 94 1E 86 8C 显示地址8C:86:1E:94:A0:9E十、最终总结这一组 HCI 日志可以总结为Host 发送 HCI_Read_BD_ADDR / Read Device Address 命令 用于读取本地 Controller 的蓝牙设备地址。 命令 Opcode 为 0x1009 OGF 0x04属于 Informational Parameters commands OCF 0x0009对应 Read BD_ADDR / Read Device Address。 该命令没有 Command Parameters所以 Parameter_Total_Length 0。 Controller 返回 Command Complete Event Event Code 0x0E Parameter_Total_Length 0x0A Command_Opcode 0x1009 Status 0x00表示成功 BD_ADDR 9E A0 94 1E 86 8C。 按照常见蓝牙地址显示顺序最终地址为 8C:86:1E:94:A0:9E这条日志本质上是蓝牙初始化阶段常见的信息读取流程之一用来确认本地蓝牙 Controller 的设备地址。