The Freescale MCR20A Simple Media Access Controller (MCR20A SMAC) is a simple ANSI C based codebase available as sample source code. The MCR20A SMAC is used for developing proprietary RF transceiver applications using Freescale’s MCR20A 2.4 GHz transceiver 

Fork of fsl_smac by Freescale

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers SMAC.cpp Source File

SMAC.cpp

00001 /**************************************************************************************************
00002 * SMAC implementation.
00003 * 
00004 * Freescale Semiconductor Inc.
00005 * (c) Copyright 2004-2014 Freescale Semiconductor, Inc.
00006 * ALL RIGHTS RESERVED.
00007 *
00008 ***************************************************************************************************
00009 *
00010 * THIS SOFTWARE IS PROVIDED BY FREESCALE "AS IS" AND ANY EXPRESSED OR 
00011 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 
00012 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  
00013 * IN NO EVENT SHALL FREESCALE OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 
00014 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 
00015 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 
00016 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 
00017 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 
00018 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING 
00019 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 
00020 * THE POSSIBILITY OF SUCH DAMAGE.
00021 *
00022 ***********************************************************************************************//*!
00023 **************************************************************************************************/
00024 #include "SMAC.h"
00025 #include "PhyInterface.h"
00026 #include "EmbeddedTypes.h"
00027 
00028 #include "SMAC_Config.h"
00029 
00030 #include "MemManager.h"
00031 #include "FunctionLib.h"
00032 #if 0
00033 #include "panic.h"
00034 #endif 
00035 
00036 #include "cmsis_os.h"
00037 #include "rtos.h"
00038 
00039 /************************************************************************************
00040 *************************************************************************************
00041 * Public memory declarations
00042 *************************************************************************************
00043 ************************************************************************************/          
00044 uint8_t gTotalChannels;
00045 
00046 /************************************************************************************
00047 *************************************************************************************
00048 * Private memory declarations
00049 *************************************************************************************
00050 ************************************************************************************/
00051 static smacStates_t    smacState;
00052 /*volatile*/ static prssPacketPtr_t smacProccesPacketPtr;
00053 static phyRxParams_t   smacLastDataRxParams;
00054 #if defined (gPHY_802_15_4g_d)
00055 static smacPacket_t smacPacketConfig;
00056 #endif
00057 static macToPdDataMessage_t * gSmacDataMessage;
00058 static macToPlmeMessage_t *   gSmacMlmeMessage;
00059 
00060 static uint16_t u16PanID;
00061 static uint16_t u16ShortSrcAddress;
00062 
00063 static uint8_t u8AckRetryCounter = 0;
00064 static uint8_t u8CCARetryCounter = 0;
00065 
00066 static uint8_t mSmacInitialized;
00067 static uint8_t mSmacTimeoutAsked;
00068 static uint8_t u8BackoffTimerId;
00069 static txContextConfig_t txConfigurator;
00070 static uint8_t u8SmacSeqNo;
00071 //Sap Handlers Called by PHY
00072 phyStatus_t PD_SMAC_SapHandler(void* pMsg, instanceId_t smacInstanceId);
00073 phyStatus_t PLME_SMAC_SapHandler(void* pMsg, instanceId_t smacInstanceId);
00074 
00075 /************************************************************************************
00076 *************************************************************************************
00077 * Private functions
00078 *************************************************************************************
00079 ************************************************************************************/
00080 static bool_t SMACPacketCheck(pdDataToMacMessage_t* pMsgFromPhy);
00081 static void BackoffTimeElapsed(void const *arg);
00082 
00083 osTimerDef (SmacTimer, BackoffTimeElapsed);                          
00084 /************************************************************************************
00085 *************************************************************************************
00086 * Interface functions
00087 *************************************************************************************
00088 ************************************************************************************/
00089 uint8_t TMR_AllocateTimer
00090 (
00091     void
00092 )
00093 {
00094     //RtosTimer smac_timer(u8BackoffTimerId, osTimerOnce , NULL);
00095     return 0;
00096 }
00097 
00098 uint8_t TMR_StartSingleShotTimer
00099 (
00100     uint8_t timerID,
00101     uint32_t timeInMilliseconds,
00102     void (*pfTimerCallBack)(const void *),
00103     void *param
00104 )
00105 {
00106     //RtosTimer smac_timer(pfTimerCallBack, osTimerOnce , NULL);
00107 
00108     osTimerId id = osTimerCreate (osTimer(SmacTimer), osTimerOnce, NULL);
00109     osTimerStart (id, timeInMilliseconds);
00110     return 0;
00111 }
00112 
00113 
00114 /***********************************************************************************/
00115 /******************************** SMAC Data primitives *****************************/
00116 /***********************************************************************************/
00117 
00118 /************************************************************************************
00119 * MCPSDataRequest
00120 * 
00121 * This data primitive is used to send an over the air packet. This is an asynchronous 
00122 * function,  it means it asks SMAC to transmit one OTA packet,  but when the function 
00123 * returns it is not sent already.
00124 *
00125 ************************************************************************************/
00126 smacErrors_t MCPSDataRequest
00127 (
00128 txPacket_t *psTxPacket        //IN:Pointer to the packet to be transmitted
00129 )
00130 {  
00131   macToPdDataMessage_t *pMsg;
00132   phyStatus_t u8PhyRes = gPhySuccess_c; 
00133   
00134 #if(TRUE == smacInitializationValidation_d)
00135   if(FALSE == mSmacInitialized)
00136   {
00137     return gErrorNoValidCondition_c;
00138   }
00139 #endif      /* TRUE == smacInitializationValidation_d */
00140   
00141 #if(TRUE == smacParametersValidation_d)
00142   uint8_t u8MaxLen=0;
00143   
00144   u8MaxLen = gMaxSmacSDULength_c;
00145   
00146   if((NULL == psTxPacket) || (u8MaxLen < psTxPacket->u8DataLength))
00147   {
00148     return gErrorOutOfRange_c;
00149   }  
00150 #endif         /* TRUE == smacParametersValidation_d */
00151   
00152   if(mSmacStateIdle_c != smacState)
00153   {
00154     return gErrorBusy_c;
00155   }
00156 
00157   u8SmacSeqNo++;
00158   u8AckRetryCounter = 0;
00159   u8CCARetryCounter = 0;
00160   
00161   psTxPacket->u8DataLength = psTxPacket->u8DataLength + gSmacHeaderBytes_c; 
00162   
00163   pMsg = (macToPdDataMessage_t*)MEM_BufferAlloc( sizeof(macToPdDataMessage_t) +
00164                          psTxPacket->u8DataLength);
00165   if(pMsg == NULL )
00166   {
00167     return gErrorNoResourcesAvailable_c;
00168   }
00169   /* Fill with Phy related data */
00170   pMsg->macInstance = smacInstance;
00171   pMsg->msgType = gPdDataReq_c;
00172   //SMAC doesn't use slotted mode
00173   pMsg->msgData.dataReq.slottedTx = gPhyUnslottedMode_c;
00174   //start transmission immediately
00175   pMsg->msgData.dataReq.startTime = gPhySeqStartAsap_c;
00176 #ifdef gPHY_802_15_4g_d
00177   //for sub-Gig phy handles duration in case of ACK
00178   pMsg->msgData.dataReq.txDuration = 0xFFFFFFFF;
00179 #else
00180   if(txConfigurator.autoAck && 
00181      psTxPacket->smacHeader.destAddr != 0xFFFF &&
00182        psTxPacket->smacHeader.panId != 0xFFFF)
00183   {
00184                                     //Turn@       +       phy payload(symbols)+ Turn@ + ACK
00185     pMsg->msgData.dataReq.txDuration = 12 + (6 + psTxPacket->u8DataLength + 2)*2 + 12 + 42; 
00186     if(txConfigurator.ccaBeforeTx)
00187     {
00188       pMsg->msgData.dataReq.txDuration += 0x08; //CCA Duration: 8 symbols
00189     }
00190   }
00191   else
00192   {
00193     pMsg->msgData.dataReq.txDuration = 0xFFFFFFFF;
00194   }
00195 #endif
00196   pMsg->msgData.dataReq.psduLength = psTxPacket->u8DataLength;
00197   pMsg->msgData.dataReq.pPsdu = (uint8_t*)&pMsg->msgData.dataReq.pPsdu +
00198     sizeof(pMsg->msgData.dataReq.pPsdu);
00199   
00200   FLib_MemCpy(pMsg->msgData.dataReq.pPsdu, &(psTxPacket->smacHeader), gSmacHeaderBytes_c);
00201   FLib_MemCpy(pMsg->msgData.dataReq.pPsdu + gSmacHeaderBytes_c, 
00202               &(psTxPacket->smacPdu), 
00203               psTxPacket->u8DataLength - gSmacHeaderBytes_c);
00204   
00205   if(txConfigurator.ccaBeforeTx)
00206   {
00207     //tell phy to perform CCA before transmission
00208     pMsg->msgData.dataReq.CCABeforeTx = gPhyCCAMode1_c;
00209   }
00210   else
00211   {
00212     pMsg->msgData.dataReq.CCABeforeTx = gPhyNoCCABeforeTx_c;
00213   }
00214   
00215   if(txConfigurator.autoAck && 
00216      psTxPacket->smacHeader.destAddr != 0xFFFF &&
00217        psTxPacket->smacHeader.panId != 0xFFFF)
00218   {
00219     //set frame control option: ACK.
00220     pMsg->msgData.dataReq.pPsdu[0] |= FRAME_CTRL_ACK_FIELD_SET;
00221     pMsg->msgData.dataReq.ackRequired = gPhyRxAckRqd_c;
00222   }
00223   else
00224   {
00225     pMsg->msgData.dataReq.ackRequired = gPhyNoAckRqd_c;
00226   }
00227   //set sequence number;
00228   pMsg->msgData.dataReq.pPsdu[2] = u8SmacSeqNo;
00229   gSmacDataMessage = pMsg;      //Store pointer for freeing later 
00230   u8PhyRes = MAC_PD_SapHandler(pMsg, 0);
00231   
00232   psTxPacket->u8DataLength -= gSmacHeaderBytes_c;
00233   
00234   if(u8PhyRes == gPhySuccess_c)
00235   {
00236     smacState= mSmacStateTransmitting_c; 
00237     return gErrorNoError_c;
00238   }
00239   else
00240   {
00241     MEM_BufferFree(gSmacDataMessage);
00242     gSmacDataMessage = NULL;
00243     return gErrorNoResourcesAvailable_c;
00244   }
00245 }
00246 
00247 /************************************************************************************
00248 * MLMEConfigureTxContext
00249 * 
00250 * This management primitive is used to configure the conditions under which SMAC will
00251 * perform a transmission OTA.
00252 *
00253 ************************************************************************************/
00254 smacErrors_t MLMEConfigureTxContext(txContextConfig_t* pTxConfig)
00255 {
00256   if( (pTxConfig->autoAck == FALSE && pTxConfig->retryCountAckFail !=0) || 
00257       (pTxConfig->ccaBeforeTx == FALSE && pTxConfig->retryCountCCAFail !=0) )
00258   {
00259     return gErrorNoValidCondition_c;
00260   }
00261   if( pTxConfig->retryCountAckFail > gMaxRetriesAllowed_c || 
00262      pTxConfig->retryCountCCAFail > gMaxRetriesAllowed_c)
00263   {
00264     return gErrorOutOfRange_c;
00265   }
00266   txConfigurator.autoAck           = pTxConfig->autoAck;
00267   txConfigurator.ccaBeforeTx       = pTxConfig->ccaBeforeTx;
00268   txConfigurator.retryCountAckFail = pTxConfig->retryCountAckFail;
00269   txConfigurator.retryCountCCAFail = pTxConfig->retryCountCCAFail;
00270   
00271   return gErrorNoError_c;
00272 }
00273 
00274 /************************************************************************************
00275 * MLMERXEnableRequest
00276 * 
00277 * Function used to place the radio into receive mode 
00278 *
00279 ************************************************************************************/
00280 smacErrors_t MLMERXEnableRequest
00281 (
00282 rxPacket_t *gsRxPacket, //OUT: Pointer to the structure where the reception results 
00283 //     will be stored.
00284 smacTime_t stTimeout     //IN:  64-bit timeout value, absolute value in symbols
00285 )
00286 {
00287   
00288   uint8_t u8PhyRes = 0; 
00289   macToPlmeMessage_t lMsg;
00290   
00291 #if(TRUE == smacParametersValidation_d)
00292   uint8_t u8MaxLen=0;
00293   
00294   u8MaxLen = gMaxSmacSDULength_c;
00295 #endif         /* TRUE == smacParametersValidation_d */
00296   
00297 #if(TRUE == smacParametersValidation_d)
00298   if((NULL == gsRxPacket) || (u8MaxLen < gsRxPacket->u8MaxDataLength))
00299   {
00300     return gErrorOutOfRange_c;
00301   }
00302 #endif     /* TRUE == smacParametersValidation_d */
00303   
00304 #if(TRUE == smacInitializationValidation_d)
00305   if(FALSE == mSmacInitialized)
00306   {
00307     return gErrorNoValidCondition_c;
00308   }
00309 #endif     /* TRUE == smacInitializationValidation_d */
00310   
00311   if(mSmacStateIdle_c != smacState)
00312   {
00313     return gErrorBusy_c;
00314   }
00315   if(stTimeout)
00316   {
00317     lMsg.msgType = gPlmeSetTRxStateReq_c;
00318     lMsg.msgData.setTRxStateReq.startTime = gPhySeqStartAsap_c;
00319     lMsg.macInstance = smacInstance;
00320     lMsg.msgData.setTRxStateReq.state = gPhySetRxOn_c;
00321     mSmacTimeoutAsked = TRUE;
00322     lMsg.msgData.setTRxStateReq.rxDuration = stTimeout;
00323   }
00324   else
00325   {
00326     lMsg.msgType = gPlmeSetReq_c;
00327     lMsg.msgData.setReq.PibAttribute = gPhyPibRxOnWhenIdle;
00328     lMsg.msgData.setReq.PibAttributeValue = (uint64_t)1;
00329   }
00330   u8PhyRes = MAC_PLME_SapHandler(&lMsg, 0);
00331   if(u8PhyRes == gPhySuccess_c)
00332   {
00333     gsRxPacket->rxStatus = rxProcessingReceptionStatus_c;
00334     smacProccesPacketPtr.smacRxPacketPointer  = gsRxPacket;
00335     
00336     smacState= mSmacStateReceiving_c; 
00337     return gErrorNoError_c;
00338   }
00339   else
00340   {
00341     return gErrorNoResourcesAvailable_c;
00342   }
00343 }
00344 #if defined (gPHY_802_15_4g_d)
00345 /************************************************************************************
00346 * MLMESetPreambleLength
00347 * 
00348 * Function used to change the preamble size in the OTA Packet 
00349 *
00350 ************************************************************************************/
00351 smacErrors_t MLMESetPreambleLength
00352 (
00353 uint16_t u16preambleLength
00354 )
00355 {
00356 #if(TRUE == smacInitializationValidation_d)
00357   if(FALSE == mSmacInitialized)
00358   {
00359     return gErrorNoValidCondition_c;
00360   }
00361 #endif     /* TRUE == smacInitializationValidation_d */
00362   
00363   if(mSmacStateIdle_c != smacState)
00364   {
00365     return gErrorBusy_c;
00366   }
00367   smacPacketConfig.u16PreambleLength = u16preambleLength;
00368   gPhyPib.mPIBphyFSKPreambleRepetitions = u16preambleLength;
00369   PhyPib_RFUpdatePreambleLength();
00370   
00371   return gErrorNoError_c;
00372   
00373 }
00374 
00375 /************************************************************************************
00376 * MLMESetSyncWordSize
00377 * 
00378 * Function used to change the synchronization word size. Values from 0 to 8 required. 
00379 * IMPORTANT-> Use below arguments only (indicating a direct value from 1-8 will not work) 
00380 * Inputs      : 
00381 *   SyncConfig_SyncSize_1             
00382 *   SyncConfig_SyncSize_2              
00383 *   SyncConfig_SyncSize_3               
00384 *   SyncConfig_SyncSize_4               
00385 *   SyncConfig_SyncSize_5                
00386 *   SyncConfig_SyncSize_6                
00387 *   SyncConfig_SyncSize_7              
00388 *   SyncConfig_SyncSize_8    
00389 *
00390 ************************************************************************************/
00391 smacErrors_t MLMESetSyncWordSize
00392 (
00393 uint8_t u8syncWordSize
00394 )
00395 {
00396   
00397   phyStatus_t status;
00398 #if(TRUE == smacInitializationValidation_d)
00399   if(FALSE == mSmacInitialized)
00400   {
00401     return gErrorNoValidCondition_c;
00402   }
00403 #endif     /* TRUE == smacInitializationValidation_d */
00404   
00405   if(mSmacStateIdle_c != smacState)
00406   {
00407     return gErrorBusy_c;
00408   }
00409   
00410   status = (phyStatus_t)Phy_SetSyncWordSize(u8syncWordSize);
00411   if(status == gPhyInvalidParameter_c)
00412     return gErrorOutOfRange_c;
00413   
00414   smacPacketConfig.u8SyncWordSize = u8syncWordSize;
00415   
00416   return gErrorNoError_c;
00417   
00418 }
00419 
00420 /************************************************************************************
00421 * MLMESetSyncWordValue
00422 * 
00423 * Function used to change the synchronization word value. 
00424 *     
00425 *
00426 ************************************************************************************/
00427 smacErrors_t MLMESetSyncWordValue
00428 (
00429 uint8_t *u8syncWordValue
00430 )
00431 {
00432   uint8_t syncWordSizeTemp = smacPacketConfig.u8SyncWordSize;
00433   uint8_t syncValueRegIndex = 0;
00434   
00435 #if(TRUE == smacInitializationValidation_d)
00436   if(FALSE == mSmacInitialized)
00437   {
00438     return gErrorNoValidCondition_c;
00439   }
00440 #endif     /* TRUE == smacInitializationValidation_d */
00441   
00442   if(mSmacStateIdle_c != smacState)
00443   {
00444     return gErrorBusy_c;
00445   }
00446   
00447   smacPacketConfig.u8SyncWordValue = u8syncWordValue;
00448   
00449   while (syncWordSizeTemp--)
00450   {
00451     Phy_SetSyncWordValue(syncValueRegIndex, (uint8_t)*u8syncWordValue);
00452     syncValueRegIndex++;
00453     u8syncWordValue++;
00454   }
00455   while(syncValueRegIndex < 8)
00456   {
00457     Phy_SetSyncWordValue(syncValueRegIndex, 0x00);
00458     syncValueRegIndex++;
00459   }
00460   
00461   return gErrorNoError_c;
00462   
00463 }
00464 
00465 /************************************************************************************
00466 * MLMEPacketConfig
00467 * 
00468 *  
00469 *
00470 ************************************************************************************/
00471 smacErrors_t MLMEPacketConfig
00472 (
00473 packetConfig_t *pPacketCfg
00474 )
00475 {
00476   smacErrors_t err = gErrorNoError_c;
00477 #if(TRUE == smacInitializationValidation_d)
00478   if(FALSE == mSmacInitialized)
00479   {
00480     return gErrorNoValidCondition_c;
00481   }
00482 #endif     /* TRUE == smacInitializationValidation_d */
00483   
00484   if(mSmacStateIdle_c != smacState)
00485   {
00486     return gErrorBusy_c;
00487   } 
00488   err  = MLMESetSyncWordSize(pPacketCfg->u8SyncWordSize);
00489   err |=  MLMESetSyncWordValue(pPacketCfg->pu8SyncWord);
00490   err |= MLMESetPreambleLength(pPacketCfg->u16PreambleSize);
00491   if(err != gErrorNoError_c)
00492     return gErrorOutOfRange_c;
00493   
00494   return gErrorNoError_c;   
00495 }
00496 
00497 #endif
00498 
00499 /************************************************************************************
00500 * MLMESetChannelRequest
00501 * 
00502 *  
00503 *
00504 ************************************************************************************/
00505 smacErrors_t MLMESetChannelRequest
00506 (
00507 channels_t newChannel
00508 )
00509 {
00510   uint8_t errorVal;
00511   smacErrors_t err = gErrorNoError_c;
00512   
00513   macToPlmeMessage_t lMsg;
00514 #if(TRUE == smacInitializationValidation_d)
00515   if(FALSE == mSmacInitialized)
00516   {
00517     return gErrorNoValidCondition_c;
00518   }
00519 #endif     /* TRUE == smacInitializationValidation_d */
00520   if(mSmacStateIdle_c != smacState)
00521   {
00522     return gErrorBusy_c;
00523   } 
00524   lMsg.msgType = gPlmeSetReq_c;
00525   lMsg.macInstance = smacInstance;
00526   lMsg.msgData.setReq.PibAttribute = gPhyPibCurrentChannel_c;
00527   lMsg.msgData.setReq.PibAttributeValue = (uint64_t) newChannel;
00528   
00529   errorVal = MAC_PLME_SapHandler(&lMsg, 0);
00530   switch (errorVal)
00531   {
00532   case  gPhyBusy_c:
00533     err = gErrorBusy_c;
00534     break;
00535     
00536   case gPhyInvalidParameter_c:   
00537     err = gErrorOutOfRange_c;
00538     break;
00539     
00540   case gPhySuccess_c: 
00541     err = gErrorNoError_c;
00542     break;
00543     
00544   default:
00545     err = gErrorOutOfRange_c;
00546     break;
00547   }
00548   
00549   return err;
00550 }
00551 
00552 
00553 /************************************************************************************
00554 * MLMESetAdditionalRFOffset
00555 *
00556 *************************************************************************************/
00557 smacErrors_t MLMESetAdditionalRFOffset (uint32_t additionalRFOffset)
00558 {
00559 #if(TRUE == smacInitializationValidation_d)
00560   if(FALSE == mSmacInitialized)
00561   {
00562     return gErrorNoValidCondition_c;
00563   }
00564 #endif     /* TRUE == smacInitializationValidation_d */
00565 
00566 #ifdef gIncludeCalibrationOption
00567   gPhyPib.mPIBAdditionalRFFrequencyOffset = additionalRFOffset;
00568   return gErrorNoError_c;
00569 #else
00570   return gErrorNoResourcesAvailable_c;
00571 #endif
00572 }
00573 
00574 
00575 /************************************************************************************
00576 * MLMEGetAdditionalRFOffset
00577 *
00578 *************************************************************************************/
00579 uint32_t MLMEGetAdditionalRFOffset( void )
00580 {
00581 #ifdef gIncludeCalibrationOption
00582   return gPhyPib.mPIBAdditionalRFFrequencyOffset;
00583 #else
00584   return 0;
00585 #endif
00586 }
00587 
00588 #if defined (gPHY_802_15_4g_d)
00589 /************************************************************************************
00590 * MLMESetFreqBand
00591 *
00592 ************************************************************************************/
00593 smacErrors_t MLMESetFreqBand
00594 (
00595 smacFrequencyBands_t freqBand,
00596 smacRFModes_t phyMode
00597 )
00598 {               
00599   return gErrorNoResourcesAvailable_c;
00600 }
00601 
00602 smacErrors_t MLMESetPhyMode(smacRFModes_t phyMode)
00603 {
00604 #if(TRUE == smacInitializationValidation_d)
00605   if(FALSE == mSmacInitialized)
00606   {
00607     return gErrorNoValidCondition_c;
00608   }
00609 #endif     /* TRUE == smacInitializationValidation_d */
00610   phyStatus_t err;
00611   macToPlmeMessage_t lMsg;
00612   
00613   if(mSmacStateIdle_c != smacState)
00614   {
00615     return gErrorBusy_c;
00616   }
00617   lMsg.macInstance = smacInstance;
00618   lMsg.msgType = gPlmeSetReq_c;
00619   lMsg.msgData.setReq.PibAttribute = gPhyPibCurrentMode_c;
00620   lMsg.msgData.setReq.PibAttributeValue = (uint64_t)phyMode;
00621   err = MAC_PLME_SapHandler(&lMsg, 0);
00622   if(err == gPhyInvalidParameter_c)
00623     return gErrorOutOfRange_c;
00624   if(err == gPhyBusy_c)
00625     return gErrorBusy_c;
00626   
00627   gTotalChannels = gPhyPib.pPIBphyRfConstants->totalNumChannels;
00628   
00629   return gErrorNoError_c;
00630 }
00631 
00632 #endif
00633 /************************************************************************************
00634 * MLMEGetChannelRequest
00635 * 
00636 *  
00637 *
00638 ************************************************************************************/
00639 channels_t MLMEGetChannelRequest
00640 (
00641 void 
00642 )
00643 {
00644   channels_t currentChannel;
00645   macToPlmeMessage_t lMsg;  
00646 #if(TRUE == smacInitializationValidation_d)
00647   if(FALSE == mSmacInitialized)
00648   {
00649     //panic(0,0,0,0);
00650   }
00651 #endif     /* TRUE == smacInitializationValidation_d */ 
00652   lMsg.msgType = gPlmeGetReq_c;
00653   lMsg.macInstance = smacInstance;
00654   lMsg.msgData.getReq.PibAttribute = gPhyPibCurrentChannel_c;
00655   lMsg.msgData.getReq.pPibAttributeValue = (uint64_t*)&currentChannel;
00656   MAC_PLME_SapHandler(&lMsg, 0);
00657   return currentChannel;    
00658 }
00659 
00660 #if defined (gPHY_802_15_4g_d)
00661 /************************************************************************************
00662 * MLMERssi
00663 * 
00664 *  
00665 * 
00666 ************************************************************************************/
00667 uint8_t MLMERssi(void )
00668 {
00669   uint8_t rssiVal;
00670   
00671 #if(TRUE == smacInitializationValidation_d)
00672   if(FALSE == mSmacInitialized)
00673   {
00674     return gErrorNoValidCondition_c;
00675   }
00676 #endif     /* TRUE == smacInitializationValidation_d */
00677   
00678   if(mSmacStateIdle_c != smacState)
00679   {
00680     return gErrorBusy_c;
00681   }
00682   
00683   rssiVal = Phy_GetRssi();
00684   return rssiVal;
00685 }
00686 
00687 /************************************************************************************
00688 * MLMESetCCADuration
00689 * 
00690 *  
00691 * 
00692 ************************************************************************************/
00693 smacErrors_t MLMESetCCADuration(uint64_t usCCADuration )
00694 {
00695   macToPlmeMessage_t lMsg;
00696   phyStatus_t status;
00697   
00698 #if(TRUE == smacInitializationValidation_d)
00699   if(FALSE == mSmacInitialized)
00700   {
00701     return gErrorNoValidCondition_c;
00702   }
00703 #endif     /* TRUE == smacInitializationValidation_d */
00704   
00705   if(mSmacStateIdle_c != smacState)
00706   {
00707     return gErrorBusy_c;
00708   }
00709   
00710   usCCADuration = TIME_US_TO_TICKS(usCCADuration);
00711   Phy_TimeDivider((phyTime_t*)&usCCADuration);
00712   
00713   lMsg.msgType = gPlmeSetReq_c;
00714   lMsg.msgData.setReq.PibAttribute = gPhyPibCCADuration_c;
00715   lMsg.msgData.setReq.PibAttributeValue = usCCADuration;
00716   status = MAC_PLME_SapHandler(&lMsg, 0);
00717   
00718   if(status == gPhySuccess_c)
00719     return gErrorNoError_c;
00720   else
00721     return gErrorNoResourcesAvailable_c;
00722 }
00723 
00724 /************************************************************************************
00725 * MLMESetInterPacketRxDelay
00726 * 
00727 * IMPORTANT-> Use below arguments only (indicating a direct value from 1-12 will not work)
00728 * Inputs      :
00729 *
00730 * InterPacketRxDelay_0
00731 * InterPacketRxDelay_1
00732 * InterPacketRxDelay_2
00733 * InterPacketRxDelay_3
00734 * InterPacketRxDelay_4
00735 * InterPacketRxDelay_5
00736 * InterPacketRxDelay_6
00737 * InterPacketRxDelay_7
00738 * InterPacketRxDelay_8
00739 * InterPacketRxDelay_9
00740 * InterPacketRxDelay_A
00741 * InterPacketRxDelay_B
00742 ************************************************************************************/
00743 smacErrors_t MLMESetInterPacketRxDelay
00744 (
00745 uint8_t u8InterPacketRxDelay
00746 )
00747 {   
00748 #if(TRUE == smacInitializationValidation_d)
00749   if(FALSE == mSmacInitialized)
00750   {
00751     return gErrorNoValidCondition_c;
00752   }
00753 #endif     /* TRUE == smacInitializationValidation_d */
00754   
00755   if(mSmacStateIdle_c != smacState)
00756   {
00757     return gErrorBusy_c;
00758   }
00759   
00760   if (gPhySuccess_c != Phy_SetInterPacketRxDelay(u8InterPacketRxDelay))
00761   {
00762     return gErrorOutOfRange_c;
00763   }
00764   return gErrorNoError_c;
00765 }
00766 
00767 #endif
00768 /************************************************************************************
00769 * MLMERXDisableRequest
00770 * 
00771 * Returns the radio to idle mode from receive mode.
00772 *
00773 ************************************************************************************/
00774 smacErrors_t MLMERXDisableRequest(void)
00775 {
00776   macToPlmeMessage_t lMsg;
00777   phyStatus_t err;
00778 #if(TRUE == smacInitializationValidation_d)
00779   if(FALSE == mSmacInitialized)
00780   {
00781     return gErrorNoValidCondition_c;
00782   }
00783 #endif
00784   if((mSmacStateReceiving_c != smacState) && (mSmacStateIdle_c != smacState))
00785   {
00786     return gErrorNoValidCondition_c;
00787   }
00788   lMsg.macInstance = smacInstance;
00789   if(!mSmacTimeoutAsked)
00790   {
00791     lMsg.msgType                          = gPlmeSetReq_c;
00792     lMsg.msgData.setReq.PibAttribute      = gPhyPibRxOnWhenIdle;
00793     lMsg.msgData.setReq.PibAttributeValue = (uint64_t)0;
00794     err = MAC_PLME_SapHandler(&lMsg, 0);
00795     if(err != gPhySuccess_c)
00796       return gErrorBusy_c;
00797   }
00798   else
00799   {
00800     lMsg.msgType = gPlmeSetTRxStateReq_c;
00801     lMsg.msgData.setTRxStateReq.state = gPhyForceTRxOff_c;
00802     (void)MAC_PLME_SapHandler(&lMsg, 0);
00803     mSmacTimeoutAsked = FALSE;
00804   }
00805   smacState= mSmacStateIdle_c;
00806   
00807   return gErrorNoError_c;
00808   
00809 }
00810 
00811 /*@CMA, Conn Test Added*/
00812 /************************************************************************************
00813 * MLMETXDisableRequest
00814 * 
00815 * Returns the radio to idle mode from Tx mode.
00816 *
00817 ************************************************************************************/
00818 void MLMETXDisableRequest(void)
00819 {
00820   macToPlmeMessage_t lMsg;
00821   lMsg.macInstance = smacInstance;
00822   lMsg.msgType     = gPlmeSetTRxStateReq_c;
00823   lMsg.msgData.setTRxStateReq.state = gPhyForceTRxOff_c;
00824   (void)MAC_PLME_SapHandler(&lMsg, 0);
00825   if(gSmacDataMessage != NULL)
00826   {
00827     (void)MEM_BufferFree(gSmacDataMessage);
00828     gSmacDataMessage = NULL;
00829   }
00830   smacState= mSmacStateIdle_c;
00831 }
00832 
00833 /************************************************************************************
00834 * MLMELinkQuality
00835 * 
00836 * This  function  returns  an  integer  value  that is the link quality from the last 
00837 * received packet of the form:  dBm = (-Link Quality/2).
00838 *
00839 ************************************************************************************/
00840 uint8_t MLMELinkQuality(void)
00841 {
00842 #if(TRUE == smacInitializationValidation_d)
00843   if(FALSE == mSmacInitialized)
00844   {
00845     return 0;
00846   }
00847 #endif
00848   return smacLastDataRxParams.linkQuality;
00849 }
00850 
00851 /************************************************************************************
00852 * MLMEPAOutputAdjust
00853 * 
00854 *
00855 ************************************************************************************/
00856 smacErrors_t MLMEPAOutputAdjust
00857 ( 
00858 uint8_t u8PaValue
00859 )
00860 {
00861   macToPlmeMessage_t lMsg;
00862   smacErrors_t err = gErrorNoError_c;
00863   uint8_t errorVal;     
00864 #if(TRUE == smacInitializationValidation_d)
00865   if(FALSE == mSmacInitialized)
00866   {
00867     return gErrorNoValidCondition_c;
00868   }
00869 #endif /* TRUE == smacInitializationValidation_d */
00870   
00871   if(mSmacStateIdle_c != smacState)
00872   {
00873     return gErrorBusy_c;
00874   }
00875   lMsg.macInstance = smacInstance;
00876   lMsg.msgType     = gPlmeSetReq_c;
00877   lMsg.msgData.setReq.PibAttribute      =  gPhyPibTransmitPower_c;
00878   lMsg.msgData.setReq.PibAttributeValue =  (uint64_t) u8PaValue;
00879   errorVal = MAC_PLME_SapHandler(&lMsg, 0);
00880   switch (errorVal)
00881   {
00882   case  gPhyBusy_c:
00883     err = gErrorBusy_c;
00884     break;
00885     
00886   case gPhyInvalidParameter_c:   
00887     err = gErrorOutOfRange_c;
00888     break;
00889     
00890   case gPhySuccess_c: 
00891     err = gErrorNoError_c;
00892     break;
00893     
00894   default:
00895     err = gErrorOutOfRange_c; 
00896     break;
00897   }
00898   
00899   return err;
00900 }
00901 
00902 /************************************************************************************
00903 * MLMEScanRequest
00904 * 
00905 * This  function  returns  the RSSI value of the channel passes as a parameter  
00906 * 
00907 *
00908 ************************************************************************************/
00909 smacErrors_t MLMEScanRequest(channels_t u8ChannelToScan)
00910 {
00911   smacErrors_t err = gErrorNoError_c;
00912   phyStatus_t u8PhyRes;
00913 #if(TRUE == smacInitializationValidation_d)
00914   if(FALSE == mSmacInitialized)
00915   {
00916     return gErrorNoValidCondition_c;
00917   }
00918 #endif /* TRUE == smacInitializationValidation_d */
00919   
00920   if(mSmacStateIdle_c != smacState)
00921   {
00922     return gErrorBusy_c;
00923   }
00924   if(u8ChannelToScan != MLMEGetChannelRequest())
00925     err = MLMESetChannelRequest(u8ChannelToScan);
00926   if(err != gErrorNoError_c)
00927     return err;
00928   
00929   macToPlmeMessage_t* pMsg = (macToPlmeMessage_t*)MEM_BufferAlloc(sizeof(macToPlmeMessage_t));
00930   pMsg->msgType = gPlmeEdReq_c;
00931   pMsg->msgData.edReq.startTime = gPhySeqStartAsap_c;
00932   pMsg->macInstance = smacInstance;
00933   gSmacMlmeMessage = pMsg;
00934   u8PhyRes = MAC_PLME_SapHandler(pMsg,0);
00935   if(u8PhyRes != gPhySuccess_c)
00936   {
00937     MEM_BufferFree(gSmacMlmeMessage);
00938     gSmacMlmeMessage = NULL;
00939     return gErrorBusy_c;
00940   }
00941   smacState = mSmacStateScanningChannels_c;
00942   return gErrorNoError_c;
00943 }
00944 
00945 
00946 /************************************************************************************
00947 * MLMECcaRequest
00948 * 
00949 * This  function  performs Clear Channel Assessment on the active channel  
00950 * 
00951 *
00952 ************************************************************************************/
00953 smacErrors_t MLMECcaRequest()
00954 {
00955   phyStatus_t u8PhyRes;
00956 #if(TRUE == smacInitializationValidation_d)
00957   if(FALSE == mSmacInitialized)
00958   {
00959     return gErrorNoValidCondition_c;
00960   }
00961 #endif /* TRUE == smacInitializationValidation_d */
00962   
00963   if(mSmacStateIdle_c != smacState)
00964   {
00965     return gErrorBusy_c;
00966   }
00967   macToPlmeMessage_t* pMsg = (macToPlmeMessage_t*)MEM_BufferAlloc(sizeof(macToPlmeMessage_t));
00968   pMsg->msgType = gPlmeCcaReq_c;
00969   pMsg->msgData.ccaReq.ccaType = gPhyCCAMode1_c;
00970   pMsg->msgData.ccaReq.contCcaMode = gPhyContCcaDisabled;
00971   pMsg->macInstance = smacInstance;
00972   gSmacMlmeMessage = pMsg;
00973   u8PhyRes = MAC_PLME_SapHandler(pMsg,0);
00974   if(u8PhyRes != gPhySuccess_c)
00975   {
00976     MEM_BufferFree(gSmacMlmeMessage);
00977     gSmacMlmeMessage = NULL;
00978     return gErrorBusy_c;
00979   }
00980   smacState = mSmacStatePerformingCca_c;
00981   return gErrorNoError_c;
00982 }
00983 /************************************************************************************
00984 * MLMEPhySoftReset
00985 * 
00986 * This function performs a software reset on the radio, PHY and SMAC state machines.
00987 * 
00988 *
00989 ************************************************************************************/
00990 smacErrors_t MLMEPhySoftReset
00991 (
00992 void    
00993 )
00994 {   
00995   macToPlmeMessage_t lMsg;
00996 #if(TRUE == smacInitializationValidation_d)
00997   if(FALSE == mSmacInitialized)
00998   {
00999     return gErrorNoValidCondition_c;
01000   }
01001 #endif /* TRUE == smacInitializationValidation_d */
01002 //  
01003 //  if(mSmacStateIdle_c != smacState)
01004 //  {
01005 //    return gErrorBusy_c;
01006 //  }
01007   lMsg.macInstance = smacInstance;
01008   lMsg.msgType     = gPlmeSetTRxStateReq_c;
01009   lMsg.msgData.setTRxStateReq.state = gPhyForceTRxOff_c;
01010   (void)MAC_PLME_SapHandler(&lMsg, 0);
01011   smacState= mSmacStateIdle_c; 
01012   
01013   return gErrorNoError_c;
01014 }
01015 /************************************************************************************
01016 * PD_SMAC_SapHandler
01017 * 
01018 * This SAP handles data confirm and data indication from PHY.
01019 * 
01020 ************************************************************************************/
01021 phyStatus_t PD_SMAC_SapHandler(void* pMsg, instanceId_t smacInstanceId)
01022 {
01023   phyStatus_t status = gPhyInvalidPrimitive_c;
01024   smacToAppDataMessage_t* pSmacMsg;
01025   pdDataToMacMessage_t* pDataMsg = (pdDataToMacMessage_t*)pMsg;
01026   (void)smacInstanceId;
01027   
01028   switch(pDataMsg->msgType)
01029   {
01030   case gPdDataCnf_c:
01031     //no data request was fired
01032     if(NULL == gSmacDataMessage)
01033     {
01034       status = gPhySuccess_c;
01035     }
01036     else
01037     {
01038       //phy finished work with the data request packet so it can be freed
01039       MEM_BufferFree(gSmacDataMessage);
01040       gSmacDataMessage = NULL;
01041       
01042       pSmacMsg = (smacToAppDataMessage_t*)MEM_BufferAlloc(sizeof(smacToAppDataMessage_t));
01043       if(pSmacMsg == NULL)
01044       {
01045         status = gPhySuccess_c;
01046       }
01047       else
01048       {
01049         pSmacMsg->msgType = gMcpsDataCnf_c;
01050         pSmacMsg->msgData.dataCnf.status = gErrorNoError_c;
01051         // call App Sap
01052         gSMAC_APP_MCPS_SapHandler(pSmacMsg,smacInstance); 
01053       }
01054       smacState = mSmacStateIdle_c;
01055     }
01056     break;
01057   case gPdDataInd_c:
01058     if(FALSE == SMACPacketCheck(pDataMsg))
01059     {
01060       MEM_BufferFree(pDataMsg);
01061       status = gPhySuccess_c;
01062     }
01063     else
01064     {
01065       smacLastDataRxParams.linkQuality = ((pdDataToMacMessage_t*)pMsg)->msgData.dataInd.ppduLinkQuality;
01066       smacLastDataRxParams.timeStamp = (phyTime_t)((pdDataToMacMessage_t*)pMsg)->msgData.dataInd.timeStamp;
01067       smacProccesPacketPtr.smacRxPacketPointer->rxStatus = rxSuccessStatus_c;
01068       
01069       // in case no timeout was asked we need to unset RXOnWhenIdle Pib.
01070       if(!mSmacTimeoutAsked) 
01071       {
01072         (void)MLMERXDisableRequest();
01073       }
01074       smacProccesPacketPtr.smacRxPacketPointer->u8DataLength = 
01075         pDataMsg->msgData.dataInd.psduLength - gSmacHeaderBytes_c;
01076       FLib_MemCpy(&smacProccesPacketPtr.smacRxPacketPointer->smacHeader, 
01077                   ((smacHeader_t*)pDataMsg->msgData.dataInd.pPsdu), 
01078                   gSmacHeaderBytes_c);
01079       FLib_MemCpy(&smacProccesPacketPtr.smacRxPacketPointer->smacPdu, 
01080                   ((smacPdu_t*)(pDataMsg->msgData.dataInd.pPsdu + gSmacHeaderBytes_c)), 
01081                   smacProccesPacketPtr.smacRxPacketPointer->u8DataLength);
01082       
01083       pSmacMsg = (smacToAppDataMessage_t*)MEM_BufferAlloc(sizeof(smacToAppDataMessage_t));
01084       if(pSmacMsg == NULL)
01085       {
01086         status = gPhySuccess_c;
01087       }
01088       else
01089       {
01090         pSmacMsg->msgType = gMcpsDataInd_c;
01091         pSmacMsg->msgData.dataInd.pRxPacket = smacProccesPacketPtr.smacRxPacketPointer;
01092         pSmacMsg->msgData.dataInd.u8LastRxRssi = PhyGetLastRxRssiValue();
01093         gSMAC_APP_MCPS_SapHandler(pSmacMsg,smacInstance); 
01094       }
01095       smacState = mSmacStateIdle_c;
01096     }
01097     break;
01098   default:
01099     break;
01100   }
01101   MEM_BufferFree(pMsg);
01102   return status;
01103 }
01104 
01105 /************************************************************************************
01106 * PLME_SMAC_SapHandler
01107 * 
01108 * This SAP handles management for confirms and indications from PHY.
01109 * 
01110 ************************************************************************************/
01111 
01112 phyStatus_t PLME_SMAC_SapHandler(void* pMsg, instanceId_t smacInstanceId)
01113 {
01114   MEM_BufferFree(gSmacMlmeMessage);
01115   gSmacMlmeMessage = NULL;
01116   uint32_t backOffTime;
01117 
01118   plmeToMacMessage_t* pPlmeMsg = (plmeToMacMessage_t*)pMsg;
01119   
01120   smacToAppMlmeMessage_t* pSmacToApp;
01121   smacToAppDataMessage_t* pSmacMsg;
01122   switch(pPlmeMsg->msgType)
01123   {
01124   case gPlmeCcaCnf_c:
01125     if(pPlmeMsg->msgData.ccaCnf.status == gPhyChannelBusy_c && 
01126        smacState == mSmacStateTransmitting_c)
01127     {
01128       if(txConfigurator.ccaBeforeTx)
01129       { 
01130           if(txConfigurator.retryCountCCAFail > u8CCARetryCounter)
01131           {
01132             //increment cca fail counter
01133             u8CCARetryCounter++;
01134             //get random number for backoff time.
01135             RNG_GetRandomNo(&backOffTime);
01136             //start event timer. After time elapses, Data request will be fired.
01137             TMR_StartSingleShotTimer(u8BackoffTimerId, ((backOffTime & gMaxBackoffTime_c) + gMinBackoffTime_c), BackoffTimeElapsed, NULL);
01138           }
01139           else
01140           {
01141             MEM_BufferFree(gSmacDataMessage);
01142             gSmacDataMessage = NULL;
01143             
01144             //retries failed so create message for the application
01145             pSmacMsg = (smacToAppDataMessage_t*)MEM_BufferAlloc(sizeof(smacToAppDataMessage_t));
01146             if(pSmacMsg != NULL)
01147             {
01148               //error type : Channel Busy
01149               pSmacMsg->msgData.dataCnf.status = gErrorChannelBusy_c;
01150               //type is Data Confirm
01151               pSmacMsg->msgType = gMcpsDataCnf_c;
01152               gSMAC_APP_MCPS_SapHandler(pSmacMsg, smacInstance);
01153             }
01154             //place SMAC into idle state
01155             smacState = mSmacStateIdle_c;
01156           }
01157       }
01158       MEM_BufferFree(pMsg);
01159       return gPhySuccess_c;
01160     }
01161     //if SMAC isn't in TX then definitely it is a CCA confirm
01162     //allocate a message for the application
01163     pSmacToApp = (smacToAppMlmeMessage_t*)MEM_BufferAlloc(sizeof(smacToAppMlmeMessage_t));
01164     if(pSmacToApp != NULL)
01165     {
01166       //type is CCA Confirm
01167       pSmacToApp->msgType = gMlmeCcaCnf_c;
01168       //Channel status translated into SMAC messages: idle channel means no error.
01169       if(pPlmeMsg->msgData.ccaCnf.status == gPhyChannelIdle_c)
01170       {
01171         pSmacToApp->msgData.ccaCnf.status = gErrorNoError_c;
01172       }
01173       else
01174       {
01175         pSmacToApp->msgData.ccaCnf.status = gErrorChannelBusy_c;
01176       }
01177     }
01178     break;
01179   case gPlmeEdCnf_c:
01180     //allocate a message for the application
01181     pSmacToApp = (smacToAppMlmeMessage_t*)MEM_BufferAlloc(sizeof(smacToAppMlmeMessage_t));
01182     if(pSmacToApp != NULL)
01183     {
01184       //message type is ED Confirm
01185       pSmacToApp->msgType = gMlmeEdCnf_c;
01186       if(pPlmeMsg->msgData.edCnf.status == gPhySuccess_c)
01187       {
01188         pSmacToApp->msgData.edCnf.status = gErrorNoError_c;
01189         pSmacToApp->msgData.edCnf.energyLevel = pPlmeMsg->msgData.edCnf.energyLevel;
01190         pSmacToApp->msgData.edCnf.energyLeveldB = pPlmeMsg->msgData.edCnf.energyLeveldB;
01191         pSmacToApp->msgData.edCnf.scannedChannel = MLMEGetChannelRequest();
01192       }
01193       else
01194       {
01195         pSmacToApp->msgData.edCnf.status = gErrorBusy_c;
01196       }
01197     }
01198     break;
01199   case gPlmeTimeoutInd_c:
01200     if(smacState == mSmacStateTransmitting_c)
01201     {
01202       if(txConfigurator.autoAck)
01203       {
01204         //re-arm retries for channel busy at retransmission.
01205         u8CCARetryCounter = 0;
01206         
01207         if(txConfigurator.retryCountAckFail > u8AckRetryCounter)
01208         {
01209           u8AckRetryCounter++;
01210           
01211           RNG_GetRandomNo(&backOffTime);
01212           //start event timer. After time elapses, Data request will be fired.
01213           TMR_StartSingleShotTimer(u8BackoffTimerId, ((backOffTime & gMaxBackoffTime_c) + gMinBackoffTime_c), BackoffTimeElapsed, NULL);
01214         }
01215         else
01216         {
01217           (void)MEM_BufferFree(gSmacDataMessage);
01218           gSmacDataMessage = NULL;
01219           
01220           //retries failed so create message for the application
01221           pSmacMsg = (smacToAppDataMessage_t*)MEM_BufferAlloc(sizeof(smacToAppDataMessage_t));
01222           if(pSmacMsg != NULL)
01223           {
01224             //set error code: No Ack
01225             pSmacMsg->msgData.dataCnf.status = gErrorNoAck_c;
01226             //type is Data Confirm
01227             pSmacMsg->msgType = gMcpsDataCnf_c;
01228             
01229             gSMAC_APP_MCPS_SapHandler(pSmacMsg, smacInstance);
01230           }
01231           //place SMAC into idle state
01232           smacState = mSmacStateIdle_c;
01233         }
01234       }
01235       MEM_BufferFree(pMsg);
01236       return gPhySuccess_c;
01237     }
01238     //if no ack timeout was received then it is definitely a RX timeout
01239     pSmacToApp = (smacToAppMlmeMessage_t*)MEM_BufferAlloc(sizeof(smacToAppMlmeMessage_t));
01240     if(pSmacToApp != NULL)
01241     {
01242       if(smacState == mSmacStateReceiving_c)
01243       {
01244         smacProccesPacketPtr.smacRxPacketPointer->rxStatus = rxTimeOutStatus_c;
01245       }
01246       pSmacToApp->msgType = gMlmeTimeoutInd_c;
01247     }
01248     break;
01249   case gPlme_UnexpectedRadioResetInd_c:
01250     pSmacToApp = (smacToAppMlmeMessage_t*)MEM_BufferAlloc(sizeof(smacToAppMlmeMessage_t));
01251     if(pSmacToApp != NULL)
01252       pSmacToApp->msgType = gMlme_UnexpectedRadioResetInd_c;
01253     break;
01254   default:
01255     //MEM_BufferFree(pSmacToApp);
01256     MEM_BufferFree(pMsg);
01257     return gPhySuccess_c;
01258   }
01259   smacState = mSmacStateIdle_c;
01260   //send message to upper layer if it is not NULL
01261   if(pSmacToApp != NULL)
01262     (gSMAC_APP_MLME_SapHandler)(pSmacToApp,0);
01263   MEM_BufferFree(pMsg);
01264   return gPhySuccess_c;
01265 }
01266 
01267 /************************************************************************************
01268 * Smac_RegisterSapHandlers
01269 * 
01270 * This function helps the user register the handlers for the messages that come from 
01271 * SMAC.
01272 * 
01273 ************************************************************************************/
01274 
01275 void Smac_RegisterSapHandlers(
01276                               SMAC_APP_MCPS_SapHandler_t pSMAC_APP_MCPS_SapHandler,
01277                               SMAC_APP_MLME_SapHandler_t pSMAC_APP_MLME_SapHandler,
01278                               instanceId_t smacInstanceId
01279                                 )
01280 {
01281   gSMAC_APP_MCPS_SapHandler = pSMAC_APP_MCPS_SapHandler;
01282   gSMAC_APP_MLME_SapHandler = pSMAC_APP_MLME_SapHandler;
01283   (void)smacInstanceId;
01284 }
01285 
01286 /************************************************************************************
01287 * SMACFillHeader
01288 * 
01289 * This function helps the user fill the SMAC header(short hardcoded MAC header) with
01290 * the desired short destination address.
01291 * 
01292 ************************************************************************************/
01293 
01294 void SMACFillHeader(smacHeader_t* pSmacHeader, uint16_t destAddr)
01295 {
01296   pSmacHeader->frameControl = gSmacDefaultFrameCtrl;
01297   pSmacHeader->panId        = u16PanID;
01298   pSmacHeader->seqNo        = gSmacDefaultSeqNo;
01299   pSmacHeader->srcAddr      = u16ShortSrcAddress;
01300   pSmacHeader->destAddr     = destAddr;
01301 }
01302 
01303 /************************************************************************************
01304 * InitSmac
01305 * 
01306 * Basic SMAC initialisation.
01307 * 
01308 ************************************************************************************/
01309 void InitSmac(void)
01310 {
01311   /* SMAC Initialization */
01312   smacState = mSmacStateIdle_c;
01313   smacLastDataRxParams.linkQuality = 0;
01314   smacLastDataRxParams.timeStamp = 0;
01315   uint32_t u32RandomNo;
01316 #if defined(gPHY_802_15_4g_d)
01317   gTotalChannels = gPhyPib.pPIBphyRfConstants->totalNumChannels;
01318 #else
01319   gTotalChannels = 26;
01320 #endif
01321   
01322   
01323 #if(TRUE == smacInitializationValidation_d)
01324   mSmacInitialized = TRUE;  
01325 #endif
01326   txConfigurator.autoAck = FALSE;
01327   txConfigurator.ccaBeforeTx = FALSE;
01328   txConfigurator.retryCountAckFail = 0;
01329   txConfigurator.retryCountCCAFail = 0;
01330   u8BackoffTimerId = (uint8_t)TMR_AllocateTimer();
01331   RNG_Init();
01332   RNG_GetRandomNo(&u32RandomNo);
01333   u8SmacSeqNo = (uint8_t)u32RandomNo;
01334   //Notify the PHY what function to call for communicating with SMAC  
01335   Phy_RegisterSapHandlers((PD_MAC_SapHandler_t)PD_SMAC_SapHandler, (PLME_MAC_SapHandler_t)PLME_SMAC_SapHandler, 0);
01336   u16PanID = gDefaultPanID_c;
01337   u16ShortSrcAddress = gNodeAddress_c;
01338   (void)SMACSetShortSrcAddress(u16ShortSrcAddress);
01339   (void)SMACSetPanID(u16PanID);
01340 }
01341 
01342 /************************************************************************************
01343 * SMACSetShortSrcAddress
01344 * 
01345 * This function sets the short source address so that PHY can perform filtering
01346 * 
01347 ************************************************************************************/
01348 
01349 smacErrors_t SMACSetShortSrcAddress(uint16_t nwShortAddress)
01350 {
01351   macToPlmeMessage_t lMsg;
01352   lMsg.msgType = gPlmeSetReq_c;
01353   lMsg.msgData.setReq.PibAttribute = gPhyPibShortAddress_c;
01354   lMsg.msgData.setReq.PibAttributeValue = (uint64_t)nwShortAddress;
01355   
01356   phyStatus_t u8PhyRes = MAC_PLME_SapHandler(&lMsg,0);
01357   if(u8PhyRes == gPhyBusy_c || u8PhyRes == gPhyBusyTx_c || u8PhyRes == gPhyBusyRx_c)
01358     return gErrorBusy_c;
01359   if(u8PhyRes != gPhySuccess_c)
01360     return gErrorNoResourcesAvailable_c;
01361   u16ShortSrcAddress = nwShortAddress;
01362   return gErrorNoError_c;
01363 }
01364 
01365 /************************************************************************************
01366 * SMACSetPanID
01367 * 
01368 * This function sets the pan ID so that PHY can perform filtering
01369 * 
01370 ************************************************************************************/
01371 
01372 smacErrors_t SMACSetPanID(uint16_t nwShortPanID)
01373 {
01374   macToPlmeMessage_t lMsg;
01375   lMsg.msgType = gPlmeSetReq_c;
01376   lMsg.msgData.setReq.PibAttribute = gPhyPibPanId_c;
01377   lMsg.msgData.setReq.PibAttributeValue = (uint64_t)nwShortPanID;
01378   
01379   phyStatus_t u8PhyRes = MAC_PLME_SapHandler(&lMsg,0);
01380   if(u8PhyRes == gPhyBusy_c || u8PhyRes == gPhyBusyTx_c || u8PhyRes == gPhyBusyRx_c)
01381     return gErrorBusy_c;
01382   if(u8PhyRes != gPhySuccess_c)
01383     return gErrorNoResourcesAvailable_c;
01384   u16PanID = nwShortPanID;
01385   return gErrorNoError_c;
01386 }
01387 
01388 void BackoffTimeElapsed(void const *arg)
01389 {
01390   uint8_t u8PhyRes = MAC_PD_SapHandler(gSmacDataMessage, 0);
01391   if(u8PhyRes != gPhySuccess_c)
01392   {
01393     smacState = mSmacStateIdle_c;
01394     MEM_BufferFree(gSmacDataMessage);
01395     gSmacDataMessage = NULL;
01396   }
01397 }
01398 
01399 /************************************************************************************
01400 * SMACPacketCheck
01401 * 
01402 * This function returns TRUE if Phy payload can be of SMAC packet type
01403 * 
01404 ************************************************************************************/
01405 
01406 bool_t SMACPacketCheck(pdDataToMacMessage_t* pMsgFromPhy)
01407 {
01408   //check if packet is of type Data
01409   if( (pMsgFromPhy->msgData.dataInd.pPsdu[0] & 0x07) != 0x01 )
01410     return FALSE;
01411   //check if PSDU length is at least of smac header size.
01412   if( (pMsgFromPhy->msgData.dataInd.psduLength < gSmacHeaderBytes_c) )
01413     return FALSE;
01414   
01415   return TRUE;
01416 }