下层传输层主要负责数据的分段与重组。下层传输层接收上层传输层的Access消息和Control消息。
1. 分段消息(Segmented Msg)
1.1. 分段接入层消息(Segmented Access Message)
分段接入层消息(5-16字节)的每个分段的结构如下:
Field | Size(bits) | Notes |
---|---|---|
SEG | 1 | SEG=1,表示当前消息是分段消息 |
AKF | 1 | AKF=1,表示使用Appkey加密;AKF=0,表示使用DevKey加密,AID=0b000000 |
AID | 6 | AppKey ID,当AKF= 1时有效 |
SZMIC | 1 | TtansMIC的大小。SZMIC=0,表示TransMIC为4字节;SZMIC=1,表示TransMIC为8字节 |
SeqZero | 13 | SeqAuth的最低13位有效位 |
SegO | 5 | 表示当前分段位第几个分段 |
SegN | 5 | 表示此条消息总共有多少分段 |
Segment m | 8-96 | 此分段的消息内容,只有最后一个分段的size才小于96 |
SeqN为5bit,说明最大支持32个分段,每个分段满载的payload为12字节,所以Upper Transport Layer下发的消息包括TransMIC最大为32*12=384字节。
对于同一条消息的不同分段,只有SegN和Segment m不同。
SeqAuth是第一个分段的IV|SeqNum组合值,通过接收消息的IV,SeqNum和SeqZero三者组合而成SeqAuth,对于同一条消息的所有分段具有同样的SeqAuth值。
1.2. 分段控制消息(Segmented Control Message)
分段控制消息(5-12字节)的每个分段的结构如下:
Field | Size(bits) | Notes |
---|---|---|
SEG | 1 | SEG=1,表示当前消息是分段消息 |
Opcode | 7 | 分段控制消息的Opocde,见Upper Transport Layer |
RFU | 1 | RFU |
SeqZero | 13 | SeqAuth的最低13位有效位 |
SegO | 5 | 表示当前分段位第几个分段 |
SegN | 5 | 表示此条消息总共有多少分段 |
Segment m | 8-64 | 此分段的消息内容,只有最后一个分段的size才小于64 |
分段控制消息的最大载荷为32*8=256字节。
2. 未分段消息(Unsegmented Msg)
2.1. 未分段接入层消息(Unsegmented Access Message)
未分段接入层消息(6-16字节)的每个分段的结构如下:
Field | Size(bits) | Notes |
---|---|---|
SEG | 1 | SEG=0,表示当前消息是未分段消息 |
AKF | 1 | AKF=1,表示使用Appkey加密;AKF=0,表示使用DevKey加密,AID=0b000000 |
AID | 6 | AppKey ID,当AKF= 1时有效 |
Upper Transport Access PDU | 40-120 | 上层传输层接入消息PDU |
接入层消息至少有4字节的TransMIC,以及1字节的Opocde,所有未分段接入层消息最少为5字节。
接入层消息最大为15字节,除去4字节的TransMIC,所以从Model Layer下来的消息最大为11字节,超过11字节就要分段。
2.2. 未分段控制消息(Unsegmented Control Message)
未分段控制消息(1-12字节)的每个分段的结构如下:
Field | Size(bits) | Notes |
---|---|---|
SEG | 1 | SEG=0,表示当前消息是未分段消息 |
Opcode | 7 | 分段控制消息的Opocde,见Upper Transport Layer |
Parameters | 0-88 | 此分段的消息内容,只有最后一个分段的size才小于64 |
未分段的控制消息最大size为11字节。
在Upper Transport Layer的控制消息中提到当Opcode=0x00是为Lower Transport Layer预留。
当Opcode=0x00时表示当前消息为分段确认消息(大小为7字节)。其实也是一种控制消息而已。
其消息格式为:
Field | Size(bits) | Notes |
---|---|---|
SEG | 1 | SEG=0,表示当前消息是未分段消息 |
Opcode | 7 | Opcode=0x00 |
OBO | 1 | OBO=0,表示是当前节点的行为;OBO=1,表示这是Friend替LPN发的分段确认消息 |
SeqZero | 13 | 确认分段的SeqZero |
RFU | 2 | Reserverd for Future Use |
BlockAck | 32 | 分段的Bitmap位 |
3. 分段/重组流程
分段流程
① Access PDU大于12字节,Control PDU大于8字节进行分段,填充各个字段。
② 若目的地址为组播地址或者虚拟地址,把所有分段广播出去多次,并且每次之间附加上一个小的随机延时。结束。
③ 若目的地址为单播地址,先把所有分段广播出去一次,然后启动一个至少200+50TTL ms的定时器(segment transmission timer)。
④ 在timer期间,若收到对端的分段确认消息,然后根据分段确认消息里面的BlockAck域,将对端未收到的分段,再重新发送一次,然后再重启segment transmission timer。
⑤ 若收到的BlockAck域为0x00000000,表示对端busy或者资源不足,本端则取消分段消息的发送,结束。
⑥ 若收到的ack消息表示分段消息接收完毕,则关闭timer,消息发送成功,结束。
⑦ 若timer耗尽,仍未收到分段确认消息,则再次广播所有分段,重启timer。此操作至少进行2次,若多次仍未有确认消息,则消息发送失败,结束。
重组流程
① 收到第一个分段消息,储存此分段消息的SeqAuth,开启一个至少10s的incomplete timer。
② 若收到的消息的目的地址为单播地址,开启一个至少150+50TTL ms的acknowledgment timer,标记ack消息的BlockAck字段,表示此分段已收到。
③ 若acknowledgment timer耗尽,将此期间标记的Ack消息发送至对端。
④ 再次收到分段消息,若此消息的SeqAuth小于第一个分段的SeqAuth,则此消息是过期的,需要被抛弃。标记ack消息的BlockAck域,若此时acknowledgment timer耗尽,则重启acknowledgment timer,注意此时BlockAck域不清零。若此时incomplete timer未耗尽,则需要重启incomplete timer,重新开始计时。(incomplete timer的意义在于规定两次分段的最大时间间隔)
⑤ 若incomplete timer耗尽,则消息接收失败,结束。
⑥ 若已接收完毕所有分段后仍受到分段消息,需要立即响应ack消息。(说明对端未收到ack消息)
来源:CSDN
作者:蓬某某
链接:https://blog.csdn.net/wang_yunpeng/article/details/103805839