前述
继之前对终端Direct Join的分析,发现很多东西还很模糊,存在很多问题。终于找到时间继续深入挖下去,这次应该比较完整地搞清了终端的入网机制,并纠正之前的几个认识偏差。
由于Z-Stack网络层并不开源,所以一些地方是靠的推测,很多地方的结论也没有实验验证,谨留给诸君参考和斧正。
ZigBee2007协议规范分析
先来看看ZigBee2007协议规范是怎样规定入网请求的:
The semantics of this primitive are as follows:
NLME-JOIN.request
{
ExtendedPANId,
RejoinNetwork,
ScanChannels,
ScanDuration,
CapabilityInformation,
SecurityEnable
}The next higher layer of a device generates this primitive to request to:
- Join a network using the MAC association procedure.
- Join or rejoin a network using the orphaning procedure.
- Join or rejoin a network using the NWK rejoin procedure.
- Switch the operating channel for a device that is joined to a network.
就此原语的描述可以看出,前三种情况均为设备入网的方式,最后一个是为设备切换信道所用,暂不考虑。所以ZigBee设备入网有三种方式,我们分别称之为Join、Orphan Join、Rejoin。三种方式RejoinNetwork参数分别设置为0x00、0x01、0x02。
Join入网过程。首先发起Network Discovery,返回所有应答的节点的信息。在发现的结果中找出符合要求(这里的要求是一些最基本的条件,详见ZigBee协议规范3.6.1.4.1.1节,下同)的父节点,向它发送入网请求。父节点分配16位网络地址。
Rejoin入网过程。发起Network Discovery,在应答的节点中挑选出和自己的ExtendedPANID相同的节点,在这些节点中找出符合要求的父节点,发送入网请求,并且使用自己已拥有的16位网络地址(若没有,则随机生成一个)。
Orphan Join过程。发起Orphan Scan,寻找邻居表中保存有本设备IEEE地址的父节点,在返回结果中找出符合要求的父节点,发送入网请求。父节点返回邻居表中保存的16位网络地址。
可以看出三种入网的过程都可以归纳为网络扫描+选择目标。三者的选择的筛选条件是递增的:任何节点—>指定PANID的节点—>邻居表中有自己信息的节点。
Z-Stack协议栈分析
版本号:ZStack-CC2530-2.5.1a
1. 第一步 扫描
下面是设备启动的函数ZDO_StartDevice,它是设备入网流程的入口,这个函数仅在ZDApp_event_loop事件轮询函数中发生ZDO_NETWORK_INIT事件的时候被调用,而ZDApp_NetworkInit函数就是用来延时发送ZDO_NETWORK_INIT事件的,所以ZDApp_NetworkInit函数也是设备入网过程的触发,这个函数下面将被用到。
这里我只把与终端启动的相关代码贴了出来:
/*********************************************************************
* @fn ZDO_StartDevice
*
* @brief This function starts a device in a network.
*
* @param logicalType - Device type to start
* startMode - indicates mode of device startup
*
* @return none
*/
void ZDO_StartDevice( byte l