906 lines
25 KiB
C
906 lines
25 KiB
C
/**************************************************************************************************
|
|
Filename: stub_aps.c
|
|
Revised: $Date: 2011-04-20 10:16:44 -0700 (Wed, 20 Apr 2011) $
|
|
Revision: $Revision: 25771 $
|
|
|
|
Description: Stub APS processing functions
|
|
|
|
|
|
Copyright 2008 - 2011 Texas Instruments Incorporated. All rights reserved.
|
|
|
|
IMPORTANT: Your use of this Software is limited to those specific rights
|
|
granted under the terms of a software license agreement between the user
|
|
who downloaded the software, his/her employer (which must be your employer)
|
|
and Texas Instruments Incorporated (the "License"). You may not use this
|
|
Software unless you agree to abide by the terms of the License. The License
|
|
limits your use, and you acknowledge, that the Software may not be modified,
|
|
copied or distributed unless embedded on a Texas Instruments microcontroller
|
|
or used solely and exclusively in conjunction with a Texas Instruments radio
|
|
frequency transceiver, which is integrated into your product. Other than for
|
|
the foregoing purpose, you may not use, reproduce, copy, prepare derivative
|
|
works of, modify, distribute, perform, display or sell this Software and/or
|
|
its documentation for any purpose.
|
|
|
|
YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
|
|
PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
|
|
INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
|
|
NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
|
|
TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
|
|
NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
|
|
LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
|
|
INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
|
|
OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
|
|
OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
|
|
(INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
|
|
|
|
Should you have any questions regarding your right to use this Software,
|
|
contact Texas Instruments Incorporated at www.TI.com.
|
|
**************************************************************************************************/
|
|
|
|
/*********************************************************************
|
|
* INCLUDES
|
|
*/
|
|
#include "osal.h"
|
|
#include "mac_spec.h"
|
|
#include "nwk_util.h"
|
|
#include "AF.h"
|
|
|
|
#include "stub_aps.h"
|
|
|
|
/*********************************************************************
|
|
* MACROS
|
|
*/
|
|
|
|
/*********************************************************************
|
|
* CONSTANTS
|
|
*/
|
|
|
|
// Stub NWK header length
|
|
#define STUB_NWK_HDR_LEN 2
|
|
|
|
// Start of the Stub APS header in the Inter-PAN frame
|
|
#define STUB_APS_HDR_FRAME_CTRL STUB_NWK_HDR_LEN
|
|
|
|
// Stub APS event identifiers
|
|
#define CHANNEL_CHANGE_EVT 0x0001
|
|
|
|
#define CHANNEL_CHANGE_RETRY_TIMEOUT 100
|
|
|
|
/*********************************************************************
|
|
* TYPEDEFS
|
|
*/
|
|
typedef struct
|
|
{
|
|
zAddrType_t addr;
|
|
uint16 panId;
|
|
} pan_t;
|
|
|
|
/*********************************************************************
|
|
* GLOBAL VARIABLES
|
|
*/
|
|
|
|
uint8 StubAPS_TaskID = 0xFF; // Task ID for internal task/event processing
|
|
|
|
/*********************************************************************
|
|
* EXTERNAL VARIABLES
|
|
*/
|
|
|
|
|
|
/*********************************************************************
|
|
* EXTERNAL FUNCTIONS
|
|
*/
|
|
|
|
|
|
/*********************************************************************
|
|
* LOCAL VARIABLES
|
|
*/
|
|
|
|
static uint8 newChannel;
|
|
static uint8 channelChangeInProgress = FALSE;
|
|
|
|
// Application info
|
|
static uint8 appTaskID = 0xFF; // Application task id
|
|
static uint8 appEndPoint = 0; // Application endpoint
|
|
|
|
|
|
/*********************************************************************
|
|
* LOCAL FUNCTIONS
|
|
*/
|
|
|
|
static void StubNWK_ParseMsg( uint8 *buf, uint8 bufLength, NLDE_FrameFormat_t *snff );
|
|
static void StubAPS_ParseMsg( NLDE_FrameFormat_t *snff, aps_FrameFormat_t *saff );
|
|
static void StubNWK_BuildMsg( uint8 *nwkHdr );
|
|
static void StubAPS_BuildMsg( uint8 *apsHdr, uint8 frmCtrl, uint16 groupID, APSDE_DataReq_t *req );
|
|
static ZStatus_t StubAPS_BuildFrameControl( uint8 *frmCtrl, zAddrType_t *dstAddr,
|
|
uint16 *groupID, APSDE_DataReq_t *req );
|
|
static ZStatus_t StubAPS_SetNewChannel( uint8 channel );
|
|
static void StubAPS_NotifyApp( uint8 status );
|
|
|
|
uint8 StubAPS_ZMacCallback( uint8 *msgPtr );
|
|
|
|
/*********************************************************************
|
|
* @fn StubAPS_Init()
|
|
*
|
|
* @brief Initialize stub APS layer
|
|
*
|
|
* @param task_id - Task identifier for the desired task
|
|
*
|
|
* @return none
|
|
*/
|
|
void StubAPS_Init( uint8 task_id )
|
|
{
|
|
StubAPS_TaskID = task_id;
|
|
|
|
// register with ZMAC
|
|
pZMac_AppCallback = StubAPS_ZMacCallback;
|
|
|
|
} /* StubAPS_Init() */
|
|
|
|
/*********************************************************************
|
|
* @fn StubAPS_ProcessEvent()
|
|
*
|
|
* @brief Main event loop for Stub APS task. This function should be called
|
|
* at periodic intervals when event occur.
|
|
*
|
|
* @param task_id - Task ID
|
|
* @param events - Bitmap of events
|
|
*
|
|
* @return none
|
|
*/
|
|
UINT16 StubAPS_ProcessEvent( uint8 task_id, uint16 events )
|
|
{
|
|
(void)task_id; // Intentionally unreferenced parameter
|
|
|
|
if ( events & SYS_EVENT_MSG )
|
|
{
|
|
osal_event_hdr_t *msg_ptr;
|
|
|
|
while ( (msg_ptr = (osal_event_hdr_t *)osal_msg_receive( StubAPS_TaskID )) != NULL )
|
|
{
|
|
if ( msg_ptr->event == MAC_MCPS_DATA_CNF )
|
|
{
|
|
INTERP_DataConfirm( (ZMacDataCnf_t *)msg_ptr );
|
|
}
|
|
else if ( msg_ptr->event == MAC_MCPS_DATA_IND )
|
|
{
|
|
INTERP_DataIndication( (macMcpsDataInd_t *)msg_ptr );
|
|
}
|
|
|
|
osal_msg_deallocate( (uint8 *)msg_ptr );
|
|
}
|
|
|
|
// Return unproccessed events
|
|
return ( events ^ SYS_EVENT_MSG );
|
|
}
|
|
|
|
if ( events & CHANNEL_CHANGE_EVT )
|
|
{
|
|
// try to change to the new channel
|
|
ZStatus_t status = StubAPS_SetNewChannel( newChannel );
|
|
if ( status != ZSuccess )
|
|
{
|
|
// turn MAC receiver back on
|
|
uint8 rxOnIdle = true;
|
|
ZMacSetReq( ZMacRxOnIdle, &rxOnIdle );
|
|
|
|
// set NWK task to run
|
|
nwk_setStateIdle( FALSE );
|
|
|
|
channelChangeInProgress = FALSE;
|
|
}
|
|
|
|
// notify the application
|
|
StubAPS_NotifyApp( status );
|
|
|
|
return ( events ^ CHANNEL_CHANGE_EVT );
|
|
}
|
|
|
|
// If reach here, the events are unknown
|
|
// Discard or make more handlers
|
|
return 0;
|
|
|
|
} /* StubAPS_ProcessEvent() */
|
|
|
|
|
|
/*********************************************************************
|
|
* @fn StubNWK_ParseMsg
|
|
*
|
|
* @brief Call this function to parse an incoming Stub NWK frame.
|
|
*
|
|
* @param buf - pointer incoming message buffer
|
|
* @param bufLength - length of incoming message
|
|
* @param snff - pointer Frame Format Parameters
|
|
*
|
|
* @return pointer to network packet, NULL if error
|
|
*/
|
|
static void StubNWK_ParseMsg( uint8 *buf, uint8 bufLength, NLDE_FrameFormat_t *snff )
|
|
{
|
|
uint16 fc;
|
|
|
|
osal_memset( snff, 0, sizeof(NLDE_FrameFormat_t) );
|
|
|
|
snff->bufLength = bufLength;
|
|
|
|
// get the frame control
|
|
fc = BUILD_UINT16( buf[NWK_HDR_FRAME_CTRL_LSB], buf[NWK_HDR_FRAME_CTRL_MSB] );
|
|
|
|
// parse the frame control
|
|
NLDE_ParseFrameControl( fc, snff );
|
|
|
|
snff->hdrLen = STUB_NWK_HDR_LEN;
|
|
|
|
// Stub NWK payload
|
|
snff->nsdu = buf + snff->hdrLen;
|
|
snff->nsduLength = snff->bufLength - snff->hdrLen;
|
|
|
|
} /* StubNWK_ParseMsg */
|
|
|
|
/*********************************************************************
|
|
* @fn StubAPS_ParseMsg
|
|
*
|
|
* @brief Call this function to parse an incoming Stub APS frame.
|
|
*
|
|
* @param naff - pointer Stub NWK Frame Format Parameters
|
|
* @param saff - pointer Stub APS Format Parameters
|
|
*
|
|
* @return none
|
|
*/
|
|
static void StubAPS_ParseMsg( NLDE_FrameFormat_t *snff, aps_FrameFormat_t *saff )
|
|
{
|
|
uint8 fcb;
|
|
uint8 *asdu;
|
|
|
|
osal_memset( saff, 0, sizeof(aps_FrameFormat_t) );
|
|
|
|
saff->asduLength = snff->nsduLength;
|
|
asdu = snff->nsdu;
|
|
saff->macDestAddr = snff->macDstAddr;
|
|
|
|
// First byte is Frame Control.
|
|
saff->FrmCtrl = *asdu++;
|
|
|
|
fcb = saff->FrmCtrl & APS_FRAME_TYPE_MASK;
|
|
if ( fcb == STUB_APS_FRAME )
|
|
{
|
|
fcb = saff->FrmCtrl & APS_DELIVERYMODE_MASK;
|
|
if ( fcb == APS_FC_DM_BROADCAST )
|
|
saff->wasBroadcast = true;
|
|
else
|
|
saff->wasBroadcast = false;
|
|
|
|
if ( fcb == APS_FC_DM_GROUP )
|
|
{
|
|
saff->GroupID = BUILD_UINT16( asdu[0], asdu[1] );
|
|
asdu += sizeof( uint16 );
|
|
}
|
|
|
|
// Pull out the Cluster ID
|
|
saff->ClusterID = BUILD_UINT16( asdu[0], asdu[1] );
|
|
asdu += sizeof( uint16 );
|
|
|
|
// Pull out the profile ID
|
|
saff->ProfileID = BUILD_UINT16( asdu[0], asdu[1] );
|
|
asdu += 2;
|
|
}
|
|
|
|
saff->asdu = asdu;
|
|
saff->asduLength -= (uint8) (asdu - snff->nsdu);
|
|
saff->apsHdrLen = snff->nsduLength - saff->asduLength;
|
|
|
|
} /* StubAPS_ParseMsg */
|
|
|
|
/******************************************************************************
|
|
* @fn StubAPS_BuildFrameControl
|
|
*
|
|
* @brief This function builds Stub APS Frame Control and the destination
|
|
* address parameter for the MCPS-DATA Request.
|
|
*
|
|
* @param frmCtrl - frame control
|
|
* @param dstAddr - destination address for MCPS-DATA Request
|
|
* @param groupID - group id
|
|
* @param req - APSDE_DataReq_t
|
|
*
|
|
* @return ZStatus_t
|
|
*/
|
|
static ZStatus_t StubAPS_BuildFrameControl( uint8 *frmCtrl, zAddrType_t *dstAddr,
|
|
uint16 *groupID, APSDE_DataReq_t *req )
|
|
{
|
|
// Security
|
|
if ( req->txOptions & APS_TX_OPTIONS_SECURITY_ENABLE )
|
|
return ( ZApsNotSupported );
|
|
|
|
// Ack request
|
|
if ( req->txOptions & APS_TX_OPTIONS_ACK )
|
|
return ( ZApsNotSupported );
|
|
|
|
// Fragmentation
|
|
if ( req->txOptions & APS_TX_OPTIONS_PERMIT_FRAGMENT )
|
|
return ( ZApsNotSupported );
|
|
|
|
// set delivery mode
|
|
if ( req->dstAddr.addrMode == AddrNotPresent )
|
|
return ( ZApsNotSupported ); // No REFLECTOR
|
|
|
|
// set frame type
|
|
*frmCtrl = STUB_APS_FRAME;
|
|
|
|
// set DstAddrMode of MCPS-DATA Request to DstAddrMode of INTERP-Data Request
|
|
dstAddr->addrMode = req->dstAddr.addrMode;
|
|
|
|
// set DstAddr of MCPS-DATA Request to DstAddr of INTERP-Data Request
|
|
if ( req->dstAddr.addrMode == AddrBroadcast )
|
|
{
|
|
*frmCtrl |= APS_FC_DM_BROADCAST;
|
|
|
|
// set DstAddrMode of MCPS-DATA Request to short address
|
|
dstAddr->addrMode = Addr16Bit;
|
|
dstAddr->addr.shortAddr = req->dstAddr.addr.shortAddr;
|
|
}
|
|
else if ( req->dstAddr.addrMode == Addr16Bit )
|
|
{
|
|
*frmCtrl |= APS_FC_DM_UNICAST;
|
|
dstAddr->addr.shortAddr = req->dstAddr.addr.shortAddr;
|
|
}
|
|
else if ( req->dstAddr.addrMode == Addr64Bit )
|
|
{
|
|
*frmCtrl |= APS_FC_DM_UNICAST;
|
|
osal_cpyExtAddr( dstAddr->addr.extAddr, req->dstAddr.addr.extAddr );
|
|
}
|
|
else if ( req->dstAddr.addrMode == AddrGroup )
|
|
{
|
|
*frmCtrl |= APS_FC_DM_GROUP;
|
|
|
|
// set DstAddrMode of MCPS-DATA Request to short address
|
|
dstAddr->addrMode = Addr16Bit;
|
|
|
|
// set DstAddr of MCPS-DATA Request to 0xFFFF
|
|
dstAddr->addr.shortAddr = NWK_BROADCAST_SHORTADDR_DEVALL;
|
|
|
|
// set Group ID to DstAddr of INTERP-Data Request
|
|
*groupID = req->dstAddr.addr.shortAddr;
|
|
}
|
|
|
|
return ( ZSuccess );
|
|
|
|
} /* StubAPS_BuildFrameControl */
|
|
|
|
/******************************************************************************
|
|
* @fn StubNWK_BuildMsg
|
|
*
|
|
* @brief This function builds a Stub NWK frame.
|
|
*
|
|
* @param nwkHdr - stub NWK header
|
|
*
|
|
* @return none
|
|
*/
|
|
static void StubNWK_BuildMsg( uint8 *nwkHdr )
|
|
{
|
|
uint16 frmCtrl = 0;
|
|
uint8 protoVer = NLME_GetProtocolVersion();
|
|
|
|
// frame type
|
|
frmCtrl |= (STUB_NWK_FRAME_TYPE << NWK_FC_FRAME_TYPE);
|
|
|
|
// protocol version
|
|
frmCtrl |= (protoVer << NWK_FC_PROT_VERSION);
|
|
|
|
// set Stub NWK header
|
|
*nwkHdr++ = LO_UINT16( frmCtrl );
|
|
*nwkHdr++ = HI_UINT16( frmCtrl );
|
|
|
|
} /* StubNWK_BuildMsg */
|
|
|
|
/******************************************************************************
|
|
* @fn StubAPS_BuildMsg
|
|
*
|
|
* @brief This function builds a Stub APS frame.
|
|
*
|
|
* @param apsHdr - stub APS header
|
|
* @param frmCtrl - stub APS frame control
|
|
* @param groupID - group id
|
|
* @param req - APSDE_DataReq_t
|
|
*
|
|
* @return none
|
|
*/
|
|
static void StubAPS_BuildMsg( uint8 *apsHdr, uint8 frmCtrl, uint16 groupID, APSDE_DataReq_t *req )
|
|
{
|
|
// add frame type
|
|
*apsHdr++ = frmCtrl;
|
|
|
|
// add Group ID
|
|
if ( ( frmCtrl & APS_DELIVERYMODE_MASK ) == APS_FC_DM_GROUP )
|
|
{
|
|
*apsHdr++ = LO_UINT16( groupID );
|
|
*apsHdr++ = HI_UINT16( groupID );
|
|
}
|
|
|
|
// add clusterID
|
|
*apsHdr++ = LO_UINT16( req->clusterID );
|
|
*apsHdr++ = HI_UINT16( req->clusterID );
|
|
|
|
// add profile ID
|
|
*apsHdr++ = LO_UINT16( req->profileID );
|
|
*apsHdr++ = HI_UINT16( req->profileID );
|
|
|
|
// copy ASDU data into frame
|
|
osal_memcpy ( apsHdr, req->asdu, req->asduLen );
|
|
|
|
} /* StubAPS_BuildMsg */
|
|
|
|
/******************************************************************************
|
|
* @fn StubAPS_setNewChannel
|
|
*
|
|
* @brief This function changes the device's channel.
|
|
*
|
|
* @param none
|
|
*
|
|
* @return ZStatus_t
|
|
*/
|
|
static ZStatus_t StubAPS_SetNewChannel( uint8 channel )
|
|
{
|
|
uint8 rxOnIdle;
|
|
|
|
// make sure MAC has nothing to transmit
|
|
if ( ( nwkDB_CountTypes( NWK_DATABUF_SENT ) == 0 ) && ZMacStateIdle() )
|
|
{
|
|
// set the new channel
|
|
ZMacSetReq( ZMacChannel, &channel );
|
|
|
|
// turn MAC receiver back on
|
|
rxOnIdle = true;
|
|
ZMacSetReq( ZMacRxOnIdle, &rxOnIdle );
|
|
|
|
channelChangeInProgress = FALSE;
|
|
|
|
return ( ZSuccess );
|
|
}
|
|
|
|
return ( ZFailure );
|
|
|
|
} /* StubAPS_setNewChannel */
|
|
|
|
|
|
/******************************************************************************
|
|
* @fn StubAPS_NotifyApp
|
|
*
|
|
* @brief This function sends an OSAL message to the Application task.
|
|
*
|
|
* @param status - command status
|
|
*
|
|
* @return none
|
|
*/
|
|
static void StubAPS_NotifyApp( uint8 status )
|
|
{
|
|
osal_event_hdr_t *msgPtr;
|
|
|
|
// Notify the application task
|
|
msgPtr = (osal_event_hdr_t *)osal_msg_allocate( sizeof(osal_event_hdr_t) );
|
|
if ( msgPtr )
|
|
{
|
|
msgPtr->event = SAPS_CHANNEL_CHANGE;
|
|
msgPtr->status = status;
|
|
|
|
osal_msg_send( appTaskID, (uint8 *)msgPtr );
|
|
}
|
|
|
|
} /* StubAPS_NotifyApp */
|
|
|
|
/******************************************************************************
|
|
*
|
|
* External APIs provided to the Application.
|
|
*/
|
|
|
|
/******************************************************************************
|
|
* @fn StubAPS_SetInterPanChannel
|
|
*
|
|
* @brief This function changes the device's channel for inter-PAN communication.
|
|
*
|
|
* @param channel - new channel
|
|
*
|
|
* @return ZStatus_t
|
|
*/
|
|
ZStatus_t StubAPS_SetInterPanChannel( uint8 channel )
|
|
{
|
|
uint8 currChannel;
|
|
uint8 rxOnIdle;
|
|
|
|
if ( channelChangeInProgress )
|
|
return ( ZFailure );
|
|
|
|
ZMacGetReq( ZMacChannel, &currChannel );
|
|
if ( currChannel == channel )
|
|
{
|
|
// inter PANs communication within the same channel
|
|
return ( ZSuccess );
|
|
}
|
|
|
|
// go into channel transition state
|
|
channelChangeInProgress = TRUE;
|
|
|
|
// set NWK task to idle
|
|
nwk_setStateIdle( TRUE );
|
|
|
|
// turn MAC receiver off
|
|
rxOnIdle = false;
|
|
ZMacSetReq( ZMacRxOnIdle, &rxOnIdle );
|
|
|
|
// try to change to the new channel
|
|
if ( StubAPS_SetNewChannel( channel ) == ZSuccess )
|
|
return ( ZSuccess );
|
|
|
|
// save the new channel for retry
|
|
newChannel = channel;
|
|
|
|
// ask StubAPS task to retry it later
|
|
osal_start_timerEx( StubAPS_TaskID, CHANNEL_CHANGE_EVT, CHANNEL_CHANGE_RETRY_TIMEOUT );
|
|
|
|
return ( ZApsNotAllowed );
|
|
|
|
} /* StubAPS_SetInterPanChannel */
|
|
|
|
/******************************************************************************
|
|
* @fn StubAPS_SetIntraPanChannel
|
|
*
|
|
* @brief This function sets the device's channel back to the NIB channel.
|
|
*
|
|
* @param none
|
|
*
|
|
* @return ZStatus_t
|
|
*/
|
|
ZStatus_t StubAPS_SetIntraPanChannel( void )
|
|
{
|
|
uint8 currChannel;
|
|
uint8 rxOnIdle;
|
|
|
|
if ( channelChangeInProgress )
|
|
return ( ZFailure );
|
|
|
|
ZMacGetReq( ZMacChannel, &currChannel );
|
|
if ( currChannel == _NIB.nwkLogicalChannel )
|
|
return ( ZSuccess );
|
|
|
|
channelChangeInProgress = TRUE;
|
|
|
|
// turn MAC receiver off
|
|
rxOnIdle = false;
|
|
ZMacSetReq( ZMacRxOnIdle, &rxOnIdle );
|
|
|
|
// set the NIB channel
|
|
ZMacSetReq( ZMacChannel, &(_NIB.nwkLogicalChannel) );
|
|
|
|
// turn MAC receiver back on
|
|
rxOnIdle = true;
|
|
ZMacSetReq( ZMacRxOnIdle, &rxOnIdle );
|
|
|
|
// set NWK task to run
|
|
nwk_setStateIdle( FALSE );
|
|
|
|
channelChangeInProgress = FALSE;
|
|
|
|
return ( ZSuccess );
|
|
|
|
} /* StubAPS_SetIntraPanChannel */
|
|
|
|
/******************************************************************************
|
|
* @fn StubAPS_InterPan
|
|
*
|
|
* @brief This function checks to see if a PAN is an Inter-PAN.
|
|
*
|
|
* @param panId - PAN ID
|
|
* @param endPoint - endpoint
|
|
*
|
|
* @return TRUE if PAN is Inter-PAN, FALSE otherwise
|
|
*/
|
|
uint8 StubAPS_InterPan( uint16 panId, uint8 endPoint )
|
|
{
|
|
(void)panId; // Intentionally unreferenced parameter
|
|
|
|
// No need to check the MAC/NIB Channels or Source/Destination PAN IDs
|
|
// since it's possible to send Inter-PAN messages within the same network.
|
|
if ( endPoint == STUBAPS_INTER_PAN_EP )
|
|
{
|
|
// Inter-PAN endpoint
|
|
return ( TRUE );
|
|
}
|
|
|
|
return ( FALSE );
|
|
|
|
} /* StubAPS_InterPan */
|
|
|
|
/******************************************************************************
|
|
* @fn StubAPS_RegisterApp
|
|
*
|
|
* @brief This function registers the Application with the Stub APS layer.
|
|
*
|
|
* NOTE: Since Stub APS messages don't include the application
|
|
* endpoint, the application has to register its endpoint
|
|
* with Stub APS.
|
|
*
|
|
* @param epDesc - application's endpoint descriptor
|
|
*
|
|
* @return none
|
|
*/
|
|
void StubAPS_RegisterApp( endPointDesc_t *epDesc )
|
|
{
|
|
appTaskID = *epDesc->task_id;
|
|
appEndPoint = epDesc->endPoint;
|
|
|
|
} /* StubAPS_RegisterApp */
|
|
|
|
/******************************************************************************
|
|
* @fn StubAPS_ZMacCallback
|
|
*
|
|
* @brief This function accepts an inter-PAN message from ZMac.
|
|
*
|
|
* @param msgPtr - received message
|
|
*
|
|
* @return TRUE if message is processed. FALSE otherwise.
|
|
*/
|
|
uint8 StubAPS_ZMacCallback( uint8 *msgPtr )
|
|
{
|
|
uint16 nwk_fc;
|
|
uint8 aps_fc;
|
|
uint8 frameType;
|
|
uint8 *buf = NULL;
|
|
uint8 event = ((osal_event_hdr_t *)msgPtr)->event;
|
|
|
|
if ( event == MAC_MCPS_DATA_IND )
|
|
{
|
|
buf = ((macMcpsDataInd_t *)msgPtr)->msdu.p;
|
|
}
|
|
else if ( event == MAC_MCPS_DATA_CNF )
|
|
{
|
|
buf = ((macMcpsDataCnf_t *)msgPtr)->pDataReq->msdu.p;
|
|
}
|
|
|
|
if ( buf )
|
|
{
|
|
// get the NWK frame control
|
|
nwk_fc = BUILD_UINT16( buf[NWK_HDR_FRAME_CTRL_LSB], buf[NWK_HDR_FRAME_CTRL_MSB] );
|
|
|
|
// frame type
|
|
frameType = (uint8)((nwk_fc >> NWK_FC_FRAME_TYPE) & NWK_FC_FRAME_TYPE_MASK);
|
|
|
|
// check if incoming frame is of the right type
|
|
if ( frameType != STUB_NWK_FRAME_TYPE )
|
|
{
|
|
// message doesn't belong to Stub APS
|
|
return ( FALSE );
|
|
}
|
|
|
|
// get the APS frame control
|
|
aps_fc = buf[STUB_APS_HDR_FRAME_CTRL];
|
|
|
|
// frame type
|
|
frameType = aps_fc & APS_FRAME_TYPE_MASK;
|
|
|
|
// check if incoming frame is of the right type
|
|
if ( frameType != STUB_APS_FRAME )
|
|
{
|
|
// message doesn't belong to Stub APS
|
|
return ( FALSE );
|
|
}
|
|
|
|
// message belongs to Stub APS
|
|
osal_msg_send( StubAPS_TaskID, (uint8 *)msgPtr );
|
|
|
|
return ( TRUE );
|
|
}
|
|
|
|
// message doesn't belong to Stub APS
|
|
return ( FALSE );
|
|
|
|
} /* StubAPS_ZMacCallback */
|
|
|
|
/******************************************************************************
|
|
*
|
|
* Stub APS Inter-PAN interface INTERP and its callbacks.
|
|
*/
|
|
|
|
/******************************************************************************
|
|
* @fn INTERP_DataReq
|
|
*
|
|
* @brief This function requests the transfer of data from the next
|
|
* higher layer to a single peer entity.
|
|
*
|
|
* @param req - APSDE_DataReq_t
|
|
*
|
|
* @return ZStatus_t
|
|
*/
|
|
ZStatus_t INTERP_DataReq( APSDE_DataReq_t *req )
|
|
{
|
|
uint8 apsFrmCtrl;
|
|
uint16 groupID = 0;
|
|
uint8 *buf;
|
|
uint8 hdrLen;
|
|
ZMacDataReq_t dataReq;
|
|
ZStatus_t status;
|
|
|
|
if ( channelChangeInProgress || !StubAPS_InterPan( req->dstPanId, req->dstEP ) )
|
|
return ( ZFailure );
|
|
|
|
osal_memset( &dataReq, 0, sizeof( ZMacDataReq_t ) );
|
|
|
|
// Build Stub APS header
|
|
status = StubAPS_BuildFrameControl( &apsFrmCtrl, &(dataReq.DstAddr), &groupID, req );
|
|
if ( status != ZSuccess )
|
|
return ( status );
|
|
|
|
// set default Stub APS header length
|
|
hdrLen = APS_FRAME_CTRL_FIELD_LEN;
|
|
|
|
// add group ID length
|
|
if ( ( apsFrmCtrl & APS_DELIVERYMODE_MASK ) == APS_FC_DM_GROUP )
|
|
hdrLen += APS_GROUP_ID_FIELD_LEN;
|
|
|
|
// add cluster ID length
|
|
hdrLen += APS_CLUSTERID_FIELD_LEN;
|
|
|
|
// add profile ID length
|
|
hdrLen += APS_PROFILEID_FIELD_LEN;
|
|
|
|
// add default Stub NWK header length
|
|
hdrLen += STUB_NWK_HDR_LEN;
|
|
|
|
// calculate MSDU length
|
|
dataReq.msduLength = hdrLen + req->asduLen;
|
|
|
|
// allocate buffer
|
|
buf = osal_mem_alloc( dataReq.msduLength );
|
|
if ( buf != NULL )
|
|
{
|
|
dataReq.msdu = buf;
|
|
|
|
// Add Stub APS header and data
|
|
StubAPS_BuildMsg( &buf[STUB_APS_HDR_FRAME_CTRL], apsFrmCtrl, groupID, req );
|
|
|
|
// Add Stub NWK header
|
|
StubNWK_BuildMsg( buf );
|
|
|
|
// Set ZMac data request
|
|
dataReq.DstPANId = req->dstPanId;
|
|
dataReq.SrcAddrMode = Addr64Bit;
|
|
dataReq.Handle = req->transID;
|
|
|
|
if ( ( apsFrmCtrl & APS_DELIVERYMODE_MASK ) == APS_FC_DM_UNICAST )
|
|
dataReq.TxOptions = NWK_TXOPTIONS_ACK;
|
|
else
|
|
dataReq.TxOptions = 0;
|
|
|
|
// send the frame
|
|
status = ZMacDataReq( &dataReq );
|
|
|
|
// free the frame
|
|
osal_mem_free( buf );
|
|
}
|
|
else
|
|
{
|
|
// flag a memory error
|
|
status = ZMemError;
|
|
}
|
|
|
|
return ( status );
|
|
|
|
} /* INTERP_DataReq */
|
|
|
|
/******************************************************************************
|
|
* @fn INTERP_DataReqMTU
|
|
*
|
|
* @brief This function requests the MTU (Max Transport Unit) of the
|
|
* Inter-PAN Data Service.
|
|
*
|
|
* @param none
|
|
*
|
|
* @return uint8 - MTU
|
|
*/
|
|
uint8 INTERP_DataReqMTU( void )
|
|
{
|
|
uint8 mtu;
|
|
uint8 hdrLen;
|
|
|
|
// Use maximum header size for Stub APS header
|
|
hdrLen = APS_FRAME_CTRL_FIELD_LEN +
|
|
APS_GROUP_ID_FIELD_LEN +
|
|
APS_CLUSTERID_FIELD_LEN +
|
|
APS_PROFILEID_FIELD_LEN;
|
|
|
|
mtu = MAC_A_MAX_FRAME_SIZE - STUB_NWK_HDR_LEN - hdrLen;
|
|
|
|
return ( mtu );
|
|
|
|
} /* INTERP_DataReqMTU */
|
|
|
|
/****************************************************************************
|
|
* @fn INTERP_DataConfirm
|
|
*
|
|
* @brief This function processes the data confirm from the MAC layer.
|
|
*
|
|
* @param dataCnf - data confirm primitive
|
|
*
|
|
* @return none
|
|
*/
|
|
void INTERP_DataConfirm( ZMacDataCnf_t *dataCnf )
|
|
{
|
|
afDataConfirm( appEndPoint, dataCnf->msduHandle, dataCnf->hdr.Status );
|
|
|
|
} /* INTERP_DataConfirm */
|
|
|
|
/****************************************************************************
|
|
* @fn INTERP_DataIndication
|
|
*
|
|
* @brief This function indicates the transfer of a data SPDU (MSDU)
|
|
* from the MAC layer to the local application layer entity.
|
|
*
|
|
* @param dataInd - data indicate primitive
|
|
*
|
|
* @return none
|
|
*/
|
|
void INTERP_DataIndication( macMcpsDataInd_t *dataInd )
|
|
{
|
|
NLDE_FrameFormat_t snff;
|
|
aps_FrameFormat_t saff;
|
|
zAddrType_t srcAddr;
|
|
NLDE_Signal_t sig;
|
|
|
|
// parse the Stub NWK header
|
|
StubNWK_ParseMsg( dataInd->msdu.p, dataInd->msdu.len, &snff );
|
|
|
|
// Fill in MAC destination address
|
|
snff.macDstAddr = dataInd->mac.dstAddr.addr.shortAddr;
|
|
|
|
// fill in MAC source address (Stub NWK frame doesn't have address fields)
|
|
osal_copyAddress( &srcAddr, (zAddrType_t *)&(dataInd->mac.srcAddr) );
|
|
|
|
// check if incoming frame is of the right type
|
|
if ( snff.frameType != STUB_NWK_FRAME_TYPE )
|
|
return;
|
|
|
|
// check if incoming frame is of the right version
|
|
if ( snff.protocolVersion != NLME_GetProtocolVersion() )
|
|
return;
|
|
|
|
// check if the remaining sun-fields are zero
|
|
if ( ( snff.discoverRoute != 0 ) || ( snff.multicast != 0 ) ||
|
|
( snff.secure != 0 ) || ( snff.srcRouteSet != 0 ) ||
|
|
( snff.dstExtAddrSet != 0 ) || ( snff.srcExtAddrSet != 0 ) )
|
|
{
|
|
return;
|
|
}
|
|
|
|
// parse the Stub APS header
|
|
StubAPS_ParseMsg( &snff, &saff );
|
|
|
|
// check if incoming frame is of the right type
|
|
if ( ( saff.FrmCtrl & APS_FRAME_TYPE_MASK ) != STUB_APS_FRAME )
|
|
return;
|
|
|
|
// check if delivery mode is of the right type
|
|
if ( ( saff.FrmCtrl & APS_DELIVERYMODE_MASK ) == APS_FC_DM_INDIRECT )
|
|
return;
|
|
|
|
// check if incoming frame is unsecured
|
|
if ( saff.FrmCtrl & APS_FC_SECURITY )
|
|
return;
|
|
|
|
// check if there's no extended header
|
|
if ( saff.FrmCtrl & APS_FC_EXTENDED )
|
|
return;
|
|
|
|
// Set the endpoints
|
|
saff.DstEndPoint = appEndPoint;
|
|
saff.SrcEndPoint = STUBAPS_INTER_PAN_EP;
|
|
|
|
// Set the signal strength information
|
|
sig.LinkQuality = dataInd->mac.mpduLinkQuality;
|
|
sig.correlation = dataInd->mac.correlation;
|
|
sig.rssi = dataInd->mac.rssi;
|
|
|
|
APSDE_DataIndication( &saff, &srcAddr, dataInd->mac.srcPanId,
|
|
&sig, snff.broadcastId, FALSE, dataInd->mac.timestamp );
|
|
|
|
} /* INTERP_DataIndication */
|
|
|
|
|
|
/*********************************************************************
|
|
*********************************************************************/
|