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

📄 sockets.c

📁 基于东南大学开发的SEP3203的ARM7中的所有驱动
💻 C
📖 第 1 页 / 共 5 页
字号:
               /* get the pointer */
                SCK_Sockets[new_sock]->s_accept_list = NU_NULL;

                /* clear the TCP_Ports task id */
                SCK_Sockets[new_sock]->s_TXTask = NU_NULL;
            
                /* A connection has been successfully accpted. */
                return_status = new_sock;
                break;
            }
        }

        /* There are no connections to accept so check to see if the application
           wants to block pending a connection. */
        else if( !(SCK_Sockets[socketd]->s_flags & SF_BLOCK) )
        {
            /* Blocking is not desired so indicate that no connection was made. */
            return_status = NU_NO_TASK_MATCH;
            break;
        }
        else /* no match in task table */
        {
            /* Indicate that this task is accepting connections. */
            task_entry->Task_ID = NU_Current_Task_Pointer();

            /*  Let others in while we are waiting for the connection.  */
            SCK_Suspend_Task(task_entry->Task_ID);

            /* Clear the accept flag. */
            task_entry->Task_ID = NU_NULL;
        }
    }

    /* allow others to use the TCP resource */
    NU_Release_Semaphore(&TCP_Resource);

    /* Switch back to user mode. */
    NU_USER_MODE();

    /* return the new socket descriptor to the server */
    return(return_status);

} /* NU_Accept  */

#endif /* INCLUDE_TCP == NU_TRUE */

#if (INCLUDE_TCP == NU_TRUE)

/*************************************************************************
*                                                                       
*   FUNCTION                                                              
*                                                                       
*       NU_Send                                                          
*                                                                       
*   DESCRIPTION                                                           
*                                                                       
*       This function is responsible for transmitting data across a       
*       network during a connection-oriented transfer.                    
*                                                                       
*   INPUTS                                                                
*                                                                       
*       socketd                                                          
*       *buff                                                             
*       nbytes                                                           
*       flags                                                            
*                                                                       
*   OUTPUTS                                                               
*                                                                       
*       Returns number of bytes sent.                                    
*       NU_INVALID_SOCKET                                                
*       NU_NOT_CONNECTED                                                 
*       NU_NO_ROUTE_TO_HOST
*       NU_CONNECTION_REFUSED 
*       NU_MSG_TOO_LONG
*                                                                       
*************************************************************************/
INT32 NU_Send(INT socketd, CHAR *buff, UINT16 nbytes, INT16 flags)
{
    NET_BUFFER_SUSPENSION_ELEMENT   *waiting_for_buffer;
    INT32   return_status;                  /* initialized to error status */
    struct  sock_struct     *sockptr;
    UINT16  count;                          /* number of bytes written */
    UINT16  bytes_to_go;                    /* number of bytes yet to transmit */
    UINT16  curr_count;                     /* number of bytes written this call */
    INT     status = 0;
    NU_SUPERV_USER_VARIABLES

    /*  Validate the socket number.  */
    if ((socketd < 0) || (socketd >= NSOCKETS) ||
        (SCK_Sockets[socketd] == NU_NULL))
        return(NU_INVALID_SOCKET);

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

    /*  Clean up warnings.  This parameter is used for socket compatibility
        but we are currently not making any use of it.  */
    UNUSED_PARAMETER(flags);

    /*  Don't let anyone else in until we are through.  */
    NU_Obtain_Semaphore(&TCP_Resource, NU_SUSPEND);

    /* Get a pointer to the socket */
    sockptr = SCK_Sockets[socketd];

    /* Check for a NULL socket ptr and a connected socket. */
    if ( sockptr && (sockptr->s_state & SS_ISCONNECTED) )
    {
        /* initialize the byte counters */
        count = 0;
        bytes_to_go = nbytes;

        while ((bytes_to_go > 0))
        {
            /* call tcp/ip library netwrite routine */
            curr_count = (UINT16) TCPSS_Net_Write( sockptr, (UINT8 *)(buff + count), bytes_to_go, 
                                   &status);

            /* If 0 was returned, then for some reason we failed to send the
               data.  Check to see if we failed because we have already
               filled up the window of the remote host.  If so just
               continue.  We will suspend below, and be awakened when the
               remote host acks some of the data we have already sent.  At
               that point some more data can be transmitted.  If we failed
               for any other reason check to see if some data has already
               been sent.  If so return the number of bytes that have
               already been sent.  If no data has been sent (i.e., count ==
               0) then set count equal to the error code so the application
               layer will see the error.
            */
            if (curr_count == 0)
            {
                if ((status != NU_WINDOW_FULL) && (status != NU_NO_BUFFERS))
                {
                    if (count == 0)
                        count = curr_count;
                    break;
                }
            }

            /* update the bytes counter */
            bytes_to_go -= curr_count;

            /* update the total bytes sent */
            count += curr_count;

            /* If the status is NO BUFFERS then we will suspend until
               more buffers become available. */
            if (status == NU_NO_BUFFERS)
            {
                /* Allocate memory for a suspension list element. */
                status = NU_Allocate_Memory (&System_Memory,
                                        (VOID **)&waiting_for_buffer,
                                        sizeof (NET_BUFFER_SUSPENSION_ELEMENT),
                                        NU_NO_SUSPEND);

                /* Make sure we got the memory. */
                if (status == NU_SUCCESS)
                {
                    /* Add this task to the element. */
                    waiting_for_buffer->waiting_task = NU_Current_Task_Pointer();

                    /* Mark this task as suspended on TX. */
                    sockptr->s_TXTask = waiting_for_buffer->waiting_task;

                    /* Put this element on the buffer suspension list */
                    DLL_Enqueue (&MEM_Buffer_Suspension_List, waiting_for_buffer);

                    /* Suspend this task. */
                    SCK_Suspend_Task (waiting_for_buffer->waiting_task);

                    /* Clear it. */
                    sockptr->s_TXTask = NU_NULL;

                    /* Make sure this entry is removed from the list. */
                    DLL_Remove (&MEM_Buffer_Suspension_List, waiting_for_buffer);

                    /* Give the memory back. */
                    NU_Deallocate_Memory (waiting_for_buffer);

                }
                else
                    NERRS_Log_Error (NERR_RECOVERABLE, __FILE__, __LINE__);
            }

            /* If the number of bytes to go indicates more to be sent
               then suspend until there are buffers available. */
            else if (bytes_to_go > 0)
            {

                /* Increment the number of tasks that are waiting for
                    buffers before they can send. */
                tasks_waiting_to_send++;

                sockptr->s_TXTask = NU_Current_Task_Pointer();
                SCK_Suspend_Task(sockptr->s_TXTask);
                sockptr->s_TXTask = NU_NULL;
            } /* still bytes to be sent */

        } /* while still bytes to transmit. */

        /* verify success of transfer, if a code of less than */
        if (status == NU_SUCCESS)
            /* return number of bytes transferred */
            return_status = count;

        /* If the port is not -1 and the value of the icmp_error field of
         * the port is less than zero (an error code) return the error code */
        else if ( (sockptr->s_port_index != NU_IGNORE_VALUE) 
                && (TCP_Ports[sockptr->s_port_index]->icmp_error < 0) )
            return_status = TCP_Ports[sockptr->s_port_index]->icmp_error;

        else
            return_status = status;
    }

    /* If the port is not -1 and the value of the icmp_error field of
     * the port is less than zero (an error code) return the error code */
    else if ( (sockptr->s_port_index != NU_IGNORE_VALUE) 
            && (TCP_Ports[sockptr->s_port_index]->icmp_error < 0) )
        return_status = TCP_Ports[sockptr->s_port_index]->icmp_error;

    /* Either the socket pointer was NULL or the connection has closed. */
    else
        return_status = NU_NOT_CONNECTED;
           
    /* allow others to use the TCP resource */
    NU_Release_Semaphore(&TCP_Resource);
      
    /* Switch back to user mode. */
    NU_USER_MODE();

    /* return to caller */
    return(return_status);

}  /*  end of NU_Send  */

#endif /* INCLUDE_TCP == NU_TRUE */

#if (INCLUDE_UDP == NU_TRUE)
/*************************************************************************
*                                                                       
*   FUNCTION                                                              
*                                                                       
*       NU_Send_To                                                       
*                                                                       
*   DESCRIPTION                                                           
*                                                                       
*       This function is responsible for transmitting data across         
*       a network during a connectionless transfer.                       
*                                                                       
*   INPUTS                                                                
*                                                                       
*       socketd                                                          
*       *buff                                                             
*       nbytes                                                           
*       flags                                                            
*       *to                                                               
*       addrlen                                                          
*                                                                       
*   OUTPUTS                                                               
*                                                                       
*       Number of bytes sent.                                            
*       NU_NO_PORT_NUMBER                                                
*       NU_INVALID_SOCKET                                                
*       NU_INVALID_ADDRESS                                               
*       NU_NO_DATA_TRANSFER                                              
*                                                                       
*************************************************************************/
INT32 NU_Send_To(INT socketd, CHAR *buff, UINT16 nbytes, INT16 flags,
     struct addr_struct *to, INT16 addrlen)
{
    INT32              count;               /* number of bytes written */
    struct uport       *uprt;
    struct sock_struct *sockptr;            /* pointer to current socket */
    INT16   port_num;                         /* local machine's port number */
    INT32   return_status = NU_NO_PORT_NUMBER;  /* initialized to error status */
    UINT16  dest_port;
    NU_SUPERV_USER_VARIABLES

    /*  Validate the socket number.  */
    if ((socketd < 0) || (socketd >= NSOCKETS) ||
                (SCK_Sockets[socketd] == NU_NULL))
        return(NU_INVALID_SOCKET);

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

    /*  Clean up warnings.  This parameter is used for socket compatibility
     *  but we are currently not making any use of it.  */
    UNUSED_PARAMETER(flags);
    UNUSED_PARAMETER(addrlen);

    /* Grab the stack semaphore. */
    NU_Obtain_Semaphore(&TCP_Resource, NU_SUSPEND);

    /* Pick up a pointer to the socket list entry.  */
    sockptr = SCK_Sockets[socketd];

    if (!(sockptr->s_state & SS_DEVICEDOWN))
    {
        /* get the server's port number */
        dest_port = to->port;

        /* verify that a port number exists */
        if (dest_port)

⌨️ 快捷键说明

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