1. Introduction
Rejoining in Zigbee® allows a device that has already joined a network to rejoin the same network. There are several types of Rejoining mentioned in the Zigbee Specification.
Type of Rejoin | Rejoin procedure | Prerequisites | Stack function call | Example use case |
---|---|---|---|---|
Rejoin while joined to a network | Secure Rejoin | NWK key is present | ZbStartupRejoin |
The device must establish a better parent |
Rejoin while joined to a network but the NWK key is missing or outdated | TC Rejoin | TCLK is present | ZbTrustCenterRejoin |
The device missed a NWK key update |
Rejoin while not joined to a network | TC Rejoin (suggested) or secure Rejoin | TCLK is present or NWK key is present | ZbStartup |
The device lost connection or left the network for a period of time |
Rejoin while not joined and without security | TC Rejoin | Preconfigured TCLK is present (the TC must allow this type of Rejoin) | ZbStartup |
The device lost both the NWK key and TCLK |
NLME-LEAVE.request with rejoin==true | Secure Rejoin (suggested) or TC Rejoin | NWK key is present or TCLK is present | ZbNlmeLeaveReq |
A device requests another device to leave and rejoin the network |
2. How to trigger Rejoin
2.1. Rejoin while joined to a network
This is the more basic type of Rejoin. It has the fewest configurations and the fewest air transmissions.
The device must already be connected to a network to call this function.
The device can rejoin using the function call ZbStartupRejoin
.
The prototype of the API is:
ZbStartupRejoin(struct ZigBeeT *zb, void (*callback)(struct ZbNlmeJoinConfT *conf, void *arg), void *cbarg)
2.2. Rejoin while joined to a network but the NWK key is missing or outdated
This type of Rejoin has one additional air transmission. It includes the transmission of a transport key command from TC to rejoining device, which contains the active NWK Key.
The transport key command is encrypted at the APS layer using the TCLK.
The transport key command is not encrypted at the NWK layer, as the receiving device does not yet have the active NWK key to decrypt.
The device can rejoin using the function call ZbTrustCenterRejoin
.
The prototype of the API is:
ZbTrustCenterRejoin(struct ZigBeeT *zb, void (*callback)(enum ZbStatusCodeT status, void *arg), void *cbarg)
2.3. Rejoin while not joined to a network
This type of Rejoin has several configurations. It requires setting parameter configPtr
for the ZbStartup
function.
In addition to the startup configurations, configPtr
should be set as follows:
startupControl
:ZbStartTypeRejoin
panId
: 16-bit PAN ID of the networkextendedPanId
: 64-bit extended PAN ID of the network
Then, depending on whether TC Rejoin or secure Rejoin is used:
Trust Center Rejoin (suggested)
security.trustCenterAddress
: 64-bit IEEE address of the network TC
or secure Rejoin
security.networkKey
: Byte-array containing the NWK key
The device can rejoin using the function call ZbStartup
.
The prototype of the API is:
ZbStartup(struct ZigBeeT *zb, struct ZbStartupT *configPtr, void (*callback)(enum ZbStatusCodeT status, void *cb_arg), void *arg)
2.3.1. Additional information
2.3.1.1. Obtaining the 64-bit IEEE address of the network TC
The 64-bit IEEE address of the network TC can be obtained during a time when the rejoining device was connected to the network. That is:
uint64_t rejoinTcAddress;
ZbApsGet(stZigbeeAppInfo.pstZigbee, ZB_APS_IB_ID_TRUST_CENTER_ADDRESS, &rejoinTcAddress, sizeof(rejoinTcAddress));
2.3.1.2. Obtaining the byte-array containing the NWK key
The byte-array containing the NWK key can be obtained during a time when the rejoining device was connected to the network.
That is:
struct ZbNwkSecMaterialT rejoinNwkSecMaterial;
ZbNwkGet(stZigbeeAppInfo.pstZigbee, ZB_NWK_NIB_ID_SecurityMaterialSet, &rejoinNwkSecMaterial, sizeof(rejoinNwkSecMaterial));
The NWK key is found in the field rejoinNwkSecMaterial.key
.
2.3.1.3. Obtaining and setting the TCLK for TC Rejoin
For a TC Rejoin, the TCLK must be set before function call ZbStartup
in the APS layer using ZbApsSetIndex
, if it does not persist. That is:
struct ZbApsmeKeyPairT rejoinKeyPair;
/* Set fields of rejoinKeyPair here, or copy the key from memory */
ZbApsSetIndex(stZigbeeAppInfo.pstZigbee, ZB_APS_IB_ID_DEVICE_KEY_PAIR_SET, &rejoinKeyPair, sizeof(rejoinKeyPair), 0);
The TCLK can be obtained during a time when the rejoining device was connected to the network. That is:
uint64_t rejoinTcAddress;
/* Set rejoinTcAddress here... */
struct ZbApsmeKeyPairT rejoinKeyPair;
unsigned int i;
struct ZbApsmeKeyPairT keyPair;
for (i = 0;; i++)
{
if (ZbApsGetIndex( stZigbeeAppInfo.pstZigbee, ZB_APS_IB_ID_DEVICE_KEY_PAIR_SET, keyPair, sizeof(*keyPair), i ) != ZB_NWK_STATUS_SUCCESS)
{
/* End of Key Pair Set */
break;
}
if ( keyPair->deviceAddress == rejoinTcAddress )
{
memcpy(rejoinKeyPair, keyPair, sizeof(rejoinKeyPair))
}
}
2.4. Rejoin while not joined and without security
This type of Rejoin requires minimal security. However, it can only be enabled by modifying the TC policy. Therefore, some changes must be made on the TC as well as the device.
The TC and device must disable TCLK exchange after joining.
uint8_t value = 0x00;
ZbBdbSet(stZigbeeAppInfo.pstZigbee, ZB_BDB_TrustCenterRequiresKeyExchange, &value, sizeof(value));
Additionally, the TC must modify its TC policy to allow Rejoin using the preconfigured TCLK.
uint32_t tcPolicy;
ZbApsGet(stZigbeeAppInfo.pstZigbee, ZB_APS_IB_ID_TRUST_CENTER_POLICY, &tcPolicy, sizeof(tcPolicy));
tcPolicy |= ZB_APSME_POLICY_ALLOW_REJOIN;
ZbApsSet(stZigbeeAppInfo.pstZigbee, ZB_APS_IB_ID_TRUST_CENTER_POLICY, &tcPolicy, sizeof(tcPolicy));
Then, parameter configPtr
must be set for the ZbStartup
function.
In addition to the startup configurations, configPtr
should be set as follows:
startupControl
:ZbStartTypeRejoin
panId
: 16-bit PAN ID of the networkextendedPanId
: 64-bit Extended PAN ID of the network
The device can rejoin using the function call ZbStartup
.
The prototype of the API is:
ZbStartup(struct ZigBeeT *zb, struct ZbStartupT *configPtr, void (*callback)(enum ZbStatusCodeT status, void *cb_arg), void *arg)
2.4.1. Additional information
2.4.1.1. Rejoining a network without having joined in the past
Rejoining a network without having joined in the past is possible using this Rejoin procedure, contrary to the definition of rejoining.
The rejoining device only need to have the correct preconfigured TCLK (usually ZigbeeAlliance09 Key).
2.5. NLME-LEAVE.request with rejoin==true
This type of rejoin is used when one device is requesting another device (or itself) to leave the network and rejoin using the NLME-LEAVE.request. It requires setting parameter leaveReqPtr
for the ZbNlmeLeaveReq
function.
The device issuing the NLME-LEAVE.request should set leaveReqPtr
as follows:
deviceAddr
: 64-bit IEEE address of the device to leave and rejoin the networkrejoin
:true
removeChildren
: Remove the children of the device
The device can issue a NLME-LEAVE.request using the function call ZbNlmeLeaveReq
.
The prototype of the API is:
ZbNlmeLeaveReq(struct ZigBeeT *zb, struct ZbNlmeLeaveReqT *leaveReqPtr, void (*callback)(struct ZbNlmeLeaveConfT *leaveConfPtr, void *arg), void *cbarg)
The device leaving and rejoining the network should be set to handle this message, using a message filter. It requires setting parameters mask
, prio
, and callback for the ZbMsgFilterRegister
function.
mask and prio should be set as follows:
mask
:ZB_MSG_FILTER_STACK_EVENT
prio
:ZB_MSG_INTERNAL_PRIO + 1
callback should be set to a callback function resembling the following:
enum zb_msg_filter_rc callback(struct ZigBeeT *zb, uint32_t id, void *msg, void *cbarg)
{
if (id == ZB_MSG_FILTER_STACK_EVENT) {
struct ZbMsgStackEventT *event = msg;
switch (event->type) {
case ZB_MSG_STACK_EVENT_ATTEMPT_REJOIN:
ZbStartupRejoin(zb, NULL, NULL); /* Could try other strategies here such as 3x Rejoin, then fallback on TC Rejoin if all fail */
return ZB_MSG_DISCARD;
default:
break;
}
}
return ZB_MSG_CONTINUE;
}
The device can register the message filter using the function call ZbMsgFilterRegister
.
The prototype of the API is:
ZbMsgFilterRegister(struct ZigBeeT *zb, uint32_t mask, uint8_t prio, enum zb_msg_filter_rc (*callback)(struct ZigBeeT *zb, uint32_t id, void *msg, void *cbarg), void *arg);
3. Information on keys
3.1. Link key
A link key is a key shared between two devices, used to encrypt APS messages.
3.2. TCLK
A TCLK is a link key shared between a device and a Trust Center.
3.3. Preconfigured TCLK
A preconfigured TCLK is a TCLK that is known at boot. It is used prior to negotiating a new TCLK (unless TCLK negotiation is disabled at the TC). The most common preconfigured TCLK used is the ZigbeeAlliance09 Key.
3.4. NWK key
A NWK key is a key shared between all devices on a network, used to encrypt NWK messages.
4. Acronyms and definitions
Term | Definition |
---|---|
APS | Application support sublayer |
NWK | Network |
TC | Trust Center |
TCLK | Trust Center link key |