AF.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912
  1. /**************************************************************************************************
  2. Filename: AF.c
  3. Revised: $Date: 2009-03-19 13:41:00 -0700 (Thu, 19 Mar 2009) $
  4. Revision: $Revision: 19470 $
  5. Description: Application Framework - Device Description helper functions
  6. Copyright 2004-2009 Texas Instruments Incorporated. All rights reserved.
  7. IMPORTANT: Your use of this Software is limited to those specific rights
  8. granted under the terms of a software license agreement between the user
  9. who downloaded the software, his/her employer (which must be your employer)
  10. and Texas Instruments Incorporated (the "License"). You may not use this
  11. Software unless you agree to abide by the terms of the License. The License
  12. limits your use, and you acknowledge, that the Software may not be modified,
  13. copied or distributed unless embedded on a Texas Instruments microcontroller
  14. or used solely and exclusively in conjunction with a Texas Instruments radio
  15. frequency transceiver, which is integrated into your product. Other than for
  16. the foregoing purpose, you may not use, reproduce, copy, prepare derivative
  17. works of, modify, distribute, perform, display or sell this Software and/or
  18. its documentation for any purpose.
  19. YOU FURTHER ACKNOWLEDGE AND AGREE THAT THE SOFTWARE AND DOCUMENTATION ARE
  20. PROVIDED “AS IS” WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS OR IMPLIED,
  21. INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY, TITLE,
  22. NON-INFRINGEMENT AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL
  23. TEXAS INSTRUMENTS OR ITS LICENSORS BE LIABLE OR OBLIGATED UNDER CONTRACT,
  24. NEGLIGENCE, STRICT LIABILITY, CONTRIBUTION, BREACH OF WARRANTY, OR OTHER
  25. LEGAL EQUITABLE THEORY ANY DIRECT OR INDIRECT DAMAGES OR EXPENSES
  26. INCLUDING BUT NOT LIMITED TO ANY INCIDENTAL, SPECIAL, INDIRECT, PUNITIVE
  27. OR CONSEQUENTIAL DAMAGES, LOST PROFITS OR LOST DATA, COST OF PROCUREMENT
  28. OF SUBSTITUTE GOODS, TECHNOLOGY, SERVICES, OR ANY CLAIMS BY THIRD PARTIES
  29. (INCLUDING BUT NOT LIMITED TO ANY DEFENSE THEREOF), OR OTHER SIMILAR COSTS.
  30. Should you have any questions regarding your right to use this Software,
  31. contact Texas Instruments Incorporated at www.TI.com.
  32. **************************************************************************************************/
  33. /*********************************************************************
  34. * INCLUDES
  35. */
  36. #include "OSAL.h"
  37. #include "AF.h"
  38. #include "nwk_globals.h"
  39. #include "nwk_util.h"
  40. #include "aps_groups.h"
  41. #include "ZDProfile.h"
  42. #include "aps_frag.h"
  43. #if defined ( MT_AF_CB_FUNC )
  44. #include "MT_AF.h"
  45. #endif
  46. #if defined ( INTER_PAN )
  47. #include "stub_aps.h"
  48. #endif
  49. /*********************************************************************
  50. * MACROS
  51. */
  52. /*********************************************************************
  53. * @fn afSend
  54. *
  55. * @brief Helper macro for V1 API to invoke V2 API.
  56. *
  57. * input parameters
  58. *
  59. * @param *dstAddr - Full ZB destination address: Nwk Addr + End Point.
  60. * @param srcEP - Origination (i.e. respond to or ack to) End Point.
  61. * @param cID - A valid cluster ID as specified by the Profile.
  62. * @param len - Number of bytes of data pointed to by next param.
  63. * @param *buf - A pointer to the data bytes to send.
  64. * @param options - Valid bit mask of AF Tx Options as defined in AF.h.
  65. * @param *transID - A pointer to a byte which can be modified and which will
  66. * be used as the transaction sequence number of the msg.
  67. *
  68. * output parameters
  69. *
  70. * @param *transID - Incremented by one if the return value is success.
  71. *
  72. * @return afStatus_t - See previous definition of afStatus_... types.
  73. */
  74. #define afSend( dstAddr, srcEP, cID, len, buf, transID, options, radius ) \
  75. AF_DataRequest( (dstAddr), afFindEndPointDesc( (srcEP) ), \
  76. (cID), (len), (buf), (transID), (options), (radius) )
  77. /*********************************************************************
  78. * CONSTANTS
  79. */
  80. /*********************************************************************
  81. * TYPEDEFS
  82. */
  83. /*********************************************************************
  84. * GLOBAL VARIABLES
  85. */
  86. epList_t *epList;
  87. /*********************************************************************
  88. * EXTERNAL VARIABLES
  89. */
  90. /*********************************************************************
  91. * EXTERNAL FUNCTIONS
  92. */
  93. /*********************************************************************
  94. * LOCAL VARIABLES
  95. */
  96. /*********************************************************************
  97. * LOCAL FUNCTIONS
  98. */
  99. static void afBuildMSGIncoming( aps_FrameFormat_t *aff, endPointDesc_t *epDesc,
  100. zAddrType_t *SrcAddress, uint16 SrcPanId, NLDE_Signal_t *sig,
  101. byte SecurityUse, uint32 timestamp );
  102. static epList_t *afFindEndPointDescList( byte EndPoint );
  103. static pDescCB afGetDescCB( endPointDesc_t *epDesc );
  104. /*********************************************************************
  105. * NETWORK LAYER CALLBACKS
  106. */
  107. /*********************************************************************
  108. * PUBLIC FUNCTIONS
  109. */
  110. /*********************************************************************
  111. * @fn afInit
  112. *
  113. * @brief Initialization function for the AF.
  114. *
  115. * @param none
  116. *
  117. * @return none
  118. */
  119. void afInit( void )
  120. {
  121. // Start with no endpoint defined
  122. epList = NULL;
  123. }
  124. /*********************************************************************
  125. * @fn afRegisterExtended
  126. *
  127. * @brief Register an Application's EndPoint description.
  128. *
  129. * @param epDesc - pointer to the Application's endpoint descriptor.
  130. * @param descFn - pointer to descriptor callback function
  131. *
  132. * NOTE: The memory that epDesc is pointing to must exist after this call.
  133. *
  134. * @return Pointer to epList_t on success, NULL otherwise.
  135. */
  136. epList_t *afRegisterExtended( endPointDesc_t *epDesc, pDescCB descFn )
  137. {
  138. epList_t *ep;
  139. epList_t *epSearch;
  140. ep = osal_mem_alloc( sizeof ( epList_t ) );
  141. if ( ep )
  142. {
  143. // Fill in the new list entry
  144. ep->epDesc = epDesc;
  145. // Default to allow Match Descriptor.
  146. ep->flags = eEP_AllowMatch;
  147. ep->pfnDescCB = descFn;
  148. ep->nextDesc = NULL;
  149. // Does a list exist?
  150. if ( epList == NULL )
  151. epList = ep; // Make this the first entry
  152. else
  153. {
  154. // Look for the end of the list
  155. epSearch = epList;
  156. while( epSearch->nextDesc != NULL )
  157. epSearch = epSearch->nextDesc;
  158. // Add new entry to end of list
  159. epSearch->nextDesc = ep;
  160. }
  161. }
  162. return ep;
  163. }
  164. /*********************************************************************
  165. * @fn afRegister
  166. *
  167. * @brief Register an Application's EndPoint description.
  168. *
  169. * @param epDesc - pointer to the Application's endpoint descriptor.
  170. *
  171. * NOTE: The memory that epDesc is pointing to must exist after this call.
  172. *
  173. * @return afStatus_SUCCESS - Registered
  174. * afStatus_MEM_FAIL - not enough memory to add descriptor
  175. * afStatus_INVALID_PARAMETER - duplicate endpoint
  176. */
  177. afStatus_t afRegister( endPointDesc_t *epDesc )
  178. {
  179. epList_t *ep;
  180. // Look for duplicate endpoint
  181. if ( afFindEndPointDescList( epDesc->endPoint ) )
  182. return ( afStatus_INVALID_PARAMETER );
  183. ep = afRegisterExtended( epDesc, NULL );
  184. return ((ep == NULL) ? afStatus_MEM_FAIL : afStatus_SUCCESS);
  185. }
  186. /*********************************************************************
  187. * @fn afDataConfirm
  188. *
  189. * @brief This function will generate the Data Confirm back to
  190. * the application.
  191. *
  192. * @param endPoint - confirm end point
  193. * @param transID - transaction ID from APSDE_DATA_REQUEST
  194. * @param status - status of APSDE_DATA_REQUEST
  195. *
  196. * @return none
  197. */
  198. void afDataConfirm( uint8 endPoint, uint8 transID, ZStatus_t status )
  199. {
  200. endPointDesc_t *epDesc;
  201. afDataConfirm_t *msgPtr;
  202. // Find the endpoint description
  203. epDesc = afFindEndPointDesc( endPoint );
  204. if ( epDesc == NULL )
  205. return;
  206. // Determine the incoming command type
  207. msgPtr = (afDataConfirm_t *)osal_msg_allocate( sizeof(afDataConfirm_t) );
  208. if ( msgPtr )
  209. {
  210. // Build the Data Confirm message
  211. msgPtr->hdr.event = AF_DATA_CONFIRM_CMD;
  212. msgPtr->hdr.status = status;
  213. msgPtr->endpoint = endPoint;
  214. msgPtr->transID = transID;
  215. #if defined ( MT_AF_CB_FUNC )
  216. /* If MT has subscribed for this callback, don't send as a message. */
  217. if ( AFCB_CHECK(CB_ID_AF_DATA_CNF,*(epDesc->task_id)) )
  218. {
  219. /* Send callback if it's subscribed */
  220. MT_AfDataConfirm ((void *)msgPtr);
  221. /* Release the memory. */
  222. osal_msg_deallocate( (void *)msgPtr );
  223. }
  224. else
  225. #endif
  226. {
  227. /* send message through task message */
  228. osal_msg_send( *(epDesc->task_id), (byte *)msgPtr );
  229. }
  230. }
  231. }
  232. /*********************************************************************
  233. * @fn afIncomingData
  234. *
  235. * @brief Transfer a data PDU (ASDU) from the APS sub-layer to the AF.
  236. *
  237. * @param aff - pointer to APS frame format
  238. * @param SrcAddress - Source address
  239. * @param sig - incoming message's link quality
  240. * @param SecurityUse - Security enable/disable
  241. *
  242. * @return none
  243. */
  244. void afIncomingData( aps_FrameFormat_t *aff, zAddrType_t *SrcAddress, uint16 SrcPanId,
  245. NLDE_Signal_t *sig, byte SecurityUse, uint32 timestamp )
  246. {
  247. endPointDesc_t *epDesc = NULL;
  248. uint16 epProfileID = 0xFFFF; // Invalid Profile ID
  249. epList_t *pList;
  250. #if !defined ( APS_NO_GROUPS )
  251. uint8 grpEp;
  252. #endif
  253. if ( ((aff->FrmCtrl & APS_DELIVERYMODE_MASK) == APS_FC_DM_GROUP) )
  254. {
  255. #if !defined ( APS_NO_GROUPS )
  256. // Find the first endpoint for this group
  257. grpEp = aps_FindGroupForEndpoint( aff->GroupID, APS_GROUPS_FIND_FIRST );
  258. if ( grpEp == APS_GROUPS_EP_NOT_FOUND )
  259. return; // No endpoint found
  260. epDesc = afFindEndPointDesc( grpEp );
  261. if ( epDesc == NULL )
  262. return; // Endpoint descriptor not found
  263. pList = afFindEndPointDescList( epDesc->endPoint );
  264. #else
  265. return; // Not supported
  266. #endif
  267. }
  268. else if ( aff->DstEndPoint == AF_BROADCAST_ENDPOINT )
  269. {
  270. // Set the list
  271. if ( (pList = epList) )
  272. {
  273. epDesc = pList->epDesc;
  274. }
  275. }
  276. else if ( (epDesc = afFindEndPointDesc( aff->DstEndPoint )) )
  277. {
  278. pList = afFindEndPointDescList( epDesc->endPoint );
  279. }
  280. while ( epDesc )
  281. {
  282. if ( pList->pfnDescCB )
  283. {
  284. uint16 *pID = (uint16 *)(pList->pfnDescCB(
  285. AF_DESCRIPTOR_PROFILE_ID, epDesc->endPoint ));
  286. if ( pID )
  287. {
  288. epProfileID = *pID;
  289. osal_mem_free( pID );
  290. }
  291. }
  292. else if ( epDesc->simpleDesc )
  293. {
  294. epProfileID = epDesc->simpleDesc->AppProfId;
  295. }
  296. if ( (aff->ProfileID == epProfileID) ||
  297. ((epDesc->endPoint == ZDO_EP) && (aff->ProfileID == ZDO_PROFILE_ID)) )
  298. {
  299. {
  300. afBuildMSGIncoming( aff, epDesc, SrcAddress, SrcPanId, sig, SecurityUse, timestamp );
  301. }
  302. }
  303. if ( ((aff->FrmCtrl & APS_DELIVERYMODE_MASK) == APS_FC_DM_GROUP) )
  304. {
  305. #if !defined ( APS_NO_GROUPS )
  306. // Find the next endpoint for this group
  307. grpEp = aps_FindGroupForEndpoint( aff->GroupID, grpEp );
  308. if ( grpEp == APS_GROUPS_EP_NOT_FOUND )
  309. return; // No endpoint found
  310. epDesc = afFindEndPointDesc( grpEp );
  311. if ( epDesc == NULL )
  312. return; // Endpoint descriptor not found
  313. pList = afFindEndPointDescList( epDesc->endPoint );
  314. #else
  315. return;
  316. #endif
  317. }
  318. else if ( aff->DstEndPoint == AF_BROADCAST_ENDPOINT )
  319. {
  320. pList = pList->nextDesc;
  321. if ( pList )
  322. epDesc = pList->epDesc;
  323. else
  324. epDesc = NULL;
  325. }
  326. else
  327. epDesc = NULL;
  328. }
  329. }
  330. /*********************************************************************
  331. * @fn afBuildMSGIncoming
  332. *
  333. * @brief Build the message for the app
  334. *
  335. * @param
  336. *
  337. * @return pointer to next in data buffer
  338. */
  339. static void afBuildMSGIncoming( aps_FrameFormat_t *aff, endPointDesc_t *epDesc,
  340. zAddrType_t *SrcAddress, uint16 SrcPanId, NLDE_Signal_t *sig,
  341. byte SecurityUse, uint32 timestamp )
  342. {
  343. afIncomingMSGPacket_t *MSGpkt;
  344. const byte len = sizeof( afIncomingMSGPacket_t ) + aff->asduLength;
  345. byte *asdu = aff->asdu;
  346. MSGpkt = (afIncomingMSGPacket_t *)osal_msg_allocate( len );
  347. if ( MSGpkt == NULL )
  348. {
  349. return;
  350. }
  351. MSGpkt->hdr.event = AF_INCOMING_MSG_CMD;
  352. MSGpkt->groupId = aff->GroupID;
  353. MSGpkt->clusterId = aff->ClusterID;
  354. afCopyAddress( &MSGpkt->srcAddr, SrcAddress );
  355. MSGpkt->srcAddr.endPoint = aff->SrcEndPoint;
  356. MSGpkt->endPoint = epDesc->endPoint;
  357. MSGpkt->wasBroadcast = aff->wasBroadcast;
  358. MSGpkt->LinkQuality = sig->LinkQuality;
  359. MSGpkt->correlation = sig->correlation;
  360. MSGpkt->rssi = sig->rssi;
  361. MSGpkt->SecurityUse = SecurityUse;
  362. MSGpkt->timestamp = timestamp;
  363. MSGpkt->macDestAddr = aff->macDestAddr;
  364. MSGpkt->srcAddr.panId = SrcPanId;
  365. MSGpkt->cmd.TransSeqNumber = 0;
  366. MSGpkt->cmd.DataLength = aff->asduLength;
  367. if ( MSGpkt->cmd.DataLength )
  368. {
  369. MSGpkt->cmd.Data = (byte *)(MSGpkt + 1);
  370. osal_memcpy( MSGpkt->cmd.Data, asdu, MSGpkt->cmd.DataLength );
  371. }
  372. else
  373. {
  374. MSGpkt->cmd.Data = NULL;
  375. }
  376. #if defined ( MT_AF_CB_FUNC )
  377. // If ZDO or SAPI have registered for this endpoint, dont intercept it here
  378. if (AFCB_CHECK(CB_ID_AF_DATA_IND, *(epDesc->task_id)))
  379. {
  380. MT_AfIncomingMsg( (void *)MSGpkt );
  381. // Release the memory.
  382. osal_msg_deallocate( (void *)MSGpkt );
  383. }
  384. else
  385. #endif
  386. {
  387. // Send message through task message.
  388. osal_msg_send( *(epDesc->task_id), (uint8 *)MSGpkt );
  389. }
  390. }
  391. /*********************************************************************
  392. * @fn AF_DataRequest
  393. *
  394. * @brief Common functionality for invoking APSDE_DataReq() for both
  395. * SendMulti and MSG-Send.
  396. *
  397. * input parameters
  398. *
  399. * @param *dstAddr - Full ZB destination address: Nwk Addr + End Point.
  400. * @param *srcEP - Origination (i.e. respond to or ack to) End Point Descr.
  401. * @param cID - A valid cluster ID as specified by the Profile.
  402. * @param len - Number of bytes of data pointed to by next param.
  403. * @param *buf - A pointer to the data bytes to send.
  404. * @param *transID - A pointer to a byte which can be modified and which will
  405. * be used as the transaction sequence number of the msg.
  406. * @param options - Valid bit mask of Tx options.
  407. * @param radius - Normally set to AF_DEFAULT_RADIUS.
  408. *
  409. * output parameters
  410. *
  411. * @param *transID - Incremented by one if the return value is success.
  412. *
  413. * @return afStatus_t - See previous definition of afStatus_... types.
  414. */
  415. uint8 AF_DataRequestDiscoverRoute = TRUE;
  416. afStatus_t AF_DataRequest( afAddrType_t *dstAddr, endPointDesc_t *srcEP,
  417. uint16 cID, uint16 len, uint8 *buf, uint8 *transID,
  418. uint8 options, uint8 radius )
  419. {
  420. pDescCB pfnDescCB;
  421. ZStatus_t stat;
  422. APSDE_DataReq_t req;
  423. afDataReqMTU_t mtu;
  424. // Verify source end point
  425. if ( srcEP == NULL )
  426. {
  427. return afStatus_INVALID_PARAMETER;
  428. }
  429. #if !defined( REFLECTOR )
  430. if ( dstAddr->addrMode == afAddrNotPresent )
  431. {
  432. return afStatus_INVALID_PARAMETER;
  433. }
  434. #endif
  435. // Validate broadcasting
  436. if ( ( dstAddr->addrMode == afAddr16Bit ) ||
  437. ( dstAddr->addrMode == afAddrBroadcast ) )
  438. {
  439. // Check for valid broadcast values
  440. if( ADDR_NOT_BCAST != NLME_IsAddressBroadcast( dstAddr->addr.shortAddr ) )
  441. {
  442. // Force mode to broadcast
  443. dstAddr->addrMode = afAddrBroadcast;
  444. }
  445. else
  446. {
  447. // Address is not a valid broadcast type
  448. if ( dstAddr->addrMode == afAddrBroadcast )
  449. {
  450. return afStatus_INVALID_PARAMETER;
  451. }
  452. }
  453. }
  454. else if ( dstAddr->addrMode != afAddr64Bit &&
  455. dstAddr->addrMode != afAddrGroup &&
  456. dstAddr->addrMode != afAddrNotPresent )
  457. {
  458. return afStatus_INVALID_PARAMETER;
  459. }
  460. // Set destination address
  461. req.dstAddr.addrMode = dstAddr->addrMode;
  462. if ( dstAddr->addrMode == afAddr64Bit )
  463. osal_cpyExtAddr( req.dstAddr.addr.extAddr, dstAddr->addr.extAddr );
  464. else
  465. req.dstAddr.addr.shortAddr = dstAddr->addr.shortAddr;
  466. req.profileID = ZDO_PROFILE_ID;
  467. if ( (pfnDescCB = afGetDescCB( srcEP )) )
  468. {
  469. uint16 *pID = (uint16 *)(pfnDescCB(
  470. AF_DESCRIPTOR_PROFILE_ID, srcEP->endPoint ));
  471. if ( pID )
  472. {
  473. req.profileID = *pID;
  474. osal_mem_free( pID );
  475. }
  476. }
  477. else if ( srcEP->simpleDesc )
  478. {
  479. req.profileID = srcEP->simpleDesc->AppProfId;
  480. }
  481. req.txOptions = 0;
  482. if ( ( options & AF_ACK_REQUEST ) &&
  483. ( req.dstAddr.addrMode != AddrBroadcast ) &&
  484. ( req.dstAddr.addrMode != AddrGroup ) )
  485. {
  486. req.txOptions |= APS_TX_OPTIONS_ACK;
  487. }
  488. if ( options & AF_SKIP_ROUTING )
  489. {
  490. req.txOptions |= APS_TX_OPTIONS_SKIP_ROUTING;
  491. }
  492. if ( options & AF_EN_SECURITY )
  493. {
  494. req.txOptions |= APS_TX_OPTIONS_SECURITY_ENABLE;
  495. mtu.aps.secure = TRUE;
  496. }
  497. else
  498. {
  499. mtu.aps.secure = FALSE;
  500. }
  501. mtu.kvp = FALSE;
  502. req.transID = *transID;
  503. req.srcEP = srcEP->endPoint;
  504. req.dstEP = dstAddr->endPoint;
  505. req.clusterID = cID;
  506. req.asduLen = len;
  507. req.asdu = buf;
  508. req.discoverRoute = AF_DataRequestDiscoverRoute;//(uint8)((options & AF_DISCV_ROUTE) ? 1 : 0);
  509. req.radiusCounter = radius;
  510. #if defined ( INTER_PAN )
  511. req.dstPanId = dstAddr->panId;
  512. if ( StubAPS_InterPan( dstAddr->panId, dstAddr->endPoint ) )
  513. {
  514. if ( len > INTERP_DataReqMTU() )
  515. {
  516. stat = afStatus_INVALID_PARAMETER;
  517. }
  518. else
  519. {
  520. stat = INTERP_DataReq( &req );
  521. }
  522. }
  523. else
  524. #endif // INTER_PAN
  525. {
  526. if (len > afDataReqMTU( &mtu ) )
  527. {
  528. if (apsfSendFragmented)
  529. {
  530. stat = (*apsfSendFragmented)( &req );
  531. }
  532. else
  533. {
  534. stat = afStatus_INVALID_PARAMETER;
  535. }
  536. }
  537. else
  538. {
  539. stat = APSDE_DataReq( &req );
  540. }
  541. }
  542. /*
  543. * If this is an EndPoint-to-EndPoint message on the same device, it will not
  544. * get added to the NWK databufs. So it will not go OTA and it will not get
  545. * a MACCB_DATA_CONFIRM_CMD callback. Thus it is necessary to generate the
  546. * AF_DATA_CONFIRM_CMD here. Note that APSDE_DataConfirm() only generates one
  547. * message with the first in line TransSeqNumber, even on a multi message.
  548. * Also note that a reflected msg will not have its confirmation generated
  549. * here.
  550. */
  551. if ( (req.dstAddr.addrMode == Addr16Bit) &&
  552. (req.dstAddr.addr.shortAddr == NLME_GetShortAddr()) )
  553. {
  554. afDataConfirm( srcEP->endPoint, *transID, stat );
  555. }
  556. if ( stat == afStatus_SUCCESS )
  557. {
  558. (*transID)++;
  559. }
  560. return (afStatus_t)stat;
  561. }
  562. /*********************************************************************
  563. * @fn afFindEndPointDescList
  564. *
  565. * @brief Find the endpoint description entry from the endpoint
  566. * number.
  567. *
  568. * @param EndPoint - Application Endpoint to look for
  569. *
  570. * @return the address to the endpoint/interface description entry
  571. */
  572. static epList_t *afFindEndPointDescList( byte EndPoint )
  573. {
  574. epList_t *epSearch;
  575. // Start at the beginning
  576. epSearch = epList;
  577. // Look through the list until the end
  578. while ( epSearch )
  579. {
  580. // Is there a match?
  581. if ( epSearch->epDesc->endPoint == EndPoint )
  582. {
  583. return ( epSearch );
  584. }
  585. else
  586. epSearch = epSearch->nextDesc; // Next entry
  587. }
  588. return ( (epList_t *)NULL );
  589. }
  590. /*********************************************************************
  591. * @fn afFindEndPointDesc
  592. *
  593. * @brief Find the endpoint description entry from the endpoint
  594. * number.
  595. *
  596. * @param EndPoint - Application Endpoint to look for
  597. *
  598. * @return the address to the endpoint/interface description entry
  599. */
  600. endPointDesc_t *afFindEndPointDesc( byte EndPoint )
  601. {
  602. epList_t *epSearch;
  603. // Look for the endpoint
  604. epSearch = afFindEndPointDescList( EndPoint );
  605. if ( epSearch )
  606. return ( epSearch->epDesc );
  607. else
  608. return ( (endPointDesc_t *)NULL );
  609. }
  610. /*********************************************************************
  611. * @fn afFindSimpleDesc
  612. *
  613. * @brief Find the Simple Descriptor from the endpoint number.
  614. *
  615. * @param EP - Application Endpoint to look for.
  616. *
  617. * @return Non-zero to indicate that the descriptor memory must be freed.
  618. */
  619. byte afFindSimpleDesc( SimpleDescriptionFormat_t **ppDesc, byte EP )
  620. {
  621. epList_t *epItem = afFindEndPointDescList( EP );
  622. byte rtrn = FALSE;
  623. if ( epItem )
  624. {
  625. if ( epItem->pfnDescCB )
  626. {
  627. *ppDesc = epItem->pfnDescCB( AF_DESCRIPTOR_SIMPLE, EP );
  628. rtrn = TRUE;
  629. }
  630. else
  631. {
  632. *ppDesc = epItem->epDesc->simpleDesc;
  633. }
  634. }
  635. else
  636. {
  637. *ppDesc = NULL;
  638. }
  639. return rtrn;
  640. }
  641. /*********************************************************************
  642. * @fn afGetDescCB
  643. *
  644. * @brief Get the Descriptor callback function.
  645. *
  646. * @param epDesc - pointer to the endpoint descriptor
  647. *
  648. * @return function pointer or NULL
  649. */
  650. static pDescCB afGetDescCB( endPointDesc_t *epDesc )
  651. {
  652. epList_t *epSearch;
  653. // Start at the beginning
  654. epSearch = epList;
  655. // Look through the list until the end
  656. while ( epSearch )
  657. {
  658. // Is there a match?
  659. if ( epSearch->epDesc == epDesc )
  660. {
  661. return ( epSearch->pfnDescCB );
  662. }
  663. else
  664. epSearch = epSearch->nextDesc; // Next entry
  665. }
  666. return ( (pDescCB)NULL );
  667. }
  668. /*********************************************************************
  669. * @fn afDataReqMTU
  670. *
  671. * @brief Get the Data Request MTU(Max Transport Unit).
  672. *
  673. * @param fields - afDataReqMTU_t
  674. *
  675. * @return uint8(MTU)
  676. */
  677. uint8 afDataReqMTU( afDataReqMTU_t* fields )
  678. {
  679. uint8 len;
  680. uint8 hdr;
  681. if ( fields->kvp == TRUE )
  682. {
  683. hdr = AF_HDR_KVP_MAX_LEN;
  684. }
  685. else
  686. {
  687. hdr = AF_HDR_V1_1_MAX_LEN;
  688. }
  689. len = (uint8)(APSDE_DataReqMTU(&fields->aps) - hdr);
  690. return len;
  691. }
  692. /*********************************************************************
  693. * @fn afGetMatch
  694. *
  695. * @brief Set the allow response flag.
  696. *
  697. * @param ep - Application Endpoint to look for
  698. * @param action - true - allow response, false - no response
  699. *
  700. * @return TRUE allow responses, FALSE no response
  701. */
  702. uint8 afGetMatch( uint8 ep )
  703. {
  704. epList_t *epSearch;
  705. // Look for the endpoint
  706. epSearch = afFindEndPointDescList( ep );
  707. if ( epSearch )
  708. {
  709. if ( epSearch->flags & eEP_AllowMatch )
  710. return ( TRUE );
  711. else
  712. return ( FALSE );
  713. }
  714. else
  715. return ( FALSE );
  716. }
  717. /*********************************************************************
  718. * @fn afSetMatch
  719. *
  720. * @brief Set the allow response flag.
  721. *
  722. * @param ep - Application Endpoint to look for
  723. * @param action - true - allow response, false - no response
  724. *
  725. * @return TRUE if success, FALSE if endpoint not found
  726. */
  727. uint8 afSetMatch( uint8 ep, uint8 action )
  728. {
  729. epList_t *epSearch;
  730. // Look for the endpoint
  731. epSearch = afFindEndPointDescList( ep );
  732. if ( epSearch )
  733. {
  734. if ( action )
  735. {
  736. epSearch->flags |= eEP_AllowMatch;
  737. }
  738. else
  739. {
  740. epSearch->flags &= (eEP_AllowMatch ^ 0xFFFF);
  741. }
  742. return ( TRUE );
  743. }
  744. else
  745. return ( FALSE );
  746. }
  747. /*********************************************************************
  748. * @fn afNumEndPoints
  749. *
  750. * @brief Returns the number of endpoints defined (including 0)
  751. *
  752. * @param none
  753. *
  754. * @return number of endpoints
  755. */
  756. byte afNumEndPoints( void )
  757. {
  758. epList_t *epSearch;
  759. byte endpoints;
  760. // Start at the beginning
  761. epSearch = epList;
  762. endpoints = 0;
  763. while ( epSearch )
  764. {
  765. endpoints++;
  766. epSearch = epSearch->nextDesc;
  767. }
  768. return ( endpoints );
  769. }
  770. /*********************************************************************
  771. * @fn afEndPoints
  772. *
  773. * @brief Fills in the passed in buffer with the endpoint (numbers).
  774. * Use afNumEndPoints to find out how big a buffer to supply.
  775. *
  776. * @param epBuf - pointer to mem used
  777. *
  778. * @return void
  779. */
  780. void afEndPoints( byte *epBuf, byte skipZDO )
  781. {
  782. epList_t *epSearch;
  783. byte endPoint;
  784. // Start at the beginning
  785. epSearch = epList;
  786. while ( epSearch )
  787. {
  788. endPoint = epSearch->epDesc->endPoint;
  789. if ( !skipZDO || endPoint != 0 )
  790. *epBuf++ = endPoint;
  791. epSearch = epSearch->nextDesc;
  792. }
  793. }
  794. void afCopyAddress ( afAddrType_t *afAddr, zAddrType_t *zAddr )
  795. {
  796. afAddr->addrMode = (afAddrMode_t)zAddr->addrMode;
  797. if ( zAddr->addrMode == Addr64Bit )
  798. osal_cpyExtAddr( afAddr->addr.extAddr, zAddr->addr.extAddr );
  799. else
  800. afAddr->addr.shortAddr = zAddr->addr.shortAddr;
  801. }
  802. /*********************************************************************
  803. *********************************************************************/