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

📄 tcpss.c

📁 基于nucleus操作系统的GPRS无线数据传输终端全套源文件。包括支持ARM7的BSP,操作系统
💻 C
📖 第 1 页 / 共 4 页
字号:
/*************************************************************************
*                                                                       
*       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 implicitly  
* accepts the terms of the license.                                     
*                                                                       
*************************************************************************/

/* Portions of this program were written by: */
/*************************************************************************
 *                                                                        
 *     part of:                                                           
 *     TCP/IP kernel for NCSA Telnet                                      
 *     by Tim Krauskopf                                                   
 *                                                                        
 *     National Center for Supercomputing Applications                    
 *     152 Computing Applications Building                                
 *     605 E. Springfield Ave.                                            
 *     Champaign, IL  61820                                               
 *
 ************************************************************************/

/*************************************************************************
*                                                                        
*   FILENAME                                           VERSION                     
*                                                                                
*       TCPSS.C                                          4.4                          
*                                                                                
*   DESCRIPTION                                                            
*                                                                        
*       TCP socket services. That is those services that are used by the 
*       sockets layer to manage the TCP.
*                                                                        
*   DATA STRUCTURES                                                        
*
*       NONE
*                                                                        
*   FUNCTIONS                                                              
*                                                                        
*       TCPSS_Do_Connect                                                      
*       TCPSS_Net_Close                                                       
*       TCPSS_Net_Listen                                                      
*       TCPSS_Net_Read                                                        
*       TCPSS_Net_Send                                                        
*       TCPSS_Net_Write                                                       
*       TCPSS_Net_Xopen                                                       
*       TCPSS_Send_SYN_FIN                                                    
*       TCPSS_Window_Probe                                                    
*                                                                        
*   DEPENDENCIES                                                           
*                                                                        
*       nucleus.h                                                             
*       target.h                                                              
*       tcp.h                                                                 
*       tcpdefs.h                                                             
*       socketd.h                                                             
*       externs.h                                                             
*       ip.h
*       netevent.                                                             
*       nerrs.h                                                               
*       arp.h                                                                 
*       net_extr.h                                                            
*                                                                        
************************************************************************/
#include "plus/nucleus.h"
#include "net/target.h"
#include "net/inc/externs.h"
#include "net/inc/ip.h"
#include "net/inc/tcp.h"
#include "net/inc/tcpdefs.h"
#include "net/inc/socketd.h"
#include "net/inc/netevent.h"
#include "net/inc/nerrs.h"
#include "net/inc/arp.h"
#include "net/inc/net_extr.h"

#if (INCLUDE_SNMP == NU_TRUE)
#include SNMP_GLUE
#endif

extern NU_TASK           NU_EventsDispatcher_ptr;
extern NU_TASK           timer_task_ptr;

#if (INCLUDE_TCP == NU_TRUE)

/* Local Prototypes. */
static STATUS  TCPSS_Net_Send(TCP_PORT *, NET_BUFFER *);
static STATUS  TCPSS_Do_Connect(INT pnum, UINT16 service);
static INT32   TCPSS_Window_Probe(TCP_PORT *, UINT16, UINT8 HUGE *);

/*************************************************************************
*                                                                       
*   FUNCTION                                                              
*                                                                       
*       TCPSS_Net_Read 
*                                                                       
*   DESCRIPTION                                                           
*                                                                       
*       Read data from the connection buffer (specified by *pnum*) into 
*       the user buffer for up to *n* bytes.                              
*       Returns number of bytes read, or <0 if error.  Does not block.    
*                                                                       
*   INPUTS                                                                
*                                                                       
*       *sock_ptr                                                        
*       *buffer                                                          
*       nbytes                                                           
*                                                                       
*   OUTPUTS                                                               
*                                                                       
*       The number of bytes read or 0 if an error occurs.
*                                                                       
*************************************************************************/
INT32 TCPSS_Net_Read(struct sock_struct *sock_ptr, char *buffer, UINT16 nbytes)
{
    INT32           i, lowwater;
    INT32           howmany;
    INT             pnum;
    TCP_PORT        *prt;

    /* As long as there is data return it.  It is possible for the connection to
       have been closed in the event of a RESET.  However, if the data is here
       then it has been validated and is acceptable. So the data will be given to
       the application even if the connection has been closed.
    */

    if (sock_ptr->s_recvbytes > 0)
    {
        /* Retrieve the queue data. */
        howmany = TLS_Dequeue(sock_ptr, buffer, (UINT32)nbytes);

        if (sock_ptr->s_state & SS_ISCONNECTED)
        {
            /* Get the look up the index of the port structure. */
            if ((pnum = sock_ptr->s_port_index) >= 0)
            {
                prt = TCP_Ports[pnum];

                i = prt->in.size;                   /* how much before? */
                prt->in.size += howmany;            /* increment leftover room  */

                lowwater = (prt->credit >> 1);

                if ((i < lowwater) && ((prt->in.size) >= lowwater))
                    TCP_ACK_It(prt, 1);
            }
            else
            {
                howmany = NU_NOT_CONNECTED;
            }
        }
    }
    else
    {
        /* There was no queued data to receive. So, check to see if the
           connection still exists. */
        if (sock_ptr->s_state & SS_ISCONNECTED)
            howmany = 0;
        else
            howmany = NU_NOT_CONNECTED;
    }

    return (howmany);

} /* end TCPSS_Net_Read() */

/*************************************************************************
*                                                                       
*   FUNCTION                                                             
*                                                                       
*       TCPSS_Net_Write                                                  
*                                                                       
*   DESCRIPTION                                                          
*                                                                       
*       Write data into the output queue (specified by pnum).            
*       As long as there is buffer space and the foreign host's receive  
*       window has not been filled, data will be sent.  The number of 
*       bytes actually sent is returned ( a number between 0 and nbytes).
*                                                                       
*   INPUTS                                                               
*
*       *sockptr        Pointer to a socket on which to send the data.   
*       *buffer         Pointer to the data to be sent.                  
*       nbytes          The number of bytes of data to send.             
*       *status         Indicates why all data could not be sent.        
*                                                                       
*   OUTPUTS                                                              
*                                                                       
*       The number of bytes that were sent.                              
*                                                                       
*************************************************************************/
INT32 TCPSS_Net_Write(struct sock_struct *sockptr, UINT8 HUGE *buffer, UINT16 nbytes,
               INT *status)
{
    INT         nsent=0, s, temp_len;
    INT32       sent_by_wp=0;
    TCP_PORT    *prt;
    TCP_WINDOW  *wind;
    NET_BUFFER  *buf_ptr, *work_buf;
    INT32       bytes_to_move;
    INT32       numbytes, bytes_left, bc;
    INT         pnum;

    /* Assume a successful operation until we are proven wrong. */
    *status = NU_SUCCESS;

    if ((pnum = sockptr->s_port_index) < 0)
    {
        *status = NU_INVALID_PORT;
        return(0);
    }

    if((prt = TCP_Ports[pnum]) == NU_NULL)
    {
        *status = NU_INVALID_PORT;
        return(0);
    }

    /* must be established connection */
    if((prt->state != SEST) && (prt->state != SCWAIT))
    {
        *status = NU_NOT_CONNECTED;
        return(0);
    }

    wind = &prt->out;

    numbytes = nbytes;


    /*  Find out what their advertised window size is.  If we want to
        send more bytes than they are advertising, then decrease the
        amount of bytes we want to send. */
    if ((wind->size - wind->contain) < numbytes)
    {
        numbytes = (wind->size - wind->contain);
    }

    if (numbytes <= 0)
    {
        /* Check to see if a window probe is needed.  A probe is only needed if
           the foreign port has advertised a window of 0 and there is no
           unacknowledged data. */
        if ( (wind->size == 0) && (wind->nxt == wind->ack) )
        {
            if ((sent_by_wp=TCPSS_Window_Probe(prt, nbytes, buffer)) == NU_NOT_ESTAB)
            {
                *status = NU_NOT_CONNECTED;
                return(0);
            }

            /* Advance the buffer pointer beyond the data that has already been
               sent. */
            buffer += sent_by_wp;

            numbytes = nbytes - sent_by_wp;
            if (numbytes > (wind->size - wind->contain))
                numbytes = wind->size - wind->contain;
        }
        else
        {
            *status = NU_WINDOW_FULL;
            return(0);
        }
    }

    /* Are there any packets that contain data but have not yet been sent.
       Should never be more than one of these. */
    if (wind->nextPacket != NU_NULL)
    {

        /* Get a pointer to the start of the buffer chain. */
        buf_ptr = wind->nextPacket;

        /* Calculate the amount of data to be put into this buffer chain. */
        bytes_to_move = (numbytes < (UINT16)(MAX_SEGMENT_LEN - buf_ptr->mem_total_data_len))
            ?  numbytes : (MAX_SEGMENT_LEN - buf_ptr->mem_total_data_len);

        bytes_left = bytes_to_move;

        /* Find the end of this buffer chain. */
        for ( work_buf = buf_ptr; 
              work_buf->next_buffer != NU_NULL; 
              work_buf = work_buf->next_buffer);

        if (work_buf == wind->nextPacket)
        {
            /* How much data should be added to this buffer. */
            bc = (NET_PARENT_BUFFER_SIZE - NET_MAX_TCP_HEADER_SIZE) 
                   - work_buf->data_len;

            bc = (bytes_left < bc) ? bytes_left : bc;
        }
        else
        {
            /* How much data should be added to this buffer. */
            bc = NET_MAX_BUFFER_SIZE - work_buf->data_len;
            bc = (bytes_left < bc) ? bytes_left : bc;
        }

        NU_BLOCK_COPY (work_buf->data_ptr + work_buf->data_len, buffer, (unsigned int)bc);
        work_buf->data_len += bc;

        /* Bump up the total count for this buffer chain. */
        buf_ptr->mem_total_data_len += bc;

        bytes_left -= bc;
        buffer += bc;

        while (bytes_left)
        {
            /* Make sure there are enough buffers left before we take 
               another one. We must leave some for RX. */
            if ((MAX_BUFFERS - MEM_Buffers_Used) <= NET_FREE_BUFFER_THRESHOLD)
            {
                /* Set the counter to reflect that we could not complete
                   sending all the data. */
                bytes_to_move -= bytes_left;

                /* Set bytes_left to zero so we can get out of this loop. */
                bytes_left = 0;
    
                /* Set the status. */
                *status = NU_NO_BUFFERS;

                continue;
            }

            work_buf->next_buffer = MEM_Buffer_Dequeue (&MEM_Buffer_Freelist);
            
            work_buf = work_buf->next_buffer;

            bc = (bytes_left < NET_MAX_BUFFER_SIZE) ?
                    bytes_left : NET_MAX_BUFFER_SIZE;

            /* Copy the data. */
            NU_BLOCK_COPY (work_buf->mem_packet, buffer, (unsigned int)bc);

            /* Set the data pointer. */
            work_buf->data_ptr = work_buf->mem_packet;

⌨️ 快捷键说明

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