文章目录

  • 前言
  • Mesh Message
  • Advertising bearer
  • Network PDU
  • Mesh beacons
  • Unprovisioned Device beacon
  • Secure Network beacon
  • PB - ADV
  • Provisioning
  • Provisioning bearer layer
  • PB-ADV PDU


前言

蓝牙Mesh网络一共有3种广播包,如下图所示,我们接下来按照PDF章节顺序依次介绍。

android 蓝牙mesh库 蓝牙mesh数据包大小_字段


另外厂商可以自定义ADV data来制造自己的Beacon广播,在一个或多个标准广播数据包中编码数据,传递信息。

android 蓝牙mesh库 蓝牙mesh数据包大小_mesh_02

但是编码原理可能有所差异,即帧格式不同。目前主流的三种帧格式分别为苹果公司的iBeacon,Radius Networks公司的AltBeacon以及谷歌公司的Eddystone。

android 蓝牙mesh库 蓝牙mesh数据包大小_字段_03

  • 当多个八位字节值被定义为以“大端”(也称为“网络字节顺序”)发送时,数据增长方向与内存增长方向相同。例如,值 0x123456 应作为 0x12、0x34 和 0x56(最重要的八位字节在前)传输。
  • 当多个八位字节值被定义为以“小端”发送时,数据增长方向与内存增长方向相反。例如,值 0x123456 应作为 0x56、0x34 和 0x12(最低有效八位字节在前)传输。

Mesh Message

Mesh Message,这个是在设备入网后,进行数据通信的时候大量使用的包。节点间通信就是使用这种包进行的。

Advertising bearer

android 蓝牙mesh库 蓝牙mesh数据包大小_蓝牙_04

任何使用Mesh Message AD type的广播都应是不可连接和不可扫描的无向广播事件。如果节点在可连接广播或可扫描广播事件中接收到 Mesh Message AD type,则应忽略该消息。

注意:不可连接的广播被使用,因为不需要在广播数据包中包含Flag AD type,从而允许将两个额外的八位字节分配给Network PDU(参见后文)。为了降低所有广播通道上数据包冲突的概率,建议随机化广播事件中连续数据包之间的间隙。

仅支持广播承载的设备应以尽可能接近 100% 的占空比执行被动扫描,以避免丢失任何传入的网格消息或供应 PDU。所有设备都应支持 GAP Observer 角色和 GAP Broadcaster 角色。



Network PDU

网络层定义了网络 PDU 格式,允许承载层传输较低的传输 PDU。

它将在输入接口上接收到的传入消息解密和验证并将其转发到上层和/或输出接口,并加密和验证并转发传出消息,将它们传递到输出网络接口。

The mesh Network PDU 格式在表 3.7 中定义,并在下面的图 3.7 中说明:

android 蓝牙mesh库 蓝牙mesh数据包大小_网络_05


使用从 NID 字段标识的a single network key 派生的密钥来保护Network PDU。

android 蓝牙mesh库 蓝牙mesh数据包大小_网络_06

  • IVI:IVI 字段包含用于验证和加密此网络 PDU 的随机数中的 IV 索引的最低有效位(参见第 3.8.3 节)。
  • NID:NID 字段包含一个 7 位网络标识符,允许更轻松地查找用于验证和加密此网络 PDU 的加密密钥和隐私密钥(参见第 3.8.6.3.1 节)。NID 值源自网络密钥以及加密密钥和隐私密钥。对于主网络消息和朋友与其低功耗节点之间的私有网络消息,它的派生方式不同(参见第 3.8.6.3.1 节)
  • CTL:CTL 字段是一个 1 位值,用于确定消息是控制消息还是访问消息的一部分,如表 3.8 所示。
    如果 CTL 字段设置为 0,则 NetMIC 是一个 32 位值并且下层传输 PDU 包含一个访问消息。
    如果 CTL 字段设置为 1,则 NetMIC 是一个 64 位值并且下层传输 PDU 包含一个控制消息。
  • TTL:TTL 字段是一个 7 位字段。该字段的初始值由传输层(lower transport layer, upper transport layer,
    access, foundation model, model)或应用程序设置,并在作为中继节点运行时由网络层使用。 **TTL 值为零表示允许节点传输那些它知道不会被中继的网络 PDU,因此接收节点可以确定发送节点与单个无线电链路相距。**使用 1 或更大的 TTL 值不能用于这种确定。 其定义了以下值:
  • 0 = 没有被转发,也不会被转发
  • 1 = 可能已转发,但不会转发
  • 2 ~ 126 = 可能已中继并且可以中继
  • 127 = 未中继且可以中继
  • SEQ:SEQ 字段是一个 24 位整数。组合的 SEQ 字段、IV 索引字段和 SRC 字段(参见第 3.4.4.6 节)对于该元素产生的每个新网络 PDU 应是唯一值。
  • SRC:SRC 字段是一个 16 位值,用于标识发起此网络 PDU 的元素。该地址应为单播地址。SRC 字段由发起元素设置,并且不受作为中继节点操作的节点的影响。
  • DST:DST 字段是一个 16 位值,用于标识此网络 PDU 所指向的一个或多个元素。该地址应为单播地址、组地址或虚拟地址。DST 字段由始发节点设置,并且在作为中继节点运行的节点中不受网络层影响。
  • TransportPDU:从网络层的角度来看,TransportPDU 字段是数据的八位字节序列。当 CTL 位为 0 时,TransportPDU 字段最大为 128 位。当 CTL 位为 1 时,TransportPDU 字段最多为 96 位。TransportPDU 字段由the originating lower transport layer设置,网络层不得更改。
  • NetMIC:NetMIC 字段是一个 32 位或 64 位字段(取决于 CTL 位的值),用于验证 DST 和 TransportPDU 未更改。当 CTL 位为 0 时,NetMIC 字段应为 32 位。当 CTL 位为 1 时,NetMIC 字段应为 64 位。NetMIC 由网络层在传输或中继此网络 PDU 的每个节点上设置。

消息通过网络接口从承载层传递到网络层。图 3.8 说明了传入网络 PDU 的处理步骤示例:

android 蓝牙mesh库 蓝牙mesh数据包大小_字段_07

Mesh beacons

Mesh Beacon 包含两种类型:Unprovisioned Device beaconSecure Network beacon,根据包头的 Beacon Type 可以区分。

android 蓝牙mesh库 蓝牙mesh数据包大小_蓝牙_08


其中Unprovisioned Device Beacon是用来被Provisioner发现设备用的,也就是在Provisioning之前设备发送的包,这个包里会包含Manufacturer相关的Device UUID(128bits)这个Device UUID是用来区分设备的,因此需要保证唯一性。

Secure Network beacon则是设备入网后用来发送一些安全相关的包,比如IV index更新包。

因此一个正常流程是这样的:

1、设备(入网前)广播Unprovisioned Device beacon的广播包,这个包里包含Device UUID

2、Provisioner(比如蓝牙网关,手机等)通过扫描发现这个设备,并通过Device UUID和云端同步设备信息(比如厂家信息,产品功能等等),然后通过PB-ADV的包发起Provisioning过程

3、设备成功加入Mesh网络后,如果需要,可以通过Secure Network beacon更新IV index。当然大部分时间,设备是通过Mesh Message的信息和其他节点进行数据通信。

Mesh beacons是由节点和未配置的设备定期广播的数据包。

Mesh beacons包含在«Mesh Beacon» AD Type中。Mesh Beacon 广播数据有效载荷的第一个八位字节(Beacon Type 字段)决定了信标的类型。使用代理协议将Mesh Beacon 转发到其他bearers(参见第 6 节)。

Mesh Beacon AD Type 的格式如图3.44所示。

android 蓝牙mesh库 蓝牙mesh数据包大小_网络_09


Mesh beacons应使用不可连接和不可扫描的无向广播事件进行广播。Mesh beacons中的所有多八位字节数值应以“大端”发送。

Unprovisioned Device beacon

Unprovisioned Device beacon 由未设置的设备使用,以允许设置器发现它们。该信标的格式如图 3.45 所示,并在表 3.53 中定义。

android 蓝牙mesh库 蓝牙mesh数据包大小_android 蓝牙mesh库_10

android 蓝牙mesh库 蓝牙mesh数据包大小_字段_11

Secure Network beacon

节点使用Secure Network beacon来识别子网及其安全状态。该信标的格式如图 3.46 所示,并在表 3.55 中定义。

android 蓝牙mesh库 蓝牙mesh数据包大小_mesh_12

PB - ADV

Provisioning

Provisioning 是将未配置的设备添加到网状网络的过程,由 Provisioner 管理。Provisioner 为未配置的设备提供配置数据,使其成为a mesh node。供应数据包括网络密钥、当前 IV 索引和每个元素的单播地址。

Provisioner 通常是智能手机或其他移动计算设备。尽管网络上只需要一个 Provisioner 来进行配置,但也可以使用多个 Provisioner。在多个 Provisioner 之间共享缓存数据和协调的方法是特定于实现的。

为了 provision a device,必须在开通方和设备之间建立the provisioning bearer

设备可以通过其设备 UUID 和其他可能提供的补充信息向供应商标识。The provisioning bearer建立后,供应器使用椭圆曲线 Diffie-Hellman (ECDH) 协议与设备建立共享secret。然后,它使用特定于该设备的 OOB 信息对设备进行身份验证。这样的OOB信息可以包括设备的公钥、·a long secret·、向设备输入值的要求或在该设备上输出值的要求。

此类 OOB 信息还支持对该设备进行身份验证。设备通过身份验证后,供应数据将传输到使用从该共享秘密派生的密钥加密的设备。设备密钥源自 ECDHSecret 和 ProvisioningSalt。

android 蓝牙mesh库 蓝牙mesh数据包大小_网络_13


设备的 Provisioning 是使用发送配置 PDU 的配置协议完成的。使用Generic Provisioning layer 或 Proxy protocol layer将Provisioning PDU 传输到unprovisioned device。这些层定义了如何将供应 PDU 作为可以分段和重组的事务传输。这些交易通过 provisioning bearer发送。

provisioning bearer 定义了如何建立会话,以便可以将来自通用供应层的事务传送到单个设备。 最后,在供应架构的底部是 the bearers。

除非另有说明,本层中的所有多字节数值都应为“大端”,如第 3.1.1.1 节所述。

Provisioning bearer layer

供应承载层支持在供应器和未供应设备之间传输供应 PDU。定义了两个供应承载:

  • PB-ADV(见第 5.2.1 节)
  • PB-GATT(参见第 5.2.2 节)未配置的设备可能支持 PB-ADV,也可能支持 PB-GATT。

Provisioner 应至少支持 PB-ADV 或 PB-GATT 之一。强烈建议支持PB-ADV。

PB-ADV PDU

PB-ADV 是一种 provisioning bearer,用于通过广播通道使用Generic Provisioning PDUs(参见第 5.3 节) 去 provision 一个设备。

供应机制是基于会话的。未配置的设备一次只能支持一个会话。Provisioner 没有这样的限制,使用链路建立过程建立会话(参见第 5.3.2 节)。

PB-ADV 承载用于传输通用供应 PDU。PB-ADV 承载 MTU(最大传输单元)大小为 24 个八位字节。当使用 PB-ADV 时,应使用由«PB-ADV» 标识 的 PB-ADV AD Type 发送 Generic Provisioning PDU。

支持 PB-ADV 的设备应以尽可能接近 100% 的占空比执行被动扫描,以避免丢失任何传入的通用配置 PDU。

PB-ADV AD Type 包含一个 PB-ADV PDU。此 AD Type的格式在表 5.1 中定义。

android 蓝牙mesh库 蓝牙mesh数据包大小_网络_14


PB-ADV PDU 的格式在表 5.2 中定义。

android 蓝牙mesh库 蓝牙mesh数据包大小_蓝牙_15


任何使用 PB-ADV AD Type 的广播应是不可连接和不可扫描的无向广播事件。如果节点在可连接或可扫描广播事件中接收到 PB-ADV AD Type,则应忽略该消息。

发送 PB-ADV PDU 时应执行以下规则:

  1. 当 PB-ADV PDU 包含 Provisioning Bearer Control PDU 时,Transaction Number 字段应设置为 0 并在接收时忽略。
  2. 当提供者第一次通过开放的提供链接发送一个提供 PDU 时,它应该以 0x00 的 the Transaction Number 开始。Provisioner 应为它在提供链路持续时间内发送的每个新 Provisioning PDU 将字段值加 1。
  3. 如果该字段值已达到 0x7F,则在发送下一个 Provisioning PDU 时,它应回绕到 0x00。
  4. 当未配置的设备第一次通过open provisioning link发送一个配置 PDU 时,它应该以 0x80 的 the Transaction Number 开始。设备应为它在供应链路持续时间内发送的每个新供应 PDU 将字段值增加 1。
  5. 如果该字段值已达到 0xFF,则在发送下一个 Provisioning PDU 时它应回绕到 0x80。
  6. 当一个设备正在接收一个 Provisioning PDU 时,它应该将 the Transaction Number 设置为事务期间接收的 PB-ADV PDU 的 the Transaction Number 的值。
  7. 当设备发送Transaction Acknowledgement PDU时,the Transaction Number字段应设置为传输被确认的供应 PDU 的 PB-ADV PDU 的 the Transaction Number字段的值。