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

📄 mac_indirect_queue.c

📁 ucos在NEC平台下的移植
💻 C
📖 第 1 页 / 共 2 页
字号:
/*******************************************************************************************************
 *                                                                                                     *
 *        **********                                                                                   *
 *       ************                                                                                  *
 *      ***        ***                                                                                 *
 *      ***   +++   ***                                                                                *
 *      ***   + +   ***                                                                                *
 *      ***   +                         CHIPCON CC2420 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, 2004                                                                          *
 *******************************************************************************************************
 * This module contains functions related to the indirect packet queue (on coordinators), including    *
 * queue management, transmission initiation, expiration, and other functions.                         *
 *******************************************************************************************************
 * Compiler: AVR-GCC                                                                                   *
 * Target platform: CC2420DB, CC2420 + any ATMEGA MCU                                                  *
 *******************************************************************************************************
 * The revision history is located at the bottom of this file                                          *
 *******************************************************************************************************/
#pragma SFR
#pragma NOP
#pragma STOP
#pragma HALT
#pragma DI
#pragma EI
#pragma  section @@DATA queue at 0xE200///
#include "mac_headers.h"
#if MAC_OPT_FFD


//-------------------------------------------------------------------------------------------------------
// Variables related to the indirect packet queue
MAC_INDIRECT_QUEUE_INFO miqInfo;
//-------------------------------------------------------------------------------------------------------




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




//-------------------------------------------------------------------------------------------------------
//  void miqInit(void)
//
//  DESCRIPTION:
//      Initializes the indirect packet queue
//-------------------------------------------------------------------------------------------------------
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) {
    MAC_TX_PACKET *pPacket = (MAC_TX_PACKET*) pTask->taskData;
    MAC_TX_PACKET *pIndirectPacket;
    UINT8 temp;
    BYTE destAddrMode;
    ADDRESS *pDestAddr;
    
    ENABLE_FIFOP_INT();
    
    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 = 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 (msupCompareQword((QWORD*) pDestAddr, (QWORD*) (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) {
    MAC_TX_PACKET *pPacket = (MAC_TX_PACKET*) pTask->taskData;
    MAC_TX_PACKET *pIndirectPacket;
    BYTE temp;
    BYTE destAddrMode;
    ADDRESS *pDestAddr;
    
    ENABLE_FIFOP_INT();
    
    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 = 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 (msupCompareQword((QWORD*) pDestAddr, (QWORD*) (pIndirectPacket->pHeader + 5))) {
                            pIndirectPacket->isFirstPacket = TRUE;
                            break;
                        }
                    }
                }
                temp = pIndirectPacket->nextPacket;
                //ENABLE_FIFOP_INT(); THL Bug 17082004 fix
            }
        }
        
        // 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
//-------------------------------------------------------------------------------------------------------
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 (msupCompareQword((QWORD*) pDestAddr, (QWORD*) (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
//-------------------------------------------------------------------------------------------------------
BOOL miqFindAndRequestIndirectPacket(ADDRESS *pDestAddr, BOOL isExtAddr) {
    BOOL retVal; 
    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)) {
            
            // ... and the address itself
            if (destAddrMode == DEST_ADDR_SHORT) {
                if (pDestAddr->Short == *((WORD*) (pIndirectPacket->pHeader + 5))) {
                    miqSetRequested(pIndirectPacket, TRUE);
                    return TRUE;
                }
            } else {
                if (msupCompareQword((QWORD*) pDestAddr, (QWORD*) (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;*/
    
    pIndirectPacket =  miqFindIndirectPacket(pDestAddr, isExtAddr);
    if (pIndirectPacket != NULL)
    {
        miqSetRequested(pIndirectPacket, TRUE);
        retVal = TRUE;
    }
    else
    {
        retVal = FALSE;
    }
    

⌨️ 快捷键说明

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