📄 mac_rx_engine.c
字号:
//-------------------------------------------------------------------------------------------------------
// void mrxProcessData(MAC_TASK_INFO *pTask)
//
// DESCRIPTION:
// This task is responsible for processing data packets.
//
// TASK DATA
// A pointer to the MAC_RX_PACKET to be processed
//-------------------------------------------------------------------------------------------------------
void mrxProcessData(MAC_TASK_INFO *pTask) NEAR {
MAC_RX_PACKET *pPacket = (MAC_RX_PACKET *) pTask->taskData;
MCPS_DATA_INDICATION *pMDI = &pPacket->mdi;
BOOL success = TRUE;
MAC_STATE_TYPE macState;
// Cancel the timeout (will reset the MAC state if polling)
macState = mipCancelDataRequestTimeout();
// Make the call(s) to the higher layer
switch (macState) {
case MAC_STATE_MANUAL_DATA_REQUEST_SENT:
mlmePollConfirm((BYTE)(pMDI->msduLength ? SUCCESS : NO_DATA));
break;
case MAC_STATE_ASSOC_DATA_REQUEST_SENT:
mlmeAssociateConfirm(0xFFFF, NO_DATA);
success = FALSE;
break;
default:
break;
}
if (success) mcpsDataIndication(pMDI);
// Remove the task from the queue
mschRemoveTask(pTask->priority, 0);
// Release the packet
mrxpReleasePacket(pPacket);
} // mrxProcessData
//-------------------------------------------------------------------------------------------------------
// void mrxProcessAcknowledgment(MAC_TASK_INFO *pTask)
//
// DESCRIPTION:
// This task is responsible for processing acknowledgment packets. Note that some packet types are
// handled by mtxFinishTransmission.
//
// TASK DATA
// Frame pending? (the frame pending bit from the frame control field)
//-------------------------------------------------------------------------------------------------------
void mrxProcessAcknowledgment(MAC_TASK_INFO *pTask) NEAR {
MAC_TX_PACKET *pTxPacket = mtxInfo.pPacket;
BOOL framePending = !!pTask->taskData;
BOOL cleanUpAfterSwitch = TRUE;
// Notify the transmission task
mtxInfo.status = MTX_STATUS_ACK_RECEIVED;
// Handle acknowledgments for command frames
if (pTxPacket->type == FT_MAC_COMMAND) {
switch (pTxPacket->commandType) {
case CMD_ASSOCIATION_REQUEST:
if (macSetState(MAC_STATE_ASSOC_REQUEST_SENT)) {
mtimSetCallback(mipPollAssociateResponse, (INT32)(aResponseWaitTime / aUnitBackoffPeriod));
}
break;
case CMD_DATA_REQUEST:
switch (macInfo.state) {
case MAC_STATE_TX_AUTO_DATA_REQUEST:
// Set the response timeout if there is pending data...
if (framePending) {
macSetState(MAC_STATE_AUTO_DATA_REQUEST_SENT);
mrxIncrOnCounter();
mtimSetCallback(mipDataRequestTimeout, (INT32)(aMaxFrameResponseTime / aUnitBackoffPeriod));
} else {
macSetState(MAC_STATE_DEFAULT);
}
break;
case MAC_STATE_TX_MANUAL_DATA_REQUEST:
// Set the response timeout if there is pending data...
if (framePending) {
macSetState(MAC_STATE_MANUAL_DATA_REQUEST_SENT);
mrxIncrOnCounter();
mtimSetCallback(mipDataRequestTimeout, (INT32)(aMaxFrameResponseTime / aUnitBackoffPeriod));
} else {
// Clean up before making the call to the higher layer
cleanUpAfterSwitch = FALSE;
mschRemoveTask(pTask->priority, 0);
macSetState(MAC_STATE_DEFAULT);
mlmePollConfirm(NO_DATA);
}
break;
case MAC_STATE_TX_ASSOC_DATA_REQUEST:
// Set the response timeout if there is pending data...
if (framePending) {
macSetState(MAC_STATE_ASSOC_DATA_REQUEST_SENT);
mrxIncrOnCounter();
mtimSetCallback(mipDataRequestTimeout, (INT32)(aMaxFrameResponseTime / aUnitBackoffPeriod));
} else {
// Clean up before making the call to the higher layer
cleanUpAfterSwitch = FALSE;
mschRemoveTask(pTask->priority, 0);
macSetState(MAC_STATE_DEFAULT);
mlmeAssociateConfirm(0xFFFF, NO_DATA);
}
break;
default:
break;
}
break;
default:
break;
}
}
// Cancel the packet timeout
if (mtimCancelCallback(mtxAckTimeout)) {
FSMTC1 &= ~FSMTC1_ACCEPT_ACKPKT_BM;
mrxDecrOnCounter();
}
// Clean up (used when there are no calls to the upper layer
if (cleanUpAfterSwitch) {
mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_IN_PROGRESS_BM);
}
} // mrxProcessAcknowledgment
//-------------------------------------------------------------------------------------------------------
// void mrxProcessMacCommand(MAC_TASK_INFO *pTask)
//
// DESCRIPTION:
// This task is responsible for processing command packets.
// Note: The polling timeout will only be cancelled when receiving an association response or a
// disassociation notification.
//
// TASK DATA:
// A pointer to the MAC_RX_PACKET to be processed
//-------------------------------------------------------------------------------------------------------
void mrxProcessMacCommand(MAC_TASK_INFO *pTask) NEAR {
MAC_RX_PACKET *pPacket = (MAC_RX_PACKET *) pTask->taskData;
MCPS_DATA_INDICATION *pMDI = &pPacket->mdi;
BOOL cleanUpAfterSwitch = TRUE;
MAC_STATE_TYPE macState;
BOOL processCoordinatorRealignment;
// Which command type?
switch ((MAC_COMMAND_TYPE) pMDI->pMsdu[0]) {
#if MAC_OPT_FFD
case CMD_DATA_REQUEST:
// First make sure that we acknowledged the data request with the pending-bit set
if (pPacket->flags & MRXP_FLAG_SACKPEND_ISSUED_BM) {
// Try to locate the requested packet and transmit it
if (!miqFindAndRequestIndirectPacket((ADDRESS *)&pMDI->srcAddr, (BYTE)(pMDI->srcAddrMode == AM_EXTENDED_64))) {
// If nothing was found, then try to transmit a data packet without any payload
miqTransmitNoDataPacket((ADDRESS *)&pMDI->srcAddr, (BYTE)(pMDI->srcAddrMode == AM_EXTENDED_64));
}
}
break;
#endif
#if MAC_OPT_FFD
case CMD_ASSOCIATION_REQUEST:
// Clean up before making the call to the higher layer
cleanUpAfterSwitch = FALSE;
mschRemoveTask(pTask->priority, 0);
// Generate mlmeAssociateIndication only when association is allowed
if (mpib.macAssociationPermit) {
mlmeAssociateIndication(pMDI->srcAddr, pMDI->pMsdu[1], pMDI->securityUse, pMDI->aclEntry);
}
mrxpReleasePacket(pPacket);
break;
#endif
case CMD_ASSOCIATION_RESPONSE:
macState = mipCancelDataRequestTimeout();
if (macState == MAC_STATE_ASSOC_DATA_REQUEST_SENT) {
// Update PIB attributes if successful
if (pMDI->pMsdu[3] == SUCCESS) {
mlmeSetRequest(MAC_COORD_EXTENDED_ADDRESS, &pMDI->srcAddr);
mlmeSetRequest(MAC_SHORT_ADDRESS, (WORD *) &pMDI->pMsdu[1]);
mlmeSetRequest(MAC_PAN_ID, &pMDI->srcPanId);
}
// Clean up before making the call to the higher layer
cleanUpAfterSwitch = FALSE;
mschRemoveTask(pTask->priority, 0);
// Generate confirmation
mlmeAssociateConfirm(mpib.macShortAddress, pMDI->pMsdu[3]);
mrxpReleasePacket(pPacket);
}
break;
#if MAC_OPT_FFD
case CMD_BEACON_REQUEST:
if ((mpib.macBeaconOrder == 15) && GET_MF(MF_COORDINATOR)) {
mscTransmitBeacon();
}
break;
#endif
case CMD_DISASSOCIATION_NOTIFICATION:
if ((pMDI->srcAddrMode == AM_EXTENDED_64) && (pMDI->dstAddrMode == AM_EXTENDED_64)) {
// Clean up before making the call to the higher layer
cleanUpAfterSwitch = FALSE;
mschRemoveTask(pTask->priority, 0);
// Poll confirm(?) + disassociate indication
macState = mipCancelDataRequestTimeout();
if (macState == MAC_STATE_MANUAL_DATA_REQUEST_SENT) {
mlmePollConfirm(SUCCESS);
} else if (macState == MAC_STATE_ASSOC_DATA_REQUEST_SENT) {
mlmeAssociateConfirm(0xFFFF, NO_DATA);
}
mlmeDisassociateIndication(pMDI->srcAddr, pMDI->pMsdu[1], pMDI->securityUse, pMDI->aclEntry);
mrxpReleasePacket(pPacket);
}
break;
case CMD_COORDINATOR_REALIGNMENT:
// Process coordinator realignment frame if doing orphan scan
// or if received from the coordinator to which we are associated
processCoordinatorRealignment = FALSE;
if (pMDI->srcAddrMode == AM_EXTENDED_64) {
if (macInfo.state == MAC_STATE_ORPHAN_SCAN) {
if (pMDI->dstAddrMode == AM_EXTENDED_64) {
processCoordinatorRealignment = TRUE;
}
} else {
// Exended address match?
if (msupCompareExtendedAddress(&pMDI->srcAddr, (ADDRESS *) mpib.pMacCoordExtendedAddress)) {
processCoordinatorRealignment = TRUE;
}
}
}
if (processCoordinatorRealignment) {
// Update MAC PIB with coordinator extended address, coordinator short address,
// device PAN ID, device short address and ppib.phyCurrentChannel (the CC2430 registers are
mlmeSetRequest(MAC_COORD_EXTENDED_ADDRESS, &pMDI->srcAddr.pExtended);
mlmeSetRequest(MAC_PAN_ID, (WORD *) &pMDI->pMsdu[1]);
mlmeSetRequest(MAC_COORD_SHORT_ADDRESS, (WORD *) &pMDI->pMsdu[3]);
// Update the received channel
msupSetChannel(pMDI->pMsdu[5], TRUE);
// For orphan responses, with extended destination address, update the short address from the realignment frame
if (pMDI->dstAddrMode == AM_EXTENDED_64) {
mlmeSetRequest(MAC_SHORT_ADDRESS, (WORD *) &pMDI->pMsdu[6]);
macSetState(MAC_STATE_ORPHAN_REALIGNED);
}
// Clean up before making the call to the higher layer
cleanUpAfterSwitch = FALSE;
mschRemoveTask(pTask->priority, 0);
mrxpReleasePacket(pPacket);
// Indicate realignment to higher layer
mlmeSyncLossIndication(REALIGNMENT);
}
break;
#if MAC_OPT_FFD
case CMD_ORPHAN_NOTIFICATION:
// Must have source addressing mode 3 and destination addressing mode 2
if ((pMDI->srcAddrMode == AM_EXTENDED_64) && (pMDI->dstAddrMode == AM_SHORT_16)) {
// Must have broadcast source and destination PAN
if ((pMDI->srcPanId == 0xFFFF) && (pMDI->dstPanId == 0xFFFF)) {
// Clean up before making the call to the higher layer
cleanUpAfterSwitch = FALSE;
mschRemoveTask(pTask->priority, 0);
mlmeOrphanIndication(pMDI->srcAddr, pMDI->securityUse, pMDI->aclEntry);
mrxpReleasePacket(pPacket);
}
}
break;
#endif
#if MAC_OPT_FFD
case CMD_PAN_ID_CONFLICT_NOTIFICATION:
// The PAN Coordinator has received a PAN ID conflict notification command from a device on its own PAN
if ((GET_MF(MF_PAN_COORDINATOR)) && (pMDI->srcPanId == mpib.macPANId)) {
// Clean up before making the call to the higher layer
cleanUpAfterSwitch = FALSE;
mschRemoveTask(pTask->priority, 0);
mrxpReleasePacket(pPacket);
mlmeSyncLossIndication(PAN_ID_CONFLICT);
}
break;
#endif
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -