Here is my code to fix that issue. Any suggestions to make it more realiable are very apprecaited.
ZDApp.h
#define ZDO_MAX_NUM_PANID_BLACKLIST 10
ZDApp.c
static __no_init uint16 ZDApp_JoinBlackList[ZDO_MAX_NUM_PANID_BLACKLIST];
uint16 Current_Join_PanID;
uint16 Current_Num_PanID;
/*********************************************************************
* @fn ZDApp_NwkDescListProcessing
*
* @brief This function process the network discovery result and select
* a parent device to join itself.
*
* @param none
*
* @return ZStatus_t
*/
#define STACK_PROFILE_MAX 2
networkDesc_t* ZDApp_NwkDescListProcessing(void)
{
networkDesc_t *pNwkDesc;
uint8 i, j, ResultCount = 0;
uint8 stackProfile;
uint8 stackProfilePro;
uint8 selected;
uint8 fInBlackList;
// Count the number of nwk descriptors in the list
pNwkDesc = nwk_getNwkDescList();
while (pNwkDesc)
{
ResultCount++;
pNwkDesc = pNwkDesc->nextDesc;
}
// process discovery results
stackProfilePro = FALSE;
selected = FALSE;
Current_Num_PanID = ResultCount; //Get the number of total PanIDs
{
pNwkDesc = nwk_getNwkDescList();
for ( i = 0; i < ResultCount; i++, pNwkDesc = pNwkDesc->nextDesc )
{
fInBlackList = false; //Default false, not in the blacklist
{
for( j = 0; j < ZDO_MAX_NUM_PANID_BLACKLIST; j++)
{
if ( pNwkDesc->panId == ZDApp_JoinBlackList[j] )
fInBlackList = true; }
if(fInBlackList == true )
}
if ( zgConfigPANID != 0xFFFF )
{
// PAN Id is preconfigured. check if it matches
if ( pNwkDesc->panId != zgConfigPANID )
continue;
}
if ( nwk_ExtPANIDValid( ZDO_UseExtendedPANID) == true )
{
// If the extended Pan ID is commissioned to a non zero value
// Only join the Pan that has match EPID
if ( osal_ExtAddrEqual( ZDO_UseExtendedPANID, pNwkDesc->extendedPANID) == false )
continue;
}
// check that network is allowing joining
if ( ZSTACK_ROUTER_BUILD )
{
if ( stackProfilePro == FALSE )
{
if ( !pNwkDesc->routerCapacity )
{
continue;
}
}
else
{
if ( !pNwkDesc->deviceCapacity )
{
continue;
}
}
}
else if ( ZSTACK_END_DEVICE_BUILD )
{
if ( !(pNwkDesc->deviceCapacity) )
{
continue;
}
}
// check version of zigbee protocol
if ( pNwkDesc->version != _NIB.nwkProtocolVersion )
continue;
// check version of stack profile
if ( pNwkDesc->stackProfile != zgStackProfile )
{
if ( ((zgStackProfile == HOME_CONTROLS) && (pNwkDesc->stackProfile == ZIGBEEPRO_PROFILE))
|| ((zgStackProfile == ZIGBEEPRO_PROFILE) && (pNwkDesc->stackProfile == HOME_CONTROLS)) )
{
stackProfilePro = TRUE;
}
if ( stackProfile == 0 )
{
continue;
}
}
break;
}
if (i < ResultCount)
{
selected = TRUE;
break;
}
// break if selected or stack profile pro wasn't found
if ( (selected == TRUE) || (stackProfilePro == FALSE) )
{
break;
}
}
if ( i == ResultCount )
{
ZDApp_JoinBlackList[j] = 0;
return (NULL); // couldn't find appropriate PAN to join !
}
else
{
Current_Join_PanID = pNwkDesc->panId;
return (pNwkDesc);
}
}// ZDApp_NwkDescListProcessing()
/*********************************************************************
* @fn ZDApp_event_loop()
*
* @brief Main event loop for Zigbee device objects task. This function
* should be called at periodic intervals.
*
* @param task_id - Task ID
* @param events - Bitmap of events
*
* @return none
*/
UINT16 ZDApp_event_loop( uint8 task_id, UINT16 events )
{
uint8 *msg_ptr;
if ( events & SYS_EVENT_MSG )
{
while ( (msg_ptr = osal_msg_receive( ZDAppTaskID )) )
{
ZDApp_ProcessOSALMsg( (osal_event_hdr_t *)msg_ptr );
// Release the memory
osal_msg_deallocate( msg_ptr );
}
// Return unprocessed events
return (events ^ SYS_EVENT_MSG);
}
if ( events & ZDO_NETWORK_INIT )
{
// Initialize apps and start the network
devState = DEV_INIT;
osal_set_event( ZDAppTaskID, ZDO_STATE_CHANGE_EVT );
ZDO_StartDevice( (uint8)ZDO_Config_Node_Descriptor.LogicalType, devStartMode,
DEFAULT_BEACON_ORDER, DEFAULT_SUPERFRAME_ORDER );
// Return unprocessed events
return (events ^ ZDO_NETWORK_INIT);
}
if ( ZSTACK_ROUTER_BUILD )
{
if ( events & ZDO_NETWORK_START )
{
ZDApp_NetworkStartEvt();
// Return unprocessed events
return (events ^ ZDO_NETWORK_START);
}
if ( events & ZDO_ROUTER_START )
{
if ( nwkStatus == ZSuccess )
{
if ( devState == DEV_END_DEVICE )
devState = DEV_ROUTER;
osal_pwrmgr_device( PWRMGR_ALWAYS_ON );
}
else
{
// remain as end device!!
}
osal_set_event( ZDAppTaskID, ZDO_STATE_CHANGE_EVT );
// Return unprocessed events
return (events ^ ZDO_ROUTER_START);
}
}
if ( events & ZDO_STATE_CHANGE_EVT )
{
ZDO_UpdateNwkStatus( devState );
// At start up, do one MTO route discovery if the device is a concentrator
if ( zgConcentratorEnable == TRUE )
{
// Start next event
osal_start_timerEx( NWK_TaskID, NWK_MTO_RTG_REQ_EVT, 100 );
}
// Return unprocessed events
return (events ^ ZDO_STATE_CHANGE_EVT);
}
if ( events & ZDO_COMMAND_CNF )
{
// User defined logic
// Return unprocessed events
return (events ^ ZDO_COMMAND_CNF);
}
if ( events & ZDO_NWK_UPDATE_NV )
{
ZDApp_SaveNetworkStateEvt();
// Return unprocessed events
return (events ^ ZDO_NWK_UPDATE_NV);
}
{
#ifdef ZBA_FALLBACK_NWKKEY
if ( devState == DEV_END_DEVICE_UNAUTH )
{
ZDSecMgrFallbackNwkKey();
}
else
#endif
{
if( Current_Num_PanID != 1 )
if(devState == DEV_END_DEVICE_UNAUTH ) //If unauthorized before reset, then add it into blacklist
ZDApp_JoinBlackList[0] = Current_Join_PanID;
for ( uint8 j = ZDO_MAX_NUM_PANID_BLACKLIST; j > 1; j--)
ZDApp_JoinBlackList[j-1] = ZDApp_JoinBlackList[j-2];
ZDApp_JoinBlackList[0] = 0; //
}
// Set the NV startup option to force a "new" join.
zgWriteStartupOptions( ZG_STARTUP_SET, ZCD_STARTOPT_DEFAULT_NETWORK_STATE );
// The device has been in the UNAUTH state, so reset
// Note: there will be no return from this call
SystemResetSoft();
}
}
if ( ZG_SECURE_ENABLED )
{
return ( ZDApp_ProcessSecEvent( task_id, events ) );
}
else
{
// Discard or make more handlers
return 0;
}
}