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.

How to Remove End-Device Children When The Parent Child Association Capacity Goes Full?

Dear friends,

I was working on a locating project. To slove parent address overflow issue, I disabled both router and end-device's NV_RESTORE option and made end-devices to send LEAVE request to its parent once the locating result data had been sent. Then the end-device will reset itself. The parent node should remove the child from its association list at same time. Next round, the end-device will join network as new node to do next locating task.

It seems woking fine with less nodes quantity. Unfortunately, when apply this to a high amount router and end-devices in a work floor environment(100 routers and 50 end-devices), There're too many conflict in the air. too many beacon request and response. too may route boardcast. Sometimes the LEAVE request cannot to process well. It causes the child address cannot be removed from parent's association list, so parent's children capacity went full (14 end-devices by default). The result is end device cannot join network at all. To solve this, what I only can do: just reboot all routers to let them to "forget" their children.

My idea is let parent node to clean its child association list without reboot when it's association list goes full. I don't know what the correct way is to remove all end-device children without affecting to its router children. Please help. Code sample will be highly appreciated.

Henry

 

  • Today's idea, not implement yet:

    1) Loop the following array to get associated devices, then check the nodeRelation to find out all child devices and its index in addrIdx.

    associated_devices_t AssociatedDevList[NWK_MAX_DEVICES];

    Related type definition:

    typedef struct
    {
      UINT16 shortAddr;                 // Short address of associated device
      uint16 addrIdx;                   // Index from the address manager
      byte nodeRelation;
      byte devStatus;                   // bitmap of various status values
      byte assocCnt;
      linkInfo_t linkInfo;
    } associated_devices_t;


    // Node Relations
    #define PARENT              0
    #define CHILD_RFD           1
    #define CHILD_RFD_RX_IDLE   2
    #define CHILD_FFD           3
    #define CHILD_FFD_RX_IDLE   4
    #define NEIGHBOR            5
    #define OTHER               6
    #define NOTUSED             0xFF

     

    2) Get ExtAddr from the following function call.
    extern uint8 AddrMgrExtAddrLookup( uint16 nwkAddr, uint8* extAddr );
    or
    extern uint8 AddrMgrEntryGet( AddrMgrEntry_t* entry );

    3) Invoke the following function call to remove child.
    extern void NLME_RemoveChild( uint8* extAddr, uint8 dealloc );

     

    I wonder if it is required to manually remove association record and address manager entry once the child has been removed. 

     

    Henry

  • below is my code for this, but it is not working, please help.

     

      byte index;
      associated_devices_t *aDevice;
      uint8* extAddr;
      
      index = 0;
      
      for ( ; index < NWK_MAX_DEVICES; index++ )
      {
        aDevice = AssocFindDevice( index );
        if ( ( aDevice->nodeRelation == CHILD_RFD ) || ( aDevice->nodeRelation == CHILD_RFD_RX_IDLE ) )
          {
            if ( AddrMgrExtAddrLookup( aDevice->shortAddr, extAddr ) == TRUE )
            {
              NLME_RemoveChild( extAddr, FALSE );
            }
         } 
      }     

    I found sometimes "AddrMgrExtAddrLookup( aDevice->shortAddr, extAddr )" does not return "TRUE" as expected.

    and even "NLME_RemoveChild" has been excuted, it causes nothing. It seems no child be removed.

     

    Henry

  • Hi Henry,

    Below is some code I use to flush stale children that you can pick the bones out of if you want. It seems to work and I've not discovered any side effects(yet).

    The childDevList[] is a structure I maintain to determin if the child is stale. You will want to devise your test for this.

    Cheers.

     

    static void FlushStaleNodes(void) {
      for (uint8 x=0;x<NWK_MAX_DEVICES;x++) {
        byte nr =  AssociatedDevList[x].nodeRelation;
        if (nr == CHILD_RFD || nr == CHILD_RFD_RX_IDLE || nr == CHILD_FFD || nr == CHILD_FFD_RX_IDLE) {
          if (childDevList[x].isActive && childDevList[x].rxMsgCount == 0) {
            childDevList[x].isActive = FALSE;
            RemoveStaleNode(x);
          }
          else {
            childDevList[x].isActive = TRUE;
          }
          childDevList[x].rxMsgCount=0;
        }
      }
    }

     

    static void RemoveStaleNode(uint8 index) {
      AddrMgrEntry_t addrEntry;
      NLME_LeaveReq_t req;

      // Set up device info

      addrEntry.user  = ADDRMGR_USER_DEFAULT;
      addrEntry.index = index;

      if (AddrMgrEntryGet( &addrEntry )) {

        // Remove device

        req.extAddr = addrEntry.extAddr;
        req.removeChildren = TRUE;
        req.rejoin = FALSE;
        req.silent = FALSE;

        NLME_LeaveReq( &req );
      }

    }

     

     

     

     

  • Hi Steve,

    Many thanks! I will look into it and write back later!

    Cheers

    Henry

  • Hi Steve,

    Your code is working fine~~.

    After test this, I found a new issue.

    if the end device missed the LEAVE message from its parent, it always assumes itself in the network and keep using its nwk address. After "removed" the original child, the parent should accept a new child and allocate the recycled nwk address. So, duplicate nwk addr may appeare in the network.

    My solution is ask the end device force reset after complete locating data transfer, then the end device restart, it will send orphan request to get a nwk address from then router, router should remove some children  timely using the FIFO strategy. The remove time span should > end device working cycle to aviod duplicate nwk address.

    I guess this way can solve the 14 children pain in locating application.

    Henry 

  • Where abouts did you implement the code above, I have the same issue with the AssociatedDevList fulling up. I have looked for a place in the ZDApp and ZDNwkMgr where the stack already handles new devices joining, but it apears to be hiden in the libarry files.

    Have you just implemented this code on a Polling timer event?

    Also how are you counting the child msgs to check if a child is active. ie where do you get the child  event msg cb from.

  • Hello Henry and Steve.

    I have revised the forum and I think have the same problem that you. I would like trying your solution.

    I need that the coordinator permits much more of 14 children. Is your code the solution to my problem???

    Moreover, I don't know where put your code for testing. In which file ?????

    Thank you very much.

  • Hi Steve,

    Did you explicitly let all children update their parent about their presence periodically? In my application, end devices polls from their parents every 5 minutes. However, they might not send anything. Can I use some kind of callback in parent nodes to update the active field in the childDevList table every time end devices poll?

    Thanks.

    Yuan Jian

  • This thread became a run-on after the original problem was solved by the code shared by Steve - so I marked his response as the answer. As for concerns about duplicate ZED addresses, it won't happen, because in ZigBee PRO, ZED devices keep thier assigned address for their lifetime, even when they change parents.