从蓝牙设备状态转换可以知道,蓝牙设备连接需经过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 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也是类似!