BLE蓝牙的连接和配对过程 |
您所在的位置:网站首页 › 蓝牙配对无法通信的原因 › BLE蓝牙的连接和配对过程 |
一 连接
同一款手机,为什么跟某些设备可以连接成功,而跟另外一些设备又连接不成功?同一个设备,为什么跟某些手机可以建立连接,而跟另外一些手机又无法建立连接?同一个手机,同一个设备,为什么他们两者有时候连起来很快,有时候连起来又很慢?Master是什么?slave又是什么?什么又是Connection event和slave latency?希望这篇文章能帮助你回答上述问题。 1 BLE连接示例假设我们有一台手机A(以安卓手机为例),一个设备B(设备名称:Nordic_HRM),如下所示,我们可以通过安卓设置菜单里面的蓝牙界面,让两者连接起来。 打开安卓设置菜单选择“蓝牙”条目打开蓝牙等待系统搜索结果,不出意外的话,设备“Nordic_HRM”会出现在结果列表中点击“Nordic_HRM”,手机将与此设备建立连接![]() 在手机跟设备B建立连接之前,设备B需要先进行广播,即设备B(Advertiser)不断发送如下广播信号,t为广播间隔。每发送一次广播包,我们称其为一次广播事件(advertising event),因此t也称为广播事件间隔。虽然图中广播事件是用一根线来表示的,但实际上广播事件是有一个持续时间的,蓝牙芯片只有在广播事件期间才打开射频模块,这个时候功耗比较高,其余时间蓝牙芯片都处于idle状态,因此平均功耗非常低,以Nordic nRF52810为例,每1秒钟发一次广播,平均功耗不到11uA。 根据蓝牙spec规定,advertiser发送完一个广播包之后150us(T_IFS,该值称为帧间隔,是指在同一个信道上连续两帧之间的间隔详见: 蓝牙核心卷,Vol 6, Part B,4.1.1),advertiser必须开启一段时间的射频Rx窗口,以接收来自observer的数据包。Observer就可以在这段时间里给advertiser发送连接请求。如下图所示,手机在第三个广播事件的时候扫到了设备B,并发出了连接请求conn_req。 注:图中M代表手机,S代表设备B,M->S表示手机将数据包发给设备B,即手机开启Tx窗口,设备B开启Rx窗口;S->M正好相反,表示设备B将数据包发给手机,即设备B开启Tx窗口,手机开启Rx窗口。 如图所示,手机在收到A1广播包ADV_IND后,以此为初始锚点(这个锚点不是连接的锚点),T_IFS后给Advertiser发送一个connection request命令,即A2数据包,告诉advertiser我将要过来连你,请做好准备。手机在发完连接请求之后会被强制延时1.25ms,紧接着是发送窗口偏移,和发送窗口。发送窗口偏移可以是0到连接间隔之间的任意值,但必须是1.25ms的整数倍。从发送窗口开始从设备必须打开RX窗口用来接收手机发过来的P1数据包。如果发送窗口结束还没有收到P1数据包,那么从设备终止监听,并会在下一个连接间隔后再次尝试。从P1开始使用数据通道。Advertiser根据connect_req命令信息做好接收准备,connect_req包含如下关键信息: Transmit window offset,定义如图5所示Transmit window size,定义如图5所示connect_req数据包完整定义如下所示![]() ![]() connect_req其实是在告诉advertiser,手机将在Transmit Window期间发送第一个同步包(P1)给你,请在这段时间里把你的射频接收窗口打开。设备B收到P1后,T_IFS时间后将给手机回复数据包P2。一旦手机收到数据包P2,连接即可认为建立成功。后续手机将以P1为锚点(原点),Connection Interval为周期,周期性地给设备B发送Packet,Packet除了充当数据传送功能,它还有如下两个非常重要的功能: 同步手机和设备的时钟,也就是说,设备每收到手机发来的一个包,都会把自己的时序原点重新设置,以跟手机同步。告诉设备你现在可以传数据给我了。连接成功后,BLE通信将变成主从模式,因此把连接发起者(手机)称为Master或者Central,把被连接者(之前的Advertiser)称为Slave或者Peripheral。BLE通信之所以为主从模式,是因为Slave不能“随性”给Master发信息,它只有等到Master给它发了一个packet后,然后才能把自己的数据回传给Master。对于主设备而言,连接请求一旦发出就认为连接已经建立。当从设备收到连接请求时,它也认为自己已经处在连接之中,连接已经创建,但不能证明完全确立。 4 连接失败有如下几种典型的连接失败情况: 如图5所示,如果slave在transmit window期间没有收到master发过来的P1,那么连接将会失败。此时应该排查master那边的问题,看看master为什么没有在约定的时间把P1发出来。如果master在transmit window期间把P1发出来了,也就是说master按照connect_req约定的时序把P1发出来了,但slave没有把P2回过去,那么连接也会失败。此时应该排查slave这边的问题,看一看slave为什么没有把P2回过去如果master把P1发出来了,slave也把P2回过去了,此时主机还是报连接失败,这种情况有可能是master软件有问题,需要仔细排查master的软件。还有一种比较常见的连接失败情况:空中射频干扰太大。此时应该找一个干净的环境,比如屏蔽室,排除干扰后再去测试连接是否正常。 5 连接事件连接事件(Connection events) 连接成功后,master和slave在每一个connection interval开始的时候,都必须交互一次,即master给slave发一个包,slave再给master发一个包,整个交互过程称为一个connection event。蓝牙芯片只有在connection event期间才把射频模块打开,此时功耗比较高,其余时间蓝牙芯片都是处于idle状态的,因此蓝牙芯片平均功耗就非常低,以Nordic nRF52810为例,每1秒钟Master和Slave通信1次,平均功耗约为6微安左右。Master不可能时时刻刻都有数据发给slave,所以master大部分时候都是发的空包(empty packet)给slave。同样slave也不是时时刻刻都有数据给master,因此slave回复给master的包大部分时候也是空包。另外在一个connection event期间,master也可以发多个包给slave,以提高吞吐率。综上所述,连接成功后的通信时序图应该如下所示:
从设备延时(Slave latency) 图10中出现了slave latency(slave latency = 2),那么什么叫slave latency? 如前所述,在每一个connection interval开始的时候,Master和Slave必须交互一次,哪怕两者之间交互的是empty packet(空包),但如果slave定义了slave latency,比如slave latency = 9,此时slave可以每9个connection interval才回复一次master,也就是说slave可以在前面8个connection interval期间一直睡眠,直到第9个connection interval到来之后,才回复一个packet给master,这样将大大节省slave的功耗,提高电池续航时间。当然如果slave有数据需要上报给master,它也可以不等到第9个connection interval才上报,直接像正常情况进行传输即可,这样既节省了功耗,又提高了数据传输的实时性。 7 GAP层角色总结对上面提到的手机和设备B,在BLE通信过程中,随着时间的推移,他们的状态在发生变化,两者的关系也在发生变化,为此蓝牙spec根据不同的时间段或者状态给手机和设备B取不同的名字,即GAP层定义了如下角色: advertiser。 发出广播的设备observer或者scanner。可以扫描广播的设备initiator。能发起连接的设备master或者central。连接成功后的主设备,即主动发起packet的设备slave或者peripheral。连接成功后的从设备,即被动回传packet的设备图11通过时间把observer,initiator和central串起来了,其实这三个角色是相互独立的,也就是说一个设备可以只支持observer角色,而不支持initiator和central角色。同样,图11也把advertiser和peripheral串起来了,其实advertiser和peripheral也是相互独立的,即一个设备可以只作为advertiser角色,而不支持peripheral角色。 区别于传统蓝牙的配对过程,BLE的配对过程发生在连接过程之后。 配对是一个三阶段的过程。前两个阶段是必须的,第三阶段是可选的。 第一阶段:配对特征交换第二阶段:短期秘钥(STK)生成第三阶段: 传输特定秘钥分配STK生成规则 Just work: 没有加密 TK=0x00passkey entry: 密码输入如果 passkey 是 ‘019655’ TK的值就是0x00000000000000000000000000004CC7。 将输入的值作为一个6位数的十进制,转换成16字节的十六进制。OOB: 带外的TK值是一个16字节的随机数,通过非BLE的方式传递给对端。 2.1 第一阶段设备首先在配对特征交换阶段交换IO能力来决定在第二阶段使用下面哪种方法: JustWorks:只工作PasskeyEntry:输入密码OutOfBand(OOB):带外LE Legacy Pairing - Just Works Just Works方式不能抵抗窃听者和中间人攻击,只有在配对过程时没有遭受攻击,后面加密的链路的数据传输才是可信的。安全级别很低。 LE Legacy Pairing - Passkey Entry 这种方式通过输入6位数字的方式来进行配对,生成STK。6位数是随机产生的在000000到999999之间的数值,这个数值相当于一个TK,比如远端显示这个数字,需要在本地端输入这个数字给本地设备与远端配对。如输入019655,那此时的临时Key–TK是:0x00000000000000000000000000004CC7。 Out of Band 带外 这种方式是通过BLE之外的,设备上的其他方式来获取这个OOB data,比如通过IR红外,或其余的方式,因此对于蓝牙窃听者/攻击者而言这个data的传输是不可见的了,因此会显得要安全些。 2.1.1 配对请求的数据格式1. IO capabilities表明输入,输出的能力 输入是按键、键盘,输出是显示数字用的界面。 0x00 DisplayOnly 只能是显示000000 ~ 999999的数字0x01 DisplayYesNo 显示Yes/No 的按钮0x02 KeyboardOnly 只能是输入000000 ~ 999999的数字0x03 NoinputNoOutput 没有输入也没有显示,只能用Just work工作方式0x04 KeyboardDisplay 能输入000000 ~ 999999的数字和输出2. OOB data flag 0x00 OOB 数据没有发送0x01 OOB 数据通过远端设备发送(如IR)0x02-0xFF 保留3. 身份验证请求 Bonding_Flags b1b0 Bonding Type 00 No Bonding01 Bonding10 Reserved11 ReservedMITM MITM域设置为1为请求MITM(中间人介入)保护,否则设置为0. 设备将标志设置为1为STK请求认证的安全属性。 选择Key生成的方法 如果auth Req中MITM没有,则说明不需要人参与中间,所以IO capabilities会被忽略,只用Just Works就OK了。 如果有OOB data,auth Req将可直接忽略,会直接选择OOB的方式了。 SCSC字段是一个1位标志,设置为1以请求LE安全连接配对,否则应根据发起方和响应方支持的功能将其设置为0,可能的结果配对机制为:如果两个设备均支持 LE安全连接,使用LE安全连接; 否则,请使用LE旧式配对。 Keypresskeypress字段是一个1位标志,仅在Passkey Entry协议中使用,而在其他协议中将被忽略。 当双方将该字段设置为1时,应使用SMP配对按键通知PDU生成并发送按键通知。 4. MaximumEncryptionKeySize 最大秘钥长度,7到16字节之间 5. InitiatorKeyDistribution 发起者的秘钥分配,该域表明秘钥初始化设备请求分配使用。 配对请求命令中的“生成”字段由主机使用,以请求发起者向响应者分发或生成哪些密钥。 6. ResponderKeyDistribution 响应者的秘钥分配,该字段表明秘钥初始化设备请求响应设备来分配秘钥分配使用。 2.1.2 配对请求实例1. Code (1 octet) 0x01 Pairing Request 2. IO Capability (1 octet) 0x03 NoInputNoOutput: 用just work 认证方式 3. OOB data 0x00 OOB(out of band) 没有带外认证, 带外这种方式是通过BLE之外的,设备上的其他方式来获取这个OOB data,比如通过IR红外,或其余的方式,因此对于蓝牙窃听者/攻击者而言这个data的传输是不可见的了,因此会显得要安全些。 4. AuthReq (1 octet) AuthReq字段是一个位字段,指示STK和LTK以及GAP绑定信息的请求安全属性 0x01 :表示绑定 5. MaxEncKeySize 0x10 表示最大认证key大小是0x10个字节 6. InitiatorKeyDistribution 该域表明秘钥初始化设备请求分配秘钥分配使用。 7. ResponderKeyDistribution 001 该字段表明秘钥初始化设备请求响应设备来分配秘钥分配使用。 2.1.3 从设备向主设备向发送配对回复报文具体字段含义参考 配对请求报文。 2.2 第二阶段 2.2.1 配对确认第一阶段的配对特征交换成功之后,用来启动STK生成。该命令被两个对等设备使用,来向对等设备发送确认值。初始化设备通过向响应设备发送配对确认命令启动STK生成。 报文格式 启动STK的生成,这一部分可简述为以下步骤的实现 Initiator生成128-bit随机数Mrand,并使用这个Mrand结合一些其他的输入,使用密码工具箱中c1计算出一个128-bit的Mconfirm值: Mconfirm = c1(TK, Mrand, Pairing Request command, Pairing Response command, initiating device address type, initiating device address, responding device address type, responding device address)Responder也生成一个128-bit随机数Srand,并使用这个Srand结合一些其他的输入,使用密码工具箱中c1计算出一个128-bit的Sconfirm值: Sconfirm = c1(TK, Srand, Pairing Request command, Pairing Response command, initiating device address type, initiating device address, responding device address type, responding device address) Initiator将其计算的Mconfirm值通过Pairing Confirm包发送给Responder,而Responder也将其计算的Sconfirm值通过Pairing Confirm包发送给Initiator;Initiator收到Sconfirm后,再将Mrand值通过Pairing Random包发送给Responder;Responder收到Mrand值后计算它的Mconfirm值,再跟前面那个Initiator送过来的Mconfirm值进行比较,若不同说明配对失败了。若相同,则Responder也会将它的Srand值通过Pairing Random包发送给Initiator;而Initiator也会计算收到的Srand值的Sconfirm值,并跟前面那个Responder送过来的Sconfirm值进行比较,若不同说明配对失败了,若相同,继续。报文实例 主设备向从设备发送配对确认报文,从设备也向主设备发送配对确认报文。 该命令用来由初始化和响应设备发送,用来计算在配对确认命令中的确认值的随机数。 报文数据格式 报文实例 主设备向从设备发送配对随机值报文,从设备也向主设备发送配对随机值报文。 所有的键和值都由主从设备分发。 要分发的密钥由配对请求和配对响应的密钥分发参数决定, 配对请求和配对响应来自第一阶段配对特征交换 BLE的SMP的一些Key相关定义 Long Term Key (LTK):加密链路用,128-bit; Encrypted Diversifier (EDIV):在LE legacy pairing过程中,用于识别LTK分发,16-bit; Random Number (Rand):在LE legacy pairing过程中,用于识别LTK分发,64-bit。 Identity Resolving Key (IRK):用于生成和解析random address用的,128-bit; AddrType (1 octet) 如果BD_ADDR是公共设备地址,则AddrType应设置为0x00。 如果BD_ADDR是静态随机设备地址,则AddrType应设置为0x01。 BD_ADDR(6个八位字节)此字段设置为分发设备的公共设备地址或静态随机地址。 Connection Signature Resolving Key (CSRK):用于对数据进行签名已经验证签名数据,128-bit; 2.3.2 特定key分发原因密钥分发阶段的从设备将密钥发送给主设备,这样就可以对重新连接进行加密,并解析其随机地址。或者,主设备可以验证来自从设备的签名数据,主设备也可以向从设备提供密钥,这样,如果角色互换,可以对重连接进行加密,可以解析主设备的随机地址,或者从设备可以验证来自主设备的签名数据。 三 绑定就是将配对阶段产生的一系列key 保持到flash中,以便后续使用。 以上这个过程的报文交互如下图, |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |