Quantcast
Viewing all articles
Browse latest Browse all 116964

Forum Post: RE: A solution for the nature shortcoming of Z-Stack 2.5.1.a to join the network in an environment with many networks

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

  for ( stackProfile = 0; stackProfile < STACK_PROFILE_MAX; stackProfile++ )
  {
    pNwkDesc = nwk_getNwkDescList();
    for ( i = 0; i < ResultCount; i++, pNwkDesc = pNwkDesc->nextDesc )
    { 
      fInBlackList = false;  //Default false, not in the blacklist
      if( Current_Num_PanID != 1 ) //Don't enable the blacklist if there is only one PanID
      {
        for( j = 0; j < ZDO_MAX_NUM_PANID_BLACKLIST; j++)
        {
            if ( pNwkDesc->panId == ZDApp_JoinBlackList[j] )
                fInBlackList = true;         }
              
        if(fInBlackList == true ) 
            continue;
      }

      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 )
  {

//This is very important to avoid infinite loop when the intended PanID is trapped into blacklist
//Because even the intended network is possible to fail to get autorization.
 for( j = 0; j < ZDO_MAX_NUM_PANID_BLACKLIST; j++)
      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);
  }

  if ( events & ZDO_DEVICE_RESET )
  {
#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;
  }
}


Viewing all articles
Browse latest Browse all 116964

Trending Articles