一.概述
在windows下寻找远端蓝牙设备,从最开始的inquiry寻找设备,到连接设备,到最后配对完成,整个HCI层所发的command和event以及Data包可以反应整个蓝牙的inquiry,pair等原理和过程。这篇笔记就是分析这个过程,结合Spec的具体描述,以此熟悉蓝牙的配对流程。
二.Inquiry流程
这个流程主要是inquiry远端的蓝牙设备,不进行连接,只进行发现。
1.Write_Inquiry_Transmit_Power_Level command
01011001 00001100 00000001 00000000
可以看出首先是设置inquiry的发射功率。
OpCode为0x0c59
total_lenrth为0x01
发射功率为0x00db
command completed event:
00001110 00000100 00000010 01011001 00001100 00000000
这个event有三个parameters:Num_HCI_Command_Packets,Command_Opcode和Return_Parameters
EventCode为0x0e,
total_length为0x04
Number HCI Command Packets: 2
OpCode为0x0c59
status为0,表示设置成成功。
2.Inquiry command event
设置完inquiry的Tx Power后,就可以进行inquiry了。Inquiry的三个参数为LAP, Inquiry_Length和
Num_Responses
00000001 00000100 00000101 00110011 10001011 10011110 00000011 00000000
OpCode:0x0401
Total_length:0x05
LAP:00110011 10001011 10011110(GIAC) //这是通用的呼叫的LAP为0x9e8b33
Inquiry Length (sec): 0x03 //3 * 1.28 sec 总的inquiry时间
Num_Responses:0x00 //0x00表示在inquiry时间结束前不限制response的数量
command status event:
//注意这里没有返回command completed events,表示inquiry的过程正在进行,结束应该用Inquiry Complete event
00001111 00000100 00000000 00000010 00000001 00000100
这个event有三个parameters:Status, Num_HCI_Command_Packets, Command_Opcode
EventCode:0x0F
totalLength:0x04
status:0x00
Num_HCI_Command_Packets:0x02
Command_Opcode:0x0401
表示inquiry的command执行成功
3.奇怪的command completed event
Spec上指出在inquiry的过程中不会有command completed event产生,但FTS抓到两个command completed event,但是这连两个event的OpCode无效,这里不知道为什么,猜测被Host忽略掉了。
4.Inquiry Result with RSSI event
之后就是所有接收到inquiry的设备返回inquiry的结果,event为Inquiry Result with RSSI。以下是其中的一个:
该Event的参数为:
Num_responses,
BD_ADDR[i],
Page_Scan_Repetition_Mode[i],
Reserved[i],
Class_of_Device[i],
Clock_Offset[i],
RSSI[i]
00100010 00001111 00000001 01100100 01110110 01011000 00001101 10110111 10011100 00000001 00000010 00000100 00000001 00000010 11010010 01010000 10110010
EventCode:0x0F:0x22
totalLength:0x0F = 15
Num_responses:0x01
BD_ADDR[i] = 01100100 01110110 01011000 00001101 10110111 10011100 = 0x9c-b7-0d-58-76-64
Page_Scan_Repetition_Mode[i] = 00000001 = 0x01(R1)
Reserved[i] = 00000010 = 0x02 //保留
Class_of_Device[i] = 00000100 00000001 00000010 = 0x020104 //Computer,Handheld PC
Clock_Offset[i]:11010010 01010000 = 0x50d2
RSSI[i] = 10110010 = 0xb2(-78db)
以上反应了这个搜索到的设备的相关信息
5.Extended Inquiry Result event
紧跟在Inquiry Result with RSSI event后,可能有多个。这个event反应的设备的额外信息,例如设备名称。相比于Inquiry Result with RSSI event多了一个Extended_Inquiry_Response部分。如:
00101111 11111111 00000001 01110000 01010001 01000110 10000011 00010101 00000000 00000001 00000000 00000100 00000001 10111110 00101000 01110110 10110110 01010100 01010010 01001001 01010011 01010100 01000001 01001110 00101101 01010000 01000011 00000010 00001010 00000100 00000000 00000000 00000000 00000000 00000000 00000000 ........ 00000000
EventCode:0x0F:0x2F
totalLength:0xFF = 255 //减去15个字节剩下240个Extended Inquiry Response部分
Num_responses:0x01
BD_ADDR[i] = 01110000 01010001 01000110 10000011 00010101 00000000 = 0x00-15-83-46-51-70
Page_Scan_Repetition_Mode[i] = 00000001 = 0x01(R1)
Reserved[i] = 00000000 = 0x00 //保留
Class_of_Device[i] = 00000100 00000001 10111110 = 0xbe0104 //Computer,Handheld PC
Clock_Offset[i]:00101000 01110110 = 0x7628
RSSI[i] = 10110110 = 0xb6
以下是拓展部分:
Length:0x00001011 = 0x0b = 11
EIR Data Type:00001001 = 0x09(Complete Local Name)
EIR Data:01010100 01010010 01001001 01010011 01010100 01000001 01001110 00101101 01010000 01000011 00000010 00001010 00000100 00000000
转换成ascii即为:TRISTAN-PC
奇怪的是在这个名称后面有几个无法识别的字符:
猜测可能是指明名称的结束,收到event端的设备忽略即可吧,或者名称很奇怪?
可能有一系列的Extended Inquiry Result event,反映了不同的设备在响应主机的搜索。
6.inquiry completed event
这个event表示已经完成了整个的inquiry的过程。只有一个参数Status。如下:
00000001 00000001 00000000
event code:0x01
totalLength:0x01
status:0x00 成功
奇怪的是在这条event之后又产生了command completed event,和3中的情况一样,OpCode是不可识别的。。。
三.总结
以上是整个inquiry过程产生的command和event。首先通过Write_Inquiry_Transmit_Power_Level command设置inquiry的发射功率,然后通过inquiry command寻找设备,Inquiry Result with RSSI event返回设备的相关信息,包括蓝牙地址,class device等;Extended Inquiry Result event返回设别的额外信息,在这里是设备的名称;在inquiry length到达后,产生inquiry completed event表示inquiry整个过程的结束。
需要注意的是,返回的inquiry result可能是多个的,至于command completed event的产生,很是奇怪,Spec上指出inquiry的过程不会产生command completed event的,而且这些event里的OpCode部分是不可识别的,猜测Host会忽略这些没有作用的command completed event。
- 在HCI层ACL Connection的建立
一.概述 上一篇博文介绍的是inquiry的整个过程中HCI层的command和event.在寻找到有效的远端蓝牙设备后,开始建立ACL连接,这里仅仅反应HCI层的数据包,对于LM层和Base ...
- BLUETOOTH:HCI层编程
1. HCI层协议概述: Host Controller Interface(HCI) 就是用来沟通Host和Module.Host通常就是PC,Module则是以各种物理连接形式(USB,seri ...
- FTS抓包看蓝牙的SDP整个过程
1.概述 SDP是蓝牙的Service Discovery Protocol,用来发现远程设备能够提供的Service.它只负责发现对方支持的Service,不负责Service的具体实现. ...
- 【转】FTS抓包看蓝牙的SDP整个过程
原文网址:http://blog.sina.com.cn/s/blog_69b5d2a50101f23c.html 1.概述 SDP是蓝牙的Service Discovery Protocol,用 ...
- 第11节-BLE协议HCI层的硬件接口
本篇博客由韦东山视频整理所得 如何控制链路层让其发出广播包.数据包?通过HCI层向它发出命令,也可以通过ATT层.L2CAP层向LL层发出数据. 学习资料: 蓝牙协议core_v5.0.pdf < ...
- NGUI发布后UI层看不见的解决办法
NGUI发布后UI层看不见的解决办法 提示信息:You can'tplace widgets on a layer different than the UIPanel that manages th ...
- 第12节-BLE协议HCI层的数据格式
学习资料: 1. 蓝牙协议core_v5.0.pdf <Vol 2: Core System Package [BR/EDR Controller volume]>的“Part E: Ho ...
- FTS抓包看L2CAP Connection的建立(一)
一.概述 在前面的文章中介绍了inquiry和ACL connection的建立过程.这个连接建立后,L2CAP signaling channel(CID = 0x0001)就已经存在,可以 ...
- 第13节-BLE协议L2CAP层
学习资料:官方手册 Vol 3: Core System Package [Host volume] Part A: Logical Link Control and Adaptation Proto ...
随机推荐
- 属性动画PropertyAnimation
xml实现 <?xml version="1.0" encoding="utf-8"?> <set xmlns:android="h ...
- 关于LR中的EXTRARES
LoadRunner脚本之EXTRARES参数 EXTRARES:分隔符,表示标记下一个属性是资源属性的列表(list of resource attributes). [EXTRARES后的资源是由 ...
- Codeforces Round #328 (Div. 2)
这场CF,准备充足,回寝室洗了澡,睡了一觉,可结果... 水 A - PawnChess 第一次忘记判断相等时A先走算A赢,hack掉.后来才知道自己的代码写错了(摔 for (int i=1; ...
- General part中方向选取的作用
这个方向是零部件坐标系 part coordinate system, 也叫local part reference frame. 这个方向要注意, 因为质心的方位由它决定,同时下面的输入的转动惯量就 ...
- BZOJ2874 : 训练士兵
设$a[i][j]$表示$(i,j)$右下角要增加多少 $aj[i][j]=a[i][j]\times j$ $ai[i][j]=a[i][j]\times i$ $aij[i][j]=a[i][j] ...
- TYVJ P1001 第K极值 Label:水
背景 成成第一次模拟赛 第一道 描述 给定一个长度为N(0<n<=10000)的序列,保证每一个序列中的数字a[i]是小于maxlongint的非负整数 ,编程要求求出整个序列中第k大的数 ...
- MongoBD解决没有自动增长ID 的问题
Sequence Numbers:序列号传统的数据库中,通常用一个递增的序列来提供主键,在 MongoDB中用 ObjectId 的来代替,我们可以通过如下的函数来获取主键 function coun ...
- js for循环,为什么一定要加var定义i变量
我知道,有些人(譬如之前的我)写js的for循环时,都不习惯加上var,这当然是语法允许的.譬如下面. for(i=0;i<10;i++){//就不写成: var i=0 alert(i); } ...
- myeclipse 第一个web project
创建一个java project. 不行...js文件是javascript代码的文件.应该放在web目录下...java文件是后台管理的程序代码.放在src目录下...不同的... 那是不是把所 ...
- Java实战equals()与hashCode()
一.equals()方法详解 equals()方法在object类中定义如下: 代码 public boolean equals(Object obj) { return (this == obj); ...