1,When a router act non--silent-rejoin, the rejoin-timeout is 0(NWK_REJOIN_TIMEOUT_EVT), that will a failed-rejoin in "ZDO_JoinConfirmCB".
It can be fixed like this
fix ZDApp_RestoreNetworkState, set a valid timeout for router's rejoining.
uint8_t ZDApp_RestoreNetworkState( void )
{
...
else if( ZG_DEVICE_RTRONLY_TYPE &&
(zgRouterSilentRejoin == FALSE) )
{
devStartMode = MODE_REJOIN;
_NIB.nwkState = NWK_INIT;
// set rejoin-timeout to be valid, fixed by luoyiming 2023-05-13
if(nwk_pollRateTable.PollRateRejoin == 0)
{
nwk_pollRateTable.PollRateRejoin = REJOIN_POLL_RATE;
}
}
...
}
fix ZDO_JoinConfirmCB, stop NWK_REJOIN_TIMEOUT_EVT timer for router.
void ZDO_JoinConfirmCB( uint16_t PanId, ZStatus_t Status )
{
(void)PanId; // remove if this parameter is used.
nwkStatus = (byte)Status;
if ( Status == ZSUCCESS )
{
if ( ZSTACK_END_DEVICE_BUILD
|| (ZSTACK_ROUTER_BUILD && BUILD_FLEXABLE && ((_NIB.CapabilityFlags & ZMAC_ASSOC_CAPINFO_FFD_TYPE) == 0)))
{
neighborEntry_t *pItem;
// We don't need the neighbor table entries.
// Clear the neighbor Table to remove beacon information
nwkNeighborInitTable();
// Force a neighbor table entry for the parent
pItem = nwkNeighborFindEmptySlot();
if ( pItem != NULL )
{
memset( pItem, 0x00, sizeof ( neighborEntry_t ) );
pItem->neighborAddress = _NIB.nwkCoordAddress;
osal_cpyExtAddr( pItem ->neighborExtAddr, _NIB. nwkCoordExtAddress );
pItem->panId = _NIB. nwkPanId;
pItem->linkInfo.rxLqi = DEF_LQI;
pItem->linkInfo.txCounter = DEF_LINK_COUNTER;
pItem->linkInfo.txCost = DEF_LINK_COST;
}
}
// Stop NWK auto poll for Router, fixed by luoyiming 2023-05-13
if( ZG_DEVICE_RTRONLY_TYPE )
{
OsalPortTimers_stopTimer(NWK_TaskID, NWK_AUTO_POLL_EVT);
}
if ( devState == DEV_HOLD )
{
ZDApp_ChangeState( DEV_NWK_JOINING );
}
}
// Pass the join confirm to higher layer if callback registered
if (zdoCBFunc[ZDO_JOIN_CNF_CBID] != NULL )
{
zdoJoinCnf_t joinCnf;
joinCnf.status = Status;
joinCnf.deviceAddr = _NIB.nwkDevAddress;
joinCnf.parentAddr = _NIB.nwkCoordAddress;
zdoCBFunc[ZDO_JOIN_CNF_CBID]( (void*)&joinCnf );
}
// Notify ZDApp
ZDApp_SendMsg( ZDAppTaskID, ZDO_NWK_JOIN_IND, sizeof(OsalPort_EventHdr), (byte*)NULL );
}
2, If Router act unsecured-rejoin, it will request APS-link key again, it can be fixed like this
if ( events & ZDO_DEVICE_AUTH )
{
ZDApp_StoreNwkSecMaterial();
ZDApp_DeviceAuthEvt();
// Don't exchange key for unsecured-rejoin, fixed by luoyiming 2023-05-13
if(!bdb_isDeviceNonFactoryNew())
{
bdb_setNodeIsOnANetwork(TRUE);
bdb_reportCommissioningState(BDB_COMMISSIONING_STATE_JOINING, TRUE);
}
// Return unprocessed events
return (events ^ ZDO_DEVICE_AUTH);
}
3, When Router act non-silent-rejoin, if Router can't discover any parent of its network,it will leave the current network. It can be fixed like this
case ZDO_NWK_DISC_CNF:
if (devState != DEV_NWK_DISC)
{
break;
}
if ( ZG_BUILD_JOINING_TYPE && ZG_DEVICE_JOINING_TYPE )
{
//Rejoin or resume
if(bdb_isDeviceNonFactoryNew())
{
if(bdb_rejoinNwk() == ZSuccess)
{
return;
}
else
{
if(ZG_DEVICE_ENDDEVICE_TYPE)
{
bdb_parentLost();
}
//Router change to orphan state when discover failed, fixed by luoyiming 2023-05-13
else if(ZG_DEVICE_RTRONLY_TYPE)
{
ZDApp_ChangeState( DEV_NWK_ORPHAN );
}
}
return;
}
if(nwk_getNwkDescList())
{
bdb_nwkDiscoveryAttempt(TRUE);
}
else
{
bdb_nwkDiscoveryAttempt(FALSE);
}
}
break;
void ZDApp_ProcessNetworkJoin( void )
{
if ( (devState == DEV_NWK_JOINING) ||
((devState == DEV_NWK_ORPHAN) &&
(ZDO_Config_Node_Descriptor.LogicalType == NODETYPE_ROUTER)) )
{
...
}
else if ( devState == DEV_NWK_ORPHAN ||
devState == DEV_NWK_SEC_REJOIN_CURR_CHANNEL ||
devState == DEV_NWK_TC_REJOIN_CURR_CHANNEL ||
devState == DEV_NWK_TC_REJOIN_ALL_CHANNEL ||
devState == DEV_NWK_SEC_REJOIN_ALL_CHANNEL )
{
// results of an orphaning attempt by this device
if (nwkStatus == ZSuccess)
{
.......
}
else
{
.........
//Router change to orphan state when rejoin failed, fixed by luoyiming 2023-05-13
if(ZG_DEVICE_RTRONLY_TYPE)
{
ZDApp_ChangeState( DEV_NWK_ORPHAN );
}
}
}
else if ( devState != DEV_HOLD )
{
}
}