Free (GPLv2) TCP/IP stack developed by TASS Belgium

Dependents:   lpc1768-picotcp-demo ZeroMQ_PicoTCP_Publisher_demo TCPSocket_HelloWorld_PicoTCP Pico_TCP_UDP_Test ... more

PicoTCP. Copyright (c) 2013 TASS Belgium NV.

Released under the GNU General Public License, version 2.

Different licensing models may exist, at the sole discretion of the Copyright holders.

Official homepage: http://www.picotcp.com

Bug tracker: https://github.com/tass-belgium/picotcp/issues

Development steps:

  • initial integration with mbed RTOS
  • generic mbed Ethernet driver
  • high performance NXP LPC1768 specific Ethernet driver
  • Multi-threading support for mbed RTOS
  • Berkeley sockets and integration with the New Socket API
  • Fork of the apps running on top of the New Socket API
  • Scheduling optimizations
  • Debugging/benchmarking/testing

Demo application (measuring TCP sender performance):

Import programlpc1768-picotcp-demo

A PicoTCP demo app testing the ethernet throughput on the lpc1768 mbed board.

Committer:
daniele
Date:
Thu Jun 06 00:38:54 2013 +0000
Revision:
10:dd7111d4279f
Child:
45:ca30069e49bb
Update from masterbranch;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
daniele 10:dd7111d4279f 1 /*********************************************************************
daniele 10:dd7111d4279f 2 PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
daniele 10:dd7111d4279f 3 See LICENSE and COPYING for usage.
daniele 10:dd7111d4279f 4
daniele 10:dd7111d4279f 5 .
daniele 10:dd7111d4279f 6
daniele 10:dd7111d4279f 7 Authors: Daniele Lacamera
daniele 10:dd7111d4279f 8 *********************************************************************/
daniele 10:dd7111d4279f 9
daniele 10:dd7111d4279f 10
daniele 10:dd7111d4279f 11 #include "pico_config.h"
daniele 10:dd7111d4279f 12 #include "pico_frame.h"
daniele 10:dd7111d4279f 13
daniele 10:dd7111d4279f 14 #ifdef PICO_SUPPORT_DEBUG_MEMORY
daniele 10:dd7111d4279f 15 static int n_frames_allocated;
daniele 10:dd7111d4279f 16 #endif
daniele 10:dd7111d4279f 17
daniele 10:dd7111d4279f 18 /** frame alloc/dealloc/copy **/
daniele 10:dd7111d4279f 19 void pico_frame_discard(struct pico_frame *f)
daniele 10:dd7111d4279f 20 {
daniele 10:dd7111d4279f 21 (*f->usage_count)--;
daniele 10:dd7111d4279f 22 if (*f->usage_count <= 0) {
daniele 10:dd7111d4279f 23 pico_free(f->usage_count);
daniele 10:dd7111d4279f 24 #ifdef PICO_SUPPORT_DEBUG_MEMORY
daniele 10:dd7111d4279f 25 dbg("Discarded buffer @%p, caller: %p\n", f->buffer, __builtin_return_address(3));
daniele 10:dd7111d4279f 26 dbg("DEBUG MEMORY: %d frames in use.\n", --n_frames_allocated);
daniele 10:dd7111d4279f 27 #endif
daniele 10:dd7111d4279f 28 pico_free(f->buffer);
daniele 10:dd7111d4279f 29 if (f->info)
daniele 10:dd7111d4279f 30 pico_free(f->info);
daniele 10:dd7111d4279f 31 }
daniele 10:dd7111d4279f 32 #ifdef PICO_SUPPORT_DEBUG_MEMORY
daniele 10:dd7111d4279f 33 else {
daniele 10:dd7111d4279f 34 dbg("Removed frame @%p(copy), usage count now: %d\n", f, *f->usage_count);
daniele 10:dd7111d4279f 35 }
daniele 10:dd7111d4279f 36 #endif
daniele 10:dd7111d4279f 37 pico_free(f);
daniele 10:dd7111d4279f 38 }
daniele 10:dd7111d4279f 39
daniele 10:dd7111d4279f 40 struct pico_frame *pico_frame_copy(struct pico_frame *f)
daniele 10:dd7111d4279f 41 {
daniele 10:dd7111d4279f 42 struct pico_frame *new = pico_zalloc(sizeof(struct pico_frame));
daniele 10:dd7111d4279f 43 if (!new)
daniele 10:dd7111d4279f 44 return NULL;
daniele 10:dd7111d4279f 45 memcpy(new, f, sizeof(struct pico_frame));
daniele 10:dd7111d4279f 46 *(new->usage_count) += 1;
daniele 10:dd7111d4279f 47 #ifdef PICO_SUPPORT_DEBUG_MEMORY
daniele 10:dd7111d4279f 48 dbg("Copied frame @%p, into %p, usage count now: %d\n", f, new, *new->usage_count);
daniele 10:dd7111d4279f 49 #endif
daniele 10:dd7111d4279f 50 new->next = NULL;
daniele 10:dd7111d4279f 51 return new;
daniele 10:dd7111d4279f 52 }
daniele 10:dd7111d4279f 53
daniele 10:dd7111d4279f 54
daniele 10:dd7111d4279f 55 struct pico_frame *pico_frame_alloc(int size)
daniele 10:dd7111d4279f 56 {
daniele 10:dd7111d4279f 57 struct pico_frame *p = pico_zalloc(sizeof(struct pico_frame));
daniele 10:dd7111d4279f 58 if (!p)
daniele 10:dd7111d4279f 59 return NULL;
daniele 10:dd7111d4279f 60 p->buffer = pico_zalloc(size);
daniele 10:dd7111d4279f 61 if (!p->buffer) {
daniele 10:dd7111d4279f 62 pico_free(p);
daniele 10:dd7111d4279f 63 return NULL;
daniele 10:dd7111d4279f 64 }
daniele 10:dd7111d4279f 65 p->usage_count = pico_zalloc(sizeof(uint32_t));
daniele 10:dd7111d4279f 66 if (!p->usage_count) {
daniele 10:dd7111d4279f 67 pico_free(p->buffer);
daniele 10:dd7111d4279f 68 pico_free(p);
daniele 10:dd7111d4279f 69 return NULL;
daniele 10:dd7111d4279f 70 }
daniele 10:dd7111d4279f 71 p->buffer_len = size;
daniele 10:dd7111d4279f 72
daniele 10:dd7111d4279f 73
daniele 10:dd7111d4279f 74 /* By default, frame content is the full buffer. */
daniele 10:dd7111d4279f 75 p->start = p->buffer;
daniele 10:dd7111d4279f 76 p->len = p->buffer_len;
daniele 10:dd7111d4279f 77 *p->usage_count = 1;
daniele 10:dd7111d4279f 78 #ifdef PICO_SUPPORT_DEBUG_MEMORY
daniele 10:dd7111d4279f 79 dbg("Allocated buffer @%p, len= %d caller: %p\n", p->buffer, p->buffer_len, __builtin_return_address(2));
daniele 10:dd7111d4279f 80 dbg("DEBUG MEMORY: %d frames in use.\n", ++n_frames_allocated);
daniele 10:dd7111d4279f 81 #endif
daniele 10:dd7111d4279f 82 return p;
daniele 10:dd7111d4279f 83 }
daniele 10:dd7111d4279f 84
daniele 10:dd7111d4279f 85 struct pico_frame *pico_frame_deepcopy(struct pico_frame *f)
daniele 10:dd7111d4279f 86 {
daniele 10:dd7111d4279f 87 struct pico_frame *new = pico_frame_alloc(f->buffer_len);
daniele 10:dd7111d4279f 88 int addr_diff;
daniele 10:dd7111d4279f 89 unsigned char *buf;
daniele 10:dd7111d4279f 90 uint32_t *uc;
daniele 10:dd7111d4279f 91 if (!new)
daniele 10:dd7111d4279f 92 return NULL;
daniele 10:dd7111d4279f 93
daniele 10:dd7111d4279f 94 /* Save the two key pointers... */
daniele 10:dd7111d4279f 95 buf = new->buffer;
daniele 10:dd7111d4279f 96 uc = new->usage_count;
daniele 10:dd7111d4279f 97
daniele 10:dd7111d4279f 98 /* Overwrite all fields with originals */
daniele 10:dd7111d4279f 99 memcpy(new, f, sizeof(struct pico_frame));
daniele 10:dd7111d4279f 100
daniele 10:dd7111d4279f 101 /* ...restore the two key pointers */
daniele 10:dd7111d4279f 102 new->buffer = buf;
daniele 10:dd7111d4279f 103 new->usage_count = uc;
daniele 10:dd7111d4279f 104
daniele 10:dd7111d4279f 105 /* Update in-buffer pointers with offset */
daniele 10:dd7111d4279f 106 addr_diff = (int)new->buffer - (int)f->buffer;
daniele 10:dd7111d4279f 107 new->net_hdr += addr_diff;
daniele 10:dd7111d4279f 108 new->transport_hdr += addr_diff;
daniele 10:dd7111d4279f 109 new->app_hdr += addr_diff;
daniele 10:dd7111d4279f 110 new->start += addr_diff;
daniele 10:dd7111d4279f 111 new->payload += addr_diff;
daniele 10:dd7111d4279f 112
daniele 10:dd7111d4279f 113 #ifdef PICO_SUPPORT_DEBUG_MEMORY
daniele 10:dd7111d4279f 114 dbg("Deep-Copied frame @%p, into %p, usage count now: %d\n", f, new, *new->usage_count);
daniele 10:dd7111d4279f 115 #endif
daniele 10:dd7111d4279f 116 new->next = NULL;
daniele 10:dd7111d4279f 117 return new;
daniele 10:dd7111d4279f 118 }
daniele 10:dd7111d4279f 119
daniele 10:dd7111d4279f 120 /**
daniele 10:dd7111d4279f 121 * Calculate checksum of a given string
daniele 10:dd7111d4279f 122 */
daniele 10:dd7111d4279f 123 uint16_t pico_checksum(void *inbuf, int len)
daniele 10:dd7111d4279f 124 {
daniele 10:dd7111d4279f 125 uint8_t *buf = (uint8_t *) inbuf;
daniele 10:dd7111d4279f 126 uint16_t tmp = 0;
daniele 10:dd7111d4279f 127 uint32_t sum = 0, carry=0;
daniele 10:dd7111d4279f 128 int i=0;
daniele 10:dd7111d4279f 129 for(i=0; i<len; i++){
daniele 10:dd7111d4279f 130 if (i%2){
daniele 10:dd7111d4279f 131 sum+=buf[i];
daniele 10:dd7111d4279f 132 }else{
daniele 10:dd7111d4279f 133 tmp = buf[i];
daniele 10:dd7111d4279f 134 sum+=( tmp << 8);
daniele 10:dd7111d4279f 135 }
daniele 10:dd7111d4279f 136 }
daniele 10:dd7111d4279f 137 carry = (sum&0xFFFF0000) >>16;
daniele 10:dd7111d4279f 138 sum = (sum&0x0000FFFF);
daniele 10:dd7111d4279f 139 return (uint16_t) ~(sum + carry) ;
daniele 10:dd7111d4279f 140 }
daniele 10:dd7111d4279f 141
daniele 10:dd7111d4279f 142 uint16_t pico_dualbuffer_checksum(void *inbuf1, int len1, void *inbuf2, int len2)
daniele 10:dd7111d4279f 143 {
daniele 10:dd7111d4279f 144 uint8_t *b1 = (uint8_t *) inbuf1;
daniele 10:dd7111d4279f 145 uint8_t *b2 = (uint8_t *) inbuf2;
daniele 10:dd7111d4279f 146 uint16_t tmp = 0;
daniele 10:dd7111d4279f 147 uint32_t sum = 0, carry=0;
daniele 10:dd7111d4279f 148 int i=0, j=0;
daniele 10:dd7111d4279f 149 for(i=0; i<len1; i++){
daniele 10:dd7111d4279f 150 if (j%2){
daniele 10:dd7111d4279f 151 sum+=b1[i];
daniele 10:dd7111d4279f 152 }else{
daniele 10:dd7111d4279f 153 tmp = b1[i];
daniele 10:dd7111d4279f 154 sum+=( tmp << 8);
daniele 10:dd7111d4279f 155 }
daniele 10:dd7111d4279f 156 j++;
daniele 10:dd7111d4279f 157 }
daniele 10:dd7111d4279f 158
daniele 10:dd7111d4279f 159 for(i=0; i<len2; i++){
daniele 10:dd7111d4279f 160 if (j%2){
daniele 10:dd7111d4279f 161 sum+=b2[i];
daniele 10:dd7111d4279f 162 }else{
daniele 10:dd7111d4279f 163 tmp = b2[i];
daniele 10:dd7111d4279f 164 sum+=( tmp << 8);
daniele 10:dd7111d4279f 165 }
daniele 10:dd7111d4279f 166 j++;
daniele 10:dd7111d4279f 167 }
daniele 10:dd7111d4279f 168 carry = (sum&0xFFFF0000) >>16;
daniele 10:dd7111d4279f 169 sum = (sum&0x0000FFFF);
daniele 10:dd7111d4279f 170 return (uint16_t) (~(sum + carry)) ;
daniele 10:dd7111d4279f 171 }
daniele 10:dd7111d4279f 172
daniele 10:dd7111d4279f 173 uint16_t pico_dualbuffer_checksum_broken(void *inbuf1, int len1, void *inbuf2, int len2)
daniele 10:dd7111d4279f 174 {
daniele 10:dd7111d4279f 175 uint16_t *b1 = (uint16_t *) inbuf1;
daniele 10:dd7111d4279f 176 uint16_t *b2 = (uint16_t *) inbuf2;
daniele 10:dd7111d4279f 177 uint32_t sum = 0;
daniele 10:dd7111d4279f 178 int i=0, j=0;
daniele 10:dd7111d4279f 179 for(i=0; i<(len1>>1); i++){
daniele 10:dd7111d4279f 180 sum += short_be(b1[i]);
daniele 10:dd7111d4279f 181 j++;
daniele 10:dd7111d4279f 182 }
daniele 10:dd7111d4279f 183 for(i=0; i<(len2>>1); i++){
daniele 10:dd7111d4279f 184 sum += short_be(b2[i]);
daniele 10:dd7111d4279f 185 j++;
daniele 10:dd7111d4279f 186 }
daniele 10:dd7111d4279f 187 sum = (sum & 0xFFFF) + (sum >> 16);
daniele 10:dd7111d4279f 188 sum += (sum >> 16);
daniele 10:dd7111d4279f 189
daniele 10:dd7111d4279f 190 // Take the bitwise complement of sum
daniele 10:dd7111d4279f 191 sum = ~sum;
daniele 10:dd7111d4279f 192 return (uint16_t) (sum) ;
daniele 10:dd7111d4279f 193 }
daniele 10:dd7111d4279f 194
daniele 10:dd7111d4279f 195