MATLAB Examples

ZigBee Frame Generation and Decoding for General Commands

This example shows how to generate and decode General Command frames of the ZigBee specification [ 1 ] using the Communications System Toolbox™ Library for the ZigBee® protocol.

Contents

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 a different example.

Commands

This examples illustrates frame generation and decoding for the following general commands:

  1. Read Attributes: This command inquires an attribute value at a different device.
  2. Read Attributes Response: This command responds with an attribute value.
  3. Write Attributes: This command modifies an attribute value at a different device.
  4. 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):

  1. 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.
  2. Write Attributes No Response: This command is the same with "Write Attributes" with the only exception that a response frame is not required.
  3. Report Attributes: This command reports all attributes and their values.
  4. 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', '71FA') %#ok<*NOPTS>
readPayload = zigbee.GeneralFrameGenerator(readConfigTx);

% Read Attributes Response command:
readResponseConfigTx = zigbee.GeneralFrameConfig('CommandType', 'Read Attributes Response', ...
                            'AttributeID', '71FA', 'Status', 'Success', 'AttributeType', 'uint16', 'AttributeValue', 358)
readResponsePayload = zigbee.GeneralFrameGenerator(readResponseConfigTx);

% Write Attributes command:
writeConfigTx = zigbee.GeneralFrameConfig('CommandType', 'Write Attributes', 'AttributeID', '8DFA', 'AttributeValue', 17)
writePayload = zigbee.GeneralFrameGenerator(writeConfigTx);

% % Write Attributes Response command:
writeResponseConfigTx = zigbee.GeneralFrameConfig('CommandType', 'Write Attributes Response', 'Status', 'Not found')
writeResponsePayload = zigbee.GeneralFrameGenerator(writeResponseConfigTx);
readConfigTx = 

  GeneralFrameConfig with properties:

    CommandType: 'Read Attributes'
    AttributeID: '71FA'


readResponseConfigTx = 

  GeneralFrameConfig with properties:

       CommandType: 'Read Attributes Response'
       AttributeID: '71FA'
            Status: 'Success'
     AttributeType: 'uint16'
    AttributeValue: 358


writeConfigTx = 

  GeneralFrameConfig with properties:

       CommandType: 'Write Attributes'
       AttributeID: '8DFA'
     AttributeType: 'double'
    AttributeValue: 17


writeResponseConfigTx = 

  GeneralFrameConfig with properties:

    CommandType: 'Write Attributes Response'
    AttributeID: '0000'
         Status: 'Not found'

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 System Toolbox Support Package for USRP® radio.

% load captured payloads
load zigbeeGeneralCommandCaptures

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.

% Read Attributes :
readConfigRx = zigbee.GeneralFrameDecoder('Read Attributes', capturedReadPayload)

% Read Attributes Response:
readResponseRx = zigbee.GeneralFrameDecoder('Read Attributes Response', capturedReadResponsePayload)

% Default Response
defaultResponseRx = zigbee.GeneralFrameDecoder('Default Response', capturedDefaultResponsePayload)
readConfigRx = 

  GeneralFrameConfig with properties:

    CommandType: 'Read Attributes'
    AttributeID: '0000'


readResponseRx = 

  GeneralFrameConfig with properties:

       CommandType: 'Read Attributes Response'
       AttributeID: '0000'
            Status: 'Success'
     AttributeType: 'Boolean'
    AttributeValue: 1


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 (i.e., 'Write Attributes', 'Write Attributes Response').

% Write Attributes :
writeConfigRx = zigbee.GeneralFrameDecoder('Write Attributes', writePayload)

% Write Attributes Response:
writeResponseRx = zigbee.GeneralFrameDecoder('Write Attributes Response', writeResponsePayload)
writeConfigRx = 

  GeneralFrameConfig with properties:

       CommandType: 'Write Attributes'
       AttributeID: '8DFA'
     AttributeType: 'double'
    AttributeValue: 17


writeResponseRx = 

  GeneralFrameConfig with properties:

    CommandType: 'Write Attributes Response'
    AttributeID: '0000'
         Status: 'Not found'

Wireshark Decoding

The generated frames can be converted to a PCAP format, which can be analyzed and visualized with Wireshark [ 4 ]. This process can serve as an additional verification step advocating that the Communications System Toolbox Library for the ZigBee Protocol generates and decodes frames in a standard-compliant manner.

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

You can further explore the following generator and decoding functions, as well as the configuration object:

Selected Bibliography

  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/