Attribute Management#
ZCL Attribute Configuration#
In the Zigbee Application Framework , attribute storage is managed by two .c files app/framework/util/attribute-storage.c and attribute-table.c as well as a single header file zap-config.h which Project Configurator generates from the application configuration. The endpoint configuration header file sets up the attribute metadata and the actual attribute storage.
You have several options for attribute storage:
External Attributes
Persistent Memory Storage
Singleton
Attribute Bounding
Attribute Reporting
Attribute Storage Endianness#
All attributes that are not a ZCL string type are expected to be stored with the same endianness as the platform on which the application is being run. On the EFR32, this means that attributes with a non-string type are expected to be stored with the least significant byte first (LSB, little endian).
Implications of Attribute Storage Endianness#
The Zigbee protocol demands that all values that are not a string or byte array type be sent over the air in a Little Endian or LSB format. The implication of this for the EFR32 and other little-endian platforms is that no byte swapping needs to be done with attributes when they are pulled from attribute storage and sent over the air. Conversely, when the Zigbee Application Framework is run a big-endian processor, like certain UNIX host systems for EZSP-UART, it will perform byte swapping on integer type attributes before they are sent over the air so that they are sent in the LSB format.
The previous section says that attributes are expected to be stored in the proper format because no byte swapping is done on local writes into the attribute table from native types or from byte arrays. Therefore, it is up to the user to ensure that byte arrays which represent Zigbee integer types but do not map directly to a native type like the int16u or int32u are represented in the byte order of the application platform.
If you are writing an application that may be run on several platforms with different endianness, you may check the endianness of the platform by using the #define BIGENDIAN_CPU provided in the platform header platform/common/inc/sl_endianness.h.
Example: Consider the simple-meter-server component’s test code located at app/framework/plugin/simple-metering-server/simple-metering-test.c. This test code pulls the simple metering daily summation attribute from the attribute table, updates it, and puts it back into the attribute table. Unfortunately, the daily summation is a Zigbee 48-bit unsigned integer, which is not a native data type.
The Zigbee platform for the EFR32 family of processors has no native data type like an int48u into which the daily summation attribute can be read and simply manipulated. As a result, the attribute must be read into a byte array and the byte array must be manipulated before it is written back into the attribute table. During this manipulation it is important for the developer to remember that on the EFR32 the attribute is stored LSB, so the manipulation must be done LSB. Otherwise, the value will be stored and sent over the air in the wrong format when it is read by another device on the network.
Note: For EZSP host applications, since all attributes are stored on the host processor in an NCP + Host design, it is the endianness of the host that counts for attribute storage.
External Attributes#
You may wish to store the values for some attributes in a location external to the Zigbee application framework. This type of storage makes the most sense for attributes that must be read from the hardware each time they are requested. In a case like this, no real reason exists to store a copy of the attribute in some wasted RAM space within the Zigbee application framework.
Mark an attribute as externally located by editing the cluster in Zigbee Cluster Configurator, editing the attribute, and selecting External in the attribute’s Storage Option menu. The attribute’s metadata will be tagged to indicate that the Zigbee Application Framework should not reserve memory for the storage of that attribute. Instead, when that attribute is to be read or written, the Zigbee Application Framework accesses it by calling sl_zigbee_af_external_attribute_read_cb
and sl_zigbee_af_external_attribute_write_cb
.
The application is expected to respond to the request immediately. No state machine is currently associated with accessing external attributes that would be able to, for example, start a read and then callback again in a minute to see how the data read is going.
Any attribute that cannot be returned or updated in a timely manner is not currently a candidate for externalization. For attributes of this type, Silicon Labs suggests that you include Zigbee Application Framework storage and update the value in the Zigbee Application Framework on a specific interval within the sl_zigbee_af_main_tick_cb.
Persistent Memory Storage#
Silicon Labs System-on-Chip (SoC) chips can store attributes in persistent memory (SIMEEPROM or NVM3). Mark an attribute for persistent memory storage by editing the cluster in Zigbee Cluster Configurator, editing the attribute, and selecting NVM in the attribute’s Storage Option menu. This automatically adds the necessary header file code to the generated zap-tokens.h file and marks the attribute as persisted in flash within the attribute’s metadata.
Because each host chip has its own way of storing persistent data, the Zigbee Application Framework and Project Configurator do not have a way of persisting attributes on the host. However, you can mark any attribute you wish to persist as ‘External’ and then handle the data persistence yourself within sl_zigbee_af_external_attribute_read_cb
and sl_zigbee_af_external_attribute_write_cb
.
Singleton#
While ZCL clusters and attributes can be spread across multiple endpoints, it does not make sense to have multiple instances of many of these attributes. For instance, the Basic Cluster may be implemented on three different endpoints, but it does not make sense to store three versions of the mandatory ‘ZCL Version’ attribute, since each endpoint will likely have the same version. Mark an attribute as a singleton by editing the cluster in Zigbee Cluster Configurator, editing the attribute, and selecting the Singleton checkbox. As a convenience, the Zigbee Application Framework provides a default ‘Singleton’ modifier for many of the obvious cases. This default modifier can be overridden if you choose.
Attributes marked as singleton are stored in a special singleton storage area in memory. A read or write to any endpoint for one of these attributes resolves to an access of the same location in memory.
Attribute Bounding#
Attributes which contain min and max values defined by the Zigbee ZCL specification can be bounded within the Zigbee Application Framework. Mark an attribute as bounded by editing the cluster in Zigbee Cluster Configurator, editing the attribute, selecting the Bounded checkbox. When an attribute is bounded, the min and max values defined by the ZCL specification are included in the generated zap-config.h file. When the application attempts to write one of these attributes, the attribute write succeeds only if its value falls within the bounds defined by the ZCL specification.
Interacting with ZCL Attributes#
The Zigbee Application Framework attributes table exposes several APIs that help you do things like read, write, and verify that certain attributes are included on a given endpoint. The prototypes for functions used to interact with the attribute tables are conveniently located in app/framework/include/af.h. The API includes:
sl_zigbee_af_attribute_metadata_t
: Retrieves the metadata for a given attribute
Use this function to determine if the attribute exists or is implemented on a given endpoint. You can use the sl_zigbee_af_attribute_metadata_t
pointer returned to access more information about the attribute in question including its type, size, defaultValue and any internal settings for the attribute contained in its mask.
sl_zigbee_af_attribute_metadata_t *sl_zigbee_af_locate_attribute_metadata(uint8_t endpoint, sl_zigbee_af_cluster_id_t clusterId, sl_zigbee_af_attribute_id_t attributeId, uint8_t mask, uint16_t manufacturerCode);
The Zigbee Application Framework stores metadata for all the attributes that it contains in CONST memory. It does this for all attributes, including those that may have values stored externally or singletons.
ZCL String Attributes#
The String data type is a special case in the ZCL. All strings are MSB with the first byte being the length byte for the string. There is no null terminator or similar concept in the ZCL. Therefore a 5-byte string is 6 bytes long, with the first byte indicating the length of the proceeding string. For example, “05 68 65 6C 6C 6F” is a ZCL string that says “hello”.