📄 tools.c
字号:
/*************************************************************************
*
* 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.
*
*************************************************************************/
/*************************************************************************
*
* FILENAME
*
* TOOLS.C
*
* DESCRIPTION
*
* This file contains misc. "tools" used by the networking stack.
* An example of such tools are enqueueing and dequeueing
* operations. Aso, all source code for the PUT/GET macros used to
* access packet data is contained in this module.
*
* DATA STRUCTURES
*
* None
*
* FUNCTIONS
*
* TLS_Dequeue
* TLS_Enqueue
* TLS_Normalize_Ptr
* TLS_Rmqueue
* TLS_Put_Event
* TLS_Get32
* TLS_Put32
* TLS_Get16
* TLS_Put16
* TLS_IP_Address
* TLS_Put_String
* TLS_Get_String
* TLS_Eq_String
* TLS_IP_Check
* TLS_TCP_Check
* TLS_Longswap
* TLS_Intswap
* TLS_Comparen
* TLS_IP_Check_Buffer_Chain
*
* DEPENDENCIES
*
* nucleus.h
* target.h
* externs.h
* rtab.h
* net_extr.h
* socketd.h
* tcpdefs.h
* nerrs.h
* tcp.h
* dos.h
*
*************************************************************************/
#include "plus/nucleus.h"
#include "net/target.h"
#include "net/inc/externs.h"
#include "net/inc/rtab.h"
#include "net/inc/net_extr.h"
#include "net/inc/socketd.h"
#include "net/inc/tcpdefs.h"
#include "net/inc/nerrs.h"
#include "net/inc/tcp.h"
#ifdef NORM_PTR
#include <dos.h>
#endif
/* The only purpose of this variable is to facilitate the removal of warnings. */
UINT32 TLS_Unused_Parameter;
#if (INCLUDE_TCP == NU_TRUE)
/*************************************************************************
*
* FUNCTION
*
* TLS_Enqueue
*
* DESCRIPTION
*
* Add a packet to a TCP queue. Used by both 'write()' and
* TCP_Interpret(). WINDOWSIZE is the size limitation of the
* advertised window.
*
* INPUTS
*
* *sock_ptr
*
* OUTPUTS
*
* UINT16 The size of the packet enqueued
*
************************************************************************/
UINT16 TLS_Enqueue (struct sock_struct *sock_ptr)
{
NET_BUFFER *item_ptr;
NET_BUFFER *dest = sock_ptr->s_recvlist.tail;
NET_BUFFER *src = MEM_Buffer_List.head;
/* This first check is an optimization that attempts to merge the data
received in small packets. It is not intended to concatenate all
received data, but only relatively small packets that are received
contiguously. First check to see if a packet was received prior to
the current one (dest). Check to see if the current packet is a
relatively small one (total_data_len < 50). Finally check to make sure that
the current packet will fit within the first buffer of the chain in
which the previous packet was stored. All of these checks guarantee
that we will not waste a lot of time moving data around, rather
packets will be merged only when the benefits are great relative to
the work that must be done. */
if ( dest && (dest->next_buffer == NU_NULL) &&
(src->mem_total_data_len < 50) &&
((dest->mem_total_data_len + src->mem_total_data_len +
(dest->data_ptr - dest->mem_parent_packet)) <= NET_PARENT_BUFFER_SIZE) )
{
/* Copy the data in the current packet to the previous one. */
MEM_Chain_Copy(dest, src, 0, (INT32)src->mem_total_data_len);
/* Update the length. */
dest->mem_total_data_len += src->mem_total_data_len;
/* Free the current packet. */
item_ptr = MEM_Update_Buffer_Lists(&MEM_Buffer_List, &MEM_Buffer_Freelist);
}
else
{
/* It was not possible to merge the data. So, remove the whole packet from
the buffer_list and place it in the socket's receive list. */
item_ptr = MEM_Update_Buffer_Lists(&MEM_Buffer_List, &sock_ptr->s_recvlist);
sock_ptr->s_recvpackets++;
}
/* Increment the number of bytes this socket contains. */
sock_ptr->s_recvbytes += item_ptr->mem_total_data_len;
return ((UINT16) item_ptr->mem_total_data_len);
} /* TLS_Enqueue */
#endif /* INCLUDE_TCP == NU_TRUE */
#if (INCLUDE_TCP == NU_TRUE)
/*************************************************************************
*
* FUNCTION
*
* TLS_Dequeue
*
* DESCRIPTION
*
* Used by netread, this copies data out of the queue and then
* deallocates it from the queue.
* rmqueue is very similar and is to be used by tcpsend
* to store unacknowledged data.
*
* Returns the number of bytes removed from the queue.
*
* INPUTS
*
* *sock_ptr
* *buffer
* nbytes
*
* OUTPUTS
*
* actual_bytes The number of bytes removed from the queue
* 0
*
************************************************************************/
INT32 TLS_Dequeue (struct sock_struct *sock_ptr, char * buffer, UINT32 nbytes)
{
INT32 actual_bytes;
NET_BUFFER *buf_ptr, *work_ptr;
UINT32 bytes_copied, offset = 0;
/* If there is no data in the window, return. */
if ((sock_ptr->s_recvbytes == 0) || (sock_ptr->s_recvlist.head == NU_NULL))
return(0);
/* If we don't have as much data as the user wants then give him what
* we have. */
if ((sock_ptr->s_recvbytes) < nbytes)
nbytes = sock_ptr->s_recvbytes;
/* because nbytes has its value changed below, actual_bytes is used
* to preserve the number that will be returned.
*/
actual_bytes = nbytes;
/* While there is more data to be moved and buffers exist from which to
* move it, continue.
*/
while ( (nbytes) && (sock_ptr->s_recvlist.head != NU_NULL) )
{
bytes_copied = 0;
/* Check to see if the current packet buffer contains more than
* enough data. If it does, then simply move the data and update
* the data structures. If it doesn't then all data in the current
* buffer is moved, and that buffer is deallocated.
*/
if (sock_ptr->s_recvlist.head->mem_total_data_len > nbytes)
{
/* Move the data into the caller's buffer, copy it from the
buffer chain. */
/* Get a pointer to the data */
buf_ptr = sock_ptr->s_recvlist.head;
/* Is there more than enough data in the parent buffer. If
so then copy what is needed. */
if (buf_ptr->data_len >= nbytes)
{
/* Copy only what is requested. */
NU_BLOCK_COPY((UINT8 HUGE*)buffer + offset, buf_ptr->data_ptr, (unsigned int)nbytes);
/* Update the bytes copied. */
bytes_copied = nbytes;
/* Update what is in this buffer and in the chain. */
buf_ptr->data_ptr += nbytes;
buf_ptr->data_len -= nbytes;
buf_ptr->mem_total_data_len -= nbytes;
}
/* Is there any data in this buffer? */
else if (buf_ptr->data_len > 0)
{
/* Copy all of it */
NU_BLOCK_COPY ((UINT8 HUGE*)buffer + offset, buf_ptr->data_ptr,
(unsigned int)buf_ptr->data_len);
/* Update the offset to copy more data too and the
number of bytes just copied. */
offset += buf_ptr->data_len;
bytes_copied += buf_ptr->data_len;
/* Update what is in this buffer and in the chain. */
buf_ptr->mem_total_data_len -= buf_ptr->data_len;
buf_ptr->data_len = 0;
}
/* Get a work pointer. */
work_ptr = buf_ptr;
/* Loop through the chain if needed and copy all buffers. */
while ((work_ptr->next_buffer != NU_NULL) &&
(bytes_copied < nbytes))
{
/* Move to the next buffer in the chain */
work_ptr = work_ptr->next_buffer;
/* Is there more than enough data in the buffer. If
so then copy what is needed. */
if (work_ptr->data_len >= (nbytes - bytes_copied))
{
/* Copy only what is requested. */
NU_BLOCK_COPY((UINT8 HUGE*)buffer + offset, work_ptr->data_ptr,
(unsigned int)(nbytes - bytes_copied));
/* Update what is in this buffer and in the chain. */
work_ptr->data_ptr += (nbytes - bytes_copied);
work_ptr->data_len -= (nbytes - bytes_copied);
buf_ptr->mem_total_data_len -= (nbytes - bytes_copied);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -