stub_aps.c 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905
  1. /**************************************************************************************************
  2. Filename: stub_aps.c
  3. Revised: $Date: 2011-04-20 10:16:44 -0700 (Wed, 20 Apr 2011) $
  4. Revision: $Revision: 25771 $
  5. Description: Stub APS processing functions
  6. Copyright 2008 - 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 "mac_spec.h"
  38. #include "nwk_util.h"
  39. #include "AF.h"
  40. #include "stub_aps.h"
  41. /*********************************************************************
  42. * MACROS
  43. */
  44. /*********************************************************************
  45. * CONSTANTS
  46. */
  47. // Stub NWK header length
  48. #define STUB_NWK_HDR_LEN 2
  49. // Start of the Stub APS header in the Inter-PAN frame
  50. #define STUB_APS_HDR_FRAME_CTRL STUB_NWK_HDR_LEN
  51. // Stub APS event identifiers
  52. #define CHANNEL_CHANGE_EVT 0x0001
  53. #define CHANNEL_CHANGE_RETRY_TIMEOUT 100
  54. /*********************************************************************
  55. * TYPEDEFS
  56. */
  57. typedef struct
  58. {
  59. zAddrType_t addr;
  60. uint16 panId;
  61. } pan_t;
  62. /*********************************************************************
  63. * GLOBAL VARIABLES
  64. */
  65. uint8 StubAPS_TaskID = 0xFF; // Task ID for internal task/event processing
  66. /*********************************************************************
  67. * EXTERNAL VARIABLES
  68. */
  69. /*********************************************************************
  70. * EXTERNAL FUNCTIONS
  71. */
  72. /*********************************************************************
  73. * LOCAL VARIABLES
  74. */
  75. static uint8 newChannel;
  76. static uint8 channelChangeInProgress = FALSE;
  77. // Application info
  78. static uint8 appTaskID = 0xFF; // Application task id
  79. static uint8 appEndPoint = 0; // Application endpoint
  80. /*********************************************************************
  81. * LOCAL FUNCTIONS
  82. */
  83. static void StubNWK_ParseMsg( uint8 *buf, uint8 bufLength, NLDE_FrameFormat_t *snff );
  84. static void StubAPS_ParseMsg( NLDE_FrameFormat_t *snff, aps_FrameFormat_t *saff );
  85. static void StubNWK_BuildMsg( uint8 *nwkHdr );
  86. static void StubAPS_BuildMsg( uint8 *apsHdr, uint8 frmCtrl, uint16 groupID, APSDE_DataReq_t *req );
  87. static ZStatus_t StubAPS_BuildFrameControl( uint8 *frmCtrl, zAddrType_t *dstAddr,
  88. uint16 *groupID, APSDE_DataReq_t *req );
  89. static ZStatus_t StubAPS_SetNewChannel( uint8 channel );
  90. static void StubAPS_NotifyApp( uint8 status );
  91. uint8 StubAPS_ZMacCallback( uint8 *msgPtr );
  92. /*********************************************************************
  93. * @fn StubAPS_Init()
  94. *
  95. * @brief Initialize stub APS layer
  96. *
  97. * @param task_id - Task identifier for the desired task
  98. *
  99. * @return none
  100. */
  101. void StubAPS_Init( uint8 task_id )
  102. {
  103. StubAPS_TaskID = task_id;
  104. // register with ZMAC
  105. pZMac_AppCallback = StubAPS_ZMacCallback;
  106. } /* StubAPS_Init() */
  107. /*********************************************************************
  108. * @fn StubAPS_ProcessEvent()
  109. *
  110. * @brief Main event loop for Stub APS task. This function should be called
  111. * at periodic intervals when event occur.
  112. *
  113. * @param task_id - Task ID
  114. * @param events - Bitmap of events
  115. *
  116. * @return none
  117. */
  118. UINT16 StubAPS_ProcessEvent( uint8 task_id, uint16 events )
  119. {
  120. (void)task_id; // Intentionally unreferenced parameter
  121. if ( events & SYS_EVENT_MSG )
  122. {
  123. osal_event_hdr_t *msg_ptr;
  124. while ( (msg_ptr = (osal_event_hdr_t *)osal_msg_receive( StubAPS_TaskID )) != NULL )
  125. {
  126. if ( msg_ptr->event == MAC_MCPS_DATA_CNF )
  127. {
  128. INTERP_DataConfirm( (ZMacDataCnf_t *)msg_ptr );
  129. }
  130. else if ( msg_ptr->event == MAC_MCPS_DATA_IND )
  131. {
  132. INTERP_DataIndication( (macMcpsDataInd_t *)msg_ptr );
  133. }
  134. osal_msg_deallocate( (uint8 *)msg_ptr );
  135. }
  136. // Return unproccessed events
  137. return ( events ^ SYS_EVENT_MSG );
  138. }
  139. if ( events & CHANNEL_CHANGE_EVT )
  140. {
  141. // try to change to the new channel
  142. ZStatus_t status = StubAPS_SetNewChannel( newChannel );
  143. if ( status != ZSuccess )
  144. {
  145. // turn MAC receiver back on
  146. uint8 rxOnIdle = true;
  147. ZMacSetReq( ZMacRxOnIdle, &rxOnIdle );
  148. // set NWK task to run
  149. nwk_setStateIdle( FALSE );
  150. channelChangeInProgress = FALSE;
  151. }
  152. // notify the application
  153. StubAPS_NotifyApp( status );
  154. return ( events ^ CHANNEL_CHANGE_EVT );
  155. }
  156. // If reach here, the events are unknown
  157. // Discard or make more handlers
  158. return 0;
  159. } /* StubAPS_ProcessEvent() */
  160. /*********************************************************************
  161. * @fn StubNWK_ParseMsg
  162. *
  163. * @brief Call this function to parse an incoming Stub NWK frame.
  164. *
  165. * @param buf - pointer incoming message buffer
  166. * @param bufLength - length of incoming message
  167. * @param snff - pointer Frame Format Parameters
  168. *
  169. * @return pointer to network packet, NULL if error
  170. */
  171. static void StubNWK_ParseMsg( uint8 *buf, uint8 bufLength, NLDE_FrameFormat_t *snff )
  172. {
  173. uint16 fc;
  174. osal_memset( snff, 0, sizeof(NLDE_FrameFormat_t) );
  175. snff->bufLength = bufLength;
  176. // get the frame control
  177. fc = BUILD_UINT16( buf[NWK_HDR_FRAME_CTRL_LSB], buf[NWK_HDR_FRAME_CTRL_MSB] );
  178. // parse the frame control
  179. NLDE_ParseFrameControl( fc, snff );
  180. snff->hdrLen = STUB_NWK_HDR_LEN;
  181. // Stub NWK payload
  182. snff->nsdu = buf + snff->hdrLen;
  183. snff->nsduLength = snff->bufLength - snff->hdrLen;
  184. } /* StubNWK_ParseMsg */
  185. /*********************************************************************
  186. * @fn StubAPS_ParseMsg
  187. *
  188. * @brief Call this function to parse an incoming Stub APS frame.
  189. *
  190. * @param naff - pointer Stub NWK Frame Format Parameters
  191. * @param saff - pointer Stub APS Format Parameters
  192. *
  193. * @return none
  194. */
  195. static void StubAPS_ParseMsg( NLDE_FrameFormat_t *snff, aps_FrameFormat_t *saff )
  196. {
  197. uint8 fcb;
  198. uint8 *asdu;
  199. osal_memset( saff, 0, sizeof(aps_FrameFormat_t) );
  200. saff->asduLength = snff->nsduLength;
  201. asdu = snff->nsdu;
  202. saff->macDestAddr = snff->macDstAddr;
  203. // First byte is Frame Control.
  204. saff->FrmCtrl = *asdu++;
  205. fcb = saff->FrmCtrl & APS_FRAME_TYPE_MASK;
  206. if ( fcb == STUB_APS_FRAME )
  207. {
  208. fcb = saff->FrmCtrl & APS_DELIVERYMODE_MASK;
  209. if ( fcb == APS_FC_DM_BROADCAST )
  210. saff->wasBroadcast = true;
  211. else
  212. saff->wasBroadcast = false;
  213. if ( fcb == APS_FC_DM_GROUP )
  214. {
  215. saff->GroupID = BUILD_UINT16( asdu[0], asdu[1] );
  216. asdu += sizeof( uint16 );
  217. }
  218. // Pull out the Cluster ID
  219. saff->ClusterID = BUILD_UINT16( asdu[0], asdu[1] );
  220. asdu += sizeof( uint16 );
  221. // Pull out the profile ID
  222. saff->ProfileID = BUILD_UINT16( asdu[0], asdu[1] );
  223. asdu += 2;
  224. }
  225. saff->asdu = asdu;
  226. saff->asduLength -= (uint8) (asdu - snff->nsdu);
  227. saff->apsHdrLen = snff->nsduLength - saff->asduLength;
  228. } /* StubAPS_ParseMsg */
  229. /******************************************************************************
  230. * @fn StubAPS_BuildFrameControl
  231. *
  232. * @brief This function builds Stub APS Frame Control and the destination
  233. * address parameter for the MCPS-DATA Request.
  234. *
  235. * @param frmCtrl - frame control
  236. * @param dstAddr - destination address for MCPS-DATA Request
  237. * @param groupID - group id
  238. * @param req - APSDE_DataReq_t
  239. *
  240. * @return ZStatus_t
  241. */
  242. static ZStatus_t StubAPS_BuildFrameControl( uint8 *frmCtrl, zAddrType_t *dstAddr,
  243. uint16 *groupID, APSDE_DataReq_t *req )
  244. {
  245. // Security
  246. if ( req->txOptions & APS_TX_OPTIONS_SECURITY_ENABLE )
  247. return ( ZApsNotSupported );
  248. // Ack request
  249. if ( req->txOptions & APS_TX_OPTIONS_ACK )
  250. return ( ZApsNotSupported );
  251. // Fragmentation
  252. if ( req->txOptions & APS_TX_OPTIONS_PERMIT_FRAGMENT )
  253. return ( ZApsNotSupported );
  254. // set delivery mode
  255. if ( req->dstAddr.addrMode == AddrNotPresent )
  256. return ( ZApsNotSupported ); // No REFLECTOR
  257. // set frame type
  258. *frmCtrl = STUB_APS_FRAME;
  259. // set DstAddrMode of MCPS-DATA Request to DstAddrMode of INTERP-Data Request
  260. dstAddr->addrMode = req->dstAddr.addrMode;
  261. // set DstAddr of MCPS-DATA Request to DstAddr of INTERP-Data Request
  262. if ( req->dstAddr.addrMode == AddrBroadcast )
  263. {
  264. *frmCtrl |= APS_FC_DM_BROADCAST;
  265. // set DstAddrMode of MCPS-DATA Request to short address
  266. dstAddr->addrMode = Addr16Bit;
  267. dstAddr->addr.shortAddr = req->dstAddr.addr.shortAddr;
  268. }
  269. else if ( req->dstAddr.addrMode == Addr16Bit )
  270. {
  271. *frmCtrl |= APS_FC_DM_UNICAST;
  272. dstAddr->addr.shortAddr = req->dstAddr.addr.shortAddr;
  273. }
  274. else if ( req->dstAddr.addrMode == Addr64Bit )
  275. {
  276. *frmCtrl |= APS_FC_DM_UNICAST;
  277. osal_cpyExtAddr( dstAddr->addr.extAddr, req->dstAddr.addr.extAddr );
  278. }
  279. else if ( req->dstAddr.addrMode == AddrGroup )
  280. {
  281. *frmCtrl |= APS_FC_DM_GROUP;
  282. // set DstAddrMode of MCPS-DATA Request to short address
  283. dstAddr->addrMode = Addr16Bit;
  284. // set DstAddr of MCPS-DATA Request to 0xFFFF
  285. dstAddr->addr.shortAddr = NWK_BROADCAST_SHORTADDR_DEVALL;
  286. // set Group ID to DstAddr of INTERP-Data Request
  287. *groupID = req->dstAddr.addr.shortAddr;
  288. }
  289. return ( ZSuccess );
  290. } /* StubAPS_BuildFrameControl */
  291. /******************************************************************************
  292. * @fn StubNWK_BuildMsg
  293. *
  294. * @brief This function builds a Stub NWK frame.
  295. *
  296. * @param nwkHdr - stub NWK header
  297. *
  298. * @return none
  299. */
  300. static void StubNWK_BuildMsg( uint8 *nwkHdr )
  301. {
  302. uint16 frmCtrl = 0;
  303. uint8 protoVer = NLME_GetProtocolVersion();
  304. // frame type
  305. frmCtrl |= (STUB_NWK_FRAME_TYPE << NWK_FC_FRAME_TYPE);
  306. // protocol version
  307. frmCtrl |= (protoVer << NWK_FC_PROT_VERSION);
  308. // set Stub NWK header
  309. *nwkHdr++ = LO_UINT16( frmCtrl );
  310. *nwkHdr++ = HI_UINT16( frmCtrl );
  311. } /* StubNWK_BuildMsg */
  312. /******************************************************************************
  313. * @fn StubAPS_BuildMsg
  314. *
  315. * @brief This function builds a Stub APS frame.
  316. *
  317. * @param apsHdr - stub APS header
  318. * @param frmCtrl - stub APS frame control
  319. * @param groupID - group id
  320. * @param req - APSDE_DataReq_t
  321. *
  322. * @return none
  323. */
  324. static void StubAPS_BuildMsg( uint8 *apsHdr, uint8 frmCtrl, uint16 groupID, APSDE_DataReq_t *req )
  325. {
  326. // add frame type
  327. *apsHdr++ = frmCtrl;
  328. // add Group ID
  329. if ( ( frmCtrl & APS_DELIVERYMODE_MASK ) == APS_FC_DM_GROUP )
  330. {
  331. *apsHdr++ = LO_UINT16( groupID );
  332. *apsHdr++ = HI_UINT16( groupID );
  333. }
  334. // add clusterID
  335. *apsHdr++ = LO_UINT16( req->clusterID );
  336. *apsHdr++ = HI_UINT16( req->clusterID );
  337. // add profile ID
  338. *apsHdr++ = LO_UINT16( req->profileID );
  339. *apsHdr++ = HI_UINT16( req->profileID );
  340. // copy ASDU data into frame
  341. osal_memcpy ( apsHdr, req->asdu, req->asduLen );
  342. } /* StubAPS_BuildMsg */
  343. /******************************************************************************
  344. * @fn StubAPS_setNewChannel
  345. *
  346. * @brief This function changes the device's channel.
  347. *
  348. * @param none
  349. *
  350. * @return ZStatus_t
  351. */
  352. static ZStatus_t StubAPS_SetNewChannel( uint8 channel )
  353. {
  354. uint8 rxOnIdle;
  355. // make sure MAC has nothing to transmit
  356. if ( ( nwkDB_CountTypes( NWK_DATABUF_SENT ) == 0 ) && ZMacStateIdle() )
  357. {
  358. // set the new channel
  359. ZMacSetReq( ZMacChannel, &channel );
  360. // turn MAC receiver back on
  361. rxOnIdle = true;
  362. ZMacSetReq( ZMacRxOnIdle, &rxOnIdle );
  363. channelChangeInProgress = FALSE;
  364. return ( ZSuccess );
  365. }
  366. return ( ZFailure );
  367. } /* StubAPS_setNewChannel */
  368. /******************************************************************************
  369. * @fn StubAPS_NotifyApp
  370. *
  371. * @brief This function sends an OSAL message to the Application task.
  372. *
  373. * @param status - command status
  374. *
  375. * @return none
  376. */
  377. static void StubAPS_NotifyApp( uint8 status )
  378. {
  379. osal_event_hdr_t *msgPtr;
  380. // Notify the application task
  381. msgPtr = (osal_event_hdr_t *)osal_msg_allocate( sizeof(osal_event_hdr_t) );
  382. if ( msgPtr )
  383. {
  384. msgPtr->event = SAPS_CHANNEL_CHANGE;
  385. msgPtr->status = status;
  386. osal_msg_send( appTaskID, (uint8 *)msgPtr );
  387. }
  388. } /* StubAPS_NotifyApp */
  389. /******************************************************************************
  390. *
  391. * External APIs provided to the Application.
  392. */
  393. /******************************************************************************
  394. * @fn StubAPS_SetInterPanChannel
  395. *
  396. * @brief This function changes the device's channel for inter-PAN communication.
  397. *
  398. * @param channel - new channel
  399. *
  400. * @return ZStatus_t
  401. */
  402. ZStatus_t StubAPS_SetInterPanChannel( uint8 channel )
  403. {
  404. uint8 currChannel;
  405. uint8 rxOnIdle;
  406. if ( channelChangeInProgress )
  407. return ( ZFailure );
  408. ZMacGetReq( ZMacChannel, &currChannel );
  409. if ( currChannel == channel )
  410. {
  411. // inter PANs communication within the same channel
  412. return ( ZSuccess );
  413. }
  414. // go into channel transition state
  415. channelChangeInProgress = TRUE;
  416. // set NWK task to idle
  417. nwk_setStateIdle( TRUE );
  418. // turn MAC receiver off
  419. rxOnIdle = false;
  420. ZMacSetReq( ZMacRxOnIdle, &rxOnIdle );
  421. // try to change to the new channel
  422. if ( StubAPS_SetNewChannel( channel ) == ZSuccess )
  423. return ( ZSuccess );
  424. // save the new channel for retry
  425. newChannel = channel;
  426. // ask StubAPS task to retry it later
  427. osal_start_timerEx( StubAPS_TaskID, CHANNEL_CHANGE_EVT, CHANNEL_CHANGE_RETRY_TIMEOUT );
  428. return ( ZApsNotAllowed );
  429. } /* StubAPS_SetInterPanChannel */
  430. /******************************************************************************
  431. * @fn StubAPS_SetIntraPanChannel
  432. *
  433. * @brief This function sets the device's channel back to the NIB channel.
  434. *
  435. * @param none
  436. *
  437. * @return ZStatus_t
  438. */
  439. ZStatus_t StubAPS_SetIntraPanChannel( void )
  440. {
  441. uint8 currChannel;
  442. uint8 rxOnIdle;
  443. if ( channelChangeInProgress )
  444. return ( ZFailure );
  445. ZMacGetReq( ZMacChannel, &currChannel );
  446. if ( currChannel == _NIB.nwkLogicalChannel )
  447. return ( ZSuccess );
  448. channelChangeInProgress = TRUE;
  449. // turn MAC receiver off
  450. rxOnIdle = false;
  451. ZMacSetReq( ZMacRxOnIdle, &rxOnIdle );
  452. // set the NIB channel
  453. ZMacSetReq( ZMacChannel, &(_NIB.nwkLogicalChannel) );
  454. // turn MAC receiver back on
  455. rxOnIdle = true;
  456. ZMacSetReq( ZMacRxOnIdle, &rxOnIdle );
  457. // set NWK task to run
  458. nwk_setStateIdle( FALSE );
  459. channelChangeInProgress = FALSE;
  460. return ( ZSuccess );
  461. } /* StubAPS_SetIntraPanChannel */
  462. /******************************************************************************
  463. * @fn StubAPS_InterPan
  464. *
  465. * @brief This function checks to see if a PAN is an Inter-PAN.
  466. *
  467. * @param panId - PAN ID
  468. * @param endPoint - endpoint
  469. *
  470. * @return TRUE if PAN is Inter-PAN, FALSE otherwise
  471. */
  472. uint8 StubAPS_InterPan( uint16 panId, uint8 endPoint )
  473. {
  474. (void)panId; // Intentionally unreferenced parameter
  475. // No need to check the MAC/NIB Channels or Source/Destination PAN IDs
  476. // since it's possible to send Inter-PAN messages within the same network.
  477. if ( endPoint == STUBAPS_INTER_PAN_EP )
  478. {
  479. // Inter-PAN endpoint
  480. return ( TRUE );
  481. }
  482. return ( FALSE );
  483. } /* StubAPS_InterPan */
  484. /******************************************************************************
  485. * @fn StubAPS_RegisterApp
  486. *
  487. * @brief This function registers the Application with the Stub APS layer.
  488. *
  489. * NOTE: Since Stub APS messages don't include the application
  490. * endpoint, the application has to register its endpoint
  491. * with Stub APS.
  492. *
  493. * @param epDesc - application's endpoint descriptor
  494. *
  495. * @return none
  496. */
  497. void StubAPS_RegisterApp( endPointDesc_t *epDesc )
  498. {
  499. appTaskID = *epDesc->task_id;
  500. appEndPoint = epDesc->endPoint;
  501. } /* StubAPS_RegisterApp */
  502. /******************************************************************************
  503. * @fn StubAPS_ZMacCallback
  504. *
  505. * @brief This function accepts an inter-PAN message from ZMac.
  506. *
  507. * @param msgPtr - received message
  508. *
  509. * @return TRUE if message is processed. FALSE otherwise.
  510. */
  511. uint8 StubAPS_ZMacCallback( uint8 *msgPtr )
  512. {
  513. uint16 nwk_fc;
  514. uint8 aps_fc;
  515. uint8 frameType;
  516. uint8 *buf = NULL;
  517. uint8 event = ((osal_event_hdr_t *)msgPtr)->event;
  518. if ( event == MAC_MCPS_DATA_IND )
  519. {
  520. buf = ((macMcpsDataInd_t *)msgPtr)->msdu.p;
  521. }
  522. else if ( event == MAC_MCPS_DATA_CNF )
  523. {
  524. buf = ((macMcpsDataCnf_t *)msgPtr)->pDataReq->msdu.p;
  525. }
  526. if ( buf )
  527. {
  528. // get the NWK frame control
  529. nwk_fc = BUILD_UINT16( buf[NWK_HDR_FRAME_CTRL_LSB], buf[NWK_HDR_FRAME_CTRL_MSB] );
  530. // frame type
  531. frameType = (uint8)((nwk_fc >> NWK_FC_FRAME_TYPE) & NWK_FC_FRAME_TYPE_MASK);
  532. // check if incoming frame is of the right type
  533. if ( frameType != STUB_NWK_FRAME_TYPE )
  534. {
  535. // message doesn't belong to Stub APS
  536. return ( FALSE );
  537. }
  538. // get the APS frame control
  539. aps_fc = buf[STUB_APS_HDR_FRAME_CTRL];
  540. // frame type
  541. frameType = aps_fc & APS_FRAME_TYPE_MASK;
  542. // check if incoming frame is of the right type
  543. if ( frameType != STUB_APS_FRAME )
  544. {
  545. // message doesn't belong to Stub APS
  546. return ( FALSE );
  547. }
  548. // message belongs to Stub APS
  549. osal_msg_send( StubAPS_TaskID, (uint8 *)msgPtr );
  550. return ( TRUE );
  551. }
  552. // message doesn't belong to Stub APS
  553. return ( FALSE );
  554. } /* StubAPS_ZMacCallback */
  555. /******************************************************************************
  556. *
  557. * Stub APS Inter-PAN interface INTERP and its callbacks.
  558. */
  559. /******************************************************************************
  560. * @fn INTERP_DataReq
  561. *
  562. * @brief This function requests the transfer of data from the next
  563. * higher layer to a single peer entity.
  564. *
  565. * @param req - APSDE_DataReq_t
  566. *
  567. * @return ZStatus_t
  568. */
  569. ZStatus_t INTERP_DataReq( APSDE_DataReq_t *req )
  570. {
  571. uint8 apsFrmCtrl;
  572. uint16 groupID = 0;
  573. uint8 *buf;
  574. uint8 hdrLen;
  575. ZMacDataReq_t dataReq;
  576. ZStatus_t status;
  577. if ( channelChangeInProgress || !StubAPS_InterPan( req->dstPanId, req->dstEP ) )
  578. return ( ZFailure );
  579. osal_memset( &dataReq, 0, sizeof( ZMacDataReq_t ) );
  580. // Build Stub APS header
  581. status = StubAPS_BuildFrameControl( &apsFrmCtrl, &(dataReq.DstAddr), &groupID, req );
  582. if ( status != ZSuccess )
  583. return ( status );
  584. // set default Stub APS header length
  585. hdrLen = APS_FRAME_CTRL_FIELD_LEN;
  586. // add group ID length
  587. if ( ( apsFrmCtrl & APS_DELIVERYMODE_MASK ) == APS_FC_DM_GROUP )
  588. hdrLen += APS_GROUP_ID_FIELD_LEN;
  589. // add cluster ID length
  590. hdrLen += APS_CLUSTERID_FIELD_LEN;
  591. // add profile ID length
  592. hdrLen += APS_PROFILEID_FIELD_LEN;
  593. // add default Stub NWK header length
  594. hdrLen += STUB_NWK_HDR_LEN;
  595. // calculate MSDU length
  596. dataReq.msduLength = hdrLen + req->asduLen;
  597. // allocate buffer
  598. buf = osal_mem_alloc( dataReq.msduLength );
  599. if ( buf != NULL )
  600. {
  601. dataReq.msdu = buf;
  602. // Add Stub APS header and data
  603. StubAPS_BuildMsg( &buf[STUB_APS_HDR_FRAME_CTRL], apsFrmCtrl, groupID, req );
  604. // Add Stub NWK header
  605. StubNWK_BuildMsg( buf );
  606. // Set ZMac data request
  607. dataReq.DstPANId = req->dstPanId;
  608. dataReq.SrcAddrMode = Addr64Bit;
  609. dataReq.Handle = req->transID;
  610. if ( ( apsFrmCtrl & APS_DELIVERYMODE_MASK ) == APS_FC_DM_UNICAST )
  611. dataReq.TxOptions = NWK_TXOPTIONS_ACK;
  612. else
  613. dataReq.TxOptions = 0;
  614. // send the frame
  615. status = ZMacDataReq( &dataReq );
  616. // free the frame
  617. osal_mem_free( buf );
  618. }
  619. else
  620. {
  621. // flag a memory error
  622. status = ZMemError;
  623. }
  624. return ( status );
  625. } /* INTERP_DataReq */
  626. /******************************************************************************
  627. * @fn INTERP_DataReqMTU
  628. *
  629. * @brief This function requests the MTU (Max Transport Unit) of the
  630. * Inter-PAN Data Service.
  631. *
  632. * @param none
  633. *
  634. * @return uint8 - MTU
  635. */
  636. uint8 INTERP_DataReqMTU( void )
  637. {
  638. uint8 mtu;
  639. uint8 hdrLen;
  640. // Use maximum header size for Stub APS header
  641. hdrLen = APS_FRAME_CTRL_FIELD_LEN +
  642. APS_GROUP_ID_FIELD_LEN +
  643. APS_CLUSTERID_FIELD_LEN +
  644. APS_PROFILEID_FIELD_LEN;
  645. mtu = MAC_A_MAX_FRAME_SIZE - STUB_NWK_HDR_LEN - hdrLen;
  646. return ( mtu );
  647. } /* INTERP_DataReqMTU */
  648. /****************************************************************************
  649. * @fn INTERP_DataConfirm
  650. *
  651. * @brief This function processes the data confirm from the MAC layer.
  652. *
  653. * @param dataCnf - data confirm primitive
  654. *
  655. * @return none
  656. */
  657. void INTERP_DataConfirm( ZMacDataCnf_t *dataCnf )
  658. {
  659. afDataConfirm( appEndPoint, dataCnf->msduHandle, dataCnf->hdr.Status );
  660. } /* INTERP_DataConfirm */
  661. /****************************************************************************
  662. * @fn INTERP_DataIndication
  663. *
  664. * @brief This function indicates the transfer of a data SPDU (MSDU)
  665. * from the MAC layer to the local application layer entity.
  666. *
  667. * @param dataInd - data indicate primitive
  668. *
  669. * @return none
  670. */
  671. void INTERP_DataIndication( macMcpsDataInd_t *dataInd )
  672. {
  673. NLDE_FrameFormat_t snff;
  674. aps_FrameFormat_t saff;
  675. zAddrType_t srcAddr;
  676. NLDE_Signal_t sig;
  677. // parse the Stub NWK header
  678. StubNWK_ParseMsg( dataInd->msdu.p, dataInd->msdu.len, &snff );
  679. // Fill in MAC destination address
  680. snff.macDstAddr = dataInd->mac.dstAddr.addr.shortAddr;
  681. // fill in MAC source address (Stub NWK frame doesn't have address fields)
  682. osal_copyAddress( &srcAddr, (zAddrType_t *)&(dataInd->mac.srcAddr) );
  683. // check if incoming frame is of the right type
  684. if ( snff.frameType != STUB_NWK_FRAME_TYPE )
  685. return;
  686. // check if incoming frame is of the right version
  687. if ( snff.protocolVersion != NLME_GetProtocolVersion() )
  688. return;
  689. // check if the remaining sun-fields are zero
  690. if ( ( snff.discoverRoute != 0 ) || ( snff.multicast != 0 ) ||
  691. ( snff.secure != 0 ) || ( snff.srcRouteSet != 0 ) ||
  692. ( snff.dstExtAddrSet != 0 ) || ( snff.srcExtAddrSet != 0 ) )
  693. {
  694. return;
  695. }
  696. // parse the Stub APS header
  697. StubAPS_ParseMsg( &snff, &saff );
  698. // check if incoming frame is of the right type
  699. if ( ( saff.FrmCtrl & APS_FRAME_TYPE_MASK ) != STUB_APS_FRAME )
  700. return;
  701. // check if delivery mode is of the right type
  702. if ( ( saff.FrmCtrl & APS_DELIVERYMODE_MASK ) == APS_FC_DM_INDIRECT )
  703. return;
  704. // check if incoming frame is unsecured
  705. if ( saff.FrmCtrl & APS_FC_SECURITY )
  706. return;
  707. // check if there's no extended header
  708. if ( saff.FrmCtrl & APS_FC_EXTENDED )
  709. return;
  710. // Set the endpoints
  711. saff.DstEndPoint = appEndPoint;
  712. saff.SrcEndPoint = STUBAPS_INTER_PAN_EP;
  713. // Set the signal strength information
  714. sig.LinkQuality = dataInd->mac.mpduLinkQuality;
  715. sig.correlation = dataInd->mac.correlation;
  716. sig.rssi = dataInd->mac.rssi;
  717. APSDE_DataIndication( &saff, &srcAddr, dataInd->mac.srcPanId,
  718. &sig, snff.broadcastId, FALSE, dataInd->mac.timestamp );
  719. } /* INTERP_DataIndication */
  720. /*********************************************************************
  721. *********************************************************************/