STM32WBA Zigbee® Multi-hop

1. Introduction

In Zigbee®, there are several layers in the stack, each with its own responsibilities. From highest to lowest there is ZCL, APS, NWK, MAC, and PHY. As a packet moves down the stack, each layer appends its header and/or trailer. The ZCL Layer has the smallest packet size being the highest layer. The PHY Layer has the largest packet size being the lowest layer. The ZCL Layer is the most familiar to the user as its packets are commands such as a Toggle Command defined in the ZCL Specification in order to toggle a light (or other) connected to a server within the Zigbee Network. The PHY Layer is the least familiar to the user as it is the final packet form to be transmitted on-air. The packet structure is nested as shown in the following diagram.

Connectivity zigbee packet structure.png

Multi-hop in Zigbee is a key feature that enables Mesh Networking. In Zigbee, Multi-hop is handled at the NWK Layer. Consequently, any Zigbee packet must follow the Multi-hop path below to arrive at its destination in the simplest use case, which includes three devices: one Source Node (Device A), one Relay Node (Device B), and one Destination Node (Device C).

Connectivity multihop.png

2. Zigbee routing mechanisms

In Zigbee, there are three routing mechanisms: Table Routing, Source Routing, and Broadcast Routing (Multicast Routing is deprecated). The appropriate routing mechanism is chosen internally by the stack based on the following points:

  1. If the Destination Address is a broadcast address, use Broadcast Routing.
  2. Else, if Source Routing is available, use Source Routing.
  3. Else, if Table Routing is available, use Table Routing.
  4. If none of the above apply, try sending directly.

2.1. Table Routing

Table Routing is used when a packet has a Destination Address that is not a Broadcast Address (Unicast or Group Address), and when a Route Entry can be found in the Route Table of the Source Node. The route (list of addresses) followed by the packet is not known in advance of the first transmission. Each node contributes the Next Address in the route by searching its Route Table. Each Route Entry in the Route Table contains a Next Address (nextAddr), and Destination Address (dstAddr).​ The Route Table is automatically populated by the Route Discovery Procedure. See the Zigbee Specification "Initiation of Route Discovery" for more details.

In the following diagram, the packet follows the logic explained below:

  1. The packet starts at the Source Node with address 0x0001.
  2. The Route Table provides the Next Address 0x0002 to get to the Destination Node with address 0x0005.
  3. The packet is transmitted from the Source Node with address 0x0001 to Relay Node with address 0x0002.
  4. The Route Table provides the Next Address 0x0004 to get to the Destination Node with address 0x0005.
  5. The packet is transmitted from Relay Node with address 0x0002 to Relay Node with address 0x0004.
  6. The Route Table provides the Next Address 0x0005 to get to the Destination Node with address 0x0005.
  7. The packet is transmitted from Relay Node with address 0x0004 to the Destination Node with address 0x0005.
  8. The packet finishes at the Destination Node with address 0x0005.
Connectivity table routing.png

2.2. Source Routing

Source Routing is used when a packet has a Destination Address that is not a Broadcast Address (Unicast or Group Address), and when a Route Record can be found in the Route Record Table of the Source Node. This routing mechanism takes precedence over Table Routing. The route (list of addresses) followed by the packet is known in advance of the first transmission. The Source Node constructs a Source Route by searching its Route Record Table and copies the Source Route into the NWK Header of the packet. The NWK Header contains a Source Route (srcRoute) with attributes: Relay List (relayList), Relay Index (relayIndex), and Relay Count (relayCount). It also contains a Destination Address (dstAddr). The Relay List is a list of Next Addresses in reverse chronological order. The Relay Index is initialized as relayCount-1 and is decremented after each reception (if relayCount>0). The Relay Count is initialized as the size of the Relay List. The Route Record Table is automatically populated by the Route Discovery Procedure with Many-to-One (only Concentrators issue Route Discovery Procedures with Many-to-One periodically).

In the following diagram, the packet follows the logic explained below:

  1. The packet starts at the Source Node with address 0x0001. In the NWK Header, relayIndex==1.
  2. The NWK Header srcRoute provides the Next Address relayList[relayIndex]==0x0002.
  3. The packet is transmitted from the Source Node with address 0x0001 to Relay Node with address 0x0002.
  4. The NWK Header srcRoute provides the relayIndex. Since relayIndex!=0, therefore it is decremented. Now, in the NWK Header, relayIndex==0.
  5. The NWK Header srcRoute provides the Next Address relayList[relayIndex]==0x0004.
  6. The packet is transmitted from Relay Node with address 0x0002 to Relay Node with address 0x0004.
  7. The NWK Header srcRoute provides the relayIndex. Since relayIndex==0, therefore the Next Address is the Destination Address.
  8. The NWK Header srcRoute provides the Destination Address dstAddr==0x0005.
  9. The packet is transmitted from Relay Node with address 0x0004to the Destination Node with address 0x0005.
  10. The packet finishes at the Destination Node with address 0x0005.
Connectivity source routing.png

2.3. Broadcast Routing

Broadcast Routing is used when a packet has a Destination Address that is a Broadcast Address. The packet is re-transmitted by any receiving Router or Coordinator maximum of nwkMaxBroadcastRetries times (three times by default).

3. Printing and manually modifying the Route Table

3.1. Printing the Route Table

In order to print the Route Table, a developer may call a function resembling the following:

void printRouteTable( struct ZigBeeT *zb )
{
  unsigned int                  i;
  struct ZbNwkRouteEntryT       route;

  LOG_INFO_APP( "status | nextAddr | dstAddr" );

  for ( i = 0;; i++ )
  {
    if ( ZbNwkGetIndex( zb, ZB_NWK_NIB_ID_RouteTable, &route, sizeof(route), i ) != ZB_NWK_STATUS_SUCCESS )
    {
      /* End of Routing Table */
      break;
    }

    LOG_INFO_APP( "%d | 0x%04" PRIX16 " | 0x%04" PRIX16,
                  route.status,
                  route.nextAddr,
                  route.destAddr );
  }
}

3.2. Manually modifying the Route Table

This is not recommended as the Route Table is overwritten by Route Discovery Procedures which is triggered internally.

In order to manually modify the Route Table, a developer may call a function resembling the following:

void addRoute( struct ZigBeeT *zb, uint16_t dstAddr, uint16_t nextAddr )
{
  unsigned int                  i;
  struct ZbNwkRouteEntryT       route;
  int                           addIndex = -1;

  for ( i = 0;; i++ )
  {
    if ( ZbNwkGetIndex( zb, ZB_NWK_NIB_ID_RouteTable, &route, sizeof(route), i ) != ZB_NWK_STATUS_SUCCESS )
    {
      /* End of Routing Table */
      break;
    }

    if ( route.status == ZB_NWK_ROUTE_STATUS_INACTIVE )
    {
      if ( addIndex == -1 )
      {
        /* Store the index to overwrite in addIndex */
        addIndex = i;
      }
      continue;
    }

    if ( (dstAddr == ZB_NWK_ADDR_UNDEFINED) || (dstAddr == route.destAddr) )
    {
      /* Set the route to INACTIVE */
      memset( &route, 0, sizeof(struct ZbNwkRouteEntryT) );
      route.status = ZB_NWK_ROUTE_STATUS_INACTIVE;
      ZbNwkSetIndex( zb, ZB_NWK_NIB_ID_RouteTable, &route, sizeof(route), i );
      if ( addIndex == -1 )
      {
        /* Store the index to overwrite in addIndex */
        addIndex = i;
      }
    }
  }

  /* Overwrite the Routing Table at index addIndex */
  memset( &route, 0, sizeof(struct ZbNwkRouteEntryT) );
  route.status = ZB_NWK_ROUTE_STATUS_ACTIVE;
  route.destAddr = dstAddr;
  route.nextAddr = nextAddr;
  ZbNwkSetIndex( zb, ZB_NWK_NIB_ID_RouteTable, &route, sizeof(route), addIndex );
}

4. Configuring a device as a Concentrator

4.1. Setting a device to a Concentrator

A non-end-device can be set to a Concentrator by calling the following function.

void setConcentrator( struct ZigBeeT *zb )
{
  uint8_t concentrator = 1;
  ZbNwkSet( zb, ZB_NWK_NIB_ID_IsConcentrator, &concentrator, sizeof(concentrator) );
}

A Zigbee device acting as a Trust Center in a Centalized Zigbee Network is internally configured as a Concentrator by the stack.

4.2. Setting the periodicity of the Route Discovery Procedure with Many-to-One (only applicable for Concentrators)

A device can set the periodicity of the Route Discovery Procedure with Many-to-One by calling the following function.

void setPeriodicity( struct ZigBeeT *zb )
{
  uint8_t discoveryTime = 120; /* seconds */
  ZbNwkSet( zb, ZB_NWK_NIB_ID_ConcentratorDiscoveryTime, &discoveryTime, sizeof(discoveryTime) );
}

Set to 0 to turn off the procedure.

5. Triggering a Route Discovery Procedure

5.1. Triggering a Route Discovery Procedure

A device can trigger a Route Discovery Procedure by calling a function resembling the following.

void routeDiscReq( struct ZigBeeT *zb )
{
  struct ZbNlmeRouteDiscReqT routeDiscReq;
  routeDiscReq.dstAddrMode = ZB_NWK_ADDRMODE_SHORT; /* single device */
  routeDiscReq.dstAddr = 0x0000; /* coordinator address (can be any network address) */
  routeDiscReq.radius = 0; /* set to 0 for maximum depth */
  routeDiscReq.noRouteCache = 0; /* do not care */
  ZbNlmeRouteDiscReq( zb, &routeDiscReq, NULL, NULL );
}

5.2. Triggering a Route Discovery Procedure with Many-to-One

A device can trigger a Route Discovery Procedure with Many-to-One by calling a function resembling the following.

void routeDiscReqManyToOne( struct ZigbeeT *zb )
{
  struct ZbNlmeRouteDiscReqT routeDiscReq;
  routeDiscReq.dstAddrMode = ZB_NVK_ADDRMODE_NONE; /* this makes the request many-to-one */
  routeDiscReq.dstAddr = ZB_NWK_ADDR_UNDEFINED;
  routeDiscReq.radius = 0; /* set to 0 for maximum depth */
  routeDiscReq.noRouteCache = 0;
  ZbNlmeRouteDiscReq( zb, &routeDiscReq, NULL, NULL );
}

6. Acronyms and definitions

Term Definition
APS Application support sublayer
MAC Medium access control
NWK Network
PHY Physical
ZCL Zigbee cluster library