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

[nRF52840 with zigbee] How to append user data append to HA profile ?

Hi,

I am developing a system similar to door lock system.

In our system, user data should transmit from ZED(or ZR) to ZC.

So i modified the ZB_ZCL_ON_OFF_SEND_REQ macro to add user data.

With wireshark, packet size is ok (includes the user data bytes).

But i cannot extract appended user data at ZC side.(Light On/Off command can be parsed successfully).

I am using HA profile.

Give some clues.

Thanks.

#define my_ZB_ZCL_ON_OFF_SEND_REQ(                                                         \
    buffer, addr, dst_addr_mode, dst_ep, ep, prof_id, dis_default_resp, command_id, cb) \
{                                                                                       \
  zb_uint8_t* ptr = ZB_ZCL_START_PACKET_REQ(buffer)                                     \
  ZB_ZCL_CONSTRUCT_SPECIFIC_COMMAND_REQ_FRAME_CONTROL(ptr, dis_default_resp)            \
  ZB_ZCL_CONSTRUCT_COMMAND_HEADER_REQ(ptr, ZB_ZCL_GET_SEQ_NUM(), command_id);           \
  ZB_ZCL_PACKET_PUT_DATA8(ptr, 0xab);  \
  ZB_ZCL_PACKET_PUT_DATA8(ptr, 0xcd);  \
  ZB_ZCL_PACKET_PUT_DATA8(ptr, 0xef);  \
  ZB_ZCL_PACKET_PUT_DATA8(ptr, 0x01);  \
  ZB_ZCL_PACKET_PUT_DATA8(ptr, 0xaa);  \
  ZB_ZCL_FINISH_PACKET(buffer, ptr)                                                     \
  ZB_ZCL_SEND_COMMAND_SHORT(                                                            \
      buffer, addr, dst_addr_mode, dst_ep, ep, prof_id, ZB_ZCL_CLUSTER_ID_ON_OFF, cb);  \
}

Parents
  • Hi,

    Could you explain a bit more about why you are not able to extract the appended user data? How are you implementing this right now?

    Since the payload is not what is expected for an on/off cluster you need to register an endpoint handler to intercept every frame coming to the endpoint and parse the data yourself.

    You can take a look at how it's handled in the zigbee_cli_cmd_attr.c file in the CLI example, as we handle reading attributes the same way.

    Best regards,

    Marjeris

  • Hi,

    I added ep handler register sentence and related functions in main.c.

    but the handler is not called when packet is received.

    My code is coordinator side.

    Pls help me.

    Thanks.

    ===============================================================

    NRF_ZIGBEE_EP_HANDLER_REGISTER(attr, cli_agent_ep_handler_attr);

  • For registering an endpoint handler you should use

    ZB_AF_SET_ENDPOINT_HANDLER()

    In the CLI example the NRF_ZIGBEE_EP_HANDLER_REGISTER is just a macro for storing multiple endpoint handlers (NRF_SECTION_ITEM_REGISTER) and they are registered using ZB_AF_SET_ENDPOINT_HANDLER() in main.c.

    Try then to add a nrf log info message inside your handler function to test if the handler is being called or not.

    Best regards,

    Marjeris

  • Hi,

    Now registered handler is called when packet is received.

    But i cannot find how to locate "user supplied data".

    Where can i find clues about this ?

    With HA, ZB_ZCL_CLUSTER_ID_ON_OFF command with additional data i added,

    how can access the data.

    Thanks..

  • I got the answer.

    ZB_BUF_BEGIN returns start address of user supplied data.

  • Hi,
    as the next step, you may also look into the CLI ping command implementation. It looks like it does exactly the thing that you want to achieve - presents how to send a hand-crafted, raw ZCL packet via Zigbee.

    Over time it got quite complicated (you may want to look inside previous SDKs to check that), so it might not be that easy to understand what's going on inside "cli_agent_ep_handler_ping" (the endpoint handler), but the most important piece is right at the beginning of the function:

        zb_buf_t * p_zcl_cmd_buf = (zb_buf_t *)ZB_BUF_FROM_REF(param);
        zb_zcl_parsed_hdr_t * p_cmd_info = ZB_GET_BUF_PARAM(p_zcl_cmd_buf, zb_zcl_parsed_hdr_t);

    There are two pointers - one of them (p_zcl_cmd_buf) gives you the access to the payload of the received ZCL packet, the other one (p_cmd_info) gives you all additional data from ZCL header and other, lower layers headers you may need (RSSI, addresses, endpoints, cluster ID, profile ID, command ID, sequence number etc.).

    Note that whatever you do inside endpoint handler - you should behave according to the specification. If someone requests a default response - you should send one. Returning ZB_TRUE means that everything related to that packet got processed inside the application (i.e. the buffer got reused or freed), and no further processing will be performed. If you plan to return ZB_FALSE, please remember not to modify the packet, or recover the initial state of the buffer before returning (like endianness). The endpoint handler is a very powerful tool and must be used with care.

    If you plan to implement a custom cluster, the right place to start is to look at the zb_zcl_pressure_measurement.c. This time the profile and cluster ID will be checked automatically by the stack and your role will be to implement all three handlers passed to "zb_zcl_add_cluster_handlers(...)" call. The idea is pretty much the same - you get the payload at the beginning of the buffer and additional data in "buf_param". Using this approach will keep your code clean, much closer to the way other Zigbee devices expect it to be and reusable in further projects.

    Regards,

    Tomchy

Reply
  • Hi,
    as the next step, you may also look into the CLI ping command implementation. It looks like it does exactly the thing that you want to achieve - presents how to send a hand-crafted, raw ZCL packet via Zigbee.

    Over time it got quite complicated (you may want to look inside previous SDKs to check that), so it might not be that easy to understand what's going on inside "cli_agent_ep_handler_ping" (the endpoint handler), but the most important piece is right at the beginning of the function:

        zb_buf_t * p_zcl_cmd_buf = (zb_buf_t *)ZB_BUF_FROM_REF(param);
        zb_zcl_parsed_hdr_t * p_cmd_info = ZB_GET_BUF_PARAM(p_zcl_cmd_buf, zb_zcl_parsed_hdr_t);

    There are two pointers - one of them (p_zcl_cmd_buf) gives you the access to the payload of the received ZCL packet, the other one (p_cmd_info) gives you all additional data from ZCL header and other, lower layers headers you may need (RSSI, addresses, endpoints, cluster ID, profile ID, command ID, sequence number etc.).

    Note that whatever you do inside endpoint handler - you should behave according to the specification. If someone requests a default response - you should send one. Returning ZB_TRUE means that everything related to that packet got processed inside the application (i.e. the buffer got reused or freed), and no further processing will be performed. If you plan to return ZB_FALSE, please remember not to modify the packet, or recover the initial state of the buffer before returning (like endianness). The endpoint handler is a very powerful tool and must be used with care.

    If you plan to implement a custom cluster, the right place to start is to look at the zb_zcl_pressure_measurement.c. This time the profile and cluster ID will be checked automatically by the stack and your role will be to implement all three handlers passed to "zb_zcl_add_cluster_handlers(...)" call. The idea is pretty much the same - you get the payload at the beginning of the buffer and additional data in "buf_param". Using this approach will keep your code clean, much closer to the way other Zigbee devices expect it to be and reusable in further projects.

    Regards,

    Tomchy

Children
Related