Beware that this post is related to an SDK in maintenance mode
More Info: Consider nRF Connect SDK for new designs

Unable to receive any read commands for zigbee time cluster from end devices to the coordinator even after binding time cluster

Hello Nordic support,

I have a Zigbee coordinator application which has declared the time cluster as a server. I have a zigbee end device which has a time cluster as a client. When I send binding request from the coordinator for the time cluster, I get the bind status as success in the bind request callback function. However, I do not receive any read commands from the device for the time cluster.

This is how I have declared the time cluster and the endpoint, which has some other clusters as well:

typedef struct
{
zb_zcl_basic_attrs_ext_t basic_attr;
zb_zcl_identify_attrs_t identify_attr;
zb_zcl_scenes_attrs_t scenes_attr;
zb_zcl_groups_attrs_t groups_attr;
zb_zcl_on_off_attrs_ext_t on_off_attr;
zb_zcl_level_control_attrs_t level_control_attr;
//time cluster attributes
zb_zcl_time_attrs_t time_attr;
}server_device_ctx_t;

/************************************************************************
server endpoint variable
*************************************************************************/
#define ZB_HA_SERVER_EP_IN_CLUSTER_NUM 0
#define ZB_HA_SERVER_EP_OUT_CLUSTER_NUM 7
#define SERVER_REPORTING_ATTR_NR 4           //max nr of reporting attribute for server endpoint

#define ZB_HA_DECLARE_SERVER_EP_CLUSTER_LIST_COORD(             \
  cluster_list_name,                                            \
  basic_attr_list,                                              \
  identify_attr_list,                                           \
  scenes_attr_list,                                             \
  groups_attr_list,                                             \
  on_off_attr_list,                                             \
  level_control_attr_list,                                      \
  time_attr_list)                                               \
  zb_zcl_cluster_desc_t cluster_list_name[] =                   \
  {                                                              \
    ZB_ZCL_CLUSTER_DESC(                                         \
      ZB_ZCL_CLUSTER_ID_IDENTIFY,                                \
      ZB_ZCL_ARRAY_SIZE(identify_attr_list, zb_zcl_attr_t),      \
      (identify_attr_list),                                      \
      ZB_ZCL_CLUSTER_SERVER_ROLE,                                \
      ZB_ZCL_MANUF_CODE_INVALID                                  \
    ),                                                           \
    ZB_ZCL_CLUSTER_DESC(                                         \
      ZB_ZCL_CLUSTER_ID_BASIC,                                   \
      ZB_ZCL_ARRAY_SIZE(basic_attr_list, zb_zcl_attr_t),         \
      (basic_attr_list),                                         \
      ZB_ZCL_CLUSTER_SERVER_ROLE,                                \
      ZB_ZCL_MANUF_CODE_INVALID                                  \
    ),                                                           \
    ZB_ZCL_CLUSTER_DESC(                                         \
      ZB_ZCL_CLUSTER_ID_SCENES,                                  \
      ZB_ZCL_ARRAY_SIZE(scenes_attr_list, zb_zcl_attr_t),        \
      (scenes_attr_list),                                        \
      ZB_ZCL_CLUSTER_SERVER_ROLE,                                \
      ZB_ZCL_MANUF_CODE_INVALID                                  \
    ),                                                           \
    ZB_ZCL_CLUSTER_DESC(                                         \
      ZB_ZCL_CLUSTER_ID_GROUPS,                                  \
      ZB_ZCL_ARRAY_SIZE(groups_attr_list, zb_zcl_attr_t),        \
      (groups_attr_list),                                        \
      ZB_ZCL_CLUSTER_SERVER_ROLE,                                \
      ZB_ZCL_MANUF_CODE_INVALID                                  \
    ),                                                           \
    ZB_ZCL_CLUSTER_DESC(                                         \
      ZB_ZCL_CLUSTER_ID_ON_OFF,                                  \
      ZB_ZCL_ARRAY_SIZE(on_off_attr_list, zb_zcl_attr_t),        \
      (on_off_attr_list),                                        \
      ZB_ZCL_CLUSTER_SERVER_ROLE,                                \
      ZB_ZCL_MANUF_CODE_INVALID                                  \
    ),                                                           \
    ZB_ZCL_CLUSTER_DESC(                                         \
      ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL,                           \
      ZB_ZCL_ARRAY_SIZE(level_control_attr_list, zb_zcl_attr_t), \
      (level_control_attr_list),                                 \
      ZB_ZCL_CLUSTER_SERVER_ROLE,                                \
      ZB_ZCL_MANUF_CODE_INVALID                                  \
    ),                                                           \
    ZB_ZCL_CLUSTER_DESC(                                         \
      ZB_ZCL_CLUSTER_ID_TIME,                                    \
      ZB_ZCL_ARRAY_SIZE(time_attr_list, zb_zcl_attr_t),          \
      (time_attr_list),                                          \
      ZB_ZCL_CLUSTER_SERVER_ROLE,                                \
      ZB_ZCL_MANUF_CODE_INVALID                                  \
    )                                                            \
   }

#define ZB_HA_DECLARE_SERVER_EP_SIMPLE_DESC(                     \
  ep_name, ep_id, in_clust_num, out_clust_num)                  \
      ZB_DECLARE_SIMPLE_DESC(in_clust_num, out_clust_num);      \
      ZB_AF_SIMPLE_DESC_TYPE(in_clust_num, out_clust_num)       \
            simple_desc_##ep_name =                             \
      {                                                         \
        ep_id,                                                  \
        ZB_AF_HA_PROFILE_ID,                                    \
        ZB_HA_IAS_ZONE_ID,                                      \
        ZB_HA_IAS_ZONE_VER,                                     \
        0,                                                      \
        in_clust_num,                                           \
        out_clust_num,                                          \
        {                                                       \
          ZB_ZCL_CLUSTER_ID_IDENTIFY,                           \
          ZB_ZCL_CLUSTER_ID_BASIC,                              \
          ZB_ZCL_CLUSTER_ID_SCENES,                             \
          ZB_ZCL_CLUSTER_ID_GROUPS,                             \
          ZB_ZCL_CLUSTER_ID_ON_OFF,                             \
          ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL,                      \
          ZB_ZCL_CLUSTER_ID_TIME                                \
        }                                                       \
      }

#define ZB_HA_DECLARE_SERVER_EP(ep_name, ep_id, cluster_list) \
      ZB_HA_DECLARE_SERVER_EP_SIMPLE_DESC(                       \
          ep_name,                                              \
          ep_id,                                                \
          ZB_HA_SERVER_EP_IN_CLUSTER_NUM,                        \
          ZB_HA_SERVER_EP_OUT_CLUSTER_NUM);                      \
  ZBOSS_DEVICE_DECLARE_REPORTING_CTX(reporting_info## device_ctx_name,  \
                                     SERVER_REPORTING_ATTR_NR); \
  ZB_AF_DECLARE_ENDPOINT_DESC(                                          \
    ep_name,                                                            \
            ep_id,                                              \
            ZB_AF_HA_PROFILE_ID,                                \
            0,                                                  \
            NULL,                                               \
            ZB_ZCL_ARRAY_SIZE(cluster_list, zb_zcl_cluster_desc_t),     \
            cluster_list,                                               \
            (zb_af_simple_desc_1_1_t*)&simple_desc_##ep_name,           \
            SERVER_REPORTING_ATTR_NR,                                   \
            reporting_info## device_ctx_name,                           \
            0,                                                          \
            NULL)

static server_device_ctx_t m_dev_ctx;

ZB_ZCL_DECLARE_IDENTIFY_ATTRIB_LIST(client_identify_attr_list, &m_dev_ctx.identify_attr.identify_time);

ZB_ZCL_DECLARE_GROUPS_ATTRIB_LIST(groups_attr_list, &m_dev_ctx.groups_attr.name_support);

ZB_ZCL_DECLARE_SCENES_ATTRIB_LIST(scenes_attr_list,
                                  &m_dev_ctx.scenes_attr.scene_count,
                                  &m_dev_ctx.scenes_attr.current_scene,
                                  &m_dev_ctx.scenes_attr.current_group,
                                  &m_dev_ctx.scenes_attr.scene_valid,
                                  &m_dev_ctx.scenes_attr.name_support);

ZB_ZCL_DECLARE_BASIC_ATTRIB_LIST_EXT(client_basic_attr_list,
                                     &m_dev_ctx.basic_attr.zcl_version,
                                     &m_dev_ctx.basic_attr.app_version,
                                     &m_dev_ctx.basic_attr.stack_version,
                                     &m_dev_ctx.basic_attr.hw_version,
                                     m_dev_ctx.basic_attr.mf_name,
                                     m_dev_ctx.basic_attr.model_id,
                                     m_dev_ctx.basic_attr.date_code,
                                     &m_dev_ctx.basic_attr.power_source,
                                     m_dev_ctx.basic_attr.location_id,
                                     &m_dev_ctx.basic_attr.ph_env,
                                     m_dev_ctx.basic_attr.sw_ver);

/* On/Off cluster attributes additions data */
ZB_ZCL_DECLARE_ON_OFF_ATTRIB_LIST_EXT(on_off_attr_list,
                                      &m_dev_ctx.on_off_attr.on_off,
                                      &m_dev_ctx.on_off_attr.global_scene_ctrl,
                                      &m_dev_ctx.on_off_attr.on_time,
                                      &m_dev_ctx.on_off_attr.off_wait_time);

ZB_ZCL_DECLARE_LEVEL_CONTROL_ATTRIB_LIST(level_control_attr_list,
                                         &m_dev_ctx.level_control_attr.current_level,
                                         &m_dev_ctx.level_control_attr.remaining_time);

ZB_ZCL_DECLARE_TIME_ATTR_LIST(time_attr_list,
                              m_dev_ctx.time_attr);

// Declare cluster list for Nordic server end point
ZB_HA_DECLARE_SERVER_EP_CLUSTER_LIST_COORD(server_ep_clusters,
                                          client_basic_attr_list,
                                          client_identify_attr_list,
                                          groups_attr_list,
                                          scenes_attr_list,
                                          on_off_attr_list,
                                          level_control_attr_list,
                                          time_attr_list);

ZB_HA_DECLARE_SERVER_EP(server_ep,
                       HA_SERVER_ENDPOINT,
                       server_ep_clusters);
                       
ZBOSS_DECLARE_DEVICE_CTX_2_EP(ZbDev_ctx, server_ep, second_ep); //Note second endpoint is a client endpoint

This is how I bind to the time cluster:

void APP_zigbeeBindTime(uint16_t type, uint16_t short_addr, zb_ieee_addr_t * long_addr, uint16_t ep)
{
  zb_zdo_bind_req_param_t  *req;
  zb_bufid_t buf;
  buf = zb_buf_get_out();
  DB_EXCEPTION(buf == ZB_BUF_INVALID);
  req = ZB_BUF_GET_PARAM(buf, zb_zdo_bind_req_param_t);

  ZB_MEMCPY(&req->src_address, long_addr, sizeof(zb_ieee_addr_t));
  req->src_endp = ep;
  req->cluster_id = ZB_ZCL_CLUSTER_ID_TIME;
  req->dst_addr_mode = ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
  ZB_MEMCPY(&req->dst_address.addr_long, &ieee_addr, sizeof(zb_ieee_addr_t));
  req->dst_endp = HA_SERVER_ENDPOINT;
  req->req_dst_addr = short_addr;
  zb_zdo_bind_req(buf, zb_bind_timecluster_callback);
}

void zb_bind_timecluster_callback(zb_uint8_t param)
{
  zb_zdo_bind_resp_t * p_resp = (zb_zdo_bind_resp_t *)zb_buf_begin(param);
  if (p_resp->status == ZB_ZDP_STATUS_SUCCESS)
  {
    PRINT(APP_ZB_DB_PRINT1, "bind_time SUCCESS\r\n");
    //APP_mainSetEventFromISR(eventDvlcoWindowBound);
  }
  else
  {
    PRINT(APP_ZB_DB_PRINT1, "bind_time error 0x%02x\r\n",p_resp->status);
  }
  zb_buf_free(param);
}

This is the function to initialise the server attributes, which is called in main(),

static void server_ep_attr_init(void)
{
  /* Basic cluster attributes data */
  m_dev_ctx.basic_attr.zcl_version   = ZB_ZCL_VERSION;
  m_dev_ctx.basic_attr.app_version   = BULB_INIT_BASIC_APP_VERSION;
  m_dev_ctx.basic_attr.stack_version = BULB_INIT_BASIC_STACK_VERSION;
  m_dev_ctx.basic_attr.hw_version    = BULB_INIT_BASIC_HW_VERSION;

  /* Use ZB_ZCL_SET_STRING_VAL to set strings, because the first byte should
   * contain string length without trailing zero.
   *
   * For example "test" string will be encoded as:
   *   [(0x4), 't', 'e', 's', 't']
   */
  ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.mf_name,
                        BULB_INIT_BASIC_MANUF_NAME,
                        ZB_ZCL_STRING_CONST_SIZE(BULB_INIT_BASIC_MANUF_NAME));

  ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.model_id,
                        BULB_INIT_BASIC_MODEL_ID,
                        ZB_ZCL_STRING_CONST_SIZE(BULB_INIT_BASIC_MODEL_ID));

  ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.date_code,
                        BULB_INIT_BASIC_DATE_CODE,
                        ZB_ZCL_STRING_CONST_SIZE(BULB_INIT_BASIC_DATE_CODE));

  m_dev_ctx.basic_attr.power_source = BULB_INIT_BASIC_POWER_SOURCE;

  ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.location_id,
                        BULB_INIT_BASIC_LOCATION_DESC,
                        ZB_ZCL_STRING_CONST_SIZE(BULB_INIT_BASIC_LOCATION_DESC));


  m_dev_ctx.basic_attr.ph_env = BULB_INIT_BASIC_PH_ENV;

  ZB_ZCL_SET_STRING_VAL(m_dev_ctx.basic_attr.sw_ver,
                        BULB_INIT_BASIC_SW_VERSION,
                        ZB_ZCL_STRING_CONST_SIZE(BULB_INIT_BASIC_SW_VERSION));

  /* Identify cluster attributes data */
  m_dev_ctx.identify_attr.identify_time = ZB_ZCL_IDENTIFY_IDENTIFY_TIME_DEFAULT_VALUE;

  /* On/Off cluster attributes data */
  m_dev_ctx.on_off_attr.on_off = (zb_bool_t)ZB_ZCL_ON_OFF_IS_ON;

  m_dev_ctx.level_control_attr.current_level  = ZB_ZCL_LEVEL_CONTROL_LEVEL_MAX_VALUE;
  m_dev_ctx.level_control_attr.remaining_time = ZB_ZCL_LEVEL_CONTROL_REMAINING_TIME_DEFAULT_VALUE;

  /* Time cluster attributes */
  uint16_t time_reg;
  ReadRegister(ADDR_TIME_LOW, SIZE_TIME_LOW, &time_reg, false, false, true);
  m_dev_ctx.time_attr.time = (uint32_t)time_reg;
  ReadRegister(ADDR_TIME_HIGH, SIZE_TIME_HIGH, &time_reg, false, false, true);
  m_dev_ctx.time_attr.time |= ((uint32_t)time_reg)<<16;
  
  m_dev_ctx.time_attr.time_status = 0x01;
  }

Also, in the main(), the callback for the server endpoint is declared:

ZB_AF_SET_ENDPOINT_HANDLER(HA_SERVER_ENDPOINT, serverEpClusterCallBack);

However, even though the time cluster bind callback status is a success, I never see the serverEpClusterCallback being triggered. Could you please let me know if I'm missing something for binding time cluster and how to resolve this?  

Regards,

Anusha

Parents Reply Children
No Data
Related