This discussion has been locked.
You can no longer post new replies to this discussion. If you have a question you can start a new discussion

Zigbee Multiple Endpoint declaration gives error

I want to expose 2 endpoints on the nrf52840 DK - one is the existing Onboard LED and the other is the GPIO pin (P0.02) which I have enabled in overlay.

I am extending the LightBulb example and repeating the steps of the declaration of the LED.  However, it gives the following compile time error, not sure what is wrong here.

/* Device endpoint, used to receive light controlling commands. */
#define HA_DIMMABLE_LIGHT_ENDPOINT      10

// * - Additional Endpoint for GPIO P0.02
#define HA_DIMMABLE_LIGHT_ENDPOINT_GPIO      11

/* Version of the application software (1 byte). */
#define BULB_INIT_BASIC_APP_VERSION     01

/* Version of the implementation of the Zigbee stack (1 byte). */
#define BULB_INIT_BASIC_STACK_VERSION   10

/* Version of the hardware of the device (1 byte). */
#define BULB_INIT_BASIC_HW_VERSION      11

/* Manufacturer name (32 bytes). */
#define BULB_INIT_BASIC_MANUF_NAME      "Nordic"

/* Model number assigned by manufacturer (32-bytes long string). */
#define BULB_INIT_BASIC_MODEL_ID        "Light_Bulb_v1.0"

/* First 8 bytes specify the date of manufacturer of the device
 * in ISO 8601 format (YYYYMMDD). The rest (8 bytes) are manufacturer specific.
 */
#define BULB_INIT_BASIC_DATE_CODE       "202112177777"

/* Type of power sources available for the device.
 * For possible values see section 3.2.2.2.8 of ZCL specification.
 */
#define BULB_INIT_BASIC_POWER_SOURCE    ZB_ZCL_BASIC_POWER_SOURCE_DC_SOURCE

/* Describes the physical location of the device (16 bytes).
 * May be modified during commisioning process.
 */
#define BULB_INIT_BASIC_LOCATION_DESC   "Desk"

/* Describes the type of physical environment.
 * For possible values see section 3.2.2.2.10 of ZCL specification.
 */
#define BULB_INIT_BASIC_PH_ENV          ZB_ZCL_BASIC_ENV_UNSPECIFIED

/* LED immitaing dimmable light bulb - define for informational
 * purposes only.
 */
#define BULB_LED                        DK_LED4

#define TOGGLE_SWITCH					DK_BTN3_MSK

/* Use onboard led4 to act as a light bulb.
 * The app.overlay file has this at node label "pwm_led3" in /pwmleds.
 */
#define PWM_DK_LED4_NODE                DT_NODELABEL(pwm_led3)
// * - Define the GPIO P 0.02 - picked from the overlay file
#define PWM_GPIO_LED_P0_02_NODE         DT_NODELABEL(pwm_led4)

/* Nordic PWM nodes don't have flags cells in their specifiers, so
 * this is just future-proofing.
 */
#define FLAGS_OR_ZERO(node) \
	COND_CODE_1(DT_PHA_HAS_CELL(node, pwms, flags), \
		    (DT_PWMS_FLAGS(node)), (0))

#if DT_NODE_HAS_STATUS(PWM_DK_LED4_NODE, okay)
/* Get the defines from overlay file. */
#define PWM_DK_LED4_CTLR                DT_PWMS_CTLR(PWM_DK_LED4_NODE)
#define PWM_DK_LED4_CHANNEL             DT_PWMS_CHANNEL(PWM_DK_LED4_NODE)
#define PWM_DK_LED4_FLAGS               FLAGS_OR_ZERO(PWM_DK_LED4_NODE)
#else
#error "Choose supported PWM driver"
#endif

// * - define for the GPIO P 0.02
#if DT_NODE_HAS_STATUS(PWM_GPIO_LED_P0_02_NODE, okay)
/* Get the defines from overlay file. */
#define PWM_GPIO_LED_P0_02_CTLR                DT_PWMS_CTLR(PWM_GPIO_LED_P0_02_NODE)
#define PWM_GPIO_LED_P0_02_CHANNEL             DT_PWMS_CHANNEL(PWM_GPIO_LED_P0_02_NODE)
#define PWM_GPIO_LED_P0_02_FLAGS               FLAGS_OR_ZERO(PWM_GPIO_LED_P0_02_NODE)
#else
#error "Choose supported PWM driver for GPIO P 0.02"
#endif

/* Led PWM period, calculated for 50 Hz signal - in microseconds. */
#define LED_PWM_PERIOD_US               (USEC_PER_SEC / 50U)

#ifndef ZB_ROUTER_ROLE
#error Define ZB_ROUTER_ROLE to compile router source code.
#endif

// * - Declare the On_off_set_value function
static void on_off_set_value(zb_bool_t on);

LOG_MODULE_REGISTER(app);

/* Main application customizable context.
 * Stores all settings and static values.
 */
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_t            on_off_attr;
	zb_zcl_level_control_attrs_t     level_control_attr;
} bulb_device_ctx_t;

/////////// DECLARATION FOR FIRST ENDPOINT - START /////////////////////////////////////
/* Zigbee device application context storage. */
static bulb_device_ctx_t dev_ctx;

/* Pointer to PWM device controlling leds with pwm signal. */
static const struct device *led_pwm_dev;

ZB_ZCL_DECLARE_IDENTIFY_ATTRIB_LIST(
	identify_attr_list,
	&dev_ctx.identify_attr.identify_time);

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

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

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

/* On/Off cluster attributes additions data */
ZB_ZCL_DECLARE_ON_OFF_ATTRIB_LIST(
	on_off_attr_list,
	&dev_ctx.on_off_attr.on_off);

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

ZB_HA_DECLARE_DIMMABLE_LIGHT_CLUSTER_LIST(
	dimmable_light_clusters,
	basic_attr_list,
	identify_attr_list,
	groups_attr_list,
	scenes_attr_list,
	on_off_attr_list,
	level_control_attr_list);

ZB_HA_DECLARE_DIMMABLE_LIGHT_EP(
	dimmable_light_ep,
	HA_DIMMABLE_LIGHT_ENDPOINT,
	dimmable_light_clusters);

/////////// DECLARATION FOR FIRST ENDPOINT - END /////////////////////////////////////

/////////// * - DECLARATION FOR SECOND ENDPOINT - START /////////////////////////////////////
/* Zigbee device application context storage. */
static bulb_device_ctx_t dev_ctx_gpio;

/* Pointer to PWM device controlling leds with pwm signal. */
static const struct device *led_pwm_dev_gpio;

ZB_ZCL_DECLARE_IDENTIFY_ATTRIB_LIST(
	identify_attr_list_gpio,
	&dev_ctx_gpio.identify_attr.identify_time);

ZB_ZCL_DECLARE_GROUPS_ATTRIB_LIST(
	groups_attr_list_gpio,
	&dev_ctx_gpio.groups_attr.name_support);

ZB_ZCL_DECLARE_SCENES_ATTRIB_LIST(
	scenes_attr_list_gpio,
	&dev_ctx_gpio.scenes_attr.scene_count,
	&dev_ctx_gpio.scenes_attr.current_scene,
	&dev_ctx_gpio.scenes_attr.current_group,
	&dev_ctx_gpio.scenes_attr.scene_valid,
	&dev_ctx_gpio.scenes_attr.name_support);

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

/* On/Off cluster attributes additions data */
ZB_ZCL_DECLARE_ON_OFF_ATTRIB_LIST(
	on_off_attr_list_gpio,
	&dev_ctx_gpio.on_off_attr.on_off);

ZB_ZCL_DECLARE_LEVEL_CONTROL_ATTRIB_LIST(
	level_control_attr_list_gpio,
	&dev_ctx_gpio.level_control_attr.current_level,
	&dev_ctx_gpio.level_control_attr.remaining_time);

ZB_HA_DECLARE_DIMMABLE_LIGHT_CLUSTER_LIST(
	dimmable_light_clusters_gpio,
	basic_attr_list_gpio,
	identify_attr_list_gpio,
	groups_attr_list_gpio,
	scenes_attr_list_gpio,
	on_off_attr_list_gpio,
	level_control_attr_list_gpio);

ZB_HA_DECLARE_DIMMABLE_LIGHT_EP(
	dimmable_light_ep_gpio,
	HA_DIMMABLE_LIGHT_ENDPOINT_GPIO,
	dimmable_light_clusters_gpio);

/////////// * - DECLARATION FOR SECOND ENDPOINT - END /////////////////////////////////////

// * - Combine the declatation of  multiple Endpoints - start 
ZBOSS_DECLARE_DEVICE_CTX_2_EP(dimmable_light_ctx, dimmable_light_ep, dimmable_light_ep_gpio);
// * - Combine the declatation of  multiple Endpoints - End	

// * - commented out the below as the multiple endpoints declaration takes care of the context of both the Endpoints
// ZB_HA_DECLARE_DIMMABLE_LIGHT_CTX(
// 	dimmable_light_ctx,
// 	dimmable_light_ep);

The build error is

In file included from E:\nRF\v1.7.1\nrfxlib\zboss\include\zboss_api.h:52,
                 from e:\nRF\projects\test_light_bulb\src\main.c:29:
E:\nRF\v1.7.1\nrfxlib\zboss\include\zboss_api_af.h:238:32: error: redefinition of 'struct zb_af_simple_desc_6_0_s'
  238 |   typedef ZB_PACKED_PRE struct zb_af_simple_desc_ ## in_clusters_count ## _ ## out_clusters_count ## _s \
      |                                ^~~~~~~~~~~~~~~~~~
E:\nRF\v1.7.1\nrfxlib\zboss\include\ha\zb_ha_dimmable_light.h:160:3: note: in expansion of macro 'ZB_DECLARE_SIMPLE_DESC'
  160 |   ZB_DECLARE_SIMPLE_DESC(in_clust_num, out_clust_num);                                         \
      |   ^~~~~~~~~~~~~~~~~~~~~~
E:\nRF\v1.7.1\nrfxlib\zboss\include\ha\zb_ha_dimmable_light.h:190:3: note: in expansion of macro 'ZB_ZCL_DECLARE_HA_DIMMABLE_LIGHT_SIMPLE_DESC'
  190 |   ZB_ZCL_DECLARE_HA_DIMMABLE_LIGHT_SIMPLE_DESC(ep_name, ep_id,                     \
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
e:\nRF\projects\test_light_bulb\src\main.c:282:1: note: in expansion of macro 'ZB_HA_DECLARE_DIMMABLE_LIGHT_EP'
  282 | ZB_HA_DECLARE_DIMMABLE_LIGHT_EP(
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
E:\nRF\v1.7.1\nrfxlib\zboss\include\zboss_api_af.h:238:32: note: originally defined here
  238 |   typedef ZB_PACKED_PRE struct zb_af_simple_desc_ ## in_clusters_count ## _ ## out_clusters_count ## _s \
      |                                ^~~~~~~~~~~~~~~~~~
E:\nRF\v1.7.1\nrfxlib\zboss\include\ha\zb_ha_dimmable_light.h:160:3: note: in expansion of macro 'ZB_DECLARE_SIMPLE_DESC'
  160 |   ZB_DECLARE_SIMPLE_DESC(in_clust_num, out_clust_num);                                         \
      |   ^~~~~~~~~~~~~~~~~~~~~~
E:\nRF\v1.7.1\nrfxlib\zboss\include\ha\zb_ha_dimmable_light.h:190:3: note: in expansion of macro 'ZB_ZCL_DECLARE_HA_DIMMABLE_LIGHT_SIMPLE_DESC'
  190 |   ZB_ZCL_DECLARE_HA_DIMMABLE_LIGHT_SIMPLE_DESC(ep_name, ep_id,                     \
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
e:\nRF\projects\test_light_bulb\src\main.c:219:1: note: in expansion of macro 'ZB_HA_DECLARE_DIMMABLE_LIGHT_EP'
  219 | ZB_HA_DECLARE_DIMMABLE_LIGHT_EP(
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
E:\nRF\v1.7.1\nrfxlib\zboss\include\zboss_api_af.h:250:3: error: conflicting types for 'zb_af_simple_desc_6_0_t'
  250 |   zb_af_simple_desc_ ## in_clusters_count ## _ ## out_clusters_count ## _t
      |   ^~~~~~~~~~~~~~~~~~
E:\nRF\v1.7.1\nrfxlib\zboss\include\ha\zb_ha_dimmable_light.h:160:3: note: in expansion of macro 'ZB_DECLARE_SIMPLE_DESC'
  160 |   ZB_DECLARE_SIMPLE_DESC(in_clust_num, out_clust_num);                                         \
      |   ^~~~~~~~~~~~~~~~~~~~~~
E:\nRF\v1.7.1\nrfxlib\zboss\include\ha\zb_ha_dimmable_light.h:190:3: note: in expansion of macro 'ZB_ZCL_DECLARE_HA_DIMMABLE_LIGHT_SIMPLE_DESC'
  190 |   ZB_ZCL_DECLARE_HA_DIMMABLE_LIGHT_SIMPLE_DESC(ep_name, ep_id,                     \
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
e:\nRF\projects\test_light_bulb\src\main.c:282:1: note: in expansion of macro 'ZB_HA_DECLARE_DIMMABLE_LIGHT_EP'
  282 | ZB_HA_DECLARE_DIMMABLE_LIGHT_EP(
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
E:\nRF\v1.7.1\nrfxlib\zboss\include\zboss_api_af.h:250:3: note: previous declaration of 'zb_af_simple_desc_6_0_t' was here
  250 |   zb_af_simple_desc_ ## in_clusters_count ## _ ## out_clusters_count ## _t
      |   ^~~~~~~~~~~~~~~~~~
E:\nRF\v1.7.1\nrfxlib\zboss\include\ha\zb_ha_dimmable_light.h:160:3: note: in expansion of macro 'ZB_DECLARE_SIMPLE_DESC'
  160 |   ZB_DECLARE_SIMPLE_DESC(in_clust_num, out_clust_num);                                         \
      |   ^~~~~~~~~~~~~~~~~~~~~~
E:\nRF\v1.7.1\nrfxlib\zboss\include\ha\zb_ha_dimmable_light.h:190:3: note: in expansion of macro 'ZB_ZCL_DECLARE_HA_DIMMABLE_LIGHT_SIMPLE_DESC'
  190 |   ZB_ZCL_DECLARE_HA_DIMMABLE_LIGHT_SIMPLE_DESC(ep_name, ep_id,                     \
      |   ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
e:\nRF\projects\test_light_bulb\src\main.c:219:1: note: in expansion of macro 'ZB_HA_DECLARE_DIMMABLE_LIGHT_EP'
  219 | ZB_HA_DECLARE_DIMMABLE_LIGHT_EP(
      | ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
[7/152] Building C object modules/nrfxlib/nrf_802154/nrf_802154/driver/CMakeFiles/nrf-802154-driver.dir/src/mac_features/nrf_802154_ie_writer.c.obj
[8/152] Building C object modules/nrfxlib/nrf_802154/nrf_802154/driver/CMakeFiles/nrf-802154-driver.dir/src/mac_features/nrf_802154_precise_ack_timeout.c.obj
[9/152] Building C object modules/nrfxlib/nrf_802154/nrf_802154/driver/CMakeFiles/nrf-802154-driver.dir/src/mac_features/nrf_802154_security_pib_ram.c.obj
[10/152] Building C object modules/nrfxlib/nrf_802154/nrf_802154/driver/CMakeFiles/nrf-802154-driver.dir/src/mac_features/nrf_802154_ifs.c.obj
[11/152] Linking C static library zephyr\libzephyr.a
ninja: build stopped: subcommand failed.

I wonder why the ZB_HA_DECLARE_DIMMABLE_LIGHT_EP  would give the error as all the declaration for individual end points are unique?

  • Okay I found the solution by implementing by expanding the macros, but it begs the question, why is the macro creating duplicate struct?

    The problem was the Macro ZB_HA_DECLARE_DIMMABLE_LIGHT_EP was creating a duplicate struct zb_af_simple_desc_6_0_s and its instance zb_af_simple_desc_6_0_t.  I just expanded this macro and change the struct naming. Maybe because it was used for creating the declaration for first Endpoint?  Anyway, if Nordic can fix this macro, it will save some debugging and effort in future

    // ZB_HA_DECLARE_DIMMABLE_LIGHT_EP(
    // 	dimmable_light_ep_gpio,
    // 	HA_DIMMABLE_LIGHT_ENDPOINT_GPIO,
    // 	dimmable_light_clusters_gpio);
    
    // Expansion of ZB_HA_DECLARE_DIMMABLE_LIGHT_EP - START
    typedef ZB_PACKED_PRE struct zb_af_simple_desc_6_0_struc 
    { 
    	zb_uint8_t endpoint; 
    	zb_uint16_t app_profile_id; 
    	zb_uint16_t app_device_id; 
    	zb_bitfield_t app_device_version:4; 
    	zb_bitfield_t reserved:4; 
    	zb_uint8_t app_input_cluster_count; 
    	zb_uint8_t app_output_cluster_count; 
    	zb_uint16_t app_cluster_list[(6) + (0)]; 
    } ZB_PACKED_STRUCT zb_af_simple_desc_6_0_t_instance;
    
    ZB_AF_SIMPLE_DESC_TYPE(6, 0) simple_desc_dimmable_light_ep_gpio = 
    	{ 
    	  11, ZB_AF_HA_PROFILE_ID, ZB_HA_DIMMABLE_LIGHT_DEVICE_ID, ZB_HA_DEVICE_VER_DIMMABLE_LIGHT, 0, 6, 0, 
    	  { 
    	    ZB_ZCL_CLUSTER_ID_BASIC, ZB_ZCL_CLUSTER_ID_IDENTIFY, ZB_ZCL_CLUSTER_ID_SCENES, ZB_ZCL_CLUSTER_ID_GROUPS, ZB_ZCL_CLUSTER_ID_ON_OFF, ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL, 
    	  }
    	};
    ZBOSS_DEVICE_DECLARE_REPORTING_CTX(reporting_infodevice_ctx_name, ZB_HA_DIMMABLE_LIGHT_REPORT_ATTR_COUNT);
    ZBOSS_DEVICE_DECLARE_LEVEL_CONTROL_CTX(cvc_alarm_infodevice_ctx_name, ZB_HA_DIMMABLE_LIGHT_CVC_ATTR_COUNT);
    ZB_AF_DECLARE_ENDPOINT_DESC(dimmable_light_ep_gpio, HA_DIMMABLE_LIGHT_ENDPOINT_GPIO, ZB_AF_HA_PROFILE_ID, 0, NULL, ZB_ZCL_ARRAY_SIZE(dimmable_light_clusters_gpio, zb_zcl_cluster_desc_t), dimmable_light_clusters_gpio, (zb_af_simple_desc_1_1_t*)&simple_desc_dimmable_light_ep_gpio, ZB_HA_DIMMABLE_LIGHT_REPORT_ATTR_COUNT, reporting_infodevice_ctx_name, ZB_HA_DIMMABLE_LIGHT_CVC_ATTR_COUNT, cvc_alarm_infodevice_ctx_name);
    

  • @Nordic Team,

        Please confirm that the above changes is the correct one and whether the macro is a problem?  If yes, can we expect bug to be fixed in the macro?

  • @Nordic Team,

        Please update on the above, whether the multiple endpoint definition code is correct or is there a better way to define the multiple endpoints

  • Hi, sorry for the late reply. Here is the feedback from the Zigbee team here in Nordic:

    ZBOSS ZCL APIs are not fully prepared to work with multiple endpoints (especially if you declare the same set of clusters on more than one endpoint).
    In order to do that, you have to define a new set of defines, that will handle the variable name collisions.
    We have done that in nRF5 SDK in the examples/multiprotocol/experimental/ble_zigbee_dynamic_color_light_bulb_thingy/zb_ha_dimmable_color_light.h. This header should be full of nice ideas on how to adapt the original ZCL declaration into your use case.
Related