Ble Mesh技术(九)之Friendship

Friend直接流程建立都是通过上层传输曾的控制PDU进行交互。控制消息大部分都为不分段消息,所以这一章我们以下层传输层的为分段消息作为PDU格式的总体示意图。
unsegcontrol

1. Friendship相关Control PDU

1.1. Friend Poll

由LPN发起,请求Friend发送LPN睡眠期间为LPN存储的消息。
Opcode=0x01,对应的Parameters如下所示:
poll

FieldSize(bits)Notes
Padding70b0000000,固定值
FSN1Friend Sequence Number

TTL域设置为0。
消息使用friendship security credentials加密。

1.2. Friend Update

Friend通知LPN安全参数已经改变,或者当前消息队列为空。
Opcode=0x02,对应的Parameters如下所示:
update

FieldSize(octets)Notes
Flags1第0个bit表示当前的Key Refresh阶段
第1个bit表示当前的IV Update状态
第2-7位RFU
IV Index4Friend节点当前的IV Index
MD1MD=0:表明Friend Queue为空
MD=1:表明Friend Queue非空

在这里插入图片描述

FieldNotes
Key Refresh Flag0:未处于阶段2
1:处于阶段2
IV Update Flag0:未处于IV更新状态
1:处于IV更新状态中

TTL域设置为0。
消息使用friendship security credentials加密。

1.3. Friend Request

LPN发起,向所有Friend节点广播,希望与一个Friend建立Friendship。
Opcode=0x03,对应的Parameters如下所示:
request

FieldSize(octets)Notes
Criteria1表明要与本LPN建立Friendship,Friend应该具有的最低要求
ReceiveDelay1LPN端要求的ReceiveDelay
0x00-0x09:Prohibited
0x0A-0xFF:Receive Delay,单位1ms
PollTimeout3LPN端设置的初始PollTimeout Timer值
0x000000-0x000009:Prohibited
0x00000A-0x34BBFF:PollTimerout,单位100ms
0x34BC00-0xFFFFFF:Prohibited
PreviousAddress2友尽前的前朋友地址
NumElement1当前LPN节点的元素数量,通过该值和首元素地址可以计算出该LPN的非首元素的地址,从而保证能够缓存非首元素模型的消息。
0x00:Prohibited
0x01-0xFF:元素个数
LPNCounter2Request命令发送次数的计数

在这里插入图片描述

FieldSize(bits)Notes
RFU1Reserved for Future Use
RSSIFactor2RSSI计算精度
0b00:1
0b01:1.5
0b10:2
0b11:2.5
ReceiveWindowFactor2ReceiveWindow计算精度
0b00:1
0b01:1.5
0b10:2
0b11:2.5
MinQueueSizeLog3Friend队列能存储消息数量的最小值
0b000:Prohibited
0b001:2
0b010:4
0b011:8
0b100:16
0b101:32
0b110:64
0b111:128

TTL域设置为0。
消息使用master security credentials加密。

1.4. Friend Offer

Friend收到LPN发起的Request,觉得自己条件满足要求的,向LPN发起Offer,导师转身了。
Opcode=0x04,对应的Parameters如下所示:
offer

FieldSize(octets)Notes
ReceiveWindow1本Friend支持的ReceiveWindow
0x00:Prohibited
0x01-0xFF:Receive Window,单位1ms
QueueSize1Friend端提供的队列大小
SubscriptionListSize1Friend提供给该LPN的订阅表大小,Friend通过此表来判断该消息是否属于该LPN
RSSI1计算出来的我Friend与你LPN之间的RSSI值,表征两者之间的信号强度
FriendCounter2Offer命令发送次数的计数

TTL域设置为0。
消息使用master security credentials加密。

1.5. Friend Clear

新Friend与LPN建立了Friendship后,发送该消息通知LPN的前Friend,告诉他被抛弃了,需要自己把之前留给LPN的资源给回收了。
Opcode=0x05,对应的Parameters如下所示:
clear

FieldSize(octets)Notes
LPNAddress2需要移除的LPN的单播地址
LPNCounter2新的Friendship的LPNCounter值

新Friend发送此消息期待老Friend响应,若没有收到响应,则需要重发,每次重发的时间间隔为上一次的2倍,初始间隔时间为1s。
TTL域设置为0。(会不会导致Old Friend收不到New Friend的Clear消息??协议P85)
消息使用master security credentials加密。

1.6. Friend Clear Confirm

LPN的老Friend收到新Friend的Friend Clear消息后,向新Friend响应Confirm消息,表示这边知道了,你们放心耍。
Opcode=0x06,对应的Parameters如下所示:
clearconfirm

FieldSize(octets)Notes
LPNAddress2需要移除的LPN的单播地址
LPNCounter2收到的Friend Clear中的LPNCounter值

TTL域设置为0。(疑问同上??协议P85)
消息使用master security credentials加密。

1.7. Friend Subscription List Add

LPN发送此命令给Friend,告诉Friend需要添加订阅地址。
Opcode=0x07,对应的Parameters如下所示:
list add

FieldSize(octets)Notes
TransactionNumber1交互的标记号,用于区分每个独立的消息
AddressList2*N需要添加的订阅地址(群组地址、虚拟地址)

TTL域设置为0。
消息使用friendship security credentials加密。
当N>5时,会产生分段。

1.8. Friend Subscription List Remove

LPN发送此命令给Friend,告诉Friend需要删除订阅地址。
Opcode=0x08,对应的Parameters如下所示:
list remove

FieldSize(octets)Notes
TransactionNumber1交互的标记号,用于区分每个独立的消息
AddressList2*N需要删除的订阅地址(群组地址、虚拟地址)

TTL域设置为0。
消息使用friendship security credentials加密。
当N>5时,会产生分段。

1.9. Friend Subscription List Confirm

Friend收到Subscription List Add/Remove后,需要响应Confirm,告诉LPN我这边已经收到了。
Opcode=0x09,对应的Parameters如下所示:
list confirm

FieldSize(octets)Notes
TransactionNumber1交互的标记号,用于区分每个独立的消息

TTL域设置为0。
消息使用friendship security credentials加密。

2. Friendship建立流程

2.1. ReceiveDelay/ReceiveWindow/PollTimeout

LPN月Friend之间的通信LPN每一条消息都有Friend的响应。
ReceiveDelay:LPN发送一条消息后,开始监听Friend的响应之间的时间。(给Friend准备响应的时间??)
ReceiveWindow:LPN监听Friend的响应的窗口。收到Friend的响应后,关闭窗口,发送下一个请求;若窗口时间到仍未收到响应,需要重发上次消息。达到重发次数上限(一般是3次),就认为对端不在消息处理范围内,可能是没开机或者出故障了,所以LPN需要结束Friendship,再次向周围Friend发起建立Friendship的请求。
recwindow
PollTimeout:两次连续的Friend Poll之间的最大时间间隔,即LPN单次的最大睡眠时间,Friend收到Friend Poll后,重置此timer。若PollTimeout时间到期,Friendship结束。在1.3可以知道,PollTimeout的取值范围为0x0A-0x34BBFF,单位是100ms,换算过来为1s-96h之间,为啥最大值是96h呢?因为IV更新流程的最大持续时长为96小时,这样保证了LPN不会错过IV的安全更新。

2.2. Friendship建立

建立流程如下:
① LPN向周围所有Friend发送Friend Request,表示他需要一个Friend为他保存数据。这里的Request消息TTL为0,保证只有直接收到消息的Friend才能收到Request。
② Friends收到Request后经过Friend Offer Delay的延迟后,向LPN发起Friend Offer,Friend发送Offer后期待1s内,LPN响应,若没有响应,则表示LPN未选择他 。
③ LPN在等待期间(发送Request后等待100ms,然后开启1s的等待窗口)收到的所有Offer中选择最满意的一个。给那个指定的Friend发送Friend Poll消息。若没有收到Offer,则再次发送Request,两次连续的Request之间的间隔至少为1.1s。
④ Friend收到Poll后,表示LPN选择了他,然后响应Friend Update消息,并向LPN的上一任Friend发送Friend Clear消息。
⑤ LPN收到Friend Update消息后,表明Friendship建立成功。
friendshipsetup
Friend Offer Delay体现当前LPN对信号强度和信号窗口期的重视度,通过不同的Delay,响应Offer,一是可以避免大量的Offer同时响应,导致信号拥堵,再者可以通过Factor的设置,优先过滤出想要的Friend。Friend Offer Delay的计算公式如下:
L o c a l D e l a y = R e c e i v e W i n d o w F a c t o r ∗ R e c e i v e W i n d o w − R S S I F a c t o r ∗ R S S I F r i e n d O f f e r D e l a y = m a x ( 100 , L o c a l D e l a y ) \begin{aligned} &LocalDelay=ReceiveWindowFactor*ReceiveWindow-RSSIFactor*RSSI\\ &FriendOfferDelay = max(100, LocalDelay) \end{aligned} LocalDelay=ReceiveWindowFactorReceiveWindowRSSIFactorRSSIFriendOfferDelay=max(100,LocalDelay)
当Friend收到已于他建立了friendship的LPN的Friend Request请求,说明LPN认为friendship已断,或者LPN想换一个Friend,此时Friend应该结束LPN,并释放相关的资源。

3. Friend/LPN通信

在进行通信之前,需要对friendship进行配置。

3.1. Friendship配置

配置流程如下:
① LPN收到Friend的Update后,表示友谊建立成功。发送Friend Subscription List Add消息,将自己订阅表的地址发送给Friend。
② Friend收到Subscription List Add后,响应Friend Subscription List Confirm消息,表示地址添加成功。
配置时Add和Remove消息与对应的Confirm消息应有相同的TransactionNumber值。
配置完成后,就可以进行通信了。

3.1. Friendship通信

通信流程如下:
① 所有发给LPN的消息,Friend会根据LPN的PrimAddress和元素个数和订阅表判断是否属于LPN,然后把此消息存在Friend Queue中。(Friend节点为每个建立Friendship的LPN都维护了一个Friend Queue)
② LPN醒来后,向Friend发送Friend Poll,Friend收到Poll后,向LPN响应队列的第一条消息。
③ LPN收到消息后,再次向Friend发送Friend Poll,Friend依次把队列的消息响应给LPN,若此时队列为空,则响应MD=0的Friend Update消息。
④ LPN收到MD=0的Friend Update消息,表明Friend缓存的消息都收到了。LPN再次进入睡眠,等待下一次唤醒。
friendcomunicate
当Friend Queue满了的时候,收到新的消息不是Friend Update时,则抛弃最老的非Update消息,Update消息包含了网络安全KeyRefresh和IVUpdate,因此不能被普通消息替换掉。
若Friend Queue中有多个分段确认消息,其中仅仅只有IV和Seq不同,则抛弃过期的确认消息。
LPN发起Friend Poll时,所带参数的最后1bit为FSN,当收到Friend发送的存储消息后,下一次的Poll消息中的FSN会翻转,表示这条消息LPN收到了,若Friend收到的Poll消息中FSN未翻转,说明LPN未收到上一次的消息,这事Friend需要将上一次的消息再发一次。

4. Friendship安全

在建立Friendship期间,交换的数据中包含LPNAddress/FriendAddress/LPNCounter/FriendCounter以及NetKey共同生成friendship security material,只由NetKey生成的为master security material。在非LPN/Friend的条件下,均使用master加密。在LPN/Friend建连期间的控制命令使用master security material,配置和通信期间的控制命令使用friendship security material。
所以Friend Request/Offer/Clear/Clear Confirm使用master security material。
Friend Poll/Update/Subscription List Add/Remove/Confirm使用friendship security material。
Friend Queue存储的消息通过Publish Friendship Credentials Flag字段来选择friendship还是master加密,这个字段是由配置客户端配置节点Publication参数时配置的。
若LPN向外发的消息使用的friendship security material,则只有Friend能解析,Friend收到后,转化为master加密然后再中继出去。

5. LPN分段消息的收发

发给LPN的分段消息,Friend代替LPN接收,分段确认消息也由Friend发送给源节点。Friend重组完这个分段消息后才会放入Friend Queue中,等待LPN睡醒后来拿。
LPN主动向外发送分段消息,首先分段消息应该使用master加密,只有Friend才能解析friendship加密的消息。LPN发送所有分段后,向Friend发送Poll消息,期望收到Friend存储的Segmented Ack消息,根据收到的Ack消息再次重发对端未收到的分段,其余流程同普通分段消息发送。
在分段发送期间,LPN不会睡眠,因此不会存在timer超时的情况。

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值