<!--
我相信看过我们PB-GATT入网过程的读者,应该对入网的全过程有了一个相对程度的了解吧;当然啦,如果短期间看不明白也没有关系,那就多看几遍。接下来,小编仍然还是给大家讲解Mesh入网的全过程,只不过此次是PB-ADV的方式入网;那么,接下来先讲讲什么是PB-ADV。
什么是PB-ADV?
对于有一些了解的读者,看到这个名词时肯定会说“这不就是通过广播包互相收发数据,从而配置入网嘛”,其实对于总的概括来说是没有错的。但是,我们有一些关键的地方我们仍然还要注意:
讲了这么多,接下来我们还是采用同样的套路,先看PB-ADV的帧格式,之后再分别层层剖析。
由上图可知,PB-ADV PDU主要由Link ID,Transaction Number,Generic Provisioning PDU三个部分组成;
该字段所表示的含义比较好理解,其起到的就是一个标识符的作用;主要用于在配置过程辨别同一个LINK ID下,Provisioner与unprovisioned device的数据交互;不同LINK ID的packets会被彼此忽略,因为一个会话的生命周期时有且仅有一个Link ID,不同的会话其LINK ID是不一样的。注意,LINK ID是由Provisioner随机产生的。
该字段主要用于辨别每个单独的Generic Provisioning PDU;即从0x00开始,该值在每个新的Generic Provisioning PDU上累加 (对于Provisioning Bearer Control PDU,其Transaction Number一直都是0x00),如果累加到最大值时,则又从0x00重新开始;对于Provisioner和Unprovisioned device它们两者的最大值是不一样的:
Provisioner
最大只能达到0x7F;
Unprovisioned Device
最大可能达到0xFF;
但是,也有两种情况是不需要累加的:
该PDU的详细情况,小编不在此处展开,准备将其放在Generic Mesh Provisioning Control和Generic Mesh Provisioning Payload两个章节中细述。
同理,这个步骤跟我们上一章节PB-GATT入网过程中的入网流程小章节所细述的内容是一模一样,小编这里就不再细述;下图所示的是PB-ADV方式入网的全过程:
与PB-GATT相比之下,多了Generic Mesh Provisioning Link Open、Generic Mesh Provisioning Link Ack、Generic Mesh Provisioning Link Close,那么这三者之间有什么关联呢?我们在上述的内容也有提到这一点,PB-ADV是采用会话的模型进行配置数据的收发,那么会话模型就需要这三个PDU来建立,具体如下图所示:
注意:上述的这三个PDU均属于Provisioning Bearer Control PDU的范畴,也就是说这三个PDU根据不同的场景所组装成不同的PDU就表示Provisioning Bearer Control PDU;
Link Open消息用于在Provisioner和Unprovisioned Device之间建立链接,Unprovisioned Device如果接收到该消息,应使用Link ACK消息应答此消息。具体的帧格式如下:
其中Device UUID指的是选中的Unprovisioned Device的UUID。
该消息用于发送应答消息,表示其收到Link Open的消息了,具体的帧格式如下:
这里值得注意的是:应答消息是不携带任何参数的。
该消息用于关闭Link会话,由于该消息是没有被应答的,因此为了保险起见,Link关闭消息最少要发送3次且Provisioner和Unprovisioned Device均可以发送该消息,并且携带关闭原因这个参数。具体的帧格式如下图所示:
注意:关于Link Establishment procedure我们还有以下几点需要大家了解下:
- 对于Provisioner而言,其在准备建立Link会话时会先设置一个60秒的定时器,接着发送Link Open消息;如果在60秒后没有收到Unprovisioned Device的Link Ack的消息,则认为此次Link会话建立失败;
- 对于Unprovisioned Device而言,其在收到Link Open消息之后,会给Provisioner回应Link Ack的消息,紧接着同样也开启一个60秒定时器;如果在60秒后没有收到任何的Provisioning PDU,则认为此次Link会话建立失败;
除了上述的之外,这两种方式最大的不同是:
PB-GATT
通过Proxy PDUs进行配置数据的收发
PB-ADV
通过Generic Provisioning PDUs进行配置数据的收发
至于Proxy PDUs,我们在PB-GATT入网过程已经细述过,该小章节我们着重描绘Generic Provisioning PDUs的内容,如下图所示:
由上图可知,该PDU主要由Generic Provisioning Control和Generic Provisioning Payload组成。
该字段主要表明Generic Provisioning Control域包含的是哪一种类型的GPCF,至于一共有哪几种类型的Generic Provisioning Control,上述的Generic Provisioning PDU示意图已经描述地很清楚了:
Transaction Start PDU用于启动分段消息的转输,也就是说每一个Provisioning PDU的消息传输都是使用该PDU开始传输。而Provisioning PDU到底都是些什么帧格式呢?在上一章节PB-GATT入网过程中已经详述过,即
Type | Name |
---|---|
0x00 | Provisioning Invite |
0x01 | Provisioning Capabilities |
0x02 | Provisioning Start |
0x03 | Provisioning Public Key |
0x04 | Provisioning Input Complete |
0x05 | Provisioning Confirmation |
0x06 | Provisioning Random |
0x07 | Provisioning Data |
0x08 | Provisioning Complete |
0x09 | Provisioning Failed |
0x0A-0xFF | RFU |
该PDU的具体帧格式如下表所示:
Field | Size (bits) | Description |
---|---|---|
SegN | 6 | The last segment number |
GPCF | 2 | 0b00 = Transaction Start |
TotalLength | 16 | The number of octets in the Provisioning PDU |
FCS | 8 | Frame Check Sequence of the Provisioning PDU |
该字段其实就是表示除了Transaction Start中携带了一些Provisioning PDU,剩下的Provisioning PDU还需要多少个分段的包才能发送完成;
对于该PDU,该字段固定为0x00
表示要表达的Provisioning PDU总有多少字节
该字段则表示对Provisioning PDU进行计算后的帧检验值
为了上述更易于理解,我们可以查看如下所示的捉包图:
Transaction应答PDU用于应答接收到的Provisioning PDU,跟其他的应答消息一样,它也是不携带任何参数的。
Field | Size (bits) | Description |
---|---|---|
Padding | 6 | 0b000000; all other values Prohibited |
GPCF | 2 | 0b01 = Transaction Acknowledgment |
使用Transaction Start PDU没有办法将整个Provisioning PDU传送完成,就应该使用该字段传输分包的Provisioning PDU。具体的帧格式如下所示:
Field | Size (bits) | Description |
---|---|---|
SegmentIndex | 6 | Segment number of the transaction |
GPCF | 2 | 0b10 = Transaction Continuation |
该字段表示当前的Provisioning PDU是第几个分包;
固定为0b10,表示Transaction Continuation;
表示各个分包Provisioning PDU的内容;
该类型的PDU是上述的Generic Mesh Provisioning Link Open、Generic Mesh Provisioning Link Ack、Generic Mesh Provisioning Link Close的统称,这也就是说该PDU是由根据不同的BearerOpcode类型来表示不同的PDU。
该字段所描述的PDU内容其实是根据Generic Mesh Provisioning Control设置的不同而不同,其本质就是用来传输Provisioning PDU,至于怎么传输,传输哪些内容则是看当前处于入网的哪个阶段,Provisioning PDU有多少字节。例如:当前Provisioner与Unprovisioned Device进入到交换公钥的阶段,这个时候就必须使用Transaction Start PDU和Transaction Continuation PDU来传输Provisioning PDU。
同时,我们在刚看上面前言中的PB-ADV图时,肯定会有读者在想“Generic Provisioning PDU不是最大只支持24字节吗?为什么下面的Generic Provisioning Payload是0~64字节,这不是比24字节还大吗?” 我想有这样疑问的读者,现在应该知道为什么了吧?没错,放不下去我还可以分包啊。
在入网流程中的最前面提及到整个PB-ADV流程中可以看出,基本上跟PB-GATT是一模一样的,所以这个章节就不再重复。不同的点我在上述也已经一一细述。但是还有一些细节,小编觉得还是有必要要了解一下: