GAP层(Generic access profile-通用访问配置文件)。GAP是对LL层payload(有效数据包)如何进行解析的两种方式的一种,而且也是最简单的一种。GAP简单的对LL payload进行一些规范和定义,因此GAP能实现的功能极其有限。GAP目前主要用来进行广播,扫描和发起连接。GAP保证了不同的BLE设备可以互相发现对方并建立连接。
GAP定义了蓝牙设备如何发现和建立与其他设备的安全或不安全连接。它处理一些一般模式的业务,比如询问、命名和搜索,还处理一些安全问题,比如担保。同时还处理一些有关连接的业务,比如链路建立、信道和连接建立。GAP规定的是一些一般性的运行任务。因此,它具有强制性,并作为所有其他蓝牙应用规范的基础。GAP是所有其他配置文件的基础,它定义了在蓝牙设备之间建立基带链路的通用方法,除此之外,GAP还定义了下列内容:
GAP是应用层能够直接访问BLE协议栈的最底层,它包括管理广播和连接事件的有关参数。GAP模块代表了所有蓝牙设备的共用基础功能,如传输,协议或者应用规范所使用的模式和访问过程。GAP的服务包括设备发现,连接方式,安全,认证,关联模型和服务发现等。
总之一句话,GAP是保证BLE设备能互相发现和连接的规范。GAP就好比一种语言,大家都说同一种语言才能相互听懂,相互知道说的是什么。否则就只能大眼瞪小眼。
BLE协议栈的GAP层负责处理设备的接入方式和过程,包括设备发现,链路建立,链路终止,启动安全功能,设备配置。
GAP还定义了以下四种角色类型:
广播者(Broadcaster):用于只通过广播发送数据的应用。广播发送者,是不可连接的设备。广播者角色只是广播信息而不接受信息(ibeacon类似应用)。
观察者(Observer):用于接收广播数据的应用。扫描广播,不能够启动连接。观察者只监听空气中的事件(抓包器)。
外围设备(Peripheral):用于通过广播发送数据并且可以建立链路的应用。广播发送者,是可连接的设备,在单一链路层连接时作为从机。
中央设备(Central):用于接收广播数据并且建立一条或多条链路的应用。扫描广播启动连接,在单一或多链路层连接时作为主机,支持三个同时连接。
GAP层作为蓝牙协议层的组成模块,如下图所示,虚线框内的部分为蓝牙协议层。Application在蓝牙协议层之上,baseband/RF位于蓝牙协议层之下。GAP层给application提供访问Upper stack的接口。
GAP提供如下功能
广播(Advertising):设置和获取广播参数,启动和停止
扫描(Scan):设置和获取扫描参数,启动和停止
连接(Connection):设置连接参数,创建连接,终止连接,更新连接参数
配对:设置配对参数,启动配对。使用passkey entry方式时输入/显示passkey,删除绑定设备密钥
密钥管理:根据设备地址和地址类型查找密钥,保存/加载绑定设备信息的密钥,解析random address
其他:
设置GAP公共参数,例如外貌和名字。
获取支持的最大BLE链路数目
修改白名单(white list)
生成/设置本地设备random address
配置本地设备identiy address
广播
中央设备能够与外围设备建立连接,外围设备必须处于广播状态,它每经过一个时间间隔发送一次广播数据包,这个时间间隔被称为广播间隔。他的范围是20ms到10.24s。广播间隔影响建立连接的时间。
中央设备在发送一个连接请求来发起连接之前,必须接收到一个广播数据包。外围设备发送一个广播数据包之后一小段时间内只监听连接请求。
一个广播数据包最多能携带31字节的数据,它通常包含用户可读的名字、关于设备发送数据包的有关信息、用于表示此设备是否可被发现的标志等类似的标志。
当中央设备接收到广播数据包后,它可以发送请求更多数据包的请求,称为扫描回应。如果它被设置成主动扫描。外围设备将会发送一个扫描响应作为对集中器请求的回应。扫描回应最多可以携带31字节的数据。
扫描
扫描是中央设备监听广播数据包和发送扫描请求的过程。它有2个定时参数需要特别注意:扫描窗口和扫描间隔。
对于每一个扫描间隔,中央设备扫描的时间等于一个扫描窗口,这就意味着如果扫描窗口等于扫描间隔,那么集中器将处于连接扫描之中。扫描窗口和扫描间隔之比称为扫描占空比。
连接
中央设备和外围设备第一次交换数据定义为连接状态。在一个连接状态中,中央设备将会在一个特定定义的间隔从外围设备请求数据,这个间隔称为连接间隔,它由中央设备决定并应用于连接,但是外围设备可以发送连接参数更新请求给中央设备。根据蓝牙核心规范,连接间隔必须在7.5ms到4S之间。
如果外围设备在一个时间帧内没有回应集中器的数据包,被称为连接监管超时,连接则被认为丢失。
可以通过在每一个连接间隔中传输多个数据包以获得更高的数据吞吐量(IOS一次连接间隔最多可以交互4次,安卓为6次)。在蓝牙5.0里,每个传输数据包最多可以写到247个字节的应用数据。但是如果电流消耗是重点,同时外围设备也没有数据要发送,则可以忽略一定数量的连接间隔,这个忽略连接间隔的数目称为从机延迟(从机潜伏)。
在一个连接中,除了广播信道,设备间在频带的所有信道中进行通信。
GAP层设备状态由advertising、scan、connection组成。每个状态都有相应的子状态,
advertising
advertising有四个子状态,分别为idle、start、advertising和stop。
scan
scan状态有四个子状态,idle、start、scanning和stop。
GAP在启动连接时会负责BLE连接的安全功能。只有对通过身份验证的连接而言的某些数据是可读或可写的。一旦形成一个连接,两个设备可以通过一个过程进行连接,称为配对。进行配对时,密钥建立加密或认证的链接。例如当两个设备要建立配对关系时,外围设备需要中央设备提供密钥以完成配对。这个密钥可以是固定值或随机值。中央设备发送正确的密钥后,两台设备交换安全密钥并验证链接。
在许多情况下,两个设备会经常建立连接和断开连接。BLE具有一个安全功能,允许两个设备在配对的时候给对方一个长久的安全密钥。此功能被称为绑定。绑定后的两个设备每次重连时能够迅速重新确立加密和认证,并且不需要经过充分的配对过程,只需要提供他们存储的长期密钥信息即可。
加密方式大概分为一下几种
不允许连接
无安全要求(可直接连接)
加密连接
MITM(man in the middle-中间人攻击)保护
LESC(LE secure connections-)加密
签名
设备名称
当我们需要查找蓝牙设备的时候,大部分情况都是通过设备名称来查找的。协议栈也是支持用户自行修改设备名称的。在设置的时候可以设置short_name和full_name。
short_name:可以成为可选名称,字面意思上可以理解为名称的简写。当一个名称比较长的时候,由于广播的信息容量是有限的。要留空间放置其他信息,没有那么多空间显示全名,因此APP显示的时候为简称。
full_name:如果名称不是很长,广播数据可以容纳。那么可以通过GAP设置全名显示。
设备外观
当我们在搜寻蓝牙的时候,不但可以找到蓝牙设备的名称,还可以查看到蓝牙设备的外观。外观是什么,就决定了我们找的设备是什么。例如未知、键盘、鼠标、温度计、手表等等
在一个典型的蓝牙系统中,外围设备发送具体的广播数据让所有中央设备知道它是一个可连接的设备。广播内容包含设备地址,还包含了一些额外的数据,比如设备名称。中央设备接收到广播之后发送一个搜索请求给外围设备,外围设备答复一个搜索应答,这就是设备发现的过程。
设备发现之后,中央设备就知道外围设备是一个可连接的设备。中央设备可以发送一个建立链接的请求给外围设备,开始进行主机和从机设备的互联。
在一个连接中,包含了如下参数:
连接间隔:
在一个BLE连接中,使用跳频机制,这样两个设备之间可以在一个特定的通道上进行数据收发。在一个特定的时间之后,会跳到一个新的通道上,LL层负责通道切换。这个发现设备并收到数据的事件,就被称为连接事件。
尽管没有应用程序数据需要收发,两个设备之间仍然需要交换链路层数据来保持连接。连接间隔是两个连接事件之间的时间,使用一个单元是1.25ms的步进。连接间隔从最小值6(7.5ms)到最大值3200(4.0S)。
不同的应用需要不同的连接间隔,一个长时间的连接间隔将会节约更多的能量,因为设备可以在两个连接事件之间睡眠更长的时间。但是他会导致数据发送不及时。如果有数据要发送,那么只能等下一个连接事件到来时才能被发送。
值得注意的是,连接间隔参数是中央设备进行设置,外围设备只是负责执行。
从机潜伏周期:
这个参数描述了从机跳过连接事件的次数。这使外围设备具有一定的灵活性,如果它不具有任何数据传送,它可以选择跳过连接事件,并保持睡眠,从而提供了一些积蓄力量。这一决定取决于外围设备。也可以成为从机延迟,从设备能够忽略主设备的链接事件的最大值。比如:从设备延迟为6的话,那么从设备每隔6个锚点可以监听到主设备发送过来的数据包。如果从设备延迟为0,从设备在每个锚点都可以监听主设备的数据包。
监督超时:
这是两个成功的连接事件之间间隔的最大值。如果超过这个时间还未出现成功的连接事件,那么设备将会考虑失去连接,返回一个未连接状态。这个参数值使用10ms的步进。监督超时时间从最小10(100ms)到最大3200(32.0s)。监督超时时间必须大于有效连接事件。
有效连接事件时间 = 连接间隔 * (1 + 从机延迟值)。
连接间隔、潜伏周期的不同组合,有好有坏,而如何组合,需要根据实际的应用场景而定。例如短连接间隔,功耗高,数据吞吐量高,发送等待时间短。长链接间隔,功耗低,数据吞吐量低,发送等待时间长。低潜伏值,从机在没有数据发送的情况下功耗高,但从机可以快速的收到主机的数据。高潜伏值,从机在没有数据发送的情况下可以低功耗。但从机无法及时收到主机的数据,但主机能及时收到从机的数据。
在某些情况下,中央设备请求与外围设备建立链接包含的连接参数对外围设备而言是不利的。此时,外围设备可以在连接过程中改变连接参数。这个取决于外围设备的应用程序。外围设备可以通过设置连接参数更新请求,请求中央设备改变连接参数。这个请求包含四个参数:最小链接间隔、最大链接间隔、从机潜伏周期、连接超时时间。这些值代表了外围设备针对连接的期望参数,连接间隔是以范围的形式提供的。当中央设备接收到这个请求后,中央设备有权利决定是接受还是拒绝这些参数。
每个尖刺就是一次连接事件(Connection events),两个连接事件的中间为sleeping休眠时间。从图中也可以看出,在每次从机的连接事件中,首先是射频接收,然后才是射频发送。其实也是为了保证主机和从机的射频时序是相匹配的。设备在建立链接之后的大多数事件都是处于sleeping。这种情况下耗电量比较低,只有在连接事件(connection events)中,耗电量才相对较高,但持续时间很短。这也是为什么BLE非常省电的原因之一。
在两个connection interval连接间隔之间,BLE会使用跳频机制。两个设备使用特定的信道发送和接收数据,然后过一段时间后,再使用新的信道(BLE协议栈的LL链路层处理信道的切换)。两个设备在切换信道后发送和接收数据被称为一个连接事件。尽管没有应用数据被发送或接收,两个设备仍旧会交换链路层数据(空包 Empty PDU)来维持连接。在每个连接事件中,都是由主机发送,从机回复。
当大数据传递时,通讯数据包是连续传递的。主机会选择最小连接间隔来进行通讯。无数据传递时,主机会选择最大链接间隔来定期询问从机状态,以保持连接不中断。当从机向主机发送一个连接参数更新请求后,主机会按照请求,修改连接间隔。但这个时间需要在主机设置的最大和最小连接间隔之内。
从机设备没有数据要发时,跳过一定数目的连接事件Connection Event。范围0-499。设置为0则每次连接间隔都连接。数字越小,通讯速度越快,但功耗越高。注:如果在距离远或干扰大的情况下,当无数据通信时,这个值设置大,可以减少掉线的概率。比如防丢器:如果这个参数设置为0,表示规定时间内必须响应从机,不然就以为是蓝牙断开了。如果设置为3,假设信号不好时,中间丢了3个包,只接受到了1个就表示连接正常。因为他会跳过其中3个,保证了不掉线的概率。
从机设备没有数据要发时,跳过一定数目的连接事件Connection Event。范围0-499。设置为0则每次连接间隔都连接。数字越小,通讯速度越快,但功耗越高。注:如果在距离远或干扰大的情况下,当无数据通信时,这个值设置大,可以减少掉线的概率。比如防丢器:如果这个参数设置为0,表示规定时间内必须响应从机,不然就以为是蓝牙断开了。如果设置为3,假设信号不好时,中间丢了3个包,只接受到了1个就表示连接正常。因为他会跳过其中3个,保证了不掉线的概率。
允许从机在没有数据发送的情况下,跳过一定数目的连接事件。在这些连接事件中,不必回复主机的包。这样就更省电。
超时时间,就是两个设备在连接的这段时间没有发生通讯而导致连接自动断开的值。Range(10ms-32s)。用在信号不太好的情况下,给对方一点时间,超过这个时间通讯就建立失败。
连接间隔、从机潜伏周期以及超时时间这三者必须满足以下公式:
超时时间 > (1 + 从机潜伏周期) * 连接间隔。否则连接就会不正常断开。
这三个连接参数不同情况下对通信速率和功耗的影响:
连接间隔缩短,主机和从机通信更加频繁。提高了数据吞吐速度,缩短了数据发送的时间,增加了功耗。
连接间隔增长,通信频率降低,数据吞吐速度降低,增加了数据发送的时间,降低了功耗。
潜伏间隔减少,每次连接事件中都回复主机包,功耗增加,数据发送速度提高。
潜伏间隔增加,功耗降低,数据发送速度降低。
蓝牙协议栈定义了主机决定连接参数的值(连接间隔、潜伏周期、超时时间),从机可以请求更新这些参数,但是由主机决定是否接受,接受的值是多少。所以会出现手机接受参数后和从机请求的参数有偏差的情况,甚至是拒绝(IOS)。安卓和IOS都是在手机和设备建立链接时就会默认设置这些参数,APP开发时无法修改这些参数,这些默认参数是由手机厂商决定的。