<!--

前言

小编在前面的几个章节讲解了MESH各层的帧格式、入网的整个过程以及基础模型的作用,基本上构筑了SIG MESH的理论地基;接下来让读者们跟随着小编的步伐趁热打铁,继续讲解节点中各角色的工作流程是怎么样的;对于各角色的功能,不知道大家脑海里是否还有印象,小编在SIG MESH各个角色的功能简介中就提及到,节点的角色是由其特性所决定,而这个特性是可选的,一个节点可以存在零个或者多个特性。那么,接下来小编要讲的就是Proxy特性,即代理节点。

Proxy Protocol

既然是要讲解到代理节点,那么就不得不提及代理协议了。小编在PB-GATT入网过程以及BLE Mesh各层帧包格式详解这两个篇章均有稍微提及,那么在这篇章节小编将增加更多的细节内容。其中,代理协议的作用:

Proxy Roles

代理角色当且仅当只有两种Server和Client,其主要的作用如下:

Proxy Filter

小编在上述Proxy Protocol中的代理协议提及的内容,除了Proxy Configuration Messages之外,其他的均已经细述;可能敏感的读者已经察觉;没错,Proxy Configuration Messages就是用于配置Proxy Filter。顾名思义,Proxy Filter主要是用于Proxy Client过滤掉它不想要的数据,仅接收想要的一些目标地址的信息。这里的过滤指的是不向Proxy Client发送数据,并不是Proxy Server过滤掉不想要的数据,这个举个例子:

如果过滤器类型为白名单,其中白名单中有0xC000的地址;这个时候有一个目标地址也是0xC000的消息,让与Proxy Client相连接的Proxy Server扫描到了,这个时候Proxy Server就会通过GATT承载将该消息发送给Proxy Client;前提是当前的Proxy Server使能了中继特性,且TTL >= 2;否则,传到Proxy Server的Lower Transport Layer就被丢弃了

其中过滤器类型如下所示:

一般Proxy Filter默认为白名单类型且名单的列表内容为空,这个时候有读者可能会有这样的疑问:

既然默认为白名单且名单列表也为空,而且上述的Proxy Server.2也加强了这个观点,但是为什么小编之前篇章所提及的内容中,Proxy Client和Proxy Server却仍然能正常通信呢?白名单列表不是为空吗?是不是小编在胡说八道?

不管怎么样,小编都不会忽悠你们的哈;除了上述之后,其实还有如下几个比较特殊的点:

这也是为什么我们并没有设置白名单的内容,Proxy Client和Proxy Server仍然能正常通信的原因。

从上图的1中可知,白名单列表默认就是空的,只有增加了一个目标地址之后,其白名单列表才变成1;可能这个时候又会有读者有疑问:“Proxy Client不是已经发了Set Filter Type和 Add Addresses To Filter吗?为什么它的源地址没有添加至白名单?”

原因如下:

在没有收到任意来自于Proxy Client的有效信息时,是不会往白名单中添加的。上述的疑问中提及到的Set Filter Type和 Add Addresses To Filter中的目标地址均为unassigned address,放在Network PDU中这不算是一个有效的Mesh Message。因此,当收到这些消息时则不会将其源地址添加至白名单中;

接下来,我们再来看看上图中的2,当收到来自于Proxy Client的有效信息---Mesh Generic OnOff Get时,此时就会将该消息的源地址添加至白名单中;我们往白名单新增一个地址之后,可以从返回的Filter状态中看出此时的白名单中存放了两个地址了。

Proxy Configuration Messages

小编在上文就已经提及,代理协议还可以传输Proxy Configuration Messages,专门用于配置Proxy Server的Proxy Filter;其中该消息的帧格式跟NetWork PDU是一致的,只不过下面的域的值有些许不同:

该消息的Transport PDU帧格式如下所示:

Field NameSize(octets)Notes
Opcode1Message opcode
ParametersvariableMessage parameters

其中,该消息的Opcode如下表所示:

ValueOpcodeNotes
0x00Set Filter TypeSent by a Proxy Client to set the proxy filter type
0x01Add Addresses To FilterSent by a Proxy Client to add addresses to the proxy filter list
0x02Remove Addresses From FilterSent by a Proxy Client to remove addresses from the proxy filter list
0x03Filter StatusAcknowledgment by a Proxy Server to a Proxy Client to report the status of the proxy filter list
0x04-0xFFRFUReserved for Future Use

Set Filter Type

Proxy Client发送该消息设置Proxy Filter类型,同时清空Proxy Filter列表的内容。其帧格式的内容如下所示:

Field NameSize(octets)Notes
Filter Type1The proxy filter type

其中Filter Type有如下几种:

Add Addresses To Filter

顾名思义,该消息用增加一个或者多个目标地址至Proxy Filter列表中,其中目标地址可以为:

具体的帧格式如下所示:

FieldSize(octets)Notes
AddressArray2*NList of addresses where N is the number of addresses in this message

由上述可知,各种类型的地址的大小为16bits。

Remove Addresses from Filter

跟上述ADD Addresses To Filter相反的操作,该消息是从Proxy Filter列表中删除一个或者多个在Proxy Filter列表中的目标地址;但是你不能选择你要删除哪个目标地址,只能选择删除多少个目标地址;其帧格式跟上述的ADD Addresses To Filter是一样的,只不过Opcode不一样。

Filter Status

该消息用于应答上述的SetAddRemove消息,其帧格式内容如下所示:

FieldSize(octets)Notes
FilterType1White list or black list
ListSize2Number of addresses in the proxy filter list

Mesh GATT services

小编在上述中已经提及了代理协议、代理角色以及代理过滤器的配置;那么,Proxy Client与Proxy Server又是通过怎样进行数据收发的呢?这也就涉及到代理节点的工作流程是怎么样的;显然,它们之间的数据交互就是通过GATT承载来实现的。接下来小编将带大家好好讲讲它们的“庐山真面目”。

Mesh Provisioning Service

该服务的主要作用是用于Proxy Client配置Proxy Server,以使其加入Mesh网络;而且该服务只会存于unprovisioned device中,这也就是说一旦unprovisioned device入网变为node之后,Mesh Provisioning Service就会消失;而这里的消失只是说不暴露出来这个Service,并不是说彻底取消这个服务了,因为一旦node再次变成unprovisioned device的时候,这个服务就又会冒出来了;需要注意的是,该Service UUID为0x1827

由上图我们可以清楚知道Provisioning Service的脉络:

如上述的Provisioning Protocol,Provisioning PDUs只不过是Proxy PDU的子集。对于该服务,读者无须有恐惧感,其跟我们平时普通的BLE服务是一模一样的,只不过该服务是专门用于配置Proxy Server,使其加入mesh网络;为了加强对这个概念的巩固,我们可以参考下图:

Advertising

由于是Proxy Node,在还没有入网之前,unprovisioned device必须要发出可连接非定向广播;因为只有这样,Proxy Client才给跟Proxy Server建立连接,从而进行配置并使其加入Mesh网络;而且,Provisioning Service也要在该广播包中暴漏出来,其具体的帧格式如下所示:

AD TypeTotal LengthRequirementComments
«Flags»3M 
«Incomplete List of 16-bit Service UUIDs» or «Complete List of 16-bit Service UUIDs»4MInclude «Mesh Provisioning Service»
«Service Data»22MService Data AD Type for «Mesh Provisioning Service» followed by Service Data for this service

其中Service Data又包含如下几部分:

FieldSize(octets)Notes
Device UUID16 
OOB Information2 

除了可连接非定向广播之外,如果设备还支持PB-ADV,那么unprovisioned device还会发出不可连接的非定向广播,也就是Mesh Unprovisioned Device Beacon。关于该Beacon的详情请参考Mesh Beacon帧格式;这也就是说当device还没有入网之前,它会交替发送不可连接非定向广播和可连接非定向广播

其中可连接非定向广播的帧格式如下所示:

至于,上述提到的Service Data中的内容细节,请参考Mesh Beacon帧格式

Mesh Provisioning Service characteristics

由上述的Provisioning Service可知,Provisioning Service共有两个特征值分别为:

不知道读者对PB-GATT入网过程还有没有印象,其中Provisioning PDUs中长度最长的就是Provisioning Public Key共64字节;所以为了容纳这个最长的PDU,不管是In还是Out,这两个特征值的数据最大长度均为66字节,而且ATT_MTU值最好大于等于69字节 (不强制);这又是什么骚操作呢?

为了理清上述之间的数据依赖关系,小编又专门绘制一张它们的关系图如下所示:

如此,我相信读者如今可以理会明白它们之间的关系了吧;至于,该服务是如何对进行数据交互的,如下所示:

Mesh Proxy Service

入网之后,Service就由Mesh Provisioning Service切换成Mesh Proxy Service;那么,这也就意味着入网完成之后,紧接着会有一个断开连接的动作,然后Node发出带Mesh Proxy Service内容的可连接非定向广播包,Provisioner再次与其建立联系,从此以后都是通过Mesh Proxy Service进行入网之后的数据交互。

Advertising

跟上述的Mesh Provisioning Service-->Advertising一样,Node必须要发出可连接非定向广播;因为只有这样,Proxy Client才给跟Proxy Server建立连接,从而在Mesh网络中进行数据交互;而且,Proxy Service也要在该广播包中暴漏出来,其具体的帧格式如下所示:

AD TypeTotal LengthRequirementComments
«Flags»3M 
«Incomplete List of 16-bit Service UUIDs» or «Complete List of 16-bit Service UUIDs»4MInclude «Mesh Proxy Service»
«Service Data»21MService Data AD Type for «Mesh Proxy Service» followed by Service Data for this service

其中Service Data又包含如下几部分:

FieldSize(octets)Notes
Identification Type10x00->Network ID type; 0x01->Node Identity type; 0x02-0xFF->Reserved for future use
Identification ParametersVariableFormat determined by Identification Type field

除了可连接非定向广播之外,如果设备还支持PB-ADV,那么node还会发出不可连接的非定向广播,也就是Mesh Secure Network Beacon。关于该Beacon的详情请参考Mesh Beacon帧格式;这也就是说当device入网之后,它仍然会交替发送不可连接非定向广播和可连接非定向广播。

Mesh Proxy Service characteristics

跟上述的Mesh Provisioning Service Characteristics一样,该服务也有两个特征值分别为:

小编在上述不断地再提及,Proxy Service还可以传输如下三个类型的数据:

由于这些类型帧的最大长度没有一个固定值,所以Spec规定Proxy Service的ATT_MTU最好是大于或等于33字节即可;可能读者会想:“为什么是33这个数字,而不是34或者35?”,敏感的读者可以会联想到上述的Mesh Provisioning Service Characteristics;是的,这种联想是完全正确,因为Provisioning PDUs中最大的数据包就是64字节,经过层层拼装 (如上图的mesh_provisioning_service_data_flow所示) 之后,ATT_MTU最好是大于或者69字节;而Mesh Proxy Service则以Network PDUs的最大传输单元为基准即29字节,层层拼装之后就是33字节了;如下图所示:

是不是基本上是一样的 “套路” ;至于,该服务又是如何对进行数据交互的,如下所示: