协议浅述
HCI简介
HCI协议数据格式
HCI Command Packet
HCI ACL Data Packet
HCI Synchronous(SCO) Data Packet
HCI Event Packet
HCI命令和事件介绍
Inquiry command
Write Local Name Command
Read BD_ADDR Command
HCI协议数据分析
所谓协议就是一个数据通讯规范,因此有两个学习核心是不变的:协议的使用场景(服务对象)和数据通讯格式,所以我接下来按这两个方面来进行说明!
HCI层为上层级提供了一个统一访问hci控制器的接口,其接口为一系列的指令和事件,其接口适用于BR/EDR控制器、BR/EDR/LE控制器、LE控制器、AMP控制器,与底层的结构关系如下图:
两个蓝牙设备点对点hci层的交互过程如下图所示:
主机(用户软件)对蓝牙芯片的控制都是通过协议规范中定义的指令,来控制蓝牙控制器(蓝牙芯片)进入相应的工作模式,例如在蓝牙启动的时候,主机会发送的复位,设置蓝牙名称、设置pincode等指令,当控制器完成相关的操作之后会返回相应的事件通知主机。
当蓝牙发起连接之后,在协商好双方的配置信息之后,hci会根据实际的需要建立acl或者sco链路,这两个链路都是为传输上层的协议。从这里可以看出hci有四种协议包,下面会介绍 !
HCI以命令的形式去访问控制器。HCI链路命令提供了去连接其他控制器的能力。如ER/EDR控制器包含链路管理和链路控制等命令用于与远端设备交互。
HCI命令的处理完成时间是不确定的,所以当一个命令处理完之后会针对这个命令返回一个事件
在传输过程中会有一个句柄,用于识别主机之间的逻辑通道和控制器,共有三种类型的句柄:连接句柄、逻辑链路句柄和物理链路句柄。
HCI共有四种类型的数据包:command(0x01)、acl(0x02)、sco(0x03)和event(0x04)。
Command的数据包格式如下图:
其中opcode(操作码)由ogf(opcode group field,6个bits)和ocf(opcode command field,10个bits)组成,详细内容将在下章介绍。
ACL data用于两个控制器之间的非同步数据交换,如播放音乐的数据,的数据包格式如下图:
其中中PB Flag(指明包适用范围)和BC Flag(广播标志)的描述如下:
SCO data用于两个控制器之间的同步的数据的交换,例如蓝牙通话的数据,的数据包格式如下图:
其中packet_status_flag的描述如下:
HCI事件包用于有事件发生时控制器通知主机,其数据格式入下图:
其中事件代码将在后面章节中具体介绍。
由于命令和事件类型太多,在此不可能一一介绍,具体请参考蓝牙核心协议关于hci的章节,在本小节将举几个典型的例子进行分析。
发送这个命令之后,控制器将进入查询模式,去发现周围的设备,命令的操作组为0x01,操作命令为0x0001,参数为LAP(Lower Address Part)、inquiry_length、num_responses,在core_V5.0的Vol 2,Part E,7.1.1章节,参数描述如下图:
控制器收到该命令之后会回复inquiry complete事件和inquiry result事件,如下:
Event parameter内容请参考核心协议,这里我们就不详细描述了。
这条指令用于设置控制器的蓝牙名称,命令的操作组为0x03,操作命令为0x0013,参数为local name,name编码格式为UTF-8,在core_V5.0的Vol 2,Part E,7.3.11 章节。
控制器收到该命令之后会回复command complete事件,返回事件参数描述如下:
这条指令用于读取控制器的蓝牙地址,命令的操作组为0x04,操作命令为0x0009,无参数,在core_V5.0的Vol 2,Part E,7.4.6 章节。
控制器收到该命令之后会回复事件状态和参数,返回事件参数描述如下:
这里我们已经列举了三个例子作为说明,其他命令和事件在核心协议中都有具体的描述,有兴趣可以去看蓝牙核心规范,下章我们将对具体的hci的log进行分析,以便对hci有更深的理解。
分析的log使用手机进行抓取,在这里只贴取四个分析,其余部分的和log文件会在放在最下面的网盘链接中。
其中蓝色的部分是数据包的类型,红色为具体的hci的数据,在这里我们将解析到l2cap开始建立为止,至于l2cap部分我们将在l2cap分析中说明。
1、Host:(在core_V5.0中的位置:Vol 2,Part E,7.3.2 Reset Command)
00000001 00000011 00001100 00000000
Command:00000001(0x01)
Opcode: 00000011 00001100(ogf:000011(0x03),ocf:0000000011(0x03))根据ogf和ocf查表可知为复位指令
Paramter total length:00000000(参数长度为零,即没有参数)
2、Controller:
00000100 00001110 00000100 00000001 00000011 00001100 00000000
Event:00000100(0x04)
Event code:00001110(0x0e,命令完成指令)
Paramter total length:00000100 (参数长度为4)
Num hci command packet:00000001(表明controller还可以接收1个host的指令)
Opcode: 00000011 00001100(ogf:000011(0x03),ocf:0000000011(0x03))指明是对reset指令的回复
Status:00000000(零为成功,其他为失败,具体参考失败码)
3、Host:(在core_V5.0中的位置:Vol 2,Part E,7.4.5 Read Buffer Size Command)
00000001 00000101 00010000 00000000
Command:00000001(0x01)
Opcode: 00000101 00010000(ogf:000100(0x04),ocf:0000000101(0x05))根据ogf和ocf查表可知为读取buffer大小的指令
Paramter total length:00000000(参数长度为零,即没有参数)
4、Controller:
00000100 00001110 00001011 00000001 00000101 00010000 00000000 00000000 00000100 00111100 00000111 00000000 00001000 00000000
Event:00000100(0x04)
Event code:00001110(0x0e,命令完成指令)
Paramter total length:00001011 (参数长度为11)
Num hci command packet:00000001(表明controller还可以接收1个host的指令)
Opcode: 00000101 00010000(ogf:000100(0x04),ocf:0000000101(0x05))指明是对read buffer指令的回复
后面为具体的参数内容,其在指令的返回值中有描述,下同:
Status:00000000(零为成功,其他为失败,具体参考失败码)
HC_ACL_Data_Packet_Length:00000000 00000100(0x0400=1024)
HC_Synchronous_Data_Packet_Length: 00111100(0x3c=60)
HC_Total_Num_ACL_Data_Packets: 00000111 00000000(0x7=7)
HC_Total_Num_Synchronous_Data_Packets: 00001000 00000000(0x8=8)
上面我只举了四个协议交互例子进行分析,具体的协议的log以及数据分析,以及相关资料,请到我的博客<蓝牙学习笔记(序)>最下面的网盘链接中下载!