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

📄 mac_indirect_queue.c

📁 zigbee location examples
💻 C
📖 第 1 页 / 共 2 页
字号:

} // miqFindAndRequestIndirectPacket

/*******************************************************************************************************
 *******************************************************************************************************
 **************************           INDIRECT PACKET TRANSMISSION            **************************
 *******************************************************************************************************
 *******************************************************************************************************/




//-------------------------------------------------------------------------------------------------------
//  void miqSetRequested(MAC_TX_PACKET *pPacket, BOOL requested)
//
//  DESCRIPTION:
//      Requests or unrequests indirect packets. This function is responsible for creating the task that
//      initiates the indirect packet transmission.
//
//  ARGUMENTS:
//      MAC_TX_PACKET *pPacket
//          A pointer to the packet to be requested or unrequested
//      BOOL requested
//          TRUE if the packet should be flagged for transmission, FALSE if the flag is to be cleared
//          (note that this .
//
//  RETURN VALUE:
//      BOOL
//          A packet was found and flagged for transmission
//-------------------------------------------------------------------------------------------------------
ROOT void miqSetRequested(MAC_TX_PACKET *pPacket, BOOL requested) {

    // Unrequested -> requested
    if (requested && !pPacket->requested) {
        if (pPacket->timeToLive > 0) {

            // Create the transmission whn the first packet is requested
            if (miqInfo.requestedCounter == 0) {
                if (mschAddTask(mschReserveTask(), MAC_TASK_PRI_LOW, miqTransmitRequestedPackets, NULL)) {
                    pPacket->requested = TRUE;
                    miqInfo.requestedCounter++;
                }
            } else {
                pPacket->requested = TRUE;
                miqInfo.requestedCounter++;
            }
        }


    // Requested -> unrequested
    } else {
        DISABLE_GLOBAL_INT();
        if (!requested && pPacket->requested) {
            miqInfo.requestedCounter--;
            pPacket->requested = FALSE;
        }
        ENABLE_GLOBAL_INT();
    }
} // miqSetRequested




//-------------------------------------------------------------------------------------------------------
//  void miqUnrequestAll(void)
//
//  DESCRIPTION:
//      Unrequests all indirect packets
//-------------------------------------------------------------------------------------------------------
ROOT void miqUnrequestAll(void) {
    UINT8 n;

    for (n = 0; n < MAC_OPT_TX_POOL_SIZE; n++) {
        miqSetRequested(&pMtxPacketPool[n], FALSE);
    }
} // miqUnrequestAll




//--------------------------        -----------------------------------------------------------------------------
//  void                    miqTransmitRequestedPackets(MAC_TASK_INFO *pTask)
//
//  DESCRIPTION:
//      This task runs in a loop (reschedules itself), and creates the mtxScheduleTransmission tasks for
//      requested indirect packets. The task dies when there are no more requested packets.
//
//  TASK DAYA:
//      0
//-------------------------------------------------------------------------------------------------------
void miqTransmitRequestedPackets(MAC_TASK_INFO *pTask) NEAR {
    UINT8 index;
    MAC_TX_PACKET   *pIndirectPacket;

    if (miqInfo.requestedCounter) {

        // Search for requested packets
        index = miqInfo.firstIndirectPacket;
        while (index != NO_PACKET) {

            // Activate the current packet if it has been requested
            pIndirectPacket = &pMtxPacketPool[index];
            DISABLE_GLOBAL_INT();
            if (pIndirectPacket->requested) {
                pIndirectPacket->transmissionStarted = TRUE;
                ENABLE_GLOBAL_INT();

                // The requested bit should still be set, because it will be checked before the packet is transmitted
                if (!mschAddTask(mschReserveTask(), MAC_TASK_PRI_LOW, mtxScheduleTransmission, (WORD) pIndirectPacket)) {
                    pIndirectPacket->transmissionStarted = FALSE;
                }
                break;
            }
            ENABLE_GLOBAL_INT();

            // Move on to the next packet
            index = pIndirectPacket->nextPacket;
        }

        // Re-schedule this task, so that it runs in a loop while there are packets to be transmitted
        mschRescheduleTask(pTask, 0);

    } else {
        ENABLE_GLOBAL_INT();
        mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_IN_PROGRESS_BM);
    }

} // miqTransmitRequestedPackets




//-------------------------------------------------------------------------------------------------------
//  void miqTransmitRequestedPackets(ADDRESS *pDestAddr, BOOL isExtAddr)
//
//  DESCRIPTION:
//      Transmits a packet with no payload as a response to a data request when there are no pending
//      packets in the queue.
//
//  ARGUMENTS:
//      ADDRESS *pDestAddr
//          The destination address of the packet
//      BOOL isExtAddr
//          TRUE if pDestAddr points to an extended address
//
//  RETURN VALUE:
//      BOOL
//          The packet transmission has been initiated
//-------------------------------------------------------------------------------------------------------
ROOT BOOL miqTransmitNoDataPacket(ADDRESS *pDestAddr, BOOL isExtAddr) {
    MAC_TX_PACKET   *pPacket;
    UINT8 taskNumber;
    BYTE txOptions;

    // Try to reserve a packet
    pPacket = mtxpReservePacket();
    if (!pPacket) return FALSE;

    // Try to reserve a transmission task
    taskNumber = mschReserveTask();
    if (taskNumber == NO_TASK) {
        mtxpReleasePacket(pPacket);
        return FALSE;
    }

    // Set TX options
    txOptions = TX_OPT_ACK_REQ;
#if MAC_OPT_SECURITY
//TBD: Include security here?
//    if (securityEnable) {
//        txOptions |= TX_OPT_SECURITY_ENABLE;
//    }
#endif

    // TX mode
    pPacket->txMode = MTX_MODE_USE_CSMACA_BM | MTX_MODE_MAC_INTERNAL_BM;
    pPacket->retriesLeft = 1;

    // Generate the packet header (and find security material, if enabled)
    if (mpib.macShortAddress >= 0xFFFE) {
        msupPrepareHeader(pPacket, FT_DATA, (isExtAddr ? DEST_ADDR_EXT : DEST_ADDR_SHORT) | SRC_ADDR_EXT, mpib.macPANId, (ADDRESS  *) &aExtendedAddress, mpib.macPANId, pDestAddr, txOptions);
    } else {
        msupPrepareHeader(pPacket, FT_DATA, (isExtAddr ? DEST_ADDR_EXT : DEST_ADDR_SHORT) | SRC_ADDR_SHORT, mpib.macPANId, (ADDRESS  *) &mpib.macShortAddress, mpib.macPANId, pDestAddr, txOptions);
    }

    // Calculate and set the total packet length (TBD: will security ever be used / is it allowed by the spec?)
#if MAC_OPT_SECURITY
    pPacket->length = pPacket->headerLength + pPacket->securitySetup.micLength + MAC_FCS_LENGTH;
#else
    pPacket->length = pPacket->headerLength + MAC_FCS_LENGTH;
#endif

    // Calculate the packet duration (including ack. and IFS)
    pPacket->duration = msupCalcPacketDuration(pPacket->length, pPacket->txOptions & TX_OPT_ACK_REQ);

    // Initiate the transmission
    mschAddTask(taskNumber, MAC_TASK_PRI_LOW, mtxScheduleTransmission, (WORD) pPacket);

    return TRUE;
} // miqTransmitNoDataPacket




/*******************************************************************************************************
 *******************************************************************************************************
 **************************            INDIRECT PACKET EXPIRATION             **************************
 *******************************************************************************************************
 *******************************************************************************************************/




//-------------------------------------------------------------------------------------------------------
//  void miqDecrTimeToLive(void)
//
//  DESCRIPTION:
//      Decrements the "time to live" variable for all indirect packets, until it reaches zero
//-------------------------------------------------------------------------------------------------------
ROOT void miqDecrTimeToLive(void) {
    UINT8 n;
    for (n = 0; n < MAC_OPT_TX_POOL_SIZE; n++) {
        DISABLE_GLOBAL_INT();
        if (pMtxPacketPool[n].timeToLive > 0) pMtxPacketPool[n].timeToLive--;
        ENABLE_GLOBAL_INT();
    }
} // miqDecrTimeToLive




//-------------------------------------------------------------------------------------------------------
//  void miqExpireIndirectPacketsTask(MAC_TASK_INFO *pTask)
//
//  DESCRIPTION:
//      Expires indirect packets that have not been requested or taken into the TX engine. Only one
//      packet will be expired for each round.
//
//  TASK DATA:
//      0 (modified by the task)
//-------------------------------------------------------------------------------------------------------
void miqExpireIndirectPacketsTask(MAC_TASK_INFO *pTask) NEAR {
    UINT8 index;
    BOOL wasPurged;
    UINT8 msduHandle;
    MAC_TX_PACKET   *pIndirectPacket;

    // Skip the search state if we already have a pointer to a specific packet
    if (pTask->taskData != NULL) pTask->state = MIQ_STATE_REMOVE_EXPIRED_PACKET;

    switch (pTask->state) {
    case MIQ_STATE_FIND_EXPIRED_PACKET:
        index = miqInfo.firstIndirectPacket;
        while (index != NO_PACKET) {
            pIndirectPacket = &pMtxPacketPool[index];

            // Purge packets with time no more time to live (unless they have been requested
            DISABLE_GLOBAL_INT();
            if (!pIndirectPacket->requested && (pIndirectPacket->timeToLive < 1)) {
                pTask->taskData = (WORD) pIndirectPacket;
                // pTask->state = MIQ_STATE_REMOVE_EXPIRED_PACKET is not required here (duplicate operation, see above)
                ENABLE_GLOBAL_INT();
                return;
            }
            ENABLE_GLOBAL_INT();
            index = pIndirectPacket->nextPacket;
        }
        mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_IN_PROGRESS_BM);
        break;

    case MIQ_STATE_REMOVE_EXPIRED_PACKET:

        // The task data contains a pointer to the packet to be removed
        pIndirectPacket = (MAC_TX_PACKET   *) pTask->taskData;

        // Only if the packet has not been requested, and is not already been taken into the TX engine...
        if (!pIndirectPacket->requested && !pIndirectPacket->transmissionStarted) {

            // Save the reason for the packet to be removed
            wasPurged = pIndirectPacket->purgeRequest;
            msduHandle = pIndirectPacket->msduHandle;

            // Make the call to the higher layer
            if (!wasPurged) {
                if (pIndirectPacket->type == FT_DATA) {
                    mcpsDataConfirm(TRANSACTION_EXPIRED, msduHandle);
                } else {
                    switch (pIndirectPacket->commandType) {
                    case CMD_ASSOCIATION_RESPONSE:
                        mtxCommStatusIndication(pIndirectPacket, TRANSACTION_EXPIRED);
                        break;
                    case CMD_DISASSOCIATION_NOTIFICATION:
                        mlmeDisassociateConfirm(TRANSACTION_EXPIRED);
                        break;
                    }
                }
            }

            // Transform this task into a removal task
            pTask->pTaskFunc = miqRemoveIndirectPacket;
            pTask->state = 0;

        } else {
            mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_IN_PROGRESS_BM);
        }
        break;
    }

} // miqExpireIndirectPacketsTask


#endif // MAC_OPT_FFD

⌨️ 快捷键说明

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