父节点删除子节点后,又收到了子节点的Data request命令包,父节点会根据Data request返回一个LeaveReq命令,这条命令没有目标extAddr。
所以我在函数里面做了一个这样的处理:节点收到没有目标IEEE地址的LeaveInd命令,不采用ASSOC JOIN的方式入网,而是采用Rejoin的方式寻找一个父节点。
void ZDO_LeaveInd( NLME_LeaveInd_t* ind ) {uint8 leave;// Parent is requesting the leave - NWK layer filters out illegal// requestsif ( ind->request == TRUE ){if (osal_ExtAddrEqual(ind->extAddr,NLME_GetExtAddr())){// Only respond if we are not rejoining the networkif ( ind->rejoin == FALSE ){// Notify network of leaveNLME_LeaveRsp_t rsp;rsp.rejoin = ind->rejoin;if ( ZSTACK_ROUTER_BUILD ){rsp.removeChildren = ind->removeChildren;}else if ( ZSTACK_END_DEVICE_BUILD ){rsp.removeChildren = 0;}NLME_LeaveRsp( &rsp );}if ( ZSTACK_END_DEVICE_BUILD ){// Stop polling and get ready to resetNLME_SetPollRate( 0 );}// Prepare to leave with resetZDApp_LeaveReset( ind->rejoin );}else{retryCnt = 0;devStartMode = MODE_RESUME;_tmpRejoinState = true;osal_cpyExtAddr( ZDO_UseExtendedPANID, _NIB.extendedPANID );zgDefaultStartingScanDuration = BEACON_ORDER_60_MSEC;ZDApp_NetworkInit( 0 );}}else{leave = FALSE;// Check if this device needs to leave as a child or descendentif ( ind->srcAddr == NLME_GetCoordShortAddr() ){if ( ( ind->removeChildren == TRUE) ||( ZDO_Config_Node_Descriptor.LogicalType ==NODETYPE_DEVICE)){leave = TRUE;}}else if ( ind->removeChildren == TRUE ){// Check NWK address allocation algorithm//leave = RTG_ANCESTOR(nwkAddr,thisAddr);}if ( leave == TRUE ){// Prepare to leave with resetZDApp_LeaveReset( ind->rejoin );}else{// Remove device address(optionally descendents) from dataZDApp_LeaveUpdate( ind->srcAddr,ind->extAddr,ind->removeChildren );}}// Pass the leave indication to higher layer if callback registered.if (zdoCBFunc[ZDO_LEAVE_IND_CBID] != NULL){(void)zdoCBFunc[ZDO_LEAVE_IND_CBID](ind);} }
VV:
采用join和rejoin对于父设备来说都没问题,不管怎么样,父设备都会去update自己的Association list,而且每次都会当成一个新的设备加入。
对于节点来说就是短地址的问题,如果join的方式新的短地址,rejoin就是原先的地址。