ZigBee Frame Generation and Decoding for General Commands
This example shows how to generate and decode General Command frames of the ZigBee® specification [ 1 ].
Background
The ZigBee standard [ 1 ] specifies network (NET or NWK) and application (APP) layers of low-rate wireless personal area networks. These NET- and APP-layer specifications build upon the PHY and MAC specifications of IEEE® 802.15.4™ [ 2 ]. ZigBee devices find application in home automation and sensor networking and are highly relevant to the Internet of Things (IoT) trend.
The ZigBee application layer consists of multiple sub-layers: (i) the Application Support Sublayer (APS), and (ii) the ZigBee Cluster Library (ZCL).
The APS and ZCL headers follow a format that is common for all application profiles and ZigBee clusters/commands (see Clauses 2.2.5 in [ 1 ] and 2.4 in [ 3 ], respectively). The APS header declares the cluster of the frame and the ZCL header declares the command of the frame. The ZCL payload is present only for some clusters/commands and follows a command-specific format.
Some commands only apply for a specific cluster, while some other (general) commands can be used for all clusters. General command frames are used for manipulating attributes and other general tasks that are not specific to an individual cluster (see Clause 2.5 in [ 3 ]). This example illustrates how to generate and decode ZCL payloads for such general, library-wide ZigBee commands. The generic APS and ZCL header generation and decoding is illustrated in the ZigBee Home Automation Frame Generation and Decoding example.
Commands
This example illustrates frame generation and decoding for the following general commands:
Read Attributes: This command inquires an attribute value at a different device.
Read Attributes Response: This command responds with an attribute value.
Write Attributes: This command modifies an attribute value at a different device.
Write Attributes Response: This command responds with the result of a Write Attributes command.
In addition, this example provides an implementation for the following commands (which are not illustrated):
Write Attributes Undivided: This command is the same with "Write Attributes" with the only exception that an attribute is updated only if all other specified attributes can also be updated.
Write Attributes No Response: This command is the same with "Write Attributes" with the only exception that a response frame is not required.
Report Attributes: This command reports all attributes and their values.
Default Response: This command generates response frames of generic format.
A zigbee.GeneralFrameConfig
configuration object is used both in generating and decoding ZCL payloads of General Commands. Such objects describe a General Commands payload and all applicable properties.
Generating ZCL Payloads of General Commands
The zigbee.GeneralFrameGenerator
function accepts a zigbee.GeneralFrameConfig
object describing the payload of the general command and generates the payload in bytes. The following code creates the payload of the Read/Write Attribute commands and their responses.
% Read attributes command readConfigTx = zigbee.GeneralFrameConfig( ... 'CommandType','Read Attributes','AttributeID','0000')
readConfigTx = GeneralFrameConfig with properties: CommandType: 'Read Attributes' AttributeID: '0000'
readPayload = zigbee.GeneralFrameGenerator(readConfigTx); % Read attributes response command readResponseConfigTx = zigbee.GeneralFrameConfig( ... 'CommandType','Read Attributes Response', ... 'AttributeID','0000', ... 'Status','Success', ... 'AttributeType','boolean', ... 'AttributeValue',false)
readResponseConfigTx = GeneralFrameConfig with properties: CommandType: 'Read Attributes Response' AttributeID: '0000' Status: 'Success' AttributeType: 'Boolean' AttributeValue: 0
readResponsePayload = zigbee.GeneralFrameGenerator(readResponseConfigTx); % Write attributes command writeConfigTx = zigbee.GeneralFrameConfig( ... 'CommandType','Write Attributes', ... 'AttributeID','0000', ... 'AttributeType','boolean', ... 'AttributeValue',true)
writeConfigTx = GeneralFrameConfig with properties: CommandType: 'Write Attributes' AttributeID: '0000' AttributeType: 'Boolean' AttributeValue: 1
writePayload = zigbee.GeneralFrameGenerator(writeConfigTx); % % Write attributes response command: writeResponseConfigTx = zigbee.GeneralFrameConfig( ... 'CommandType','Write Attributes Response', ... 'Status','Success')
writeResponseConfigTx = GeneralFrameConfig with properties: CommandType: 'Write Attributes Response' Status: 'Success'
writeResponsePayload = zigbee.GeneralFrameGenerator(writeResponseConfigTx);
Decoding ZCL Payloads of General Commands Captured from ZigBee Radios
This section decodes ZCL payloads of general commands captured from commercial Home-Automation ZigBee radios with a USRP® B200-mini radio and the Communications Toolbox Support Package for USRP® radio. For more information, see section 'Clusters and Frame Captures' in the ZigBee Home Automation Frame Generation and Decoding example.
load zigbeeGeneralCommandCaptures % Load captured payloads
The zigbee.GeneralFrameDecoder
function accepts a general command name and its payload in bytes and outputs a zigbee.GeneralFrameConfig
object describing the payload of the general command. The command name is retrieved from the decoding of the ZCL header. See section 'Decoding ZCL Header of Home Automation ZigBee Radios' in the ZigBee Home Automation Frame Generation and Decoding example.
% Read attributes readConfigRx = zigbee.GeneralFrameDecoder( ... 'Read Attributes',capturedReadPayload)
readConfigRx = GeneralFrameConfig with properties: CommandType: 'Read Attributes' AttributeID: '0000'
% Read attributes response readResponseRx = zigbee.GeneralFrameDecoder( ... 'Read Attributes Response',capturedReadResponsePayload)
readResponseRx = GeneralFrameConfig with properties: CommandType: 'Read Attributes Response' AttributeID: '0000' Status: 'Success' AttributeType: 'Boolean' AttributeValue: 1
% Default response defaultResponseRx = zigbee.GeneralFrameDecoder( ... 'Default Response',capturedDefaultResponsePayload)
defaultResponseRx = GeneralFrameConfig with properties: CommandType: 'Default Response' Status: 'Success' CommandToRespond: '01'
Decoding Generated ZCL Payloads of General Commands
This section illustrates the decoding of the remaining generated general commands (such as 'Write Attributes' and 'Write Attributes Response').
% Write attributes writeConfigRx = zigbee.GeneralFrameDecoder( ... 'Write Attributes',writePayload)
writeConfigRx = GeneralFrameConfig with properties: CommandType: 'Write Attributes' AttributeID: '0000' AttributeType: 'Boolean' AttributeValue: 1
% Write attributes response writeResponseRx = zigbee.GeneralFrameDecoder( ... 'Write Attributes Response',writeResponsePayload)
writeResponseRx = GeneralFrameConfig with properties: CommandType: 'Write Attributes Response' Status: 'Success'
Wireshark Decoding
The generated frames can be converted to a PCAP format, which can be analyzed and visualized with Wireshark [ 4 ]. You can use Wireshark to verify the frames you generate and decode frames are standard-compliant.
The PCAP file needs the ZCL payloads to be enclosed with headers from all other layers and sublayers (MAC, NET, APS, ZCL). The following commands generate a PCAP file, for the ZCL payloads generated in this example, that can be loaded with Wireshark.
% Profile ID profileID = zigbee.profileID('Home Automation'); onOffID = zigbee.clusterID('On/Off'); payloadsWithInfo(1) = struct( ... 'Payload',readPayload, ... 'ProfileID',profileID, ... 'ClusterSpecific',false, ... 'ClusterID',onOffID, ... 'CommandType','Read Attributes', ... 'Direction','Downlink'); payloadsWithInfo(2) = struct( ... 'Payload',readResponsePayload, ... 'ProfileID',profileID, ... 'ClusterSpecific',false, ... 'ClusterID',onOffID, ... 'CommandType','Read Attributes Response', ... 'Direction','Uplink'); payloadsWithInfo(3) = struct( ... 'Payload',writePayload, ... 'ProfileID',profileID, ... 'ClusterSpecific',false, ... 'ClusterID',onOffID, ... 'CommandType','Write Attributes', ... 'Direction','Downlink'); payloadsWithInfo(4) = struct( ... 'Payload',writeResponsePayload, ... 'ProfileID',profileID, ... 'ClusterSpecific',false, ... 'ClusterID',onOffID, ... 'CommandType','Write Attributes Response', ... 'Direction','Uplink'); % Add headers from other layers/sublayers MPDUs = zigbeeAddProtocolHeaders(payloadsWithInfo); % Export MPDUs to a PCAP format zigbeeExportToPcap(MPDUs,'zigbeeGeneralCommands.pcap'); % Open PCAP file with Wireshark
Further Exploration
The example uses these undocumented utilities. The API and functionality of undocumented utilities may change in the future. To view the source code of the utilities, use the edit
function.
zigbee.GeneralFrameConfig
zigbee.GeneralFrameGenerator
zigbee.GeneralFrameDecoder
References
1 - ZigBee Alliance, ZigBee Specification Document 053474r17, 2007.
2 - IEEE 802.15.4-2011 - IEEE Standard for Local and Metropolitan Area Networks--Part 15.4: Low-Rate Wireless Personal Area Networks (LR-WPANs).
3 - ZigBee Alliance, ZigBee Cluster Library Specification, Revision 6, Jan. 2016.
4 - Wireshark software: https://www.wireshark.org/