蓝牙mesh底层传输层(分包和组包)

当传输大于15字节的上层传输层PDU时,底层传输层就需要对上层传输层PDU进行分包并重新组包为了减少底层传输层包的数量,这里使用块应答机制。

问题:怎么通过块应答机制减少底层传输层包的数量?


上层传输层需要分成两个底层传输层PDU的例子.jpg

示例中上层传输层访问PDU包含1字节的OPCode字段,3字节的NetKeyIndex和APPKeyIndex字段,还有16字节的APPkey字段。这以为着当使用应用秘钥加密和验证时,上层传输层PDU为24字节。这被底层传输层分为两个包,即分包0和分包1。每个分包具有一个标识分包数的包头,然后被传递到网络层,在那里计算完整的网络层PDU。网络层再使用该网络层PDU的序列号加密网络层PDU,然后对这些消息进行模糊处理,最终只有NID(和IV索引)字节以明文形式可见。因此可以使用两个网络层PDU安全地传递单个访问消息。

分包

底层传输层将上层传输层PDU分为一个或多个底层传输层PDU。同一时间底层传输层将同一上层传输层PDU的分包访问消息和分包控制消息发送到同一目的地。只有当上一个传输层PDU的所有分包都已被应答或消息被取消时,底层传输层才可以发送另外一个上层传输层PDU。

上层传输层访问消息一个分包最大为12字节,上层传输层控制消息一个分包最大为8字节。因为上层传输层PDU中TransMIC的值是变动的,访问消息是4字节,控制消息是8字节。

分包消息会在底层传输层会确认消息,但是不分包消息则不会。为了更加有效可靠的传输上层PDU,应该使用单包分段消息代替未分包消息。因为单包分段消息会被重传,而未分包消息就不会。

上层PDU使用SegO字段识别每个分包。用于加密和验证的SeqAuth值将不同分包链接在一起。同一个上层PDU分包后的每个下层传输层PDU应具有相同的IV Index。

SeqAuth是一个56bit的值,它由IV Index和第1个分包的序列号组成,其中IV Index在高字节,序列号在低字节。只有低位的13bit(称为SeqZero)才包含在分包消息和分包应答消息中。在对完整的分包消息进行组包时,可以从任何段中的IV Index、SeqZero和SEQ得到SeqAuth值。例如,如果接收到的消息的SEQ是0x647262, IV索引是0x58437AF2,接收到的SeqZero值是0x1849,那么SeqAuth值就是0x58437AF2645849。如果收到的SEQ值为0x647262, SeqZero值为0x1263,则SeqAuth值为0x58437AF2645263。

由于SeqZero的大小有限,一旦SEQ比SeqAuth高8192,就不可能发送分段消息。如果一个分段消息在SEQ比SeqAuth高8192时还没有被确认,则取消上行传输PDU的发送。

消息的每个段都包括它的段偏移号和最后的段号。段号(SegO)和最后段号(SegN)都包含在消息中,以允许接收方在接收到消息的任何段后总是确定上层传输PDU的大小(到最近的8字节)。

组包

当使用了低功耗节点功能时,消息应答由朋友节点执行,而低功耗节点不会发送应答消息。在收到分包消息时,首先应检查SeqAuth以确认此消息是否正在接收或先前是否已接收。如果尚未接收,则接收设备应根据SeqN字段分配足够的内存,以便存储上层传输层PDU的分包并跟踪它的分包是否被收到。

如果未使用低功耗功能,则该消息的目的地是单播地址,并且此时节点无法接收此上层传输层PDU,例如因为节点繁忙或资源不足以重新组装此消息,然后节点通过将BlockAck值设置为0x00000000来向源节点发信号,通知它无法接收此上层传输层PDU。

底层传输层针对每条收到的某个SeqAuth取值的所有分包消息都设置了序列认证值(Sequence Authentication Value)和块应答值(Block Acknowledgement)。

如果底层传输层收到SeqAuth值小于序列认证值的消息分包,则忽略该段。如果底层传输层收到新消息的分包,则它应将该段中的SeqAuth值保存为新的序列认证值。

如果底层传输层收到多个分包消息的其中一个分包,但此时因为它当前正忙或没有资源接收更多的分包消息,并且如果该消息的目的地是单播地址,底层传输层应回复一个BlockAck字段为0x00000000的应答消息。

当接收SeqAuth值大于序列认证值的一个分包消息时,底层传输层将启动不完成定时器,定义底层传输层接收不同分包的等待最大时间,此定时器应被设置为最少10秒。

当接收SeqAuth值大于目的地为单播地址的序列认证值的分包消息时,底层传输层应启动一个应答定时器,该定时器定义底层传输层发送分包应答消息的时间,最少设置为150+50xTTLms.

底层传输层应将接收的每个分包在块应答值中进行标记,该块应答值可以稍后传输回源节点。收到分包消息的所有分包之后,底层传输层将发送分包确认消息,其中BlockAck字段被设置为用于序列认证值的块应答值。它应取消未完成定时器和应答定时器,并将重新组装的消息发送到上层传输层。

当应答定时器到期时,底层传输层将为当前序列认证值包发送分包应答消息,其中BlockAck字段被设置为块应答值。

当未完成定时器到期时,底层传输层应认为正在接收的消息已经失败并取消应答定时器,之前接收的部分消息都应被忽略。

如果只看这一篇,会感觉写的太捞了,根本不知道在讲什么玩意,连个例子都没有。没办法,如果没有整个mesh知识体系,举出例子了也没法理解。如果直接上例子,不讲规则,也没法搞。

你可能感兴趣的:(蓝牙mesh底层传输层(分包和组包))