This post is older than 2 years and might not be relevant anymore
More Info: Consider searching for newer posts

Reverse finding and binding role, initiator and target.

Hello,

Originally, the Zigbee light_control examples ships with a bulb that can call the zb_bdb_finding_binding_target() functionand a light switch that calls zb_bdb_finding_binding_initiator() functionThis allows the light switch to add the bulb to its binding table. Here are the corresponding WireShark packets, which shows the Simple Descriptor Request being sent using the Zigbee ZDP protocol. The request is sent from the switch to the bulb.

I am now trying to implement the reverse. Have the light switch call zb_bdb_finding_binding_target(), then call zb_bdb_finding_binding_initiator() on the bulb, in order to have the bulb add the switch to its binding table. 

However, this does not work. I am using the CLI example in coordinator mode to query the bulb using the zdo mgmt_bind 0xXXXX command to see if there are any entries in the bulbs binding table, but it consistently shows the binding table to be empty.

There are no errors thrown inside the bulb or the switch, and the entire system (joining network, turning bulbs on and off, etc.) works just fine. One possible clue is when using WireShark, I can can see the bulb is never able to send the Simple Descriptor Request that is sent during a normal interaction. Instead, a default response is sent indicating an unsupported cluster. In addition to this, it is not being sent via the Zigbee ZDP protocol, but is instead using Zigbee HA.

I was wondering if you could help me with this dilemma, and hopefully point me in the correct direction.

Thank you,
Angry Oatmeal

Parents
  • Hello Angry Oatmeal,

    I thought I should look into this. What SDK version are you using? I couldn't find that the bulb nor switch called any of these functions. Is this something you have added?

     

    There are no errors thrown inside the bulb or the switch, and the entire system (joining network, turning bulbs on and off, etc.) works just fine.

     Is ERASE_PERSISTENT_CONFIG set to ZB_TRUE or ZB_FALSE when this happens? Are you sure that this is not caused because of previous network settings in the devices? This information is stored in flash, and will not by default be erased when you reprogram the application. Only if you erase all the flash (nrfjprog -e) or set ERASE_PERSISTENT_CONFIG to ZB_TRUE.

    Also, is it possible to send the sniffer trace as a pcapng file?

Reply
  • Hello Angry Oatmeal,

    I thought I should look into this. What SDK version are you using? I couldn't find that the bulb nor switch called any of these functions. Is this something you have added?

     

    There are no errors thrown inside the bulb or the switch, and the entire system (joining network, turning bulbs on and off, etc.) works just fine.

     Is ERASE_PERSISTENT_CONFIG set to ZB_TRUE or ZB_FALSE when this happens? Are you sure that this is not caused because of previous network settings in the devices? This information is stored in flash, and will not by default be erased when you reprogram the application. Only if you erase all the flash (nrfjprog -e) or set ERASE_PERSISTENT_CONFIG to ZB_TRUE.

    Also, is it possible to send the sniffer trace as a pcapng file?

Children
  • Hello Edvin,

    Sorry, I should have been more clear. I am using the Thread and Zigbee SDK v3.2.

    The zb_bdb_finding_binding_target() does exist in the light bulb code in the SDK version I have. For me, it is located on line 350 (line 12 in the below snippet)

    static void buttons_handler(bsp_event_t evt)
    {
        zb_ret_t zb_err_code;
    
        switch(evt)
        {
            case IDENTIFY_MODE_BSP_EVT:
                /* Check if endpoint is in identifying mode, if not put desired endpoint in identifying mode. */
                if (m_dev_ctx.identify_attr.identify_time == ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE)
                {
                    NRF_LOG_INFO("Bulb put in identifying mode");
                    zb_err_code = zb_bdb_finding_binding_target(HA_DIMMABLE_LIGHT_ENDPOINT);
                    ZB_ERROR_CHECK(zb_err_code);
                }
                else
                {
                    NRF_LOG_INFO("Cancel F&B target procedure");
                    zb_bdb_finding_binding_target_cancel();
                }
                break;
    
            default:
                NRF_LOG_INFO("Unhandled BSP Event received: %d", evt);
                break;
        }
    }

    However, the zb_bdb_finding_binding_initiator() was added by myself in the light switch. Again, this setup works just fine. It is only when switching the functions around on both devices that abnormal behavior starts popping up.

    ERASE_PERSISTENT_CONFIG is set to ZB_TRUE on both the light switch and the light bulb, as per the default settings in the shipped examples.

    Find attached both pcapng files of the working and non-working wireshark frames. The start of both files is just the switch and bulb joining the newly formed network after the coordinator comes online. The final burst of frames in both files is the find_and_bind function call.

    Wireshark_Working.pcapng

    Wireshark_Not_Working.pcapng

  • Ah, ok. I see it in SDK3.2.0, but couldn't find them in 4.0.0. I guess they are changed.

    Ok, so when you switch them around, you can't operate the light bulb from the light switch. Did you check the callback function for zb_bdb_finding_binding_initator()?

    zb_ret_t zb_bdb_finding_binding_initiator(zb_uint8_t endpoint, zb_bdb_comm_binding_callback_t user_binding_cb);

    Can you try to provide a callback function to this call, and check the status in the callback (if the callback is called)?

    Also, what is the addr, ep, cluster. and does it help if you return true in this callback?

    BR,

    Edvin

  • Hello Edvin,

    I have a callback function ready for the initiator as below. Unfortunately, the bulb never enters this callback function. It simply acts as though nothing has occurred. 

    static zb_bool_t finding_binding_cb(zb_int16_t status, zb_ieee_addr_t addr, zb_uint8_t ep, zb_uint16_t cluster)
    {
        NRF_LOG_INFO("Entering finding_binding_cb");
        NRF_LOG_INFO("status: %d", status);
        NRF_LOG_INFO("addr: %X", addr);
        NRF_LOG_INFO("ep: %d", ep);
        NRF_LOG_INFO("cluster: %d", cluster);
        return ZB_TRUE;
    }

    A point though about my previous comment concerning the lack of errors in the bulb. While the bulb and switch continue to operate normally after calling zb_bdb_finding_binding_initiator() on the bulb, if zb_bdb_finding_binding_initiator() is called twice in a row, the bulb freezes. The bulb will no longer respond if zb_bdb_finding_binding_initiator() is called a 3rd time, and will no longer receive any ON/OFF commands from the light switch. Once this freeze occurs, checking on WireShark reveals the bulb is truly frozen, as It no longer responds to the coordinator's Link Status request, and does not respond to a zdo match_desc() command from the coordinator CLI. A reset is the only option at this point.

    This might be a good time to ask a higher-level question regarding this project. I am trying to implement a scenario where the coordinator can regularly check the topology of the network. By scanning the binding tables of all router devices, the coordinator will be able to form a table of what devices are connected to each other. The reason I am trying to have the binding table on the bulb/router as opposed to the switch/end device, is the because the light switch will be a low power energy harvesting device, hence powered down most of the time, until it is pressed. Other than what I am trying to do now, do you think there are better ways to implement this?

    Thank you,
    Angry Oatmeal

  • Hello Edvin,

    Just as an added note, I've tried to manually bind the switch the bulb using the Zigbee CLI in coordinator mode.

    Using the zdo bind on command followed by the zdo mgmt_bind command, I was able to bind the bulb to the switch and check the switch's binding table to find the bulb (as usual) but I was also able to bind the switch to the bulb, and read the binding table on the bulb to find the switch listed there, as expected.

    It seems then that there is nothing stopping the switch being bound to the bulb, and that the issue might be the the zb_bdb_finding_binding_initiator()/zb_bdb_finding_binding_target() functions. 

    The plot thickens,

    Angry Oatmeal.

  • Hello Mr/Ms Angry Slight smile

    Is it possible to send the projects that you have used so that I can try to replicate this? If you didn't change anything other than main.c, then you only need to send those (please name the two main.c files differently, because there is a bug in devzone that will only allow one file with a specific name per ticket). 

    If you have changed things outside the main.c file, please zip the project folder. If it is too big to upload, delete the build folders, and it should be just fine.

    Best regards,

    Edvin

Related