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 Reply Children
  • Hi Elfving
    I used SDK 3.2 because I have developed this product for my customer in 2018. Then we are on production since 2019 ad we have several thousand of pieces on the field.
    Now we need to add the sensor here above quoted, and we need to solve the issue and add at least a second endpoint to our Coordinator
    We know about the new 4.2 solution, but unfortunatly there are no chanche tu update directly from 3.2 (we used IAR EWARM) to 4.2.
    It needs probably to remake full project, and this is too much expensive and is not accettable.
    In adition, there is the field that ask for this update.
    Coould you help me for this solution?
    Thanks
    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

Related