X-Git-Url: https://oss.titaniummirror.com/gitweb/?a=blobdiff_plain;f=support%2Fsdk%2Fc%2Fblip%2Flibtcp%2Fcirc.c;h=cd91d8e4b648b10569924bfca26d8cad3f9b504b;hb=3d5c78e867d6fd52e44894e93e4bd0c172071522;hp=de8bff1fcc412379b9fde43302af13ef352edde6;hpb=34dda4f22e2b435b6ddec072706809f158e60c7f;p=tinyos-2.x.git diff --git a/support/sdk/c/blip/libtcp/circ.c b/support/sdk/c/blip/libtcp/circ.c index de8bff1f..cd91d8e4 100644 --- a/support/sdk/c/blip/libtcp/circ.c +++ b/support/sdk/c/blip/libtcp/circ.c @@ -1,125 +1,73 @@ +/* + * "Copyright (c) 2008, 2009 The Regents of the University of California. + * All rights reserved." + * + * Permission to use, copy, modify, and distribute this software and its + * documentation for any purpose, without fee, and without written agreement is + * hereby granted, provided that the above copyright notice, the following + * two paragraphs and the author appear in all copies of this software. + * + * IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT + * OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF + * CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + * THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, + * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + * AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS." + * + */ #include #include -// #include #include #include "tcplib.h" struct circ_buf { - uint8_t *map; - uint16_t map_len; uint8_t *data_start; uint8_t *data_head; uint16_t data_len; uint32_t head_seqno; }; -int circ_buf_init(void *data, int len, uint32_t seqno, int incl_map) { +int circ_buf_init(void *data, int len, uint32_t seqno) { struct circ_buf *b = (struct circ_buf *)data; - int bitmap_len = ((len - sizeof(struct circ_buf)) / 9); - // int data_len = bitmap_len * 8; - - // printf("circ_buf_init: len: %i data_len: %i bitmap_len: %i\n", len, data_len, bitmap_len); - // assert(bitmap_len + data_len + sizeof(struct circ_buf) <= len); if (len < sizeof(struct circ_buf)) return -1; - if (incl_map) { - b->map = (uint8_t *)(b + 1); - b->map_len = bitmap_len; - b->data_start = b->map + bitmap_len; - b->data_len= bitmap_len * 8; - memset(b->map, 0, bitmap_len * 9); - } else { - b->map = NULL; - b->map_len = 0; - b->data_start = (uint8_t *)(b + 1); - b->data_len = len - sizeof(struct circ_buf); - memset(b->data_start, 0, b->data_len); - } - b->data_head = b->data_start; + b->data_head = b->data_start = (uint8_t *)(b + 1); + b->data_len = len - sizeof(struct circ_buf); b->head_seqno = seqno; - - // printf("circ_buf_init: buf: %p data_start: %p data_head: %p data_len: %i\n", - // b, b->data_start, b->data_head, b->data_len); - return 0; } -#define BIT_SET(off,map) map[(off)/8] |= (1 << (7 - ((off) % 8))) -#define BIT_UNSET(off,map) map[(off)/8] &= ~(1 << (7 - ((off) % 8))) -#define BIT_ISSET(off, map) map[(off)/8] & 1 << (7 - (off) % 8) - -static void bitmap_mark(struct circ_buf *b, uint8_t *data, int len) { - int offset = data - b->data_start; - if (b->map_len == 0) return; - while (len-- > 0) { - BIT_SET(offset, b->map); - offset = (offset + 1) % b->data_len; - } -} - -/* return the sequence number of the first byte of data in the buffer; - this is what the stack can ACK. */ uint32_t circ_get_seqno(void *buf) { struct circ_buf *b = (struct circ_buf *)buf; return b->head_seqno; } -void circ_set_seqno(void *buf, uint32_t seqno) { - struct circ_buf *b = (struct circ_buf *)buf; - b->head_seqno = seqno; -} - -uint16_t circ_get_window(void *buf) { - struct circ_buf *b = (struct circ_buf *)buf; - return b->data_len; -} - -/* read as many contiguous bytes from the head of the buffer as - * possible, and update the internal data structures to shorten the - * buffer - * - * buf: the circular buffer - * data: a pointer which will be updated with the location of the data - * return: the number of bytes available - */ -int circ_buf_read_head(void *buf, char **data) { - struct circ_buf *b = (struct circ_buf *)buf; - int off = b->data_head - b->data_start; - int rlen = 0; - *data = b->data_head; - while (BIT_ISSET(off, b->map) && off < b->data_len) { - BIT_UNSET(off, b->map); - rlen++; - b->head_seqno++; - b->data_head ++; - if (b->data_head == b->data_start + b->data_len) - b->data_head = b->data_start; - off++; - } - return rlen; -} - - static void get_ptr_off_1(struct circ_buf *b, uint32_t sseqno, int len, uint8_t **writeptr, int *w_len) { uint8_t *endptr = b->data_start + b->data_len; int offset; *writeptr = NULL; - *w_len = 0; + *w_len = len; /* write up to either the end of the buffer */ offset = sseqno - b->head_seqno; if (b->data_head + offset < endptr) { - *w_len = len; *writeptr = b->data_head + offset; - if (*writeptr + *w_len > endptr) { - *w_len = endptr - *writeptr; - } + } else { + offset -= (endptr - b->data_head); + *writeptr = b->data_start + offset; + } + if (*writeptr + *w_len > endptr) { + *w_len = endptr - *writeptr; } } @@ -128,8 +76,8 @@ int circ_shorten_head(void *buf, uint32_t seqno) { int offset = seqno - b->head_seqno; b->head_seqno = seqno; - b->data_head += offset; + while (b->data_head > b->data_start + b->data_len) b->data_head -= b->data_len; @@ -156,64 +104,44 @@ int circ_buf_read(void *buf, uint32_t sseqno, return rc; } -int circ_buf_write(void *buf, uint32_t sseqno, +int circ_buf_write(char *buf, uint32_t sseqno, uint8_t *data, int len) { struct circ_buf *b = (struct circ_buf *)buf; uint8_t *writeptr; int w_len; - /* we can't write any bytes since we're trying to write too far ahead */ - // printf("circ_buf_write: sseqno: %i head_seqno: %i len: %i\n", - // sseqno, b->head_seqno, len); - if (sseqno > b->head_seqno + b->data_len) return -1; - - if (sseqno < b->head_seqno) { - /* old data, but already received */ - if (sseqno < b->head_seqno - len) return -1; - /* a segment which overlaps with data we've already received */ - data += (b->head_seqno - sseqno); - len -= (b->head_seqno - sseqno); - sseqno = b->head_seqno; - } if (len == 0) return 0; - // printf("circ_buf_write: buf: %p data_start: %p data_head: %p data_len: %i\n", - // b, b->data_start, b->data_head, b->data_len); get_ptr_off_1(b, sseqno, len, &writeptr, &w_len); + memcpy(writeptr, data, w_len); data += w_len; - bitmap_mark(b, writeptr, w_len); if (w_len != len) { writeptr = b->data_start; w_len = min(len - w_len, b->data_head - b->data_start); memcpy(writeptr, data, w_len); - bitmap_mark(b, writeptr, w_len); - // printf("circ_buf_write (2): write: %p len: %i\n", writeptr, w_len); } + return 0; } #ifdef PC void circ_buf_dump(void *buf) { struct circ_buf *b = (struct circ_buf *)buf; + uint8_t *d; int i; /* printf("circ buf: %p\n\tmap: %p\n\tmap_len: %i\n\tdata_start: %p\n\t" */ /* "data_head: %p\n\tdata_len: %i\n\thead_seqno: %i\n", */ /* b, b->map, */ /* b->map_len, b->data_start, b->data_head, b->data_len, b->head_seqno); */ - - for (i = 1; i <= b->data_len; i++) { - if (BIT_ISSET(i-1, b->map)) - putc('x',stdout); - else - putc('_',stdout); - if (i % 80 == 0 || i == b->data_len) { - putc('\n',stdout); - } + for (d = b->data_start; d < b->data_start + b->data_len; d++) { + if (d == b->data_head) putc('|', stdout); + printf("%2.x ", *d); } + putc('\n', stdout); } #endif