diff options
Diffstat (limited to 'cfe/cfe/net/net_tcpbuf.c')
-rw-r--r-- | cfe/cfe/net/net_tcpbuf.c | 298 |
1 files changed, 298 insertions, 0 deletions
diff --git a/cfe/cfe/net/net_tcpbuf.c b/cfe/cfe/net/net_tcpbuf.c new file mode 100644 index 0000000..08e690b --- /dev/null +++ b/cfe/cfe/net/net_tcpbuf.c @@ -0,0 +1,298 @@ +/* ********************************************************************* + * Broadcom Common Firmware Environment (CFE) + * + * TCP Protocol File: net_tcp.c + * + * This file contains a very simple TCP. + * + * Author: Mitch Lichtenberg (mpl@broadcom.com) + * + ********************************************************************* + * + * Copyright 2000,2001,2002,2003 + * Broadcom Corporation. All rights reserved. + * + * This software is furnished under license and may be used and + * copied only in accordance with the following terms and + * conditions. Subject to these conditions, you may download, + * copy, install, use, modify and distribute modified or unmodified + * copies of this software in source and/or binary form. No title + * or ownership is transferred hereby. + * + * 1) Any source code used, modified or distributed must reproduce + * and retain this copyright notice and list of conditions + * as they appear in the source file. + * + * 2) No right is granted to use any trade name, trademark, or + * logo of Broadcom Corporation. The "Broadcom Corporation" + * name may not be used to endorse or promote products derived + * from this software without the prior written permission of + * Broadcom Corporation. + * + * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR + * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED + * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR + * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT + * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN + * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY + * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR + * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF + * THE POSSIBILITY OF SUCH DAMAGE. + ********************************************************************* */ + + +#include "lib_types.h" +#include "lib_string.h" +#include "lib_queue.h" +#include "lib_malloc.h" +#include "lib_printf.h" + +#include "cfe_error.h" + +#include "net_tcpbuf.h" + + + +/* ********************************************************************* + * tmb_init(buf) + * + * Initialize a modulo buffer's pointers to the "empty" state + * + * Input parameters: + * buf - modulo buffer structure + * + * Return value: + * nothing + ********************************************************************* */ + +void tmb_init(tcpmodbuf_t *buf) +{ + buf->tmb_addptr = 0; + buf->tmb_remptr = 0; + buf->tmb_len = 0; +} + +/* ********************************************************************* + * tmb_adjust(buf,amt) + * + * Move the "remove" pointer ahead by 'amt' without retrieving the + * data. + * + * Input parameters: + * buf - modulo buffer structure + * amt - number of bytes to move + * + * Return value: + * nothing + ********************************************************************* */ + + +void tmb_adjust(tcpmodbuf_t *buf,int amt) +{ + /* XXX should we check for moving to far? */ + buf->tmb_len -= amt; + buf->tmb_remptr = (buf->tmb_remptr + amt) % buf->tmb_bufsize; +} + +/* ********************************************************************* + * tmb_alloc(buf,size) + * + * Allocate memory for the modulo buffer. + * + * Input parameters: + * buf - modulo buffer structure + * size - size of data in modulo buffer + * + * Return value: + * 0 if ok + * -1 if error + ********************************************************************* */ + +int tmb_alloc(tcpmodbuf_t *buf,int size) +{ + buf->tmb_buf = KMALLOC(size,0); + if (!buf->tmb_buf) return -1; + buf->tmb_bufsize = size; + + tmb_init(buf); + + return 0; +} + +/* ********************************************************************* + * tmb_free(buf) + * + * Free memory associated with the modulo buffer + * + * Input parameters: + * buf - modulo buffer + * + * Return value: + * nothing + ********************************************************************* */ + +void tmb_free(tcpmodbuf_t *buf) +{ + if (buf->tmb_buf) KFREE(buf->tmb_buf); + buf->tmb_buf = NULL; +} + + +/* ********************************************************************* + * tmb_copyin(tmb,buf,len,update) + * + * Copy data into the modulo buffer at the 'add' pointer + * + * Input parameters: + * tmb - modulo buffer structure + * buf,len - buffer and length of buffer to copy in + * update - true to advance 'add' pointer (usually true for copyin) + * + * Return value: + * number of bytes actually added to the buffer + ********************************************************************* */ + +int tmb_copyin(tcpmodbuf_t *tmb,uint8_t *buf,int len,int update) +{ + int maxlen; + int l; + int newptr; + int retlen; + + if (len == 0) return 0; + + /* Set 'maxlen' to the max # of bytes we will send now */ + maxlen = tmb->tmb_bufsize - tmb->tmb_len; + if (maxlen > len) maxlen = len; + + retlen = maxlen; /* we'll return this later. */ + + /* Copy the bytes into the buffer and deal with buffer wrap */ + l = tmb->tmb_bufsize - tmb->tmb_addptr; + if (l > maxlen) l = maxlen; + + memcpy(tmb->tmb_buf + tmb->tmb_addptr,buf,l); + maxlen -= l; + buf += l; + + if (maxlen) { + memcpy(tmb->tmb_buf,buf,maxlen); + newptr = maxlen; + } + else { + newptr = tmb->tmb_addptr + l; + } + + if (update) { + tmb->tmb_len += retlen; /* this many more in the buffer */ + tmb->tmb_addptr = newptr; + } + + return retlen; +} + +/* ********************************************************************* + * tmb_copyout(tmb,buf,len,update) + * + * Copy data out of the modulo buffer from the 'remove' pointer + * + * Input parameters: + * tmb - modulo buffer structure + * buf,len - buffer and length of buffer to copy out + * update - true to advance 'remove' pointer + * + * Return value: + * number of bytes actually removed from the buffer + ********************************************************************* */ + +int tmb_copyout(tcpmodbuf_t *tmb,uint8_t *buf,int len,int update) +{ + int maxlen; + int l; + int newptr; + int retlen; + + /* Compute how many bytes to return */ + maxlen = tmb->tmb_len; + if (maxlen > len) maxlen = len; + + retlen = maxlen; + + l = tmb->tmb_bufsize - tmb->tmb_remptr; + if (l > maxlen) l = maxlen; + + memcpy(buf,tmb->tmb_buf + tmb->tmb_remptr,l); + buf += l; + maxlen -= l; + + if (maxlen) { + memcpy(buf,tmb->tmb_buf,maxlen); + newptr = maxlen; + } + else { + newptr = tmb->tmb_remptr + l; + } + + if (update) { + tmb->tmb_len -= retlen; + tmb->tmb_remptr = newptr; + } + + return retlen; +} + +/* ********************************************************************* + * tmb_copyout2(tmb,buf,offset,len) + * + * Copy data out of the modulo buffer from a specific offset from + * the remove pointer. This is done without updating the + * remove pointer - we use this to dig data out when segmenting + * packets for transmission. + * + * Input parameters: + * tmb - modulo buffer structure + * buf,len - buffer and length of buffer to copy out + * offset - offset from remove pointer to start + * + * Return value: + * number of bytes actually copied out of the buffer + ********************************************************************* */ + +int tmb_copyout2(tcpmodbuf_t *tmb,uint8_t *buf,int offset,int len) +{ + int maxlen; + int l; + int retlen; + int remptr; + + /* Compute how many bytes to return */ + maxlen = tmb->tmb_len - offset; + + /* if offset is beyond length, get out now. */ + if (maxlen <= 0) return 0; + + /* otherwise choose min(max_can_copy,max_to_copy) */ + if (maxlen > len) maxlen = len; + retlen = maxlen; + + /* Adjust remove pointer for offset */ + remptr = (tmb->tmb_remptr + offset) % tmb->tmb_bufsize; + + l = tmb->tmb_bufsize - remptr; + if (l > maxlen) l = maxlen; + + memcpy(buf,tmb->tmb_buf + remptr,l); + buf += l; + maxlen -= l; + + if (maxlen) { + memcpy(buf,tmb->tmb_buf,maxlen); + } + + return retlen; +} + |