6.1. Adaptation (ADP) Layer

The ADP layer adapts application layer requests to the 802.15.4 MAC layer. This way, applications do not have to worry about MAC layer interfaces. The job of an application developer become simpler.

6.1.1. Functions

ADP_sts_t ADP_appPyldTxReq(void)

This request to send payload on the wireless channel comes from the application layer. As a special case, the gateway can also request transmission. Parameters of the transmission are passed into this function via the global variable ADP_cntxt. The caller is expected to allocate memory and fill in the relevant contents. For example, an RFD sending sensor data will typically sent it to the PAN coordinator whose address is set as LPWMN_COORD_MAC_SHORT_ADDR.

Returns:Indicates status of transmission. If there is a failure, this defined enum gives the cause of error.
ADP_sts_t ADP_appPyldTxProc(void)

This requests MAC layer transmission of payload. Data sent to MAC will include ADP header. Function checks if fragmentation is to be performed when the packet size exceeds MAC_MAX_HDR_PLUS_PYLD_LEN. If mesh routing is supported and the next hop destination is not the final destination, mesh header is also added.

Returns:Indicates status of transmission. If there is a failure, this defined enum gives the cause of error.
void ADP_evtHndlr(UINT16_t globalEvtId, void *params_p)

This function is called to handle events based on the setting of event flags in global system event variables. For example, SYS_GLOBAL_EVT_MAC_DATA_CONFIRM and SYS_GLOBAL_EVT_MAC_DATA_INDICATION are two flags set in SYS_globalEvtMsk0. When either one is set, this function is called from the main system loop. Another event handled here is the SYS_GLOBAL_EVT_ADP_TRSCN_PENDING that is set in SYS_globalEvtMsk1.

This function triggers the processing of received events. For example, with SYS_GLOBAL_EVT_MAC_DATA_CONFIRM, the confirmation could be of a message sent from ADP layer, the gateway or related to mesh networking. For ADP source, function sets SYS_GLOBAL_EVT_ADP_DATA_CONFIRM in SYS_globalEvtMsk0. For gateway source, confirmation is relayed to the gateway. In case of routing, mesh parameters are updated.

Parameters:
  • globalEvtId – Identity of the event.
  • params_p – Pointer to the parameters of the event. Typically, this pointer would be typecast to the particular event’s data structure.
void ADP_init(void)

Initializes ADP including the global variable ADP_cntxt. In particular, destination/hop addresses are set to MAC_BROADCAST_SHORT_ADDR. Transaction queues are initialized to null. This function is typically called when the system boots up.

void ADP_procPendingTrscns(void)

Process pending transactions. The function obtains the transaction type and switches to the appropriate code block. Before the function returns, it checks if the transaction queue is empty. If empty, it clears SYS_globalEvtMsk1 of SYS_GLOBAL_EVT_ADP_TRSCN_PENDING.

void ADP_retryAppDataTxPostRtDisc(void)

This function is triggered following the setting of SYS_GLOBAL_EVT_APP_DATA_REQ_POST_RT_DISC in SYS_globalEvtMsk1. Sometimes data transmission may be requested when route to destination is not known. In such a scenario, data is buffered at the node until the route is discovered. Once route is discovered, this function gets called.

void ADP_procRtDiscOpnRslt(UINT16_t destAddr, UINT16_t nextHopAddr)

This function is called following route discovery to a destination node. If route has been obtained, function proceeds to schedule packets that are waiting in transmit queues. Once scheduled in this manner, the function sets SYS_GLOBAL_EVT_ADP_TRSCN_PENDING in SYS_globalEvtMsk1. Function is also responsible for setting SYS_GLOBAL_EVT_APP_DATA_REQ_POST_RT_DISC in SYS_globalEvtMsk1. In case route is not available, ADP_TRSCN_TYPE_RERR_TRX_REQ message is sent as response.

Parameters:
  • destAddr – Short address of the destination.
  • nextHopAddr – Short address of the next hop on the way to the destination. Where route discovery has failed, this must be set to MAC_BROADCAST_SHORT_ADDR.
void ADP_sendSigPkt(UINT8_t bdHndl, UINT16_t nextHop, UINT8_t ackReqd)

Sends a signalling packet at the ADP layer. At the receiving end, processing would be triggered from ADP_evtHndlr().

Parameters:
  • bdHndl – Handle to memory containing the message.
  • nextHop – Short address of the next hop destination.
  • ackReqd – If non-zero, acknowledgement is required from receiver. If zero, no acknowledgement is needed.
UINT8_t* ADP_prefixMeshHdr(UINT8_t *buff_p, UINT16_t destAddr)

When multihop mesh networking is enabled in the network, a mesh header is necessary. This function adds that header. The mesh header contains the destination short address while the MAC address contains the next hop short address.

Parameters:
  • buff_p – Pointer to buffer where the header has to be added.
  • destAddr – Destination short address.
UINT16_t ADP_getRoute(UINT16_t destAddr)

This function is not applicable for RFDs since they don’t have routing functionality. When an FFD or PAN coordinator needs to send out a packet, it requires a route to the destination node. This function obtains the route. If route is known, it is simply returned. If not known, a broadcast is sent out to discover the route.

Parameters:
  • destAddr – Short address of the destination node.

6.1.2. Globals

ADP_cntxt_s ADP_cntxt

Stores the ADP context. This is used by application code. The gateway uses it. Memory handles and associated parameters are passed in and out of ADP layer using this variable.

6.1.3. Macros

#define ADP_ELEMENT_TYPE_LEN  0x1

#define ADP_MAX_HOP_COUNT  0x8


// source port (4 bits) | destination port (4 bits)
#define ADP_NON_IP_DEST_PORT_FIELD_LEN   0x1


#define ADP_ELEMENT_TYPE_IPv4   0x1
#define ADP_ELEMENT_TYPE_COMP_IPv4   0x2

#define ADP_ELEMENT_TYPE_IPv6   0x8
#define ADP_ELEMENT_TYPE_COMP_IPv6   0x9

#define ADP_ELEMENT_TYPE_AODVL  0x10

#define ADP_ELEMENT_TYPE_MESH_HDR  0x20

#define ADP_ELEMENT_TYPE_NON_IP  0x40

#define ADP_ELEMENT_TYPE_ASSOC_REQ       0x30    // COORD -> PAN COORD
#define ADP_ELEMENT_TYPE_ASSOC_RESP      0x31    // PAN COORD -> COORD
#define ADP_ELEMENT_TYPE_DISASSOC_REQ    0x32    // PAN COORD -> ANY NODE
#define ADP_ELEMENT_TYPE_DISASSOC_RESP   0x33    // ANY Node -> PAN COORD

#define ADP_ELEMENT_TYPE_FIRST_FRAG_HDR    0x60
#define ADP_ELEMENT_TYPE_MIDDLE_FRAG_HDR   0x61
#define ADP_ELEMENT_TYPE_LAST_FRAG_HDR     0x62

#define ADP_MESH_HDR_DEST_ADDR_FIELD_LEN  MAC_SHORT_ADDR_LEN
#define ADP_MESH_HDR_SRC_ADDR_FIELD_LEN  MAC_SHORT_ADDR_LEN

#define ADP_MESH_HDR_HOP_COUNT_FIELD_LEN  1
#define ADP_MESH_HDR_LEN  (ADP_MESH_HDR_HOP_COUNT_FIELD_LEN \
                           + ADP_MESH_HDR_DEST_ADDR_FIELD_LEN \
                           + ADP_MESH_HDR_SRC_ADDR_FIELD_LEN)

#define ADP_MESH_HDR_HOP_CONT_OFF   0x0
#define ADP_MESH_HDR_DEST_ADDR_OFF  0x1
#define ADP_MESH_HDR_SRC_ADDR_OFF   0x3

// Fragmentation header
#define ADP_FRAG_HDR_LEN  1  //   (4 bits tag | 4 bits frag index)
#define ADP_FRAG_HDR_TAG_FIELD_MSK  0xf
#define ADP_FRAG_HDR_IDX_FIELD_MSK  0xf
#define ADP_FRAG_HDR_TAG_FIELD_SHIFT  4
#define ADP_FRAG_HDR_IDX_FIELD_SHIFT  0
#define ADP_FRAG_HDR_TAG_FIELD_SHIFT_MSK  0xf0
#define ADP_FRAG_HDR_IDX_FIELD_SHIFT_MSK  0x0f

#define ADP_MAX_FRAGS_PER_SDU  16  // (0x0 - 0xf)

#define ADP_ASSOC_RESP_ELEMENT_LEN   (MAC_EXT_ADDR_LEN \
                                      + MAC_ASSOC_RESP_STS_LEN \
                                      + MAC_SHORT_ADDR_LEN)

#define ADP_ASSOC_REQ_ELEMENT_LEN    (MAC_EXT_ADDR_LEN \
                                      + MAC_NODE_CAPABILITY_INFO_LEN)


#define ADP_TX_REQ_SRC_NONE             0x0
#define ADP_TX_REQ_SRC_APP              0x1
#define ADP_TX_REQ_SRC_AODVL            0x2
#define ADP_TX_REQ_SRC_FWD_PATH         0x3
#define ADP_TX_REQ_SRC_ASSOC_REQ_RELAY  0x4
#define ADP_TX_REQ_SRC_ASSOC_RESP_TO_RELAY  0x5
#define ADP_TX_REQ_SRC_GW               0x6





#define ADP_TRSCN_TYPE_ASSOC_REQ             0x1
#define ADP_TRSCN_TYPE_ASSOC_RESP            0x2
#define ADP_TRSCN_TYPE_ASSOC_RESP_TO_RELAY   0x3
#define ADP_TRSCN_TYPE_IPv4_PDU              0x4
#define ADP_TRSCN_TYPE_MESH_PDU              0x5
#define ADP_TRSCN_TYPE_AODVL_PATH_REQ        0x6
#define ADP_TRSCN_TYPE_AODVL_PATH_REP        0x7
#define ADP_TRSCN_TYPE_RERR_TRX_REQ          0x8
#define ADP_TRSCN_TYPE_RFD_REASSOC           0x9


#define ADP_TRSCN_TYPE_FIELD_LEN  0x1


#define ADP_FWD_PKT_Q_LEN  3


#define ADP_PKT_TYPE_IPv4_PDU    0x1
#define ADP_PKT_TYPE_MESH_PDU    0x2
#define ADP_PKT_TYPE_ASSOC_PDU   0x3

6.1.4. Type Definitions

typedef enum
{
   ADP_STS_SUCCESS,
   ADP_STS_NODE_NOT_FOUND,
   ADP_STS_OOM,
   ADP_STS_TX_FLR,
   ADP_STS_RT_DISC_OOM,
   ADP_STS_RT_DISC_FAILED,
   ADP_STS_ROUTING_LOOP,
   ADP_STS_MAX_HOPS_EXCEEDED,
   ADP_STS_NO_ROUTE,
   ADP_STS_PATH_DISC_TIMED_OUT,
   ADP_STS_NODE_NOT_ASSOCIATED,
   ADP_STS_TOO_MANY_FRAGMENTS
} ADP_sts_t;

typedef struct
{
   UINT8_t bdHndl;
   UINT8_t localOrig;
   UINT16_t destShortAddr;
   UINT16_t nextHopAddr;
#ifdef IPv4_SUPPORT_ENA
   UINT16_t destUdpPort;
   UINT32_t destIp;
#endif
} ADP_dataReqParams_s;

typedef struct
{
   UINT8_t fragCnt;
   UINT8_t fragLen;
   UINT8_t fragTag;
   UINT8_t currFragIdx;
   UINT8_t macHdrLen;
   UINT8_t adpHdrLen;
   UINT16_t currFragOffset;
} ADP_dataReqFragInfo_s;

typedef struct
{
   ADP_sts_t sts;
} ADP_dataCnfrmParams_s;

typedef struct
{
   UINT8_t bdHndl;
   UINT16_t srcAddr;
} ADP_dataIndParams_s;

typedef struct
{
   UINT8_t bdHndl;
   UINT8_t nextIdx;
} ADP_fwdPktQEntry_s;

typedef struct
{
#ifdef ADP_STATS_ENA
   UINT8_t ADP_dataRcvdCnt;
#endif
   UINT8_t pendTxReqSrc;
   UINT8_t fragTag;
#if !defined(DEV_TYPE_RFD) && !defined(DEV_TYPE_FFD_NO_MESH) && !defined(PAN_COORD_NO_MESH)
   UINT8_t fwdPktQHead;
#endif
   ADP_dataCnfrmParams_s cnfrmSts;
#ifdef IPv4_SUPPORT_ENA
   UINT16_t ipv4NetAddr;
#endif
   ADP_dataReqParams_s txParams;
   ADP_dataIndParams_s dataIndParams;
   ADP_dataReqFragInfo_s fragInfo;
   SYS_trscnQ_s trscnQ;
#if !defined(DEV_TYPE_RFD) && !defined(DEV_TYPE_FFD_NO_MESH) && !defined(PAN_COORD_NO_MESH)
   ADP_fwdPktQEntry_s fwdPktQ[ADP_FWD_PKT_Q_LEN];
   SYS_trscnQ_s rtPendFwdPktTrscnQ;
   SYS_trscnQ_s assocRtPendTrscnQ;
#endif
} ADP_cntxt_s;