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

📄 mac_rx_engine.c

📁 ucos在NEC平台下的移植
💻 C
📖 第 1 页 / 共 5 页
字号:
//      MAC_RX_PACKET *pPacket
//          The packet that contains the beacon. This structure will be modified to contain the 
//          notification.
//
//  RETURN VALUE:
//      MLME_BEACON_NOTIFY_INDICATION*
//          A pointer to the notification to be passed to the higher layer
//-------------------------------------------------------------------------------------------------------
MLME_BEACON_NOTIFY_INDICATION* mrxMakeBeaconNotifyIndication(MAC_RX_PACKET *pPacket) {
    MLME_BEACON_NOTIFY_INDICATION *pMBNI = (MLME_BEACON_NOTIFY_INDICATION*) (((BYTE*) pPacket) + 1);
    MCPS_DATA_INDICATION *pMDI = &pPacket->mdi;
    PAN_DESCRIPTOR *pPanDescriptor = &pMBNI->panDescriptor;
    UINT8 n;
    UINT8 payloadOffset;
    UINT8 pendAddrOffset;
    UINT8 pendAddrSpec;
    UINT8 pendingIndex;
     
    // Do not change the order of these operations!!!
    
    // Calculate the pSDU offset
    n = (pMDI->pMsdu[2] & 0x07);
    if (n) {
        n = 3 + 1 + 3 * n;
    } else {
        n = 3;
    }
    pendAddrSpec = pMDI->pMsdu[n];
    payloadOffset = n + 1 + (sizeof(WORD) * (pendAddrSpec & 0x07)) + (sizeof(QWORD) * ((pendAddrSpec & 0x70) >> 4));
    
    // Start by copying the payload in reverse order to avoid overwriting
    msupReverseCopy(pMBNI->pSdu, pMDI->pMsdu + payloadOffset, aMaxBeaconPayloadLength);
    
    // Copy lots of parameters (no fields are overwritten!)
    pMBNI->sduLength = pMDI->msduLength - payloadOffset;
    pPanDescriptor->logicalChannel = ppib.phyCurrentChannel;
    pPanDescriptor->linkQuality = pMDI->mpduLinkQuality;
    pPanDescriptor->superframeSpec = *((WORD*) pMDI->pMsdu);
    pPanDescriptor->gtsPermit = !!(pMDI->pMsdu[2] & 0x80);
    pPanDescriptor->securityUse = pMDI->securityUse;
    pPanDescriptor->aclEntry = pMDI->aclEntry;
#if ((MAC_OPT_SECURITY) || (MAC_OPT_ACL_SIZE>0))
    pPanDescriptor->securityFailure = (pPacket->securityStatus != SUCCESS);
#else
    pPanDescriptor->securityFailure = pMDI->securityUse;
#endif
    pMBNI->pendAddrSpec = pendAddrSpec;
    
    // Copy the pending addresses in the reverse order
    pendingIndex = (pendAddrSpec & 0x07) + ((pendAddrSpec & 0x70) >> 4) - 1;
    pendAddrOffset = payloadOffset - 1;
    
    // Extended addresses first
    n = (pendAddrSpec & 0x70) >> 4;
    while (n--) {
        pendAddrOffset -= sizeof(QWORD);
        msupReverseCopy((BYTE*) (&pMBNI->pAddrList[pendingIndex--]), (BYTE*) (&pMDI->pMsdu[pendAddrOffset]), sizeof(QWORD));
    }
    
    // Then short addresses
    n = pendAddrSpec & 0x07;
    while (n--) {
        pendAddrOffset -= sizeof(WORD);
        pMBNI->pAddrList[pendingIndex--].Short = *((WORD*) (pMDI->pMsdu + pendAddrOffset));
    }
    
    return pMBNI;
    
} // mrxMakeBeaconNotifyIndication




//-------------------------------------------------------------------------------------------------------
//  void mrxProcessBeacon(MAC_TASK_INFO *pTask)
//
//  DESCRIPTION:
//      This task is responsible for processing beacon packets.
//
//  TASK DATA
//      A pointer to the MAC_RX_PACKET to be processed
//-------------------------------------------------------------------------------------------------------
void mrxProcessBeacon(MAC_TASK_INFO *pTask) {
    MAC_RX_PACKET *pPacket = (MAC_RX_PACKET*) pTask->taskData;
    MLME_BEACON_NOTIFY_INDICATION *pMBNI;
    MCPS_DATA_INDICATION *pMDI = &pPacket->mdi;
    BYTE pendAddrOffset;
    ZBOOL pendDataAvailable;
    WORD superframeSpec;
    ZBOOL panIdConflict;
    BYTE pendAddrSpec;
    UINT8 oldBeaconOrder;
    ZBOOL findBeacon;
    MAC_ENUM result; 
    ZBOOL securityEnable = FALSE;
    
    switch (pTask->state) {
    case MRX_STATE_BCN_ALIGN_OR_SPEC_MODES:
        // When received by a scanning device/coordinator...
        if (macInfo.state == MAC_STATE_ACTIVE_OR_PASSIVE_SCAN) {
          ///  ENABLE_FIFOP_INT();
            
            // Turn off RX if "RX on when idle" was on
            if (pPacket->flags & MRXP_FLAG_RX_NOT_TURNED_OFF_BM) mrxDecrOnCounter();
            
            // Make the beacon notify indication (overwrites the pPacket structure)
            pMBNI = mrxMakeBeaconNotifyIndication(pPacket);
            
            // Store the PAN descriptor in the scan result table
            if (mscInfo.pScanResult->resultListSize < MAC_OPT_MAX_PAN_DESCRIPTORS) {
				memcpy(&mscInfo.pScanResult->ENERGY_OR_ACTIVE.pPANDescriptorList[mscInfo.pScanResult->resultListSize], &pMBNI->panDescriptor, sizeof(PAN_DESCRIPTOR));
                if (!mscPanDescriptorExists(&pMBNI->panDescriptor)) mscInfo.pScanResult->resultListSize++;
            }

            // Abort the scan if the result buffer is full
            if (mscInfo.pScanResult->resultListSize == MAC_OPT_MAX_PAN_DESCRIPTORS) {
                macSetState(MAC_STATE_SCAN_RESULT_BUFFER_FULL);
                mscInfo.channelComplete = TRUE;
            }

            // Remove the task
            mschRemoveTask(pTask->priority, 0);
            
            // Make the call to the higher layer when there's a beacon payload 
            if (pMBNI->sduLength) mlmeBeaconNotifyIndication(pMBNI);
            
            // Release the task
            mrxpReleasePacket(pPacket);
            break;
            
        // Ignore additional beacons until we've finished the scanning
        } else if (macInfo.state == MAC_STATE_SCAN_RESULT_BUFFER_FULL) {
        
            // Turn off RX if "RX on when idle" was on
            if (pPacket->flags & MRXP_FLAG_RX_NOT_TURNED_OFF_BM) mrxDecrOnCounter();
            
            // Clean up
            mschRemoveTask(pTask->priority, 0);
            mrxpReleasePacket(pPacket);
            
        // When received by a PAN coordinator...
        } else if (GET_MF(MF_PAN_COORDINATOR)) {
        
         ///   ENABLE_FIFOP_INT();

            // Turn off RX if "RX on when idle" was on
            if (pPacket->flags & MRXP_FLAG_RX_NOT_TURNED_OFF_BM) mrxDecrOnCounter();
            
            // Detect PAN ID conflict: When another unit is transmitting beacons with the PAN coordinator bit set
            // and using the same PAN ID as we are -> Report as a PAN_ID_CONFLICT.
            panIdConflict = (pMDI->pMsdu[1] & (SS_PAN_COORDINATOR_BM >> 8)) && (pMDI->srcPanId == mpib.macPANId);
            mschRemoveTask(pTask->priority, 0);
            mrxpReleasePacket(pPacket);
            if (panIdConflict) mlmeSyncLossIndication(PAN_ID_CONFLICT);

        // When received by a device...
        } else {
            
            //Find out if we have PAN ID conflict, check pan id then address if one or both failes we have a porblem 
            if (pMDI->srcPanId == mpib.macPANId)
            {                        
                panIdConflict = FALSE;
                if (pMDI->srcAddrMode == AM_SHORT_16) 
                {
                    if (pMDI->srcAddr.Short != mpib.macCoordShortAddress) 
                    {                        
                        panIdConflict = TRUE;
                    }
                }
                if(pMDI->srcAddrMode == AM_EXTENDED_64)
                {
                    if (!msupCompareQword((QWORD*)&mpib.macCoordExtendedAddress, (QWORD*)&pMDI->srcAddr.Extended))
                    {
                            panIdConflict = TRUE;
                    }
                }
                if(!panIdConflict) //Correct PANID and no conflict
                {                        
                    // Update the PIB and the superframe spec. structure
                    superframeSpec = *((WORD*) &pMDI->pMsdu[0]);
                    mpib.macSuperframeOrder = BF(superframeSpec, SS_SUPERFRAME_ORDER_BM, SS_SUPERFRAME_ORDER_IDX);
                    oldBeaconOrder = mpib.macBeaconOrder;
                    mpib.macBeaconOrder = BF(superframeSpec, SS_BEACON_ORDER_BM, SS_BEACON_ORDER_IDX);
                    mbcnInfo.lastSfSpec.finalCap = BF(superframeSpec, SS_FINAL_CAP_SLOT_BM, SS_FINAL_CAP_SLOT_IDX);
                    mbcnInfo.lastSfSpec.battLifeExt = BF(superframeSpec, SS_BATT_LIFE_EXT_BM, SS_BATT_LIFE_EXT_IDX);
                    
                    // Align the local timer with the beacon (in beacon-enabled networks only)
                    if (mpib.macBeaconOrder != 15) {
                        mtimAlignWithBeacon();
                    }
                    
                    // Handle non-beacon <-> beacon network change
                    mbcnHandleBeaconModeChange(oldBeaconOrder == 15);
                    
                    // Calculate the beacon duration (BOS) including IFS
                    mbcnInfo.beaconDuration = msupCalcPacketDuration(2 + 1 + 2 + ((pMDI->srcAddrMode == AM_EXTENDED_64) ? 8 : 2) + pMDI->msduLength, FALSE);
                    
                    pTask->state = MRX_STATE_BCN_TX_AFTER_BEACON;                    
                }else
                {
                    if (pPacket->flags & MRXP_FLAG_RX_NOT_TURNED_OFF_BM) mrxDecrOnCounter();
                    mschRemoveTask(pTask->priority, 0);
                    mrxpReleasePacket(pPacket);
                    if (panIdConflict) mlmeSyncLossIndication(PAN_ID_CONFLICT);
                    // Try to transmit the PAN ID COnflict message
                    if(mpib.macAssocatedPanCordinator)
                    {
                        if (pMDI->srcAddrMode == AM_SHORT_16) 
                        {
                            result = msupTransmitPanConflict(AM_SHORT_16, mpib.macPANId, (ADDRESS*) &mpib.macCoordShortAddress, securityEnable);
                        } else {
                            result = msupTransmitPanConflict(AM_EXTENDED_64, mpib.macPANId, (ADDRESS*) &mpib.macCoordExtendedAddress, securityEnable);
                        }
                    }
                                        
                }                                
            } else 
            { //Wrong PAN ID drop beacon, Clean up
                if (pPacket->flags & MRXP_FLAG_RX_NOT_TURNED_OFF_BM) mrxDecrOnCounter();
                mschRemoveTask(pTask->priority, 0);
                mrxpReleasePacket(pPacket);                
            }                       
        }
        break;
       
    case MRX_STATE_BCN_TX_AFTER_BEACON:
          
        // Cancel the beacon reception timeout!
        if (mtimCancelCallback(mbcnRxBeaconTimeout)) {
            mrxDecrOnCounter();
        }
        mbcnInfo.noBcnCountdown = aMaxLostBeacons;
            
        mtxResumeAfterBeacon();
        pTask->state = MRX_STATE_BCN_EXAMINE_PENDING_FIELDS;
        break;
        
    case MRX_STATE_BCN_EXAMINE_PENDING_FIELDS:
                
        // Adjust the timing of the beacon handler
        if (mtimCancelCallback(mbcnRxPeriodicalBeacon)) {
            //                                      <-- Beacon interval --->   <------ Used CAP ------->   <------ Margin ----->   <- RX startup overhead ->
            mtimSetCallback(mbcnRxPeriodicalBeacon, msupCalcBeaconInterval() - (mtimInfo.bosCounter - 1) - mbcnGetBeaconMargin() - MBCN_RX_STARTUP_OVERHEAD);
        }
        
        // Handle "RX on when idle"
        if (mpib.macSuperframeOrder != 15) {
            if (mpib.macRxOnWhenIdle) {
            
                // On:
                mrxAutoIncrOnCounter();

                // Off: Force when the superframe is shorter than the beacon interval
                mtimSetCallback((mpib.macBeaconOrder == mpib.macSuperframeOrder) ? mrxDecrOnCounter : mrxForceRxOff, msupCalcCapDuration() - mtimInfo.bosCounter);
            }
        }
        if (pPacket->flags & MRXP_FLAG_RX_NOT_TURNED_OFF_BM) mrxDecrOnCounter();

     ///   ENABLE_FIFOP_INT();
        
        // Stop searching for the beacon
        findBeacon = mbcnInfo.findBeacon;
        if (findBeacon) {
            mrxDecrOnCounter();
            mbcnInfo.findBeacon = FALSE;
        }

        // Remove the task
        mschRemoveTask(pTask->priority, 0);
        
        // Auto-request pending data?
        if ((mpib.macAutoRequest || (macInfo.state == MAC_STATE_ASSOC_REQUEST_SENT)) && (mbcnInfo.trackBeacon || findBeacon)) {
            
            // Find offset to Pending Address Specification in the payload
            //               < SFS + GTS >   <-------- GTS list ------->
            pendAddrOffset =    2  +  1    + 3 * (pMDI->pMsdu[2] & 0x07);
            
            // Get the Pending Address Specification
            pendAddrSpec = pMDI->pMsdu[pendAddrOffset++];
            
            // Short addresses are located first...
            while (pendAddrSpec & 0x07) {
                if (mpib.macShortAddress == *((WORD*) (pMDI->pMsdu + pendAddrOffset))) {
                    pendDataAvailable = TRUE;
                    goto stopPendSearch;
                }
                pendAddrOffset += 2;
                pendAddrSpec -= 0x01;
            }

            // Then check extended addresses, see if anyone has pending data!
            while (pendAddrSpec & 0x70) {
                if (msupCompareQword(&aExtendedAddress, (QWORD*) (pMDI->pMsdu + pendAddrOffset))) {
                    pendDataAvailable = TRUE;
                    goto stopPendSearch;
                }
                pendAddrOffset += 8;
                pendAddrSpec -= 0x10;
            }
            
            // Nothing was found :(
            pendDataAvailable = FALSE;
           
stopPendSearch:
            
            // Transmit the data request?
            if (pendDataAvailable) {
                if (macInfo.state == MAC_STATE_ASSOC_REQUEST_SENT) {
                    mipTransmitAssocDataRequest();
                } else {
                    mipTransmitAutoDataRequest();
                }
            }
        }        
                
        // Make the beacon notify indication (overwrites the pPacket structure)
        pMBNI = mrxMakeBeaconNotifyIndication(pPacket);
        

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -