⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mac_rx_engine.c

📁 ucos在NEC平台下的移植
💻 C
📖 第 1 页 / 共 5 页
字号:
                } 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 + -