Best way to reset nrf52 after zigbee connection fails

Hi,
What is in your opinion the best way to handle device reset after the Zigbee connection fails?

I want to archive behavior like so: after connection fails sleep for 10 minutes and reboot.

I was thinking about using a watchdog for the ZigBee thread.

I'm trying to make this modification, while not changing zb_nrf_platform.c.

Do you think there is another way?

I was also thinking about reimplementing ZB_BDB_SIGNAL_DEVICE_REBOOT case from zigbee_default_signal_handler in zigbee_app_utils.c.

Maybe in this case I should check in the zboss_signal_handler for reboot signal and if occurs handle the desired behavior. and if no pass zb_bufid_t to zigbee_default_signal_handler.

What in your opinion is the most elegant way?

Parents
  • Hi,

    With Zigbee connection fail, do you mean that the device is unable to join a network at start up, or that it leaves a network? In both cases the device will keep trying to join a network, so you should not have to reboot the device in order to make it join or rejoin networks. If you still want to reboot the best option would probably be to use the Zigbee stack signals.

    When a device starts up it will try to join the network with a call to the function start_network_rejoin(). This will start network steering, and will generate the stack signal ZB_BDB_SIGNAL_STEERING. The status of this signal indicates whether the device successfully joined/rejoined a network or not. If it did not join, the device will try again by once again calling start_network_rejoin() and starting network steering. On leaving a network, the signal ZB_ZDO_SIGNAL_LEAVE is generated, and the stack will handle this by also calling on start_network_rejoin() to try and rejoin a network, causing the device to start network steering again. If you want to implement some custom logic for these signals you can override this by handling the signal in the zboss_signal_handler() instead of the zigbee_default_signal_handler(). See Zigbee default signal handler for more information about how to do this. 

    Maybe in this case I should check in the zboss_signal_handler for reboot signal and if occurs handle the desired behavior. and if no pass zb_bufid_t to zigbee_default_signal_handler.

    The signal ZB_BDB_SIGNAL_DEVICE_REBOOT indicates that the device has rebooted, and that it has network data stored in NVRAM from a network it was connected to before reboot. It will then try to rejoin the same network using the data stored in NVRAM. It this is not a signal used to tell the device that it should reboot. You can also override this signal using zboss_signal_handler() as I mentioned above.

    Best regards,

    Marte

Reply
  • Hi,

    With Zigbee connection fail, do you mean that the device is unable to join a network at start up, or that it leaves a network? In both cases the device will keep trying to join a network, so you should not have to reboot the device in order to make it join or rejoin networks. If you still want to reboot the best option would probably be to use the Zigbee stack signals.

    When a device starts up it will try to join the network with a call to the function start_network_rejoin(). This will start network steering, and will generate the stack signal ZB_BDB_SIGNAL_STEERING. The status of this signal indicates whether the device successfully joined/rejoined a network or not. If it did not join, the device will try again by once again calling start_network_rejoin() and starting network steering. On leaving a network, the signal ZB_ZDO_SIGNAL_LEAVE is generated, and the stack will handle this by also calling on start_network_rejoin() to try and rejoin a network, causing the device to start network steering again. If you want to implement some custom logic for these signals you can override this by handling the signal in the zboss_signal_handler() instead of the zigbee_default_signal_handler(). See Zigbee default signal handler for more information about how to do this. 

    Maybe in this case I should check in the zboss_signal_handler for reboot signal and if occurs handle the desired behavior. and if no pass zb_bufid_t to zigbee_default_signal_handler.

    The signal ZB_BDB_SIGNAL_DEVICE_REBOOT indicates that the device has rebooted, and that it has network data stored in NVRAM from a network it was connected to before reboot. It will then try to rejoin the same network using the data stored in NVRAM. It this is not a signal used to tell the device that it should reboot. You can also override this signal using zboss_signal_handler() as I mentioned above.

    Best regards,

    Marte

Children
  • Thank you very much for your answer.
    Clearing up ambiguities I'm talking about the behavior just after the start of the application.
    REJOIN_INTERVAL_MAX_S allows only to reconnect several times, and then it hangs. I don't want such behaviour as in some cases it can brick our device.
    I would our application keep retrying (eventually after some sleep for energy consumption optimizations)

  • Hi,

    In zigbee_app_utils.c there is a global variable rejoin_attempt_cnt, which keeps track of the number of rejoin attempts. You can use this to track how many times it has tried, and if the number of rejoin attempts is too high, you reset the device in some way. In this case, you should also make sure the device has not joined a network with !ZB_JOINED(). However, for this you must make changes in the zigbee_app_utils.c file, as rejoin_attempt_cnt is only available there. Another possibility if you do not want to make changes in this file is create a static rejoin_attempt_cnt in main.c, and override the ZB_BDB_SIGNAL_STEERING signal in zboss_signal_handler() to count number of rejoin attempts there, before calling the default signal handler to handle the rest of ZB_BDB_SIGNAL_STEERING:

    void zboss_signal_handler(zb_bufid_t bufid)
    {
    	zb_zdo_app_signal_hdr_t    *sig_hndler = NULL;
    	zb_zdo_app_signal_type_t    sig = zb_get_app_signal(bufid, &sig_hndler);
    	
    	/* Update network status LED. */
    	zigbee_led_status_update(bufid, ZIGBEE_NETWORK_STATE_LED);
    	
    	switch(sig) {
    		case ZB_BDB_SIGNAL_STEERING:
    			LOG_INF("Rejoin attempt: %d", rejoin_attempt_cnt);
    			rejoin_attempt_cnt++;
    			/* Call default signal handler.*/
    			ZB_ERROR_CHECK(zigbee_default_signal_handler(bufid));
    			break;
    			
    	...

    As for how to reset the device to keep trying to rejoin you can use the function zb_reset().

    Best regards,

    Marte

Related