文章目录
前言
上篇文章介绍了非连接态下空口的各种状态的表现,现在让我们一起看下在连接态,各种状态又有什么表现。
4.5 CONNECTION STATE
当发起者在主广播物理信道上向广播者发送 CONNECT_IND PDU、广播者在主要广播物理信道上从发起者接收到 CONNECT_IND PDU、广播者在次要广播物理信道上向发起者发送 AUX_CONNECT_RSP PDU 时,链路层进入连接状态, 或者发起者在二级广播物理信道上收到来自广播者的AUX_CONNECT_RSP PDU。进入连接状态后,认为连接已创建。
这里需要说明一下,交互 CONNECT_IND 或者 AUX_CONNECT_REQ/AUX_CONNECT_RSP,这并不代表双方真正的建立起了,连接进入 Connection State,因为空口情况复杂,您并不一定能够保证在这个关键的交互时刻点,对方一定能够收到你发送的这个关键的数据包,万一对方没收到呢?
因此,此时不认为连接已建立。只有从对端设备接收到数据物理通道数据包后,才认为建立连接。连接的创建created 和 连接的建立established 之间的唯一区别是使用的 LinkLayer 连接监督超时值supervision timeout value(一般为连续 6 个 Event 没有包的交互)(请参阅第 4.5.2 节)。
-
如果首先使用主通告物理信道上的 CONNECT_IND PDU 创建连接,则它应在两个方向上使用 LE 1M PHY。
-
如果首先使用 AUX_CONNECT_REQ 和 AUX_CONNECT_RSP PDU 在辅助信道上创建连接,则它应在两个方向上使用与 AUX_CONNECT_REQ 和 AUX_CONNECT RSP PDU 相同的 PHY。连接不被认为是在此阶段建立的,随后可以使用 PHY 更新程序(第 5.1.10 节)更改 PHY。
-
当使用 LE 编码 PHY 时,每个数据包的编码由第 2.2.3 节中定义的 Coding Indicator 确定,并且在每个方向和给定方向的相邻数据包中可能不同。当两个设备连接时,两个设备 扮演不同的角色。
Master 角色中的链路层称为 master。Slave角色中的链路层称为Slave。HOST控制连接事件的时间。连接事件是主从之间的同步点。
无论是否建立,两个 LE 设备地址之间只能有一个连接。发起者不应向其已连接的广播商发送连接请求。如果广播商收到来自其已连接的发起者的连接请求,则应忽略该请求。
如果发起方发送了 CONNECT_IND PDU 以响应 ADV_IND 或 ADV_DIRECT_IND PDU,并且其中一个或两个设备的 PDU 的 ChSel 字段设置为 0,则应在连接上使用信道选择算法 #1(参见第 4.5.8.2 节)。
否则,应使用信道选择算法#2(见第 4.5.8.3 节)。ACL 连接的主控在主机指示时,可以使用连接等时流创建过程与对等设备创建连接等时流(CIS)(参见 第 5.1.15 节)。
The CIS 应与用于创建它的 ACL 相关联。链路层可以为同一个slave创建多个CIS。 注意:slave不能在链路层发起创建CIS的请求,但可以在更高层发起。 当master和slave之间的ACL连接终止时,所有关联 CIS 应同时终止。
4.5.1 Connection events
Connection Event 我们简称 CE,代表着一个连接态的 Master/Slave 的交互集合。两个 CE 的起始时间之间的时间差,我们叫做 Connection Interval 也叫 CI。
处于连接状态的链路层应仅在连接事件中传输 Data PhysicalChannel PDUs (见第 2.4 节)。
每个连接事件通常包含至少一个master发送的数据包。 但是,由于调度冲突,master可以在连接事件中完全传输失败,但应在每个supervision timeout 周期内传输至少一个Data Channel PDU (参见第 4.5.2 节) .
在连接事件期间,master和slave交替发送和接收数据包。当两个设备继续发送数据包时,连接事件被认为是打开的。
不管有效的 CRC 匹配如何,如果从slave接收到来自master的数据包,slave应始终发送数据包,除非在第 4.5.6 节中指定的多个连续的无效 CRC 匹配之后。如果master收到来自slave的数据包而不考虑有效的 CRC 匹配,则它可以发送一个数据包,除非在第 4.5.6 节中指定的多个连续的无效 CRC 匹配之后。
连接事件的开始称为锚点an anchor point
。在锚点产生后,master通常会开始向slave发送 Data Physical Channel PDU。
连接事件的时间由两个参数决定:连接间隔(connection interval / connInterval)和从设备延迟(slave latency / connSlaveLatency)。
- connInterval 应为 1.25 ms 的倍数,范围为 7.5 ms 到 4.0 s。connInterval 由发起方的链路层在 CONNECT_IND 或 AUX_CONNECT_REQ PDU 范围内设置,由master给出,可以使用连接更新程序(见第 5.1.1 节)或连接参数请求程序(见第 5.1.7 节)进行更改。
- connSlaveLatency允许slave 减少连接事件数量。 connSlaveLatency 参数定义了slave不需要侦听master的连续连接事件的数量。 但是,connSlaveLatency 的值不应导致Supervision Timeout(请参阅第 4.5.2 节)。connSlaveLatency 应为
0 ~ ((connSupervisionTimeout / (connInterval*2)) - 1)
范围内的整数,且参数也应小于 500。
当 connSlaveLatency 设置为零时,slave应在每个锚点(anchor point)侦听。如果slave在应用从设备延迟后没有收到来自主设备的数据包,它应该在每个锚点进行侦听,并且在收到来自主设备的数据包之前不应用从设备延迟。
当双方建立起连接并维持连接的过程中,双方都会记录一个 Event Counter 的东西,顾名思义,这个值代表了当前这是第几个 Connection Event。他是一个 16bits 的数字,从 0x0000 - 0xFFFF.
4.5.2 Supervision timeout
连接可能会由于各种原因而中断,例如设备超出范围、遇到严重干扰或断电情况。由于这种情况可能会在没有任何事先警告的情况下发生,因此master和slave都必须监视状态连接。
为了能够检测 ACL 连接中的链路丢失,master和slave都应使用ACL connection supervision timer T L L c o n n S u p e r v i s i o n T_{LLconnSupervision} TLLconnSupervision。在 ACL 上接收到有效数据包后,计时器将被重置。为了能够检测 CIS 中的链路丢失,master和slave都应使用 CIS supervision timer T C I S S u p e r v i s i o n T_{CISSupervision} TCISSupervision。在 CIS 上接收到有效数据包后,定时器 T C I S S u p e r v i s i o n T_{CISSupervision} TCISSupervision 将被重置。
如果在连接建立之前 ACL connection supervision timer 大于等于 6 * connInterval(见第 4.5 节),则认为 ACL 连接丢失。这使得未能建立的 ACL 连接能够快速终止。建立 CIS 时,主设备应在收到 LL_CIS_IND 的确认后,在下一个 CIS 事件开始时启动 CIS supervision timer 。
如果在CIS建立前CIS supervision timer 大于等于 6 * ISO_Interval,则认为CIS丢失。建立CIS时,slave应在收到LL_CIS_IND后,在下一个CIS事件开始时启动 CIS supervision timer。
ConnSupervisionTimeout
应为 10 ms 的倍数,范围为 100 ms 到 32.0 s ,且应大于(1 + connSlaveLatency) * connInterval * 2
。
如果在连接建立后的任何时间处于连接状态,定时器 T L L c o n n S u p e r v i s i o n T_{LLconnSupervision} TLLconnSupervision 大于等于 connSupervisionTimeout 值,连接应被视为丢失(参见第 4.5.12 节)。如果在 CIS 建立后的任何时间处于连接状态,timerTCISSupervision 达到 connSupervisionTimeout 值,则 CIS 应被视为丢失。
无论哪种情况,如果最近的事件已经关闭并且定时器将在下一个 ACL 或 CIS 锚点之前达到 connSupervisionTimeout 值,则Controller 可以更早地发送丢失的通知。可以使用Connection Update
procedure(参见第 5.1.1 节) ) 或the Connection Parameters Request (参见第 5.1.7 节)修改 the supervision timeout。
4.5.3 Connection event transmit window
为了允许 Master 高效地为多个连接或它可能涉及的其他活动安排连接事件,master具有在其选择时调度第一个连接事件锚点的灵活性。
传输窗口transmit window
在包含 CONNECT_IND PDU 或 AUX_CONNECT_REQ PDU 的数据包结束后的 TransmitWindowDelay + Transmit WindowOffset 处开始,并且传输 WindowSize 参数应定义传输窗口的大小。 connInterval 用于计算最大偏移量和传输窗口大小。传输窗口偏移和传输窗口大小参数由链路层确定。
- 传输窗口偏移应是 0 毫秒到 connInterval 范围内的 1.25 毫秒的倍数。
- 传输窗口大小应为 1.25 毫秒的倍数,范围为 1.25 毫秒到 10 毫秒和(connInterval - 1.25 毫秒)中的较小者。
因此,在包含 CONNECT_IND PDU 或 AUX_CONNECT_REQ PDU 的数据包结束之后,第一个数据包的开始将不早于transmitWindowDelay + transmitWindowOffset
,并且不晚于transmitWindowDelay + transmitWindowOffset + transmitWindowSize
。
当使用 CONNECT_IND PDU 时,transmitWindowDelay 的值应为 1.25 毫秒,当在 LE 未编码 PHY 上使用 AUX_CONNECT_REQ PDU 时为 2.5 毫秒,当在 LE 编码 PHY 上使用 AUX_CONNECT_REQ PDU 时为 3.75 毫秒。
4.5.4 Connection setup – Master Role
initiator者在主广播物理通道上发送 CONNECT_IND PDU 或在 二级广播物理通道上收到 AUX_CONNECT_RSP PDU 后,链路层处于Master角色的连接状态。Master将重置链路层连接监督定时器connection supervision timer
T
L
L
c
o
n
n
S
u
p
e
r
v
i
s
i
o
n
T_{LLconnSupervision}
TLLconnSupervision。链路层应通知HOST连接已创建。
第一个连接事件应使用第 4.5.8 节中指定的数据通道索引。HOST应开始在第 4.5.3 节中定义的传输窗口the transmit window.
内发送第一个数据包。允许HOST的第一个数据包超出传输窗口。
Master在连接状态中发送的第一个数据包确定了第一个连接事件的锚点,因此确定了此连接中所有未来连接事件的时序。
第二个连接事件锚点应在第一个连接事件锚点之后的 connInterval 。4.5.1 节规定的所有正常连接事件传输规则均适用。 图 4.38 和图 4.39 显示了从Master角度来看的 LL 连接建立过程时序的两个示例。
最开始是可连接的 Advertising packet,T_IFS(150us)后,接着 CONNECT_IND 包。此刻,我们假设双方都正常的收到/发送了这个 CONNECT_IND,那么连接开始 SetUp。
- 经过 transmitWindowDelay
- 在经过 transmitWindowOffset
- 开窗 transmitWindowSize 发送第一个 packet
- 这些确定后,Slave 就在那个指定的位置去开窗收包即可
4.5.5 Connection setup – Slave Role
当advertiser在主广播物理通道上收到 CONNECT_IND PDU 或在 二级广播物理通道上发送 AUX_CONNECT_RSP PDU 后,链路层处于slave的连接状态。Slave将重置链路层连接监督定时器connection supervision timer
T
L
L
c
o
n
n
S
u
p
e
r
v
i
s
i
o
n
T_{LLconnSupervision}
TLLconnSupervision。链路层应通知 HOST连接已创建。
第一个连接事件应使用第 4.5.8 节中指定的数据通道索引。slave应开始侦听第 4.5.3 节中定义的传输窗口内的第一个数据包;这样做时,它应该执行第 4.2.4 节中指定的窗口加宽。
允许Master的第一个数据包超出传输窗口,因此slave必须考虑到这一点。接收到的第一个数据包,不管有效的 CRC 匹配(即,只有访问地址需要匹配),在连接状态中由slave 确定第一个连接事件的锚点,因此所有未来连接事件的时序这种联系。
如果在一个传输窗口中没有接收到一个数据包,slave将尝试在随后的传输窗口中接收一个数据包。后续传输窗口应在前一个传输窗口开始后以相同的传输窗口大小开始 connInterval。数据信道索引应是第 4.5.8 节中规定的下一个数据信道索引。connEventCount 也应加一。
图 4.40 和图 4.41 显示了从Slave角度的两个过程示例。在这些示例中,Slave未能从Master 接收第一个数据包的任何部分(即 connEventCount = 0),并从第二个数据包(即 connEventCount = 1)获取锚点定时。
Slave在每个连接事件中都应处于活动状态,直到它从主设备接收到一个 NESN 设置为 1 的数据包。从那时起,它可以使用第 4.5.1 节中定义的 slave latency。
4.5.6 Closing connection events
好了,连接这些都建立上了,我们开始数据传送之旅。BLE 是周期性业务,所以每次的数据交互,只能在每个 Connection Event 中,那么一个 Connection Event 有多长呢?这个就涉及到一个概念,叫 MD。
Data Physical Channel PDU Header 的 MD 位用于指示设备有更多数据要发送。它的物理含义是,代表了当前的这个包后面还有没有跟进其他的非空数据包。如何理解呢?
比如,Master 想发 40 个 Bytes 的数据,(默认情况下,27 Bytes 为一个 Date Length),那么就要分为两包发送,第一次发送 27 Bytes,第二次发送 13 Bytes;那么在第一组包中的 Header 域中的 MD 字段,就要被设置成为 1,由于第二组发包后,发完了,那么第二组数据包的 Header 中的 MD 字段就被设置成为 0;
如果两个设备都没有在它们的数据包中设置 MD 位,则来自从设备的数据包关闭连接事件。
如果两个设备中的一个或两个都设置了 MD 位,主设备可以通过发送另一个数据包来继续连接事件,而从设备应该在发送其数据包后进行侦听。未能接收到一个数据包,或者在一个连接事件中接收到两个连续的具有无效 CRC 匹配的数据包将关闭该事件。
打个比如:如果双方都没有要传输的数据,那么 MD 都为 0,则这次的 CE 就提前结束,CE 就显得比较小。
类似于上面的例子。如果 Master 有 40 Bytes 的数据传送,那么 Slave 也要陪着 Master 玩,那么这时的 CE 就会较大:
当然,只允许 Master 传数据,那是不合理的,Slave 也可以发送据呀,当 Slave 发送据 Master 没数据的时候,Slave 的 MD 就会被设置成为 1,Master 也只有陪玩:
当然,Master 和 Slave 可以同时发数据,MD 都被设置成为 1:
这里我们总算是看出来了,MD 会影响到 CE 的长度;同时可看出来了,CE 最长不能超过 CI 的长度。那么有没有办法指定 CE 呢?当然可以,HCI 命令中,可以指定 CE MIN Length 和 CE MAX Length,如果一个 CE 装不了那么多数据,那么数据顺延到下一个 CI 去发就好,MD 照样置上。
所以 Core Spec 根据上面画的 4 个图的场景,根据 MD 的值,绘制了一个表格,来代表 MD 对 CE 的影响: