/************************************************************************************************** * @fn macRadioUpdateChannel * * @brief Update the radio channel if a new channel has been requested. * * @param none * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macRadioUpdateChannel(void) { halIntState_t s; MAC_ASSERT(!macTxActive); /* cannot change channel during a transmit */ /* if the channel has changed, set the radio to the new channel */ HAL_ENTER_CRITICAL_SECTION(s); if (reqChannel != macPhyChannel) { macPhyChannel = reqChannel; HAL_EXIT_CRITICAL_SECTION(s); /* changing the channel stops any receive in progress */ macRxOff(); MAC_RADIO_SET_CHANNEL(macPhyChannel); /* If the channel is updated in the middle of receiving a frame, we must * clean up the Rx logic. */ macRxHaltCleanup(); macRxOnRequest(); } else { HAL_EXIT_CRITICAL_SECTION(s); } }
/************************************************************************************************** * @fn macRxHardDisable * * @brief Clear all enable flags and turn off receiver. * * @param none * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macRxHardDisable(void) { halIntState_t s; DBG_PRINT0(DBGSYS, "macRxHardDisable()"); HAL_ENTER_CRITICAL_SECTION(s); macRxEnableFlags = 0; MAC_DEBUG_TURN_OFF_RX_LED(); HAL_EXIT_CRITICAL_SECTION(s); /* force off and clean up */ macRxHaltCleanup(); /* Power management state may change. Hence, vote. */ macPwrVote(); }
/************************************************************************************************** * @fn macRxHardDisable * * @brief Clear all enable flags and turn off receiver. * * @param none * * @return none ************************************************************************************************** */ void macRxHardDisable(void) { halIntState_t s; HAL_ENTER_CRITICAL_SECTION(s); macRxEnableFlags = 0; macRxOnFlag = 0; /* force receiver off */ MAC_RADIO_RXTX_OFF(); MAC_RADIO_FLUSH_RX_FIFO(); MAC_DEBUG_TURN_OFF_RX_LED(); HAL_EXIT_CRITICAL_SECTION(s); /* clean up after being forced off */ macRxHaltCleanup(); }
/************************************************************************************************** * @fn macTxCollisionWithRxCallback * * @brief Function called if transmit strobed on top of a receive. * * @param none * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macTxCollisionWithRxCallback(void) { macRxHaltCleanup(); }
/*================================================================================================= * @fn rxAddrIsr * * @brief Receive ISR state for decoding address. Reads and stores the address information * from the incoming packet. * * @param none * * @return none *================================================================================================= */ static void rxAddrIsr(void) { uint8 buf[MAX_ADDR_FIELDS_LEN]; uint8 dstAddrMode; uint8 srcAddrMode; #ifdef FEATURE_MAC_SECURITY uint8 securityControl; #endif /* MAC_SECURITY */ uint8 * p; MAC_ASSERT(rxNextLen != 0); /* logic assumes at least one address byte in buffer */ /* read out address fields into local buffer in one shot */ MAC_RADIO_READ_RX_FIFO(buf, rxNextLen); /* set pointer to buffer with addressing fields */ p = buf; /* destination address */ dstAddrMode = MAC_DEST_ADDR_MODE(&rxBuf[1]); if (dstAddrMode != SADDR_MODE_NONE) { pRxBuf->mac.srcPanId = pRxBuf->mac.dstPanId = BUILD_UINT16(p[0], p[1]); p += MAC_PAN_ID_FIELD_LEN; if (dstAddrMode == SADDR_MODE_EXT) { sAddrExtCpy(pRxBuf->mac.dstAddr.addr.extAddr, p); p += MAC_EXT_ADDR_FIELD_LEN; } else { pRxBuf->mac.dstAddr.addr.shortAddr = BUILD_UINT16(p[0], p[1]); p += MAC_SHORT_ADDR_FIELD_LEN; } } /* sources address */ srcAddrMode = MAC_SRC_ADDR_MODE(&rxBuf[1]); if (srcAddrMode != SADDR_MODE_NONE) { if (!(pRxBuf->internal.flags & MAC_RX_FLAG_INTRA_PAN)) { pRxBuf->mac.srcPanId = BUILD_UINT16(p[0], p[1]); p += MAC_PAN_ID_FIELD_LEN; } if (srcAddrMode == SADDR_MODE_EXT) { sAddrExtCpy(pRxBuf->mac.srcAddr.addr.extAddr, p); } else { pRxBuf->mac.srcAddr.addr.shortAddr = BUILD_UINT16(p[0], p[1]); } } #ifdef FEATURE_MAC_SECURITY if (MAC_SEC_ENABLED(&rxBuf[1])) { uint8 keyIdMode; if (MAC_FRAME_VERSION(&rxBuf[1]) == 0) { /* MAC_UNSUPPORTED_LEGACY - Cancel the outgoing TX ACK. * It may be too late but we have to try. */ MAC_RADIO_CANCEL_TX_ACK(); /* clean up after unsupported security legacy */ macRxHaltCleanup(); return; } /* Copy addressing fields to RX buffer */ osal_memcpy(pRxBuf->mhr.p, buf, rxNextLen); pRxBuf->mhr.p += rxNextLen; pRxBuf->mhr.len += rxNextLen; /*------------------------------------------------------------------------------- * Prepare for auxiliary security header interrupts. */ /* read out security control field from FIFO (threshold set so bytes are guaranteed to be there) */ MAC_RADIO_READ_RX_FIFO(&securityControl, MAC_SEC_CONTROL_FIELD_LEN); /* Copy security fields to MHR buffer */ *pRxBuf->mhr.p = securityControl; pRxBuf->mhr.p += MAC_SEC_CONTROL_FIELD_LEN; pRxBuf->mhr.len += MAC_SEC_CONTROL_FIELD_LEN; /* store security level and key ID mode */ pRxBuf->sec.securityLevel = SECURITY_LEVEL(securityControl); pRxBuf->sec.keyIdMode = keyIdMode = KEY_IDENTIFIER_MODE(securityControl); /* Corrupted RX frame, should never occur. */ if ((keyIdMode > MAC_KEY_ID_MODE_8) /* Get the next RX length according to AuxLen table minus security control field. * The security control length is counted already. */ || ((macKeySourceLen[keyIdMode] + MAC_FRAME_COUNTER_LEN) >= rxPayloadLen) /* Security Enabled subfield is one, but the Security Level in the header is zero: * MAC_UNSUPPORTED_SECURITY - Cancel the outgoing TX ACK. */ || (pRxBuf->sec.securityLevel == MAC_SEC_LEVEL_NONE)) { /* It may be too late but we have to try. */ MAC_RADIO_CANCEL_TX_ACK(); /* clean up after unsupported security or corrupted RX frame. */ macRxHaltCleanup(); return; } /* get the next RX length according to AuxLen table minus security control field. * The sceurity control length is counted already. */ rxNextLen = macKeySourceLen[keyIdMode] + MAC_FRAME_COUNTER_LEN; MAC_RADIO_SET_RX_THRESHOLD(rxNextLen); pFuncRxState = &rxSecurityHdrIsr; } else #endif /* MAC_SECURITY */ { /* clear security level */ pRxBuf->sec.securityLevel = MAC_SEC_LEVEL_NONE; /*------------------------------------------------------------------------------- * Prepare for payload interrupts. */ pFuncRxState = &rxPayloadIsr; rxPrepPayload(); } }
/************************************************************************************************** * @fn macRxFifoOverflowIsr * * @brief This interrupt service routine is called when RX FIFO overflow. Note that this * exception does not retrieve the good frames that are trapped in the RX FIFO. * It simply halts and cleanup the RX. * * @param none * * @return none ************************************************************************************************** */ MAC_INTERNAL_API void macRxFifoOverflowIsr(void) { rxFifoOverflowCount++; /* This flag is used for debug purpose only */ macRxHaltCleanup(); }
/************************************************************************************************** * @fn macTxCollisionWithRxCallback * * @brief Function called if transmit strobed on top of a receive. * * @param none * * @return none ************************************************************************************************** */ void macTxCollisionWithRxCallback(void) { macRxHaltCleanup(); }