ZigBee Home Automation Frame Generation and Decoding
This example shows how to generate and decode application-layer frames for the Home Automation application profile [ 1 ] of the ZigBee® specification [ 2 ] using the Communications Toolbox™.
Background
The ZigBee standard [ 2 ] specifies the network (NET or NWK) and application (APP or APL) layers for low-rate wireless personal area networks. These NET- and APP-layer specifications build upon the PHY and MAC specifications of IEEE® 802.15.4™ [ 3 ]. 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 sublayer follows a format that is common for all application profiles and ZigBee clusters (see Clause 2.2.5 in [ 2 ]). The ZCL header follows a format that is common for all clusters (see Clause 2.4 in [ 4 ]). The ZCL payload is used only by some clusters and it follows a cluster-specific format.
Clusters and Frame Captures
Out of all the clusters used in the Home Automation application profile, this example decodes and generates frames for: (i) the On/Off cluster (used by light devices), and (ii) the intruder alarm system (IAS) zone cluster (used by motion sensors) [ 4 ]. The On/Off cluster does not make use of a ZCL payload, but the IAS zone cluster does.
Frames of these clusters have been captured from commercial ZigBee radios enabling home automation, using a USRP® B200-mini radio and the Communications Toolbox Support Package for USRP® radio. ZigBee can employ security either at the network or the application layer. The captured frames employed security at the network layer and were later on decrypted. This example decodes the application layer of the decrypted NET-layer payloads.
load zigbeeAPPCaptures
Decoding APS Frames of Home Automation ZigBee Radios
A zigbee.APSFrameConfig
configuration object is used both in generating and decoding ZigBee APS frames. Such objects describe a APS-layer frame and specify its frame type and all applicable properties. The zigbee.APSFrameDecoder
function accepts a APS protocol data unit (APDU) in bytes and outputs a zigbee.APSFrameConfig
object describing the frame and possibly a ZCL frame in bytes. Clause 2.2.5.1 in [ 2 ] describes the APS frame formats.
Next, the APS sublayer of a captured IAS zone frame is decoded:
[apsConfig,apsPayload] = zigbee.APSFrameDecoder(motionDetectedFrame); apsConfig
apsConfig = APSFrameConfig with properties: FrameType: 'Data' APSCounter: 230 AcknowledgmentRequest: 1 Addressing: DeliveryMode: 'Unicast' DestinationEndpoint: '01' ClusterID: '0500' ProfileID: '0104' SourceEndpoint: '01' Extended header: ExtendedHeader: 0 Security: Security: 0
Decoding ZCL Header of Home Automation ZigBee Radios
A zigbee.ZCLFrameConfig
configuration object is used both in generating and decoding ZigBee ZCL headers. Such objects describe a ZCL-layer frame and specify its frame type and all applicable properties.
The zigbee.ZCLFrameDecoder
function accepts a ZCL frame in bytes and outputs a zigbee.ZCLFrameConfig
object describing the header and possibly a ZCL payload in bytes. Clause 2.4.1 in [ 4 ] describes the ZCL header frame formats. Note that the ZCL header may either specify a 'Library-wide' or a 'Cluster-specific' command type. In the latter case, the zigbee.ZCLFrameDecoder
also needs the cluster ID, which is present in the APS header, in order to decode the cluster-specific command ID into a command type. For example, the next command decodes the ZCL header of a captured IAS zone frame.
[zclConfig,zclPayload] = zigbee.ZCLFrameDecoder( ... apsPayload, ... apsConfig.ClusterID); zclConfig
zclConfig = ZCLFrameConfig with properties: FrameType: 'Cluster-specific' CommandType: 'Zone Status Change Notification' SequenceNumber: 9 ManufacturerCommand: 0 Direction: 'Downlink' DisableDefaultResponse: 0
Decoding ZCL Payload of IAS Zone Frame from ZigBee Radio
In contrast to the On/Off cluster, the IAS zone cluster specifies a ZCL payload in addition to the ZCL header. A zigbee.IASZoneFrameConfig
configuration object is used both in generating and decoding IAS zone ZCL payloads. Such objects describe an IAS zone payload and all applicable properties. The zigbee.IASZoneFrameDecoder
function accepts an IAS zone payload in bytes and outputs a zigbee.IASZoneFrameConfig
object describing the IAS zone payload.
iasZoneConfig = zigbee.IASZoneFrameDecoder(zclPayload)
iasZoneConfig = IASZoneFrameConfig with properties: CommandType: 'Zone Status Change Notification' ZoneID: 0 Alarm1: 'Not alarmed' Alarm2: 'Alarmed' Tampered: 0 LowBattery: 0 PeriodicReports: 0 RestoreReports: 1 Trouble: 0 ACFault: 0 BatteryDefect: 0 TestMode: 0 Delay: 0
Decoding Motion-Triggered Lighting Automation of ZigBee Radios
A lighting automation has been established for the commercial home-automation ZigBee radios whose frames have been captured and decoded. Specifically, once a motion sensor detects motion, it sends a signal to the ZigBee hub, which in turn sends a signal to a light bulb so that it turns on. When the motion sensor detects that the motion has stopped (e.g., after 10 seconds without motion) it sends a signal to the ZigBee hub, which in turn wirelessly triggers the light bulb to turn off. The following video illustrates the lighting automation.
helperPlaybackVideo('LightingAutomation.mp4',2/5);
The following code decodes the actual frames transmitted between the ZigBee radios. These were captured with a USRP® device (also shown in the video).
apsFrames = ... {motionDetectedFrame; turnOnFrame; motionStoppedFrame; turnOffFrame}; for idx = 1:length(apsFrames) % APS decoding: [apsConfig,apsPayload] = zigbee.APSFrameDecoder(apsFrames{idx}); % ZCL header decoding: [zclConfig,zclPayload] = zigbee.ZCLFrameDecoder(apsPayload, ... apsConfig.ClusterID); zclConfig % On-off cluster (does not have ZCL payload) onOffClusterID = '0006'; if strcmp(apsConfig.ClusterID,onOffClusterID) fprintf(['Turn light bulb ' lower(zclConfig.CommandType) '.\n']); end % IAS zone cluster has ZCL payload: iasZoneClusterID = '0500'; if ~isempty(zclPayload) && strcmp(apsConfig.ClusterID,iasZoneClusterID) iasConfig = zigbee.IASZoneFrameDecoder(zclPayload) if any(strcmp('Alarmed',{iasConfig.Alarm1,iasConfig.Alarm2})) fprintf('Motion detected.\n'); else fprintf('Motion stopped.\n'); end end end
zclConfig = ZCLFrameConfig with properties: FrameType: 'Cluster-specific' CommandType: 'Zone Status Change Notification' SequenceNumber: 9 ManufacturerCommand: 0 Direction: 'Downlink' DisableDefaultResponse: 0 iasConfig = IASZoneFrameConfig with properties: CommandType: 'Zone Status Change Notification' ZoneID: 0 Alarm1: 'Not alarmed' Alarm2: 'Alarmed' Tampered: 0 LowBattery: 0 PeriodicReports: 0 RestoreReports: 1 Trouble: 0 ACFault: 0 BatteryDefect: 0 TestMode: 0 Delay: 0 Motion detected. zclConfig = ZCLFrameConfig with properties: FrameType: 'Cluster-specific' CommandType: 'On' SequenceNumber: 64 ManufacturerCommand: 0 Direction: 'Uplink' DisableDefaultResponse: 0 Turn light bulb on. zclConfig = ZCLFrameConfig with properties: FrameType: 'Cluster-specific' CommandType: 'Zone Status Change Notification' SequenceNumber: 10 ManufacturerCommand: 0 Direction: 'Downlink' DisableDefaultResponse: 0 iasConfig = IASZoneFrameConfig with properties: CommandType: 'Zone Status Change Notification' ZoneID: 0 Alarm1: 'Not alarmed' Alarm2: 'Not alarmed' Tampered: 0 LowBattery: 0 PeriodicReports: 0 RestoreReports: 1 Trouble: 0 ACFault: 0 BatteryDefect: 0 TestMode: 0 Delay: 0 Motion stopped. zclConfig = ZCLFrameConfig with properties: FrameType: 'Cluster-specific' CommandType: 'Off' SequenceNumber: 70 ManufacturerCommand: 0 Direction: 'Uplink' DisableDefaultResponse: 0 Turn light bulb off.
Generating IAS Zone ZCL Payloads
The zigbee.IASZoneFrameGenerator
function accepts a zigbee.IASZoneFrameConfig
object describing the IAS zone payload and outputs the payload in bytes. The following code creates two ZCL payloads for this cluster indicating that intrusion has or has not been detected.
iasConfigIntrusion = zigbee.IASZoneFrameConfig('Alarm2','Alarmed'); zclPayloadIntrusion = zigbee.IASZoneFrameGenerator(iasConfigIntrusion); iasConfigNoIntrusion = zigbee.IASZoneFrameConfig('Alarm2','Not alarmed'); zclPayloadNoIntrusion = zigbee.IASZoneFrameGenerator(iasConfigNoIntrusion);
Generating ZCL Frames
The zigbee.ZCLFrameGenerator
function accepts a zigbee.ZCLFrameConfig
object describing the frame, and optionally a ZCL payload in bytes (two-characters), and outputs the ZCL frame in bytes. The following code generates ZCL frames for the On/Off cluster (no payload) and the IAS zone cluster (payload needed).
% IAS Zone Cluster zclConfigIntrusion = zigbee.ZCLFrameConfig( ... 'FrameType','Cluster-specific', ... 'CommandType','Zone Status Change Notification', ... 'SequenceNumber',1,'Direction','Downlink'); zclFrameIntrusion = zigbee.ZCLFrameGenerator(zclConfigIntrusion, ... zclPayloadIntrusion); % On/Off Cluster zclConfigOn = zigbee.ZCLFrameConfig( ... 'FrameType','Cluster-specific', ... 'CommandType','On', ... 'SequenceNumber',2,'Direction','Uplink'); zclFrameOn = zigbee.ZCLFrameGenerator(zclConfigOn);
Generating APS Frames
The zigbee.APSFrameGenerator
function accepts a zigbee.APSFrameConfig
object describing the frame, and optionally a APS payload (ZCL-layer frame) in bytes (two-characters), and outputs the APS frame in bytes. The following code illustrates how to generate APS frames for the ZCL frames created in the previous section.
% IAS Zone Cluster apsConfigIntrusion = zigbee.APSFrameConfig( ... 'FrameType','Data', ... 'ClusterID',iasZoneClusterID, ... 'ProfileID',zigbee.profileID('Home Automation'), ... 'APSCounter',1, ... 'AcknowledgmentRequest',true); apsFrameIntrusion = zigbee.APSFrameGenerator(apsConfigIntrusion, ... zclFrameIntrusion); % On/Off cluster apsConfigOn = zigbee.APSFrameConfig('FrameType','Data', ... 'ClusterID',onOffClusterID, ... 'ProfileID',zigbee.profileID('Home Automation'), ... 'APSCounter',2, ... 'AcknowledgmentRequest',true); apsFrameOn = zigbee.APSFrameGenerator(apsConfigOn,zclFrameOn);
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.APSFrameConfig
,zigbee.APSFrameGenerator
,zigbee.APSFrameDecoder
zigbee.ZCLFrameConfig
,zigbee.ZCLFrameGenerator
,zigbee.ZCLFrameDecoder
zigbee.IASZoneFrameConfig
,zigbee.IASZoneFrameGenerator
,zigbee.IASZoneFrameDecoder
Selected Bibliography
ZigBee Alliance, ZigBee Home Automation Public Application Profile, revision 29, v. 1.2, Jun. 2013.
ZigBee Alliance, ZigBee Specification Document 053474r17, 2007
IEEE 802.15.4-2011 - IEEE Standard for Local and Metropolitan Area Networks--Part 15.4: Low-Rate Wireless Personal Area Networks (LR-WPANs)
ZigBee Alliance, ZigBee Cluster Library Specification, Revision 6, Jan. 2016.