文章目录
- Mesh networking
- Features
- Bearers
- Advertising bearer
- GATT bearer
- Network layer
- Addresses
- Lower transport layer
- Lower Transport PDU
- Unsegmented Access message
- Segmented Access message
- Unsegmented Control Message
- Segmented Control message
- 分段与重组
- 分段
- 重组
- 传输行为
Mesh networking
对于接入层和基础模型,所有多八位字节数值应为小端,如第 3.1.1.2 节所述。
- 大端模式:
例如,字段 0 为 4 位宽,值为 0x6,字段 1 为 12 位宽,值为 0x987,字段 2 为 16 位宽,值为 0x1234。二进制数的值为 0x69871234,应按 0x69、0x87、0x12、0x34 传输。 - 小端模式:
例如,字段 0 为 4 位宽,值为 0x6,字段 1 为 12 位宽,值为 0x987,字段 2 为 16 位宽,值为 0x1234。二进制数的值为 0x12349876,应按 0x76、0x98、0x 34、0x12 传输。
Features
该规范定义了四个可选功能:
- Relay feature (see Section 3.4.6.1)
- Proxy feature (see Section 3.4.6.2)
- Friend feature (see Section 3.6.6.3)
- Low Power feature (see Section 3.6.6.4)
Bearers
该规范定义了两个网格承载,网格消息可以通过它们传输:
- An advertising bearer (see Section 3.3.1)
- A GATT bearer (see Section 3.3.2)
节点应支持advertising 承载 或 GATT 承载 或 both。
Advertising bearer
当使用广播承载时,网状数据包应在蓝牙低功耗广播PDU 的广播数据中使用的中定义的《Mesh Message》标识的The Mesh Message AD Type 发送。The Mesh Message AD Typ包含表 3.2 中定义的网络 PDU。
注:Data type name 对应的value值 协议标准在 Generic Access Profile 中规定。 AD type 对应规范在Core Specification Supplement 中 或 Specification标准 补充
注意:Mesh beacon 的 ADV 需要的类型是 non-connectable and non-scannable
undirected 类型,即,不可连接,不可扫描,非定向的 ADV。
GATT bearer
提供 GATT bearer是为了使无法支持广播bearer的设备能够参与网状网络。GATT bearer使用代理协议(参见第 6 节)通过 GATT 连接在两个设备之间传输和接收代理 PDU。
- GATT bearer使用特性来写入和接收使用属性协议的网格消息的通知。
- GATT bearer定义了两个角色:GATT 承载客户端和 GATT 承载服务器。
- GATT bearer客户端应为 GATT 客户端。
- GATT bearer服务器应为 GATT 服务器。
- GATT bearer服务器应实例化一个且仅一个 Mesh 代理服务,如第 7.2 节中所定义。
- GATT Bearer Client 应支持 Mesh Proxy Service
GATT bearer客户端应使用 GATT 发现所有主要服务子过程或 GATT 通过服务 UUID 发现主要服务子过程执行主要服务发现,以发现网状代理服务。
根据 GATT 的要求
- GATT bearer客户端必须容忍与此配置文件一起使用的服务的服务记录中的其他可选特征。
- GATT bearer客户端应使用 GATT 发现服务的所有特征子过程或通过 UUID 的 GATT 发现特征子过程来发现服务的特征。
- GATT bearer客户端应使用 GATT 发现所有特征描述符子过程来发现特征描述符,这将在以下部分进行描述。
- GATT 承载客户端应发现网格代理数据输入特性、网格代理数据输出特性及其客户端特性配置描述符。一旦发现了客户端特征配置描述符,它将启用使用该特征的通知。
- 要发送代理 PDU(参见第 6.3 节),GATT bearer客户端应使用无响应写入子过程,通过写入网状代理数据输入特性将代理 PDU 写入 GATT 承载服务器。
- 为了接收代理 PDU,GATT bearer客户端应能够接收多个关于网格代理数据输出特性的通知。每个通知包含一个代理 PDU
Network layer
网络层定义了网络 PDU 格式,允许承载层传输较低的传输 PDU。
它将在输入接口上接收到的传入消息解密和验证并将其转发到上层和/或输出接口,并加密和验证并转发传出消息,将它们传递到输出网络接口。
Addresses
蓝牙Mesh网络中,统一的地址长度为16位,分四种类型:单播地址(unicast address)、组播地址(group address)、虚拟地址(virtual address)、未分配地址(unassigned)。
- 未分配地址(unassigned)
16位全零的地址,表示元素还没有配置地址。例如,这可以用于通过将模型的发布地址设置为未分配的地址来禁用模型的消息发布。
未分配的地址不得用于消息的源地址或目的地址字段。
- 单播地址(Unicast Address)
单播地址在蓝牙Mesh网络中具有唯一性,可以标识出节点内的一个元素,节点在接入网络的时候被分配获得。一个mesh网络可以有32767个单播地址(0x0001 to 0x7FFF)。
如第 5.4.2.5 节所述,在供应期间,供应器在网络上节点的生命周期内为节点的每个元素分配单播地址。
供应商可以不分配地址,以允许使用第 3.10.7 节中定义的过程重用地址。
- 虚拟地址(Virtual Address)
虚拟地址可以赋给一个或多个元素,且可以由多个节点共有。虚拟地址类似于标签,可以在设备出厂前就配置,标签可以使得节点容易在网络被识别和应用。例如,可以表示某个厂商生产的某一个特定型号的摄像头。
配置客户端可以分配和跟踪虚拟地址,但是两个设备也可以使用某种带外 (OOB) 机制创建虚拟地址。
与组地址不同,这些地址可以由所涉及的设备商定,并且不需要在集中供应数据库中注册,因为它们不太可能被复制。
虚拟地址的一个缺点是在配置过程中需要多段消息将标签 UUID 传输到发布或订阅节点。虚拟地址可以具有从 0x8000 到 0xBFFF 的任何值,如下图 3.5 所示
- 组播地址(group address)
组播地址即是多播地址,标识一个或多个元素。SIG预定义了四类组播:“All-proxies”, “All-friends”,“All-relays” 和 “All-nodes”。开发者也可以将多个元素自定义到一个多播地址,便于应用的统一控制和管理。
组地址是被编程为零个或多个元素的地址。组地址的第 15 位设置为 1,第 14 位设置为 1,如下图 3.6 所示。0xFF00 到 0xFFFF 范围内的组地址为固定组地址保留(见表 3.4),0xC000 到 0xFEFF 范围内的地址通常可用于其他用途。
- 发送到 all-proxies address 的消息应由启用了 proxy 功能的所有节点的 the primary element处理。
- 发送到 all-friends address 的消息应由启用 friend 功能的所有节点的 the primary element处理。
- 发送到 all-relays address 的消息应由启用 relay 功能的所有节点的 the primary element处理。
- 发送到 all-nodes 地址的消息应由所有节点的 the primary element处理
表 3.5 显示了哪些地址类型可用于源地址字段和目标地址字段
表 3.6 显示了哪些地址类型可用于设备密钥和应用程序密钥
Lower transport layer
- 如果下层传输 PDU 是分段消息或分段确认消息,则应按照第 3.5.3.4 节中的定义进行处理。
- 如果下层传输 PDU 是未分段消息类型,则应按照第 3.6.4.2 节中的定义对其进行处理。
- 如果下层传输 PDU 是传输控制 PDU,则应根据 3.6.5 中定义的操作码字段的值对其进行处理。
Lower Transport PDU
The Lower Transport PDU
(后文直接称之为下层传输 PDU) 用于将 Upper Transport PDUs
(后文直接称之为上层传输PDU)传输到另一个节点。
这些上层传输 PDU 可以装入单个下层传输 PDU,也可以分成多个下层传输 PDU。下层传输 PDU 的第一个八位字节的最高有效位是 SEG 字段,用于确定下层传输 PDU 的格式是分段的还是未分段的消息。
使用四种格式,具体取决于网络 PDU 中的 CTL 字段和下层传输 PDU 中的 SEG 字段的值,如下表 3.9 中所定义。
Unsegmented Access message
Unsegmented Access 消息用于传输适合单个网络 PDU 的上层传输访问 PDU。图 3.9 显示了未分段访问消息的图示,表 3.10 显示了此消息的字段。
Segmented Access message
Segmented Access 消息用于传输上层传输访问 PDU 的一个段。图 3.10 显示了分段访问消息的图示,表 3.11 显示了此消息的字段。
Unsegmented Control Message
未分段控制消息用于传输段确认消息或传输控制消息。图 3.11 显示了未分段控制消息的图示,表 3.12 显示了此消息的字段。
opcode字段应设置为 0x00(对于段确认消息)或适当的操作码(见表 3.39)。
Lower 传输层使用 Segment Acknowledgment message来确认对等 Lower传输层接收到的段。段确认消息如图 3.12 所示,并在表 3.13 中定义。
如果bit n 设置为 1,则segment n 正在被确认。如果bit n 设置为 0,则segment n无法确认。
大于 SegN 的段的任何位都应设置为 0 并在接收时忽略。如果接收到的段是在 TTL 设置为 0 的情况下发送的,建议将相应的段确认消息在 TTL 设置为 0 的情况下发送。
Segmented Control message
当传输控制消息不适合single Network PDU 时,分段控制消息用于传输传输控制消息的一部分。图 3.13 显示了分段控制消息的图示,表 3.14 显示了此消息的字段。
分段与重组
为了传输大于 15 个八位字节的上层传输 PDU,下层传输层会分段并重组上层传输 PDU。这些段使用块确认方案传递给对等的较低传输层,以最小化需要由较低传输层传输的消息数量。
图 3.14 说明了正在发送的上层传输访问 PDU,它具有单个八位字节操作码、3 个八位字节用于 NetKeyIndex 和 AppKeyIndex 字段,以及 16 个八位字节用于 AppKey。
这意味着当使用应用程序密钥加密和验证时,上层传输 PDU 是 24 个八位字节。这被较低的传输层分割成两个段,段 0 和段 1。
每个段都有一个标头,用于标识段号,然后传递到网络层,在那里计算完整的网络 PDU。然后网络层使用该网络 PDU 的序列号加密网络 PDU,然后混淆这些消息,以便只有 NID(和 IV 索引)八位字节以明文形式可见。因此,可以使用两个网络 PDU 安全地传递单个访问消息。
上层传输访问 PDU 和上层传输控制 PDU 的分段过程是相同的,下面的描述认为这两种 PDU 类型是相同的,除非明确说明。
注意:上层传输访问 PDU 和上层传输控制 PDU 的段大小不同。
分段
分段的消息在较低的传输层得到确认,但未分段的消息则不然。
- 如果上层传输 PDU 可以使用未分段消息格式装入单个下层传输 PDU,那么下层传输层应使用未分段消息来传输此上层传输 PDU。
- 如果上层传输 PDU 可以使用分段消息格式装入单个下层传输 PDU,那么下层传输层可以使用单个分段消息来传输此上层传输 PDU。
- 否则,应使用两个或多个分段消息。
分段的消息在the lower transport layer
得到acknowledged
(确认) ,但未分段的消息则不然。当使用分段消息比未分段消息可以更有效地传输上层传输 PDU 的传递时,应使用single-segment segmented message
。
例如,如果在the access layer
发送一条消息以确认已收到多段消息,并可以开始对多条消息进行处理,但此确认消息丢失,则发送方认为没有接受方收到多段消息,必须再次发送完整的多段消息。
相反,如果application acknowledgment message
在a single Segmented Access message
中发送,则application acknowledgment message
将在lower transport layer
传送,可能使用单段的多次传输,从而消除多分段消息重传的需求。
- Upper Transport Access PDU / 上层传输访问 PDU 的每个段应为 12 个八位字节长,最后一段除外,它可能更短。
- Upper Transport Access PDU / 上层传输控制 PDU 的每个段应为 8 个八位字节长,最后一段除外,它可能更短。
重组
在接收设备中执行重组。当使用低功耗节点功能时,消息确认由朋友节点执行,低功耗节点不会发送段确认消息。
收到分段消息后,应检查 SeqAuth 以确定上层传输 PDU 是否正在接收或之前已接收。如果尚未收到分段消息,则接收设备应分配足够的内存,由最后一个分段号(SegN)确定,以在收到上层传输 PDU 的分段时存储它们并跟踪它的分段已经收到,然后它会认为这个消息正在被接收。
如果未使用低功耗节点功能,并且消息的目的地是单播地址,并且节点此时无法接收此上层传输 PDU。例如因为节点繁忙或资源不足,无法重新组装这个消息,然后节点将通过将 BlockAck 值设置为 0x00000000 来通知源节点它无法接收这个上层传输 PDU。
如果分段消息正在接收过程中,那么分段号(SegO)将用于确定该分段消息中的上层传输 PDU 八位字节应放置在先前为该消息分配的内存中的何处。
接收方应更新 BlockAck 值以记录段的成功交付。一旦接收到给定 SeqZero 的上层传输 PDU 的所有段,上层传输层应检查上层传输 PDU(参见第 3.6.4.2 节)
传输行为
如果消息的目的地是单播地址,那么较低的传输层将期待来自该节点或代表该节点的朋友节点的段确认消息。如果消息寻址到虚拟地址或组地址,则这些设备将不会发送段确认消息。
如果 the segmented Upper Transport PDU
的the Lower Transport PDUs
正在发送到组地址或虚拟地址,那么下层传输层应发送 the segmented Upper Transport PDU
的所有the Lower Transport PDUs
。
建议多次发送所有
the Lower Transport PDUs
时,在每次重复中引入小的随机延迟。其旨在显着增加分段的上层传输 PDU 成功交付的可能性。
注意:发送到组或虚拟地址的上层传输 PDU 不会被接收者确认,因此消息传递状态未知,应视为未确认。
当发送低层传输 PDU 时,段传输计时器应启动,在该时间内预计会收到段确认消息。
此计时器应设置为最小 200 + 50 * TTL 毫秒。
注意:收到 OBO 字段设置为 1 的 Segment Acknowledgement 消息并不意味着已将分段消息传递到最终目的地,仅表示它已传递给该 Low Power 节点的朋友。
该消息存储在好友队列中,但如果收到该低功率节点的其他消息或友谊终止,则可以丢弃该消息。
- 如果收到的分段确认消息是对分段消息的有效确认,则较低的传输层应重置分段传输计时器并重新传输所有未确认的较低传输 PDU。
- 如果接收到确认上层传输 PDU 的所有下层传输 PDU 的段确认消息,则上层传输 PDU 完成。
- 如果接收到 BlockAck 字段设置为 0x00000000 的段确认消息,则应立即取消上层传输 PDU,并应通知较高层上层传输 PDU 已被取消。
- 如果分段传输定时器超时并且没有收到对分段消息的有效确认,那么下层传输层将重传所有未确认的下层传输 PDU。
注意:当重传每个下层传输 PDU 时,段传输定时器被重置并重新启动。
上层传输 PDU 的每个下层传输 PDU 应至少传输两次,除非提前确认。如果下层传输层在所有下层传输 PDU 被确认之前停止重传下层传输 PDU,则上层传输 PDU 被取消。
重组在开启低功耗模式和关闭低功耗模式有不同的规范。