本文是参考一些博文和书籍做的笔记,如有不适联系删除
参考:https://www.cnblogs.com/iini/p/8977806.html
参考文章: 《BLE4.0 低功耗蓝牙 协议 总结 》
目录
1、广播
在广播事件中, 每一个广播事件都会在 3 个广播信道中进行数据传输, 而且每一个事件都是以最小的信道编号开始传输;也就是说当广播事件来了,这个 PDU 是依次从广播通道 37、 38、 39 中进行传输。并不是一起同时在三个信道一起广播;设备B不断发送广播信号给手机(Observer),如果手机不开启扫描窗口,手机是收不到设备B的广播的,如下图所示,不仅手机要开启射频接收窗口,而且只有手机的射频接收窗口跟广播发送的发射窗口匹配成功,而且广播射频通道和手机扫描射频通道是同一个通道,手机才能收到设备B的广播信号。也就是说,如果设备B在37通道发送广播包,而手机在扫描38通道,那么即使他们俩的射频窗口匹配,两者也是无法进行通信的。由于这种匹配成功是一个概率事件,因此手机扫到设备B也是一个概率事件,也就是说,手机有时会很快扫到设备B,比如只需要一个广播事件,手机有时又会很慢才能扫到设备B,比如需要10个广播事件甚至更多。
1.1、广播间隔
T_advEvent = advInterval + advDelay
T_advEvent 也就是图1中的 t ; advInterval 是 0.625ms 的倍数,在 20ms~10.24s 之间。如果广播类型是非定向扫描事件或者非定向不可连接广播事件,这个值不能小
于 100ms。如果广播事件类型是非定向可连接事件,这个是只需大于20ms 即可;
advDelay 是一个随机数,在 0ms~10ms 之间,在每一个广播事件中都有。 由于设备间的时钟会有不同程度的漂移,所以这个随机延时的作用不但能消除设备之间时钟漂移,还能避免相同信道及时间点上的冲突;
1.2、三个信道切换时间间隔
上面有说道广播事件之间有时间间隔,那么广播本身里面有 3 个信道进行数据传输,这 3 个信道之间的时间间隔是多少?在协议中有规定:也就是两个连续的通用广播之间的时间必须小于等于 10ms
1.3、广播事件
在广播状态下,链路层在广播事件中发送广播 PDU 。 广播事件共有 4 种:
- 非定向可连接事件(ADV_IND)
- 定向可连接事件(ADV_DIRECT_IND)
- 非定向不可连接事件(ADV_NONCONN_IND)
- 非定向扫描事件(ADV_DISCOVER_IND/ADV_SCAN_IND)
(1)非定向可连接事件(ADV_IND):这个报文发送之后可以接收由扫描者发送的(SCAN_REQ PDU)扫描请求, 或者由发起者发送的(CONNECT_REQ PDU)连接请求。 而接收后链路层需要早同一个信道上进行扫描者或者发起者的应答。 当接收的数据报文没能通过广播滤波政策, 要么就用下一个广播信道进行广播要么就关闭广播事件。后面都是以这个事件做解析
(2)定向可连接广播事件(ADV_DIRECT_IND)
这个广播是为了快速建立连接。这种报文包含两个地址:广播者地址和发起者的地址。 发起设备收到发给自己的定向广播报文后,可以立刻发送连接请求事件作为回应,并进入连接状态。定向广播事件有特殊的时序要求。完整的广播事件必须每 3.75ms之内重复一次。这一要求似的扫描设备只需扫描 3.75ms 便可以收到定向广播设备的消息。
(3)非定向不可连接事件(ADV_NONCONN_IND)
这是一个很奇葩的事件,它像是一个车模,大张旗鼓的告诉别人,但是不允许别人摸她,而这个事件比模特更加的奇葩,模特至少可以合个影,但是这个事件大声的告诉别人我在这里,之后就不搭理别人
了,不接受任何信息,只管自己在每个广播事件中发送数据。时间要求和通用广播事件一样。它只能根据主机的要求在广播态和就绪态之间切换,也是唯一可用于只有发射机而没有接收机设备的广播类型
(4)可发现不可连事件(ADV_DISCOVER_IND/ADV_SCAN_IND)
这个广播其实是一个非定向可发现的广播,它和通用广播的时间控制是一样的,应答也是 SCAN_REQ PDU 和 SCAN_RSP PDU,这个广播和通用广播的区别是,它不能建立连接, 只能处于广播态或者就绪态。这是一种适用于广播数据的广播形式,动态数据可以包含于广播数据中, 而静态数据可以包含于扫描响应数据之中。
2、扫描与应答
如果接收到的 SCAN_REQ PDU 通过了滤波政策,那么广播者需要在同一信道并且在接收到数据到发送 SCAN_RSP PDU 扫描应答报文的时间一定是 150±2 µs 完成。
3、建立连接
3.1、锚点
连接事件开始的点叫做锚点(The start of a connection event iscalled an anchor point)。主机在锚点开始连接事件,从机需要在锚点前进入侦听状态。在连接状态下锚点由从机接收的第一个连接事件报文决定,并决定了将来的锚点。
3.2、重要的时间参数
CONNECT_REQ PDU中包含了两个重要的参数,解析如下:
(1)Transmit window offset
transmitWindowOffset = WinOffset * 1.25 ms
它是传输窗口偏移的时间,同样这个值需要乘以 1.25ms 才是真正的传输窗口偏移时间。 这个参数其实只在第一连接事件发生前或者连接参数更新时用; 范围:[0, connInterval]
(2)Transmit window size 它为传输窗口的时间
transmitWindowSize = WinSize * 1.25 ms
它为传输窗口的时间,而且这个值乘以 1.25ms 才是真正的传输窗口时间 范围:[1.25ms,MIN(10ms, connInterval - 1.25 ms)]
(3)connect_Interval 这个就是传说中的连接间隔时间
connInterval = Interval * 1.25 ms
它是 1.25ms 的倍数,范围:[7.5ms,4.0S]
(4)Latency 从机潜伏次数
范围:[0, MIN(((connSupervisionTimeout / connInterval) - 1),500)]
(5)timeout 连接超时
如果连接状态下,很长时间都没有连接事件发生,或者连接事件发送总是得不到从机的应答,是不是该考虑连接出了问题呢?在协议中 也 有 规 定 一 个 参 数 — — 连 接 监 管 超 时
100ms~30.0s
timeout > (1 + connSlaveLatency) *connInterval // 这应该好理解,从机潜伏期是双方沟通和允许的事情,所以超时时间一定要大于上面表达式才行
3.3、连接状态--主机
在第一个连接事件中,锚点是由 CONNECT_REQ PDU 中的参数决定的。当主机发送完 CONNECT_REQ 报文之后,接着发送第一个连接事件的报文,而从机接到 CONNECT_REQ 报文后,做好进入连接状态的准备工作后,根据 CONNECT_REQ 中的参数,决定开始侦听的时间,但是必须保证,主机在锚点前从机必须已经进入侦听状态;
从上可知传输偏移一定是在 1.25ms 之后。也就是说,连接状态的第一包数据传输一定是在[1.25 ms + transmitWindowOffset, 1.25ms + transmitWindowOffset + transmitWindowSize]之间
3.2、连接状态--从机
对于从机接收到CONNECT_REQ 之后,协议留了至少 1.25ms 的时间让其准备进入连接状态,进入之后偏移一个传输窗口的时间,进而进入扫描窗口,开始侦听空中的包,看是否有自己需要的报文,所以在上面的图中传输窗口都是用虚线的,也就是说传输口规定了最大时间,但是并不一定要等这么久的时间,收到数据就可以去处理,并开始计时连接间隔时间,等到连接间隔时间到,再次进入扫描窗口,侦听报文。
从机第一个连接事件接收失败处理过程:
对于主机来说控制着连接状态下的几乎所有权利,可是对于配合者的从机却是有些难办。如果理想状态,晶振没有任何偏差,那么有了这个时序,就很容易完成这个程序的编写。事实总是很残酷的,晶振总有一些漂移的,这样就会带来主机肯定是发送了连接事件中的第一个报文,但是从机并不一定能接收得到,所以看看从机如果在第一个连接事件中没有接收到数据报文的话,时间又是怎么控制的:
如果持续6次从机都没有应答,意味着连接建立失败;
4、广播软件设计流程图