📄 mac_rx_engine.c
字号:
} else if (mrxInfo.rd.a.dstAddrLength) {///
nextState = MRX_STATE_DEST_ADDR;
} else if (mrxInfo.rd.a.srcAddrLength) {///
nextState = MRX_STATE_SRC_ADDR;
} else if (mrxInfo.length) {
nextState = MRX_STATE_SECURITY_INIT;
if (mrxInfo.length == 1) mrxSetFifopThreshold(0);
} else {
nextState = MRX_STATE_FCS;
mrxSetFifopThreshold(1);
}
mrxInfo.state = nextState;
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
mrxInfo.state = MRX_STATE_DISCARD_ALL;
mschReleaseTask(reservedTask);
break;
case MRX_STATE_DEST_ADDR:
readLength = MIN(4, mrxInfo.rd.a.dstAddrLength);///
msupReadFifo((BYTE*)mrxInfo.rd.a.pDstAddrStoragePtr, readLength);///
mrxInfo.rd.a.dstAddrLength -= readLength;///
mrxInfo.length -= readLength;
if (mrxInfo.rd.a.dstAddrLength) {///
mrxInfo.rd.a.pDstAddrStoragePtr += readLength;///
break;
} else if (pMDI->srcAddrMode) {
pMDI->srcPanId = pMDI->dstPanId;
nextState = MRX_STATE_SRC_ADDR;
} else if (mrxInfo.length) {
nextState = MRX_STATE_SECURITY_INIT;
if (mrxInfo.length == 1) mrxSetFifopThreshold(0);
} else {
nextState = MRX_STATE_FCS;
mrxSetFifopThreshold(1);
}
mrxInfo.state = nextState;
break;
case MRX_STATE_SRC_ADDR:
readLength = MIN(4, mrxInfo.rd.a.srcAddrLength);///
msupReadFifo((BYTE*)mrxInfo.rd.a.pSrcAddrStoragePtr, readLength);///
mrxInfo.rd.a.srcAddrLength -= readLength;///
mrxInfo.length -= readLength;
if (mrxInfo.rd.a.srcAddrLength) {///
mrxInfo.rd.a.pSrcAddrStoragePtr += readLength;///
break;
} else if (mrxInfo.length) {
nextState = MRX_STATE_SECURITY_INIT;
if (mrxInfo.length == 1) mrxSetFifopThreshold(0);
} else {
nextState = MRX_STATE_FCS;
mrxSetFifopThreshold(1);
}
mrxInfo.state = nextState;
break;
case MRX_STATE_SECURITY_INIT:
// Store the current length of the received packet
// Adjust for optional security overhead at a later stage
pMDI->msduLength = mrxInfo.length;
// Initialize the payload storage pointer (note: this will overwrite some old variables)
mrxInfo.rd.f.pPayloadStoragePtr = pMDI->pMsdu;///
#if (MAC_OPT_SECURITY)
// By default, no security material has been found
mrxSecurityInfo.pMrxSecurityMaterial = NULL;
#endif
#if ((MAC_OPT_SECURITY) || (MAC_OPT_ACL_SIZE>0))
// MAC security and / or ACL available.
switch (mpib.macSecurityMode) {
case MAC_UNSECURED_MODE:
if (pMDI->securityUse) {
// Secure packets cannot be handled in unsecured mode
pPacket->securityStatus = FAILED_SECURITY_CHECK;
}
mrxInfo.state = MRX_STATE_PAYLOAD;
break;
default:
// MAC_ACL_MODE or MAC_SECURED_MODE
// Set the search index in the ACL
mrxInfo.aclEntrySearch = 0;
mrxInfo.state = MRX_STATE_SECURITY_ACL_SEARCH;
break;
}
break;
case MRX_STATE_SECURITY_ACL_SEARCH:
// Search through one entry in the ACL for each interrupt event to allow
// other ISRs to run during security search
n = mrxInfo.aclEntrySearch;
aclEntryFound = FALSE;
if (n < mpib.macACLEntryDescriptorSetSize) {
// Not all ACL entries searched so far, try one more
// Exended address match?
if (pMDI->srcAddrMode == AM_EXTENDED_64) {
if (msupCompareQword(&pMDI->srcAddr.Extended, &mpib.ppMacACLEntryDescriptorSet[n]->extendedAddress)) {
aclEntryFound = TRUE;
}
// Short address match?
} else if ((pMDI->srcAddrMode == AM_SHORT_16) && (pMDI->srcPanId == mpib.ppMacACLEntryDescriptorSet[n]->panId)) {
if (pMDI->srcAddr.Short == mpib.ppMacACLEntryDescriptorSet[n]->shortAddress) {
aclEntryFound = TRUE;
}
}
// Match for this ACL entry?
if (aclEntryFound) {
pMDI->aclEntry = mpib.ppMacACLEntryDescriptorSet[n]->securitySuite;
#if MAC_OPT_SECURITY
mrxSecurityInfo.securitySuite = mpib.ppMacACLEntryDescriptorSet[n]->securitySuite;
mrxSecurityInfo.pMrxSecurityMaterial = &mpib.ppMacACLEntryDescriptorSet[n]->securityMaterial;
mrxSecurityInfo.pExtendedAddress = &mpib.ppMacACLEntryDescriptorSet[n]->extendedAddress;
mrxInfo.state = MRX_STATE_FIND_COUNTERS;
#else // Only ACL implemented
mrxInfo.state = MRX_STATE_PAYLOAD;
#endif
// No match for this ACL
} else {
// Search next entry
n++;
mrxInfo.aclEntrySearch = n;
}
} else {
// All ACL entries searched, without success.
#if MAC_OPT_SECURITY
// Check default security
if (mpib.macDefaultSecurity) {
// Default security used
mrxSecurityInfo.pMrxSecurityMaterial = mpib.pMacDefaultSecurityMaterial;
mrxSecurityInfo.securitySuite = mpib.macDefaultSecuritySuite;
// Default security can only be used for receiving extended source addresses
mrxSecurityInfo.pExtendedAddress = &pMDI->srcAddr.Extended;
mrxInfo.state = MRX_STATE_FIND_COUNTERS;
} else {
// No key found
pPacket->securityStatus = UNAVAILABLE_KEY;
mrxSecurityInfo.securitySuite = MAC_SECURITY_NONE;
mrxInfo.state = MRX_STATE_PAYLOAD;
}
#else // Only ACL implemented
mrxInfo.state = MRX_STATE_PAYLOAD;
#endif
}
break;
#if MAC_OPT_SECURITY
case MRX_STATE_FIND_COUNTERS:
if ((mpib.macSecurityMode != MAC_SECURED_MODE) || (!pMDI->securityUse)) {
// Not in secured mode or unsecure packet received
mrxInfo.state = MRX_STATE_PAYLOAD;
} else {
// Security suite has been found. Decode setup info
msecDecodeSecuritySuite(&mrxSecurityInfo.securitySetup, mrxSecurityInfo.securitySuite);
if (mrxSecurityInfo.securitySetup.secFlags2420) {
// The security suite (CCM /CTR) includes frame and key sequence counters
if ((pMDI->srcAddrMode != AM_EXTENDED_64) && (pMDI->aclEntry == 0x08)) {
// Source mode must be extended when default security is used
// and security suite is CCM / CTR
pPacket->securityStatus = FAILED_SECURITY_CHECK;
mrxInfo.state = MRX_STATE_PAYLOAD;
} else {
// Set the number of cleartext bytes to be authenticated but not decrypted (in CCM)
// or cleartext bytes before encryption (in CTR)
mrxSecurityInfo.securitySetup.clearTextLength -= (mrxInfo.length + 2 - 5);
// Handle each frame type separately
switch ((BYTE) mrxInfo.frameControlField & FRAME_TYPE_BM) {
case FT_BEACON:
// TBD: Not yet handled
break;
case FT_DATA:
// No additional data is authenticated
mrxInfo.state = MRX_STATE_READ_FRAME_COUNTER;
break;
case FT_MAC_COMMAND:
// One additional byte of cleartext
mrxSecurityInfo.securitySetup.clearTextLength++;
mrxInfo.state = MRX_STATE_CMD_IDENTIFIER;
break;
case FT_ACKNOWLEDGMENT:
// Security is not allowed for acknowledge frames, ignore the rest of the packet
mrxInfo.state = MRX_STATE_DISCARD_REMAINING;
break;
} // switch
} // if
} else {
// No frame counter / key sequence counter is included in this frame
mrxSecurityInfo.securitySetup.clearTextLength = 0;
mrxInfo.state = MRX_STATE_KEY_SETUP_AND_DECRYPT;
}
}
break;
case MRX_STATE_CMD_IDENTIFIER:
// Read the one byte command frame identifier
readLength = 1;
msupReadFifo((BYTE*)mrxInfo.pPayloadStoragePtr, readLength);
mrxInfo.length--;
mrxInfo.pPayloadStoragePtr++;
mrxInfo.state = MRX_STATE_READ_FRAME_COUNTER;
break;
case MRX_STATE_READ_FRAME_COUNTER:
if (mrxInfo.length >= 5) {
// Read 4-byte frame counter
readLength = 4;
msupReadFifo((BYTE*) &mrxSecurityInfo.frameCounter, readLength);
// Don't include the 5 counter bytes in the payload length!
pMDI->msduLength -= 5;
// Update counters
mrxInfo.length -= 5;
// Next state
mrxInfo.state = MRX_STATE_READ_KEY_SEQUENCE_COUNTER;
} else {
// There are not enough bytes in the RXFIFO to read the frame counter + key sequence counter
pPacket->securityStatus = FAILED_SECURITY_CHECK;
mrxInfo.state = MRX_STATE_PAYLOAD;
}
break;
case MRX_STATE_READ_KEY_SEQUENCE_COUNTER:
// Read 1-byte key sequence counter
readLength = 1;
msupReadFifo((BYTE*) &mrxSecurityInfo.keySequenceCounter, readLength);
// Note: mrxInfo.length updated in the previous step, including key sequence counter
// Start decryption / authentication process
mrxInfo.state = MRX_STATE_KEY_SETUP_AND_DECRYPT;
// no break here!
case MRX_STATE_KEY_SETUP_AND_DECRYPT:
// Setup key / nonce for the packet
msecSetupCC2420KeyAndNonce(FALSE, &mrxSecurityInfo.securitySetup, mrxSecurityInfo.pMrxSecurityMaterial->pSymmetricKey, (BYTE*) &mrxSecurityInfo.frameCounter);
// Setup security related registers in CC2420
msecSetupCC2420Regs(&mrxSecurityInfo.securitySetup);
// Decrypt / authenticate data in rxfifo
FASTSPI_STROBE(CC2420_SRXDEC);
mrxInfo.state = MRX_STATE_PAYLOAD;
// Set the FIFOP threshold for short packets
if (mrxInfo.length == 1) {
mrxSetFifopThreshold(0);
} else if (mrxInfo.length == 0) {
mrxInfo.state = MRX_STATE_FCS;
mrxSetFifopThreshold(1);
}
break;
#endif // MAC_OPT_SECURITY
#else
// No MAC security available (MAC_OPT_SECURITY=0), go directly to the next state
mrxInfo.state = MRX_STATE_PAYLOAD;
// No break here!
#endif
case MRX_STATE_PAYLOAD:
readLength = MIN(4, mrxInfo.length);
msupReadFifo((BYTE*)mrxInfo.rd.f.pPayloadStoragePtr, readLength);///
mrxInfo.length -= readLength;
mrxInfo.rd.f.pPayloadStoragePtr += readLength;///
if (mrxInfo.length == 1) {
mrxSetFifopThreshold(0);
} else if (mrxInfo.length == 0) {
mrxInfo.state = MRX_STATE_FCS;
mrxSetFifopThreshold(1);
}
break;
case MRX_STATE_FCS:
msupReadFifo((BYTE*)mrxInfo.rd.f.pFooter, 2);
mrxSetFifopThreshold(3);
pMDI->mpduLinkQuality = ED_2_LQI(RSSI_2_ED((INT8) mrxInfo.rd.f.pFooter[0]));///
// If the CRC is OK, then spawn a task to do the further processing
pProcessTask = NULL;
processTaskData = (WORD) pPacket;
if (mrxInfo.rd.f.pFooter[1] & 0x80) {///
// CRC is OK
#if MAC_OPT_SECURITY
// Verify MIC for received CBC-MAC or CCM frames
if (mrxSecurityInfo.securitySetup.micLength > 0) {
if (pMDI->
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -