9. Miscellaneous
9.1 Configuring channel
Every Z3.0 device has a primary channel mask configuration (BDB_DEFAULT_PRIMARY_CHANNEL_SET) and a secondary channel mask configuration (BDB_DEFAULT_SECONDARY_CHANNEL_SET). For devices with formation capabilities that were instructed to create a network, these channels masks are used when scanning for a channel with the least amount of noise to create the network on. For devices with joining capabilities that were instructed to join a network, these channel masks are used when scanning for existing networks to join. The device will try first with all the channels defined in the primary channel mask and then if the process is not successful (the network were not created or no network to join was found) the secondary channel mask is used. These two channel masks can be configured by the application as needed. A value of 0 in one of these masks will disable the respective channel scanning phase (primary or secondary). The primary channel mask is defined by default to be equal to DEFAULT_CHANLIST (in f8wConfig.cfg), while the secondary channel mask is defined as all the other channels (i.e. DEFAULT_CHANLIST ^ 0x07FFF800). Section 15 provides more details on the commissioning methods.
9.2 Configuring the PAN ID and network to join
This is an optional configuration item to control which network a ZigBee Router or End Device will join. It can also be used to pre-set the PAN ID of a new network to be created by a coordinator or a router. The ZDO_CONFIG_PAN_ID parameter in f8wConfig.cfg can be set to a value (between 1 and 0xFFFE). A coordinator or a network-forming router will use this value as the PAN ID of the network when instructed to create a network. A joining router or end device will only join a network that has a PAN ID that matches the value of this parameter. To turn this feature off, set the parameter to a value of 0xFFFF. In this case, a newly created network will have a random PAN ID, and a joining device will be able to join any network regardless of its PAN ID.
The network discovery process is managed by the Network Steering commissioning process, which is explained 15.5. It allows filtering of the discovered networks, by registering a callback with the function bdb_RegisterForFilterNwkDescCB(), to which the application receives a list of network descriptors of the networks found on each scan attempt (primary channels first and then another call for secondary channel if performed). The application may skip attempting to join specific networks by freeing the network descriptors using bdb_nwkDescFree(). For details on these API refer to [1].
For further control of the joining procedure, the ZDO_NetworkDiscoveryConfirmCB function in the ZDApp.c should be modified. ZDO_NetworkDiscoveryConfirmCB() is called when the network layer has finished with the Network Discovery process, started by calling NLME_NetworkDiscoveryRequest(), detailed in the Z-Stack API [1] document.
9.3 Maximum payload size
The maximum payload size for an application is based on several factors. The MAC layer provides a constant payload length of 116 (can be changed in f8wConfig.cfg – MAC_MAX_FRAME_SIZE). The NWK layer requires a fixed header size, one size with security and one without security. The APS layer has a required, but variable, header size based on a variety of settings, including the ZigBee Protocol Version, APS frame control settings, etc. Ultimately, the user does not have to calculate the maximum payload size using the aforementioned factors. The AF module provides an API that allows the user to query the stack for the maximum payload size, or the maximum transport unit (MTU). The user can call the function, afDataReqMTU() (see AF.h) which will return the MTU, or maximum payload size.
typedef struct
{
uint8 kvp;
APSDE_DataReqMTU_t aps;
} afDataReqMTU_t;
uint8 afDataReqMTU( afDataReqMTU_t* fields )
Currently the only field that should be set in the afDataReqMTU_t structure is kvp, which indicates whether KVP is being used and this field should be set to FALSE. The aps field is reserved for future use.
9.4 Leave Network
The ZDO Management implements the function ZDO_ProcessMgmtLeaveReq(), which provides access to the “NLME-LEAVE.request” primitive. “NLME-LEAVE.request” allows a device to remove itself or remove a remote device from the network. The ZDO_ProcessMgmtLeaveReq() removes the device based on the provided IEEE address. When a device removes itself, it will wait for LEAVE_RESET_DELAY (5 seconds by default) and then reset. When a device removes a child device, it also removes the device from the local “association table”. The NWK address will only be reused in the case where a child device is a ZigBee End Device. In the case of a child ZigBee Router, the NWK address will not be reused
If the parent of a child device leaves the network, the child will stay on the network.
In version R21 of the ZigBee PRO specification, processing of “NWK Leave Request” is configurable for Routers. The application controls this feature by setting the zgNwkLeaveRequestAllowed variable to TRUE (default value) or FALSE, to allow/disallow a Router to leave the network when a “NWK Leave Request” is received. zgNwkLeaveRequestAllowed is defined and initialized in ZGlobals.c, and the corresponding NV item, ZCD_NV_NWK_LEAVE_REQ_ALLOWED, is defined in ZComDef.h. Processing of these commands depending on the logical device type has also changed: Coordinators do not process leave commands, Router devices process leave commands from any device in the network (if allowed as mentioned above), and end devices only process leave commands from their parent device.
In the base device behavior specification is also stated that if any device receives a valid leave request with rejoin set to FALSE (meaning that this device shall not rejoin the network), then that device is forced to perform a Factory New reset. In this case, Z-Stack clears all the ZigBee persistent data, while it is up to the application to clear the relevant application data from Nv.
9.5 Descriptors
All devices in a ZigBee network have descriptors that describe the type of device and its applications. This information is available to be discovered by other devices in the network.
Configuration items are setup and defined in ZDConfig.c and ZDConfig.h. These 2 files also contain the Node, Power Descriptors and default User Descriptor. Make sure to change these descriptors to define your device.
9.6 Non-Volatile Memory Items
9.6.1 Global Configuration Non-Volatile Memory
Global device configuration items are stored in ZGlobal.c. This includes items such as PAN ID, key information, network settings, etc.. The default values for most of these items are specified in f8wConfig.cfg. These items are loaded to RAM at startup for quick accessed during Z-Stack operation. To initialize the non-volatile memory area to store these items, the compile flag NV_INIT must be enabled in your project (it is enabled by default in the sample applications).
9.6.2 Network Layer Non-Volatile Memory
A ZigBee device has lots of state information that needs to be stored in non-volatile memory so that it can be recovered in case of an accidental reset or power loss. Otherwise, it will not be able to rejoin the network or function effectively.
This feature is enabled by default by the inclusion of the NV_RESTORE compile option. Note that this feature must be always enabled in a real ZigBee network. The ability to disable it off is only intended to be used in the development stage.
The ZDO layer is responsible for the saving and restoring of the Network Layer’s vital information, but it is the BDB layer which will define when to retrieve this information or when to clear and start as “factory new” device. This includes the Network Information Base (NIB - Attributes required to manage the network layer of the device);
the list of child and parent devices, and the table containing the application bindings. This is also used for security to store frame counters and keys.
If the device is not meant to be set to its factory new state, the device will then use this information to restore the device in the network if the device is reset by any mean.
Upon initializing, the BDB layer will check the attribute bdbNodeIsOnANetwork to know if this device was commissioned to a network. If it was commissioned to a network and it was also instructed to resume operations in the same network then the BDB layer will call ZDOInitDeviceEx(), which will handle the resume operation according to the state and the logical device type.
9.6.3 Application Non-Volatile Memory
In general, a device must have non-volatile memory enabled to be certified, because it must remember its network configuration. In addition to the stack ‘internal’ data, the NVM can also be used to store application data.
To save a variable to NVM, an item ID must be created for that variable. IDs reserved for applications range from 0x0401 to 0x0FFF. For a complete list of these IDs, refer to the ZComDef.h file.
Once the item ID is selected, the item must be initialized using osal_nv_item_init(). This function receives the item ID, length of the variable to be stored, and an initial value.
To write an item to NVM, use osal_nv_write(). This function receives the item ID, the index offset into an item, the length of data to write, and the variable to write.
To read the item from NVM, use osal_nv_read(). This function receives the item ID, the index offset into an item, length of data to read, and the variable to read the data to.
These functions can be found in the OSAL_Nv.c file.
9.7 Asynchronous Links
An asynchronous link occurs when a node can receive packets from another node but it can’t send packets to that node. Whenever this happens, this link is not a good link to route packets.
In ZigBee PRO, this problem is overcome by the use of the Network Link Status message. Every router in a ZigBee PRO network sends a periodic Link Status message. This message is a one hop broadcast message that contains the sending device’s neighbor list. The idea is this – if you receive your neighbor’s Link Status and you are either missing from the neighbor list or your receive cost is too low (in the list), you can assume that the link between you and this neighbor is an asynchronous link and you should not use it for routing.
To change the time between Link Status messages you can change the compile flag NWK_LINK_STATUS_PERIOD, which is used to initialize _NIB.nwkLinkStatusPeriod. You can also change _NIB.nwkLinkStatusPeriod directly. Remember that only PRO routers send the link status message and that every router in the network must have the same Link Status time period.
_NIB.nwkLinkStatusPeriod contains the number of seconds between Link Status messages.
Another parameter that affects the Link Status message is _NIB.nwkRouterAgeLimit (defaulted to NWK_ROUTE_AGE_LIMIT). This represents the number of Link Status periods that a router can remain in a device’s neighbor list, without receiving a Link Status from that device, before it becomes aged out of the list. If we haven’t received a Link Status message from a neighbor within (_NIB.nwkRouterAgeLimit * _NIB.nwkLinkStatusPeriod), we will age the neighbor out and assume that this device is missing or that it’s an asynchronous link and not use it.
9.8 Multicast Messages
This feature is a ZigBee PRO only feature (must have ZIGBEEPRO as a compile flag). This feature is similar to sending to an APS Group, but at the network layer.
A multicast message is sent from a device to a group as a MAC broadcast message. The receiving device will determine if it is part of that group: if it isn’t part of the group, it will decrement the non-member radius and rebroadcast; if it is part of the group it will first restore the group radius and then rebroadcast the message. If the radius is decremented to 0, the message isn’t rebroadcast.
The difference between multicast and APS group messages can only be seen in very large networks where the non-member radius will limit the number of hops away from the group.
_NIB.nwkUseMultiCast is used by the network layer to enable multicast (default is TRUE if ZIGBEEPRO defined) for all Group messages, and if this field is FALSE the APS Group message is sent as a normal broadcast network message.
zgApsNonMemberRadius is the value of the group radius and the non-member radius. This variable should be controlled by the application to control the broadcast distribution. If this number is too high, the effect will be the same as an APS group message. This variable is defined in ZGlobals.c and ZCD_NV_APS_NONMEMBER_RADIUS (defined in ZComDef.h) is the NV item.
9.9 Fragmentation
Message Fragmentation is a process where a large message – too large to send in one APS packet – is broken down and transmitted as smaller fragments. The fragments of the larger message are then reassembled by the receiving device.
To turn on the APS Fragmentation feature in your Z-Stack project include the ZIGBEE_FRAGMENTATION compile flag. By default, all projects where ZIGBEEPRO is defined include fragmentation and there is no need to add the ZIGBEE_FRAGMENTATION compile flag. All applications using fragmentation will include the APS Fragmentation task APSF_Init() and APSF_ProcessEvent(). If you have an existing application, make sure the code in the OSAL_xxx.c of your application has included the header file:
#if defined ( ZIGBEE_FRAGMENTATION )
#include "aps_frag.h"
#endif
And in tasksArr[] there is an entry for APSF_ProcessEvent(), like in the example below:
const pTaskEventHandlerFn tasksArr[] = {
macEventLoop,
nwk_event_loop,
#if (ZG_BUILD_RTR_TYPE)
gp_event_loop,
#endif
Hal_ProcessEvent,
#if defined( MT_TASK )
MT_ProcessEvent,
#endif
APS_event_loop,
#if defined ( ZIGBEE_FRAGMENTATION )
APSF_ProcessEvent,
#endif
ZDApp_event_loop,
#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )
Z-Stack 3.0 Developer's Guide Version 1.14
Copyright 2006-2016 Texas Instruments, In 23 c. All rights reserved.
ZDNwkMgr_event_loop,
#endif
zcl_event_loop,
bdb_event_loop,
xxx_ProcessEvent /* Where xxx is your application’s name */
};
And osalInitTasks() function calls APSF_Init(), like in the code below;
void osalInitTasks( void )
{
uint8 taskID = 0;
tasksEvents = (uint16 *)osal_mem_alloc( sizeof( uint16 ) * tasksCnt);
osal_memset( tasksEvents, 0, (sizeof( uint16 ) * tasksCnt));
macTaskInit( taskID++ );
nwk_init( taskID++ );
#if (ZG_BUILD_RTR_TYPE)
gp_Init( taskID++ );
#endif
Hal_Init( taskID++ );
#if defined( MT_TASK )
MT_TaskInit( taskID++ );
#endif
APS_Init( taskID++ );
#if defined ( ZIGBEE_FRAGMENTATION )
APSF_Init( taskID++ );
#endif
ZDApp_Init( taskID++ );
#if defined ( ZIGBEE_FREQ_AGILITY ) || defined ( ZIGBEE_PANID_CONFLICT )
ZDNwkMgr_Init( taskID++ );
#endif
zcl_Init( taskID++ );
bdb_Init( taskID++ );
xxx_Init( taskID ); /* Where xxx is your application’s name */
}
When APS Fragmentation is turned on, sending a data request with a payload larger than a normal data request payload will automatically trigger fragmentation.
Fragmentation parameters are in the structure afAPSF_Config_t, which is part of the Endpoint Descriptor list epList_t defined in AF.h, default values for these parameters are used when calling afRegister(), to register the Application’s Endpoint Descriptor, which in turn calls afRegisterExtended(), the default values APSF_DEFAULT_WINDOW_SIZE and APSF_DEFAULT_INTERFRAME_DELAY are defined in ZGlobals.h:
APSF_DEFAULT_WINDOW_SIZE - The size of a Tx window when using fragmentation. This is the number of fragments that are sent before an APS Fragmentation ACK is expected. So, if the message is broken up into 10 fragments and the max window size is 5, then an ACK will be sent by the receiving device after 5 fragments are received. If one packet of the window size isn’t received, the ACK is not sent and all the packets (within that window) are resent.
APSF_DEFAULT_INTERFRAME_DELAY – The delay between fragments within a window. This is used by the sending device.
These values can be read and set by the application by calling afAPSF_ConfigGet() and afAPSF_ConfigSet() respectively.
It is recommended that the application/profile update the MaxInTransferSize and MaxOutTransferSize of the ZDO Node Descriptor for the device, ZDConfig_UpdateNodeDescriptor() in ZDConfig.c. These fields are initialized with MAX_TRANSFER_SIZE (defined in ZDConfig.h). These values are not used in the APS layer as maximums, they are information only.
9.9.1 Quick Reference
Compile flag to activate the feature
ZIGBEE_FRAGMENTATION
Maximum fragments in a window default value
APSF_DEFAULT_WINDOW_SIZE (defined in ZGlobals.h)
Interframe delay default value
APSF_DEFAULT_INTERFRAME_DELAY (defined in ZGlobals.h)
Application/Profile maximum buffer size
MAX_TRANSFER_SIZE (defined in ZDConfig.h)
9.10 Extended PAN IDs
There are two Extended PAN IDs used in the Z-Stack:
zgApsUseExtendedPANID: This is the 64-bit PAN identifier of the network to join or form. This corresponds to the ZCD_NV_APS_USE_EXT_PANID NV item.
zgExtendedPANID: This is the 64-bit extended PAN ID of the network to which the device is joined. If it has a value of 0x0000000000000000, then the device is not connected to a network. This corresponds to the ZCD_NV_EXTENDED_PAN_ID NV item.
If the device has formation capabilities and is instructed to form a network, then it will form a network using zgApsUseExtendedPANID if zgApsUseExtendedPANID has a non-zero value. If zgApsUseExtendedPANID is 0x0000000000000000, then the device will use its 64-bit Extended Address to form the network.
9.11 Rejoining with Pre-Commissioned Network parameters
In previous ZigBee stacks, it was possible for a rejoining device to use a pre-configured network address. As of today, the Base Device Behavior specification has not addressed this topic (whether this is allowed or not). TI encourages the use of the Base Device Behavior commissioning methods described in the section 15 for rejoining the network.
.
9.12 Child management
R21 (revision 21 of the ZigBee specification, AKA ZigBee 2015), has introduced a child management feature that is meant to allow end device mobility while allowing parent devices to purge its tables from end devices which are no longer their children. When an end device joins/rejoins it will send an EndDeviceTimeout nwk command, which tells its parent device a time period after which it can remove it from its association table, if the device has not sent a keep-alive message. The parent device will answer this network command with a response stating which methods it supports for receiving the keep-alive messages. At the moment of this release only one keep-alive method is specified, which uses the standard MAC polling. If a legacy device joins an R21 or later parent device, the parent will assign a default timeout to expire this device if this legacy device fails to poll in a timely manner. Additionally if a parent device is polled by an end device which is not its child (due to being expired or not being its child at all),then the parent device must request this end device to leave the network with rejoin set to TRUE, so this device can rejoin the network and find a new parent (which could be the same router or another one).
9.12.1 Configuring child management for parent device
A default end device timeout (for both legacy and R21 end devices) can be defined in the parent device by modifying NWK_END_DEV_TIMEOUT_DEFAULT. This timeout will be overwritten by joining devices if they state their own timeout using the EndDeviceTimeout command.
Parent devices must keep track of devices that should be sent a leave request, due to being expired or end devices polling this parent due to unknown reasons. To do this, parent device must queue a leave request in the mac layer. The number of devices that can be keep track of at the same time is defined by MAX_NOT_MYCHILD_DEVICES. These devices will be tracked for a period of time defined by NWK_END_DEVICE_LEAVE_TIMEOUT. All these parameters are defined in ZGlobals.h.
9.12.2 Configuring child management for child devices
The timeout that the child device will indicate to the parent device is defined by END_DEV_TIMEOUT_VALUE and it is suggested to be at least 3 times greater than the MAC polling time to avoid being expired if there is interference when the end device is polling.
9.12.3 Parent Annce
The child management functionality includes the usage of Parent Annce ZDO message which is broadcasted by parent devices and contains the 64-bit IEEE address of all end devices in the parent’s association table. This message is send only when forming a network or being reset, after 10 seconds plus a random jitter of up to 10 seconds. If this message is receive by a different parent device, it will check if any of the reported children is also listed in its association table. If any match is found then this parent device will reply to the originator of the message, indicating which children are no longer its children. The usage of this message can be illustrated with the following example:
1) Parent device ‘A’ has a child device ‘c’.
2) Parent device ‘A’ is power cycled.
3) Child device ‘c’ finds parent device ‘B’ and joins it.
4) When parent device ‘A’ restores its network parameters, it starts a timer to send parent annce (of 10 seconds plus random jitter of up to 10 seconds.)
5) After the timeout parent ‘A’ device broadcasts parent annce containing IEEE address of child ‘c’.
6) Parent device ‘B’ finds a match with its children and responds with a parent annce response containing the IEEE address of child ‘c’.
7) Parent device removes child ‘c’ from its table.