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
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*)¤tChannel; 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 }
Generated on Mon Jul 18 2022 17:26:40 by 1.7.2