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

📄 mac_indirect_queue.c

📁 zigbee location examples
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************************************************
 *                                                                                                     *
 *        **********                                                                                   *
 *       ************                                                                                  *
 *      ***        ***                                                                                 *
 *      ***   +++   ***                                                                                *
 *      ***   + +   ***                                                                                *
 *      ***   +                         CHIPCON CC2430 INTEGRATED 802.15.4 MAC AND PHY                 *
 *      ***   + +   ***                        Indirect Packet Queue + Related                         *
 *      ***   +++   ***                                                                                *
 *      ***        ***                                                                                 *
 *       ************                                                                                  *
 *        **********                                                                                   *
 *                                                                                                     *
 *******************************************************************************************************
 * CONFIDENTIAL                                                                                        *
 * The use of this file is restricted by the signed MAC software license agreement.                    *
 *                                                                                                     *
 * Copyright Chipcon AS, 2005                                                                          *
 *******************************************************************************************************
 * This module contains functions related to the indirect packet queue (on coordinators), including    *
 * queue management, transmission initiation, expiration, and other functions.                         *
 *******************************************************************************************************/
#include <mac_headers.h>
#if MAC_OPT_FFD


//-------------------------------------------------------------------------------------------------------
// Variables related to the indirect packet queue
__no_init MAC_INDIRECT_QUEUE_INFO   miqInfo @ "PM0_XDATA";
//-------------------------------------------------------------------------------------------------------




/*******************************************************************************************************
 *******************************************************************************************************
 **************************                 QUEUE MANAGEMENT                  **************************
 *******************************************************************************************************
 *******************************************************************************************************/




//-------------------------------------------------------------------------------------------------------
//  void miqInit(void)
//
//  DESCRIPTION:
//      Initializes the indirect packet queue
//-------------------------------------------------------------------------------------------------------
ROOT void miqInit(void) {
    miqInfo.firstIndirectPacket = NO_PACKET;
    miqInfo.lastIndirectPacket = NO_PACKET;
    miqInfo.requestedCounter = 0;
} // miqInit




//-------------------------------------------------------------------------------------------------------
//  void miqAddIndirectPacket(MAC_TASK_INFO *pTask)
//
//  DESCRIPTION:
//      This task adds a packet to the indirect queue.
//
//  TASK DATA:
//      A pointer to the MAC_TX_PACKET to be added
//-------------------------------------------------------------------------------------------------------
void miqAddIndirectPacket(MAC_TASK_INFO *pTask) NEAR {
    MAC_TX_PACKET   *pPacket = (MAC_TX_PACKET *) pTask->taskData;
    MAC_TX_PACKET   *pIndirectPacket;
    UINT8           temp;
    BYTE            destAddrMode;
    ADDRESS         *pDestAddr;

    switch (pTask->state) {
    case MIQ_STATE_FIND_FIRST_PACKET_FROM_NODE:
        // Start by determining whether or not this is the first indirect packet to this node.
        pPacket->isFirstPacket = TRUE;
        destAddrMode = (BYTE)(pPacket->pHeader[1] & DEST_ADDR_BM);
        pDestAddr = (ADDRESS*) (pPacket->pHeader + 5);

        // Go through the whole packet queue, and clear the isFirstPacket flag if a match is found
        temp = miqInfo.firstIndirectPacket;
        while (temp != NO_PACKET) {
            pIndirectPacket = &pMtxPacketPool[temp];
            if (destAddrMode == (pIndirectPacket->pHeader[1] & DEST_ADDR_BM)) {
                if (destAddrMode == DEST_ADDR_SHORT) {
                    if (pDestAddr->Short == *((WORD   *) (pIndirectPacket->pHeader + 5))) {
                        pPacket->isFirstPacket = FALSE;
                        break;
                    }
                } else {
                    if (msupCompareExtendedAddress((ADDRESS   *) pDestAddr, (ADDRESS   *) (pIndirectPacket->pHeader + 5))) {
                        pPacket->isFirstPacket = FALSE;
                        break;
                    }
                }
            }
            temp = pIndirectPacket->nextPacket;
        }
        pTask->state = MIQ_STATE_INSERT_INTO_QUEUE;
        break;

    case MIQ_STATE_INSERT_INTO_QUEUE:

        // Find the index of the new packet
        temp = pPacket->poolIndex;

        // Add the packet to the queue
        if (miqInfo.lastIndirectPacket != NO_PACKET)
            pMtxPacketPool[miqInfo.lastIndirectPacket].nextPacket = temp;

        pPacket->prevPacket = miqInfo.lastIndirectPacket;
        pPacket->nextPacket = NO_PACKET;
        pPacket->timeToLive = mpib.macTransactionPersistenceTime;
        pPacket->purgeRequest = FALSE;
        pPacket->requested = FALSE;
        pPacket->transmissionStarted = FALSE;

        // Update the global indexes
        miqInfo.lastIndirectPacket = temp;
        if (miqInfo.firstIndirectPacket == NO_PACKET) miqInfo.firstIndirectPacket = temp;

        // Remove the task
        mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_IN_PROGRESS_BM);
        break;
    }

} // miqAddIndirectPacket




//-------------------------------------------------------------------------------------------------------
//  void miqRemoveIndirectPacket(MAC_TASK_INFO *pTask)
//
//  DESCRIPTION:
//      This task removes a packet from the indirect queue. Note that the "requested flag" must have been
//      cleared before this task is created. To make sure that the packet is not requested again before
//      this task completes, the timeToLive counter should be set to < 1.
//
//  TASK DATA:
//      A pointer to the MAC_TX_PACKET to be removed.
//-------------------------------------------------------------------------------------------------------
void miqRemoveIndirectPacket(MAC_TASK_INFO *pTask) NEAR {
    MAC_TX_PACKET   *pPacket = (MAC_TX_PACKET *) pTask->taskData;
    MAC_TX_PACKET   *pIndirectPacket;
    BYTE            temp;
    BYTE            destAddrMode;
    ADDRESS         *pDestAddr;

    switch (pTask->state) {
    case MIQ_STATE_REMOVE_PACKET:

        // Update the link on the previous packet
        if (pPacket->prevPacket != NO_PACKET) {
            pMtxPacketPool[pPacket->prevPacket].nextPacket = pPacket->nextPacket;
        }

        // Update the link on the next packet
        if (pPacket->nextPacket != NO_PACKET) {
            pMtxPacketPool[pPacket->nextPacket].prevPacket = pPacket->prevPacket;
        }

        // Update the "head" and "tail" indexes of the queue
        temp = pPacket->poolIndex;
        if (temp == miqInfo.firstIndirectPacket) miqInfo.firstIndirectPacket = pPacket->nextPacket;
        if (temp == miqInfo.lastIndirectPacket) miqInfo.lastIndirectPacket = pPacket->prevPacket;

        pTask->state = MIQ_STATE_MOVE_FIRST_PACKET_FLAG;
        break;

    case MIQ_STATE_MOVE_FIRST_PACKET_FLAG:

        // If set here, then move the isFirstPacket flag to the next packet with same destination in the queue
        if (pPacket->isFirstPacket) {
            pPacket->isFirstPacket = FALSE;
            temp = pPacket->nextPacket;
            destAddrMode = (BYTE)(pPacket->pHeader[1] & DEST_ADDR_BM);
            pDestAddr = (ADDRESS   *) (pPacket->pHeader + 5);

            // For each packet in the queue ...
            while (temp != NO_PACKET) {
                pIndirectPacket = &pMtxPacketPool[temp];
                if (destAddrMode == (pIndirectPacket->pHeader[1] & DEST_ADDR_BM)) {
                    if (destAddrMode == DEST_ADDR_SHORT) {
                        if (pDestAddr->Short == *((WORD   *) (pIndirectPacket->pHeader + 5))) {
                            pIndirectPacket->isFirstPacket = TRUE;
                            break;
                        }
                    } else {
                        if (msupCompareExtendedAddress((ADDRESS   *) pDestAddr, (ADDRESS   *) (pIndirectPacket->pHeader + 5))) {
                            pIndirectPacket->isFirstPacket = TRUE;
                            break;
                        }
                    }
                }
                temp = pIndirectPacket->nextPacket;
            }
        }

        // Clean up
        mschRemoveTask(pTask->priority, MSCH_KEEP_TASK_IN_PROGRESS_BM);
        mtxpReleasePacket(pPacket);
        break;
    }
} // miqRemoveIndirectPacket

//-------------------------------------------------------------------------------------------------------
//  BOOL miqFindIndirectPacket(ADDRESS *pDestAddr, BOOL isExtAddr)
//
//  DESCRIPTION:
//      Searches through the indirect packet queue for a match on the given address.
//
//  ARGUMENTS:
//      ADDRESS *pDestAddr
//          A pointer to the address to search for
//      BOOL isExtAddr
//          TRUE if pDestAddr points to an extended address
//
//  RETURN VALUE:
//      MAC_TX_PACKET
//          A packet was found a packet pointer is returned, if no packet is found NULL is returned
//-------------------------------------------------------------------------------------------------------
ROOT MAC_TX_PACKET *miqFindIndirectPacket(ADDRESS *pDestAddr, BOOL isExtAddr) {
    UINT8 temp;
    BYTE destAddrMode = isExtAddr ? DEST_ADDR_EXT : DEST_ADDR_SHORT;
    MAC_TX_PACKET *pIndirectPacket;

    // For each packet in the queue ...
    temp = miqInfo.firstIndirectPacket;
    while (temp != NO_PACKET) {
        pIndirectPacket = &pMtxPacketPool[temp];

        // ... return the packet index if there's a match on the address mode ...
        if ((destAddrMode == (pIndirectPacket->pHeader[1] & DEST_ADDR_BM)) && (pIndirectPacket->transmissionStarted != TRUE)) {

            // ... and the address itself
            if (destAddrMode == DEST_ADDR_SHORT) {
                if (pDestAddr->Short == *((WORD   *) (pIndirectPacket->pHeader + 5))) {
                    return pIndirectPacket;
                }
            } else {
                if (msupCompareExtendedAddress((ADDRESS   *) pDestAddr, (ADDRESS   *) (pIndirectPacket->pHeader + 5))) {
                    return pIndirectPacket;
                }
            }
        }


        // Move to the next packet in the queue
        temp = pIndirectPacket->nextPacket;
    }

    // Could not find any match
    return NULL;

} // miqFindIndirectPacket

//-------------------------------------------------------------------------------------------------------
//  BOOL miqFindAndRequestIndirectPacket(ADDRESS *pDestAddr, BOOL isExtAddr)
//
//  DESCRIPTION:
//      Searches through the indirect packet queue for a match on the given address. If successful, the
//      found packet will be requested, and transmitted ASAP.
//
//  ARGUMENTS:
//      ADDRESS *pDestAddr
//          A pointer to the address to search for
//      BOOL isExtAddr
//          TRUE if pDestAddr points to an extended address
//
//  RETURN VALUE:
//      BOOL
//          A packet was found and flagged for transmission
//-------------------------------------------------------------------------------------------------------
ROOT BOOL miqFindAndRequestIndirectPacket(ADDRESS *pDestAddr, BOOL isExtAddr) {
    UINT8           temp;
    BYTE            destAddrMode;
    MAC_TX_PACKET   *pIndirectPacket;

    destAddrMode = (BYTE)(isExtAddr ? DEST_ADDR_EXT : DEST_ADDR_SHORT);

    // For each packet in the queue ...
    temp = miqInfo.firstIndirectPacket;
    while (temp != NO_PACKET) {
        pIndirectPacket = &pMtxPacketPool[temp];

        // ... return the packet index if there's a match on the address mode ...
        if (destAddrMode == (pIndirectPacket->pHeader[1] & DEST_ADDR_BM))
        {

            // ... and the address itself
            if (destAddrMode == DEST_ADDR_SHORT) {
                if (pDestAddr->Short == *((WORD   *) &pIndirectPacket->pHeader[5])) {
                    miqSetRequested(pIndirectPacket, TRUE);
                    return TRUE;
                }
            } else {
                if (msupCompareExtendedAddress(pDestAddr, (ADDRESS  *) (pIndirectPacket->pHeader + 5))) {
                    miqSetRequested(pIndirectPacket, TRUE);
                    return TRUE;
                }
            }
        }


        // Move to the next packet in the queue
        temp = pIndirectPacket->nextPacket;
    }

    // Could not find any match (should reply to the data request with a zero-length data packet)
    return FALSE;

⌨️ 快捷键说明

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