nRF5 SDK for Thread and Zigbee v3.0.0
Zigbee stack API overview

Table of Contents

This page provides an overview of the stack ZCL, commissioning, and security APIs.

Common ZCL terms and definitions

The following table lists terms that are used in the Zigbee Cluster Library specification.

Term Definition
Attribute A data entity that represents a physical quantity or state. This data is communicated to other devices through commands.
Cluster A specification that defines one or more attributes, commands, behaviors, or dependencies. Cluster supports an independent utility or application function.

The term can also be used for the implementation or the instance of the cluster specification on an endpoint.
Device A specification that defines a unique device identifier and a set of mandatory and optional clusters to be implemented on a single endpoint.

The term can also be used for the implementation or the instance of the device specification on an endpoint.
Endpoint A device instance on a node.
Node A Zigbee application and stack on a single network.
ZCL specification terms and definitions

The Zigbee application implements a node that handles endpoints. Every endpoint implements a set of clusters. Clusters implement the device functionality, such as attributes to store the state and the commands for various operations.

The ZCL specification is designed to minimize the consumption of flash and RAM by the user application. The application uses the API to declare a Zigbee device and to construct and parse ZCL commands.

Implementing a Zigbee end product with ZCL

Zigbee devices are characterized by a set of clusters that have mandatory and optional attributes. To save memory, make sure that only the required attributes and clusters are declared.

Application can either use predefined device declaration (for example, IAS Zone device) or define its own set of clusters and endpoints.

At the highest level, the Zigbee end product implementation consists of the following parts:

Declaring attributes

ZCL attributes are described according to the ZCL specification. The library declares attribute lists according to the mandatory attribute sets of the clusters. The ZCL attributes are defined in a form that allows modification.

Naming convention
Each attribute list declaration API has a name corresponding to ZB_ZCL_DECLARE_<CLUSTER_NAME>_CLUSTER_ATTRIB_LIST.

The attribute list starts with ZB_ZCL_START_DECLARE_ATTRIB_LIST and ends with ZB_ZCL_FINISH_DECLARE_ATTRIB_LIST. You can add any number of additional attributes between these lines.

Example 1
The following macro defines the list of attributes for the Door Lock cluster:

#define ZB_ZCL_DECLARE_DOOR_LOCK_CLUSTER_ATTRIB_LIST(attr_list, \
lock_state, \
lock_type, \
actuator_enabled) \
ZB_ZCL_START_DECLARE_ATTRIB_LIST(attr_list) \
ZB_ZCL_SET_ATTR_DESC(ZB_ZCL_ATTR_DOOR_LOCK_LOCK_STATE_ID, (lock_state)) \
ZB_ZCL_SET_ATTR_DESC(ZB_ZCL_ATTR_DOOR_LOCK_LOCK_TYPE_ID, (lock_type)) \
ZB_ZCL_SET_ATTR_DESC(ZB_ZCL_ATTR_DOOR_LOCK_ACTUATOR_ENABLED_ID, (actuator_enabled)) \
ZB_ZCL_FINISH_DECLARE_ATTRIB_LIST

Example 2
The following code example defines global variables for the attributes and initiates them with the default values. It then declares the list of attributes for the On/Off Switch configuration cluster.

Note
Unsigned 8-bit integer type is used to store the values.

The ZB_ZCL_DECLARE_ON_OFF_SWITCH_CONFIGURATION_ATTRIB_LIST macro is defined in the zb_zcl_on_off_switch.h file. This cluster supports two attributes: switch_type and switch_actions.

Declaring cluster

The SDK provides more than 30 implemented Zigbee clusters that are ready for the user application.

To use a cluster, the application must declare it as part of the Zigbee device that is being implemented. Each cluster description is associated with a Zigbee device and includes the following data:

The cluster description data is stored using zb_zcl_cluster_desc_t type. The SDK provides several APIs to fill in cluster descriptors while creating the cluster list declaration.

Declaring custom cluster

When a non-standard cluster is required, implement it in the following manner:

  1. Create the cluster headers with the name corresponding to the following template: include/zcl/zb_zcl_<cluster_name>.h
  2. In the cluster headers, declare required attributes with read, write, or reporting functionality.
  3. In the cluster headers, implement parsers for the required commands.
    Note
    Refer to zb_zcl_on_off.h for an example of the configured cluster header.
  4. Add the new cluster to the device declaration header.
    Note
    Refer to the On/Off cluster inclusion in simple_gw_device.h and simple_gw.c for an example.
  5. If you need specific commands in the new cluster, register the application endpoint handler as follows:
  6. Handle these custom commands in your application. The commands are processed when the application layer returns ZB_TRUE.

Declaring cluster list

The functionality of a Zigbee device is defined by a set of supported clusters. The cluster list is an array of the type zb_zcl_cluster_desc_t. For standard Zigbee devices, the source code contains a set of declaration APIs for cluster lists. The code can be modified to add or remove clusters.

Naming convention
Each cluster list declaration API has a name corresponding to ZB_HA_DECLARE_<DEVICE_NAME>_CLUSTER_LIST.

Example
List declaration for a dimmable light (a standard Zigbee device):

ZB_HA_DECLARE_DIMMABLE_LIGHT_CLUSTER_LIST(cluster_list_name, basic_attr_list, identify_attr_list, groups_attr_list, scenes_attr_list, on_off_attr_list, level_control_attr_list)
Note
ZB_HA_DECLARE_DIMMABLE_LIGHT_CLUSTER_LIST() is defined in zb_ha_dimmable_light.h. Whenever the dimmable light utilizes Basic, Identify, Groups, Scenes, On/Off, and Level Control clusters in a server role, the device takes attribute lists for all of them.

Declaring endpoint

An endpoint (or a set of endpoints) fully describes a Zigbee device. The endpoint declaration in the user application finalizes the logical description of the Zigbee device. Each Zigbee device must have at least one endpoint, with the option to add more. Their list is declared each time for the Zigbee device, even if it only implements a single endpoint.

Each endpoint description includes the following data:

The endpoint description data is stored using the type zb_af_endpoint_desc_t. The SDK provides several APIs to fill in endpoint descriptors while performing a Zigbee device declaration for each supported Zigbee device. Additionally, the API declares a simple descriptor. The endpoint list declaration API is provided in the source code and can be modified depending on the application.

Naming convention
Each endpoint list declaration API has a name corresponding to ZB_HA_DECLARE_<DEVICE_NAME>_EP.

Example
Endpoint declaration for a dimmable light (a standard Zigbee device):

ZB_HA_DECLARE_DIMMABLE_LIGHT_EP(ep_name, ep_id, cluster_list)

APIs for multiple endpoints
A single endpoint is defined for the dimmable light device, just as for other standard Zigbee devices. If you want to declare a device with multiple endpoints for the application, use the following API calls to declare the endpoint list:

The endpoint list is stored as an array of the zb_af_endpoint_desc_t type. Each call to ZB_AF_DECLARE_ENDPOINT_DESC() adds an item to the ep_list_name array.

Declaring simple descriptor

The simple descriptor contains specific information for each endpoint contained in a node. The simple descriptor is mandatory for each endpoint present in the node. The API declares the simple descriptor for each standard Zigbee device and embeds the related calls into the endpoint declaration APIs. However, if modifications to the standard device are requested, the simple descriptor declaration is provided in the source code and you can modify it according to the application needs.

Technically, the simple descriptor is a variable of the type ZB_AF_SIMPLE_DESC_TYPE(in_clust_count, out_clust_count). A pointer to this variable is stored in the endpoint descriptor. This macro is used to create a full type name at compilation time. This is because the simple descriptor contains a list of in and out (client/server) clusters, and the list size varies for different devices. To minimize the RAM usage, the specified values of in and out clusters are used to declare an array of a size required to store all cluster IDs. There is a base type declared for the simple descriptor: ZB_AF_SIMPLE_DESC_TYPE(1, 1). This type is used to cast all the user-specific simple descriptor types at runtime.

Naming convention
Each simple descriptor declaration API has a name corresponding to ZB_HA_DECLARE_<DEVICE_NAME>_SIMPLE_DESC.

APIs
The APIs for managing simple descriptor types are the following:

Declaring Zigbee device context

The Zigbee device context aggregates the list of endpoints and runtime data, for example storage for reporting configuration information and Level Control context information. The application is responsible for providing enough storage for reporting and Level Control context data for all the endpoints that it declares. For standard Zigbee devices, it is the API that declares device context together with storage for all the context data.

Naming convention
Each device declaration API has a name corresponding to ZB_HA_DECLARE_<DEVICE_NAME>_CTX.

APIs
To modify the existing device context declaration or define a new one, use the API call ZBOSS_DECLARE_DEVICE_CTX_1_EP(device_ctx_name, ep_name).

You can also declare device context with multiple endpoints, for example:

Registering device context

When the declaration procedures are finished, the device context must be registered with a call to ZB_AF_REGISTER_DEVICE_CTX. As part of this call, two callbacks can be registered in the application:

Configuring default ZCL command handler override

The stack implements default handling of all the ZCL commands for all supported clusters, but there is also an option to override the handling by implementing custom procedure for a certain command . The stack comes with a mechanism that allows the interception of the default ZCL command processing and the implementation of an application-specific command handling.

Executing interception mechanism
To execute this mechanism, the ZCL packet handler callback must be first implemented and registered by the application (see Registering device context). After the ZCL packet handler is registered, it is called for each new incoming ZCL command. This happens before the default ZCL handler is called.

If the application-specific ZCL packet handler returns ZB_FALSE, the packet is not processed by the application and the default ZCL handling is applied. If the application does handle the packet and no default processing is needed, the packet handler returns ZB_TRUE. This means that the packet is processed.

Note
  • If the application started parsing packets and modified a packet (header or tail bytes have been cut or byte order has been inverted), it must finalize the packet processing. Otherwise, the default handler can fail.
  • If the application handles the received packet, it is responsible for sending a response (if needed) and managing the memory buffer that stores the original ZCL packet.

The most common commands processed by the application are responses to the requests sent, including Read attribute response, Write attribute response, and Configure reporting response.

APIs
The SDK comes with API macros for handling the received packets, for example ZB_ZCL_GENERAL_GET_NEXT_READ_ATTR_RES(), ZB_ZCL_GET_NEXT_WRITE_ATTR_RES(), and ZB_ZCL_GENERAL_GET_NEXT_CONFIGURE_REPORTING_RES().

Each packet-parsing API call can modify the ZCL packet it is parsing "in place". For more details on the parsing API, see ZCL commands shared by all clusters in the ZCL API documentation.

Macro Parameters Return value Description
ZB_AF_SET_ENDPOINT_HANDLER(endpoint, handler) endpoint – Endpoint number.
handler – Pointer to a function of the type zb_device_handler_t.
None. Register ZCL packet handler for the specific endpoint.
zb_uint8_t my_zcl_pkt_handler(zb_uint8_t param) param – Reference to the buffer with the incoming ZCL command. ZB_TRUE – If the ZCL command was processed by the application.
ZB_FALSE – If the ZCL command was not processed by the user application.
ZCL packet processing callback.
Processing API calls (selection)
Note
Registering device context is required before calling ZB_AF_SET_ENDPOINT_HANDLER().

Implementing algorithm for overriding the handling of ZCL commands
To process an incoming ZCL command, implement the following algorithm in the ZCL packet handler callback:

  1. Extract the incoming ZCL command information from the incoming buffer:
    zb_buf_t *zcl_cmd_buf = (zb_buf_t *)ZB_BUF_FROM_REF(param);
  2. Check command direction (the cmd_direction field of the zb_zcl_parsed_hdr_t structure):
  3. Check whether the command is general or cluster-specific.
    • When the command is general, the is_common_command field of the zb_zcl_parsed_hdr_t structure is set to 1.
    • When the command is cluster-specific, the is_common_command field is set to 0.
  4. Check the designated cluster ID: cmd_info -> cluster_id field of the zb_zcl_parsed_hdr_t structure.
  5. Check the command ID: cmd_info -> cmd_id field of the zb_zcl_parsed_hdr_t structure.
    • The general ZCL command identifiers are listed in the zb_zcl_cmd_t enumeration.
    • Cluster-specific command identifiers are defined in the corresponding cluster headers.
  6. Depending on the check results:
    • Handle the command.
    • Let the stack do the handling.

If the incoming command was processed by the application:

Otherwise, return ZB_FALSE to indicate to the stack to perform the default command processing.

Implementing Zigbee device callback

Zigbee device callback is an optional callback. It is called by the stack's default ZCL cluster handlers to notify the application about a certain event. The event can be caused by the incoming ZCL command or by the internal stack logic.

The “device” word in the callback name indicates that the application must react as a real device. For example, change the brightness level of the lamp on ZB_ZCL_LEVEL_CONTROL_SET_VALUE_CB_ID callback.

With a call to ZB_ZCL_REGISTER_DEVICE_CB(), the application can register a callback function that takes the reference to a buffer as the input parameter. This buffer carries the parameter zb_zcl_device_callback_param_t (see Zigbee stack memory management subsystem for information about how to get a parameter from the buffer).

To check what action triggered the callback, refer to the field device_cb_id of the received parameter. All the cases are listed in the zb_zcl_device_callback_id_t enumeration. Do not perform any blocking operations during the Zigbee device callback implementation. The memory buffer passed as a parameter to this callback must not be released or reused by the application because it is managed by the ZCL subsystem.

Examples
A few examples of device callbacks called by the kernel:

Sending ZCL commands

The SDK provides API calls for sending and parsing ZCL packets for general command frames and cluster-specific commands.

Naming convention
The naming convention is not strict. Usually, it is composed of the following elements:

For general commands, the cluster name is replaced with GENERAL.

Macro example Cluster name Action verb Command
ZB_ZCL_ON_OFF_SEND_TOGGLE_REQ() On/Off Send Toggle
ZB_ZCL_IAS_ZONE_SEND_STATUS_CHANGE_NOTIFICATION_REQ() IAS zone Send Zone notification
ZB_ZCL_GENERAL_INIT_READ_ATTR_REQ()
ZB_ZCL_GENERAL_ADD_ID_READ_ATTR_REQ()
ZB_ZCL_GENERAL_SEND_READ_ATTR_REQ()
(general commands) Initialize
Add
Send
Read Attribute
Sending ZCL commands: Naming convention examples

API command structure
The command can have a predefined or a variable size:

To construct a manufacturer-specific command (or a standard command that is not supported by the API yet), use the low-level API:

Parsing ZCL commands

The API for parsing the received ZCL packets for general command frames and cluster-specific commands is similar to the API for Sending ZCL commands.

Naming convention
The API command name is composed of the following elements:

For general commands, the cluster name is replaced with GENERAL.

Macro example Cluster name Action verb Command Additional information
ZB_ZCL_IAS_ZONE_GET_STATUS_CHANGE_NOTIFICATION_REQ() IAS zone Get Zone notification Fills in a variable of the zb_zcl_ias_zone_status_change_not_t type.
ZB_ZCL_GENERAL_GET_NEXT_READ_ATTR_RES() (general command) Get Read Attribute Parses the Read Attribute response.
Parsing ZCL commands: Naming convention examples

The parsing API is not provided for commands without a payload, for example the Toggle command in the On/Off cluster.

If the received packet is parsed manually, use the ZB_ZCL_FIX_ENDIAN API to keep the right endianness in the packet.

Support for Zigbee commissioning

The commissioning logic is based on Zigbee BDB specification, and is divided into two types:

Other types of commissioning like the legacy HA or the ZLL commissioning are supported, but not recommended.

You can configure commissioning by setting parameters before the start of the stack.

Commissioning configuration sequence

There are several commissioning parameters that can be assigned by the application or stored in NVRAM, or both.

The default parameters are coded in the application firmware. Then they can be updated by the NVRAM content.

The commissioning configuration sequence is made of the following steps:

  1. Application calls ZB_INIT() to set some reasonable defaults of commissioning parameters.
  2. If needed, the application makes an API call to tune commissioning by changing the default values.
    • Example 1: set hard-coded long address (useful for debugging): zb_set_long_address(g_ed_addr);
    • Example 2: set a ZED at channel 2: zb_set_network_ed_role(1l<<21);
  3. The application calls zboss_start() or zboss_start_no_autostart().
    • The stack loads NVRAM and updates internal parameters, for example working channel, short address, binding information.
    • The stack loads the production configuration from the flash memory. This can possibly modify some settings related to the implementation of a Zigbee device.
    • The stack continues the starting process. If a device joins, the stack updates the short address and stores it in NVRAM.
  4. The application does some commission actions (like binding) at runtime, after successful start and join.
    • The stack stores the binding information in NVRAM to be able to restore it at reboot.

The following example demonstrates the commissioning configuration sequence, with the long address updated by the long address defined in the production configuration block:

zb_ieee_addr_t g_ed_addr = {0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22, 0x22};
int main(void)
{
...
ZB_INIT("on_off_switch_zed");
zb_set_long_address(g_ed_addr);
...
if (zboss_start() != RET_OK)
...

Network configuration settings (general)

The stack implements all Zigbee roles: coordinator, router, and end device. Only one role can be defined in a Zigbee application. Switching Zigbee role at runtime is not supported.

Different libraries are provided for each role, and the application must be linked with them:

See the following table for the overview of functions for setting the device role.

Macro Parameters Return value Description
zb_set_network_coordinator_role(zb_uint32_t channel_mask) channel_mask – mask used to define the primary channel set. None. Initiate device as a Zigbee coordinator.
zb_set_network_router_role(zb_uint32_t channel_mask) channel_mask – mask used to define the primary channel set. None. Initiate device as a Zigbee router.
zb_set_network_ed_role(zb_uint32_t channel_mask) channel_mask – mask used to define the primary channel set. None. Initiate device as a Zigbee end device.
Functions for setting the device role
Note
It is possible to switch the device linked with the ZC/ZR library into the end device mode. The main reason for using the ZED library is code space and RAM economy.

For the complete list of settings, see the Application structure & commissioning start section in the Zigbee stack API reference documentation.

For information about debugging the Zigbee stack, see Debugging.

Network configuration settings (BDB-specific)

The channel_mask parameter is a bit field that defines the Zigbee channels to be used for the energy scan as the primary channel set. Bits from 11 to 26 are of special importance. Each bit enables or disables the corresponding channel. To set all channel masks (enable all channels), use the macro ZB_TRANSCEIVER_ALL_CHANNELS_MASK.

BDB has an abstraction of primary and secondary channel mask. By default, the secondary channel mask is the same, but you can define it separately by using the call zb_set_bdb_secondary_channel_set(zb_uint32_t channel_mask).

For details on the abstraction of primary and secondary channel mask and the complete network configuration API, see the official Zigbee BDB specification.

The following functions can modify the settings of the BDB channel:

To start the implicit BDB commissioning after the zboss_start() call, use the zb_set_bdb_commissioning_mode() function. Its parameter is a bitmask that specifies the BDB commissioning mode. See the official Zigbee BDB specification for detailed description. For more details about the API, see the BDB commissioning API section in the Zigbee stack API documentation.

Stack commissioning start sequence

You can use one of the following functions for stack initalization:

The zboss_start_no_autostart() function does only minimal initialization of the stack framework, enough to have the multitasking and the memory management. The stack initializes its base structures, reads NVRAM, starts the scheduler, but does not initialize Zigbee data structures and radio. It then calls zboss_signal_handler() with ZB_ZDO_SIGNAL_SKIP_STARTUP signal. You must force the Zigbee radio initialization and start commissioning by using zboss_start_continue(). This option is recommended if:

When the stack is initialized (with or without commissioning), the main loop of the stack must be started by calling zboss_main_loop().

if (zboss_start() == RET_OK)
{
}

After the main loop is started, the user application functions can be processed in the context of the scheduler: either zboss_signal_handler() or one of the two ZCL callbacks are called.

Zigbee commissioning event handling

As the full-featured Zigbee stack is implemented, all Zigbee commands and events are processed. In addition, there are tools that allow the application to handle some Zigbee events, including network formation, association status, and leave indication. Due to its nature, different Zigbee events appear asynchronously and the stack informs the application with application signals. The application can handle or ignore these signals.

All application signals are processed in the application with a predefined callback function zboss_signal_handler(). Each application must implement this function, even if there is no need to process signals. The prototype for the signal handler function is:

In this function, param is a reference to a memory buffer.

Take into account the following policies while implementing the zboss_signal_handler() function:

An application signal is described with the following parameters:

To get the signal description, the application calls zb_get_app_event(). For example:

zb_zdo_app_signal_t zb_get_app_event(zb_uint8_t param, zb_zdo_app_event_t **ev_p);

Where:

The function returns an ID of the application signal.

Example
zboss_signal_handler() implementation example:

/**@brief ZigBee stack event handler.
* @param[in] param Reference to the ZigBee stack buffer used to pass arguments (signal).
*/
{
zb_zdo_app_signal_hdr_t * p_sg_p = NULL;
zb_zdo_signal_leave_params_t * p_leave_params = NULL;
enum zb_zdo_app_signal_type_e sig = zb_get_app_signal(param, &p_sg_p);
switch(sig)
{
if (status == RET_OK)
{
NRF_LOG_INFO("Joined network successfully");
}
else
{
NRF_LOG_ERROR("Failed to join network. Status: %d", status);
}
break;
if (status == RET_OK)
{
NRF_LOG_INFO("Network left. Leave type: %d", p_leave_params->leave_type);
/* handle leave parameters leave_params */
}
else
{
NRF_LOG_ERROR("Unable to leave network. Status: %d", status);
}
break;
if (status != RET_OK)
{
NRF_LOG_WARNING("Production config is not present or invalid");
}
break;
default:
/* Unhandled signal. For more information see: zb_zdo_app_signal_type_e and zb_ret_e */
NRF_LOG_INFO("Unhandled signal %d. Status: %d", sig, status);
}
if (param)
{
ZB_FREE_BUF_BY_REF(param);
}
}

BDB Commissioning API

The stack implements procedures for the following BDB commissioning modes:

The implementation can use commissioning at any time. For example, network steering can be started at any time for the whole node, and finding and binding can be performed at any time on any application endpoint.

Note
An explicit start of commissioning is required if zboss_start_no_autostart() was called instead of zboss_start(). For details, see Stack commissioning start sequence.

The commissioning procedure is initiated by triggering a top-level commissioning procedure with the bdb_start_top_level_commissioning function.

F&B

The finding and binding procedure can be initiated independently or within the commissioning process.

To bind multiple endpoints on a target device with one endpoint on an initiator device, you must run different finding and binding procedures for all endpoint pairs consequently.

Note
The finding and binding procedure is implemented as a singleton, so there can only be one such procedure running at a time.

On the initiator device:

On the target device:

APIs
The following table shows an overview of the commissioning API:

Macro Parameters Return value Description
bdb_start_top_level_commissioning(zb_uint8_t mode_mask) mode_mask – logical OR of values from zb_bdb_commissioning_mode_mask_t. None. Initiate BDB commissioning procedure defined by the mode_mask.
zb_bdb_finding_binding_target(zb_uint8_t endpoint) endpoint – endpoint to bind. None. Finding and binding interface.
Set finding and binding target mode on the endpoint.
zb_bdb_finding_binding_initiator(zb_uint8_t endpoint, zb_bdb_comm_binding_callback_t user_binding_cb) endpoint – endpoint to bind.
user_binding_cb - user callback function.
None. Finding and binding interface.
Initiate finding and binding on the endpoint. Pass result with user_binding_cb.
typedef zb_bool_t (* zb_bdb_comm_binding_callback_t)(zb_int16_t status, zb_ieee_addr_t addr, zb_uint8_t ep, zb_uint16_t cluster) status – status (ask user, success or fail).
addr – extended address of a device to bind
ep – endpoint of a device to bind.
cluster – cluster ID to bind.
zb_bool_t – agree or disagree to bind device. Finding and binding interface.
BDB finding and binding callback template.
Commissioning API calls
Note
Finding and binding (both target and initiator) must always be started explicitly.

For details, see BDB commissioning API in the Zigbee stack API documentation.

Resetting to factory defaults

The Zigbee stack provides an interactive mechanism to reset any node implementation to the default factory settings, based on the requirements in the official Zigbee BDB specification.

The resetting process of a Zigbee-based application includes persistent data cleanup and consists of the following steps:

  1. Optionally, inform the user about the reset to the factory settings.
  2. Cancel any rejoin process if it is in progress.
  3. Stop any pending send or resend callbacks; free the buffers that are locked for these operations.
  4. Do one of the following:
    • If the device supports OTA Upgrade process: stop this process by using zcl_ota_abort().
    • If the device supports Poll Control cluster: stop the check-ins by using zb_zcl_poll_control_stop().
    • If the device supports Power Config cluster: reset Power Config reporting to default.
  5. Reset attributes for each supported cluster.
  6. Flush new attribute values to a persistent storage.
    Note
    See zb_nvram_dataset_types_e for dataset type list. Many datasets are written by the stack internally, but the following ones must be written by the application:
  7. Broadcast NWK leave.
  8. At NWK leave confirmation:
    • Optionally, inform the user about the completion of the factory reset process.
    • If needed, schedule device reboot.
  9. Free resources that were reserved by the application.
    Note
    The application must not clean up the APS resources, for example in APS binding table, APS group table, and APS security keys storage. The stack performs the cleanup after the application sends the NWK Leave request to its own node.

Security

The application has access to a selection of security measures in the stack. However, most options are invisible to the application.

Zigbee network security API

Trust Center generates random network keys. This is the default behavior, according to Zigbee PRO core specification.

It is possible to predefine the network key by using zb_secur_setup_nwk_key(). You can use this API call for debugging purposes to simplify the analysis of traffic sniffing results. Do not use it in the production environment.

Application at the coordinator role (Trust Center) can force the network key switch procedure by calling zb_secur_nwk_key_switch_procedure().

Zigbee API for code security installation

In accordance with the Zigbee 3.0 specifications, this SDK provides install code functionality. The following table provides an overview of the related API macros.

Macro Parameters Return value Description
zb_secur_ic_add(zb_ieee_addr_t address, zb_uint8_t *ic); address – long address of the device.
*ic – pointer to the install code buffer.
zb_ret_t RET_OK or error code. Add the install code for the device with the specified long address. Only for the coordinator.
zb_secur_ic_set(zb_uint8_t *ic) zb_uint8_t *ic – pointer to the install code buffer. zb_ret_t RET_OK or error code.Add the install code for a device. Not for the coordinator.
Install code API calls

Power saving for ZED

The SDK provides a mechanism for power saving that turns on the sleep mode for Zigbee end devices (RxOffWhenIdle = TRUE).

The mechanism starts with the scheduler that tracks the callback queue (see Zigbee stack multitasking (scheduler)). If there is no immediate callback for the execution and there is no outgoing packet on the MAC level, a special signal ZB_COMMON_SIGNAL_CAN_SLEEP is sent to the application. The signal has a sleep time parameter that specifies the allowed sleep duration in milliseconds. The sleep duration value is based on the time remaining before the first alarm is called. Alternatively, it is set to 10 seconds if there are no alarms in the queue.

Upon receiving the ZB_COMMON_SIGNAL_CAN_SLEEP signal, the application checks its internal state and decides whether to enter the sleep mode or not. To switch to the sleep mode, the application must call the zb_sleep_now() function.

The application can use zb_sleep_set_threshold() to set the minimum sleep duration value, which reduces the number of the triggered ZB_COMMON_SIGNAL_CAN_SLEEP signals. If the sleep duration is lower than the specified threshold, the signal is not triggered. By default, the value of the sleep duration threshold ZB_SCHED_SLEEP_THRESHOLD_MS is set to 20 ms. The upper limit for this value is 86400000 ms (one day).

Example
Possible implementation of the power saving mechanism:

/* Handle “can sleep” signal and requesting stack to go to sleep mode */
{
if (ZB_GET_APP_SIGNAL_STATUS(param) == 0)
{
switch(sig)
{
...
{
break;
}
...
}
}
else
{
TRACE_MSG(TRACE_ERROR, "Device started FAILED status %d", (FMT__D, ZB_GET_APP_SIGNAL_STATUS(param)));
ZB_SCHEDULE_ALARM(test_leave_and_join, 0, ZB_TIME_ONE_SECOND);
}
...
}

APIs
The following table provides an overview of the power saving sleep API:

Macro Parameters Return value Description
zb_ret_t zb_sleep_set_threshold(threshold_ms) threshold_ms -– sleep threshold value in milliseconds. RET_OK – If the interval is successfully set.
RET_ERROR – Otherwise.
Set threshold value.
By default, set to ZB_SCHED_SLEEP_THRESHOLD_MS (20 ms).
zb_uint32_t zb_get_sleep_threshold() None. Currently used threshold value.
zb_sleep_now() None. None. Immediately put the device into sleep mode. This call is permitted only in signal handler when application receives the ZB_COMMON_SIGNAL_CAN_SLEEP signal.
zb_void_t zb_sleep_enable() None. None. Enable power saving subsystem. Enabled by default.
zb_void_t zb_sleep_disable() None. None. Disable power saving subsystem.
Power saving sleep API calls

Documentation feedback | Developer Zone | Subscribe | Updated