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

📄 mac_rx_engine.c

📁 zigbee location examples
💻 C
📖 第 1 页 / 共 4 页
字号:
//-------------------------------------------------------------------------------------------------------
//  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 + -