?? mac_rx_engine.c
字號:
default:
break;
}
// Clean up (used when there are no calls to the upper layer
if (cleanUpAfterSwitch) {
mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_IN_PROGRESS_BM);
mrxpReleasePacket(pPacket);
}
} // mrxProcessMacCommand
//-------------------------------------------------------------------------------------------------------
// void mrxCommStatusIndication(MAC_TASK_INFO *pTask)
//
// DESCRIPTION:
// This task is responsible for generating mlme-comm-status.indication upon security failures.
//
// TASK DATA:
// A pointer to the MAC_RX_PACKET to be processed
//-------------------------------------------------------------------------------------------------------
void mrxCommStatusIndication(MAC_TASK_INFO *pTask) NEAR {
MAC_RX_PACKET *pPacket = (MAC_RX_PACKET *) pTask->taskData;
MCPS_DATA_INDICATION *pMDI = &pPacket->mdi;
mlmeCommStatusIndication(pMDI->srcPanId, pMDI->srcAddrMode, &pMDI->srcAddr, pMDI->dstAddrMode, &pMDI->dstAddr, pPacket->securityStatus);
mschRemoveTask(pTask->priority, 0);
mrxpReleasePacket(pPacket);
} //mrxCommStatusIndication
#pragma vector = DMA_VECTOR
__near_func __interrupt void DmaIsr(void) {
CLEAR_DMA_INT();
if (DMAIRQ & DMA_RFRX_CHANNEL_BM) {
CLEAR_FIFOP_INT_BIT();
ENABLE_FIFOP_INT_BIT();
DMAIRQ = ~DMA_RFRX_CHANNEL_BM;
}
}
#pragma vector=RF_VECTOR
__near_func __interrupt void RfIsr (void) {
BYTE clearedFlagN,
rfim;
clearedFlagN = 0xFF;
rfim = RFIM;
if ((RFIF & RFIF_FIFOP_BM) & rfim) {
mrxHandleFifopInt();
clearedFlagN = ~RFIF_FIFOP_BM;
} else if ((RFIF & RFIF_CSP_STOP_BM) & rfim) {
mtxCspStopped(RFIF & RFIF_CSP_MANINT_BM);
clearedFlagN = ~(RFIF_CSP_STOP_BM | RFIF_CSP_MANINT_BM | RFIF_CSP_WAIT_BM);
} else if ((RFIF & RFIF_TXDONE_BM) & rfim) {
mtxTxDone();
clearedFlagN = ~RFIF_TXDONE_BM;
}
SET_RFIF(clearedFlagN);
CLEAR_RFIF_INT();
}
static ROOT void mrxHandleFifopInt(void) {
BYTE reservedTask;
BYTE dstAddrMode;
BYTE srcAddrMode;
BOOL createProcessTask;
TFPTR pProcessTask;
WORD processTaskData;
// Copy the pointer for fast access
MAC_RX_PACKET *pPacket = mrxInfo.pPacket;
MCPS_DATA_INDICATION *pMDI = &pPacket->mdi;
switch (mrxInfo.state) {
case MRX_STATE_LEN_FCF_SEQ:
// Keep RX on while receiving
mrxAutoIncrOnCounter();
// Reserve processing task and make sure that we're not doing energy detection
reservedTask = mschReserveTask();
if ((macInfo.state != MAC_STATE_ENERGY_SCAN) && (reservedTask != NO_TASK)) {
mrxInfo.taskNumber = reservedTask;
// Reserve packet
pPacket = mrxpReservePacket();
if (pPacket) {
mrxInfo.pPacket = pPacket;
pMDI = &pPacket->mdi;
// Read the packet length, the frame control field and the sequence number
halReadRxFifo((BYTE *) &mrxInfo.length, 4);
mrxInfo.length &= 0x7F;
mrxInfo.length -= 5; // 3 for FCF and SN + 2 for FCS
// Get the time stamp (do it now to make sure that it is not overwritten by the acknowledgment)
pPacket->timestamp.counter = T2_GET_CAPTURED_COUNTER();
pPacket->timestamp.overflowCounter = T2_GET_CAPTURED_OVERFLOW_COUNTER();
// Security is currently not supported
pMDI->securityUse = FALSE;
// This packet will be acknowledged if the ack request bit is set
if ((BYTE) mrxInfo.frameControlField & ACK_REQ_BM) {
ENABLE_AUTOACK();
#if MAC_OPT_FFD
// Acknowledge with the pending flag set if there is at least one packet in the pending queue
if (miqInfo.firstIndirectPacket != NO_PACKET) {
pPacket->flags |= MRXP_FLAG_SACKPEND_ISSUED_BM;
AUTOACK_WITH_PENDING_BIT();
} else {
AUTOACK_WITHOUT_PENDING_BIT();
}
#endif
}
// Set the destination address mode and length (of the fields)
dstAddrMode = BF(mrxInfo.frameControlField, DEST_ADDR_MODE_BM, DEST_ADDR_MODE_IDX);
pMDI->dstAddrMode = dstAddrMode;
if (dstAddrMode) {
mrxInfo.destAddrLength = (dstAddrMode == AM_SHORT_16) ? 4 : 10;
} else {
mrxInfo.destAddrLength = 0;
}
// Set the source address mode and length (of the fields)
srcAddrMode = BF(mrxInfo.frameControlField, SRC_ADDR_MODE_BM, SRC_ADDR_MODE_IDX);
pMDI->srcAddrMode = srcAddrMode;
if (srcAddrMode) {
mrxInfo.srcAddrLength = (srcAddrMode == AM_SHORT_16) ? 4 : 10;
if (mrxInfo.frameControlField & INTRA_PAN_BM) mrxInfo.srcAddrLength -= 2;
} else {
mrxInfo.srcAddrLength = 0;
}
// Calculate the MSDU length
pMDI->msduLength = mrxInfo.length - (mrxInfo.destAddrLength + mrxInfo.srcAddrLength);
// Set the next state
if ((pMDI->msduLength < 0) || (pMDI->msduLength > aMaxMACFrameSize)) {
mrxpReleasePacket(pPacket);
mschReleaseTask(mrxInfo.taskNumber);
DISABLE_AUTOACK();
SET_FIFOP_THRESHOLD(mrxInfo.length + 2);
mrxInfo.state = MRX_STATE_DISCARD;
} else if (mrxInfo.destAddrLength + mrxInfo.srcAddrLength) {
SET_FIFOP_THRESHOLD(mrxInfo.destAddrLength + mrxInfo.srcAddrLength);
mrxInfo.state = MRX_STATE_ADDR;
} else {
// Configure payload DMA transfer
if (mrxInfo.length) {
mrxStartPayloadDmaTransfer();
}
SET_FIFOP_THRESHOLD(2);
mrxInfo.state = MRX_STATE_FCS;
}
break;
}
}
// This packet will be discarded because
// - There was no available task to handle the packet processing
// - There was no packet structure to store the incoming data
// - We're performing an energy detection scan, where all incoming packets are discarded
mschReleaseTask(reservedTask);
mrxInfo.length = (RFD & 0x7F) - 2;
DISABLE_AUTOACK();
SET_FIFOP_THRESHOLD(mrxInfo.length + 2);
mrxInfo.state = MRX_STATE_DISCARD;
break;
case MRX_STATE_ADDR:
// Read the source and destination addresses
halReadRxFifo((BYTE *) &pMDI->dstPanId, mrxInfo.destAddrLength);
pMDI->srcPanId = pMDI->dstPanId;
halReadRxFifo((mrxInfo.frameControlField & INTRA_PAN_BM) ? (BYTE *) &pMDI->srcAddr : (BYTE *) &pMDI->srcPanId, mrxInfo.srcAddrLength);
mrxInfo.length = pMDI->msduLength;
// Configure payload DMA transfer
if (mrxInfo.length) {
mrxStartPayloadDmaTransfer();
}
SET_FIFOP_THRESHOLD(2);
mrxInfo.state = MRX_STATE_FCS;
break;
case MRX_STATE_FCS:
// Get the footer (RSSI, CRCOK and LQI)
halReadRxFifo(mrxInfo.pFooter, 2);
pMDI->mpduLinkQuality = ED_2_LQI(RSSI_2_ED((INT8) mrxInfo.pFooter[0]));
// If the CRC is OK, then spawn a task to do the further processing
pProcessTask = NULL;
processTaskData = (WORD) pPacket;
if (mrxInfo.pFooter[1] & 0x80) {
switch ((BYTE) mrxInfo.frameControlField & FRAME_TYPE_BM) {
case FT_BEACON:
// Get the sequence number (overwrites pPacket->framePending)
pPacket->sequenceNumber = mrxInfo.sequenceNumber;
pProcessTask = mrxProcessBeacon;
break;
case FT_DATA:
pProcessTask = mrxProcessData;
break;
case FT_ACKNOWLEDGMENT:
if (((mtxInfo.status == MTX_STATUS_TRANSMISSION_STARTED) || (mtxInfo.status == MTX_STATUS_ACK_TIMEOUT) ||
(mtxInfo.status == MTX_STATUS_WAITING_FOR_ACK)) && (mrxInfo.sequenceNumber == mtxInfo.pPacket->pHeader[2])) {
// Note: If a timeout has occurred, but not been handled by the low-priority task, it will be undone here :)
// We'll use an intermediate state until the mrxProcessAcknowledgment task has started, because we could already
// be inside the transmission task (interrupted by the FIFOP ISR). It must be done this way, because otherwise the
// TX engine would release the packet, and we wouldn't be able to tie this acknowledgment to a packet.
mtxInfo.status = MTX_STATUS_ACK_HANDLER_CREATED;
pProcessTask = mrxProcessAcknowledgment;
processTaskData = mrxInfo.frameControlField & FRAME_PENDING_BM;
}
break;
case FT_MAC_COMMAND:
// TBD: Handle security errors for MAC command frames
pProcessTask = mrxProcessMacCommand;
break;
}
}
// If a handler function has been set, the task is created. If not, then free the acquired resources.
if (pProcessTask) {
// Apply filtering while scanning
if (macInfo.state & MAC_STATE_SCAN_BM) {
switch (macInfo.state) {
case MAC_STATE_ACTIVE_OR_PASSIVE_SCAN:
createProcessTask = (pProcessTask == mrxProcessBeacon);
break;
case MAC_STATE_ORPHAN_SCAN:
createProcessTask = ((pProcessTask == mrxProcessMacCommand) && (((MAC_COMMAND_TYPE) pMDI->pMsdu[0]) == CMD_COORDINATOR_REALIGNMENT));
break;
default:
createProcessTask = FALSE;
break;
}
} else {
createProcessTask = TRUE;
}
// Create the processing task?
if (createProcessTask) {
if ((pProcessTask == mrxProcessBeacon) && mpib.macRxOnWhenIdle) {
pPacket->flags |= MRXP_FLAG_RX_NOT_TURNED_OFF_BM;
} else {
if (pProcessTask == mrxProcessAcknowledgment) mrxpReleasePacket(pPacket);
mrxDecrOnCounter();
}
mschAddTask(mrxInfo.taskNumber, MAC_TASK_PRI_HIGH, (TFPTR) pProcessTask, processTaskData);
// If not (for instance during scanning), clean up
} else {
mrxDecrOnCounter();
mrxpReleasePacket(pPacket);
mschReleaseTask(mrxInfo.taskNumber);
}
// No handler function found, so just clean up
} else {
mrxDecrOnCounter();
mrxpReleasePacket(pPacket);
mschReleaseTask(mrxInfo.taskNumber);
}
RESET_FIFOP_THRESHOLD();
mrxInfo.state = MRX_STATE_LEN_FCF_SEQ;
break;
case MRX_STATE_DISCARD:
halDiscardRxFifo(mrxInfo.length + 2);
mrxDecrOnCounter();
RESET_FIFOP_THRESHOLD();
mrxInfo.state = MRX_STATE_LEN_FCF_SEQ;
break;
}
}
#pragma vector=RFERR_VECTOR
__near_func __interrupt void RferrIsr(void) {
switch (FSMSTATE) {
case RF_RX_OVERFLOW:
mrxResetRxEngine();
break;
case RF_TX_UNDERFLOW:
// This should never happen
break;
}
RFERRIF = 0;
}
?? 快捷鍵說明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -