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

📄 equeue.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 2 页
字号:
/**************************************************************************
*                                                                          
*       Copyright (c)  1993 - 2001 Accelerated Technology, Inc.            
*                                                                          
* PROPRIETARY RIGHTS of Accelerated Technology are involved in the subject 
* matter of this material.  All manufacturing, reproduction, use and sales 
* rights pertaining to this subject matter are governed by the license     
* agreement.  The recipient of this software implicity accepts the terms   
* of the license.                                                          
*                                                                          
****************************************************************************/
/****************************************************************************
*                                                                            
* FILENAME                                            VERSION                        
*                                                                                    
*  equeue.c                                             4.4                         
*                                                                                    
* DESCRIPTION                                                                
*                                                                            
*  Event queue manager                                                       
*                                                                            
* DATA STRUCTURES                                                            
*                                                                            
*                                                                            
* FUNCTIONS                                                                  
*                                                                            
*  NU_EventsDispatcher 
*  EQ_Clear_Matching_Timer                                                      
*                                                                            
* DEPENDENCIES                                                               
*                                                                            
*  No other file dependencies                                                
*                                                                            
******************************************************************************/

#include "plus/nucleus.h"
#include "net/target.h"
#include "net/inc/netevent.h"
#include "net/inc/mem_defs.h"
#include "net/inc/net.h"
#include "net/inc/arp.h"
#include "net/inc/externs.h"
#include "net/inc/ip.h"
#include "net/inc/tcp.h"
#include "net/inc/igmp.h"
#include "net/inc/icmp.h"
#include "net/inc/nerrs.h"
#include "net/inc/udp.h"
#include "net/inc/net_extr.h"

#if (INCLUDE_NAT == NU_TRUE)
#include "nat/inc/nat_extr.h"
#endif

#if (INCLUDE_DHCP == NU_TRUE)
#include "net/inc/dhcp.h"
#endif

/*
 * Define the timerlist control pointers.  These are globally used to
 * maintain the system timer list that is used for retry timeouts and
 * the like.
 */
struct tqhdr EQ_Event_List, EQ_Event_Freelist;

/*************************************************************************
*                                                                       
* FUNCTION                                                              
*                                                                       
*      NU_Events_Dispatcher                                             
*                                                                       
* DESCRIPTION                                                           
*                                                                       
*   This function is responsible for dispatching events from the        
*   event queue to the appropriate handling routines.                   
*                                                                       
* INPUTS                                                                
*                                                                       
*      None.                                                            
*                                                                       
* OUTPUTS                                                               
*                                                                       
*      None.                                                            
*                                                                       
*************************************************************************/
VOID NU_EventsDispatcher(UNSIGNED argc, VOID *argv)
{
#if (INCLUDE_TCP == NU_TRUE)
    TCP_PORT                *prt;
    NET_BUFFER              *buf_ptr;
#endif    
    struct sock_struct      *sock_ptr;    /* Socket pointer. */
    DV_DEVICE_ENTRY         *dev_ptr;
    ICMP_ECHO_LIST_ENTRY    *echo_entry;
    STATUS                  status;
    UNSIGNED                waittime;
    UNSIGNED                current_time;
    INT16                   tmoflag;
    UNSIGNED                event = 0,
                            dat   = 0;
    tqe_t                   *duptqe,
                            *tqe_wait;              /* Timer queue entry */

    /*******************************************************************
       Receive_Message points to a single occurence in the event queue.
       The index 3 signals that the structure is 3 words (or 6 bytes)
       long and is formatted as follows:

       struct
       {
          8 bits: the msg_class
          8 bits: the event
          16 bits: pointer to the next event on the queue
          16 bits: the data field
       }
    *******************************************************************/

    UNSIGNED                Receive_Message[3] = {0, 0, 0};
    UNSIGNED                actual_size;
    NU_SUPERV_USER_VARIABLES

    /* Switch to supervisor mode. */
    NU_SUPERVISOR_MODE();

    tqe_wait = (tqe_t *)0;

    /*  Remove compilation warnings for unused parameters.  */
    UNUSED_PARAMETER(argc);
    UNUSED_PARAMETER(argv);

    for (;;)
    {
        /* Retrieve a message from the event queue.  Note that if the source
           queue is empty this task suspends until something becomes
           available. */
        NU_Obtain_Semaphore(&TCP_Resource, NU_SUSPEND);

        /* If someone is waiting on the timer list, then we need to
           calculate the next hit time for that timer.  */

        if (!tqe_wait)
            tqe_wait = EQ_Event_List.flink;

        if (tqe_wait)
        {
            current_time = NU_Retrieve_Clock();

            /* Account for the wrapping of the clock. */
            if (tqe_wait->duetime > current_time)
                waittime = ((UNSIGNED) tqe_wait->duetime - current_time);
            else
            {
                if( ( current_time - tqe_wait->duetime ) > 0x80000000UL )
                    waittime = 0xFFFFFFFFUL - tqe_wait->duetime + current_time + 1;
                else
                    waittime = NU_NO_SUSPEND;
            }
        }
        else
        {
            tqe_wait = (tqe_t *)0;
            waittime = NU_SUSPEND;
        }

        /* If waittime is not NU_SUSPEND then there is a timeout value. */
        if (waittime != NU_NO_SUSPEND)
        {
            NU_Release_Semaphore(&TCP_Resource);

            status = NU_Receive_From_Queue(&eQueue, &Receive_Message[0],
                                          (UNSIGNED)3, &actual_size, waittime);

            NU_Obtain_Semaphore(&TCP_Resource, NU_SUSPEND);
        }
        else
        {
            NU_Release_Semaphore (&TCP_Resource);

            NU_Relinquish();

            if (tqe_wait == EQ_Event_List.flink)
            {
                NU_Obtain_Semaphore (&TCP_Resource, NU_SUSPEND);
                status = NU_TIMEOUT;
            }
            else
            {
                tqe_wait = (tqe_t *)0;
                continue;
            }
        }

        /* Determine if the message was received successfully.  */
        if (status == NU_TIMEOUT)
        {
            if (tqe_wait == EQ_Event_List.flink)
            {
                /*  Take off the head of the list. */
                DLL_Dequeue(&EQ_Event_List);

                /*  Place any duplicate entries on to the timer list. */
                duptqe = (tqe_t *)DLL_Dequeue(&tqe_wait->duplist);
                while (duptqe)
                {
                    tqpost((tqe_t *) &EQ_Event_List, duptqe);
                    duptqe = (tqe_t *)DLL_Dequeue(&tqe_wait->duplist);
                }

                /*  Place the dequeued entry on the free list. */
                DLL_Enqueue(&EQ_Event_Freelist, tqe_wait);

                tmoflag = 1;

#if (INCLUDE_TCP == NU_TRUE)

                /* Take care of event TCPRETRANS here...other events are
                   handled by the CASE statement below... */

                if (tqe_wait->tqe_event == TCPRETRANS)
                {
                    /*  Get a pointer to the porlist entry.  */
                    prt = TCP_Ports[tqe_wait->tqe_data];

                    TCP_Retransmit (prt, tqe_wait->tqe_ext_data);
                    tqe_wait = (tqe_t *)0;

                    NU_Release_Semaphore(&TCP_Resource);
                    continue;
                }
                else

#endif /* INCLUDE_TCP == NU_TRUE */

                {
                    event = tqe_wait->tqe_event;
                    dat = tqe_wait->tqe_data;
                    tqe_wait = (tqe_t *)0;

                    status = NU_SUCCESS;
                }

            }
            else
            {

                tqe_wait = (tqe_t *)0;

                NU_Release_Semaphore(&TCP_Resource);

                continue;
            }

        } /* end if status == NU_TIMEOUT */
        else
        {
            tmoflag = 0;
            tqe_wait = (tqe_t *)NU_NULL;
        }

        /* Determine if the message was received successfully.  */
        if (status == NU_SUCCESS)
        {
            if (!tmoflag)
            {
                event = Receive_Message[0];
                dat   = Receive_Message[2];
            }

            /* switch on the msg_class/event combination */
            switch (event)
            {
                default:
                    break;

                case CONNULL:
                    break;

                /***********  CONNECTION CLASS  **********************/

#if (INCLUDE_TCP == NU_TRUE)

                case CONFAIL:  /* connection attempt failed */
                case CONOPEN:  /* successful connect attempt */

                    /* Make sure the socket is not NULL, this is possible if a
                       TCP connection is made and immediately RESET by the
                       foreign host. */
                    if ((sock_ptr = SCK_Sockets[dat]) != NU_NULL)
                    {

                        /* return control to the waiting task */
                        if (sock_ptr->s_TXTask != NU_NULL)
                            NU_Resume_Task(sock_ptr->s_TXTask);
                    }

                    break;

                case TCPACK:
                    /* An ack needs to be sent. */

                    /* Get a pointer to the port. */
                    prt = TCP_Ports[dat];

                    /* Clear the ACK timer flag in the port. */
                    prt->portFlags &= (~ACK_TIMER_SET);

                    /* Send the ack. */
                    TCP_ACK_It(prt, 1);

                    break;


                case CONTX:

                    /*  get a pointer into the port list table at the
                        entry pointed to by dat in the event queue */
                    prt = TCP_Ports[dat];

                    if ( (prt->xmitFlag == NU_SET) &&
                        (prt->out.nextPacket != NU_NULL) )
                    {
                        prt->out.tcp_flags |= TPUSH;

                        /* Save a pointer to the next packet to send. Then move
                           the next pointer forward. nextPacket should always
                           be NULL after these steps. */
                        buf_ptr = prt->out.nextPacket;
                        prt->out.nextPacket = prt->out.nextPacket->next;

                        /* Clear the event flag. */
                        prt->xmitFlag = NU_CLEAR;

                        /* Send the buffer. */
                        TCP_Xmit(prt, buf_ptr);
                    }

                    break;

⌨️ 快捷键说明

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