Introduction

Z-Stack is a component of the SimpleLink CC13xx / CC26xx Software Development Kit and is a complete Zigbee 3.0 software solution.

The intention of this lab is to help developers create their own custom Zigbee devices using Z-Stack. Topics that we will cover in this lab include:

  1. Choosing a certifiable Zigbee device type from the Zigbee device type specifications
  2. Gathering the required information about your chosen Zigbee device from the Zigbee documentation
  3. Modifying the sample applications provided in the SimpleLink SDK to suit the needs of your chosen Zigbee device

Note: This lab is intended to be a starting point for development, it does not go into details about how to test and verify the final product.

Technical support

For any questions you may have, please refer to the TI Zigbee & Thread E2E Forum.

Prerequisites

Background

  • Familiarity with the Zigbee 3.0 specification
    • More information about the changes in Zigbee 3.0 compared to older specifications can be found in SWRA615
  • Basic CCS knowledge
  • Some basic familiarity with embedded programming

Software

Zigbee Documentation

  • Zigbee Cluster Library v7 Specification (ZCL spec) - Zigbee Document number 07-5123-07
  • Zigbee Lighting and Occupancy Device Specification (ZLO spec) - Zigbee Document number 15-0014-05
  • Zigbee Home Automation Public Application Profile (ZHA spec) - Zigbee Document number 05-3520-29

Note

Zigbee documentation can be obtained from the Connectivity Standards Alliance

Gathering information from Zigbee documentation

Before we jump into the software, our first task is to determine which type of Zigbee device we wish to create. Then we must determine which clusters that device must support and which attributes those clusters must support.

1. Choosing a Zigbee device type

There are currently two specifications we can refer to for choosing a Zigbee device type, the Zigbee Lighting and Occupancy Device Specification (ZLO spec) and the Zigbee Home Automation Public Application Profile (ZHA spec).

Go to the "Device Descriptions" sections of both documents, Section 5 in the ZLO spec and Section 5.7 in the ZHA spec. At first glance you will notice that there is some overlap between these two specifications, namely Device ID 0x0100 through 0x0107. If you are creating one of these Zigbee Lighting devices, refer to the information in the ZLO spec instead of the ZHA spec. The ZLO spec is the newest device specification document that has been released by the Connectivity Standards Alliance, so the information in this document is newer and supersedes anything regarding these devices types in the ZHA spec. For all other non-overlapping device types between these two documents, the current instructions from the Zigbee Alliance website are to follow the guidelines in each corresponding document for each device type.

So, let's say we want to create a Door Lock as our Zigbee device. In Section 5.7 of the ZHA spec, we can see in Table 5.1 below that this device has Device ID 0x000A.

2. Determining which clusters our device support

In the same document that we chose our Zigbee device out of, we can navigate to the section that defines what clusters our device supports. In our case, we need go to Section 7.4.10 of the ZHA spec for Door Lock. From here we can determine which clusters our device supports under the subsection 'Supported Clusters'.

Here are all the important points from the images below:

  • Mandatory and Optional Clusters

    • All Zigbee devices must implement their mandatory clusters to pass Zigbee device certification. Zigbee device manufacturers may choose to implement certain optional clusters for their own application needs.

    Note

    If you choose to implement an optional cluster, even though it is marked as optional, you must still pass certification for that cluster if you wish to include it with your device.

  • Server Side and Client Side cluster implementation
    • Implementing the Server vs. the Client side of a cluster is very important because it determines which attributes you support.

  • Common Clusters for all Zigbee devices
    • All Zigbee devices support a common set of mandatory and optional clusters, listed below in table 7.1. We can see in section 7.4.10.1 below that it mentions "In addition to those specified in Table 7.1"

Now, using the information from the tables above, let's make new table that shows what clusters our Door Lock device is going to support. Only the mandatory clusters are selected for this example.

Cluster ID Cluster Name Client/Server Side
0x0000 Basic Server
0x0003 Identify Client + Server
0x0004 Groups Server
0x0005 Scenes Server
0x0101 Door Lock Server

3. Determining which attributes our clusters support

Now that we have a list of clusters, we can refer to the Zigbee Cluster Library v7 Specification (ZCL spec). The ZCL spec will tell us which attributes our selected clusters support. Each section of the ZCL spec will give us a cluster and tell us which attributes the Server Side and Client Side implementations of that cluster support.

As of the ZCL v6 spec, it is mandatory for every cluster to support the ClusterRevision attribute.

Let's start with the Basic Cluster. From the table we made in the previous section, we must support the Basic Cluster Server. Table 3-7 in Section 3.2.2.2 of the ZCL spec tells us which attributes the Basic Cluster Server supports.

Next we can find the Identify Cluster, for which we must support both Client and Server. Table 3-28 in section 3.5.2.2 of the ZCL spec tells us which attributes the Identify Cluster Server supports. Section 3.5.2.1 of the ZCL spec tells us that the Identify Cluster Client does not support any cluster specific attributes.

Next is the Groups Cluster, for which we must support both Client and Server. Table 3-36 of section 3.6.2.2 of the ZCL spec tells us which attributes the Groups Cluster Server supports. The same can be said of Table 3-40 of section 3.7.2.2.1 for the Scenes Cluster and Table 7-8 of section 7.3.2.10 for the Door Lock Cluster, all for the Server side.

Once again, a new table is created using the information from the tables above that shows us which attributes our Door Lock device is going to support. Only the madatory attributes are selected for this example.

Attribute Cluster Data Type Access Default Value
ZCLVersion Basic uint8 Read 2
PowerSource Basic enum8 Read 0
ClusterRevision Basic uint16 Read 1
IdentifyTime Identify uint16 Read/Write 0
ClusterRevision Identify uint16 Read 1
NameSupport Groups map8 Read 0
ClusterRevision Groups uint16 Read 1
SceneCount Scenes uint8 Read 0
CurrentScene Scenes uint8 Read 0
CurrentGroup Scenes uint16 Read 0
SceneValid Scenes bool Read 0
NameSupport Scenes map8 Read 0
ClusterRevision Scenes uint16 Read 1
LockState Door Lock enum8 Read/Reportable 0
LockType Door Lock enum8 Read 0
ActuatorEnabled Door Lock bool Read 0
ClusterRevision Door Lock uint16 Read 1

Reportable Attributes

If any of the attributes you are supporting have an access type of Reportable, it is mandatory for your device to support ZCL reporting which means your device will need to include the compile flag BDB_REPORTING which enables ZCL report sending capabilities. We will revisit this again later on in the lab.

Modifying the SampleApp project

It's finally time to start modifying the software to suit our needs. We will be referencing the SampleApp project to create a custom certifiable application using the SysConfig Application Builder. You can learn more about this feature in the TI Z-Stack User's Guide. You can find the project in the following location:

C:\ti\simplelink_cc13xx_cc26xx_sdk_<version>\examples\rtos\<LaunchPad variant>\zstack\zr_sampleapp

1. Importing the project into Code Composer Studio

Now we are ready to import the project into Code Composer Studio (CCS). Open CCS and go to File > Import > C/C++ Project > CCS Project and then browse for the zr_sampleapp project path under Select search-directory:

At this point it is a good idea to try building the project just to make sure all the file paths resolve correctly, this will verify that we have a good starting point for our incoming code modifications.

2. Using the SysConfig Application Builder

The SysConfig Application Builder will automate several ZCL configurations. This consists of defining compile flags in ti_zstack_config.h along with including all attributes, server/client clusters, simple descriptors, callback definitions, and initialization code inside the zcl_config.c file. First, open the zr_sampleapp.syscfg > Z-Stack > Zigbee Application Endpoint menu and select Generic as the Zigbee Device Type. It is possible to change the Application Name to "Door Lock" or another suitable name of choice, however this lab will keep the default "Sample App" naming convention.

Note

Although a Door Lock is provided as a pre-configured certifiable Zigbee Device Type, we will build one from scratch for the purposes of this lab.

The following list details what all is configured inside the Zigbee Application Builder

  1. Viewing Mandatory Clusters

  2. Adding Additional Clusters

  3. Choosing BDB Reporting and Advanced Settings

Viewing Mandatory Clusters

We can select the Mandatory Clusters tab to see that only the Basic and Identify clusters are defined as the Server Clusters. This is the default requirement for a Generic Zigbee Device Type and no further changes are required towards these settings. Optional Attributes and Optional Commands Generated/Received can be added if necessary for the application. Groups is listed under Server Clusters from Recommended Optional Clusters and should be chosen accordingly.

Adding Additional Clusters

Inside the Additional Clusters tab is where we will add the clusters from SLA Table 1, excluding Basic and Identify for the server side as they are already covered by the Mandatory Clusters. For Server Clusters, select Scenes and DoorLock. Client Clusters need only add Identify.

Doing this will prompt the Zigbee Application Builder to automatically fill the Mandatory Attributes tab with the attributes described in SLA Table 2. The Mandatory Commands Generated/Received are also populated. Optional Attributes and Optional Commands Generated/Received can also be added based on application needs.

Choosing BDB Reporting and Advanced Settings

As SLA Table 2 identifies a reportable attribute which was added when configuring the Additional Clusters, the BDB Reporting tab becomes available. These values, alongside those of the Advanced Settings tab, can be chosen according to the developer's requirements. More information can be obtained in the SysConfig section of the TI Z-Stack User's Guide. For the purpose of this lab, however, the default values will be used.

After completing all configurations inside the SysConfig Zigbee Application Builder, we will build the project to generate the zcl_config.c/h file which will be located in the default/sysconfig folder. It is here that we can view the ZCL attribute variables/default values, attribute lists, command lists, callbacks, and simple descriptors that were created based on our previous selections. We also see that a zclConfigInit function is created to initialize this code, and is called by sampleApp_Init of sampleapp.c.

SysConfig output

Files found in the default/sysconfig folder must never be directly edited as they will be re-written each time the project is built. Changes can only be made by modifying the corresponding SysConfig module or copying files into the main project directory after de-selecting Include in build from the SysConfig Generated File View.

All of the ZCL source code files are included in the SampleApp project by default, but the functionality contained in each file is compiled out via compile flags. The table below shows which compile flags will be added to ti_zstack_config.h based on the clusters listed in SLA Table 1.

Cluster ID Cluster Name Compile Flags
0x0000 ZCL_CLUSTER_ID_GEN_BASIC ZCL_BASIC
0x0001 ZCL_CLUSTER_ID_GEN_POWER_CFG N/A
0x0002 ZCL_CLUSTER_ID_GEN_DEVICE_TEMP_CONFIG N/A
0x0003 ZCL_CLUSTER_ID_GEN_IDENTIFY ZCL_IDENTIFY
0x0004 ZCL_CLUSTER_ID_GEN_GROUPS ZCL_GROUPS
0x0005 ZCL_CLUSTER_ID_GEN_SCENES ZCL_SCENES
0x0006 ZCL_CLUSTER_ID_GEN_ON_OFF ZCL_ON_OFF
0x0007 ZCL_CLUSTER_ID_GEN_ON_OFF_SWITCH_CONFIG N/A
0x0008 ZCL_CLUSTER_ID_GEN_LEVEL_CONTROL ZCL_LEVEL_CTRL
0x0009 ZCL_CLUSTER_ID_GEN_ALARMS ZCL_ALARMS
0x000A ZCL_CLUSTER_ID_GEN_TIME N/A
0x000B ZCL_CLUSTER_ID_GEN_LOCATION ZCL_LOCATION
0x000C ZCL_CLUSTER_ID_GEN_ANALOG_INPUT_BASIC N/A
0x000D ZCL_CLUSTER_ID_GEN_ANALOG_OUTPUT_BASIC N/A
0x000E ZCL_CLUSTER_ID_GEN_ANALOG_VALUE_BASIC N/A
0x000F ZCL_CLUSTER_ID_GEN_BINARY_INPUT_BASIC N/A
0x0010 ZCL_CLUSTER_ID_GEN_BINARY_OUTPUT_BASIC N/A
0x0011 ZCL_CLUSTER_ID_GEN_BINARY_VALUE_BASIC N/A
0x0012 ZCL_CLUSTER_ID_GEN_MULTISTATE_INPUT_BASIC N/A
0x0013 ZCL_CLUSTER_ID_GEN_MULTISTATE_OUTPUT_BASIC N/A
0x0014 ZCL_CLUSTER_ID_GEN_MULTISTATE_VALUE_BASIC N/A
0x0015 ZCL_CLUSTER_ID_GEN_COMMISSIONING N/A
0x0016 ZCL_CLUSTER_ID_GEN_PARTITION N/A
0x0019 ZCL_CLUSTER_ID_OTA OTA_CLIENT_INTEGRATED
0x001A ZCL_CLUSTER_ID_GEN_POWER_PROFILE N/A
0x001B ZCL_CLUSTER_ID_GEN_APPLIANCE_CONTROL N/A
0x0020 ZCL_CLUSTER_ID_GEN_POLL_CONTROL N/A
0x0021 ZCL_CLUSTER_ID_GREEN_POWER N/A
0x0022 ZCL_CLUSTER_ID_MOBILE_DEVICE_CONFIGURATION N/A
0x0023 ZCL_CLUSTER_ID_NEIGHBOR_CLEANING N/A
0x0024 ZCL_CLUSTER_ID_NEAREST_GATEWAY N/A
0x0100 ZCL_CLUSTER_ID_CLOSURES_SHADE_CONFIG N/A
0x0101 ZCL_CLUSTER_ID_CLOSURES_DOOR_LOCK ZCL_DOORLOCK
0x0102 ZCL_CLUSTER_ID_CLOSURES_WINDOW_COVERING ZCL_WINDOWCOVERING
0x0200 ZCL_CLUSTER_ID_HVAC_PUMP_CONFIG_CONTROL ZCL_HVAC_CLUSTER
0x0201 ZCL_CLUSTER_ID_HVAC_THERMOSTAT ZCL_HVAC_CLUSTER
0x0202 ZCL_CLUSTER_ID_HVAC_FAN_CONTROL ZCL_HVAC_CLUSTER
0x0203 ZCL_CLUSTER_ID_HVAC_DIHUMIDIFICATION_CONTROL ZCL_HVAC_CLUSTER
0x0204 ZCL_CLUSTER_ID_HVAC_USER_INTERFACE_CONFIG ZCL_HVAC_CLUSTER
0x0300 ZCL_CLUSTER_ID_LIGHTING_COLOR_CONTROL ZCL_LIGHT_LINK_ENHANCE
0x0301 ZCL_CLUSTER_ID_LIGHTING_BALLAST_CONFIG ZCL_LIGHT_LINK_ENHANCE
0x0400 ZCL_CLUSTER_ID_MS_ILLUMINANCE_MEASUREMENT N/A
0x0401 ZCL_CLUSTER_ID_MS_ILLUMINANCE_LEVEL_SENSING_CONFIG N/A
0x0402 ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT N/A
0x0403 ZCL_CLUSTER_ID_MS_PRESSURE_MEASUREMENT N/A
0x0404 ZCL_CLUSTER_ID_MS_FLOW_MEASUREMENT N/A
0x0405 ZCL_CLUSTER_ID_MS_RELATIVE_HUMIDITY N/A
0x0406 ZCL_CLUSTER_ID_MS_OCCUPANCY_SENSING N/A
0x0500 ZCL_CLUSTER_ID_SS_IAS_ZONE ZCL_ZONE
0x0501 ZCL_CLUSTER_ID_SS_IAS_ACE ZCL_ACE
0x0502 ZCL_CLUSTER_ID_SS_IAS_WD ZCL_WD
0x0600 ZCL_CLUSTER_ID_PI_GENERIC_TUNNEL N/A
0x0601 ZCL_CLUSTER_ID_PI_BACNET_PROTOCOL_TUNNEL N/A
0x0602 ZCL_CLUSTER_ID_PI_ANALOG_INPUT_BACNET_REG N/A
0x0603 ZCL_CLUSTER_ID_PI_ANALOG_INPUT_BACNET_EXT N/A
0x0604 ZCL_CLUSTER_ID_PI_ANALOG_OUTPUT_BACNET_REG N/A
0x0605 ZCL_CLUSTER_ID_PI_ANALOG_OUTPUT_BACNET_EXT N/A
0x0606 ZCL_CLUSTER_ID_PI_ANALOG_VALUE_BACNET_REG N/A
0x0607 ZCL_CLUSTER_ID_PI_ANALOG_VALUE_BACNET_EXT N/A
0x0608 ZCL_CLUSTER_ID_PI_BINARY_INPUT_BACNET_REG N/A
0x0609 ZCL_CLUSTER_ID_PI_BINARY_INPUT_BACNET_EXT N/A
0x060A ZCL_CLUSTER_ID_PI_BINARY_OUTPUT_BACNET_REG N/A
0x060B ZCL_CLUSTER_ID_PI_BINARY_OUTPUT_BACNET_EXT N/A
0x060C ZCL_CLUSTER_ID_PI_BINARY_VALUE_BACNET_REG N/A
0x060D ZCL_CLUSTER_ID_PI_BINARY_VALUE_BACNET_EXT N/A
0x060E ZCL_CLUSTER_ID_PI_MULTISTATE_INPUT_BACNET_REG N/A
0x060F ZCL_CLUSTER_ID_PI_MULTISTATE_INPUT_BACNET_EXT N/A
0x0610 ZCL_CLUSTER_ID_PI_MULTISTATE_OUTPUT_BACNET_REG N/A
0x0611 ZCL_CLUSTER_ID_PI_MULTISTATE_OUTPUT_BACNET_EXT N/A
0x0612 ZCL_CLUSTER_ID_PI_MULTISTATE_VALUE_BACNET_REG N/A
0x0613 ZCL_CLUSTER_ID_PI_MULTISTATE_VALUE_BACNET_EXT N/A
0x0614 ZCL_CLUSTER_ID_PI_11073_PROTOCOL_TUNNEL N/A
0x0615 ZCL_CLUSTER_ID_PI_ISO7818_PROTOCOL_TUNNEL N/A
0x0617 ZCL_CLUSTER_ID_PI_RETAIL_TUNNEL N/A
0x0700 ZCL_CLUSTER_ID_SE_PRICE ZCL_SE_PRICE_SERVER, ZCL_SE_PRICE_CLIENT
0x0701 ZCL_CLUSTER_ID_SE_DRLC ZCL_SE_DRLC_SERVER, ZCL_SE_DRLC_CLIENT
0x0702 ZCL_CLUSTER_ID_SE_METERING ZCL_SE_METERING_SERVER, ZCL_SE_METERING_CLIENT
0x0703 ZCL_CLUSTER_ID_SE_MESSAGING ZCL_SE_MESSAGING_SERVER, ZCL_SE_MESSAGING_CLIENT
0x0704 ZCL_CLUSTER_ID_SE_TUNNELING ZCL_SE_TUNNELING_SERVER, ZCL_SE_TUNNELING_CLIENT
0x0705 ZCL_CLUSTER_ID_SE_PREPAYMENT ZCL_SE_PREPAYMENT_SERVER, ZCL_SE_PREPAYMENT_CLIENT
0x0706 ZCL_CLUSTER_ID_SE_ENERGY_MGMT ZCL_SE_ENERGY_MGMT_SERVER, ZCL_SE_ENERGY_MGMT_CLIENT
0x0707 ZCL_CLUSTER_ID_SE_CALENDAR ZCL_SE_CALENDAR_SERVER, ZCL_SE_CALENDAR_CLIENT
0x0708 ZCL_CLUSTER_ID_SE_DEVICE_MGMT ZCL_SE_DEVICE_MGMT_SERVER, ZCL_SE_DEVICE_MGMT_CLIENT
0x0709 ZCL_CLUSTER_ID_SE_EVENTS ZCL_SE_EVENTS_SERVER, ZCL_SE_EVENTS_CLIENT
0x070A ZCL_CLUSTER_ID_SE_MDU_PAIRING ZCL_SE_MDU_PAIRING_SERVER, ZCL_SE_MDU_PAIRING_CLIENT
0x0800 ZCL_CLUSTER_ID_SE_KEY_ESTABLISHMENT ZCL_KEY_ESTABLISH
0x0900 ZCL_CLUSTER_ID_TELECOMMUNICATIONS_INFORMATION N/A
0x0904 ZCL_CLUSTER_ID_TELECOMMUNICATIONS_CHATTING N/A
0x0905 ZCL_CLUSTER_ID_TELECOMMUNICATIONS_VOICE_OVER_ZIGBEE N/A
0x0B00 ZCL_CLUSTER_ID_HA_APPLIANCE_IDENTIFICATION ZCL_APPLIANCE_IDENTIFICATION
0x0B01 ZCL_CLUSTER_ID_HA_METER_IDENTIFICATION ZCL_METER_IDENTIFICATION
0x0B02 ZCL_CLUSTER_ID_HA_APPLIANCE_EVENTS_ALERTS ZCL_APPLIANCE_EVENTS_ALERTS
0x0B03 ZCL_CLUSTER_ID_HA_APPLIANCE_STATISTICS ZCL_APPLIANCE_STATISTICS
0x0B04 ZCL_CLUSTER_ID_HA_ELECTRICAL_MEASUREMENT ZCL_ELECTRICAL_MEASUREMENT
0x0B05 ZCL_CLUSTER_ID_HA_DIAGNOSTIC ZCL_DIAGNOSTIC
0x1000 ZCL_CLUSTER_ID_TOUCHLINK N/A

In addition to the compile flags in the table above, it is also considered whether any attributes have an access type of 'Reportable', which is information that we recorded in SLA Table 2. If there is an attribute that is 'Reportable', it is also included as the compile flag BDB_REPORTING in the ti_zstack_config.h file.

For our Door Lock device, the compile flags ZCL_BASIC, ZCL_IDENTIFY, ZCL_GROUPS, ZCL_SCENES, ZCL_DOORLOCK and BDB_REPORTING will be included in the SysConfig output once the corresponding Clusters and Attributes are added. They can be viewed in the default/syscfg/ti_zstack_config.h after building the project.

/* Cluster Flags */
#define ZCL_SYSCONFIG
#define ZCL_READ
#define ZCL_WRITE
#define ZCL_DISCOVER
#define ZCL_BASIC
#define ZCL_IDENTIFY
#define ZCL_GROUPS
#define ZCL_SCENES
#define ZCL_DOORLOCK
#define BDB_REPORTING

ti_zstack_config.h

3. Making code changes to suit our selected Zigbee device

As the SysConfig Zigbee Application Builder has automated setup of the ZCL layer inside zcl_config.h/c, all that remains is to copy the command callback functions, attribute variables, and default values into sampleapp.c and remove the WEAK tags so that they are correctly re-defined outside of the generated SysConfig files.

ZCL command callback functions are where your hardware-specific actions are performed in relation to the state of your cluster attributes. For instance, if you receive a Zigbee command from another device that changes the state of your Door Lock Cluster "LockState" attribute, you can receive a callback to your application saying that something happened, and at this point you would update your global attribute variable with the value passed into the callback function as a parameter and perform your hardware-specific action such as toggling a GPIO pin to reflect the new state of your attribute.

To receive these callback functions in your application, you must register a list of function pointers with each corresponding ZCL module. By default, zcl_config.c already does this with zclConfigInit:

static void zclConfigInit( void )
{
  ...

  zclGeneral_RegisterCmdCallbacks( SAMPLEAPP_ENDPOINT, &sampleApp_zclGeneralCmdCallbacks );
  zclClosures_RegisterDoorLockCmdCallbacks( SAMPLEAPP_ENDPOINT, &sampleApp_zclClosuresCmdCallbacks );

  ...
}

zcl_config.c

The second parameter we pass into this function is the list of function pointers that we wish to register with the ZCL module. For every function present on this list we will receive a callback in our application when the corresponding action has been triggered, and we can set any callback we do not wish to receive to NULL. To know which callback functions are available, you must look into the corresponding zcl<module>_AppCallbacks_t struct in the ZCL header files. Since the Basic, Identify, Groups, and Scenes clusters are all part of the ZCL General group (i.e. check Chapter 3 of the ZCL spec), all of their callback function descriptions are in the struct zclGeneral_AppCallbacks_t in zcl_general.h. For the Door Lock cluster, this is part of the Closures group, so it is in the struct zclClosures_DoorLockAppCallbacks_t in zcl_closures.h. Each function in these structs has a typedef associated with it so you can know how to implement the function prototype and definition in your application. For instance, for the Door Lock callback, it has the type zclClosures_DoorLock_t in the struct zclClosures_DoorLockAppCallbacks_t, and we can see the typedef definition is as below:

typedef ZStatus_t (*zclClosures_DoorLock_t) ( zclIncoming_t *pInMsg, zclDoorLock_t *pInCmd );

And in zcl_config.c the function is already defined as such:

WEAK ZStatus_t sampleApp_DoorLockCB( zclIncoming_t *pInMsg, zclDoorLock_t *pInCmd ) { return ((ZStatus_t) 0); }

However, this is an empty function which does not accomplish anything. To re-define it for application use, it must be copied into sampleapp.c and remove the WEAK tag. This directs the compiler to use the callback function declared inside this file instead.

// Declaring the function at the top of the file
ZStatus_t sampleApp_DoorLockCB( zclIncoming_t *pInMsg, zclDoorLock_t *pInCmd );
...
// Implementing the function further in the file
ZStatus_t sampleApp_DoorLockCB( zclIncoming_t *pInMsg, zclDoorLock_t *pInCmd )
{
    // Perform action based on application needs
    return 0;
}

sampleapp.c

The same can be done for ZCL attribute variables, like sampleApp_DoorLock_LockState.

As mentioned before, the ZCL command callback functions are where you, the developer, must implement your hardware-specific functionality in your application code based on the high-level intended action of each ZCL command. This is the part of the code where, aside from provided HAL drivers, there is no specific framework for how you should implement your actions since it is highly dependent on your custom hardware design. One thing you must do, however, is update the state of your global attribute(s) in these callback functions (if applicable).

As an example, in the Door Lock cluster "DoorLock" Callback, you would do at least 2 things:

  1. Update the state of your global "LockState" attribute based on the function parameter of the callback function.
  2. Perform a hardware-specific action that actually changes the state of your hardware, such as altering the door lock mechanism.
Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivatives 4.0 International License.