Zigbee End Device wrong connection to Coordinator

Hello,

I'm developing Zigbee End Device based on nRF52840 and I have some problems with network joining.

If my device is close enough to coordinator(1-1.5m) than it joins network just fine, but if I move coordinator for about 11-13m away and try to join there is a chance that joining goes wrong and connection is incomplete. In last test this error occurred after 30 reconnections, so it's not very often. But I'm in pre production stage and need to prepare device for mass production.

In SEGGER IDE I looked for logs from Zigbee stack to see if it helps to understand what caused this error. And I found that if this error occurred in logs I see "<info> app: Joined network successfully (Extended PAN ID: 0000000000000000, PAN ID: 0x1A62)".

So I'm curious if my connection quality is bad and ED didn't received Extended PAN ID, do I need to just leave network and try to connect again or I can restart network rejoin procedure partially? How can I know that joining network was "fully" successful?

  • Hi,

    do I need to just leave network and try to connect again or I can restart network rejoin procedure partially? How can I know that joining network was "fully" successful?

    If you always get ext PAN ID 0000000000000000 when it fails then you can use this to check whether the device has joined successfully or not. You can do this by overriding the way the stack signal ZB_BDB_SIGNAL_STEERING, possibly also ZB_BDB_SIGNAL_DEVICE_REBOOT, is handled using zboss_signal_handler, see Zigbee application helper functions. You also want the device to perform the necessary steps when ZB_BDB_SIGNAL_STEERING happens, so make sure to first call the default signal handler. You need to send a mgmt_leave_req to the local device for it to leave. Here is an example implementation:

    void leave_callback(zb_bufid_t bufid)
    {
      zb_zdo_mgmt_leave_res_t * p_resp = (zb_zdo_mgmt_leave_res_t*)zb_buf_begin(bufid);
      NRF_LOG_INFO("Leave callback status %hd", p_resp->status);
      zb_buf_free(bufid);
    }
    
    void leave_local_req()
    {
        zb_zdo_mgmt_leave_param_t * p_req;
        zb_ieee_addr_t ieee_addr;
        zb_get_long_address(ieee_addr);
        zb_uint16_t short_addr = zb_address_short_by_ieee(ieee_addr);
    
        zb_bufid_t bufid = zb_buf_get_out();
        if (!bufid) {
            NRF_LOG_INFO("Unable to allocate buffer");
            return;
        }
        p_req = ZB_BUF_GET_PARAM(bufid, zb_zdo_mgmt_leave_param_t);
    
        ZB_MEMSET(p_req->device_address, *ieee_addr, sizeof(zb_ieee_addr_t));
        p_req->rejoin = ZB_TRUE;
        p_req->dst_addr = short_addr;
        
        zdo_mgmt_leave_req(bufid, leave_callback);
    }
    
    void zboss_signal_handler(zb_bufid_t bufid)
    {
        zb_zdo_app_signal_hdr_t      * p_sg_p = NULL;
        zb_zdo_app_signal_type_t       sig    = zb_get_app_signal(bufid, &p_sg_p);
        zb_ret_t                       status = ZB_GET_APP_SIGNAL_STATUS(bufid);
    
        /* Update network status LED */
        zigbee_led_status_update(bufid, ZIGBEE_NETWORK_STATE_LED);
    
        switch(sig)
        {
            case ZB_BDB_SIGNAL_DEVICE_REBOOT:
                /* fall-through */
            case ZB_BDB_SIGNAL_STEERING:
                /* Call default signal handler. */
                ZB_ERROR_CHECK(zigbee_default_signal_handler(bufid));
                if (status == RET_OK)
                {
                    zb_ext_pan_id_t extended_pan_id;
                    zb_get_extended_pan_id(extended_pan_id);
                    if (extended_pan_id == 0000000000000000)
                    {
                        leave_local_req();
                    }
                }
                break;
            default:
                /* Call default signal handler. */
                ZB_ERROR_CHECK(zigbee_default_signal_handler(bufid));
                break;
        }
    
        if (bufid)
        {
            zb_buf_free(bufid);
        }
    }

    The best thing, however, is to figure out why the connection is incomplete. Is there a lot of 2,4 GHz noise where you are testing, e.g. from other Zigbee devices or WiFi? I know you say the issue happens seldom, but if you are able to collect a sniffer log of this happening and upload it here as a pcap file it would be of great help. For me to be able to look at the packets in the sniffer log you must either start the sniffer before the coordinator starts the network so the sniffer has the network key, or share the network key so I can use it to decrypt the packets.

    Best regards,

    Marte

  • Thanks,

    This will help a lot. But I'm still wondering how I can test the network "joined" if there are other errors.

    I'll try to collect the sniffer data in a few days and upload it here.

  • Hi,

    If the device is not able to join the network, it should notice so eventually by itself, especially an end device. The end device will discover that it is unable to communicate with it's parent and will try to rejoin the network under a different parent. However, this can take time depending on how often the end device communicates with it's parent and/or end device keep alive timeout.

    You can also add a handler for the ZB_NLME_STATUS_INDICATION signal, which is generated when there are errors or certain other conditions in the NWK layer, and add a check on the status. A list of status codes can be found in zboss_api_nwk.h, for example ZB_NWK_COMMAND_STATUS_PARENT_LINK_FAILURE which indicates that the device is unable to communicate with it's parent.

    If you want to actively test if the device successfully joined the network you can try to send any kind of command to the coordinator or another device and see if you get a response or not.

    Best regards,

    Marte

Related