AF.c 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086
  1. /**************************************************************************************************
  2. Filename: AF.c
  3. Revised: $Date: 2011-11-18 16:03:29 -0800 (Fri, 18 Nov 2011) $
  4. Revision: $Revision: 28423 $
  5. Description: Application Framework - Device Description helper functions
  6. Copyright 2004-2011 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. #include "rtg.h"
  44. #if defined ( MT_AF_CB_FUNC )
  45. #include "MT_AF.h"
  46. #endif
  47. #if defined ( INTER_PAN )
  48. #include "stub_aps.h"
  49. #endif
  50. /*********************************************************************
  51. * MACROS
  52. */
  53. /*********************************************************************
  54. * @fn afSend
  55. *
  56. * @brief Helper macro for V1 API to invoke V2 API.
  57. *
  58. * input parameters
  59. *
  60. * @param *dstAddr - Full ZB destination address: Nwk Addr + End Point.
  61. * @param srcEP - Origination (i.e. respond to or ack to) End Point.
  62. * @param cID - A valid cluster ID as specified by the Profile.
  63. * @param len - Number of bytes of data pointed to by next param.
  64. * @param *buf - A pointer to the data bytes to send.
  65. * @param options - Valid bit mask of AF Tx Options as defined in AF.h.
  66. * @param *transID - A pointer to a byte which can be modified and which will
  67. * be used as the transaction sequence number of the msg.
  68. *
  69. * output parameters
  70. *
  71. * @param *transID - Incremented by one if the return value is success.
  72. *
  73. * @return afStatus_t - See previous definition of afStatus_... types.
  74. */
  75. #define afSend( dstAddr, srcEP, cID, len, buf, transID, options, radius ) \
  76. AF_DataRequest( (dstAddr), afFindEndPointDesc( (srcEP) ), \
  77. (cID), (len), (buf), (transID), (options), (radius) )
  78. /*********************************************************************
  79. * GLOBAL VARIABLES
  80. */
  81. epList_t *epList;
  82. /*********************************************************************
  83. * LOCAL FUNCTIONS
  84. */
  85. static void afBuildMSGIncoming( aps_FrameFormat_t *aff, endPointDesc_t *epDesc,
  86. zAddrType_t *SrcAddress, uint16 SrcPanId, NLDE_Signal_t *sig,
  87. uint8 nwkSeqNum, uint8 SecurityUse, uint32 timestamp );
  88. static epList_t *afFindEndPointDescList( uint8 EndPoint );
  89. static pDescCB afGetDescCB( endPointDesc_t *epDesc );
  90. /*********************************************************************
  91. * PUBLIC FUNCTIONS
  92. */
  93. /*********************************************************************
  94. * @fn afInit
  95. *
  96. * @brief Initialization function for the AF.
  97. *
  98. * @param none
  99. *
  100. * @return none
  101. void afInit( void )
  102. {
  103. }
  104. */
  105. /*********************************************************************
  106. * @fn afRegisterExtended
  107. *
  108. * @brief Register an Application's EndPoint description.
  109. *
  110. * @param epDesc - pointer to the Application's endpoint descriptor.
  111. * @param descFn - pointer to descriptor callback function
  112. *
  113. * NOTE: The memory that epDesc is pointing to must exist after this call.
  114. *
  115. * @return Pointer to epList_t on success, NULL otherwise.
  116. */
  117. epList_t *afRegisterExtended( endPointDesc_t *epDesc, pDescCB descFn )
  118. {
  119. epList_t *ep = osal_mem_alloc(sizeof(epList_t));
  120. if (ep != NULL)
  121. {
  122. ep->nextDesc = epList;
  123. epList = ep;
  124. ep->epDesc = epDesc;
  125. ep->pfnDescCB = descFn;
  126. ep->apsfCfg.frameDelay = APSF_DEFAULT_INTERFRAME_DELAY;
  127. ep->apsfCfg.windowSize = APSF_DEFAULT_WINDOW_SIZE;
  128. ep->flags = eEP_AllowMatch; // Default to allow Match Descriptor.
  129. }
  130. return ep;
  131. }
  132. /*********************************************************************
  133. * @fn afRegister
  134. *
  135. * @brief Register an Application's EndPoint description.
  136. *
  137. * @param epDesc - pointer to the Application's endpoint descriptor.
  138. *
  139. * NOTE: The memory that epDesc is pointing to must exist after this call.
  140. *
  141. * @return afStatus_SUCCESS - Registered
  142. * afStatus_MEM_FAIL - not enough memory to add descriptor
  143. * afStatus_INVALID_PARAMETER - duplicate endpoint
  144. */
  145. afStatus_t afRegister( endPointDesc_t *epDesc )
  146. {
  147. if (afFindEndPointDescList(epDesc->endPoint)) // Look for duplicate endpoint.
  148. {
  149. return afStatus_INVALID_PARAMETER;
  150. }
  151. return ((NULL == afRegisterExtended(epDesc, NULL)) ? afStatus_MEM_FAIL : afStatus_SUCCESS);
  152. }
  153. /*********************************************************************
  154. * @fn afDelete
  155. *
  156. * @brief Delete an Application's EndPoint descriptor and frees the memory
  157. *
  158. * @param EndPoint - Application Endpoint to delete
  159. *
  160. * @return afStatus_SUCCESS - endpoint deleted
  161. * afStatus_INVALID_PARAMETER - endpoint not found
  162. * afStatus_FAILED - endpoint list empty
  163. */
  164. afStatus_t afDelete( uint8 EndPoint )
  165. {
  166. epList_t *epCurrent;
  167. epList_t *epPrevious;
  168. if (epList != NULL)
  169. {
  170. epPrevious = epCurrent = epList;
  171. // first element of the list matches
  172. if (epCurrent->epDesc->endPoint == EndPoint)
  173. {
  174. epList = epCurrent->nextDesc;
  175. osal_mem_free(epCurrent);
  176. return (afStatus_SUCCESS);
  177. }
  178. else
  179. {
  180. // search the list
  181. for (epCurrent = epPrevious->nextDesc; epCurrent != NULL; epPrevious = epCurrent)
  182. {
  183. if (epCurrent->epDesc->endPoint == EndPoint)
  184. {
  185. epPrevious->nextDesc = epCurrent->nextDesc;
  186. osal_mem_free(epCurrent);
  187. // delete the entry and free the memory
  188. return (afStatus_SUCCESS);
  189. }
  190. }
  191. }
  192. // no endpoint found
  193. return (afStatus_INVALID_PARAMETER);
  194. }
  195. else
  196. {
  197. // epList is empty
  198. return (afStatus_FAILED);
  199. }
  200. }
  201. /*********************************************************************
  202. * @fn afDataConfirm
  203. *
  204. * @brief This function will generate the Data Confirm back to
  205. * the application.
  206. *
  207. * @param endPoint - confirm end point
  208. * @param transID - transaction ID from APSDE_DATA_REQUEST
  209. * @param status - status of APSDE_DATA_REQUEST
  210. *
  211. * @return none
  212. */
  213. void afDataConfirm( uint8 endPoint, uint8 transID, ZStatus_t status )
  214. {
  215. endPointDesc_t *epDesc;
  216. afDataConfirm_t *msgPtr;
  217. // Find the endpoint description
  218. epDesc = afFindEndPointDesc( endPoint );
  219. if ( epDesc == NULL )
  220. return;
  221. // Determine the incoming command type
  222. msgPtr = (afDataConfirm_t *)osal_msg_allocate( sizeof(afDataConfirm_t) );
  223. if ( msgPtr )
  224. {
  225. // Build the Data Confirm message
  226. msgPtr->hdr.event = AF_DATA_CONFIRM_CMD;
  227. msgPtr->hdr.status = status;
  228. msgPtr->endpoint = endPoint;
  229. msgPtr->transID = transID;
  230. #if defined ( MT_AF_CB_FUNC )
  231. /* If MT has subscribed for this callback, don't send as a message. */
  232. if ( AFCB_CHECK(CB_ID_AF_DATA_CNF,*(epDesc->task_id)) )
  233. {
  234. /* Send callback if it's subscribed */
  235. MT_AfDataConfirm ((void *)msgPtr);
  236. /* Release the memory. */
  237. osal_msg_deallocate( (void *)msgPtr );
  238. }
  239. else
  240. #endif
  241. {
  242. /* send message through task message */
  243. osal_msg_send( *(epDesc->task_id), (uint8 *)msgPtr );
  244. }
  245. }
  246. }
  247. /*********************************************************************
  248. * @fn afIncomingData
  249. *
  250. * @brief Transfer a data PDU (ASDU) from the APS sub-layer to the AF.
  251. *
  252. * @param aff - pointer to APS frame format
  253. * @param SrcAddress - Source address
  254. * @param SrcPanId - Source PAN ID
  255. * @param sig - incoming message's link quality
  256. * @param nwkSeqNum - incoming network sequence number (from nwk header frame)
  257. * @param SecurityUse - Security enable/disable
  258. * @param timestamp - the MAC Timer2 timestamp at Rx.
  259. *
  260. * @return none
  261. */
  262. void afIncomingData( aps_FrameFormat_t *aff, zAddrType_t *SrcAddress, uint16 SrcPanId,
  263. NLDE_Signal_t *sig, uint8 nwkSeqNum, uint8 SecurityUse, uint32 timestamp )
  264. {
  265. endPointDesc_t *epDesc = NULL;
  266. epList_t *pList = epList;
  267. #if !defined ( APS_NO_GROUPS )
  268. uint8 grpEp = APS_GROUPS_EP_NOT_FOUND;
  269. #endif
  270. if ( ((aff->FrmCtrl & APS_DELIVERYMODE_MASK) == APS_FC_DM_GROUP) )
  271. {
  272. #if !defined ( APS_NO_GROUPS )
  273. // Find the first endpoint for this group
  274. grpEp = aps_FindGroupForEndpoint( aff->GroupID, APS_GROUPS_FIND_FIRST );
  275. if ( grpEp == APS_GROUPS_EP_NOT_FOUND )
  276. return; // No endpoint found
  277. epDesc = afFindEndPointDesc( grpEp );
  278. if ( epDesc == NULL )
  279. return; // Endpoint descriptor not found
  280. pList = afFindEndPointDescList( epDesc->endPoint );
  281. #else
  282. return; // Not supported
  283. #endif
  284. }
  285. else if ( aff->DstEndPoint == AF_BROADCAST_ENDPOINT )
  286. {
  287. // Set the list
  288. if ( pList != NULL )
  289. {
  290. epDesc = pList->epDesc;
  291. }
  292. }
  293. else if ( (epDesc = afFindEndPointDesc( aff->DstEndPoint )) )
  294. {
  295. pList = afFindEndPointDescList( epDesc->endPoint );
  296. }
  297. while ( epDesc )
  298. {
  299. uint16 epProfileID = 0xFFFF; // Invalid Profile ID
  300. if ( pList->pfnDescCB )
  301. {
  302. uint16 *pID = (uint16 *)(pList->pfnDescCB(
  303. AF_DESCRIPTOR_PROFILE_ID, epDesc->endPoint ));
  304. if ( pID )
  305. {
  306. epProfileID = *pID;
  307. osal_mem_free( pID );
  308. }
  309. }
  310. else if ( epDesc->simpleDesc )
  311. {
  312. epProfileID = epDesc->simpleDesc->AppProfId;
  313. }
  314. if ( (aff->ProfileID == epProfileID) ||
  315. ((epDesc->endPoint == ZDO_EP) && (aff->ProfileID == ZDO_PROFILE_ID)) )
  316. {
  317. {
  318. // Save original endpoint
  319. uint8 endpoint = aff->DstEndPoint;
  320. // overwrite with descriptor's endpoint
  321. aff->DstEndPoint = epDesc->endPoint;
  322. afBuildMSGIncoming( aff, epDesc, SrcAddress, SrcPanId, sig,
  323. nwkSeqNum, SecurityUse, timestamp );
  324. // Restore with original endpoint
  325. aff->DstEndPoint = endpoint;
  326. }
  327. }
  328. if ( ((aff->FrmCtrl & APS_DELIVERYMODE_MASK) == APS_FC_DM_GROUP) )
  329. {
  330. #if !defined ( APS_NO_GROUPS )
  331. // Find the next endpoint for this group
  332. grpEp = aps_FindGroupForEndpoint( aff->GroupID, grpEp );
  333. if ( grpEp == APS_GROUPS_EP_NOT_FOUND )
  334. return; // No endpoint found
  335. epDesc = afFindEndPointDesc( grpEp );
  336. if ( epDesc == NULL )
  337. return; // Endpoint descriptor not found
  338. pList = afFindEndPointDescList( epDesc->endPoint );
  339. #else
  340. return;
  341. #endif
  342. }
  343. else if ( aff->DstEndPoint == AF_BROADCAST_ENDPOINT )
  344. {
  345. pList = pList->nextDesc;
  346. if ( pList )
  347. epDesc = pList->epDesc;
  348. else
  349. epDesc = NULL;
  350. }
  351. else
  352. epDesc = NULL;
  353. }
  354. }
  355. /*********************************************************************
  356. * @fn afBuildMSGIncoming
  357. *
  358. * @brief Build the message for the app
  359. *
  360. * @param
  361. *
  362. * @return pointer to next in data buffer
  363. */
  364. static void afBuildMSGIncoming( aps_FrameFormat_t *aff, endPointDesc_t *epDesc,
  365. zAddrType_t *SrcAddress, uint16 SrcPanId, NLDE_Signal_t *sig,
  366. uint8 nwkSeqNum, uint8 SecurityUse, uint32 timestamp )
  367. {
  368. afIncomingMSGPacket_t *MSGpkt;
  369. const uint8 len = sizeof( afIncomingMSGPacket_t ) + aff->asduLength;
  370. uint8 *asdu = aff->asdu;
  371. MSGpkt = (afIncomingMSGPacket_t *)osal_msg_allocate( len );
  372. if ( MSGpkt == NULL )
  373. {
  374. return;
  375. }
  376. MSGpkt->hdr.event = AF_INCOMING_MSG_CMD;
  377. MSGpkt->groupId = aff->GroupID;
  378. MSGpkt->clusterId = aff->ClusterID;
  379. afCopyAddress( &MSGpkt->srcAddr, SrcAddress );
  380. MSGpkt->srcAddr.endPoint = aff->SrcEndPoint;
  381. MSGpkt->endPoint = epDesc->endPoint;
  382. MSGpkt->wasBroadcast = aff->wasBroadcast;
  383. MSGpkt->LinkQuality = sig->LinkQuality;
  384. MSGpkt->correlation = sig->correlation;
  385. MSGpkt->rssi = sig->rssi;
  386. MSGpkt->SecurityUse = SecurityUse;
  387. MSGpkt->timestamp = timestamp;
  388. MSGpkt->nwkSeqNum = nwkSeqNum;
  389. MSGpkt->macDestAddr = aff->macDestAddr;
  390. MSGpkt->srcAddr.panId = SrcPanId;
  391. MSGpkt->cmd.TransSeqNumber = 0;
  392. MSGpkt->cmd.DataLength = aff->asduLength;
  393. if ( MSGpkt->cmd.DataLength )
  394. {
  395. MSGpkt->cmd.Data = (uint8 *)(MSGpkt + 1);
  396. osal_memcpy( MSGpkt->cmd.Data, asdu, MSGpkt->cmd.DataLength );
  397. }
  398. else
  399. {
  400. MSGpkt->cmd.Data = NULL;
  401. }
  402. #if defined ( MT_AF_CB_FUNC )
  403. // If ZDO or SAPI have registered for this endpoint, dont intercept it here
  404. if (AFCB_CHECK(CB_ID_AF_DATA_IND, *(epDesc->task_id)))
  405. {
  406. MT_AfIncomingMsg( (void *)MSGpkt );
  407. // Release the memory.
  408. osal_msg_deallocate( (void *)MSGpkt );
  409. }
  410. else
  411. #endif
  412. {
  413. // Send message through task message.
  414. osal_msg_send( *(epDesc->task_id), (uint8 *)MSGpkt );
  415. }
  416. }
  417. /*********************************************************************
  418. * @fn AF_DataRequest
  419. *
  420. * @brief Common functionality for invoking APSDE_DataReq() for both
  421. * SendMulti and MSG-Send.
  422. *
  423. * input parameters
  424. *
  425. * @param *dstAddr - Full ZB destination address: Nwk Addr + End Point.
  426. * @param *srcEP - Origination (i.e. respond to or ack to) End Point Descr.
  427. * @param cID - A valid cluster ID as specified by the Profile.
  428. * @param len - Number of bytes of data pointed to by next param.
  429. * @param *buf - A pointer to the data bytes to send.
  430. * @param *transID - A pointer to a byte which can be modified and which will
  431. * be used as the transaction sequence number of the msg.
  432. * @param options - Valid bit mask of Tx options.
  433. * @param radius - Normally set to AF_DEFAULT_RADIUS.
  434. *
  435. * output parameters
  436. *
  437. * @param *transID - Incremented by one if the return value is success.
  438. *
  439. * @return afStatus_t - See previous definition of afStatus_... types.
  440. */
  441. uint8 AF_DataRequestDiscoverRoute = TRUE;
  442. afStatus_t AF_DataRequest( afAddrType_t *dstAddr, endPointDesc_t *srcEP,
  443. uint16 cID, uint16 len, uint8 *buf, uint8 *transID,
  444. uint8 options, uint8 radius )
  445. {
  446. pDescCB pfnDescCB;
  447. ZStatus_t stat;
  448. APSDE_DataReq_t req;
  449. afDataReqMTU_t mtu;
  450. // Verify source end point
  451. if ( srcEP == NULL )
  452. {
  453. return afStatus_INVALID_PARAMETER;
  454. }
  455. #if !defined( REFLECTOR )
  456. if ( dstAddr->addrMode == afAddrNotPresent )
  457. {
  458. return afStatus_INVALID_PARAMETER;
  459. }
  460. #endif
  461. // Check if route is available before sending data
  462. if ( options & AF_LIMIT_CONCENTRATOR )
  463. {
  464. if ( dstAddr->addrMode != afAddr16Bit )
  465. {
  466. return ( afStatus_INVALID_PARAMETER );
  467. }
  468. // First, make sure the destination is not its self, then check for an existing route.
  469. if ( (dstAddr->addr.shortAddr != NLME_GetShortAddr())
  470. && (RTG_CheckRtStatus( dstAddr->addr.shortAddr, RT_ACTIVE, (MTO_ROUTE | NO_ROUTE_CACHE) ) != RTG_SUCCESS) )
  471. {
  472. // A valid route to a concentrator wasn't found
  473. return ( afStatus_NO_ROUTE );
  474. }
  475. }
  476. // Validate broadcasting
  477. if ( ( dstAddr->addrMode == afAddr16Bit ) ||
  478. ( dstAddr->addrMode == afAddrBroadcast ) )
  479. {
  480. // Check for valid broadcast values
  481. if( ADDR_NOT_BCAST != NLME_IsAddressBroadcast( dstAddr->addr.shortAddr ) )
  482. {
  483. // Force mode to broadcast
  484. dstAddr->addrMode = afAddrBroadcast;
  485. }
  486. else
  487. {
  488. // Address is not a valid broadcast type
  489. if ( dstAddr->addrMode == afAddrBroadcast )
  490. {
  491. return afStatus_INVALID_PARAMETER;
  492. }
  493. }
  494. }
  495. else if ( dstAddr->addrMode != afAddr64Bit &&
  496. dstAddr->addrMode != afAddrGroup &&
  497. dstAddr->addrMode != afAddrNotPresent )
  498. {
  499. return afStatus_INVALID_PARAMETER;
  500. }
  501. // Set destination address
  502. req.dstAddr.addrMode = dstAddr->addrMode;
  503. if ( dstAddr->addrMode == afAddr64Bit )
  504. osal_cpyExtAddr( req.dstAddr.addr.extAddr, dstAddr->addr.extAddr );
  505. else
  506. req.dstAddr.addr.shortAddr = dstAddr->addr.shortAddr;
  507. req.profileID = ZDO_PROFILE_ID;
  508. if ( (pfnDescCB = afGetDescCB( srcEP )) )
  509. {
  510. uint16 *pID = (uint16 *)(pfnDescCB(
  511. AF_DESCRIPTOR_PROFILE_ID, srcEP->endPoint ));
  512. if ( pID )
  513. {
  514. req.profileID = *pID;
  515. osal_mem_free( pID );
  516. }
  517. }
  518. else if ( srcEP->simpleDesc )
  519. {
  520. req.profileID = srcEP->simpleDesc->AppProfId;
  521. }
  522. req.txOptions = 0;
  523. if ( ( options & AF_ACK_REQUEST ) &&
  524. ( req.dstAddr.addrMode != AddrBroadcast ) &&
  525. ( req.dstAddr.addrMode != AddrGroup ) )
  526. {
  527. req.txOptions |= APS_TX_OPTIONS_ACK;
  528. }
  529. if ( options & AF_SKIP_ROUTING )
  530. {
  531. req.txOptions |= APS_TX_OPTIONS_SKIP_ROUTING;
  532. }
  533. if ( options & AF_EN_SECURITY )
  534. {
  535. req.txOptions |= APS_TX_OPTIONS_SECURITY_ENABLE;
  536. mtu.aps.secure = TRUE;
  537. }
  538. else
  539. {
  540. mtu.aps.secure = FALSE;
  541. }
  542. if ( options & AF_PREPROCESS )
  543. {
  544. req.txOptions |= APS_TX_OPTIONS_PREPROCESS;
  545. }
  546. mtu.kvp = FALSE;
  547. req.transID = *transID;
  548. req.srcEP = srcEP->endPoint;
  549. req.dstEP = dstAddr->endPoint;
  550. req.clusterID = cID;
  551. req.asduLen = len;
  552. req.asdu = buf;
  553. req.discoverRoute = AF_DataRequestDiscoverRoute;//(uint8)((options & AF_DISCV_ROUTE) ? 1 : 0);
  554. req.radiusCounter = radius;
  555. #if defined ( INTER_PAN )
  556. req.dstPanId = dstAddr->panId;
  557. if ( StubAPS_InterPan( dstAddr->panId, dstAddr->endPoint ) )
  558. {
  559. if ( len > INTERP_DataReqMTU() )
  560. {
  561. stat = afStatus_INVALID_PARAMETER;
  562. }
  563. else
  564. {
  565. stat = INTERP_DataReq( &req );
  566. }
  567. }
  568. else
  569. #endif // INTER_PAN
  570. {
  571. if (len > afDataReqMTU( &mtu ) )
  572. {
  573. if (apsfSendFragmented)
  574. {
  575. stat = (*apsfSendFragmented)( &req );
  576. }
  577. else
  578. {
  579. stat = afStatus_INVALID_PARAMETER;
  580. }
  581. }
  582. else
  583. {
  584. stat = APSDE_DataReq( &req );
  585. }
  586. }
  587. /*
  588. * If this is an EndPoint-to-EndPoint message on the same device, it will not
  589. * get added to the NWK databufs. So it will not go OTA and it will not get
  590. * a MACCB_DATA_CONFIRM_CMD callback. Thus it is necessary to generate the
  591. * AF_DATA_CONFIRM_CMD here. Note that APSDE_DataConfirm() only generates one
  592. * message with the first in line TransSeqNumber, even on a multi message.
  593. * Also note that a reflected msg will not have its confirmation generated
  594. * here.
  595. */
  596. if ( (req.dstAddr.addrMode == Addr16Bit) &&
  597. (req.dstAddr.addr.shortAddr == NLME_GetShortAddr()) )
  598. {
  599. afDataConfirm( srcEP->endPoint, *transID, stat );
  600. }
  601. if ( stat == afStatus_SUCCESS )
  602. {
  603. (*transID)++;
  604. }
  605. return (afStatus_t)stat;
  606. }
  607. #if defined ( ZIGBEE_SOURCE_ROUTING )
  608. /*********************************************************************
  609. * @fn AF_DataRequestSrcRtg
  610. *
  611. * @brief Common functionality for invoking APSDE_DataReq() for both
  612. * SendMulti and MSG-Send.
  613. *
  614. * input parameters
  615. *
  616. * @param *dstAddr - Full ZB destination address: Nwk Addr + End Point.
  617. * @param *srcEP - Origination (i.e. respond to or ack to) End Point Descr.
  618. * @param cID - A valid cluster ID as specified by the Profile.
  619. * @param len - Number of bytes of data pointed to by next param.
  620. * @param *buf - A pointer to the data bytes to send.
  621. * @param *transID - A pointer to a byte which can be modified and which will
  622. * be used as the transaction sequence number of the msg.
  623. * @param options - Valid bit mask of Tx options.
  624. * @param radius - Normally set to AF_DEFAULT_RADIUS.
  625. * @param relayCnt - Number of devices in the relay list
  626. * @param pRelayList - Pointer to the relay list
  627. *
  628. * output parameters
  629. *
  630. * @param *transID - Incremented by one if the return value is success.
  631. *
  632. * @return afStatus_t - See previous definition of afStatus_... types.
  633. */
  634. afStatus_t AF_DataRequestSrcRtg( afAddrType_t *dstAddr, endPointDesc_t *srcEP,
  635. uint16 cID, uint16 len, uint8 *buf, uint8 *transID,
  636. uint8 options, uint8 radius, uint8 relayCnt, uint16* pRelayList )
  637. {
  638. uint8 status;
  639. /* Add the source route to the source routing table */
  640. status = RTG_AddSrcRtgEntry_Guaranteed( dstAddr->addr.shortAddr, relayCnt,
  641. pRelayList );
  642. if( status == RTG_SUCCESS)
  643. {
  644. /* Call AF_DataRequest to send the data */
  645. status = AF_DataRequest( dstAddr, srcEP, cID, len, buf, transID, options, radius );
  646. }
  647. else if( status == RTG_INVALID_PATH )
  648. {
  649. /* The source route relay count is exceeding the network limit */
  650. status = afStatus_INVALID_PARAMETER;
  651. }
  652. else
  653. {
  654. /* The guaranteed adding entry fails due to memory failure */
  655. status = afStatus_MEM_FAIL;
  656. }
  657. return status;
  658. }
  659. #endif
  660. /*********************************************************************
  661. * @fn afFindEndPointDescList
  662. *
  663. * @brief Find the endpoint description entry from the endpoint
  664. * number.
  665. *
  666. * @param EndPoint - Application Endpoint to look for
  667. *
  668. * @return the address to the endpoint/interface description entry
  669. */
  670. static epList_t *afFindEndPointDescList( uint8 EndPoint )
  671. {
  672. epList_t *epSearch;
  673. for (epSearch = epList; epSearch != NULL; epSearch = epSearch->nextDesc)
  674. {
  675. if (epSearch->epDesc->endPoint == EndPoint)
  676. {
  677. break;
  678. }
  679. }
  680. return epSearch;
  681. }
  682. /*********************************************************************
  683. * @fn afFindEndPointDesc
  684. *
  685. * @brief Find the endpoint description entry from the endpoint
  686. * number.
  687. *
  688. * @param EndPoint - Application Endpoint to look for
  689. *
  690. * @return the address to the endpoint/interface description entry
  691. */
  692. endPointDesc_t *afFindEndPointDesc( uint8 EndPoint )
  693. {
  694. epList_t *epSearch;
  695. // Look for the endpoint
  696. epSearch = afFindEndPointDescList( EndPoint );
  697. if ( epSearch )
  698. return ( epSearch->epDesc );
  699. else
  700. return ( (endPointDesc_t *)NULL );
  701. }
  702. /*********************************************************************
  703. * @fn afFindSimpleDesc
  704. *
  705. * @brief Find the Simple Descriptor from the endpoint number.
  706. *
  707. * @param EP - Application Endpoint to look for.
  708. *
  709. * @return Non-zero to indicate that the descriptor memory must be freed.
  710. */
  711. uint8 afFindSimpleDesc( SimpleDescriptionFormat_t **ppDesc, uint8 EP )
  712. {
  713. epList_t *epItem = afFindEndPointDescList( EP );
  714. uint8 rtrn = FALSE;
  715. if ( epItem )
  716. {
  717. if ( epItem->pfnDescCB )
  718. {
  719. *ppDesc = epItem->pfnDescCB( AF_DESCRIPTOR_SIMPLE, EP );
  720. rtrn = TRUE;
  721. }
  722. else
  723. {
  724. *ppDesc = epItem->epDesc->simpleDesc;
  725. }
  726. }
  727. else
  728. {
  729. *ppDesc = NULL;
  730. }
  731. return rtrn;
  732. }
  733. /*********************************************************************
  734. * @fn afGetDescCB
  735. *
  736. * @brief Get the Descriptor callback function.
  737. *
  738. * @param epDesc - pointer to the endpoint descriptor
  739. *
  740. * @return function pointer or NULL
  741. */
  742. static pDescCB afGetDescCB( endPointDesc_t *epDesc )
  743. {
  744. epList_t *epSearch;
  745. // Start at the beginning
  746. epSearch = epList;
  747. // Look through the list until the end
  748. while ( epSearch )
  749. {
  750. // Is there a match?
  751. if ( epSearch->epDesc == epDesc )
  752. {
  753. return ( epSearch->pfnDescCB );
  754. }
  755. else
  756. epSearch = epSearch->nextDesc; // Next entry
  757. }
  758. return ( (pDescCB)NULL );
  759. }
  760. /*********************************************************************
  761. * @fn afDataReqMTU
  762. *
  763. * @brief Get the Data Request MTU(Max Transport Unit).
  764. *
  765. * @param fields - afDataReqMTU_t
  766. *
  767. * @return uint8(MTU)
  768. */
  769. uint8 afDataReqMTU( afDataReqMTU_t* fields )
  770. {
  771. uint8 len;
  772. uint8 hdr;
  773. if ( fields->kvp == TRUE )
  774. {
  775. hdr = AF_HDR_KVP_MAX_LEN;
  776. }
  777. else
  778. {
  779. hdr = AF_HDR_V1_1_MAX_LEN;
  780. }
  781. len = (uint8)(APSDE_DataReqMTU(&fields->aps) - hdr);
  782. return len;
  783. }
  784. /*********************************************************************
  785. * @fn afGetMatch
  786. *
  787. * @brief Set the allow response flag.
  788. *
  789. * @param ep - Application Endpoint to look for
  790. * @param action - true - allow response, false - no response
  791. *
  792. * @return TRUE allow responses, FALSE no response
  793. */
  794. uint8 afGetMatch( uint8 ep )
  795. {
  796. epList_t *epSearch;
  797. // Look for the endpoint
  798. epSearch = afFindEndPointDescList( ep );
  799. if ( epSearch )
  800. {
  801. if ( epSearch->flags & eEP_AllowMatch )
  802. return ( TRUE );
  803. else
  804. return ( FALSE );
  805. }
  806. else
  807. return ( FALSE );
  808. }
  809. /*********************************************************************
  810. * @fn afSetMatch
  811. *
  812. * @brief Set the allow response flag.
  813. *
  814. * @param ep - Application Endpoint to look for
  815. * @param action - true - allow response, false - no response
  816. *
  817. * @return TRUE if success, FALSE if endpoint not found
  818. */
  819. uint8 afSetMatch( uint8 ep, uint8 action )
  820. {
  821. epList_t *epSearch;
  822. // Look for the endpoint
  823. epSearch = afFindEndPointDescList( ep );
  824. if ( epSearch )
  825. {
  826. if ( action )
  827. {
  828. epSearch->flags |= eEP_AllowMatch;
  829. }
  830. else
  831. {
  832. epSearch->flags &= (eEP_AllowMatch ^ 0xFFFF);
  833. }
  834. return ( TRUE );
  835. }
  836. else
  837. return ( FALSE );
  838. }
  839. /*********************************************************************
  840. * @fn afNumEndPoints
  841. *
  842. * @brief Returns the number of endpoints defined (including 0)
  843. *
  844. * @param none
  845. *
  846. * @return number of endpoints
  847. */
  848. uint8 afNumEndPoints( void )
  849. {
  850. epList_t *epSearch;
  851. uint8 endpoints;
  852. // Start at the beginning
  853. epSearch = epList;
  854. endpoints = 0;
  855. while ( epSearch )
  856. {
  857. endpoints++;
  858. epSearch = epSearch->nextDesc;
  859. }
  860. return ( endpoints );
  861. }
  862. /*********************************************************************
  863. * @fn afEndPoints
  864. *
  865. * @brief Fills in the passed in buffer with the endpoint (numbers).
  866. * Use afNumEndPoints to find out how big a buffer to supply.
  867. *
  868. * @param epBuf - pointer to mem used
  869. *
  870. * @return void
  871. */
  872. void afEndPoints( uint8 *epBuf, uint8 skipZDO )
  873. {
  874. epList_t *epSearch;
  875. uint8 endPoint;
  876. // Start at the beginning
  877. epSearch = epList;
  878. while ( epSearch )
  879. {
  880. endPoint = epSearch->epDesc->endPoint;
  881. if ( !skipZDO || endPoint != 0 )
  882. *epBuf++ = endPoint;
  883. epSearch = epSearch->nextDesc;
  884. }
  885. }
  886. /*********************************************************************
  887. * @fn afCopyAddress
  888. *
  889. * @brief Fills in the passed in afAddrType_t parameter with the corresponding information
  890. * from the zAddrType_t parameter.
  891. *
  892. * @param epBuf - pointer to mem used
  893. *
  894. * @return void
  895. */
  896. void afCopyAddress( afAddrType_t *afAddr, zAddrType_t *zAddr )
  897. {
  898. afAddr->addrMode = (afAddrMode_t)zAddr->addrMode;
  899. if ( zAddr->addrMode == Addr64Bit )
  900. {
  901. (void)osal_cpyExtAddr( afAddr->addr.extAddr, zAddr->addr.extAddr );
  902. }
  903. else
  904. {
  905. afAddr->addr.shortAddr = zAddr->addr.shortAddr;
  906. }
  907. // Since zAddrType_t has no INTER-PAN information, set the panId member to zero.
  908. afAddr->panId = 0;
  909. }
  910. /**************************************************************************************************
  911. * @fn afAPSF_ConfigGet
  912. *
  913. * @brief This function ascertains the fragmentation configuration that corresponds to
  914. * the specified EndPoint.
  915. *
  916. * input parameters
  917. *
  918. * @param endPoint - The source EP of a Tx or destination EP of a Rx fragmented message.
  919. *
  920. * output parameters
  921. *
  922. * @param pCfg - A pointer to an APSF configuration structure to fill with values.
  923. *
  924. * @return None.
  925. */
  926. void afAPSF_ConfigGet(uint8 endPoint, afAPSF_Config_t *pCfg)
  927. {
  928. epList_t *pList = afFindEndPointDescList(endPoint);
  929. if (pList == NULL)
  930. {
  931. pCfg->frameDelay = APSF_DEFAULT_INTERFRAME_DELAY;
  932. pCfg->windowSize = APSF_DEFAULT_WINDOW_SIZE;
  933. }
  934. else
  935. {
  936. (void)osal_memcpy(pCfg, &pList->apsfCfg, sizeof(afAPSF_Config_t));
  937. }
  938. }
  939. /**************************************************************************************************
  940. * @fn afAPSF_ConfigSet
  941. *
  942. * @brief This function attempts to set the fragmentation configuration that corresponds to
  943. * the specified EndPoint.
  944. *
  945. * input parameters
  946. *
  947. * @param endPoint - The specific EndPoint for which to set the fragmentation configuration.
  948. * @param pCfg - A pointer to an APSF configuration structure to fill with values.
  949. *
  950. * output parameters
  951. *
  952. * None.
  953. *
  954. * @return afStatus_SUCCESS for success.
  955. * afStatus_INVALID_PARAMETER if the specified EndPoint is not registered.
  956. */
  957. afStatus_t afAPSF_ConfigSet(uint8 endPoint, afAPSF_Config_t *pCfg)
  958. {
  959. epList_t *pList = afFindEndPointDescList(endPoint);
  960. if (pList == NULL)
  961. {
  962. return afStatus_INVALID_PARAMETER;
  963. }
  964. (void)osal_memcpy(&pList->apsfCfg, pCfg, sizeof(afAPSF_Config_t));
  965. return afStatus_SUCCESS;
  966. }
  967. /**************************************************************************************************
  968. */