1. 定义及概述
路由的定义是:将数据从源节点传输到目的节点。文章出现路由这个词可以有两种理解, 一种是动词,指将网络数据传输(transfer)到目标节点的动作,这个动作需要多个节点参与;另一种是名词,路由路径,指从源到目标这条传输路径。本文讨论的zigbee的路由内容,包含路由发现、邻居表、路由表、路由发现表及部分网络层命令。
zigbee路由功能在网络层实现 (类似于互联网协议的ip层),职责是将上层或其他节点发来的网络层数据正确传输到目标节点。路由路径是由路由发现过程创建的,一条完整的路径中存在多个节点的路由表中,单个节点存储了目标节点的下一跳地址(next hop)。网络层收到数据,会先检查是否为本节点的子终端节点(end device)或是存在与邻居表(neighbor table)中的路由节点,是则做相应处理,否则查找路由表,有与目标节点匹配的有效记录则根据记录的下一跳地址发送给下个节点,如无匹配记录,或链路无效,则根据数据来源是上层还是其他节点决定是发起路由请求(route request)还是通过网络状态命令(network status)告知源节点无有效路径(no route available)。
2. 重要概念
2.1 链接损耗(link cost)
zigbee中对节点间的无线链路质量进行了量化,这个量化的值称为链接损耗,用0~7的数字表示节点间链路质量,0表示无效,1最好7最差,初始化为无效值。这个值在链接状态(link status)命令、邻居表及路由发现过程中都引用了。
2.2 路径损耗(path cost)
路由发现过程中用于量化路由路径的质量,一个路由节点收到路由请求时会将发送节点与自身的链路损耗加到路径损耗中,再转播出去,就是说路径损耗是这条路径中链接损耗的累加和。目标节点在收到路由请求消息后根据路径损耗最低的路径回应路由响应(route reply)命令,以选择最优路径。
3. 连接状态命令(link status)
网络层的一条命令,id为0x08。所有rx on idle为true(路由器默认配置就是)的路由节点每一个连接状态周期(LinkStatusPeriod默认15秒)都广播一个半径为1消息,半径为1不会被转播,消息内包含所有周边节点的接收及发送链路质量,这个质量会更新到邻居表中。链路质量在3个连接状态周期内都未收到周边节点的连接状态消息之后就变为0表示无效链路。
备注:关于3个连接状态周期会将链路质量置为0的数据来源于zigbee规范文档,实际协议栈实现中可能并非3个周期,请以实测为准。
4. 邻居表
zigbee中的路由节点会存储物理范围内可直接通讯的周边节点信息,包含了终端节点,这些信息存在邻居表(neighbor tables)中。邻居表的字段很多,下表列出本文关注的部分字段。
字段 | 描述 | 其它 |
Extended address | 长地址 | |
Network address | 短地址 | |
LQI | 存储的是接收对方数据的链路损耗 | |
Outgoing Cost | 自己发送对方接收的链路损耗,在收到对方的连接状态命令时获取到 | |
Age | 每隔一个连接状态(link status)命令周期加1,收到连接状态则清0,该值大于3时outgoint cost置为0 |
5. 路由表
路由表存储路由路径信息,本文关注部分字段如下表。
字段 | 描述 | 其他 |
destination address | 路径目标地址 | |
many-to-one | 该路径是否为many-to-one路由请求创建 | 关于源路由看后续章节 |
No route cache | many-to-one 集中节点是否拥有保持源路径的缓存 | 关于源路由看后续章节 |
route record required | 数据传输是否需要发送route record命令到集中节点 | |
next-hop address | 路径下一条地址 |
抛开源路由的内容,主要的字段就是目标地址及下一跳地址,还是挺好理解的。这些字段定义在zigbee规范中,具体协议栈实现可能有少许差异,如z-stack协议栈增加了expiryTime字段,当一个路径很久没用时,则标记为超时状态给新的路径需求腾出空间。
6. 路由发现
6.1 路由发现表
路由表存储路由路径信息,本文关注部分字段如下表。
![](/qrcode.jpg)
字段 | 描述 | 其他 |
route request id | 路由请求id,每个设备发起新的路由请求都将id加1 | |
source address | 路由请求发起者地址 | |
sender address | 收到转播中路径损耗最小的发送者地址 | |
forward cost | 源节点到当前节点的路径损耗 | |
residual cost | 当前节点到目标接点的损耗 | 该值如何得到暂时不知 |
expiration time | 如果没有收到路由应答的过期时间,默认10秒,z-stack默认为7秒 |
6.2 路由发现过程
路由发现用于寻找创建到达目标节点的路由路径,当网络层收到上层的数据请求,而在路由表中没有有效的路由路径时,网络层会广播路由请求消息。周边路由节点收到该广播时,将发送者与自己的链接损耗累加到路由请求消息的路径损耗中并转播,同时将该请求记录到路由发现表,并在路由表中创建对应的路径,此时的路径是不可用的。收到广播与转播之间存在一个随机延迟,具体协议栈实现中,链接质量越好转播延迟会越短。最终目标节点可能会收到多个转播,并拥有多个可选路径,它选择其中路径损耗最小的路径原路响应路由应答(route reply)。收到路由应答的路由节点按最优的路径将应答传回源节点,过程中发送者添加到路由表中目标地址为目标节点的记录的下一跳地址,并将该路径设置为可用,同时创建从目标到源节点的路由路径。
如下,左图节点1发送路由请求,查找到节点10的路径,转播的路径如黑色箭头。右图数字表示路连接损耗,黑色的表示路由响应,图中所示10-5-1路径只需要两跳,但是路径损耗为4,因此10应答了10-6-0-1这条路径损耗为3的路径。
7. 源路由
zigbee网络通常存在一个集中节点,需要与网络中的其他节点互相通信,为了创建与所有节点的路径,这可能需要话费很长的时间去创建路径。方向来说,可能存在所有节点同时发起路由请求寻找集中节点的的情况,这还可能引起广播风暴。zigbee网络层提供源路由方式解决这类问题。
7.1 多对一路由请求 (many-to-one route request)
集中节点通过发起many-to-one路由请求,来创建普通节点到集中节点的路径。路径损耗的计算及转播与普通路由请求一样,但是many-to-one路由请求没有路由应答,每个收到多对一路由的节点,都将收到的最优路径存储到路由表中并标记为many-to-one路径,目标地址为集中节点,下一跳为路径最优的发送者。普通节点会根据many-to-one路由请求的消息设置路由表中的No route cache属性,为true表示集中节点没有源路由缓存,每次发送数据都需要跟着发送路由记录消息。
7.2 路由记录命令(route record)
多对一路由请求创建了普通节点到集中节点的路径,但是反向路径还没有。集中节点到普通节点的路径由普通节点发送路由记录(route record)消息告知集中节点,在发送应用数据给集中节点之后普通节点会接着发送一条路由记录命令,收到这条命令的节点会将自己的地址添加到中继列表中,集中节点收到路由记录命令后根据中继列表以源路由的方式原路发送给普通节点。集中节点如有源路由缓存用于存储源路径,则这条路径会被存储在ram,否则使用过后便舍弃。
8. 终端节点(end device)与路由
终端节点不具备路由功能,其的数据往来都是通过父节点这个通道完成。发送数据直接发给父节点,由父节点发送到目标节点或者发起路由请求创建路由路径。父节点接收或响应所有目标节点为自己终端子节点的消息,将应用层数据放在缓存队列中,在终端子节点请求数据(data request)时将数据发送给它。队列中的数据超时一定时间还没有被请求的,父节点将会丢弃,如z-stack中默认为7秒。
非低功耗的终端节点可配置rx on idle 为true。这时候终端节点不需要发送数据请求就可以接收父节点的数据。
转载请注明出处:https://blog.csdn.net/jason_lm/article/details/82223079