首页 最新 热门 推荐

  • 首页
  • 最新
  • 热门
  • 推荐
2025年7月6日 星期日 11:23am

BLE 技术(八)--- BLE MESH 各层报文是如何设计的(上)?

  • 24-03-03 17:01
  • 2916
  • 9626
blog.csdn.net

文章目录

  • 前言:
  • 一、SIG MESH Bearer Layer
    • 1.1 Advertising Bearer Layer
    • 1.2 GATT Bearer Layer
  • 二、SIG MESH Provisioning
    • 2.1 Unprovisioned Device Beacon
    • 2.2 MESH Provisioning Process
      • 2.2.1 Link Establishment Procedure
      • 2.2.2 Provisioning Protocol
  • 三、MESH Beacon and Security state
    • 3.1 Key Refresh procedures
    • 3.2 IV Update procedure
  • 四、SIG MESH Network Layer
    • 4.1 Publish/Subscribe Addresses
    • 4.2 Encrypted/Obfuscated Network PDU
    • 4.3 Receiving/Transmitting Network PDU
  • 五、SIG MESH Transport Control messages
    • 5.1 Unsegmented Control Message
      • 5.1.1 Heartbeat message
      • 5.1.2 Friendship messages
      • 5.1.3 Segment Acknowledgment message
    • 5.2 Segmented Control message
  • 更多文章:

前言:

前篇博文BLE MESH 是如何设计的 介绍了SIG MESH 为解决大规模物联网设备之间安全可靠高效通信的问题,采用了哪些设计来传递消息并应对各种网络攻击的、如何支持低功耗节点和大量现有BLE GATT 节点的入网通信等。前篇博文从解决问题的角度介绍了SIG MESH 协议的设计方案,本篇博文从MESH 消息报文在各协议层的传递过程,介绍SIG 是如何设计MESH 报文结构的、又是如何处理MESH 报文消息的。
BLE MESH 消息流程图

  • Bearer Layer:定义了如何使用底层BLE 协议栈传输MESH 消息报文PDU,目前定义了Advertising Bearer 和GATT Bearer 两种承载层。其中GATT Bearer 是为了让现有无法升级MESH 协议的BLE 设备接入MESH 网络,Advertising Bearer 是MESH 协议主要的承载层,Advertising Bearer 又可分为Mesh Beacon Advertising Bearer 和Mesh Advertising Bearer,前者主要用来启动配网和更新安全密钥,后者主要用来传输消息;
  • Network Layer:定义了MESH 消息报文如何安全寻址到一个或一组元素,启动配网后分发的NetKey 就是用于网络层消息报文加解密认证和完整性校验的(实际使用的是NetKey 派生的EncryptionKey 和PrivacyKey)。网络层为不同的承载层定义了不同的网络接口(包括用于本节点内不同元素间通信的本地网络接口),可通过配置 input / output filter 对经网络接口输入或输出的消息进行过滤,从网络接口接收到的报文根据其目的地址字段判断是需要中继/代理转发还是递交上层处理;
  • Lower Transport Layer:定义了如何将上层传输层消息分段为多个网络层协议可以处理的大小,如何将来自网络层协议的分段数据重新组合为完整消息递交给上层传输层处理,还定义了用于确认重传的分段消息应答报文。如果是Friend 节点接收到了要发送给与其建立友谊关系的低功耗节点的报文,则在该层将消息报文放入对应的Friend Queue,待收到来自LPN 的Friend Poll 报文后将缓存报文发送给LPN;
  • Upper Transport Layer:定义了如何对应用消息(也即来自访问层的Access PDU)进行加解密认证和完整性校验(应用消息使用与模型绑定的AppKey 加密认证,配置消息使用为目标节点分配的DevKey 加密认证)。上层传输层也会为每个消息分配一个序列号SEQ 用于防护中继/重放攻击,该层还定义了用于管理Friendship 和Heartbeat 相关的控制报文(用于管理LPN 与FN 之间友谊建立/终止、订阅地址添加/移除、消息轮询与发送,心跳报文发布/接收、节点距离或跳数Hop count 计算等过程);
  • Access Layer:定义更高层应用程序如何使用上层传输层,比如定义应用程序数据的格式(通常指各种 Model)、定义和控制上层传输层执行的应用数据加密和解密过程(AppKey 通常是绑定到特定Model 的)、验证从上层传输层接收的数据是否适用于正确的网络和应用程序(报文中的NetKeyIndex 和AppKeyIndex 等信息)等,通过验证的消息根据目的地址和模型识别码递交给目标元素和目标模型处理;
  • Foundation Model Layer:定义了配置和管理MESH 网络及其节点设备所需的状态、消息和模型。基础模型层主要定义了两组模型:一组是配置服务端模型和配置客户端模型,MESH 网络所有设备节点都需要实现配置服务端模型(包含一系列与配置相关的状态和消息),为该设备节点提供各种配置能力(比如配置发布消息时的目的地址和TTL、元素或模型的订阅地址、设备节点可能扮演的Relay/Friend/Low Power/Proxy 角色等),用户可以使用实现了配置客户端模型的设备(比如智能手机APP)凭对应的DevKey 来获取或改变设备节点的配置状态;另一组是健康服务端模型和健康客户端模型,MESH 网络所有设备节点的主元素都需要实现健康服务端模型(包含一系列与故障相关的状态和消息),为该设备节点提供各种故障报告和诊断能力(比如当前故障、注册故障等),用户可以使用实现了健康客户端模型的设备(比如智能手机APP)凭对应的AppKey 来获取或接收设备节点的健康状态;
  • Model Layer:定义了用于标准化典型用户场景操作的模型,目前SIG MESH Model Specification 中定义了Generics、Sensors、Time and Scenes、Lighting 等四组模型,每组模型都包含一系列具体的模型,每个模型都定义了一组状态、状态间的绑定关系、作用于状态的消息、响应消息的行为等。除了上述SIG 定义的Bluetooth SIG models,供应商也可以在SIG 模型无法满足需求的情况下定义Vendor models;
  • Application Layer:应用开发服务于用户场景、依托于各种标准化模型,通过业务逻辑把不同功能的Model 组合起来,实现一个特定功能或者服务,比如楼宇照明网络中的复杂灯控功能、工厂车间或农业大棚传感网络中的复杂监测功能、智能家居各种MESH 设备间的复杂联动功能等。

一、SIG MESH Bearer Layer

SIG MESH 作为网络协议,是承载在BLE 物理层和数据链路层之上的,为了使用BLE 协议栈传输MESH 消息报文PDU,引入了MESH Bearer Layer。

目前MESH Bearer Layer 定义了Advertising Bearer 和GATT Bearer 两种承载层:GATT Bearer 是为了让无法升级MESH 协议的BLE 设备能够接入MESH 网络;Advertising Bearer 则是SIG MESH 网络主要的消息报文传输承载层。

1.1 Advertising Bearer Layer

虽然BLE 5.x 协议为了提高传输速率和扩大传输距离,新增支持LE 2M PHY 和LE Coded PHY 两种空口报文;为了提高广播能力,新增支持Extended Advertising Channel(可以将数据信道作为广播信道使用,且单个扩展广播包可承载更多载荷数据)。

但是,目前的SIG MESH 1.0.1 协议并不支持BLE 5.x 协议的新特性,仍然使用传统的 3 个固定广播信道(channel 37、38、39)和LE 1M PHY 空口报文来传输MESH 消息报文(或许后续的MESH 2.x 协议支持BLE 5.x 协议新特性吧)。

SIG MESH 广播包并不需要对方连接,也不会响应对方的扫描请求,因此MESH Advertising Bearer Layer 使用ADV_NONCONN_IND 广播报文来承载MESH 消息报文。不可连接不可扫描非定向的广播报文payload 支持的AdvData 最大长度为 31 octets,所以MESH Advertising Bearer 报文的最大长度也只有 31 字节。
SIG MESH Advertising Bearer 报文格式
AdvData 被划分为一系列AD structures,每个AD structure 包含AD Length、AD Type、Content 三个字段。每个MESH 广播报文只包含一个AD structure,MESH 协议仅支持如下三种广播报文(参阅:Assigned Numbers – GAP):

AD Type
               
Type Name
                             
Content
0x29«PB-ADV»PB-ADV PDU,包含 Link ID (4 octets)、Transaction Number (1 octets)和Generic Provisioning PDU (1 - 24 octets) 三部分
0x2A«Mesh Message»Network PDU (1 - 29 octets)
0x2B«Mesh Beacon»Mesh Beacon PDU,包含Beacon Type (1 octets) 和Beacon Data 两部分,其中Beacon Type 目前只定义了Unprovisioned Device beacon 和Secure Network beacon 两种类型
  • «PB-ADV»:主要用于启动配网过程中邀请入网–>创建安全通道–>身份认证–>安全密钥分发等过程必要信息的传输,可以承载的Generic Provisioning PDU 最大为24 个字节。Link ID 用于标识Provisioner 与New Device之间建立的通信链路,Transaction Number 则用于标识每个单独的Generic Provisioning PDU(分段或重传报文的Transaction Number 相同,新的单独PDU 报文则Transaction Number 自增 1);
  • «Mesh Message»:主要用于承载MESH 网络层的消息报文,可承载的Network PDU 最大为29 个字节;
  • «Mesh Beacon»:目前定义了Unprovisioned Device beacon 和Secure Network beacon 两种类型:Unprovisioned Device beacon 主要用于未配网设备对外广播,以便Provisioner 能发现自己,并向自己发出入网邀请;Secure Network beacon 主要用于识别并通知子网内的设备节点进行 IV Index 更新或密钥刷新过程。

MESH 网络节点之间通过ADV_NONCONN_IND 广播报文进行通信时,需要设备同时支持GAP Observer role 和GAP Broadcaster role。由于MESH 网络节点设备随时都有可能接收到消息报文,为了避免丢失传入的广播数据包,MESH 设备应以尽可能接近 100% 的占空比执行被动扫描过程(也即scanWindow 尽可能等于scanInterval)。为了尽量降低多个MESH 设备节点同时广播导致广播信道上数据包冲突的概率,广播间隔advInterval 应尽可能设置为随机值。

1.2 GATT Bearer Layer

MESH GATT Bearer Layer 是为了让无法升级MESH 协议的BLE 设备能够接入到MESH 网络中而设计的,GATT Bearer Layer 使用Proxy protocol 通过GATT 连接在两个设备之间发送或接收Proxy PDU。

使用BLE GATT 连接传输数据需要在GATT Server 实现相应的GATT Service 和Characteristic,GATT Client 则通过发现Service、读写Characteristic 实现服务数据的传输。
MESH Proxy Server-Client GATT Services
MESH GATT Bearer 定义了两个角色:GATT Bearer Server 和GATT Bearer Client,由于二者使用Proxy protocol 通信,因此也可称为MESH Proxy Server 和MESH Proxy Client。

MESH GATT Bearer 也提供了两个GATT 服务:Mesh Provisioning Service 和Mesh Proxy Service,每个Service 都提供了两个Characteristic(参阅:Assigned Numbers – 16-bit UUIDs):

GATT Services UUIDGATT Services NameGATT Characteristic
0x1827Mesh Provisioning ServiceMesh Provisioning Data In (0x2ADB)
Mesh Provisioning Data Out (0X2ADC)
0x1828Mesh Proxy ServiceMesh Proxy Data In (0X2ADD)
Mesh Proxy Data Out (0X2ADE)

GATT Bearer Client 发现GATT Bearer Server 提供的Service 和Characteristic 后(可参阅:GATT Profile 和Service Discovery),通过Mesh Provisioning/Proxy Data In Characteristic 的Write Without Response 方法向GATT Bearer Server 发送数据,通过Mesh Provisioning/Proxy Data Out Characteristic 的Notify 方法从GATT Bearer Server 接收数据,实现在GATT 连接上发送或接收Proxy PDU 的功能。

MESH GATT Bearer 通过Mesh Provisioning Service 或Mesh Proxy Service 传输的Proxy PDU 格式如下:
MESH Proxy PDU Format
MESH Proxy PDU 目前支持的消息类型有四种:

  • Network PDU:MESH 网络层的消息报文,同MESH Advertising Bearer 中的«Mesh Message»,是否需要分段传输取决于ATT_MTU 的配置值;
  • Mesh Beacon:同MESH Advertising Bearer 中的«Mesh Beacon»,目前定义了Unprovisioned Device beacon 和Secure Network beacon 两种类型;
  • Proxy Configuration:主要用于Proxy Client 向Proxy Server 配置过滤条件,Data 部分由Opcode(1 octets) 和Parameters(variable) 两部分构成(相当于配置Proxy Client 的订阅地址列表),比如向Proxy Server 维护的白名单或黑名单中新增或删除地址;
  • Provisioning PDU:用于Provisioner 与New Device之间启动配网过程中必要信息的交换,MESH Advertising Bearer 中的Generic Provisioning PDU 由«PB-ADV» 承载,MESH GATT Bearer 中Provisioning PDU 则是由«PB-GATT» 承载。

由此可知,MESH Advertising Bearer 和MESH GATT Bearer 封装的有效载荷Network PDU、Mesh Beacon、Provisioning PDU 都是相同的,只是MESH Bearer Layer 封装的外壳有区别。

二、SIG MESH Provisioning

一个BLE 新设备要想加入到一个MESH 网络中并与其它MESH 节点通信,需要通过执行启动配网过程Provisioning。启动配网过程是 Provisioner 向对外广播Unprovisioned Device beacon 报文的设备发起入网邀请–>创建安全通信链路–>验证入网者身份–>分发网络安全密钥等一系列过程的组合(参阅博文:启动配网与密钥分发)。

2.1 Unprovisioned Device Beacon

一个BLE 设备上电启动后,要想让附近的Provisioner 发现该设备,并向自己发起配网邀请,自己需要周期性向外广播Unprovisioned Device Beacon 报文。Provisioner 设备扫描到Unprovisioned Device Beacon 报文后,才知道附近有想要入网的设备,可以向其发送入网邀请报文。

Unprovisioned Device Beacon 报文是«Mesh Beacon» 的其中一种类型,该报文的格式如下:
Unprovisioned device beacon format

FieldSize (octets)Description
Beacon Type1Unprovisioned Device beacon type (0x00)
Device UUID16这个设备的全局唯一标识符,128 位UUID
OOB Information2通知Provisioner 本设备OOB 数据的可用性,比如是否支持通过二维码或者NFC传输设备公钥
URI Hash4指向OOB 信息(比如设备公钥)的统一资源定位符哈希值,该字段是可选的

Provisioner 扫描到附近广播Unprovisioned Device Beacon 报文的设备,就可以向该设备发起配网邀请报文,开始启动配网过程了。

2.2 MESH Provisioning Process

MESH 启动配网过程是Provisioner 将Unprovisioned Device 加入到MESH 网络中的过程。Provisioner 可以是手机、平板电脑或其它智能设备,每个MESH 网络只需要一个Provisioner 设备,当然也支持多个Provisioner 设备,但同一MESH 网络中的多个Provisioner 设备数据要共享且同步。

启动配置设备Provisioner 与Unprovisioned Device 在进行启动配网过程中,需要交换很多数据报文,启动配网过程的报文可统称为Provisioning PDU。对于支持MESH 协议的设备,使用Advertising Bearer Layer 承载数据报文,Provisioning PDU 便封装在PB-ADV 广播报文中。对于不支持MESH 协议的BLE 设备,使用GATT Bearer Layer 承载数据报文,Provisioning PDU 便封装在PB-GATT 数据报文中,且Provisioner 需要提供Mesh Provisioning Service 来传输PB-GATT 数据报文。
Provisioning protocol stack

2.2.1 Link Establishment Procedure

Provisioner 与Unprovisioned Device 之间交换Provisioning PDUs,双方需要建立可靠的通信链路,甚至应该支持数据包的分片重组功能。

对于PB-GATT 承载的Provisioning PDUs,Provisioner 与Unprovisioned Device 之间的通信链路由BLE GATT 管理,借助GATT Mesh Provisioning Service 在双方之间传递数据报文还是比较可靠的。如果ATT_MTU 设置长度不足以容纳完整的Provisioning PDUs 报文,则Proxy PDU 中的SAR(Segmentation And Reassembly) 字段可用于同一Provisioning PDU 被分割为多个 Attribute PDU(包括反向重组过程)。

对于PB-ADV 承载的Provisioning PDUs,Provisioner 与Unprovisioned Device 之间的通信报文在Advertising 信道传输,单向广播通信属于不可靠通信,MESH 协议需要在进行广播通信的设备间建立并维护可靠的通信链路,该如何基于单向广播信道建立可靠的通信链路呢?

基于单向广播通信建立可靠的通信链路,可以参考连接通信建立的过程。BLE 连接建立过程是Initiator 向特定Advertiser 发送包含Device Address 的连接请求报文,Provisioning 链路建立过程则是Provisioner 向特定Unprovisioned Device 发起链路建立报文:
Establishment of Link by ID between a Provisioner and an unprovisioned device
由于广播通信是单向的,要保证通信的可靠性,需要通信对端设备回复Ack 应答报文,上图中Unprovisioned Device 向Provisioner 回复的Link Ack 报文就是响应Link Open 报文的,前面介绍的«PB-ADV»报文中的Link ID 则可以标识这里建立的通信链路。

Provisioner 与Unprovisioned Device 之间建立通信链路后,如何保证通信的可靠性呢?首先就是为了解决单向通信的不可靠性,引入Ack 确认应答报文,可以让通信对端及时知道前一个数据包是否被正确接收。

除了确认应答报文设计,还需要考虑单个PB-ADV 无法承载完整的Provisioning PDU 报文,需要支持报文的分片重组功能。前面介绍的«PB-ADV»报文中的Transaction Number 字段可以标识每个单独的Generic Provisioning PDU,但如何区分这个单独的Provisioning PDU 分割出的起始报文和后续报文呢?

参考Proxy PDU 中SAR 字段的作用,«PB-ADV»报文中的Generic Provisioning PDU 除了承载Generic Provisioning PDU 外,还可以设计控制通信链路建立、报文确认应答、区分每个单独的Generic Provisioning PDU 分割出的起始报文和后续报文的Generic Provisioning Control 部分。于是,«PB-ADV»报文的格式设计成如下的样子(图片取自博文:Mesh Provisioning):
PB-ADV 承载Generic Provisioning Control 构成
从上图各字段的名字也可以看出其作用,比如Provisioning Bearer Control PDU 设计了通信链路建立、应答、关闭等三种报文,Transaction Start PDU 和Transaction Continuation PDU 则标识每个单独的Generic Provisioning PDU 分割出的起始报文和后续报文,Transaction Acknowledgment PDU 则是确认应答报文。也即,«PB-ADV»报文中的Generic Provisioning Control 部分用于Provisioner 与Unprovisioned Device 之间基于广播信道建立可靠的通信链路,保证Provisioning Process 的顺利进行。

2.2.2 Provisioning Protocol

Provisioner 与Unprovisioned Device 之间建立了可靠的通信链路后,就可以使用Provisioning Protocol 执行启动配网过程了。Provisioning Process 的四个阶段(邀请Unprovisioned Device 入网–>创建安全通信链路–>验证Unprovisioned Device 的身份–>向Unprovisioned Device 分发安全密钥)已经在前篇博文中介绍过了,这里列出四个阶段使用到的Provisioning PDU 格式及类型说明(每种类型Provisioning PDU 的格式设计可参阅Mesh Profile Section 5.4):
Provisioning PDU format
Provisioner 与Unprovisioned Device 之间的启动配网过程,可以对比BLE Central/Master 与BLE Peripheral/Slave 之间的LE 安全配对过程来理解。整个启动配对过程的流程如下:
BLE MESH 启动配置入网过程

  1. Scan for Unprovisioned Device Beacons:Provisioner 扫描周围Unprovisioned Device 广播的Unprovisioned Device Beacon,并根据该报文中的OOB Information 字段信息判断OOB 信息是否可用;
  2. Invitation & Capabilities:Provisioner 根据Unprovisioned Device Beacon 报文中的Device UUID 信息选择邀请入网的设备,并向其发送Provisioning Invite 入网邀请报文,收到该报文的Unprovisioned Device 则回复Provisioning Capabilities 报文,告知Provisioner 自己支持的元素数量、安全算法、是否支持OOB 公钥、Input/Output/Static OOB 能力等信息;
  3. Start without / using OOB Public Key:Provisioner 收到Provisioning Capabilities 报文后,向Unprovisioned Device 发送Provisioning Start 报文,告诉对方自己选择的安全算法(目前MESH 仅支持FIPS P-256 Elliptic Curve)、是否使用OOB 公钥、身份认证方法等信息,并使用Provisioning Public Key 报文向其发送公钥信息。若使用OOB 公钥,则Provisioner 通过OOB 链路(比如二维码或者NFC链路)从Unprovisioned Device 读取公钥信息,若不使用OOB 公钥 则Unprovisioned Device 通过Provisioning Public Key 报文向Provisioner 发送公钥信息。双方交换公钥后,通过ECDH 密钥协商算法计算出共享密钥,并通过共享密钥加密创建安全通信链路;
  4. Use Output / Input / Static / No OOB:Provisioner 为了保证MESH 网络安全,需要用户参与验证入网者的身份,防止攻击者的设备入网获取安全密钥。Provisioner 根据选定的身份认证方法对Unprovisioned Device 进行身份认证:若选择Output OOB 认证方法,用户可以将Unprovisioned Device 闪烁/蜂鸣次数或者显示的数字字母信息输入到Provisioner 中;若选择Input OOB 认证方法,用户可以向Unprovisioned Device 按压/扭转/输入 Provisioner 显示的数字,完成输入后Unprovisioned Device 向Provisioner 发送Provisioning Input Complete 报文;若选择Static OOB,用户可以向Provisioner 输入与Unprovisioned Device 绑定的特定信息;若选择No OOB 则不需要用户参与认证,因此是不安全的。用户输入认证信息后,双方还需要计算出Confirmation value,并通过Provisioning Confirmation 和Provisioning Random 报文完成Confirmation value 的校验;
  5. Distribution of Provisioning Data:Provisioner 完成对Unprovisioned Device 的身份校验后,使用创建的安全通信链路向Unprovisioned Device 发送Provisioning Data 报文,该报文包括Network Key、Key Index、IV Index、Unicast Address、Key Refresh Flag / IV Update Flag等MESH 安全密钥信息,Unprovisioned Device 成功接收并处理这些安全密钥信息后向Provisioner 回复Provisioning Complete 报文,整个启动配网过程完成,先前的Unprovisioned Device 变成了MESH Node,其它MESH 节点通过分配的Unicast Address 寻址该设备。

MESH 设备经过启动配网后,也会生成一个DevKey,该密钥是只有本设备节点和Configuration Client 才知道的接入层密钥。Configuration Client 如果需要对某个节点设备进行配置,需要使用该节点设备的DevKey 加密认证配置消息,目标节点设备使用同样的DevKey 成功解密并通过完整性校验后才会处理该配置消息。

DevKey = k1(ECDHSecret, ProvisioningSalt, “prdk”)

三、MESH Beacon and Security state

我们使用某些对信息安全比较敏感的应用时(比如邮箱、网银等),通常需要定期更新密钥,当我们决定当前密钥不再安全时,也会主动去更改密码。MESH 网络对通信安全尤其看重,因此也会有密钥参数更新过程。

MESH 网络中设备节点较多,没法做到所有设备统一更新密钥,因此通常有一个新旧密钥共存的过渡阶段,比如为了应对垃圾桶攻击,从MESH 网络移除节点时需要执行的密钥刷新程序,或者为了应对重放攻击,在SEQ 将要递增到最大值时执行的 IV Index 更新过程等。

在MESH 网络安全参数更新过程中,Secure Network Beacon 报文可以通知设备节点当前使用新密钥参数还是旧密钥参数,在MESH 节点间同步协调新旧安全参数的切换过程。Secure Network Beacon 报文格式如下:
Secure Network beacon

FieldSize (octets)Description
Beacon Type1Secure Network beacon (0x01)
Flags1Bit-0 (Key Refresh Flag):0->未处于更新阶段;1->处于更新阶段
Bit-1 (IV Update Flag):0->正常状态;1-> IV更新状态
Bit 2~7:Reserved for Future Use
Network ID8当前的Network ID 值
IV Index4当前的 IV Index 值
Authentication Value8当前 security network beacon 的认证或鉴权值,采用AES-CMAC 算法生成

Authentication Value = AES-CMACBeaconKey(Flags || Network ID || IV Index) [0–7]

BeaconKey = k1 (NetKey, salt, P)

由于Secure Network Beacon 报文并没有经过加密,为了防止攻击者伪造该报文影响安全参数更新过程,设备节点接收到该报文后需要校验Authentication Value,该值是通过BeaconKey 认证加密的,BeaconKey 是通过入网时被分发的NetKey 计算出来的,也即只有知道NetKey 的设备节点发出的Secure Network Beacon 报文才会被持有相同NetKey 的设备节点校验通过并接受。

从Secure Network Beacon 报文格式可以看出,其主要服务于Key Refresh procedure 和IV Update procedure,当MESH 网络节点或用户感觉网络不安全时,广播到MESH 网络中通知Network ID 标识网络中设备节点何时启用新的安全密钥或 IV Index 通信,协调MESH 网络中所有节点顺利从旧安全参数切换到新安全参数。

由于Secure Network Beacon 报文是向全网广播的,为了减少对网络资源的占用,需要对Secure Network Beacon 报文的数量或者发送间隔进行限制,通常两个Beacon 报文之间的间隔时间Beacon Interval 应设置在10 秒到600 秒之间,计算公式如下:

Beacon Interval = Observation Period * (Observed Number of Beacons + 1) / Expected Number of Beacons

比如假设Observation Period 为 50 秒,在此期间实际扫描到Beacon 报文的数量Observed Number of Beacons 为2 个,每个节点在子网中期望平均每 10 秒接收到一个Beacon 报文,在扫描周期内期望扫描到的Beacon 报文数量为 5 个(= 50 / 10),按照上述公式实际计算出的信标间隔Beacon Interval 为 30 秒(= 50 * 3 / 5)。

3.1 Key Refresh procedures

当一个或多个NetKey 或AppKey 可能不再安全时,由Configuration Client(比如智能手机或平板电脑等)启动密钥刷新过程,比如从MESH 网络中移除某个节点设备时,为应对垃圾桶攻击,通常需要先将其加入黑名单、再执行密钥刷新过程。

密钥刷新过程管理NetKey、AppKey 和所有派生安全凭证从一个密钥更改为另一个密钥的过程,在新旧密钥切换过程中要求对MESH 网络运行的影响尽可能小。密钥刷新过程大致可分为如下三个阶段(以更新NetKey 为例):
Key Refresh diagram

  • Phase 1 – 分发新密钥:Configuration Client 通过Foundation Configuration Client model 中的Config NetKey Update 消息(该消息使用Device Key 加密)向该子网内未列入黑名单的所有节点分发新的密钥New Key,节点设备收到分发的New Key 后会向Configuration Client 回复Config NetKey Status 消息。此阶段使用Old Key 加密发送报文,使用Old Key 或New Key 接收解密报文;
  • Phase 2 – 启用新密钥:待Configuration Client 收到所有未列入黑名单的节点设备回复的Config NetKey Status 消息后,开始发送Key Refresh Flag 设置为 1 的Secure Network Beacon 报文(使用New NetKey 生成的BeaconKey 认证保护),或者发送Transition 参数设置为0x02 的Config Key Refresh Phase Set 消息到未列入黑名单的节点,节点收到上述消息后进入密钥刷新过程的第二阶段,并向Configuration Client 回复Config Beacon Status 或Config Key Refresh Phase Status 消息。此阶段使用New Key 加密发送报文,使用Old Key 或New Key 接收解密报文,但仅接收使用New Key 认证保护的Secure Network Beacon 报文;
  • Phase 3 – 废弃旧密钥:待Configuration Client 确定所有未列入黑名单的节点都处于第二阶段后,开始发送Key Refresh Flag 设置为 0 的Secure Network Beacon 报文(使用New NetKey 认证保护),或者发送Transition 参数设置为0x03 的Config Key Refresh Phase Set 消息到未列入黑名单的节点,节点收到上述消息后废弃Old Key(处于第一阶段的节点收到上述消息后将跳过第二阶段,直接进入第三阶段),后续都使用New Key 来加密发送或者接收解密报文。

密钥刷新过程是由Configuration Client 发起的,MESH 网络中的节点设备Foundation models 都需要提供 Configuration Server model 和Health Server model,密钥刷新过程是Configuration Client 通过向MESH 网络或子网内未列入黑名单的所有设备的Configuration Server model 发送相应的配置消息实现的。

在启用新密钥和废弃旧密钥阶段,需要通过Secure Network Beacon 报文通知该网络内的节点何时进入密钥刷新过程的哪个阶段,起到协调各节点顺畅同步切换密钥的作用。

与密钥刷新过程相关的,还有一个Node Removal procedure,该过程是通过将某节点从密钥刷新过程中排除,实现将该节点从MESH 网络中移除的目的。在一个节点从MESH 网络中移除后,它的单播地址 unicast addresses 可以被Provisioner 重新使用。

3.2 IV Update procedure

IV Index 是MESH 网络所有节点共享的一个32 位值,它为网络层或应用层中用于AES-CCM 认证加密的随机数提供种子,同时配合MESH 报文序列号SEQ 唯一标识一个MESH 网络层中传输的报文,为了避免出现重复的SEQ 而被重放攻击者有机可乘,IV Index 需要时常更新,IV Index 更新后SEQ 值重置为0x000000。

IV Update procedure 可以由MESH 主网(也即NetKey Index = 0x000)中的任何节点发起,当节点判断它自己或者另一节点在 96 小时后即将用尽其SEQ 时,可以发起 IV Index 更新过程,所以发送消息越多的节点发起 IV Update procedure 的概率越大些。

IV Update procedure 是为了应对重放攻击保证SEQ 不会重复而设计的机制,通常在更新 IV Index 时在其当前值基础上递增 1,理论上只要更新值比当前值大就可以,但 IV Index 更新过程也不是随时都能进行的。由于SEQ 用 24 位二进制表示,两个广播报文之间的最小间隔 advInterval 为20 ms(还需要再加个0 ~ 10 ms 的随机延时),可以计算出理论上SEQ 从0x000000 到0xFFFFFF 至少需要 96 小时(取随机延时约 1 ms)。

IV Update procedure 就取 96 h 作为 IV Index 更新周期的限制时间了,由于MESH 网络中节点数量可能非常多(理论单播地址最大数量为215 - 1 = 32767 个),为了尽可能照顾到每个节点的 IV Index 更新,MESH 所有节点 IV Update procedure 总持续时间至少为 96 小时,这就要求MESH 主网节点判断SEQ 在即将用尽前的 96 小时就要发起 IV Update procedure。

由于 IV Update procedure 在SEQ 即将用尽的前96 小时就开始了,更新 IV Index 后重置SEQ,至少又可以使用 96 小时,所以MESH 网络中的某个节点在 192 小时内至多执行一次 IV Update procedure。

Low Power Node 的 IV Update procedure 由Friend Node 代劳,一个 IV Index 至少可以使用96 小时,因此Low Power Node 为了不错过 IV Update procedure,向Friend 轮询的超时时间PollTimeout 不能超过96 小时。

IV Update procedure 与前面的密钥刷新过程类似(IV 更新是针对MESH 全网的,密钥刷新可能只针对某个子网),都包含更新New IV Index、通过Secure Network Beacon 报文通知其它节点进入 IV 更新状态、节点完成 IV 更新后返回正常状态三个阶段,这三个阶段 IV Index 的使用情况如下:
IV Update procedure summary

  • Phase 1 – Normal:MESH 主网中的某个节点判断自己或者另一节点在96小时后即将用尽SEQ,则其更新自己的 IV Index 为m(通常为当前值n 递增 1),并向其它节点发送 IV Update Flag 为 1 的Secure Network Beacon 报文通知其开始 IV Index 更新过程。其它处于正常状态的节点在接收并验证该报文后,比对自己当前的 IV Index(简称为 c)和报文中的 IV Index(简称为 b),如果b < c 或b > c + 42(节点离网超过48 周后需要重新启动配网,假如每192 小时 IV Index 递增 1,则48 周递增 42)则忽略该Beacon 报文,如果 c + 1 < b <= c + 42 则该节点可以启动 IV Index Recovery procedure,如果 b = c + 1 则该节点进入 IV 更新状态。此阶段节点还处于正常状态,使用当前 IV Index(当前值 n)发送报文,使用 n 或 n - 1 处理接收到的报文(n - 1 该节点的Old IV Index);
  • Phase 2 – In Progress:MESH 网络中某个节点接收到 IV Update Flag 为 1 的Secure Network Beacon 报文,且该报文中的 IV Index 值(简称为m)等于该节点当前 IV Index(简称为n)+ 1,则该节点进入 IV Update in Progress State,自己当前的 IV Index 更新为 m,并将该节点使用的SEQ 重置为0x000000。此阶段节点继续使用更新前的 IV Index(也即m - 1 或 n)发送报文,使用更新前后的 IV Index(也即m - 1 或 m)处理接收到的报文,相当于废除了前一个 IV Index 更新过程中的Old IV Index(也即 n - 1);
  • Phase 3 – Normal:MESH 网络中处于 IV Update procedure State 超过96 小时的节点向其它节点发送 IV Update Flag 为 0 的Secure Network Beacon 报文,其它节点接收并验证该报文后(通常已完成 IV Index 更新和SEQ 重置过程),切换回Normal Operation state(处于 IV Update procedure State 达到144 小时后也会切换回正常状态),并且使用更新后的 IV Index(也即 m)发送报文,依然使用 m - 1 或 m 处理接收到的报文。

IV Index Recovery procedure 是为某个节点可能长时间远离网络而错过 IV Update procedure 导致不能再与其它节点通信而设计的,为了恢复与其它节点的通信需要先获得其它节点使用的 IV Index,这个过程就是 IV Index 恢复过程。为了恢复 IV Index,节点需要侦听Secure Network Beacon(其中包含 Network ID 和 IV Index),该节点接收并验证Beacon 报文后,根据该报文中的 IV Index 更新自己的 IV Index,并将 IV Update Procedure State 设置为In Progress。IV Index Recovery procedure 同样在192 小时内至多执行一次。

IV Update procedure 和 IV Index Recovery procedure 都需要 Secure Network Beacon 来通知 IV Index 值和 IV Update Procedure State,协调MESH 网络所有节点在保证SEQ 不重复的情况下顺利从Old IV Index 更新到New IV Index。即便某个节点暂时离开MESH 网络(比如距离太远或者断电等原因),错过了 IV Update procedure 而无法与其它节点进行通信,只要离网时间不超过48 周(离网超过48 周需要重新启动配网),都可以通过 IV Index Recovery procedure 更新到MESH 网络当前使用的 IV Index,从而恢复与其它节点的正常通信。

四、SIG MESH Network Layer

前面已经介绍了MESH Advertising Bearer 和GATT Bearer Layer 支持的报文类型,也介绍了与MESH Provisioning 相关的Unprovisioned Device beacon、«PB-ADV»、«PB-GATT» 报文,以及与MESH 密钥刷新和 IV Index 更新过程相关的Secure Network beacon 报文,剩下的就是«Mesh Message» 或Proxy PDU 承载的Network PDU 报文了,网络层是MESH 消息安全寻址的关键。

MESH Advertising Bearer 承载的 Network PDU 最大为 29 字节,GATT Bearer Layer 通过Mesh Proxy Service 传输的Network PDU 格式定义跟MESH Advertising Bearer 一致,Network PDU 的格式定义如下:
Network PDU format

Field NameBits       Description
IVI1IV Index 的最低有效位,可以在 IV Update procedure 中标识该报文使用的是Old IV 还是New IV
NID7用来标识一个网络或子网的网络标识符,NID、EncryptionKey、PrivacyKey 都是由NetKey 一同生成的,NID 字段有助于更快的找到该报文加解密使用的EncryptionKey 和模糊化使用的PrivacyKey
CTL1CTL = 0:该报文承载的消息类型是Access Message,且NetMIC Size 为32 位;
CTL = 1:该报文承载的消息类型是Control Message,且NetMIC Size 为64 位
TTL7指示该报文剩余的生存跳数Time To Live,若 TTL < 2 则该报文不会被中继转发,若 2 <= TTL <= 127 则该报文可能会被中继转发,该字段由上层协议设置
SEQ24报文序列号,配合 IV Index、SRC 唯一标识MESH 网络中的一个报文
SRC16用于标识发送该报文的元素地址,该地址是元素的单播地址
DST16用来标识接收该报文的一个或一组元素地址,该地址可以是单播地址、组播地址或虚拟地址
TransportPDU8 to 128网络层报文的数据载荷,承载传输层报文。若CTL 值为 0 则该字段最长为128 位,若CTL 值为 1 则该字段最长为96 位
NetMIC32 or 64Message Integrity Check for Network(也即消息认证码MAC),用于对DST 和TransportPDU 字段信息进行完整性校验。若CTL 值为 0 则该字段长度为32 位,若CTL 值为 1 则该字段长度为64 位

Network PDU 中TransportPDU 字段(也即Lower Transport Layer 报文)承载的消息分两种:Access Message 的最大长度为 16 字节,Control Message 的最大长度是 12 字节。

4.1 Publish/Subscribe Addresses

Network PDU 中的SRC 和DST 字段分别标识该数据包的发送地址和接收地址(类似于 IP 协议中的源地址和目标地址),这里的地址只有 16 位,又不像 IP 地址那样是分层设计的,该如何寻址呢?

在介绍MESH 网络如何寻址之前,先看看MESH 网络都支持哪些地址类型:
16-bit address allocations

Address TypeAddress ValueDescription
Unassigned Address0x0000节点元素尚未分配的地址,未分配地址不能用于消息的源地址或目的地址字段(若将该地址设为某模型的发布地址,则相当于禁用该模型的消息发布功能)。
Unicast Address0x0001 ~ 0x7FFF在启动配网过程中分配给每个元素的唯一地址,消息的源地址都是单播地址,目的地址可以是单播、组播、虚拟地址,发送到单播地址的消息最多由一个元素处理。
Virtual Address0x8000 ~ 0xBFFF代表在逻辑上与特定Label UUID 相关联的一组元素地址,Label UUID 实际上是用户在逻辑上定义的一个128 位的标签类别,虚拟地址的低14 位是从Label UUID派生的散列值。若Configuration Client 分配的订阅或发布地址为虚拟地址,则需要在配置过程中将Label UUID 发送到订阅或发布节点;若消息的目的地址是虚拟地址,则需要使用Label UUID 作为认证加密的附加数据。Control Message 不能使用虚拟地址。
Group Address0xC000 ~ 0xFFFF主要用于消息的目的地址,发送到组地址的消息应传递给订阅该组地址的所有元素。组播地址分为两种:
1. 固定组地址(0xFF00 ~ 0xFFFF):All-proxies -> 0xFFFC,All-friends -> 0xFFFD,All-relays -> 0xFFFE,All-nodes -> 0xFFFF,其余的供将来使用;
2. 动态分配组地址(0xC000 ~ 0xFEFF):用户通过Configuration Client 分配,作为订阅或发布地址供MESH 元素使用。

MESH 设备启动配网后,该设备的每个元素都会被Provisioner 分配一个单播地址,该元素向其它节点发送消息时,源地址就是自己的元素地址。如果MESH 消息的目的地址是单播地址,这个单播地址代表该MESH 网络中的某个特定元素,该消息报文只会被该目标元素处理。

虚拟地址或组播地址代表一组元素,通常由用户在配置MESH 网络节点订阅-发布关系时分配的。用户通过Configuration Client 分配组播地址或虚拟地址,在配置MESH 元素订阅地址和发布地址时选择,Configuration Client 分配的组播地址或虚拟地址也会发送到订阅或发布该地址的节点(若是虚拟地址还需要发送对应的Label UUID,若组播地址够用一般就不用虚拟地址了),也即某个组播地址或虚拟地址的订阅节点和发布节点都保存有该组播或虚拟地址。

某个元素想向MESH 网络中的多个元素发布消息,就可以将该消息的目的地址设置为这多个元素的组播地址。MESH 网络是通过受控泛洪广播方式寻址目的节点的,这条消息会被广播到MESH 全网或某个子网的几乎所有节点(低功耗节点和GATT 节点有相应的朋友节点或代理节点帮忙接收转发),当节点收到该消息后,会取出该消息中的目的地址并与自己的订阅地址列表相比较,若该消息的目的地址属于自己的订阅地址则接收并处理,否则丢弃忽略或中继转发该消息,这就实现了消息的寻址功能。

4.2 Encrypted/Obfuscated Network PDU

MESH 网络中节点之间的通信安全主要是由网络层实现的,比如前篇博文BLE MESH 如何保证通信安全 介绍的子网隔离、加密认证、重放攻击防护、模糊化处理等都靠MESH 网络层实现,MESH 网络从是如何保证消息报文的安全发送接收的呢?

首先看下MESH 网络层报文的认证加密和模糊化处理过程,前面Network PDU 格式已经展示了哪些字段Encrypted、哪些字段Obfuscated?认证加密使用的是EncryptionKey,模糊混淆使用的是PrivacyKey,这两个密钥是如何获得的呢?
Network key hierarchy
Network PDU 中的网络标识符NID,加密认证DST 和TransportPDU 字段的加密密钥EncryptionKey,模糊混淆CTL、TTL、SEQ、SRC 等字段的隐私密钥PrivacyKey 都是使用k2 函数由NetKey 计算出来的,NetKey 又是Provisioner(启动配网过程)或Configuration Client(密钥刷新过程)分发的。
Network layer encryption
Network PDU 中的DST 和TransportPDU 字段使用AES-CCM 认证加密算法获得Encrypted Data 和Network MIC,使用的密钥是EncryptionKey 和Network Nonce,其中EncryptionKey 是由NetKey 生成的,Network Nonce 则是由 IV Index、CTL、TTL、SEQ、SRC 等字段构成的。
Network layer obfuscation
Network PDU 中的CTL、TTL、SEQ、SRC 等字段通过与PrivacyKey 和Privacy Plaintext 进行AES-128 加密后的密文异或运算后获得ObfuscatedData,Privacy Plaintext 则是由padding、IV Index、Encrypted Data、Network MIC 等字段构成的。

通过对Network PDU 进行认证加密和模糊混淆处理,攻击者假如没有网络密钥NetKey,将只能看到 IVI 和 NID 两个字段的信息,其它信息都无法查看到,自然起到防止嗅探或篡改的目的。配合SEQ 递增、IV Index 更新、缓存SEQ 和SRC 等设计,也可以起到防止重放攻击的目的。

4.3 Receiving/Transmitting Network PDU

MESH 网络层支持通过Advertising Bearer 或GATT Bearer 发送和接收消息,面向广播的Advertising Bearer 是一个网络接口,面向连接的GATT Bearer 每个GATT 连接都是一个网络接口。比如本文开头的MESH 消息流向图,此节点就具有三个网络接口,一个通过Advertising Bearer 发送接收消息,两个通过GATT Bearer 分别和两个连接的GATT Client 发送接收消息。此外,MESH 协议为了允许在同一节点的不同元素间传递消息,还定义了本地接口 Local Network Interface。

Network interfaces 提供了 input filter 和output filter,过滤器可以使用 bearer-specific PDUs 进行配置(可以类比Proxy Configuration 配置White list filter 和Black list filter)。接收的MESH 消息通过网络接口从承载层传递到网络层,接口使用其 input filter 定义的过滤规则先对消息进行过滤处理,决定是将该消息传递到网络层进一步处理还是直接丢弃。发送的MESH 消息则是通过网络接口从网络层传递到承载层,接口使用其 output filter 定义的过滤规则对消息进行过滤处理,决定是将该消息传递到承载层还是直接丢弃。

MESH 网络层接收到通过网络接口传递来的MESH 消息后,处理流程如下:
MESH 网络层报文处理过程

  1. Check NID:节点从网络接口接收到来自承载层的Network PDU 后,首先检查该报文的NID 字段值是否能匹配上本节点存储的NID 列表(每个NID 标识一个MESH 网络或子网和相应的 NetKey,本节点存储的NID 列表记录该节点都处于哪些MESH 网络中)。若该节点并没有存储接收报文中的NID,则说明该节点不在接收报文NID 标识的网络中(也即没有解密该报文的NetKey),直接丢弃该报文,这实际上就是MESH 消息传递中子网间的区域隔离机制。若该节点已经存储接收报文中的NID,则继续进行下一步处理;
  2. Verify NetMIC:该节点根据Network PDU 中的NID 字段,查找相应的EncryptionKey 和PrivacyKey,然后使用这两个密钥和当前使用的 IV Index 解密反模糊接收报文,并通过比对NetMIC 字段值验证接收报文的完整性。若NetMIC 验证失败则直接丢弃该报文(可能是接收报文被破坏,或者本节点使用的NetKey 不正确),若接收报文通过完整性校验则继续下一步处理;
  3. Check SRC and DST:检查Network PDU 中的SRC 字段是否是有效的单播地址,DST 字段是否是有效的单播、组播、虚拟地址,若SRC 或DST 是无效地址则直接丢弃该报文。若SRC 和DST 都是有效的,则检查DST 是否在本节点的订阅地址列表中(包括Friend Subscription List 和Proxy white / black list),若DST 是本节点的订阅地址则后续将其递交给传输层继续处理(或者Proxy 节点将其转发给对应的GATT 节点),若DST 不是本节点的订阅地址则不向上传递了(看是否需要将其中继转发给其它节点);
  4. Check SEQ and SRC Cache:检查Network PDU 中的SEQ 和SRC 字段,这两个字段配合当前使用的 IV Index 可以唯一标识该MESH 网络中的一个报文,节点会将接收报文的SEQ 和SRC 字段缓存起来,以避免重复处理相同的报文。若接收报文中的SEQ 和SRC 字段组合值已在该节点的接收消息缓存中,则直接丢弃该报文。若SEQ 和SRC 组合值不在该节点接收消息缓存中,则将这两个字段值添加到该节点的消息缓存中,继续下一步处理;
  5. Check TTL and Relay / Proxy feature:如果本节点启用了Relay 特性且DST 不是本节点上元素的单播地址,若TTL < 2 则将其丢弃,若TTL >= 2 则TTL 值减 1 后将其重新加密认证并通过承载层中继转发出去。如果本节点启用了Proxy 特性且DST 在Proxy white list 中则将其重新加密认证并通过Mesh Proxy Service 发送给Proxy / GATT Client 节点。如果DST 是本节点上元素的订阅地址,或者与本节点建立友谊关系的低功耗节点上元素的订阅地址,则将接收报文向上传递到Lower Transport Layer 继续处理。

如果该节点上的元素想要向其它节点发送MESH 消息,来自Lower Transport Layer 的报文作为MESH 网络层的TransportPDU 字段,CTL、TTL、DST 字段都是由上层协议设置的,使用该元素所在MESH 网络的 NID 、LSB of IV Index 填充NID 和 IVI 字段,使用发送该消息的元素的单播地址填充SRC 字段,将发送前一个报文的SEQ 值加 1 填充SEQ 字段。使用 NID 标识的EncryptionKey、PrivacyKey 和当前的 IV Index 对Network PDU 特定字段进行加密认证和模糊化处理,最后将生成的Network PDU 经网络接口传递给承载层发送出去。

五、SIG MESH Transport Control messages

在介绍MESH Network Layer 时我们知道,TransportPDU 分为Access Message 和Control Message,前者是来自Access Layer 的消息,后者则是来自Transport Layer 的消息。

Access Message 承载的主要是Foundation Model 的配置或健康消息、以及SIG / Vendor Model 的应用消息报文。为了保证发布者模型发布的消息报文,只能被相应的订阅者模型处理或响应,除了使用NetKey 对网络数据报文进行认证加密外,还需要使用AppKey 对模型或应用消息报文进行认证加密,且发布者模型与订阅者模型都绑定到相同的AppKey。限于篇幅,Access Message 在谈Model 时再介绍。

Control Message 承载的主要是跟Friend node 如何帮助Low Power node 管理订阅列表 / 缓存并转发消息相关的友谊消息报文,以及监测MESH 网络中其它节点活动状态和拓扑距离相关的心跳消息报文。Friendship 相关的消息主要在FN 与LPN 之间传输,Heartbeat 相关的消息则在MESH 网络或子网中传输,这两种Control Message 发送对象都比较确定,不属于应用业务的范畴,没必要再使用类似AppKey 之类的密钥进行二次认证加密,因此Control Message 在传输层不需要进行认证加密(只在网络层进行认证加密)。

5.1 Unsegmented Control Message

Control Message 主要由Opcode 和Parameters 两部分构成(可以类比Attribute PDU,MESH Access Layer 的Access Message 也主要由Opcode 和Parameters 这两部分构成),考虑到MESH 网络层报文承载的Transport PDU 只有 12 字节,为了支持更大的消息报文长度,传输层需要支持消息报文的分片重组功能(TCP/IP 协议和BLE L2CAP 协议都支持报文的分片重组功能),为此新增了一个指示该报文是否分片的标识位SEG,Unsegmented Control Message 的格式如下:
Unsegmented Control message

FieldSize (bits)Description
SEG10 = Unsegmented Message
Opcode70x00 = Segment Acknowledgment
0x01 to 0x7F = Opcode of the Transport Control message
Parameters0 to 88Parameters for the Transport Control message

Control Message 的Opcode 字段只有 7 位,0x00 是分片报文的确认应答报文(消息发送者可通过该报文得知哪个分片未送达需重新发送,保证分片报文传输的完整性),剩余的 127 个操作码可用来标识每个Control Message。目前SIG MESH 定义的Control Message 如下:
Summary of Transport Control message opcodes

5.1.1 Heartbeat message

Transport Control messages 最后一种Opcode 为0x0A 的控制消息是Heartbeat message,主要用来监测MESH 网络上其它节点的活动状态及其拓扑距离。

MESH 网络节点间通信采用订阅 – 发布消息传递模型,该消息传递模型通常需要各节点周期性发送心跳报文,以通知其可能的订阅者自己是否还在网并处于活动状态,这是MESH Heartbeat message 的第一个作用。
Heartbeat parameters
MESH Heartbeat message 的第二个作用就是帮助接收该消息的节点计算到该消息发布者的拓扑距离也即跳数,该消息报文会包含 InitTTL 字段,接收者在Network PDU 中会获知接收到该报文时的 RxTTL 值,就可以计算得到该消息发送者与接收者之间的拓扑距离如下:

hops = InitTTL - RxTTL +1

MESH 节点通过Heartbeat message 知道了到其它节点的拓扑距离hops,也就可以在发布消息时设置合适的TTL 值,尽可能以较小的网络资源占用将消息发送到其它所有订阅者,这也是MESH 网络受控泛洪广播提高通信效率的一个设计。

MESH Heartbeat message 中除了包含 InitTTL 字段,还包含Features 字段,该字段主要是用来通知其它节点,自己是否支持Relay、Proxy、Friend、Low Power 等Feature,不仅让MESH 节点知道到其它节点的拓扑距离hops,也让MESH 节点知道其它节点支持的功能Feature。当MESH 节点的某个功能Feature(比如Relay、Proxy、Friend、Low Power 等)发生变化时,应该向其它节点发布Heartbeat message,及时通知其它节点自己功能角色的变化。

5.1.2 Friendship messages

Transport Control messages 中间的 9 种都属于Friendship 相关的消息,Friend node 与Low Power node 之间友谊的建立、订阅列表维护、消息传递等过程都已经在博文BLE MESH 如何支持低功耗设备 中介绍过了,每种报文的参数格式可以参阅Mesh Profile Section 3.6.5,这里就不赘述了。

跟Friendship 相关的Transport Control messages 报文,由于仅在Friend 节点和Low Power 节点间传输,网络层报文的TTL 字段设置为 0(也即不中继转发)。FN 与LPN 双方建立Friendship 后,通信报文改为friendship security material 认证加密,这个安全密钥是由NetKey 和FriendAddress、LPNAddress 等参数计算出来的(用于网络层报文对TransportPDU 字段的认证加密),生成过程如下:

The master security material using:
NID || EncryptionKey || PrivacyKey = k2(NetKey, 0x00)

The friendship security material using:
NID || EncryptionKey || PrivacyKey = k2(NetKey, 0x01 || LPNAddress || FriendAddress || LPNCounter || FriendCounter)

在建立Friendship 之前FN 与LPN 之间发送的Friend Request、Friend Offer 控制消息报文,以及建立New Friendship 后New Friend 节点与Old Friend 节点之间发送的取消Old Friendship 关系的Friend Clear 和Friend Clear Confirm 控制消息报文都是采用master security material 认证加密的(实际上就是前面介绍Network Layer 时使用的EncryptionKey 和PrivacyKey)。建立Friendship 之后FN 与LPN 之间交互的报文,比如Friend Poll、Friend Update、Friend Subscription List Add / Remove / Confirm 等控制消息报文都是采用friendship security material 认证加密的,由于包含FN 与LPN 之间的私有信息(比如LPNAddress、FriendAddress、LPNCounter、FriendCounter 等),这些报文只能被建立Friendship 关系的另一方正确解密并处理。

前面也介绍了,当从MESH 网络中移除节点时Configuration Client 会启动Key Refresh procedures,当某个节点判断自己或者另一节点在 96 小时后即将用尽其SEQ 时会启动 IV Update procedure,这两个过程用于MESH 网络中未列在黑名单中的所有结点更新密钥或 IV Index,Low Power 节点怎么从Friend 节点获得这些更新值呢?
Friend Update message parametersFriend Update 控制消息报文Opcode 为0x02,参数包含Key Refresh / IV Update Flags、IV Index、MD 等字段,前两个字段就可以将MESH 网络或子网更新的 NetKey 或 IV Index 发送给Low Power 节点(由于Key Refresh 和 IV Update 过程都是有时限的,LPN 轮询FN 的最长时间间隔PollTimeout 不能超过这个时限 96 小时),若NetKey 更新则friendship security material 也需要更新。Friend Update 报文中的MD 字段 则告诉Low Power 节点是否还有后续更多消息报文待传输,LPN 节点根据MD 字段的值决定是否继续向FN 发送Friend Poll 报文以请求后续更多的消息(MD = 1 则还有后续更多消息待发送,MD = 0 则本次缓存的消息已发送完毕)。

5.1.3 Segment Acknowledgment message

由于单个Network 报文承载的Transport PDU 长度有限(Access Message 最大长度为 16 字节,Control Message 最大长度是 12 字节),对于长度超过单个Network 报文承载极限的消息,我们很自然想到分片重组。

分段传输有可能导致某个报文未成功送达,如果此时重传整个消息报文就降低了网络利用率,因此接收者有必要通过Segment Acknowledgment message 告诉消息发送者,自己都接收到了哪些分段报文,消息发送者只需要重传对方未收到的分段报文就可以了,从而提高了网络利用率。

Segment Acknowledgment message 不仅用于Segmented Control message 的确认应答,还用于Segmented Access message 的确认应答,该报文的格式如下:
Segment Acknowledgment message format

FieldSize (bits)Description
SEG10 = Unsegmented Message
Opcode70x00 = Segment Acknowledgment
OBO1Friend on behalf of a Low Power node,OBO = 1 代表一个低功耗节点的朋友节点确认此消息,OBO = 0 直接寻址的消息接收者确认此消息
SeqZero13Least significant 13 bits of SeqAuth(由32 位 IV Index 和24 位第一个分段的SEQ 构成的一个56 位消息认证码,用来标识该元素发出的每一个报文),相当于消息第一个分段的SEQ 的低 13 位,同一个消息不同分段的SeqZero 值相同,用来标识某个特定的消息
RFU2Reserved for Future Use
BlockAck32Block acknowledgment for segments,每一位置为 1 代表确认已接收到对应的一个分段消息,比如 LSB - 0 置为 1 标识分段 0 消息被确认接收到、LSB - 31 置为 1 标识分段 31 消息被确认已接收到,一条消息最多被分成32 个分段

发送给LPN 的消息报文是由与其建立Friendship 关系的FN 代为缓存转发的(FN 为每个与其建立友谊关系的 LPN 都设置了一个 Friend Queue,用于缓存即将发送给LPN 的消息),当FN 接收到发送给LPN 的消息时(也即消息报文的目的地址是LPN 的单播地址或者订阅地址),如果报文的TTL 字段值大于等于2 则将其减 1 后存入Friend Queue(如果报文的TTL 值小于2 则将其丢弃)。

如果发送给LPN 的消息是分段消息,则由与其建立友谊关系的FN 代为回复Segment Acknowledgment message,该消息的OBO 字段应设置为 1。FN 接收到发送给LPN 的分段消息后,待所有分段报文重组为完整的消息后,才放入到Friend Queue 中(如果该好友队列已满,则会丢弃除Friend Update 消息外的最旧的消息)。

5.2 Segmented Control message

通常Access Messages 长度可能超过单个Network 报文承载极限,需要分段传输,Control messages 中的Friend Subscription List Add 和Friend Subscription List Remove 消息也可能超过单个Network 报文承载极限,因此也为Control message 定义了Segmented Control message,该报文的格式如下():
Segmented Control message

Field          Size(bits)Description
SEG11 = Segmented Message
Opcode70x00 = Reserved
0x01 to 0x7F = Opcode of the Transport Control message
RFU1Reserved for Future Use
SeqZero13Least significant 13 bits of SeqAuth,相当于消息第一个分段的SEQ 的低 13 位,同一个消息不同分段的SeqZero 值相同,用来标识某个特定的消息
SegO5Segment Offset number,表示当前报文的分段号(可以理解为当前报文是该消息的第几个分段,需要从0 开始计)
SegN5Last Segment number,该消息的最后一个分段号,同一个消息不同分段的SegN 值相同,用来表示该消息被分成了多少段
Segment m8 to 64Segment m of the Upper Transport Control PDU,承载控制消息的每个分段内容

从SegN 字段只有 5 位可以得知,一条MESH 消息最多只能分成 32 个片段,每个片段最多只能承载 8 字节有效载荷,Segmented Control message 最多可以承载256 字节有效载荷。

分段报文相比未分段报文,多了SeqZero、SegO、SegN 三个字段,这三个字段信息也是分段重组的关键。这三个字段控制报文分段的图示如下(同一消息的不同分段使用相同的Opcode,下图就不单独给出Opcode 字段了):
Example of segmentation and reassembly for a two-segment PDU
SeqZero 是SeqAuth 的低13 位,可以唯一标识213 = 8192 个报文中的一条消息(若在该范围内未完成分段重组,则该消息传递失败),在分段报文重组时通过该字段判断是否属于同一条消息的不同分段。

SegO / SegN 可以唯一标识某个消息(由 SeqZero 标识)的每个分段,比如 0 / 5 表示当前报文是消息SeqZero 总共六个分段中的第一个分段。在分段报文重组时通过这两个字段判断同一条消息不同分段的组合顺序。

前面介绍的Segment Acknowledgment message 中的BlockAck 字段每一位表示已经接收到分段报文的SegO 字段值,BlockAck 字段中超过SegN 字段值的位应该置 0(也即不需要确认不存在的分段)。比如已经接收到SegO / SegN 值为 0 / 5、1 / 5、3 / 5、5 / 5 则BlockAck 字段应设置为0x0000002B,发送者收到该报文后就知道对方未收到 2 / 5、4 / 5 分段报文,便会重新发送这两个分段报文给对方。

值得一提的是,对于分段报文,在传输层有Segment Acknowledgment message 用于确认应答。但对于未分段报文,在传输层并没有相应的确认应答机制,Unsegmented Access message 可以由应用层确认应答,Unsegmented Control Message 针对重要的控制消息提供了专门的确认应答消息,比如Friend Clear Confirm、Friend Subscription List Confirm。其它的Unsegmented Control Message 会多次发生(比如Heartbeat 是周期性多次发送的,LPN 发送Friend Poll 后若一段时间内未收到Friend Update 响应则会继续重发Friend Poll ),即便有一两个控制消息未送达也影响不大。若想使用传输层的确认应答机制,如果Control Message Parameters 字段不超过8 个字节,可以使用单分段报文发送(也即SegN 值为 0 的分段报文)。

Transport Access messages、Foundation Model Layer 和Models Layer 的详细介绍见下篇博文:BLE 技术(九)— SIG MESH Models 是如何设计的(下)?

更多文章:

  • 《BLE 技术(九)— SIG MESH Models 是如何设计的(下)?》
  • 《BLE 技术(七)— BLE MESH 是如何设计的?》
  • 《Bluetooth 技术(一)— 协议栈设计与演进(Core_v5.2 + 6LoWPAN + Mesh)》
  • 《Mesh Profile 1.0.1》
  • 《Mesh Model 1.0.1》
注:本文转载自blog.csdn.net的流云IoT的文章"https://blog.csdn.net/m0_37621078/article/details/117399744"。版权归原作者所有,此博客不拥有其著作权,亦不承担相应法律责任。如有侵权,请联系我们删除。
复制链接
复制链接
相关推荐
发表评论
登录后才能发表评论和回复 注册

/ 登录

评论记录:

未查询到任何数据!
回复评论:

分类栏目

后端 (14832) 前端 (14280) 移动开发 (3760) 编程语言 (3851) Java (3904) Python (3298) 人工智能 (10119) AIGC (2810) 大数据 (3499) 数据库 (3945) 数据结构与算法 (3757) 音视频 (2669) 云原生 (3145) 云平台 (2965) 前沿技术 (2993) 开源 (2160) 小程序 (2860) 运维 (2533) 服务器 (2698) 操作系统 (2325) 硬件开发 (2492) 嵌入式 (2955) 微软技术 (2769) 软件工程 (2056) 测试 (2865) 网络空间安全 (2948) 网络与通信 (2797) 用户体验设计 (2592) 学习和成长 (2593) 搜索 (2744) 开发工具 (7108) 游戏 (2829) HarmonyOS (2935) 区块链 (2782) 数学 (3112) 3C硬件 (2759) 资讯 (2909) Android (4709) iOS (1850) 代码人生 (3043) 阅读 (2841)

热门文章

101
推荐
关于我们 隐私政策 免责声明 联系我们
Copyright © 2020-2025 蚁人论坛 (iYenn.com) All Rights Reserved.
Scroll to Top