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:
tass
Date:
Fri May 17 12:09:59 2013 +0000
Revision:
1:cfe8984a32b4
Parent:
libraries/picotcp/stack/pico_frame.c@0:d7f2341ab245
Update for smaller SOCKETQ

Who changed what in which revision?

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