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.

CC2530: Software Reset on Network Leave

Part Number: CC2530
Other Parts Discussed in Thread: Z-STACK,

Hello,

I am using CC2530 with Z-Stack HA 3.0 and here I want to reset my system when I remove a device from the Network.

So for physical operation i.e. when we do it with physical switch, I have used bdb_resetLocalAction() to perform complete reset of the system.

In the similar manner I want to perform the same when device is removed from the network (i.e when  leave request is called). Could any one suggest me how can I do that.

  • When device receives leave request, it should clear everything and do reset by default.
  • Dear Yikai,

    Thank you. I will test this and get back to you.
  • Dear Yikai,

    Here I have set the leave rejoin to false as I dont want the network to join the same the network.

    Will it still clear all my NV and put a reset to the system?
  • Yes, it will clear NV.
  • Dear Yikai,

    I tested it further and saw that they NV for Application code is not cleared. How can I do that?
  • Use the following code and call system reset.

    zgWriteStartupOptions(ZG_STARTUP_SET, (ZCD_STARTOPT_DEFAULT_NETWORK_STATE | ZCD_STARTOPT_DEFAULT_CONFIG_STATE) );
  • Dear Yikai,

    I have udpated the following code:

    void ZDApp_LeaveReset( uint8 ra )
    {
      ZDApp_LeaveCtrlSet( ra );

      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 (ZG_DEVICE_ENDDEVICE_TYPE)
      {
        // Save polling values to be restored after rejoin
        if ( ra == TRUE )
        {
           ZDApp_SavedPollRate = zgPollRate;
           savedResponseRate = zgResponsePollRate;
           savedQueuedPollRate = zgQueuedPollRate;
        }

        // Disable polling
        NLME_SetPollRate(0);
        NLME_SetResponseRate(0);
        NLME_SetQueuedPollRate(0);
      }

      if ( ra == TRUE )
      {
        devState = DEV_NWK_DISC;
        devStartMode = MODE_REJOIN;
        _tmpRejoinState = true;

        // For rejoin, specify the extended PANID to look for
        osal_cpyExtAddr( ZDO_UseExtendedPANID, _NIB.extendedPANID );

        _NIB.nwkState = NWK_DISC;
         NLME_NwkDiscTerm();

        ZDApp_NetworkInit((uint16)(NWK_START_DELAY + ((uint16) (osal_rand() & EXTENDED_JOINING_RANDOM_MASK ))));
      }
      else
      {
        zgWriteStartupOptions(ZG_STARTUP_SET, (ZCD_STARTOPT_DEFAULT_NETWORK_STATE | ZCD_STARTOPT_DEFAULT_CONFIG_STATE) );
        ZDApp_ResetTimerStart( LEAVE_RESET_DELAY );
      }
    }

     

    But after adding the given line in the code, the device automatically joins the network again even if permit join is disabled.

    I have attached the sniffer log here. Where I have removed the device twice and it still gets added in the network even if permit join is disabled.

    Network Rejoining after Remove.zip

  • Can you elaborate with your sniffer log about where you send leave to your device and where the device rejoins?
  • Dear Yikai,

    Here in Log you can see on Line no 477 I have sent a remove request from coordinator. After which the device is removed from the network, but immediately after that you can see there is beacon sent by the device on line 548 after which the device rejoin the same network even if the permit join is disabled. Here you can see from line no 548 to 856 the device joins the network and all simple discriptor, transport key etc. is shared with and from coordinator.

  • If you set a breakpoint on ZDApp_ResetTimerStart( LEAVE_RESET_DELAY ) of ZDApp_LeaveReset, does it hit when you send remove device command to device?
  • Dear Yikai,

    Yes it hit the breakpoint.
  • If you keep tracing, does it reset and use new network state?
  • Dear Yikai,

    I will have to check that, but the same thing works fine for bdb_resetLocalAction(), here also zgWriteStartupOptions(ZG_STARTUP_SET, ZCD_STARTOPT_DEFAULT_CONFIG_STATE | ZCD_STARTOPT_DEFAULT_NETWORK_STATE); is called in bdb_setFN()
  • If you use original SampleLight example, does it still rejoin after receiving leave request?
  • Dear Yikai,

    I have not tested this, I will test it and get back to you in some time.
  • I suspect you revise something in source code and cause the issue. I don’t see the same trouble when I run Z-Stack 3.0 example.
  • Dear Yikai,

    I tested in SampleLight and I can see the same problem.

    In Samplelight code I have done following modifications:

    I have added following code in zcl_samplelight.c in zclSampleLight_Init function

    //Find New network if not already in some network
      if(ZDOInitDevice(0) == ZDO_INITDEV_RESTORED_NETWORK_STATE)
      {
        bdb_StartCommissioning(BDB_COMMISSIONING_REJOIN_EXISTING_NETWORK_ON_STARTUP);
      }
      else
      {
        bdb_StartCommissioning(BDB_COMMISSIONING_MODE_NWK_STEERING | BDB_COMMISSIONING_MODE_NWK_FORMATION | BDB_COMMISSIONING_MODE_FINDING_BINDING);
      }


    Than I have added following code in zcl_samplelight.c in zclSampleLight_event_loop function:

     

    case ZDO_STATE_CHANGE:
            UI_DeviceStateUpdated((devStates_t)(MSGpkt->hdr.status));

            switch ((devStates_t)(MSGpkt->hdr.status))
            {
            case DEV_HOLD:
              bdb_StartCommissioning(BDB_COMMISSIONING_MODE_NWK_STEERING | BDB_COMMISSIONING_MODE_NWK_FORMATION | BDB_COMMISSIONING_MODE_FINDING_BINDING);
              break;
            }
            break;

     

    And finally the part which you suggested in ZDApp.c in ZDApp_LeaveReset function:

     

        zgWriteStartupOptions(ZG_STARTUP_SET, ZCD_STARTOPT_DEFAULT_CONFIG_STATE | ZCD_STARTOPT_DEFAULT_NETWORK_STATE);
        ZDApp_ResetTimerStart( LEAVE_RESET_DELAY );

  • Do you test SampleLight without any modification?
  • Dear Yikai,

    As suggested by you I tested it with samplelight code by only adding
    zgWriteStartupOptions(ZG_STARTUP_SET, ZCD_STARTOPT_DEFAULT_CONFIG_STATE | ZCD_STARTOPT_DEFAULT_NETWORK_STATE)
    in ZDApp_LeaveReset().
    Here it works fine and does not join the network automatically.

    So I checked by futher by adding
    if(ZDOInitDevice(0) == ZDO_INITDEV_RESTORED_NETWORK_STATE)
    {
    bdb_StartCommissioning(BDB_COMMISSIONING_REJOIN_EXISTING_NETWORK_ON_STARTUP);
    }
    else
    {
    bdb_StartCommissioning(BDB_COMMISSIONING_MODE_NWK_STEERING | BDB_COMMISSIONING_MODE_NWK_FORMATION | BDB_COMMISSIONING_MODE_FINDING_BINDING);
    }
    in zclSampleLight_Init() and the device joins the network automatically with permit join disabled.

    But as suggest by you in
    e2e.ti.com/.../620578
    and
    e2e.ti.com/.../597186

    I am using it in the code so that device can automatically start finding network on bootup if the device is already not present in network.
  • Try to use "if(ZDApp_RestoreNetworkState()!=ZDO_INITDEV_NEW_NETWORK_STATE)" instead of "if(ZDOInitDevice(0) == ZDO_INITDEV_RESTORED_NETWORK_STATE)".
  • Dear Yikai,

    Thank you Very Much I will test this and get back to you.

  • Dear Yikai,

    I was trying to update the code as said by you. But there is a following error

    Error[e27]: Entry "AddrMgrWriteNVRequest::?relay" in module zcl_samplelight ( C:\Texas Instruments\Embedded-Z-Stack-3.0\Projects\zstack\HomeAutomation\ SampleLight\CC2530DB\RouterEB\Obj\zcl_samplelight.r51 ) redefined in module ZDApp ( C:\Texas Instruments\Embedded-Z-Stack-3.0\Projects\zstack\ HomeAutomation\SampleLight\CC2530DB\RouterEB\Obj\ZDApp.r51 )

    To use above function do I need to enable anything?
  • Do you redefine AddrMgrWriteNVRequest in your zcl_samplelight ? I don’t see anything it is related to my previous reply.
  • Dear Yikai,

    No I have not redefined it.

    Do I need to define it? If yes, what should be the params?
  • I add "extern uint8 ZDApp_RestoreNetworkState( void );" in my zcl_sampleLight.c and add the following codes in the end of void zclSampleLight_Init( byte task_id ). It can build without any problem.

    if( ZDApp_RestoreNetworkState()!=ZDO_INITDEV_NEW_NETWORK_STATE )
    {
    bdb_StartCommissioning(BDB_COMMISSIONING_REJOIN_EXISTING_NETWORK_ON_STARTUP);
    }
    else
    {
    bdb_StartCommissioning(BDB_COMMISSIONING_MODE_NWK_STEERING | BDB_COMMISSIONING_MODE_NWK_FORMATION | BDB_COMMISSIONING_MODE_FINDING_BINDING);
    }
  • Dear Yikai,

    Thank you. I will test this and get back to you.
  • Dear Yikai,

    As suggested by you I have update the code, so here when I remove device from network Samplelight Init function is called in which I have called ZDApp_RestoreNetworkState() as suggested by you, but here I get a response as ZDO_INITDEV_RESTORED_NETWORK_STATE instead of ZDO_INITDEV_NEW_NETWORK_STATE, due to which it does not try to rejoin the new network.
  • If you intend to leave device, I don’t think you should call ZDApp_RestoreNetworkState. Where do I suggest you to call it?
  • Dear Yikai,

    So my intention here is that once a device is removed from a network, it should start finding the new network or it can connect to the same network if its permit join is enabled for that network.

    How do you suggest I do this?
  • You should add the following code in zclSampleLight_Init.

    if( ZDApp_RestoreNetworkState()!=ZDO_INITDEV_NEW_NETWORK_STATE )
    {
    bdb_StartCommissioning(BDB_COMMISSIONING_REJOIN_EXISTING_NETWORK_ON_STARTUP);
    }
    else
    {
    bdb_StartCommissioning(BDB_COMMISSIONING_MODE_NWK_STEERING | BDB_COMMISSIONING_MODE_NWK_FORMATION | BDB_COMMISSIONING_MODE_FINDING_BINDING);
    }
  • Dear Yikai,

    I have already done this, but the problem is that when I remove device from the network, ZDApp_RestoreNetworkState() gives return param as ZDO_INITDEV_RESTORED_NETWORK_STATE instead of ZDO_INITDEV_NEW_NETWORK_STATE. Because of which my device does not start joining the new network.
  • Try to call ZDOInitDevice(0) before if( ZDApp_RestoreNetworkState()!=ZDO_INITDEV_NEW_NETWORK_STATE )...
  • Dear Yikai,

    I have added the following code in Samplelight Init

      ZDOInitDevice(0);
      if(ZDApp_RestoreNetworkState() != ZDO_INITDEV_NEW_NETWORK_STATE  )
      {
        bdb_StartCommissioning(BDB_COMMISSIONING_REJOIN_EXISTING_NETWORK_ON_STARTUP);
      }
      else
      {
        bdb_StartCommissioning(BDB_COMMISSIONING_MODE_NWK_STEERING | BDB_COMMISSIONING_MODE_NWK_FORMATION | BDB_COMMISSIONING_MODE_FINDING_BINDING);
      }

    So after adding this code, I have the same behaviour as before i.e. the device joins the network without permit join enabled. I think the device joins the network because of  bdb_StartCommissioning(BDB_COMMISSIONING_MODE_NWK_STEERING | BDB_COMMISSIONING_MODE_NWK_FORMATION | BDB_COMMISSIONING_MODE_FINDING_BINDING);.

    But the same problem does not occur when we use bdb_resetLocalAction();. Above problem is observed only while removing device through coordinator.

  • bdb_StartCommissioning(BDB_COMMISSIONING_MODE_NWK_STEERING | BDB_COMMISSIONING_MODE_NWK_FORMATION | BDB_COMMISSIONING_MODE_FINDING_BINDING) shouldn’t make device rejoin and it shouldn’t join a network without enable permit join. Do you use sniffer log to check this?
  • Dear Yikai,

    Yes its the same problem that I have said before I am attaching the sniffer log again. The details for the sniffer log are as follows:

    Here in Log you can see on Line no 477 I have sent a remove request from coordinator. After which the device is removed from the network, but immediately after that you can see there is beacon sent by the device on line 548 after which the device rejoin the same network even if the permit join is disabled. Here you can see from line no 548 to 856 the device joins the network and all simple discriptor, transport key etc. is shared with and from coordinator.

    6366.Network Rejoining after Remove.zip

    Also I have observed that if we dont add zgWriteStartupOptions(ZG_STARTUP_SET, ZCD_STARTOPT_DEFAULT_CONFIG_STATE | ZCD_STARTOPT_DEFAULT_NETWORK_STATE); in ZDApp_LeaveReset() the device does not rejoin the network without permit join but at the same time, it does not even start joining the new network.

  • This might be another Z-Stack issue in ZDO_ProcessMgmtLeaveReq. I have post a new issue at e2e.ti.com/.../695752 and you can refer to my quick fix in it.
  • Dear Yikai,

    Thank you for the help. I will keep track of your post.

  • Hi Ajit_Wadekar,

    You can register a callback for leave messages with ZDO_RegisterForZdoCB( ZDO_LEAVE_CNF_CBID, yourCBFunction), to get the leave confirms in your application as a NLME_LeaveCnf_t*:

    typedef struct
    {
      uint16 dstAddr;
      uint8  extAddr[Z_EXTADDR_LEN];
      uint8  removeChildren;
      uint8  rejoin;
      uint8  status;
    } NLME_LeaveCnf_t;

    Then in the callback you can call bdb_resetLocalAction() as necessary, this function will automatically set the startup options for factory new state. This will work in the same way as in your switch reset.

    Regards,

    Jose Alvarez

  • The code can go into else part "req.extAddr = NULL;" case of "if ( ( AddrMgrExtAddrValid( msg ) == FALSE ) || ( osal_ExtAddrEqual( msg, NLME_GetExtAddr() ) == TRUE ) )" and I see my test device acts normally when I redo the test for getting sniffer log today. I saw something different in your Network Rejoining after Remove.zip which use Remove Device command to remove device from coordinator but I use MGMT leave request to remove my device. I suggest you to use MGMT leave request to test it first.
  • Dear Yikai,

    Thank you for the reply.

    Actually here we can use only Remove command as we are using in Z-Stack Linux Gateway where we have limited access to complete code.

    But as suggested by Jose Maria Alvarez I will try to register callbacks and try perform my application action from there.

    Also Yikai, can you help me understand what is the major difference between Remove command and MGMT leave request ?
  • I suppose Z-Stack Linux GW uses MT_ZDO_SEC_DEVICE_REMOVE instead of MGMT leave request. However, I don't know why. Maybe can help to explain this.
  • Dear Yikai,

    Thank you for the help. I will wait for Ryan to reply.
  • Hi Ajit_Wadekar,

    You need to use MT_ZDO_MGMT_LEAVE_REQ to remove remote devices with an OTA MGMT Leave message. MT_ZDO_SEC_DEVICE_REMOVE is to remove a local security manager entry by extended address.

    Jose Alvarez
  • It seems Z-Stack Linux GW reference design uses MT_ZDO_SEC_DEVICE_REMOVE to remove device. Why?

  • Do you mean that the MT_ZDO_MGMT_LEAVE_REQ API is not provided?
  • No. If I remember correctly, Z-Stack Linux GW doesn't use MGMT leave request to delete device when you select remove devices from network.
  • Hi YK,

    Looking at the user interface code a NWK leave is used when you select a device to be removed.

    Regards

  • I think can elaborate how he does on Z-Stack Linux GW and see this remove device packet on sniffer.
  • Dear Jose,

    We have limited acces to Z-Stack Linux Gateway files, So here we are able to only trace upto the function comm_remove_device_request() in commissioning_engine.c.

    Here I am also attaching the sniffer file for device add and remove through zigbee network using Z-Stack linux Gateway, in this you can see on line  no. 654 a remove command is fired from the coordinator and than a leave is broadcasted by the device.

    5850.Remove Device.zip

  • Hi Ajit_Wadekar,

    I cannot see the packet payloads because of the network encryption. Can you share it just in case that you are not using your private secret key.

    But if the device ends up sending a network leave then I suggest to implement the application callback and register it as ZDO_LEAVE_CNF_CBID with ZDO_RegisterForZdoCB() as I said in my other post.

    Regards,