Developing with ZBOSS for Zigbee
ZBOSS Zigbee Cluster Library 8 developer guide

1. ZCL8 overview

1.1 List of main cluster changes in ZCL8 specification

Cluster name ZBOSS ZCL8 identifier Changes
Color Control Cluster ZB_ZCL_CLUSTER_ID_COLOR_CONTROL Fields added
Level control cluster ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL Fields added
Scenes cluster ZB_ZCL_CLUSTER_ID_SCENES Fields added
Demand-Response cluster ZB_ZCL_CLUSTER_ID_DRLC Fields added and status codes updated
Alarms cluster ZB_ZCL_CLUSTER_ID_ALARMS Status codes updated
Appliance events and alerts cluster ZB_ZCL_CLUSTER_ID_APPLIANCE_EVENTS_AND_ALERTS Status codes updated
Over The Air cluster ZB_ZCL_CLUSTER_ID_OTA_UPGRADE Optional parameters are not supposed
Door lock cluster ZB_ZCL_CLUSTER_ID_DOOR_LOCK Status codes updated
Groups cluster ZB_ZCL_CLUSTER_ID_GROUPS Status codes updated
IAS ACE cluster ZB_ZCL_CLUSTER_ID_IAS_ACE Status codes updated
IAS WD cluster ZB_ZCL_CLUSTER_ID_IAS_WD Status codes updated
IAS Zone cluster ZB_ZCL_CLUSTER_ID_IAS_ZONE Status codes updated
Identify cluster ZB_ZCL_CLUSTER_ID_IDENTIFY Status codes updated
Window covering cluster ZB_ZCL_CLUSTER_ID_WINDOW_COVERING Status codes updated
On/Off cluster ZB_ZCL_CLUSTER_ID_ON_OFF Status codes updated
Poll control cluster ZB_ZCL_CLUSTER_ID_POLL_CONTROL Status codes updated
Works with All Hubs cluster ZB_ZCL_CLUSTER_ID_WWAH Status codes updated
Thermostat cluster ZB_ZCL_CLUSTER_ID_THERMOSTAT Status codes updated
Time cluster ZB_ZCL_CLUSTER_ID_TIME Optional parameters were added

1.2 ZCL Commands statuses changes introduced in ZCL8 specification

pre-ZCL8 status codes Changes
UNSUP_CLUSTER_COMMAND(0x81) In ZCL8 renamed to UNSUP_COMMAND
UNSUP_GENERAL_COMMAND(0x82) In ZCL8 use UNSUP_CLUSTER_COMMAND
UNSUP_MANUF_CLUSTER_COMMAND(0x83) In ZCL8 use UNSUP_CLUSTER_COMMAND
UNSUP_MANUF_GENERAL_COMMAND(0x84) In ZCL8 use UNSUP_CLUSTER_COMMAND
DUPLICATE_EXISTS(0x8a) In ZCL8 use Success(0x00)
WRITE_ONLY(0x8f) In ZCL8 use NOT_AUTHORIZED(0x7e)
INCONSISTENT_STARTUP_STATE(0x90) In ZCL8 use FAILURE(0x01)
DEFINED_OUT_OF_BAND(0x91) In ZCL8 use FAILURE(0x01)
INCONSISTENT(0x92) In ZCL8 - RESERVED. Never used
ACTION_DENIED(0x93) In ZCL8 use FAILURE(0x01)
HARDWARE_FAILURE(0xc0) In ZCL8 use FAILURE(0x01)
SOFTWARE_FAILURE(0xc1) In ZCL8 use FAILURE(0x01)
CALIBRATION_ERROR(0xc2) In ZCL8 - RESERVED. Never used
LIMIT_REACHED(0xc4) In ZCL6 doesn't exist, in ZCL8 use SUCCESS(0x00)

2. ZBOSS ZCL8 design

2.1 Compatibility with previous ZCL specifications

ZBOSS has been upgraded to support the ZCL8 specification, maintaining backward compatibility with pre-ZCL8 versions according to the ZCL specification requirement. To make the migration process smoother for application developers, ZBOSS ZCL8 introduces a new feature: Backward compatibility modes. Using this functionality, the developer can make flexible decisions about upgrading their applications to ZCL8 or keeping previously implemented products that do not requires new changes.

2.2 Cluster revision

Cluster revision is a mandatory attribute for all Zigbee clusters. This attribute reflects the change history for a specific cluster. Using the attribute value, an application can distinguish between different cluster implementations and features introduced in the new revisions. Additionally, applications can control their behavior, changing the attribute value.

The cluster revision attribute is described in section 2.3.4.5.1.1 ClusterRevision Attribute [1]. The cluster revision attribute reading may be used to ensure that a remote device supports functionality corresponding to the given cluster revision. More details about ClusterRevision usage, examples of changes, and when they are expected to be implemented can be found in [3].

2.2.1 How to use cluster revision

It is important to keep in mind that, in the document, cluster revisions for local clusters and peer (remote device) clusters are considered.

The local cluster revision is assigned during the cluster declaration, when ZB_ZCL_DECLARE_<CLUSTER_NAME>_ATTRIB_LIST is being called. The default value for the cluster revision attribute value is the highest revision value supported by ZBOSS. Additionally, the revision can be set manually through ZB_ZCL_SET_ATTRIBUTE API. Note that the revision value passed through the API should not be greater than the highest supported revision. The application may want to decrease the local cluster revision in order to work with old or legacy devices. If the application implements its own cluster declaration, so it doesn't use the ZBOSS cluster declaration, the cluster revision should be initialized properly, otherwise the device will be accepted as a pre-ZCL8 implementation and won't get the advantages of ZBOSS ZCL8.

The peer cluster revision is the cluster revision for the specific remote device. Using peer revision, the application discovers which functionality is supported by the peer and then uses those features. The peer cluster revision can be obtained through the ZCL Read Attribute command. The following code sample initializes, composes, and sends the ZCL Read attribute general command:

ZB_ZCL_GENERAL_INIT_READ_ATTR_REQ(buf, cmd_ptr, ZB_ZCL_ENABLE_DEFAULT_RESPONSE);
ZB_ZCL_GENERAL_ADD_ID_READ_ATTR_REQ(cmd_ptr, attr_id);
ZB_ZCL_GENERAL_SEND_READ_ATTR_REQ(buf, cmd_ptr, dst_addr, dst_addr_mode, dst_ep, src_ep, profile_id, cluster_id, cb);

This is an example of revision requests provided with ZCL8 samples, but you can implement your own because there are no specific rules described in the specification.

2.3 Backward compatibility modes

2.3.1 Legacy mode

This is the default ZCL backward compatibility mode. The ZB_ZCL_LEGACY_MODE mode is intended for keeping pre-ZCL8 developed applications working with the updated ZBOSS ZCL8 library. No changes in the applications are required, and old, pre-ZCL8 ZBOSS API can still be used. ZCL requests will be sent according to the Cluster revision attributes set for the given cluster. The default cluster revision attribute is the highest supported revision.

In the ZB_ZCL_LEGACY_MODE mode an application can also use the ZBOSS ZCL8 API. The corresponding requests will be transformed in a format according to the cluster revision attribute: if the application revision will be set to the ZCL8 cluster revision and ZCL8 API is called, the request will be sent as is. Otherwise, if the application's revision attribute is set to a lower value, the command format will be downgraded automatically to match the revision format configured by the attribute. In most cases, the downgrade means that all fields which are absent in the format specification for the given revision are cut off.

For example:

  • If a cluster revision attribute is set to a pre-ZCL8 value, e.g. the value is 1, and an application calls ZBOSS ZCL8 via an API request, the request format in the air will correspond to revision 1
  • If the value is 3, and an application calls ZBOSS ZCL8 via an API request, the request will be formatted according to cluster revision 3.
  • If a cluster revision attribute is set to any other possible value, and an application calls with a pre-ZCL8 API request, the request will always be formatted according to revision 1. API call will "limit" the format in this case.

2.3.2 Auto mode

The ZB_ZCL_AUTO_MODE mode is intended to automatically convert ZBOSS pre-ZCL8 and ZCL8 API to the format given by the cluster revision attribute. Any ZBOSS ZCL API will be upgraded/downgraded to match the format given by the revision. In case of upgrade, request packet fields will be set to their default values according to ZCL specification. So the main rule in this mode, that own cluster revision attribute will define format of the command which will be send over-the air, regardless of the API used. This mode can be set ONLY manually (see 2.3.4 for details).

For example:

  • If a cluster revision is set to a pre-ZCL8 value, e.g. value is 1, and an application calls with a ZBOSS ZCL8 API request, the request will be downgraded to the pre-ZCL8 format
  • If the revision is 3, and an application calls with a ZBOSS ZCL8 API request, the request will be sent as is, in the ZCL8 format
  • If a cluster revision attribute is set to a pre-ZCL8 value, e.g. value is 1, and an application calls with a pre-ZCL8 API request, the request will be sent as is, in the pre-ZCL8 format
  • If the revision is 3, the pre-ZCL8 API request fields will be extended with default values to match the revision 3 format.

2.3.3 Compatibility mode

The ZB_ZCL_COMPATIBILITY_MODE mode should be supported in the application in order to fully correspond to the ZCL specification. In this mode, it is possible to achieve maximum compatibility with old/broken devices. This mode adds a mechanism of requesting revisions to peers and may cause some delays in command sending under some circumstances. Significant application changes are also required, since the application should maintain a cluster revisions table and implement a full cluster revisions API. This mode can be enabled manually or automatically after the peer_revision_callback is set.

The peer_revision_callback has to be defined according the following signature:

typedef zb_uint16_t (*zb_zcl_peer_revision_cb_t) (zb_ieee_addr_t ieee_addr, zb_uint16_t cluster_id, zb_uint8_t cluster_role, zb_uint8_t endpoint);

Here is an example using the zb_zcl_set_peer_revision_callback call:

zb_uint16_t peer_revision_cb(zb_ieee_addr_t ieee_addr, zb_uint16_t cluster_id, zb_uint8_t cluster_role, zb_uint8_t endpoint)
{
...
return peer_revision;
}
void foo_init(void)
{
zb_ret_t ret;
...
ret = zb_zcl_set_peer_revision_callback(peer_revision_cb);
...
}

The ZB_ZCL_COMPATIBILITY_MODE mode implements logic such that when revisions of the command are sent, the revisions will be limited to each peer and its cluster independently. An application must implement peer_revision_callback in order to let ZBOSS ZCL8 retrieve peer cluster revisions, to transform ZCL correctly based on the requests. In the callback function, the application should return revisions requested for the given peer and cluster identified through the callback parameters. It's up to the application implementation to define how the peer revision is obtained. If the revision is unknown, the ZB_ZCL_PEER_CLUSTER_REV_UNKNOWN value should be returned. In both cases, whether the callback is not set, or the ZB_ZCL_PEER_CLUSTER_REV_UNKNOWN value is returned, the minimum possible peer revision will be used for the mode. Please note, the format will be also limited by the set cluster revision attribute.

2.3.4 How to use backward compatibility modes

ZBOSS ZCL8 Backward compatibility modes can be set using the zb_zcl_set_backward_comp_mode call:

zb_ret_t ret = zb_zcl_set_backward_comp_mode(ZB_ZCL_LEGACY_MODE);

The current mode can be obtained through the zb_zcl_get_backward_comp_mode call:

zb_uint8_t mode = zb_zcl_get_backward_comp_mode();

All ZB_ZCL_LEGACY_MODE, ZB_ZCL_AUTO_MODE and ZB_ZCL_COMPATIBILITY_MODE modes can be set manually. ZB_ZCL_LEGACY_MODE is always the default mode, so long as an application doesn't select another mode intentionally. ZB_ZCL_COMPATIBILITY_MODE is enabled automatically when the zb_zcl_set_peer_revision_callback is called with a non-NULL parameter.

Here is brief overview for the results of ZBOSS pre-ZCL8 and ZCL8 API invocation in various backward compatibility modes:

Backward compatibility mode ZBOSS ZCL API version Local cluster revision Peer cluster revision Resulting request format Description
ZB_ZCL_LEGACY_MODE pre-ZCL8 1 n/a limited by API call 1 as is
ZB_ZCL_LEGACY_MODE pre-ZCL8 default(3) n/a limited by API call 1 as is
ZB_ZCL_LEGACY_MODE ZCL8 1 n/a limited by own rev 1 downgraded
ZB_ZCL_LEGACY_MODE ZCL8 default(3) n/a same as own revision 3 as is
ZB_ZCL_AUTO_MODE pre-ZCL8 1 n/a as set in own rev 1 as is
ZB_ZCL_AUTO_MODE pre-ZCL8 default(3) n/a as set in own rev 3 upgraded
ZB_ZCL_AUTO_MODE ZCL8 1 n/a as set in own rev 1 downgraded
ZB_ZCL_AUTO_MODE ZCL8 default(3) n/a as set in own rev 3 as is
ZB_ZCL_COMPATIBILITY_MODE pre-ZCL8 1 1 limited by own rev 1 as is
ZB_ZCL_COMPATIBILITY_MODE pre-ZCL8 1 3 limited by own rev 1 as is
ZB_ZCL_COMPATIBILITY_MODE pre-ZCL8 default(3) 1 limited by peer rev 1 as is
ZB_ZCL_COMPATIBILITY_MODE pre-ZCL8 default(3) 3 same as own default 3 upgraded
ZB_ZCL_COMPATIBILITY_MODE ZCL8 1 1 limited by own rev 1 downgraded
ZB_ZCL_COMPATIBILITY_MODE ZCL8 1 3 limited by own rev 1 downgraded
ZB_ZCL_COMPATIBILITY_MODE ZCL8 default(3) 1 limited by peer rev 1 downgraded
ZB_ZCL_COMPATIBILITY_MODE ZCL8 default(3) 3 same as own default 3 as is

NOTE: the cluster revision values in the table are provided as an example to demonstrate possible format conversions.

2.4 How ZBOSS ZCL8 treats ZCL statuses

The ZCL8 specification introduces changes in status codes, which are not compatible with pre-ZCL8 codes. Particularly for cases in which ZBOSS ZCL8 adds status code mapping that depends on backward compatibility modes. When ZB_ZCL_LEGACY_MODE is enabled, all statuses are passed as they were in pre-ZCL8 version, in order to maintain compatibility with old applications. For ZB_ZCL_AUTO_MODE and ZB_ZCL_COMPATIBILITY_MODE, all pre-ZCL8 status codes are converted to match their new ZCL8 description (see 1.2.).

3. ZBOSS ZCL8 API

The ZBOSS ZCL8 implementation extends the API with a new macro which can be distinguished in a **_ZCL8** suffix. For example:

It's recommended to use macro calls as the primary API for ZCL.

In most cases, the new API adds parameters for corresponding command fields, introduced in the ZCL8 specification. See the full ZBOSS ZCL8 API description in the ZBOSS Development Guide [4].

For simplicity, if you are not familiar with which cluster command was changed in ZCL8, and if it contains a new API function implementation - you can simply include the supplied optional header zboss_stable/include/zboss_api_zcl8.h and always call macros with the _ZCL8 suffix. In this case, even if the command is equal in pre-ZCL8 as well as in ZCL8, it will be routed to the latest available revision of the command.

4. References

[1]: 07-5123-08 Zigbee Cluster Library Revision 8 [2]: 07-5123-07 Zigbee Cluster Library Revision 7 [3]: 13-0589-13 ZigBee Application Architecture [4]: ZBOSS Development Guide