Coordinator endpoint

Hello, I developed for my customer, a ZigBee coordinator in last 2019, using nRF5 SDK for Thread and Zigbee v3.2.0.
I has installed many sistems on field, equipped witn several battery powered sensors (door, motion, occupancy ...) and mains powered actuators (bulbs and smart plug).
I have only one endpoint # 64 configured on my coordinator, and now I need to add a second endpoint to receive the info from some end-node that sends to fixed endpoint #255
How can I add it?
Thanks for help

Abele

Parents
  • abe said:
    and on _agent_ep_handler_255 I can process all data received on endpoint 255, that's right?

    Yes, if my understanding is correct then, if the correct clusters are configured, you should receive it on that endpoint handler.

    abe said:
    ZB_AF_SET_ENDPOINT_HANDLER (ZIGBEE_ADRI_ENDPOINT_255, _agent_ep_handler_255);

    Are you using 255 as the actual endpoint number here? Maybe that is the issue. You have to use between 1 and 240.

    Regards,

    Elfving

  • I apologize for the long delay ... I was busy with other works ..
    To sumarize ... I have a Sonoff Zigbee 3.0 end node that sends IAS Alarm info to coordinator using endpoint #255 It even sends all other infos (battery level and voltage, ...) to coordinator endpoint #64 (as configured by my code)
    Here below the declaration to configure the two endpoints:

    I also tried to add this to declare macro

    But I have error!

    How can I add this endpoint to my coordinator?
    I need to make it able to receive from Sonoff end node!

    Many thanks for help!

    Abele

  • I see. 

    abe said:
    Coould you help me for this solution?

    Yes, I will of course try. It's just a few hurdles in the way. 

    So your problem might be related to KRKNWK-5826. It is solved in newer versions of the SDK, but here is the workaround for KRKNWK-5826 for older versions:

    Try to call init_multi_ep_fixers() from the attached files, in your initialization steps, just after the CTX and ZCL device callbacks are registered.

    Another thing that was mentioned is this: 

    "In case in which application uses write attribute hooks or endpoints handlers, small modification in workaround is required. If this is true for customer's application I will explain what should be changed."

    Could you try implementing this workaround and see if it changed anything?

    EDIT: for some reason file uploading doesn't work right now, so I'll simply add the code instead. Here is multi_ep_fixer.c and multi_ep_fixer.c

    #include "multi_ep_fixer.h"
    
    /* Store previous write attr hook for the Identify cluster. */
    zb_zcl_cluster_write_attr_hook_t m_p_identify_write_hook;
    
    static zb_void_t sort_ep_desc_list(zb_uint8_t dst_ep)
    {
        zb_uint8_t          dst_ep_desc_index   = 0;
        zb_af_device_ctx_t  *p_dev_ctx          = zb_zcl_get_ctx()->device_ctx;
    
        /* Find index of dest_ep desc in ep_desc list. */
        while ((p_dev_ctx->ep_desc_list)[dst_ep_desc_index]->ep_id != dst_ep)
        {
            dst_ep_desc_index++;
        }
    
        /* Check if desc of dest_ep is stored as last element of the ep desc list. */
        if (dst_ep_desc_index < (p_dev_ctx->ep_count - 1))
        {
            /* Store last ep_desc as temp ep_desc  */
            zb_af_endpoint_desc_t *p_temp_ep_desc = (p_dev_ctx->ep_desc_list)[(p_dev_ctx->ep_count - 1)];
            /* Put desired ep_desc as last */
            (p_dev_ctx->ep_desc_list)[(p_dev_ctx->ep_count - 1)] = (p_dev_ctx->ep_desc_list)[dst_ep_desc_index];
            /* Restore temp ep_desc in new place */
            (p_dev_ctx->ep_desc_list)[dst_ep_desc_index] = p_temp_ep_desc;
        }
    }
    
    static zb_uint8_t multi_ep_handler(zb_bufid_t bufid)
    {
        zb_zcl_parsed_hdr_t *cmd_info = ZB_BUF_GET_PARAM(bufid, zb_zcl_parsed_hdr_t);
        /* Nbr of endpoint to which frame is to be delivered. */
        zb_uint8_t          dst_ep    = cmd_info->addr_data.common_data.dst_endpoint;
    
        if ((cmd_info->cmd_id == ZB_ZCL_CMD_CONFIG_REPORT)
            || (cmd_info->cmd_id == ZB_ZCL_CMD_REPORT_ATTRIB)
            || (cmd_info->cmd_id == ZB_ZCL_CMD_READ_REPORT_CFG))
        {
            sort_ep_desc_list(dst_ep);
        }
        return ZB_FALSE;
    }
    
    static void multi_ep_identify_cluster_write_attr_hook(zb_uint8_t endpoint, zb_uint16_t attr_id, zb_uint8_t *new_value)
    {
        sort_ep_desc_list(endpoint);
        m_p_identify_write_hook(endpoint, attr_id, new_value);
    }
    
    static void multi_ep_generic_cluster_write_attr_hook(zb_uint8_t endpoint, zb_uint16_t attr_id, zb_uint8_t *new_value)
    {
        ZVUNUSED(attr_id);
        ZVUNUSED(new_value);
    
        sort_ep_desc_list(endpoint);
    }
    
    /* Function which initializes fixer methods and hooks. */
    void init_multi_ep_fixers(void)
    {
        zb_zcl_globals_t * p_zcl_ctx = zb_zcl_get_ctx();
        zb_uint8_t endpoint = 0;
        zb_uint8_t index = 0;
    
        ZB_ASSERT(p_zcl_ctx);
    
        /* Find Identify attr hook, store previous value if exist and assing new identify cluster wrtie attr hook. */
        while (index < p_zcl_ctx->zcl_handlers_cnt)
        {
            if ((p_zcl_ctx->zcl_handlers[index].cluster_id == ZB_ZCL_CLUSTER_ID_IDENTIFY)
                && (p_zcl_ctx->zcl_handlers[index].cluster_write_attr_hook != NULL))
            {
                m_p_identify_write_hook = p_zcl_ctx->zcl_handlers[index].cluster_write_attr_hook;
                p_zcl_ctx->zcl_handlers[index].cluster_write_attr_hook = multi_ep_identify_cluster_write_attr_hook;
            }
            /* For clusters with ID >= 0x03, if there is no attr hook assigned, assign generic one. If already exists, assert. */
            else if (p_zcl_ctx->zcl_handlers[index].cluster_id >= ZB_ZCL_CLUSTER_ID_IDENTIFY)
            {
                ZB_ASSERT(p_zcl_ctx->zcl_handlers[index].cluster_write_attr_hook == NULL);
    
                p_zcl_ctx->zcl_handlers[index].cluster_write_attr_hook = multi_ep_generic_cluster_write_attr_hook;
            }
            index++;
        }
    
        /* For each endpoint register device callback. Make sure that there is no endpoint handler set already. */
        for (index = 0; index < p_zcl_ctx->device_ctx->ep_count; index++)
        {
            endpoint = p_zcl_ctx->device_ctx->ep_desc_list[index]->ep_id;
    
            ZB_ASSERT(zb_af_get_endpoint_desc((endpoint))->device_handler == NULL);
            ZB_AF_SET_ENDPOINT_HANDLER(endpoint, multi_ep_handler);
        }
    }

    #ifndef MULTI_EP_FIXER_H__
    #define MULTI_EP_FIXER_H__
    
    #include "zboss_api.h"
    
    /**@brief Function which initializes fixer methods and hooks.
     *
     * Call just this function after the Device context is registered
     * and fixer is initialised.
     * It overrides write attribute cluster hooks and endpoint handlers.
     * If application uses mentioned hooks or endpoint handlers,
     * generic method should be changed for given cluster/endpoint.
     */
    void init_multi_ep_fixers(void)
    
    #endif /* MULTI_EP_FIXER_H__ */

    Regards,

    Elfving

  • Many thanks Elfving!
    I dont well understand where I must add the init function you suggest ...

    Here?

    Because as I already said I have the compiler error here ... 

    and also with this second solution

    Then, I think that before it's needed also solve the compiler issues ...

    Abele

  • Sorry about the delay, I was sick for a few days.

    Elfving said:

    Try to call init_multi_ep_fixers() from the attached files, in your initialization steps, just after the CTX and ZCL device callbacks are registered.

    And sorry about this part, I guess that specific part might've only applied to a previous customers case. I'll look into this

    Though could you try to see if this helps if you call it wherever?

    abe said:
    Because as I already said I have the compiler error here ... 

    Ah I see. Did you not get this error last time you tested multiple end points? Does removing init_multi_ep_fixers() in anyway make the errors disappear?

    Regards,

    Elfving

  • Sorry about the delay, I was sick for a few days.

    Elfving said:

    Try to call init_multi_ep_fixers() from the attached files, in your initialization steps, just after the CTX and ZCL device callbacks are registered.

    And sorry about this part, I guess that specific part might've only applied to a previous customers case. I'll look into this

    Though could you try to see if this helps if you call it wherever?

    abe said:
    Because as I already said I have the compiler error here ... 

    Ah I see. Did you not get this error last time you tested multiple end points? Does removing init_multi_ep_fixers() in anyway make the errors disappear?

    Regards,

    Elfving

Reply
  • Sorry about the delay, I was sick for a few days.

    Elfving said:

    Try to call init_multi_ep_fixers() from the attached files, in your initialization steps, just after the CTX and ZCL device callbacks are registered.

    And sorry about this part, I guess that specific part might've only applied to a previous customers case. I'll look into this

    Though could you try to see if this helps if you call it wherever?

    abe said:
    Because as I already said I have the compiler error here ... 

    Ah I see. Did you not get this error last time you tested multiple end points? Does removing init_multi_ep_fixers() in anyway make the errors disappear?

    Regards,

    Elfving

Children
  • Elfving,

    the compiler errors is on ENDPOINT MACRO definition ... and it was present also without the call of new function (you can see on my previsous posts)
    The call of init_multi_ep_fixers() is ininfluent for compiler errors ... the errors are already present

  • So they were there from the start? Or do you know at what point you got them?

    I am just wondering how you did the test earlier with the second endpoint earlier without these issues.

    abe said:
    the compiler errors is on ENDPOINT MACRO definition ... and it was present also without the call of new function (you can see on my previsous posts)

    I assume the issue is here that you need to declare it differently when using multiple end points (see Declaring Zigbee device context with multiple endpoints), but I do not think you need to declare EP 255.

    Regards,

    Elfving

  • I am just wondering how you did the test earlier with the second endpoint earlier without these issues.

    I never tried before with TWO endpoint.
    In any case, at starting of this thread, you have said 

    If the end-node sends to the endpoint #255, it broadcasts to all end-points on the device. So you do not necessarily need to add another end-point for it to be picked up.

    Perhaps this means that for endpoint 255 it is not needed the macros declaration?
    Then, the only I have to do is to try the calling of function you suggested and on image here below the code I has to add to my application to have a callback for data received from endpoint #255?

    Let me know about ...
    Many many thanks for your patience and for your help

    Abele

  • abe said:
    Perhaps this means that for endpoint 255 it is not needed the macros declaration?

    Exactly, I do not think that is required. When something is sent to endpoint 255, it should be recieved on endpoint 64, as well as all other end points on the device. 

    abe said:

    Then, the only I have to do is to try the calling of function you suggested and on image here below the code I has to add to my application to have a callback for data received from endpoint #255?

    I am not sure exactly what you mean here, but I do not think you need to add a handler for EP 255 either. It should be recieved at all EPs on the device. 

    I just got a coworker to try this in v3.2 as well (by simply adding an enpoint handler using ZB_AF_SET_ENDPOINT_HANDLER(HA_DIMMABLE_LIGHT_ENDPOINT, light_bulb_ep_handler);). That endpoint recieved a messages addressed to both EP 10 and EP 255.

    Interestingly, that test shows that in this situation init_multi_ep_fixers() wasn't necessary, might be that is the case for you as well. Which might mean that we are back where we started, since this is the situation you had issues with to begin with, right?

    Either way, try this. And then try adding init_multi_ep_fixers() somewhere. It might be that the placement of it makes a difference, but I guess it is worth a try to check if it works without worrying too much about where it is placed.

    abe said:

    Many many thanks for your patience and for your help

    No problem, and thanks for your patience as well. It isn't as easy to support older SDKs, so it might take a bit longer than usual.

    Regards,

    Elfving

  • I just got a coworker to try this in v3.2 as well (by simply adding an enpoint handler using ZB_AF_SET_ENDPOINT_HANDLER(HA_DIMMABLE_LIGHT_ENDPOINT, light_bulb_ep_handler);). That endpoint recieved a messages addressed to both EP 10 and EP 255.

    This seems a configuration for end-node, but I'm using the Coordinator.
    On my coordinator the callback for endpoint #64 is never invoked if the end-node sends to endpoint #255


    In any case, now I try the init_multi_ep_fixers(); as you sent me, but I have some build errors:

    I am aware that this situation could be hard to solve, but please have patience to me, my customer is worried and is hoping that we could solve the issue.

    Any further suggests?

    Thanks

    Abele

Related