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

📄 mac_rx_engine.c

📁 zigbee location examples
💻 C
📖 第 1 页 / 共 4 页
字号:
//-------------------------------------------------------------------------------------------------------
ROOT 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(ADDRESS) * ((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;

    // Extended addresses first
    n = (pendAddrSpec & 0x70) >> 4;
    while (n--) {
        pendAddrOffset -= sizeof(ADDRESS);
        msupReverseCopy((BYTE  *) (&pMBNI->pAddrList[pendingIndex--]), (BYTE  *) (&pMDI->pMsdu[pendAddrOffset]), sizeof(ADDRESS));
    }

    // Then short addresses
    n = pendAddrSpec & 0x07;
    while (n--) {
        pendAddrOffset -= sizeof(WORD);
        msupReverseCopy((BYTE  *) (&pMBNI->pAddrList[pendingIndex--]), (BYTE  *) (&pMDI->pMsdu[pendAddrOffset]), sizeof(WORD));
    }

    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) NEAR {
    MAC_RX_PACKET *pPacket = (MAC_RX_PACKET*) pTask->taskData;
    MLME_BEACON_NOTIFY_INDICATION *pMBNI;
    MCPS_DATA_INDICATION *pMDI = &pPacket->mdi;
    BYTE pendAddrOffset;
    BOOL pendDataAvailable;
    WORD superframeSpec;
    BOOL panIdConflict;
    BYTE pendAddrSpec;
    UINT8 oldBeaconOrder;
    BOOL findBeacon;
    BOOL 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) {

            // 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->list.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)) {

            // 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 (msupCompareExtendedAddress(&pMDI->srcAddr, (ADDRESS  *) mpib.pMacCoordExtendedAddress)) {
                            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(&pPacket->timestamp);
                   }

                   // 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.macAssociatedPanCordinator)
                       {
                           if (pMDI->srcAddrMode == AM_SHORT_16)
                           {
                               msupTransmitPanConflict(AM_SHORT_16, mpib.macPANId, (ADDRESS*) &mpib.macCoordShortAddress, securityEnable);
                           } else {
                               msupTransmitPanConflict(AM_EXTENDED_64, mpib.macPANId, (ADDRESS  *) mpib.pMacCoordExtendedAddress, 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() - (T2_GET_OVERFLOW_COUNTER() - 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() - T2_GET_OVERFLOW_COUNTER());
            }
        }
        if (pPacket->flags & MRXP_FLAG_RX_NOT_TURNED_OFF_BM) mrxDecrOnCounter();

        // 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 (msupCompareExtendedAddress((ADDRESS  *) &aExtendedAddress, (ADDRESS  *) (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);

        // Beacon notify indication
        if (pMBNI->sduLength || !mpib.macAutoRequest) {

            // Make the call to the higher layer
            mlmeBeaconNotifyIndication(pMBNI);

        }

        // Release the packet
        mrxpReleasePacket(pPacket);
        break;
    }
} // mrxProcessBeacon




⌨️ 快捷键说明

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