Example 1-1: ZigBee Data Requests
4.1.1 Example 1-1: ZigBee Data Requests
In Freescale BeeStack, the C functions which perform data requests, confirms, and indications mirror the ZigBee terms:
A data request, whether unicast, broadcast or groupcast, is initiated by a call to AF_DataRequest(). This function returns immediately with the data queued up to be sent out the radio and returns of gZbSuccess_c. A return of gZbNoMem_cm eans the message couldn't be queued due to lack of memory or other internal resources. A return of gZbInvalidEndpoint_c means that the source endpoint (I'll get to endpoints later) hasn't been registered with BeeStack.
The C prototype for AF_DataRequest() looks like this:
typedef struct afAddrInfo_tag
The first parameter to AF_DataRequest(), the afAddrInfo_t includes all the addressing information to indicate from where the packet is coming, and to where it is going. The afAddrInfo_t also contains transmission options, which define whether the packet is acknowledged or not, and the radius to indicate how far the packet should propagate in the network.
The field dstAddrMode in afAddrInfo_t has the same meaning as this field does in the ZigBee specification. It may be one of:
The gZbAddrModeIndirect_c is used to indicate if the local binding table is used (I'll explain more about binding later). The gZbAddrModeGroup_c mode is used when transmitting to a group, and dstAddr field is then used as a group ID. The mode gZbAddrMode16Bit_c is used to transmit directly to a node, and the dstAddr field is used to indicate the 16-bit node address. The gZbAddrMode64Bit_c is used to transmit to a node using its IEEE (or 64-bit) address, and dstAddr will reflect that IEEE address.
The second and third parameters to AF_DataRequest() define the application's data (payload). The payload can be any length up to 80 bytes, and may contain any content.
The last parameter, pConfirmId, may take more explanation. Network traffic can be difficult to predict, so care must be taken in applications to either synchronize the data or to allow the data to be received by a node asynchronously. For example, say an application sends two data requests: one to node A, one to node B, in that order, as shown in Figure 4.4.
Figure 4.4: ZigBee Data Confirms
Due to multi-hops, retries, or perhaps the necessity of route discovery, the confirm from the data request to B may actually arrive before the confirm from the data request to A.
Freescale BeeStack uses a pointer to the confirm ID, a rolling 8-bit number, to allow the application to keep track of which data request is which. For those of you ZigBee experts, this confirm ID is just the APS counter, an over-the-air field used for the same purpose. Some ZigBee stacks solve the problem by allowing only one message to be in flight at a time, and hence, no need for a confirm ID.
Data confirms come into a callback function named BeeAppDataConfirm(). The data type for that function is:
typedef struct zbApsdeDataConfirm_tag
Aside from the status and the confirmId, the rest of the source and destination information is included in the structure, simplifying code logic in applications. And, as is typical with the Freescale solution, it mirrors the ZigBee specification for APSDE-DATA.confirm.