ZigBee终端直接入网(Direct Join)方式分析
[复制链接]
这里引用《ZigBee2007协议规范》中的原语流图更加清楚:
可以看到父节点只是执行了一个添加相邻表条目的动作,并没有实际的动作,这里我们可以理解为它为已知的会进行直接加入的子节点分配好空间等它。
这里是子节点试图入网的动作。其实本质就是Rejoin,和终端断网后重连的机制完全相同。就是直接扫描查询附近中有没有自己的父节点(怎么判断是不是自己的父节点,下文述),如果有就加入,如果没有就结束Rejoin,然后重新开始进行关联加入。其实我们完全可以把这个终端就视为一个掉电重连的孤儿节点。
这里是协调器或路由器对于前述的终端扫描查询(SCAN)的回复动作,注意,这里不一定是Direct Join的目标父节点。这个节点会接收到孤儿节点的查询请求(MLME_ORPHAN.indication)。然后开始比对自己有没有这个“儿子”,进行相应回复。这一部分过程也是所有的孤儿节点执行Rejoin的机制。
从上面的分析我们可以这样理解:对于终端来说Direct Join和Rejoin完全相同,只不过前者的父节点是我们人工预置的,后者的父节点是终端之前连接过的。
ZigBee终端直接入网(Direct Join)实验
平台:CC2530
协议栈:Z-Stack (version:ZStack-CC2530-2.5.1a)
代码:基于TI例程SampleApp
工具:Debug在线调试
实验步骤:
首先,修改如下几处代码。这里参考了TI的文档Using the Direct Join Request Feature in Z-Stack
ZDApp.c文件的devStartMode定义初始化修改为:
#if ( ZG_BUILD_RTRONLY_TYPE ) || ( ZG_BUILD_ENDDEVICE_TYPE )
#ifdef DIRECTJOIN
devStartModes_t devStartMode = MODE_RESUME;
#else
devStartModes_t devStartMode = MODE_JOIN;
#endif
#else
devStartModes_t devStartMode = MODE_HARD;
#endif
另外,在ZDApp.c文件的ZDAppDetermineDeviceType函数中也要修改:
if ( nwk_ExtPANIDValid( AIB_apsUseExtendedPANID ) == false )
{
#ifdef DIRECTJOIN
devStartMode = MODE_RESUME;
#else
devStartMode = MODE_JOIN; // Assume joining
#endif
}
最后在目标父节点内添加按键功能:(64位长地址为事先使用SmartRF Flash Programmer在子节点取得)
void HandleKeys( uint8 keys )
{
unsigned char device_address[8] = {0x00, 0x12, 0x4B, 0x00, 0x04, 0xEF, 0x81, 0x94};
if(keys & BUTTON_1)
{
HalLedSet( HAL_LED_3, HAL_LED_MODE_TOGGLE );
NLME_DirectJoinRequest( device_address, CAPINFO_DEVICETYPE_RFD );
}
}
开始运行调试,监视子节点在ZDO_STATE_CHANGE事件中的状态的改变。
实验一:先依次上电启动协调器、路由器(目标父节点)、终端(监视子节点)。可以观察到子节点的devStates_t的变化顺序为:
- DEV_NWK_ORPHAN
- DEV_NWK_DISC
- DEV_END_DEVICE
子节点连入父节点或协调器,视距离决定。
实验二:保持协调器、路由器运行,重启终端。观察到子节点此时的devStates_t的变化顺序为:
- DEV_NWK_ORPHAN
- DEV_END_DEVICE
子节点连入父节点或协调器,与前次保持一致,与距离无关。
实验三:依次重启协调器、路由器,按下路由器BUTTON_1启动Direct Join。然后重启终端。观察到子节点此时的devStates_t的变化顺序为:
- DEV_NWK_ORPHAN
- DEV_END_DEVICE
子节点连入父节点,与距离无关
总结:
从这三个实验可以看出,采用Direct Join的终端在启动时,设备状态为孤节点(DEV_NWK_ORPHAN),若没有搜索到父节点(实验一),将执行关联入网的搜索(DEV_NWK_DISC),然后成功入网成为DEV_END_DEVICE;若搜索到预置的父节点(实验三),将直接成为它的子节点(DEV_END_DEVICE)。第二个实验表明当终端曾经连入过某个父节点后,将在这个父节点的关联表中保留它的信息,此时这个父节点和执行了Direct Join操作的节点并无二异。
|