📄 tools.c
字号:
/* Update the bytes copied. */
offset += (nbytes - bytes_copied);
bytes_copied += (nbytes - bytes_copied);
}
/* Is there any data in this buffer? */
else if (work_ptr->data_len > 0)
{
/* Copy all of it */
NU_BLOCK_COPY ((UINT8 HUGE*)buffer + offset, work_ptr->data_ptr,
(unsigned int)work_ptr->data_len);
/* Update the offset to copy more data too and the
number of bytes just copied. */
offset += work_ptr->data_len;
bytes_copied += work_ptr->data_len;
/* Update what is in this buffer and in the chain. */
buf_ptr->mem_total_data_len -= work_ptr->data_len;
work_ptr->data_len = 0;
}
} /* end while there are buffers in the chain */
/* Update the number of bytes in the window. */
sock_ptr->s_recvbytes -= nbytes;
/* Indicate that the caller's buffer has been filled. */
nbytes = 0;
}
else /* there is not enough data in this buffer */
{
/* 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;
/* If there is data in the parent buffer then copy it. */
if (buf_ptr->data_len)
{
/* Do the parent buffer first */
NU_BLOCK_COPY((UINT8 HUGE*)buffer + offset, buf_ptr->data_ptr,
(unsigned int)buf_ptr->data_len);
/* Update the bytes copied. */
bytes_copied = buf_ptr->data_len;
}
else
bytes_copied = 0;
/* Loop through the chain if needed and copy all buffers. */
while (buf_ptr->next_buffer != NU_NULL)
{
/* Move to the next buffer in the chain */
buf_ptr = buf_ptr->next_buffer;
/* If there is data in this buffer then copy it. */
if (buf_ptr->data_len)
{
/* Copy the data */
NU_BLOCK_COPY((UINT8 HUGE*)buffer + offset + bytes_copied, buf_ptr->data_ptr,
(unsigned int)buf_ptr->data_len);
/* Update the bytes copied. */
bytes_copied += buf_ptr->data_len;
}
} /* end while there are buffers in the chain */
/* Update the number of bytes left before the caller's request
* has been filled. */
nbytes -= sock_ptr->s_recvlist.head->mem_total_data_len;
/* Update the number of bytes in the window. */
sock_ptr->s_recvbytes -= sock_ptr->s_recvlist.head->mem_total_data_len;
/* Update the number of packets that are in the window. */
sock_ptr->s_recvpackets--;
offset += (INT16) sock_ptr->s_recvlist.head->mem_total_data_len;
/* Put the empty buffer back onto the free list. */
MEM_Buffer_Chain_Free (&sock_ptr->s_recvlist,
&MEM_Buffer_Freelist);
}
}
return(actual_bytes);
} /* end TLS_Dequeue */
#endif /* INCLUDE_TCP == NU_TRUE */
#if (INCLUDE_TCP == NU_TRUE)
/*************************************************************************
*
* FUNCTION
*
* TLS_Rmqueue
*
* DESCRIPTION
*
* Does the queue deallocation once an ack is received.
* rmqueue of WINDOWSIZE or greater bytes will empty the queue
*
* INPUTS
*
* *wind
* acked
*
* OUTPUTS
*
* bytes_removed
*
************************************************************************/
UINT16 TLS_Rmqueue (TCP_WINDOW *wind, INT32 acked)
{
UINT16 bytes_removed = 0;
NET_BUFFER *buf_ptr;
INT old_level;
/* Disable interrupts while we access the receive buffer queue. */
old_level = NU_Local_Control_Interrupts (NU_DISABLE_INTERRUPTS);
buf_ptr = wind->packet_list.head;
while(buf_ptr)
{
/* If the current packet was acknowledged and the current packet is not
* the next one to be transmitted, then remove it. The sequence number
* for the next packet to be transmitted has not yet been filled in and
* there for contains an arbitrary number that maay be less than the
* received ack. */
if( (INT32_CMP(acked, (buf_ptr->mem_seqnum+(INT32)buf_ptr->mem_tcp_data_len)) >= 0) &&
(buf_ptr != wind->nextPacket) )
{
/* Update the number of bytes removed so far. */
bytes_removed = (UINT16)(bytes_removed + buf_ptr->mem_tcp_data_len);
/* Update the number of bytes contained in this window. */
wind->contain -= buf_ptr->mem_tcp_data_len;
/* Update the number of packets contained in this window. */
wind->num_packets--;
/* Look at the next buffer. */
buf_ptr = (NET_BUFFER *)buf_ptr->next;
/* Place the acknowledged buffer back on the free list. */
MEM_Buffer_Chain_Free (&wind->packet_list, &MEM_Buffer_Freelist);
}
else
break;
}
/* Restore to previous level. */
NU_Local_Control_Interrupts (old_level);
/* Return the number of bytes removed. */
return (bytes_removed);
} /* end TLS_Rmqueue */
#endif /* INCLUDE_TCP == NU_TRUE */
/*************************************************************************
*
* FUNCTION
*
* TLS_Put_Event
*
* DESCRIPTION
*
* Add an event to the queue.
* Will probably get the memory for the entry from the free list.
* Returns 0 if there was room, 1 if an event was lost.
*
* INPUTS
*
* event
* dat
*
* OUTPUTS
*
* NU_SUCCESS
* 1
*
************************************************************************/
STATUS TLS_Put_Event (UINT16 event, UNSIGNED dat)
{
STATUS status;
STATUS return_status;
/* Send_Message points to a single structure to be placed 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 Send_Message[3];
/* Send a message to the event queue. Note that if
the queue is full this task suspends until space
becomes available. */
Send_Message[0] = (UNSIGNED) event;
Send_Message[1] = (UNSIGNED) NU_NULL;
Send_Message[2] = (UNSIGNED) dat;
status = NU_Send_To_Queue(&eQueue, &Send_Message[0], (UNSIGNED)3,
(UNSIGNED)NU_NO_SUSPEND);
/* Determine if the message was sent successfully. */
if (status == NU_SUCCESS)
return_status = NU_SUCCESS;
else
return_status = 1;
return (return_status);
} /* TL_Put_Event */
/*************************************************************************
*
* FUNCTION
*
* TLS_Normalize_Ptr
*
* DESCRIPTION
*
* This function takes a pointer for segmented memory architectures
* like the 80386 in real mode and normalizes that pointer. It
* is not necessary on a flat memory model architecture.
*
* INPUTS
*
* *ptr
*
* OUTPUTS
*
* ptr
*
************************************************************************/
void *TLS_Normalize_Ptr(void *ptr)
{
#ifdef NORM_PTR
unsigned long temp_address;
temp_address = FP_SEG(ptr);
temp_address = (temp_address << 4) + FP_OFF(ptr);
FP_SEG(ptr) = (UINT16)(temp_address >> 4);
FP_OFF(ptr) = (UINT16)(temp_address & 0xf);
#endif /* NORM_PTR */
return (ptr);
}
/*************************************************************************
*
* FUNCTION
*
* TLS_Get32
*
* DESCRIPTION
*
* This function takes a memory area and an offset into the area. At
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -