BLE Mesh蓝牙组网技术详细解析之Lower Transport Layer下传输层(四)
目录
一、什么是BLE Mesh?Lower Transport Layer下传输层?
一、什么是BLE Mesh?Lower Transport Layer下传输层?
BLE mesh下传输层的作用是对上层传输层的消息进行分段和重组,以适应BLE的物理层和链路层的限制。以及将网络层接收到的分段消息重组为完整的消息。下传输层可以处理两种类型的消息:分段消息和未分段消息。
- 分段消息是指上层传输层的消息长度超过BLE的最大载荷,需要被分成多个分段,每个分段包含一些额外的信息,如消息的序号、总数、大小等,以便接收方能够正确地重组消息。
- 未分段消息是指上层传输层的消息长度小于或等于BLE的最大载荷,不需要被分段,只需要添加一些简单的信息,如消息的类型、加密方式等,以便接收方能够正确地解析消息。
下传输层还负责对分段消息进行确认和重传,以保证消息的可靠性和完整性。下传输层使用一种管理型网络泛洪的方式,让具有中继特性的节点可以转发收到的消息,扩大消息的传播范围,同时采用消息缓存和生存时间等机制,避免消息的重复和无限循环。
二、未分段消息
未分段消息是指不需要分段的传输层消息,它们包括两种类型:
- 未分段接入层消息(Unsegmented Access Message),用于传输来自访问层的应用消息或配置消息,它们的长度为6-16字节,由一个1字节的控制字段和一个5-15字节的上层传输层接入消息PDU组成。控制字段中的SEG位为0,表示未分段,AKF位表示是否使用AppKey加密,AID位表示AppKey ID。
- 未分段控制消息(Unsegmented Control Message),用于传输来自上层传输层的控制消息,如心跳消息、友谊消息和分段确认消息,它们的长度为1-12字节,由一个1字节的控制字段和一个0-11字节的参数字段组成。控制字段中的SEG位为0,表示未分段,Opcode位表示控制消息的类型。
未分段消息的优点是传输效率高,不需要分段和重组的过程,也不需要确认重传的机制,但是它们的缺点是不能传输超过网络层PDU大小限制的消息,也不能利用分段消息的安全特性,如每个分段使用不同的网络层MIC。
2.1 未分段接入层消息
Field | Size (bits) | Notes |
SEG | 1 | 表示是否为分段消息,未分段消息的值为0。 |
AKF | 1 | 表示是否使用AppKey加密,值为1表示使用AppKey,值为0表示使用DevKey。 |
AID | 6 | 表示AppKey ID,当AKF为1时有效,用于识别加密的AppKey。 |
Upper Transport Access PDU | 40 to 120 | 表示上层传输层接入消息的PDU,包含OpCode、参数和TransMIC。 |
?2.2 未分段控制层消息
Field | Size (bits) | Notes |
SEG | 1 | 表示是否为分段消息,未分段消息的值为0。 |
Opcode | 7 | 表示控制消息的操作码,用于区分不同类型的控制消息,例如心跳消息、友谊消息等。 |
Parameters | 0 - 88 | 表示控制消息的参数,用于携带控制消息的具体内容,例如心跳计数、友谊轮询地址等。 |
?
三、分段消息
BLE Mesh Lower Transport Layer分段消息是指需要分段的传输层消息,它们包括两种类型:
- 分段接入层消息(Segmented Access Message),用于传输来自访问层的应用消息或配置消息,它们的长度为5-16字节,由一个1字节的控制字段和一个4-15字节的上层传输层接入消息PDU组成。控制字段中的SEG位为1,表示分段,AKF位表示是否使用AppKey加密,AID位表示AppKey ID,SZMIC位表示TransMIC的大小,SeqZero位表示SeqAuth的最低13位有效位,SegO位表示当前分段位第几个分段,SegN位表示此条消息总共有多少分段。
- 分段控制消息(Segmented Control Message),用于传输来自上层传输层的控制消息,如心跳消息、友谊消息和分段确认消息,它们的长度为5-12字节,由一个1字节的控制字段和一个4-11字节的参数字段组成。控制字段中的SEG位为1,表示分段,Opcode位表示控制消息的类型,RFU位保留未来使用,SeqZero位表示SeqAuth的最低13位有效位,SegO位表示当前分段位第几个分段,SegN位表示此条消息总共有多少分段。
分段消息的优点是可以传输超过网络层PDU大小限制的消息,也可以利用分段消息的安全特性,如每个分段使用不同的网络层MIC。分段消息的缺点是传输效率低,需要分段和重组的过程,也需要确认重传的机制。
3.1 超过多少个字节需要分段?
在BLE Mesh下传输层,是否需要对消息进行分段取决于消息的类型和长度,以及网络层PDU的最大载荷。一般来说,有以下几种情况:
- 那么当消息长度大于等于12字节时,就需要进行分段。这是因为接入层消息至少有4字节的TransMIC,以及1字节的Opocde,所以未分段接入层消息最多为15字节,除去4字节的TransMIC,剩下11字节用于实际数据。超过11字节就要分段。
- 如果消息是分段确认消息,那么不需要进行分段,因为分段确认消息的长度固定为7字节。
/*BLE Mesh传输层发送数据子函数*/
/*源自开源协议栈NimBLE*/
int bt_mesh_trans_send(struct bt_mesh_net_tx *tx, struct os_mbuf *msg,
const struct bt_mesh_send_cb *cb, void *cb_data)
{
const u8_t *key;
u8_t *ad;
u8_t aid;
int err;
if (net_buf_simple_tailroom(msg) < 4) {
BT_ERR("Insufficient tailroom for Transport MIC");
return -EINVAL;
}
if (msg->om_len > 11) {
tx->ctx->send_rel = 1;
tx->ctx->send_rel = true;
}
BT_DBG("net_idx 0x%04x app_idx 0x%04x dst 0x%04x", tx->sub->net_idx,
tx->ctx->app_idx, tx->ctx->addr);
BT_DBG("len %u: %s", msg->om_len, bt_hex(msg->om_data, msg->om_len));
err = bt_mesh_app_key_get(tx->sub, tx->ctx->app_idx,
tx->ctx->addr, &key, &aid);
if (err) {
return err;
}
tx->aid = aid;
if (!tx->ctx->send_rel || net_buf_simple_tailroom(msg) < 8) {
tx->aszmic = 0;
} else {
tx->aszmic = 1;
}
if (BT_MESH_ADDR_IS_VIRTUAL(tx->ctx->addr)) {
ad = bt_mesh_label_uuid_get(tx->ctx->addr);
} else {
ad = NULL;
}
err = bt_mesh_app_encrypt(key, BT_MESH_IS_DEV_KEY(tx->ctx->app_idx),
tx->aszmic, msg, ad, tx->src, tx->ctx->addr,
bt_mesh.seq, BT_MESH_NET_IVI_TX);
if (err) {
return err;
}
if (tx->ctx->send_rel) {
err = send_seg(tx, msg, cb, cb_data);
} else {
err = send_unseg(tx, msg, cb, cb_data);
}
return err;
}
3.2 分段接入层消息
Field | Size (bits) | Notes |
SEG | 1 | 表示当前消息是分段消息,值为1。 |
AKF | 1 | 表示是否使用AppKey加密,值为1表示使用AppKey,值为0表示使用DevKey。 |
AID | 6 | 表示AppKey ID,当AKF为1时有效,用于识别加密的AppKey。 |
SZMIC | 1 | 表示TransMIC的大小,值为0表示TransMIC为4字节,值为1表示TransMIC为8字节。TransMIC是用于上层传输层消息的完整性校验的字段。 |
SeqZero | 13 | 表示SeqAuth的最低13位有效位,SeqAuth是第一个分段的IV|SeqNum组合值,用于防止重放攻击和识别同一条消息的不同分段。 |
SegO | 5 | 表示当前分段是第几个分段,从0开始计数。 |
SegN | 5 | 表示此条消息总共有多少分段,从0开始计数。 |
Segment m | 8 to 96 | 表示此分段的消息内容,只有最后一个分段的size才小于96位。 |
?
3.3 分段控制层消息?
Field | Size (bits) | Notes |
SEG | 1 | 表示当前消息是分段消息,值为1。 |
Opcode | 7 | 表示控制消息的类型,有7位,可以表示128种不同的控制消息。 |
RFU | 1 | 保留未来使用,值为0。 |
SeqZero | 13 | 表示SeqAuth的最低13位有效位,SeqAuth是第一个分段的IV|SeqNum组合值,用于防止重放攻击和识别同一条消息的不同分段。 |
SegO | 5 | 表示当前分段是第几个分段,从0开始计数。 |
SegN | 5 | 表示此条消息总共有多少分段,从0开始计数。 |
Segment m | 8 to 64 | 表示此分段的消息内容,只有最后一个分段的size才小于64位。 |
3.4 分段确认消息
下传输层还定义了一种控制消息,用于确认分段消息的接收情况。控制消息的Opcode为0x00,表示分段确认消息。分段确认消息包含一个BlockAck字段,用于表示哪些分段已经被接收,哪些分段需要重传。
Field | Size (bits) | Notes |
SEG | 1 | 表示当前消息是未分段消息,值为0。 |
Opcode | 7 | 表示控制消息的类型,值为0x00,表示分段确认消息 |
OBO | 1 | 表示是否是Friend节点替Low Power节点发送的分段确认消息,值为0表示是当前节点的行为,值为1表示是Friend节点的行为。 |
SeqZero | 13 | 表示确认分段的SeqZero,即分段消息的SeqAuth的最低13位有效位,用于识别同一条消息的不同分段。 |
RFU | 2 | 保留未来使用,值为0。 |
BlockAck | 32 | 表示分段的Bitmap位,每一位对应一个分段,值为1表示已收到该分段,值为0表示未收到该分段。 |
?
3.5 分段和重组流程
下传输层的分段和重组流程如下:
-
※发送方:
- 如果上层传输层的消息长度大于网络层PDU的最大载荷,就进行分段,填充各个字段,然后发送所有分段。
- 如果目的地址是单播地址,就启动一个分段传输定时器,等待接收方的分段确认消息。
- 如果收到分段确认消息,就根据BlockAck字段,重新发送未收到的分段,然后重启分段传输定时器。
- 如果收到的BlockAck字段为0,表示对端忙碌或资源不足,就取消分段消息的发送,结束流程。
- 如果收到的BlockAck字段为1,表示所有分段都已收到,就关闭分段传输定时器,结束流程。
- 如果分段传输定时器超时,就重新发送所有分段,重启分段传输定时器。这个操作至少进行两次,如果仍然没有收到分段确认消息,就结束流程。
- ※接收方:
- 如果收到第一个分段消息,就存储该消息的SeqAuth,开启一个不完整定时器。
- 如果目的地址是单播地址,就开启一个确认定时器,标记BlockAck字段,表示该分段已收到。
- 如果确认定时器超时,就发送分段确认消息给发送方,重启确认定时器。
- 如果收到其他分段消息,就检查该消息的SeqAuth,如果小于第一个分段的SeqAuth,就丢弃该消息。
- 如果该消息的SeqAuth有效,就标记BlockAck字段,表示该分段已收到。如果确认定时器超时,就重启确认定时器。如果不完整定时器未超时,就重启不完整定时器。
- 如果不完整定时器超时,就结束流程。
- 如果所有分段都已收到,就重组为完整的消息,递交给上层传输层。如果仍然收到分段消息,就立即发送分段确认消息给发送方,结束流程。
四、Lower Transport Layer如何接收数据
- 首先,下层传输层需要从网络层接收网络层PDU,根据控制字段中的SEG位判断是分段消息还是未分段消息,然后根据NID和IVI字段解密和去混淆网络层有效载荷,得到下层传输层PDU。
- 其次,如果是分段消息,下层传输层需要根据SeqZero字段计算SeqAuth,用于识别同一条消息的不同分段,然后根据SegO和SegN字段重组分段,最后根据SZMIC字段验证网络层MIC的正确性。
- 再次,如果是未分段消息,下层传输层直接将下层传输层有效载荷递交给上层传输层,无需重组或验证网络层MIC。
- 最后,如果收到的消息的目的地址是单播地址,下层传输层需要发送分段确认消息给对端,表示已收到的分段,或者请求对端重新发送未收到的分段。
五、资料获取
通过点击以下链接,您可以获取BLE Mesh模块原理图、源代码以及开发资料。链接地址将为您提供详细的文件资料,以供您进行参考和使用。
如果您在使用过程中遇到任何问题或疑虑,欢迎加我QQ ,一起探讨技术问题,我的QQ号是986571840,加的时候请注明CSDN。
BLE Mesh蓝牙组网模块 - 硬创社 (jlc.com)https://x.jlc.com/platform/detail/001d23cba7b64b0d9df5b9b69720fadb
感谢各位用户点赞、分享、在看,这些行为让知识得以更加广泛地传播,从而让更多人受益。
请在转载作品时注明出处,严禁抄袭行为。
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!