This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

Child Aging possible with NLME_PermitJoiningRequest (0x00)?

Other Parts Discussed in Thread: Z-STACK

Hi,

All I need to know is if my Coordinator does not allow joins (other than from user stimulus), NLME_PermitJoiningRequest (0x00), if a Child is 'aged' out (#define ZIGBEE_CHILD_AGING), is there no way for the End Device to simply rejoin?

If not, can CHILD_AGING be made to issue a Rejoin Request as opposed to Leave Request? A stale (not present) Child should not respond in either case, so a Rejoin instead of Leave should make no difference other than to the case outlined above.

Andy 

  • Hi Andy,

    Rejoin Req is supposed to be generated by a joining device and not something that a parent (or a potential parent) send to a (potential) child to ask it to rejoin.

    Basically, if a ZED child is aged out and so kicked out when it polls the parent, the message the ZED receives from the parent would Leave with rejoin=1. Currently with Z-Stack, ZED resets itself when it receives Leave request and will try to rejoin the network through MAC Association procedure. In that case, if the parent is not allowing new children to join by turning off Association Permit bit, the restarted ZED won't be able to join the network.

    If what you want is to enable the ZED to rejoin the network through NWK Rejoin procedures instead of MAC Association procedures, no matter what value is assigned to Association Permit bit, after being kicked out by CHILD_AGING mechanism, you need to make some modification on Z-Stack code. Please try the following patches. ('+' in the beginning of a line indicates the line needs to be added and '-' indicates the line needs to be deleted.)

    void ZDApp_LeaveReset( uint8 ra )
    {
      ZDApp_LeaveCtrlSet( ra );
    
    -  ZDApp_ResetTimerStart( LEAVE_RESET_DELAY );
    +  APSME_HoldDataRequests( LEAVE_RESET_DELAY);
    +  if ( ZSTACK_ROUTER_BUILD )
    +  {
    +    osal_stop_timerEx( NWK_TaskID, NWK_LINK_STATUS_EVT );
    +    osal_clear_event( NWK_TaskID, NWK_LINK_STATUS_EVT );
    +  }
    +
    +  if ( ra == TRUE )
    +  {
    +    devState = DEV_NWK_DISC;
    +    devStartMode = MODE_REJOIN;
    +    _tmpRejoinState = true;
    +
    +    if (ZG_DEVICE_ENDDEVICE_TYPE)
    +    {
    +      zgPollRate = POLL_RATE;
    +      ZDApp_SavedPollRate = zgPollRate;
    +      NLME_SetPollRate(0);
    +    }
    +
    +    // For rejoin, specify the extended PANID to look for
    +    osal_cpyExtAddr( ZDO_UseExtendedPANID, _NIB.extendedPANID );
    +
    +    _NIB.nwkState = NWK_DISC;
    +
    +    zdoDiscCounter = 3;
    +    NLME_NwkDiscTerm();
    +
    +    ZDApp_NetworkInit((uint16)(NWK_START_DELAY + ((uint16) (osal_rand() &
    EXTENDED_JOINING_RANDOM_MASK ))));
    +  }
    +  else
    +  {
    +    ZDApp_ResetTimerStart( LEAVE_RESET_DELAY );
    +  }
    }
    
    void ZDApp_AnnounceNewAddress( void )
    {
    #if defined ( ZIGBEE_NWK_UNIQUE_ADDR_CHECK )
      // Turn off data request hold
      APSME_HoldDataRequests( 0 );
    #endif
    
    +  ZDApp_SaveNetworkStateEvt();
    
      ZDP_DeviceAnnce( NLME_GetShortAddr(), NLME_GetExtAddr(),
                         ZDO_Config_Node_Descriptor.CapabilityFlags, 0 );
    
    #if defined ( ZIGBEE_NWK_UNIQUE_ADDR_CHECK )
      // Setup the timeout
      APSME_HoldDataRequests( ZDAPP_HOLD_DATA_REQUESTS_TIMEOUT );
    #endif
    }
    void ZDO_LeaveInd( NLME_LeaveInd_t* ind )
    {
      uint8 leave;
    
    
      // Parent is requesting the leave - NWK layer filters out illegal
      // requests
      if ( ind->request == TRUE )
      {
        // Only respond if we are not rejoining the network
        if ( ind->rejoin == FALSE )
        {
          // Notify network of leave
          NLME_LeaveRsp_t rsp;
          rsp.rejoin = ind->rejoin;
    
          if ( ZSTACK_ROUTER_BUILD )
          {
            rsp.removeChildren = ind->removeChildren;
          }
          else if ( ZSTACK_END_DEVICE_BUILD )
          {
    +        NLME_SetResponseRate(0);
    +        NLME_SetQueuedPollRate(0);
    
            rsp.removeChildren = 0;
          }

    - Cetri

  • Hi Cetri,

    Thank you for posting this code. This is great support and I am most grateful. 

    Today I have implemented the changes you describe.

    Referring to the attached Packet Sniffer log, I can see that now after a NWK Leave (P.nbr = 538), the ZED restarts and issues a Beacon Request to which the ZC replies. The difference is now the ZED issues a Rejoin Request 0x06 (P.nbr = 542). The ZED seems to rejoin OK, but then I am not sure what happens. The ZED goes in to an infinite loop of Beacon Requests (P.nbr = 548). If I power cycle the ZED it rejoins and carries on as usual (P.nbr = 7768).

    The only code I have changed in ZDApp.c is to cause a hard reset after loss of network so I can control the ZED and make it go into low power mode after 10s of searching for a network on boot and with zgDefaultStartingScanDuration = BEACON_ORDER_1_MINUTE; . This works well but may be conflicting with the new code.

    void ZDO_SyncIndicationCB( uint8 type, uint16 shortAddr )
    {
      (void)shortAddr;  // Remove this line if this parameter is used.
    
      if ( ZSTACK_END_DEVICE_BUILD
        || (ZSTACK_ROUTER_BUILD && ((_NIB.CapabilityFlags & ZMAC_ASSOC_CAPINFO_FFD_TYPE) == 0)))
      {
        if ( type == 1 )
        {
          // We lost contact with our parent.  Clear the neighbor Table.
          nwkNeighborInitTable();
    
          // Start the rejoin process.
          ZDApp_SendMsg( ZDAppTaskID, ZDO_NWK_JOIN_REQ, sizeof(osal_event_hdr_t), NULL );
    
    #ifdef END_DEVICE
          /**** Only way to get ZED into low power mode after a loss of parent is to reset ****/
         SystemReset();
    #endif
    
        }
    
      }
    }

    This is very time consuming to test as I have to wait a long time for a NWK Leave to occur. Can you tell me under what conditions does Child Aging issue a Leave Request please? I thought it would be due to a missed message from the ZED with my Child Aging timeout set to 2 minute, and the ZED transmitting every 60s, but it seems to happen with no missed messages. I am happy to read up on this but I am not sure of TI's implementation prior to it being standardised by the ZigBee Alliance.

    Thanks again for your help, this is the last obstacle before I go into pre-production testing.

    Andy

    8244.drop-out-03.psd

  • Hi Andy,

    I'm sorry I don't fully understand what you are trying for power saving. Anyway, I don't think your code made the problem you encountered.

    According to the log, the ZC didn't respond to the Rejoin Req for some reason. So, the ZED has technically not rejoined yet. The problem here is, the ZED doesn't retry to rejoin. This issue can be solved by the patch described here: http://e2e.ti.com/support/wireless_connectivity/f/158/p/208581/1337128.aspx#1337128

    - Cetri

  • Hi Cetri,

    Almost there! I have had five ZED's running with one ZC overnight with no issues- the patches worked.

    In the morning, I then introduced a ZR in to the network and powered down the ZC forcing all ZED's to reparent to the ZR- no problem and the ZC aged out the ZED's after a timeout as expected, allowing two-way comms.

    There seems to be a problem though when a Router issues a NWK Leave in that the ZED ignores it. The ZED stays in the network but is unable to receive messages as it has been aged out of the association table on the ZR.

    Please see attached sniffer log P.nbr = 5598.

    Many thanks,

    Andy2352.drop-out-04.psd

  • Hi Andy,

    If you are using Z-Stack Home 1.2.1, can you try the following workaround together?

    void nwk_Status( uint16 statusCode, uint16 statusValue )
    {
    +  if ( ZSTACK_END_DEVICE_BUILD && statusCode == NWK_STATUS_ED_ADDR )
    +  {
    +    neighborEntry_t *neighborRec;
    +
    +    neighborRec = nwkNeighborFind( _NIB.nwkCoordAddress, _NIB.nwkPanId );
    +    if ( neighborRec != NULL )
    +    {
    +      osal_cpyExtAddr( neighborRec->neighborExtAddr, _NIB.nwkCoordExtAddress );
    +    }
    +  }
    
    #if defined ( LCD_SUPPORTED )
      switch ( statusCode )
      {
        case NWK_STATUS_COORD_ADDR:
    

    - Cetri

  • Hi Cetri,

    I am using Z-Stack 1.2.1. I will try this patch and post back soon.

    Many thanks,

    Andy

  • Hi Cetri,

    Hopefully this isn't premature, but after having my network running (ZCx1, ZRx1 ZEDx4) for a couple of hours there have been no problems at all. I was expecting this last patch to allow a ZED to rejoin a Router (with permit = 0) which it probably does, but I have been unable to test it so far as it also seems to have stopped the unwanted Leave Requests in the first place. Child Aging is certainly working as the ZED's have all been aged out of the ZC and two-way comms is up and running. I will leave it running over the weekend and see.

    I don't understand why I am not seeing Leave Requests (not that I want to), but everything seems to be working great.

    The question is how low can I get the Child Aging Timeout value? The main reason for Child Aging for me is so that a user can 'join' a ZED to the ZC, walk out of radio range, the ZED automatically rejoins to a Router and two-way comms is available immediately.

    Currently my Timeout = 1, can I set this to 0? (which I think equates to 1min). Can it be less than 1min?

    Many thanks

    Andy