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

📄 mac_indirect_queue.c

📁 ucos在NEC平台下的移植
💻 C
📖 第 1 页 / 共 2 页
字号:
       
    return retVal;   
} // 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
//-------------------------------------------------------------------------------------------------------
void miqSetRequested(MAC_TX_PACKET *pPacket, BOOL requested) {
    UINT8 taskNumber;
    
    // Unrequested -> requested
    if (requested && !pPacket->requested) {
        if (pPacket->timeToLive > 0) {
            
            // Create the transmission whn the first packet is requested
            if (miqInfo.requestedCounter == 0) {
                taskNumber = mschReserveTask();
                if (mschAddTask(taskNumber, MAC_TASK_PRI_LOW, miqTransmitRequestedPackets, 0)) {
                    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
//-------------------------------------------------------------------------------------------------------
void miqUnrequestAll(void) {
UINT8 n = 0;///
    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) {
    UINT8 index;
    MAC_TX_PACKET *pIndirectPacket;

    ENABLE_FIFOP_INT();

    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
//-------------------------------------------------------------------------------------------------------
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
//-------------------------------------------------------------------------------------------------------
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) {
    UINT8 index;
    BOOL wasPurged;
    UINT8 msduHandle;
    MAC_TX_PACKET *pIndirectPacket;
    
    ENABLE_FIFOP_INT();
    
    // Skip the search state if we already have a pointer to a specific packet
    if (pTask->taskData != 0) 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)
                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->mc.msduHandle;///
                        
            // Make the call to the higher layer
            if (!wasPurged) {
                if (pIndirectPacket->type == FT_DATA) {
                    mcpsDataConfirm(TRANSACTION_EXPIRED, msduHandle);
                } else {
                    switch (pIndirectPacket->mc.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


/*******************************************************************************************************
 * Revision history:
 *
 * $Log: mac_indirect_queue.c,v $
 * Revision 1.11  2004/12/07 09:47:50  thl
 * Fixed potential coruption of memmory when max payload is recived.
 *
 * Revision 1.10  2004/11/18 15:07:57  thl
 * Added support for pending frame bit in outgoing data frames.
 * Only apply to outgoing data frames and wherer the address matches
 * one or more packet in the indirect packet quee.
 *
 * Revision 1.9  2004/11/10 09:33:14  thl
 * Fixed a number of bugs according to: MAC software check lists.xls
 *
 * Revision 1.8  2004/08/13 13:04:46  jol
 * CC2420 MAC Release v0.7
 *
 *
 *******************************************************************************************************/

⌨️ 快捷键说明

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