蓝牙的构建过程是一个复杂的过程,即使是有相当工作和使用经验的人,也需要很好的理解才能理解。
平时,我们通过蓝牙耳机听音乐,与不同的设备共享文件、打电话时,都会有配对——连接——传输数据的过程。
配对其实是认证的过程。
1. 为什么不配对便无法建立连接?
任何无线通信技术都有可能被监听并解密,蓝牙SIG为了确保蓝牙通信的安全性,利用认证方式进行数据交换。 此外,为了便于使用,两个蓝牙设备之间的初始通信认证以配对的形式进行,配对后无需每次都确认后续的通信连接。 因此,认证码的生成从配对开始,通过配对在装置之间用PIN码建立约定的link key被用于为以后要建立的连接生成初始认证码。
因此,如果不配对,则无法在两个设备间建立认证关系,无法进行连接和之后的操作,因此配对在某种程度上保证了蓝牙通信的安全。 当然,这个安全保证机制比较容易解读。 现在很多个人机器都没有人机接口,所以PIN码是固定的,几乎都是设定为通用的0000和1234等,所以很容易推测,已经建立了配对和连接。
2. 蓝牙的连接过程
如今的蓝牙芯片供应商提供了强大的技术支持,并提供了完整的硬件和软件解决方案。 APP应用程序提供了用于实现基本协议栈的固件,提供了profile库和源代码,并规范了各种APP应用程序。 开发人员只需专注于APP应用程序开发即可。 对于蓝牙底部的东西,我往往不太清楚。 我以前也是这样的,最近在做自动搜索实现自动连接的APP展。 我发现果然有必要知道基础性的结构。
我们可以很容易地操作并在手机和免提设备之间建立连接,这个连接是怎么建立的呢?
首先,主设备(master,即发起连接的设备)寻呼,从属设备(slave,接收连接的设备)跳频寻呼slave,slave保持恒定当scan外出并建立ACL链路连接时,主机开始进行信道连接请求,即L2CAP的连接,在建立L2CAP的连接后,主机使用SDP调查从机的免提服务,并从那里获取rfcomm的信道号码然后建立了APP应用程序的连接。
即link establish-channel establish-rfcomm establish-connection
3. 广播数据分析
3.1 .发送广播包被称为广播发起者(advertisers ),通过广播信道接收广播包,但是不希望连接到广播发起设备的被称为扫描仪(scanner ),需要连接到另一设备的设备称为发起者如果advertiser正在使用可连接的广播事件,则启动器将在接收连接包的物理信道上启动连接请求,并在advertiser接受连接请求时终止广播事件,并启动新的连接事件建立连接后,启动器成为主设备,advertiser成为从设备。 连接事件用于在主从设备之间传输数据包。
连接进程:
广播者:广播包使用ADV_IND PDU标志;
扫描者(发送扫描请求(SCAN_REQ PDU )并请求关于广播者的信息的SCAN_REQ PDU ) )包括扫描者的设备地址;
启动器验证启动器是否通过发送连接请求(CONNECT_REQ PDU )进入连接状态且可以进行广播。
如图所示,SCAN_REQ_PDU的负载由扫描装置的地址(ScanA )和广播装置的地址(address )构成,ScanA是扫描装置的公用地址或随机地址(paranth )
图-扫描请求PDU负载
广播消息头部中的TxAdd指示扫描设备是公共地址还是随机地址。
TxAdd=0:公共地址。
TxAdd=1:随机地址。
RxAdd指示广播设备是公共地址还是随机地址。
RxAdd=0:公共地址。
RxAdd=1:随机地址。
3.2 .扫描响应
SCAN_RSQ_PDU负载由AdvA (广播设备地址)和ScanRspData (广播设备的公共或随机地址)组成,如下图所示
图 - 扫描响应PDU载荷广播报文的报头中的TxAdd指示了广播设备使用的是公共地址(Public Address)还是随机地址(Random Address)。
TxAdd = 0:公共地址。
TxAdd = 1:随机地址。
广播报文的长度域指示了载荷的字节数(AdvA和ScanRspData)。
3.3. SCAN_REQ和SCAN_RSP解析
3.3.1. 捕获SCAN_REQ
按照《蓝牙4.0BLE抓包(一)》中的描述进行抓包,下面是我们捕获一个心率计的SCAN_REQ包。
图4:捕获的SCAN_REQ包
3.3.2. 分析SCAN_REQ
为了方便分析,我们先取出这个SCAN_REQ包实际传输的数据,如图3中所示。心率计完整的广播报文如下:
D6 BE 89 8E 83 0C 7F 0F 72 DD DF 68 DA B5 E9 D2 CC F3 BD BF 27
在分析数据之前,再次说明:广播包含扫描请求和扫描响应,所以扫描请求和扫描响应得包格式遵循广播包的格式。
分析报文时,需要注意一下报文各个域的字节序。
3.3.2.1. 接入地址
D6 BE 89 8E:接入地址,对广播来说是固定值。注意一下这里的字节序,接入地址传输时是低字节在前的。
3.3.2.2. PDU
1). 83:广播报文报头。
bit0~bit3是0011,说明广播类型是SCAN_REQ,即扫描请求。
bit7(RxAdd)是1:说明广播设备使用的是随机地址。
bit6(TxAdd)是0:说明扫描设备使用的是公共地址。
2). 0C:长度,表示SCAN_REQ报文的长度是12个字节。
3). 7F 0F 72 DD DF 68:扫描设备的公共地址(报头里的TxAdd指示了这个地址是公共地址)。这里使用的实验设备是[艾克姆科技]的EN-nRF51DK开发板和小米3手机,扫描设备是小米3手机,在图3中可以看到该公共地址对应的是Xiao_mico_72。
4). DA B5 E9 D2 CC F3:广播设备的地址(报头里的RxAdd指示了这个地址是随机地址)。
3.3.2.3. 校验
BD BF 27:24字节CRC校验。
3.3.3. 捕获SCAN_RSP
按照《蓝牙4.0BLE抓包(一)》中的描述进行抓包,捕获一个心率计的SCAN_REQ包。
图 - 捕获的SCAN_RSP包
3.3.4. 分析SCAN_RSP
同样,在这里我们先取出SCAN_REQ包的数据,便于分析。
D6 BE 89 8E 44 06 DA B5 E9 D2 CC F3 61 6A 0F
3.3.4.1 接入地址
D6 BE 89 8E:接入地址,对广播来说是固定值。注意一下这里的字节序,接入地址传输时是低字节在前的。
3.3.4.2 PDU
1). 44:广播报文报头。
bit0~bit3是0100,说明广播类型是SCAN_RSP,即扫描响应。
bit6(TxAdd)是1:说明广播设备使用的是随机地址。
2). 06:长度,表示SCAN_ RSP报文的长度是6个字节。
3). DA B5 E9 D2 CC F3:广播设备的地址(报头里的RxAdd指示了这个地址是随机地址)。
3.3.4.3 校验
61 6A 0F:24字节CRC校验。
3.4.连接请求CONNECT_REQ
在低功耗蓝牙技术建立连接的过程中,设备都是成对出现的:master和slave设备。如果master希望与slave建立连接,master就需要发起连接请求(ConnectionRequest,CONNECT_REQ)因此master可以称之为连接发起者;同时,slave必须是可连接的并且具有解析连接请求CONNECT_REQ的能力,slave可以称之为广播者。图1是连接请求CONNECT_REQ的帧结构。
图1 CONNECT_REQ帧结构
其中,InitA是连接发起者的蓝牙设备地址,长度为6字节;AdvA是广播者的蓝牙设备地址,长度为6字节。除了InitA和AdvA之外,帧格式中最为重要的部分则是LLData,这一部分包含了在连接建立过程中所需要使用的有意义的参数。
为了更好的理解连接请求CONNECT_REQ,我们可以在日常生活中找到类似的一个例子,帮助我们理解它的含义。读者们很多应该都有过工作经验,在开始新的工作之前,都需要和雇主签署一份劳动合同,而CONNECT_REQ就是一份由“雇主”master提供的“劳动合同”,只需经过“雇员”slave确认,这份“合同”就开始生效,低功耗蓝牙技术的连接也就建立了。接下来我们就对“合同”中的各项条款逐条进行分析(如图2所示)。
图2 LLData示意图
(1)接入地址(AA:Access Address)
这份合同的第一条款就是为雇员分配一个公司内部的唯一识别码,类似于工号,雇员可以在公司内部使用这一工号;当雇员离开公司之后,唯一识别码自动失效;即使是这一雇员再次加入到这家公司,热情的唇彩的新工号也与旧的工号不同。类似的,在两个低功耗蓝牙技术设备建立连接之前,master设备负责生成接入地址,这一地址类似于一个4字节的随机数,当连接建立之后,master和slave都使用这一接入地址进行通信;当连接断开之后,接入地址自动失效。
(2)CRCInit(CRC初始值)
这份“合同”的第二条款是CRCInit,它就是雇员在公司内部的一个密钥,通过这个密钥,雇员可以访问公司内部的资源。对于低功耗蓝牙技术设备,master和slave使用CRCIinit来验证数据包的完整性。
(3)WinSize和WinOffset
合同的第三条款中规范了雇员首次来公司报到的时间以及今后每次工作的时长。WinSize和WinOffset在低功耗蓝牙技术连接中,也做了类似的定义。WinOffset定义了在CONNECT_REQ命令之后的一个通信窗口的偏移量,如图3所示。在slave设备收到CONNECT_REQ之后,slave设备需要占用一些时间、根据LLData参数进行一些相关的配置,因此,WinOffeset为slave设备进行此种操作提供了时间,transmitWindowOffset= WinOffset×1.25 ms。WinSize定义了设备每次开启收发机的窗口时间,无论是master还是slave,它们都遵循WinSize的定义,窗口时间transmitWindowSize=WinSize×1.25 ms。
因此,在CONNECT_REQ之后,第一个由master发送到slave的数据帧,我们称之为“锚点”(如图3所示),因为之后的所有的连接事件都以这一时刻为基准,呈现周期性变化。从红色框图中我们可以看到,第一个数据帧的时刻不能早于(1.25ms+transmitWindowOffset),同时也不能晚于(1.25 ms + transmitWindowOffset + transmitWindowSize)。
图3 发起连接时序图
(4)Interval, Latency & Timeout
一般情况下,人们的工作时间是朝九晚五,一周工作五天。但是在低功耗蓝牙技术的连接机制当中,我们采用了更加灵活的“弹性工作制”。对于低功耗蓝牙技术连接的弹性工作制,这里有三个参数需要了解,Interval,Lantency和Timeout。
图4 连接事件时序图
在连接建立之后,master和slave之间的数据交互我们可以称之为连接事件,连接事件的发生周期(connInterval)则是由Interval参数来进行设定,connInterval= Interval×1.25 ms, connInterval的取值范围则是在7.5 ms至4 s秒之间。因此,在确定了锚点之后,master和slave将按照connInterval确定的时间间隔进行数据的交互,如图4所示。
但是,对于低功耗蓝牙技术,低功耗的特性是需要特别考虑的,而且在实际的应用当中,不需要在每次connInterval都产生连接事件,因此引入了参数Lantancy,可以有效的减少连接事件的产生,connSlaveLatency= Latency。connSlaveLatency 定义了slave设备可以忽略多少个连续的连接事件,其不需要在这些被忽略的连接事件中侦听来自master的数据包,这也意味着slave设备不需要在每个连接事件产生的时刻都唤醒并打开射频接收机进行侦听,所以可以有效减少slave设备的功耗。这也是低功耗蓝牙技术能够实现其低功耗特性的一个重要的原因。
Timeout参数定义了连接超时的长度,connSupervisionTimeout= Timeout×10 ms,其取值范围在100 ms至32 s之间。不论是master还是slave,在其收到一个数据帧之后,如果等待了connSupervisionTimeout时长都没有下一个数据帧到来,则可以认为连接已经断开。在这里要强调的是,connSupervisionTimeout必须大于(1 + connSlaveLatency) × connInterval × 2,否则,slave设备即使是在Lantency状态,也会被误认为是连接超时,导致连接误断开。
(5)ChM & Hop
我们都知道,蓝牙使用的是跳频技术,当连接建立之后,master和slave设备就需要利用某种机制来在预先设定的信道图谱上、按照预先设定的跳频跨度进行跳频工作,信道图谱就来自ChM参数,每跳的跨度则来自于Hop参数。Hop是一个整数,取值范围在5至16之间。下面的公式提供了跳频的工作方式:
————————————————
版权声明:本文为CSDN博主「偏执灬」的原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/sinat_23338865/article/details/52189538