- 什么是代理协议?
- 代理协议的作用?
- 代理协议的原理?
- 代理协议的实现过程?
- 为什么会有代理协议?
1、原理:为什么要使用代理协议?
首先,要理解BLE Mesh协议是一个应用程序,而不是BLE4.0、BLE5.2这种蓝牙协议。通常的蓝牙芯片或者支持蓝牙功能的手机,是没有BLE Mesh协议的,即一般的蓝牙功能不会包含BLE Mesh应用。所以要使一个设备支持BLE Mesh,需要在芯片里面实现BLE Mesh协议栈,在手机或者电脑上的App中,实现BLE Mesh协议栈。
其次,要知道承载器,目前有且仅有两种,Sig定义的广播承载器(Advertising bearer)和GATT承载器(GATT bearer)。广播承载器是通过发送蓝牙广播进行通信,GATT承载器是通过建立GATT蓝牙连接进行通信。注意有个简称,广播承载器简称PB-ADV
,GATT承载器简称PB-GATT
。承载器可以理解为操作BLE进行数据收发的一个结构体对象。每一个支持蓝牙mesh协议的终端,必须至少支持这两种承载器中的一种。目前手机App只能以一种角色运行,不能同时作为主机和从机,即同时无法实现两种承载器。手机App作为整个网络的管理者(配网器),在手机App上使用的是GATT承载器,毕竟GATT承载器的通信可靠性要更好。一般的做法是手机APP连接上一个设备,然后通过这个设备去控制整个Mesh网络。(可以支持多个GATT承载器,如子网模式下,APP端需要多个页面支持)
最后,与手机APP端建立GATT连接的节点必须支持代理协议。在App上要操作除建立连接外的其他节点,App只能发送消息给连接的节点,连接的节点再给mesh网络发送广播将消息传递出去。这个连接的节点就必须同时与App建立GATT连接,又能使用PB-ADV
发送广播。所以,App与节点建立GATT承载器,然后通过该节点的广播承载发送数据控制Mesh网络的通信协议,就是BLE Mesh Proxy protocol。建立连接的设备相当于手机APP的代理人,消息的收发都通过这个代理人进行处理。
总结:手机App端在mesh上的通信方式,只有一种,代理协议模式。不论是什么消息,必须走这个协议。
2、代理协议概述
代理协议
使节点能够通过面向连接的承载器发送和接收Network PDUs
、mesh beacons
、proxy configuration messages
和Provisioning PDUs
。Sig BLE Mesh协议中只有这四种消息。
例如,一个节点可以支持 GATT,但不能发送 Mesh Message AD
类型广播。 该节点将与另一个支持 GATT 承载器
和广播承载器
的节点建立 GATT 连接,使用 Proxy 协议
在这些承载器之间转发消息。
2.1、代理角色
代理协议
定义了两个角色:代理服务器
和代理客户端
。
代理服务器是支持使用代理协议的mesh承载器和至少一个其他mesh承载器的节点。 例如,代理服务器可以在广播承载器和 GATT 承载器之间转发mesh消息。
代理客户端是支持使用代理协议的mesh承载器。 例如,代理客户端可以使用 GATT 承载器将mesh消息发送到支持广播承载器的节点。
为了能愉快的阅读本文下面内容,需要记住:代理服务器就是与App端建立GATT连接的节点。代理客户端就是App端。
2.2、Proxy PDU
代理客户端和代理服务器交换代理 PDU。 代理 PDU 可以包含网络 PDU、mesh广播信标、代理配置消息或配网PDU。 单个代理 PDU 可以包含完整的消息或消息的片段。 Proxy PDU 的大小由 Proxy 协议的用户决定。 例如,GATT 承载器根据 ATT_MTU 定义 Proxy PDU 的大小。目前我司已经实现了短包和长包两种方式。
2.3、Proxy PDU format格式
字段介绍:
SAR:占2位,表示BLE收到的消息是否需要分段重组。SAR全称,Segmentation and Reassembly,指拆包组包机制。
MessageType:占6位,PDU中Data的消息类型。
Data:可变长度,数据部分,完整消息或者是分段消息内容。
字段值的范围介绍:
-
SAR字段范围 (2个位有且仅有4种情况)):
SAR值(0b代表二进制) 含义 0b00 Data段包含的是完整消息 0b01 Data段包含的是分段消息第一个数据 0b10 Data段包含的是分段消息中间数据 0b11 Data段包含的是分段消息最后一个数据 -
Type字段范围(目前有且仅有4种类型):
Type值 名称 含义 0x00 Network PDU Data段包含是网络数据 0x01 Mesh Beacon Data段包含是Mesh Beacon广播信标 0x02 Proxy Configuration Data段包含是代理配置消息 0x03 Provisioning PDU Data段包含是配网消息 0x04–0x3F 未用到 保留,供将来扩展 data段,纯数据,无需说明。
2.4、Segmentation分段与组合
在mesh协议中一共有两处消息的分段和组合:(1)配网器收发数据时,会判断是否因为MTU导致的分段或组合,这个部分属于承载层负责。(2)因底层传输层
负载最大长度的限制导致的分段与组合,底层传输层
在处理来自上层传输层消息进行消息发送时,会判断是否需要分段之后再交给网络层进行处理;底层传输层
收到来自网络层的消息时,会判断是否为完整消息,必须是消息完整后再交给上层传输层处理。
这里讲的是承载层的分段与组合:
使用代理协议发送的消息可能比单个代理 PDU
的MTU 大。 为了使这样的消息能够被传输,使用了分段和重组。
当发送小于或等于 Proxy PDU 最大大小的消息时,SAR 字段应设置为 0b00,Data 字段应包含完整的消息。
当发送的消息大于代理 PDU 的最大大小时,该消息将被分成多个段,这些段将填充每个代理 PDU。 这些段应按顺序发送,第一个段的 SAR 字段应设置为 0b01,最后一个段的 SAR 字段应设置为 0b11,所有其他段的 SAR 字段应设置为 0b10。
2.5、Proxy filtering代理过滤
为了减少代理客户端和代理服务器之间交换的网络 PDU 的数量,可以使用代理过滤器。
代理服务器实例化的网络接口的输出过滤器可以由代理客户端配置。 这允许代理客户端明确请求仅接收具有特定目标地址的mesh消息。 例如,订阅了组地址的代理客户端可能只想接收发往其元素之一的单播地址和该组地址的数据包。 因此,代理客户端可以完全控制它使用代理协议接收的数据包。
代理过滤器可以是白名单过滤器或黑名单过滤器。
白名单过滤器有一个关联的白名单,它是代理客户端感兴趣的目标地址列表。 白名单过滤器会阻止除已添加到白名单中的所有目标地址。
黑名单过滤器有一个关联的黑名单,它是代理客户端不想接收的目标地址的列表。 黑名单过滤器接受除已添加到黑名单的地址之外的所有目标地址。
具有空列表的白名单过滤器是默认过滤器类型。 代理客户端可以更改过滤器类型以及配置代理过滤器中的地址。
举个例子,网络中存在A、B、C三个节点。
如果设置过滤器类型为白名单模式,将A的地址添加到白名单列表,那么只能收到A节点的消息,B和C节点的消息会被过滤掉。
如果设置过滤器类型为黑名单模式,那么A节点的消息就会被过滤掉,只能接收到B和C节点的消息。
2.6、Proxy configuration messages
除了Network PDUs
、mesh beacons
和Provisioning PDU
,代理客户端和代理服务器可以使用代理协议交换proxy configuration messages
代理配置消息。
代理配置消息用于配置代理过滤器。
代理配置消息的格式与网络 PDU 的格式相同相同。
CTL 字段应设置为 1。代表控制消息Control Message。
TTL 字段应设置为 0。代表不转发,只让与手机APP连接的代理节点处理。
DST 字段应设置为未分配的地址。
TransportPDU 字段的格式应如下表所示,并应使用网络密钥NetworkKey中定义的主安全凭证和代理随机数proxy nonce
进行保护。
Proxy TransportPDU
字段格式如下:
字段名称 | 长度(字节) | 含义 |
---|---|---|
Opcode | 1 | 消息操作码 |
Parameters | 可变的 | 消息参数 |
Proxy TransportPDU操作码字段的值定义如下:
值 | Opcode | 含义 |
---|---|---|
0x00 | Set Filter Type | 代理客户端发送,用于设置代理过滤器类型 |
0x01 | Add Addresses To Filter | 代理客户端发送,用于添加地址到代理过滤列表 |
0x02 | Remove Addresses From Filter | 代理客户端发送,用于移除代理过滤列表中的地址 |
0x03 | Filter Status | 代理服务器与客户端用于确认过滤列表消息的状态 |
0x04–0xFF | 保留 | 供以后扩展 |
Parameters参数的值,需要根据每一种操作做具体的分析,下面内容做详细阐述。
2.6.1、Set Filter Type
设置过滤器类型
代理客户端可以发送设置过滤器类型消息来更改代理过滤器类型并清除代理过滤器列表。
参数定义如下,只有一个参数FilterType:
字段 | 长度(字节) | 含义 |
---|---|---|
FilterType | 1 | 代理过滤器类型 |
参数FilterType的值定义如下:
值 | 含义 |
---|---|
0x00 | 白名单过滤器 |
0x01 | 黑名单过滤器 |
0x02–0xFF | 禁止使用 |
2.6.2、Add Addresses to Filter
添加地址到过滤器
Add Addresses to Filter
消息由代理客户端发送以将目标地址添加到代理过滤器列表。
AddressArray数组中包含的元素是地址,一个地址的长度为2字节,参数定义如下:
字段 | 长度(字节) | 含义 |
---|---|---|
AddressArray | 2 * N | 地址列表,其中 N 是此消息中的地址个数。 |
AddressArray 字段包含要添加到代理过滤器列表的地址序列。 它可以包含单播地址、虚拟地址和组地址的任意组合。可以一次性添加多个地址。AddressArray 中的每个地址都是一个 16 位值,因此使用 16 位虚拟地址而不是Label UUID。
2.6.3、Remove Addresses from Filter
移除过滤器中的地址
从过滤器中删除地址消息由代理客户端发送以从代理过滤器列表中删除目标地址。
参数跟添加消息一样:
字段 | 长度(字节) | 含义 |
---|---|---|
AddressArray | 2 * N | 地址列表,其中 N 是此消息中的地址个数。 |
AddressArray 字段包含要从代理过滤器列表中删除的地址序列。 它可以包含单播地址、虚拟地址或组地址的任意组合。可以一次性删除多个地址。
2.6.4、Filter Status
过滤器状态
代理服务器发送过滤器状态消息以报告代理过滤器的状态。
参数定义如下:
字段 | 长度(字节) | 含义 |
---|---|---|
FilterType | 1 | 黑名单过滤器还是白名单过滤器 |
ListSize | 2 | 代理过滤器中地址的个数 |
FilterType的值已经在2.6.1中定义过了。
2.7、Proxy Server behavior
代理服务器行为
当代理客户端连接到代理服务器时,一个新的承载器的实例通过网络层接口
连接到网络层。(网络层接口:C和java语言中由回调函数实现,iOS中叫委托协议;意思就是数据能逐层传递处理。)
一旦连接后,代理服务器将代理过滤器初始化为白名单过滤器,白名单为空。
如果代理过滤器是白名单过滤器,则在从代理客户端接收到有效的Mesh消息后,代理服务器应将该消息的SRC字段中包含的单播地址添加到白名单中。
如果代理过滤器是黑名单过滤器,则在从代理客户端接收到有效的Mesh消息后,代理服务器应将消息的SRC字段中包含的单播地址从黑名单中删除。
一旦连接后,代理服务器应向代理客户端发送每个已知子网的安全网络信标。
在成功处理具有
IV Index
字段或Flags
字段的新值的Secure Network Beacon
(安全网络信标)后,代理服务器应将此安全网络信标发送到代理客户端。当代理服务器被添加到一个新的子网时,它应该为那个子网发送一个安全网络信标给代理客户端。
当代理客户端接收到安全网络信标后,代理服务器应按照安全网络信标行为中的定义对其进行处理。
发送代理配置消息时,代理服务器应将 SRC 字段设置为其主要元素的单播地址,并且 SEQ 字段应使用其主要元素的序列号。
如果代理服务器接收到
Set Filter Type
消息,则应根据消息请求中的参数,设置代理过滤器类型,并清除代理过滤器列表。然后,代理服务器应以Filter Status(过滤器状态)
消息进行响应。如果代理服务器接收到一个添加地址到过滤器消息,那么它应该将这些地址添加到代理过滤器列表中并且应该用一个过滤器状态消息来响应。如果消息中包含的一个或多个地址已经在列表中,则代理服务器不应添加这些地址。如果代理服务器在代理过滤器列表中的空间不足,代理服务器不应添加这些地址。如果 AddressArray 字段包含未分配的地址,代理服务器将忽略该地址。
如果代理服务器接收到从过滤器中删除地址消息,它将从代理过滤器列表中删除这些地址,并应以过滤器状态消息进行响应。 如果消息中包含的一个或多个地址不在列表中,代理服务器将忽略这些地址。 如果 AddressArray 字段包含未分配的地址,代理服务器将忽略该地址。
在接收到带有意外 SAR 字段值的消息时,代理服务器应断开连接。
在接收到消息类型字段设置为保留供将来使用的值的消息时,代理服务器应忽略此消息。
SAR 传输的超时时间为 20 秒。 当超时到期时,代理服务器将断开连接。
相关知识点:
有效的Mesh消息,怎么判断消息是否有效?能正常被网络密钥以解密算法解析,解析后的数据依符合协议要求。
主元素地址与节点地址:通常说的节点的单播地址,指的就是主元素的地址。一个节点可能有多个元素,每个元素地址都不一样。一个节点占用的地址个数并非一个,有多少个元素,就要占用多个地址。举例:节点依次包含三个元素A,B,C;依据当前网络中地址的分配情况,假如元素A的地址为0x0001,节点中其他的元素地址往回加一,则B元素为0x0002、C元素为0x0003。节点的地址也就是节点中主元素的地址,主元素就是第一个元素,为0x0001。如果此时,再添加一个设备,新添加节点的地址需要从0x0004开始,如果也是三个元素,那么新节点占用0x0004,0x0005,0x0006三个地址。
SRC字段:包含的值是源地址,是发出消息节点的地址。
ATT_MTU:全称Attribute Protocol Maximum Transmission Unit,属性协议最大传输单位。
IV Index:相关的内容太长,可以点击上方安全网络行为的链接。
SEQ,全称Sequence Number,序列号。用于记录消息的编号,消息发送时自动加一,根据每个节点标识进行对应存储。
2.8、Proxy Client behavior
代理客户端行为
代理客户端可以发送代理配置消息来配置代理过滤器。
发送代理配置消息时,代理客户端应将 SRC 字段设置为其主要元素的单播地址,并且 SEQ 字段应使用其主要元素的序列号。 代理客户端可以在收到过滤器状态消息时确定代理过滤器列表的状态。
在接收到带有意外 SAR 字段值的消息时,代理客户端应断开连接。
在接收到消息类型字段设置为保留供将来使用的值的消息时,代理客户端应忽略此消息。
SAR 传输的超时时间为 20 秒。 当超时到期时,代理客户端将断开连接。
2.9、消息流程图MSC(message sequence chart)
下方流程图说明了由 Proxy Client 配置,Proxy Server 执行的黑名单过滤的流程图。
2.10、具体消息解析举例
2.10.1、例一
BLE收到:
0x0303FC02DDCCF821169A72D02A0978747CFC6739A8A08B13A1A7944EDE4D3D533B27794E5898169572112201E3CD6A1F4804FBB5A618A07719C52E90C651B81A43B4
收到消息后,不会管设备处于什么状态,也不知道是谁发过来的数据。全部按照代理协议进行处理:
第一步,取第一个字节高两位,第一字节 data[0]为0x03,SAR = data[0] >> 6。计算出SAR为0。依据2.3中代理PDU的格式,这个消息为完整消息。
第二步,取第一个字节低6位,PduType = data[0] & 0x3F。计算出PduType为3。依据2.3中代理PDU的格式,这个消息为配网消息。
第三步,依据配网协议中的定义,处理从第二字节到结束的数据。这里就进入到配网协议处理了,配网协议看之前写过的内容。
2.10.2、例二
BLE收到:
0x003EBB5242C5F1E3FDFB18251C5942BFE8EC25CC767D1E1AE1FDD9C73CC0 networkKey: F9B024F55B95EFA75F6B2B8D8D3A3F5C
收到消息后,不会管设备处于什么状态,也不知道是谁发过来的数据。全部按照代理协议进行处理:
按照例一中同样的做法,计算出:SAR为0,PduType为0。依据代理PDU的格式,我们知道这是一个Network PDU类型的完整消息。到这里就会将消息传递给网络层进行下一步处理。