I've been meaning to get around to this for a while now, but things have been so busy that I just haven't had the time. Or maybe I was just too lazy. In any case, today is a good time to kick off a series detailing the Zigbee NWK layer, mostly because I caught a cold and it pretty much rendered me useless for any heavy thinking.
I know it's a bit late to start a series on the Zigbee NWK layer after they announced that they were transitioning to IP. However, I think that it'd be a good study on how Zigbee stands right now, where you'll be able to see the strengths and weaknesses of the networking protocol. Hopefully, you'll also be able to see what role IP will play in it, and what areas are and aren't a good fit for IP.
So here we go…
The Zigbee 2007 Networking Layer - Part 1
The Zigbee networking layer is probably one of the most complex layers in the protocol stack. Mostly it's because they spent a lot of time outlining all types of different conditions, routing methods, a bunch of tables, etc since it's the backbone of the transport part of the stack. Since it's quite a large topic, I think the best way to go is to divide it up into parts and dissect each part individually.
The first cut will be to split the layer into two sections: the data path and the management path. Both sides are fairly complex, but if you understand the data path well, then you can probably see why the management side is also complicated.
Below, you can see a very simple diagram of how the network layer looks from a data point of view. Data to be transmitted can either flow down from an upper layer, received data can come up, and data can do a U-turn where received data comes up, gets analyzed, and then gets retransmitted (forwarded) to its next hop destination.
On the transmit side, the Application Sub Layer (APS) sends data down to the network layer via a data request. Inside the data request, the APS specifies the destination address, whether or not route discovery will be allowed, and the radius. The radius is the maximum hops that the frame will be allowed to travel. This is mostly used in broadcasts where you might not want the broadcast to travel too far, or it's usually set to a default value to prevent endless hopping in case there's a loop in the routing tables.
Once inside the data request, the network header is filled out and then the address is examined. At this point, it's probably best to make a distinction between network addressing and MAC addressing. There are two sets of addresses in each Zigbee frame: the 802.15.4 source/destination addresses and the Zigbee network source/destination addresses. Actually, sometimes only the source or the destination is present depending on the situation, but that's another article.
The key to understanding the Zigbee routing algorithm is to understand how both addresses are used. The network source or destination address is what I'll call the absolute source or destination. This means that if a frame originated from address 0x1234, this will be the source address in the networking field no matter what. The same goes for the networking destination. On the other hand, the MAC address is used as a next hop address which could just be a stepping stone on the way to the destination. It's like if I wanted to go to Akihabara. I know where I came from, and where I want to go, but from a microscopic perspective, I have a couple of interim destinations (train platforms) I need to get to before I reach Akihabara. And one more thing about addressing, for the purpose of this series, I'm only going to be referring to the 16-bit short addresses used by the MAC layer. The MAC actually has a 64-bit address as well, but it would just confuse things.
Okay, so now where was I…ahhh yes, how the network data request processes the addresses. Inside the network layer on the transmit side, you only have one piece of real information which is the destination address. From that you'll have to figure out the next hop address for the MAC. You can say that most of the network layer exists just to figure out what the next hop address will be.
To figure out the next hop, you have to go through a series of comparisons. Although the order is dependent on the stack, I'll refer to the order that I use. The first comparison is to see if the destination is a broadcast. Zigbee has a few classes of broadcasts: broadcast to everyone, broadcast to routers, and broadcast to non-sleeping nodes. Upon checking the spec again, I see that there is a broadcast for low power routers as well, although I' haven't seen this used in the spec.
I'll go into broadcasting in more detail later, but suffice it to say that if the destination address falls into the broadcast category, then the next hop address is simple…it will be the 802.15.4 universal broadcast address which is 0xFFFF. Case closed, ship that frame out to the MAC…errr…kind of. You'll see later on that broadcasting isn't that simple. Precautions need to be taken because you because you can easily crash a network with a poor broadcast.
Moving right along, if the destination address isn't a broadcast, then you need to determine how to get it to where it's supposed to go. I check the neighbor table first to see if the address matches any destination inside of it. The neighbor table, as you might imagine, is a list of all the neighbors that are within earshot of the node. I'll describe this in more detail later on as well, however this is the next logical place to check for the next hop. If the address is inside your neighbor table, then you can get the frame to its destination in one hop and don't have to go through all the fancy, shmancy routing algorithms.
If it's not inside your neighbor table, then you have to resort to forwarding it to an intermediate node on its way to the final destination and this is where things might get a little complicated. I check my routing tables first because if the destination address is inside my routing tables, the routing table will include the next hop address and I can just send it out. However if it's not inside the routing tables, then you have to decide if you want to do a route discovery or if you want to route it along the tree (my current stack supports tree routing as well...this won't be the case if you have a Zigbee Pro implementation which only supports the mesh routing).
The tree routing is the last resort for me so the next thing I do if I can't find the destination is to check to see if the frame will allow route discovery. Route discovery takes a bit of time, and also floods the network with broadcast frames so there may be some instances that you might not want to do this. However if the route discovery flag is true, then I buffer the frame in a holding queue and kick off a route discovery to find the destination within the network. For more information on this process, check out the article I wrote a long, long time ago on Zigbee mesh routing .
And finally, if I can't do a route discovery, then I just route it along the tree, using the algorithm outlined in the Zigbee spec. Again, for more information about tree routing, as well as why it sucks, check out this article I wrote on it a few months ago .
If all hell breaks loose and you can't do route discovery or tree routing (your upper layers are sadistic, pointy-haired bosses), then you just give up and return an error status in the confirmation.
Whew…that was quite an introduction to just the transmit side of the Zigbee network layer. Join me next time as I discuss the ever exciting receive side data path which is pretty much the same, but with an added twist.