How are different tables managed in EmberZNet?
Each table has a slightly different protocol for when the table is full.
(volatile) The routing table and neighbor table (volatile) are similar in that the table entries stay in RAM until it completely fills. When this happens the new entry will overwrite any "stale" entries. "Stale" is different for the routing table and the neighbor table. For routing tables it means 64 seconds of the route being actively used without another route discovery. For neighbor tables it means 64 seconds of no successful neighbor table exchanges. If there are no "stale" entries, then it will look to overwrite entries that have the most failures or worst neighbor quality. However, if the new potential neighbor has a lower LQI than the worst current neighbor, the new neighbor will not be registered into the table.
(non-volatile) When binding tables get full and you try to add to them they will give you "Binding Table Full" error. You will have to manually remove an entry if you want to add a new one. The binding table is not needed for network behavior but can be used by the application for multiple uses such as reporting, multicast and other uses. While typical ZigBee convention is to have one binding per-cluster, per-endpoint, our stack doesn’t enforce this limitation and will allow you to send via a binding that has a different source endpoint or cluster ID from the APS frame of the outgoing message. However, in multi-network operation, the stack does enforce the per-network binding requirement.
(volatile) Address Tables will overwrite the oldest entry once it is full and you are trying to add a new entry.
*Note about the address table: Both emberAfAddAddressTableEntry and emberAfPluginAddressTableAddEntry will add a table entry to the address table. The difference between the two is that one is only meant to be used if you are using the plugin (Address Table plugin). If you are using the plugin you will want to use emberAfPluginAddresTableAddEntry. Otherwise you will want to use emberAfAddAddressTableEntry. If you use the latter, you will also want to use emberAfRemoveAddressTableEntry to remove the entries. The reason for this is because they do keep track of the reference count. The reference count itself is used to stop you from setting an entry to a used position. However, the plugin add will check to make sure it is empty before adding to it. In fact, it uses the emberSetAddressTableRemoteNodeId to set it and emberSetAddressTableRemoteNodeId(index, EMBER_TABLE_ENTRY_UNUSED_NODE_ID)) to clear it. To summarize, if you are using the plugin use emberAfPluginAddresTableAddEntry/emberAfPluginAddressTableRemoveEntry and if you want emberSetAddressTableRemoteNodeId. Otherwise use emberAfAddAddressTableEntry/emberAfRemoveAddressTableEntry and emberAfSetAddressTableEntry. For hosts only, ezspReplaceAddressTableEntry can be used as a more convienent method to replace an address table entry.
(non-volatile) Child Tables will not let any new entries join once it is full. There is also no concept of "stale" children. A child entry can time out if it does not poll its parent after a certain time (usually ~5 minutes). However you can use EmberStatus emberRemoveChild(EmberEUI64 childEui64) to manually remove an entry.
(volatile) The broadcast table is used because the only specific limit that ZigBee (and therefore our stack) places on sending of messages is in regards to broadcasts. The ZigBee Networking specification requires that in-progress broadcasts (at the Network layer) be tracked by each router (via a broadcast table) to prevent repeating duplicates of an already-circulating broadcast. Since the space in the table is constrained (by RAM), only a limited number of entries exist; and since the duration of each broadcast must be considered in the worst-case scenario (large networks where broadcasts may take many seconds to circulate through the network), limits are placed on how many broadcasts can be sent in a given timeframe. For ZigBee Pro, this limit is effectively 8 broadcasts over any 9-second period.
So if the application tries to queue an APS Broadcast or an APS Multicast (which relies on the broadcast mechanism at the NWK layer) after this broadcast table is full (due to other NWK layer broadcast activity created by APS Broadcasts, APS Multicasts, Route Discoveries, Address Discoveries, Device Announcements, etc.), the stack will refuse to queue the message and instead will return EMBER_NETWORK_BUSY status. The application must then wait until the broadcast table has room to track a new broadcast. (How long to wait depends on how quickly the table filled up relative to the 9-second table entry timeout.)
Note that this broadcast table behavior is a ZigBee NWK layer compliance requirement and is important for preventing flooding the network with too much broadcast activity. The broadcast table size is configurable at compile-time for advanced and very specific use cases and when you clearly understand why and how. Note that configuring the broadcast table differently from the default may bring interoperability issues. Specifically, if you have a closed ecosystem and have control of all routing devices in the network, this may not be a problem. However if you need to work with 3rd party routers (using the standard broadcast table size) in your network, there may be problems as the other routers may not be able to relay all broadcasts originated from your router devices due to different capacity in the broadcast table.