从蓝牙设备状态转换可以知道,蓝牙设备连接需经过Inquiry,page过程,本文主要从HCI角度分析连接过程。解析抓包文件用到的工具为Frontline 的Capture File Viewer。
HCI(Host Controller Interface):Core_v4.1规定了四种类型的接口,分别为普通串口(不带流控制),usb接口,SD接口,三线串口。主机可以通过上面的四种接口和控制器通信,每种接口都有相应的通信规范(格式)。具体的见Core_v4.1 Vol 4。本文是基于普通串口的HCI进行分析的!
HCI数据包格式如下:
其中HCI packet indicator如下表所示:
01表示命令包
02表示异步数据包
03表示同步数据包
04表示事件包
HCI_H,HCI_C分别表示主机host和蓝牙控制器。从上图可以看到inquiry的整个过程,首先主机host发送命令给控制器关闭LE扫描,然后再设置inquiry的功率,最后发送HCI_Inquiry命令,带控制器收到远程设备的inquiry_response之后,发送HCI_Event给host。Host收到应答后发送Hci_inquiry_cancel命令,控制器收到命令后响应并执行,待host 收到Command Complete响应后,整个inquiry过程结束!下面从数据包角度分析下这个过程。
HCI_LE_Set_Scan_Enable指令:开始/结束扫描。扫描用来发现/广播周边的LE设备。具体过程可以查看Core_v4.1 Vol 6 [4.1 PASSIVE SCANNING]
参数列表
具体的数据包如下:
LE_Set_Scan_Enable command has completed, aCommand Complete event shall be generated.具体数据包如下:
Write_Inquiry_Transmit_Power_Level:设置inquiry的功率
-70dBm <=N<=20dBm 表示的功率范围在多少?
10^-7mw <=P<=100mw
dBm 定义的是 miliwatt。 0 dBm =10log(1) mW = 1 mW;
dBw 定义 watt。 0 dBw =10log1 W = 10*log(1000) mw = 30 dBm。
dB在缺省情况下总是定义功率单位,以 10*log 为计。当然某些情况下可以用信号强度(Amplitude)来描述功和功率,这时候就用 20log 为计。不管是控制领域还是信号处理领域都是这样。比如有时候大家可以看到 dBmV 的表达.
具体的数据包为:
00000001 0101100100001100 00000001 00000110
Packetindicator:0x01(00000001)
OCF:0x0059(0001011001)
OGF:0x03(000011)
Len:0x01 (00000001)
CommandParameters:0x06(00000110)
Inquiry is used to detect and collect nearby devices。总共要经历三个过程,分别如下:
step1.主机发送HCI_Inquiry命令
Step 2:
主机控制器开始查询过程。当有设备响应查询,主控制器将会利用一个或者多个查询结果事件返回搜寻到设备的有用信息,比如设备地址,设备类型,支持的数据格式,时钟偏移,信号强度信息。
Step 3a:主设备如果想结束查询过程,只需向控制器发送HCI_Inquiry_Cancel命令。
Step 3b:当控制器接收响应设备数达到要求或者超时,将会返回完成事件给主设备。
![]()
HCI_Inquiry格式:
主机给控制器的HCI_Inquiry命令数据如下:
00000001 00000001 00000100 00000101 00110011 10001011 10011110 00000100 00011001
Cmd:00000001
Opcode:00000001 00000100
Len :00000101
LAP: General/UnlimitedInquiry Access Code (GIAC):00110011 1000101110011110
Inquiry Length (sec):5.12 (00000100)[Time = N * 1.28sec]
Max.Number Responses: 25 (00011001)
控制器给host的response如下:
00000100 00001111 00000100 00000000 00000001 0000000100000100
HCI_Inquiry_Result_With_RSSI:命令数据包如下
00000100 00100010 000011110000000100000011 01110000 00000000 00110000 0111001100100000000000010000001010001100 00100101 0010000000101000 00101000 10011110
Event: 00000100
HCI_Inquiry_Result_With_RSSI:00100010
Total Length: 15 : 00001111
NumResponses: 00000001
Bluetooth Device Address: 0x20-73-30-00-70-030000001101110000 00000000 00110000 01110011 00100000
Page Scan Repetition Mode: R100000001
Page Scan PeriodMode: P2 00000010
Class of Device 1000110000100101 00100000
Clock Offset: 1028000101000 00101000
RSSI(dBm): -9810011110
HCI_Inquiry_Cancel:
00000001 00000010 00000100 00000000
![]()
Inquiry_Cancel_Complete:
00000100 00001110 00000100 00000001 0000001000000100 00000000
![]()
至此 inquiry过程结束!
(下图为异步过程的示列)
上图表示Connection establishment 和 detachment 过程,总共需9个不同的过程。有些过程不是必须的比如授权和加密过程。有些过程是必须的,比如ConnectionRequest 和Setup Complet过程。
下面详细介绍下CONNECTION SETUP过程,其他过程请参考 Core_v4.1.pdf Vol 2 【ACL CONNECTION ESTABLISHMENT AND DETACHMENT】章节!
CONNECTION SETUP共需如下的10个步骤:
Step 1:主设备发送HCI_Create_Connection命令给控制器。控制器接收到命令后,会开始寻呼选定的设备。所谓选定的设备, 即Acess Code和Paging hoppingfrequence由选定设备的BD_ADDR 的LAP决定。过程如下图所示:
HCI_Create_Connection命令包格式:
Event: Command Status
Step 2:可选步骤,host和slaver的LM获取对方的特性信息。
Step 3:主控制器LM发送LMP_host_connection_req请求,远程设备LM确认请求。
Step 4a:如果远程设备拒绝连接,连接过程结束。
Step 4b:远程设备接收这个连接。
Step 4c:远程设备接收连接,并请求为Master。
Step 5:和远程设备交换特性,和AFH(Adaptive FrequencyHopping 自适应跳频)被确认可用后。主设备将会发送LMP_set_AFH 和LMP_channel_classification_req请求。
Step 6:若需要授权,控制器将会为这个连接向host请求Link Key。
Step 7a:如果链接需要授权且没有公用的link key,接下来将会是pairing过程。
LM会向host请求link key,如果host给的是Negative 回复,LM将会向host请求PIN。
Host端请求结束后,随后远程端也会产生PIN请求。链接的授权都是基于请求到的PIN。最后两端都会将link Key通知到各自的host保存,为以后的链接使用。所以配对过程实际上是获取Link Key的过程!
Step 7b:如果两端有共用的link key存在,那么不需要配对过程!
LM向host请求link key时,如果得到的是positive回复,将会直接使用回复的link key进行授权。
Step 8:一旦完成配对和授权,就会开始加密。
下图显示的是设置一个加密的点对点连接。
Step 9:两端的LM都会向各自的host发送LMP_setup_complete事件。通过LMP_setup_complete事件将底层的连接handle发送给上层,介此为止建立的链接才可以用来发送上层的数据。
HCI_Connection_Complete包如下:
上图是某个手柄连接到主机后,主机host收到controler的HCI_Connection_Complete事件。
Step 10:若需要断开链接,两端设备都可以通过发送HCI_Disconnect 和LMP_detach来终止连接。
如下图所示:
详见Core_v4.1.pdf Vol 2 SYNCHRONOUS CONNECTION ESTABLISHMENT AND DETACHMENT 章节。
蓝牙核心-L2CAP文章已经介绍了信号包的格式。上层协议需发送数据时都需要在Master 和Salve之间建立对应的L2CAP通道,举个列子来说,SDP在获取信息时,会先在L2CAP层次建立连接通道,如下图所示:
如上图所示SDP首先会发送请求建立连接,待连接连接建立后才在建立的连接上交换数据,Connection Request对应的数据包格式如下:
某次SDP请求链接数据格式如下:
response如下:
至此两个设备的SDP已经建立了链接,SDP可以相互交换信息了。
其他的协议/profile也是类似!