123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086 |
- /**************************************************************************************************
- Filename: AF.c
- Revised: $Date: 2011-11-18 16:03:29 -0800 (Fri, 18 Nov 2011) $
- Revision: $Revision: 28423 $
- Description: Application Framework - Device Description helper functions
- Copyright 2004-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 "AF.h"
- #include "nwk_globals.h"
- #include "nwk_util.h"
- #include "aps_groups.h"
- #include "ZDProfile.h"
- #include "aps_frag.h"
- #include "rtg.h"
- #if defined ( MT_AF_CB_FUNC )
- #include "MT_AF.h"
- #endif
- #if defined ( INTER_PAN )
- #include "stub_aps.h"
- #endif
- /*********************************************************************
- * MACROS
- */
- /*********************************************************************
- * @fn afSend
- *
- * @brief Helper macro for V1 API to invoke V2 API.
- *
- * input parameters
- *
- * @param *dstAddr - Full ZB destination address: Nwk Addr + End Point.
- * @param srcEP - Origination (i.e. respond to or ack to) End Point.
- * @param cID - A valid cluster ID as specified by the Profile.
- * @param len - Number of bytes of data pointed to by next param.
- * @param *buf - A pointer to the data bytes to send.
- * @param options - Valid bit mask of AF Tx Options as defined in AF.h.
- * @param *transID - A pointer to a byte which can be modified and which will
- * be used as the transaction sequence number of the msg.
- *
- * output parameters
- *
- * @param *transID - Incremented by one if the return value is success.
- *
- * @return afStatus_t - See previous definition of afStatus_... types.
- */
- #define afSend( dstAddr, srcEP, cID, len, buf, transID, options, radius ) \
- AF_DataRequest( (dstAddr), afFindEndPointDesc( (srcEP) ), \
- (cID), (len), (buf), (transID), (options), (radius) )
- /*********************************************************************
- * GLOBAL VARIABLES
- */
- epList_t *epList;
- /*********************************************************************
- * LOCAL FUNCTIONS
- */
- static void afBuildMSGIncoming( aps_FrameFormat_t *aff, endPointDesc_t *epDesc,
- zAddrType_t *SrcAddress, uint16 SrcPanId, NLDE_Signal_t *sig,
- uint8 nwkSeqNum, uint8 SecurityUse, uint32 timestamp );
- static epList_t *afFindEndPointDescList( uint8 EndPoint );
- static pDescCB afGetDescCB( endPointDesc_t *epDesc );
- /*********************************************************************
- * PUBLIC FUNCTIONS
- */
- /*********************************************************************
- * @fn afInit
- *
- * @brief Initialization function for the AF.
- *
- * @param none
- *
- * @return none
- void afInit( void )
- {
- }
- */
- /*********************************************************************
- * @fn afRegisterExtended
- *
- * @brief Register an Application's EndPoint description.
- *
- * @param epDesc - pointer to the Application's endpoint descriptor.
- * @param descFn - pointer to descriptor callback function
- *
- * NOTE: The memory that epDesc is pointing to must exist after this call.
- *
- * @return Pointer to epList_t on success, NULL otherwise.
- */
- epList_t *afRegisterExtended( endPointDesc_t *epDesc, pDescCB descFn )
- {
- epList_t *ep = osal_mem_alloc(sizeof(epList_t));
- if (ep != NULL)
- {
- ep->nextDesc = epList;
- epList = ep;
- ep->epDesc = epDesc;
- ep->pfnDescCB = descFn;
- ep->apsfCfg.frameDelay = APSF_DEFAULT_INTERFRAME_DELAY;
- ep->apsfCfg.windowSize = APSF_DEFAULT_WINDOW_SIZE;
- ep->flags = eEP_AllowMatch; // Default to allow Match Descriptor.
- }
- return ep;
- }
- /*********************************************************************
- * @fn afRegister
- *
- * @brief Register an Application's EndPoint description.
- *
- * @param epDesc - pointer to the Application's endpoint descriptor.
- *
- * NOTE: The memory that epDesc is pointing to must exist after this call.
- *
- * @return afStatus_SUCCESS - Registered
- * afStatus_MEM_FAIL - not enough memory to add descriptor
- * afStatus_INVALID_PARAMETER - duplicate endpoint
- */
- afStatus_t afRegister( endPointDesc_t *epDesc )
- {
- if (afFindEndPointDescList(epDesc->endPoint)) // Look for duplicate endpoint.
- {
- return afStatus_INVALID_PARAMETER;
- }
- return ((NULL == afRegisterExtended(epDesc, NULL)) ? afStatus_MEM_FAIL : afStatus_SUCCESS);
- }
- /*********************************************************************
- * @fn afDelete
- *
- * @brief Delete an Application's EndPoint descriptor and frees the memory
- *
- * @param EndPoint - Application Endpoint to delete
- *
- * @return afStatus_SUCCESS - endpoint deleted
- * afStatus_INVALID_PARAMETER - endpoint not found
- * afStatus_FAILED - endpoint list empty
- */
- afStatus_t afDelete( uint8 EndPoint )
- {
- epList_t *epCurrent;
- epList_t *epPrevious;
- if (epList != NULL)
- {
- epPrevious = epCurrent = epList;
- // first element of the list matches
- if (epCurrent->epDesc->endPoint == EndPoint)
- {
- epList = epCurrent->nextDesc;
- osal_mem_free(epCurrent);
- return (afStatus_SUCCESS);
- }
- else
- {
- // search the list
- for (epCurrent = epPrevious->nextDesc; epCurrent != NULL; epPrevious = epCurrent)
- {
- if (epCurrent->epDesc->endPoint == EndPoint)
- {
- epPrevious->nextDesc = epCurrent->nextDesc;
- osal_mem_free(epCurrent);
- // delete the entry and free the memory
- return (afStatus_SUCCESS);
- }
- }
- }
- // no endpoint found
- return (afStatus_INVALID_PARAMETER);
- }
- else
- {
- // epList is empty
- return (afStatus_FAILED);
- }
- }
- /*********************************************************************
- * @fn afDataConfirm
- *
- * @brief This function will generate the Data Confirm back to
- * the application.
- *
- * @param endPoint - confirm end point
- * @param transID - transaction ID from APSDE_DATA_REQUEST
- * @param status - status of APSDE_DATA_REQUEST
- *
- * @return none
- */
- void afDataConfirm( uint8 endPoint, uint8 transID, ZStatus_t status )
- {
- endPointDesc_t *epDesc;
- afDataConfirm_t *msgPtr;
- // Find the endpoint description
- epDesc = afFindEndPointDesc( endPoint );
- if ( epDesc == NULL )
- return;
- // Determine the incoming command type
- msgPtr = (afDataConfirm_t *)osal_msg_allocate( sizeof(afDataConfirm_t) );
- if ( msgPtr )
- {
- // Build the Data Confirm message
- msgPtr->hdr.event = AF_DATA_CONFIRM_CMD;
- msgPtr->hdr.status = status;
- msgPtr->endpoint = endPoint;
- msgPtr->transID = transID;
- #if defined ( MT_AF_CB_FUNC )
- /* If MT has subscribed for this callback, don't send as a message. */
- if ( AFCB_CHECK(CB_ID_AF_DATA_CNF,*(epDesc->task_id)) )
- {
- /* Send callback if it's subscribed */
- MT_AfDataConfirm ((void *)msgPtr);
- /* Release the memory. */
- osal_msg_deallocate( (void *)msgPtr );
- }
- else
- #endif
- {
- /* send message through task message */
- osal_msg_send( *(epDesc->task_id), (uint8 *)msgPtr );
- }
- }
- }
- /*********************************************************************
- * @fn afIncomingData
- *
- * @brief Transfer a data PDU (ASDU) from the APS sub-layer to the AF.
- *
- * @param aff - pointer to APS frame format
- * @param SrcAddress - Source address
- * @param SrcPanId - Source PAN ID
- * @param sig - incoming message's link quality
- * @param nwkSeqNum - incoming network sequence number (from nwk header frame)
- * @param SecurityUse - Security enable/disable
- * @param timestamp - the MAC Timer2 timestamp at Rx.
- *
- * @return none
- */
- void afIncomingData( aps_FrameFormat_t *aff, zAddrType_t *SrcAddress, uint16 SrcPanId,
- NLDE_Signal_t *sig, uint8 nwkSeqNum, uint8 SecurityUse, uint32 timestamp )
- {
- endPointDesc_t *epDesc = NULL;
- epList_t *pList = epList;
- #if !defined ( APS_NO_GROUPS )
- uint8 grpEp = APS_GROUPS_EP_NOT_FOUND;
- #endif
- if ( ((aff->FrmCtrl & APS_DELIVERYMODE_MASK) == APS_FC_DM_GROUP) )
- {
- #if !defined ( APS_NO_GROUPS )
- // Find the first endpoint for this group
- grpEp = aps_FindGroupForEndpoint( aff->GroupID, APS_GROUPS_FIND_FIRST );
- if ( grpEp == APS_GROUPS_EP_NOT_FOUND )
- return; // No endpoint found
- epDesc = afFindEndPointDesc( grpEp );
- if ( epDesc == NULL )
- return; // Endpoint descriptor not found
- pList = afFindEndPointDescList( epDesc->endPoint );
- #else
- return; // Not supported
- #endif
- }
- else if ( aff->DstEndPoint == AF_BROADCAST_ENDPOINT )
- {
- // Set the list
- if ( pList != NULL )
- {
- epDesc = pList->epDesc;
- }
- }
- else if ( (epDesc = afFindEndPointDesc( aff->DstEndPoint )) )
- {
- pList = afFindEndPointDescList( epDesc->endPoint );
- }
- while ( epDesc )
- {
- uint16 epProfileID = 0xFFFF; // Invalid Profile ID
- if ( pList->pfnDescCB )
- {
- uint16 *pID = (uint16 *)(pList->pfnDescCB(
- AF_DESCRIPTOR_PROFILE_ID, epDesc->endPoint ));
- if ( pID )
- {
- epProfileID = *pID;
- osal_mem_free( pID );
- }
- }
- else if ( epDesc->simpleDesc )
- {
- epProfileID = epDesc->simpleDesc->AppProfId;
- }
- if ( (aff->ProfileID == epProfileID) ||
- ((epDesc->endPoint == ZDO_EP) && (aff->ProfileID == ZDO_PROFILE_ID)) )
- {
- {
- // Save original endpoint
- uint8 endpoint = aff->DstEndPoint;
- // overwrite with descriptor's endpoint
- aff->DstEndPoint = epDesc->endPoint;
- afBuildMSGIncoming( aff, epDesc, SrcAddress, SrcPanId, sig,
- nwkSeqNum, SecurityUse, timestamp );
- // Restore with original endpoint
- aff->DstEndPoint = endpoint;
- }
- }
- if ( ((aff->FrmCtrl & APS_DELIVERYMODE_MASK) == APS_FC_DM_GROUP) )
- {
- #if !defined ( APS_NO_GROUPS )
- // Find the next endpoint for this group
- grpEp = aps_FindGroupForEndpoint( aff->GroupID, grpEp );
- if ( grpEp == APS_GROUPS_EP_NOT_FOUND )
- return; // No endpoint found
- epDesc = afFindEndPointDesc( grpEp );
- if ( epDesc == NULL )
- return; // Endpoint descriptor not found
- pList = afFindEndPointDescList( epDesc->endPoint );
- #else
- return;
- #endif
- }
- else if ( aff->DstEndPoint == AF_BROADCAST_ENDPOINT )
- {
- pList = pList->nextDesc;
- if ( pList )
- epDesc = pList->epDesc;
- else
- epDesc = NULL;
- }
- else
- epDesc = NULL;
- }
- }
- /*********************************************************************
- * @fn afBuildMSGIncoming
- *
- * @brief Build the message for the app
- *
- * @param
- *
- * @return pointer to next in data buffer
- */
- static void afBuildMSGIncoming( aps_FrameFormat_t *aff, endPointDesc_t *epDesc,
- zAddrType_t *SrcAddress, uint16 SrcPanId, NLDE_Signal_t *sig,
- uint8 nwkSeqNum, uint8 SecurityUse, uint32 timestamp )
- {
- afIncomingMSGPacket_t *MSGpkt;
- const uint8 len = sizeof( afIncomingMSGPacket_t ) + aff->asduLength;
- uint8 *asdu = aff->asdu;
- MSGpkt = (afIncomingMSGPacket_t *)osal_msg_allocate( len );
- if ( MSGpkt == NULL )
- {
- return;
- }
- MSGpkt->hdr.event = AF_INCOMING_MSG_CMD;
- MSGpkt->groupId = aff->GroupID;
- MSGpkt->clusterId = aff->ClusterID;
- afCopyAddress( &MSGpkt->srcAddr, SrcAddress );
- MSGpkt->srcAddr.endPoint = aff->SrcEndPoint;
- MSGpkt->endPoint = epDesc->endPoint;
- MSGpkt->wasBroadcast = aff->wasBroadcast;
- MSGpkt->LinkQuality = sig->LinkQuality;
- MSGpkt->correlation = sig->correlation;
- MSGpkt->rssi = sig->rssi;
- MSGpkt->SecurityUse = SecurityUse;
- MSGpkt->timestamp = timestamp;
- MSGpkt->nwkSeqNum = nwkSeqNum;
- MSGpkt->macDestAddr = aff->macDestAddr;
- MSGpkt->srcAddr.panId = SrcPanId;
- MSGpkt->cmd.TransSeqNumber = 0;
- MSGpkt->cmd.DataLength = aff->asduLength;
- if ( MSGpkt->cmd.DataLength )
- {
- MSGpkt->cmd.Data = (uint8 *)(MSGpkt + 1);
- osal_memcpy( MSGpkt->cmd.Data, asdu, MSGpkt->cmd.DataLength );
- }
- else
- {
- MSGpkt->cmd.Data = NULL;
- }
- #if defined ( MT_AF_CB_FUNC )
- // If ZDO or SAPI have registered for this endpoint, dont intercept it here
- if (AFCB_CHECK(CB_ID_AF_DATA_IND, *(epDesc->task_id)))
- {
- MT_AfIncomingMsg( (void *)MSGpkt );
- // Release the memory.
- osal_msg_deallocate( (void *)MSGpkt );
- }
- else
- #endif
- {
- // Send message through task message.
- osal_msg_send( *(epDesc->task_id), (uint8 *)MSGpkt );
- }
- }
- /*********************************************************************
- * @fn AF_DataRequest
- *
- * @brief Common functionality for invoking APSDE_DataReq() for both
- * SendMulti and MSG-Send.
- *
- * input parameters
- *
- * @param *dstAddr - Full ZB destination address: Nwk Addr + End Point.
- * @param *srcEP - Origination (i.e. respond to or ack to) End Point Descr.
- * @param cID - A valid cluster ID as specified by the Profile.
- * @param len - Number of bytes of data pointed to by next param.
- * @param *buf - A pointer to the data bytes to send.
- * @param *transID - A pointer to a byte which can be modified and which will
- * be used as the transaction sequence number of the msg.
- * @param options - Valid bit mask of Tx options.
- * @param radius - Normally set to AF_DEFAULT_RADIUS.
- *
- * output parameters
- *
- * @param *transID - Incremented by one if the return value is success.
- *
- * @return afStatus_t - See previous definition of afStatus_... types.
- */
- uint8 AF_DataRequestDiscoverRoute = TRUE;
- afStatus_t AF_DataRequest( afAddrType_t *dstAddr, endPointDesc_t *srcEP,
- uint16 cID, uint16 len, uint8 *buf, uint8 *transID,
- uint8 options, uint8 radius )
- {
- pDescCB pfnDescCB;
- ZStatus_t stat;
- APSDE_DataReq_t req;
- afDataReqMTU_t mtu;
- // Verify source end point
- if ( srcEP == NULL )
- {
- return afStatus_INVALID_PARAMETER;
- }
- #if !defined( REFLECTOR )
- if ( dstAddr->addrMode == afAddrNotPresent )
- {
- return afStatus_INVALID_PARAMETER;
- }
- #endif
- // Check if route is available before sending data
- if ( options & AF_LIMIT_CONCENTRATOR )
- {
- if ( dstAddr->addrMode != afAddr16Bit )
- {
- return ( afStatus_INVALID_PARAMETER );
- }
- // First, make sure the destination is not its self, then check for an existing route.
- if ( (dstAddr->addr.shortAddr != NLME_GetShortAddr())
- && (RTG_CheckRtStatus( dstAddr->addr.shortAddr, RT_ACTIVE, (MTO_ROUTE | NO_ROUTE_CACHE) ) != RTG_SUCCESS) )
- {
- // A valid route to a concentrator wasn't found
- return ( afStatus_NO_ROUTE );
- }
- }
- // Validate broadcasting
- if ( ( dstAddr->addrMode == afAddr16Bit ) ||
- ( dstAddr->addrMode == afAddrBroadcast ) )
- {
- // Check for valid broadcast values
- if( ADDR_NOT_BCAST != NLME_IsAddressBroadcast( dstAddr->addr.shortAddr ) )
- {
- // Force mode to broadcast
- dstAddr->addrMode = afAddrBroadcast;
- }
- else
- {
- // Address is not a valid broadcast type
- if ( dstAddr->addrMode == afAddrBroadcast )
- {
- return afStatus_INVALID_PARAMETER;
- }
- }
- }
- else if ( dstAddr->addrMode != afAddr64Bit &&
- dstAddr->addrMode != afAddrGroup &&
- dstAddr->addrMode != afAddrNotPresent )
- {
- return afStatus_INVALID_PARAMETER;
- }
- // Set destination address
- req.dstAddr.addrMode = dstAddr->addrMode;
- if ( dstAddr->addrMode == afAddr64Bit )
- osal_cpyExtAddr( req.dstAddr.addr.extAddr, dstAddr->addr.extAddr );
- else
- req.dstAddr.addr.shortAddr = dstAddr->addr.shortAddr;
- req.profileID = ZDO_PROFILE_ID;
- if ( (pfnDescCB = afGetDescCB( srcEP )) )
- {
- uint16 *pID = (uint16 *)(pfnDescCB(
- AF_DESCRIPTOR_PROFILE_ID, srcEP->endPoint ));
- if ( pID )
- {
- req.profileID = *pID;
- osal_mem_free( pID );
- }
- }
- else if ( srcEP->simpleDesc )
- {
- req.profileID = srcEP->simpleDesc->AppProfId;
- }
- req.txOptions = 0;
- if ( ( options & AF_ACK_REQUEST ) &&
- ( req.dstAddr.addrMode != AddrBroadcast ) &&
- ( req.dstAddr.addrMode != AddrGroup ) )
- {
- req.txOptions |= APS_TX_OPTIONS_ACK;
- }
- if ( options & AF_SKIP_ROUTING )
- {
- req.txOptions |= APS_TX_OPTIONS_SKIP_ROUTING;
- }
- if ( options & AF_EN_SECURITY )
- {
- req.txOptions |= APS_TX_OPTIONS_SECURITY_ENABLE;
- mtu.aps.secure = TRUE;
- }
- else
- {
- mtu.aps.secure = FALSE;
- }
- if ( options & AF_PREPROCESS )
- {
- req.txOptions |= APS_TX_OPTIONS_PREPROCESS;
- }
- mtu.kvp = FALSE;
- req.transID = *transID;
- req.srcEP = srcEP->endPoint;
- req.dstEP = dstAddr->endPoint;
- req.clusterID = cID;
- req.asduLen = len;
- req.asdu = buf;
- req.discoverRoute = AF_DataRequestDiscoverRoute;//(uint8)((options & AF_DISCV_ROUTE) ? 1 : 0);
- req.radiusCounter = radius;
- #if defined ( INTER_PAN )
- req.dstPanId = dstAddr->panId;
- if ( StubAPS_InterPan( dstAddr->panId, dstAddr->endPoint ) )
- {
- if ( len > INTERP_DataReqMTU() )
- {
- stat = afStatus_INVALID_PARAMETER;
- }
- else
- {
- stat = INTERP_DataReq( &req );
- }
- }
- else
- #endif // INTER_PAN
- {
- if (len > afDataReqMTU( &mtu ) )
- {
- if (apsfSendFragmented)
- {
- stat = (*apsfSendFragmented)( &req );
- }
- else
- {
- stat = afStatus_INVALID_PARAMETER;
- }
- }
- else
- {
- stat = APSDE_DataReq( &req );
- }
- }
- /*
- * If this is an EndPoint-to-EndPoint message on the same device, it will not
- * get added to the NWK databufs. So it will not go OTA and it will not get
- * a MACCB_DATA_CONFIRM_CMD callback. Thus it is necessary to generate the
- * AF_DATA_CONFIRM_CMD here. Note that APSDE_DataConfirm() only generates one
- * message with the first in line TransSeqNumber, even on a multi message.
- * Also note that a reflected msg will not have its confirmation generated
- * here.
- */
- if ( (req.dstAddr.addrMode == Addr16Bit) &&
- (req.dstAddr.addr.shortAddr == NLME_GetShortAddr()) )
- {
- afDataConfirm( srcEP->endPoint, *transID, stat );
- }
- if ( stat == afStatus_SUCCESS )
- {
- (*transID)++;
- }
- return (afStatus_t)stat;
- }
- #if defined ( ZIGBEE_SOURCE_ROUTING )
- /*********************************************************************
- * @fn AF_DataRequestSrcRtg
- *
- * @brief Common functionality for invoking APSDE_DataReq() for both
- * SendMulti and MSG-Send.
- *
- * input parameters
- *
- * @param *dstAddr - Full ZB destination address: Nwk Addr + End Point.
- * @param *srcEP - Origination (i.e. respond to or ack to) End Point Descr.
- * @param cID - A valid cluster ID as specified by the Profile.
- * @param len - Number of bytes of data pointed to by next param.
- * @param *buf - A pointer to the data bytes to send.
- * @param *transID - A pointer to a byte which can be modified and which will
- * be used as the transaction sequence number of the msg.
- * @param options - Valid bit mask of Tx options.
- * @param radius - Normally set to AF_DEFAULT_RADIUS.
- * @param relayCnt - Number of devices in the relay list
- * @param pRelayList - Pointer to the relay list
- *
- * output parameters
- *
- * @param *transID - Incremented by one if the return value is success.
- *
- * @return afStatus_t - See previous definition of afStatus_... types.
- */
- afStatus_t AF_DataRequestSrcRtg( afAddrType_t *dstAddr, endPointDesc_t *srcEP,
- uint16 cID, uint16 len, uint8 *buf, uint8 *transID,
- uint8 options, uint8 radius, uint8 relayCnt, uint16* pRelayList )
- {
- uint8 status;
- /* Add the source route to the source routing table */
- status = RTG_AddSrcRtgEntry_Guaranteed( dstAddr->addr.shortAddr, relayCnt,
- pRelayList );
- if( status == RTG_SUCCESS)
- {
- /* Call AF_DataRequest to send the data */
- status = AF_DataRequest( dstAddr, srcEP, cID, len, buf, transID, options, radius );
- }
- else if( status == RTG_INVALID_PATH )
- {
- /* The source route relay count is exceeding the network limit */
- status = afStatus_INVALID_PARAMETER;
- }
- else
- {
- /* The guaranteed adding entry fails due to memory failure */
- status = afStatus_MEM_FAIL;
- }
- return status;
- }
- #endif
- /*********************************************************************
- * @fn afFindEndPointDescList
- *
- * @brief Find the endpoint description entry from the endpoint
- * number.
- *
- * @param EndPoint - Application Endpoint to look for
- *
- * @return the address to the endpoint/interface description entry
- */
- static epList_t *afFindEndPointDescList( uint8 EndPoint )
- {
- epList_t *epSearch;
- for (epSearch = epList; epSearch != NULL; epSearch = epSearch->nextDesc)
- {
- if (epSearch->epDesc->endPoint == EndPoint)
- {
- break;
- }
- }
- return epSearch;
- }
- /*********************************************************************
- * @fn afFindEndPointDesc
- *
- * @brief Find the endpoint description entry from the endpoint
- * number.
- *
- * @param EndPoint - Application Endpoint to look for
- *
- * @return the address to the endpoint/interface description entry
- */
- endPointDesc_t *afFindEndPointDesc( uint8 EndPoint )
- {
- epList_t *epSearch;
- // Look for the endpoint
- epSearch = afFindEndPointDescList( EndPoint );
- if ( epSearch )
- return ( epSearch->epDesc );
- else
- return ( (endPointDesc_t *)NULL );
- }
- /*********************************************************************
- * @fn afFindSimpleDesc
- *
- * @brief Find the Simple Descriptor from the endpoint number.
- *
- * @param EP - Application Endpoint to look for.
- *
- * @return Non-zero to indicate that the descriptor memory must be freed.
- */
- uint8 afFindSimpleDesc( SimpleDescriptionFormat_t **ppDesc, uint8 EP )
- {
- epList_t *epItem = afFindEndPointDescList( EP );
- uint8 rtrn = FALSE;
- if ( epItem )
- {
- if ( epItem->pfnDescCB )
- {
- *ppDesc = epItem->pfnDescCB( AF_DESCRIPTOR_SIMPLE, EP );
- rtrn = TRUE;
- }
- else
- {
- *ppDesc = epItem->epDesc->simpleDesc;
- }
- }
- else
- {
- *ppDesc = NULL;
- }
- return rtrn;
- }
- /*********************************************************************
- * @fn afGetDescCB
- *
- * @brief Get the Descriptor callback function.
- *
- * @param epDesc - pointer to the endpoint descriptor
- *
- * @return function pointer or NULL
- */
- static pDescCB afGetDescCB( endPointDesc_t *epDesc )
- {
- epList_t *epSearch;
- // Start at the beginning
- epSearch = epList;
- // Look through the list until the end
- while ( epSearch )
- {
- // Is there a match?
- if ( epSearch->epDesc == epDesc )
- {
- return ( epSearch->pfnDescCB );
- }
- else
- epSearch = epSearch->nextDesc; // Next entry
- }
- return ( (pDescCB)NULL );
- }
- /*********************************************************************
- * @fn afDataReqMTU
- *
- * @brief Get the Data Request MTU(Max Transport Unit).
- *
- * @param fields - afDataReqMTU_t
- *
- * @return uint8(MTU)
- */
- uint8 afDataReqMTU( afDataReqMTU_t* fields )
- {
- uint8 len;
- uint8 hdr;
- if ( fields->kvp == TRUE )
- {
- hdr = AF_HDR_KVP_MAX_LEN;
- }
- else
- {
- hdr = AF_HDR_V1_1_MAX_LEN;
- }
- len = (uint8)(APSDE_DataReqMTU(&fields->aps) - hdr);
- return len;
- }
- /*********************************************************************
- * @fn afGetMatch
- *
- * @brief Set the allow response flag.
- *
- * @param ep - Application Endpoint to look for
- * @param action - true - allow response, false - no response
- *
- * @return TRUE allow responses, FALSE no response
- */
- uint8 afGetMatch( uint8 ep )
- {
- epList_t *epSearch;
- // Look for the endpoint
- epSearch = afFindEndPointDescList( ep );
- if ( epSearch )
- {
- if ( epSearch->flags & eEP_AllowMatch )
- return ( TRUE );
- else
- return ( FALSE );
- }
- else
- return ( FALSE );
- }
- /*********************************************************************
- * @fn afSetMatch
- *
- * @brief Set the allow response flag.
- *
- * @param ep - Application Endpoint to look for
- * @param action - true - allow response, false - no response
- *
- * @return TRUE if success, FALSE if endpoint not found
- */
- uint8 afSetMatch( uint8 ep, uint8 action )
- {
- epList_t *epSearch;
- // Look for the endpoint
- epSearch = afFindEndPointDescList( ep );
- if ( epSearch )
- {
- if ( action )
- {
- epSearch->flags |= eEP_AllowMatch;
- }
- else
- {
- epSearch->flags &= (eEP_AllowMatch ^ 0xFFFF);
- }
- return ( TRUE );
- }
- else
- return ( FALSE );
- }
- /*********************************************************************
- * @fn afNumEndPoints
- *
- * @brief Returns the number of endpoints defined (including 0)
- *
- * @param none
- *
- * @return number of endpoints
- */
- uint8 afNumEndPoints( void )
- {
- epList_t *epSearch;
- uint8 endpoints;
- // Start at the beginning
- epSearch = epList;
- endpoints = 0;
- while ( epSearch )
- {
- endpoints++;
- epSearch = epSearch->nextDesc;
- }
- return ( endpoints );
- }
- /*********************************************************************
- * @fn afEndPoints
- *
- * @brief Fills in the passed in buffer with the endpoint (numbers).
- * Use afNumEndPoints to find out how big a buffer to supply.
- *
- * @param epBuf - pointer to mem used
- *
- * @return void
- */
- void afEndPoints( uint8 *epBuf, uint8 skipZDO )
- {
- epList_t *epSearch;
- uint8 endPoint;
- // Start at the beginning
- epSearch = epList;
- while ( epSearch )
- {
- endPoint = epSearch->epDesc->endPoint;
- if ( !skipZDO || endPoint != 0 )
- *epBuf++ = endPoint;
- epSearch = epSearch->nextDesc;
- }
- }
- /*********************************************************************
- * @fn afCopyAddress
- *
- * @brief Fills in the passed in afAddrType_t parameter with the corresponding information
- * from the zAddrType_t parameter.
- *
- * @param epBuf - pointer to mem used
- *
- * @return void
- */
- void afCopyAddress( afAddrType_t *afAddr, zAddrType_t *zAddr )
- {
- afAddr->addrMode = (afAddrMode_t)zAddr->addrMode;
- if ( zAddr->addrMode == Addr64Bit )
- {
- (void)osal_cpyExtAddr( afAddr->addr.extAddr, zAddr->addr.extAddr );
- }
- else
- {
- afAddr->addr.shortAddr = zAddr->addr.shortAddr;
- }
- // Since zAddrType_t has no INTER-PAN information, set the panId member to zero.
- afAddr->panId = 0;
- }
- /**************************************************************************************************
- * @fn afAPSF_ConfigGet
- *
- * @brief This function ascertains the fragmentation configuration that corresponds to
- * the specified EndPoint.
- *
- * input parameters
- *
- * @param endPoint - The source EP of a Tx or destination EP of a Rx fragmented message.
- *
- * output parameters
- *
- * @param pCfg - A pointer to an APSF configuration structure to fill with values.
- *
- * @return None.
- */
- void afAPSF_ConfigGet(uint8 endPoint, afAPSF_Config_t *pCfg)
- {
- epList_t *pList = afFindEndPointDescList(endPoint);
- if (pList == NULL)
- {
- pCfg->frameDelay = APSF_DEFAULT_INTERFRAME_DELAY;
- pCfg->windowSize = APSF_DEFAULT_WINDOW_SIZE;
- }
- else
- {
- (void)osal_memcpy(pCfg, &pList->apsfCfg, sizeof(afAPSF_Config_t));
- }
- }
- /**************************************************************************************************
- * @fn afAPSF_ConfigSet
- *
- * @brief This function attempts to set the fragmentation configuration that corresponds to
- * the specified EndPoint.
- *
- * input parameters
- *
- * @param endPoint - The specific EndPoint for which to set the fragmentation configuration.
- * @param pCfg - A pointer to an APSF configuration structure to fill with values.
- *
- * output parameters
- *
- * None.
- *
- * @return afStatus_SUCCESS for success.
- * afStatus_INVALID_PARAMETER if the specified EndPoint is not registered.
- */
- afStatus_t afAPSF_ConfigSet(uint8 endPoint, afAPSF_Config_t *pCfg)
- {
- epList_t *pList = afFindEndPointDescList(endPoint);
- if (pList == NULL)
- {
- return afStatus_INVALID_PARAMETER;
- }
- (void)osal_memcpy(&pList->apsfCfg, pCfg, sizeof(afAPSF_Config_t));
- return afStatus_SUCCESS;
- }
- /**************************************************************************************************
- */
|