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:
Thu Dec 05 08:31:32 2013 +0000
Revision:
128:ae39e6e81531
Parent:
123:dd26752a4538
Child:
131:4758606c9316
updated repo to work with uint64 tick.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tass 123:dd26752a4538 1 /*********************************************************************
tass 123:dd26752a4538 2 PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
tass 123:dd26752a4538 3 See LICENSE and COPYING for usage.
tass 123:dd26752a4538 4
tass 123:dd26752a4538 5 Authors: Bogdan Lupu
tass 123:dd26752a4538 6 *********************************************************************/
tass 123:dd26752a4538 7 #include "pico_slaacv4.h"
tass 123:dd26752a4538 8 #include "pico_arp.h"
tass 123:dd26752a4538 9 #include "pico_constants.h"
tass 123:dd26752a4538 10 #include "pico_stack.h"
tass 123:dd26752a4538 11
tass 123:dd26752a4538 12 #ifdef PICO_SUPPORT_SLAACV4
tass 123:dd26752a4538 13
tass 123:dd26752a4538 14 #define SLAACV4_ADDRESS 0xa9fe0000
tass 123:dd26752a4538 15 #define SLAACV4_MASK 0x0000FFFF
tass 123:dd26752a4538 16 #define SLAACV4_MINRANGE 0x00000100
tass 123:dd26752a4538 17 #define SLAACV4_MAXRANGE 0x0000FD00
tass 123:dd26752a4538 18
tass 123:dd26752a4538 19 #define SLAACV4_CREATE_IPV4(seed) (((seed % SLAACV4_MAXRANGE ) + SLAACV4_MINRANGE) & SLAACV4_MASK) | SLAACV4_ADDRESS
tass 123:dd26752a4538 20
tass 123:dd26752a4538 21 #define PROBE_WAIT 1 // delay between two tries during claim
tass 123:dd26752a4538 22 #define PROBE_NB 3 // number of probe packets during claim
tass 123:dd26752a4538 23 //#define PROBE_MIN 1
tass 123:dd26752a4538 24 //#define PROBE_MAX 2
tass 123:dd26752a4538 25 #define ANNOUNCE_WAIT 2 // delay before start announcing
tass 123:dd26752a4538 26 #define ANNOUNCE_NB 2 // number of announcement packets
tass 123:dd26752a4538 27 #define ANNOUNCE_INTERVAL 2 // time between announcement packets
tass 123:dd26752a4538 28 #define MAX_CONFLICTS 10 // max conflicts before rate limiting
tass 123:dd26752a4538 29 #define RATE_LIMIT_INTERVAL 60 // time between successive attempts
tass 123:dd26752a4538 30 #define DEFEND_INTERVAL 10 // minimum interval between defensive ARP
tass 123:dd26752a4538 31
tass 123:dd26752a4538 32 enum slaacv4_state{
tass 123:dd26752a4538 33 SLAACV4_RESET = 0,
tass 123:dd26752a4538 34 SLAACV4_CLAIMING,
tass 123:dd26752a4538 35 SLAACV4_CLAIMED,
tass 123:dd26752a4538 36 SLAACV4_ANNOUNCING,
tass 123:dd26752a4538 37 SLAACV4_ERROR
tass 123:dd26752a4538 38 };
tass 123:dd26752a4538 39
tass 123:dd26752a4538 40 struct slaacv4_cookie{
tass 123:dd26752a4538 41 uint8_t state;
tass 123:dd26752a4538 42 uint8_t probe_try_nb;
tass 123:dd26752a4538 43 uint8_t conflict_nb;
tass 123:dd26752a4538 44 uint8_t announce_nb;
tass 123:dd26752a4538 45 struct pico_ip4 ip;
tass 123:dd26752a4538 46 struct pico_device *device;
tass 123:dd26752a4538 47 struct pico_timer *timer;
tass 123:dd26752a4538 48 void (*cb)(struct pico_ip4 *ip, uint8_t code);
tass 123:dd26752a4538 49 };
tass 123:dd26752a4538 50
tass 123:dd26752a4538 51 static struct slaacv4_cookie slaacv4_local;
tass 123:dd26752a4538 52
tass 123:dd26752a4538 53 static uint32_t pico_slaacv4_getip(struct pico_device *dev, uint8_t rand)
tass 123:dd26752a4538 54 {
tass 123:dd26752a4538 55 uint32_t seed = 0;
tass 123:dd26752a4538 56 if (dev->eth != NULL)
tass 123:dd26752a4538 57 {
tass 123:dd26752a4538 58 seed = pico_hash((const char *)dev->eth->mac.addr);
tass 123:dd26752a4538 59 }
tass 123:dd26752a4538 60 if (rand)
tass 123:dd26752a4538 61 {
tass 123:dd26752a4538 62 seed += pico_rand();
tass 123:dd26752a4538 63 }
tass 123:dd26752a4538 64 return SLAACV4_CREATE_IPV4(seed);
tass 123:dd26752a4538 65 }
tass 123:dd26752a4538 66
tass 123:dd26752a4538 67 static void pico_slaacv4_init_cookie(struct pico_ip4 *ip, struct pico_device *dev, struct slaacv4_cookie *ck, void (*cb)(struct pico_ip4 *ip, uint8_t code))
tass 123:dd26752a4538 68 {
tass 123:dd26752a4538 69 ck->state = SLAACV4_RESET;
tass 123:dd26752a4538 70 ck->probe_try_nb = 0;
tass 123:dd26752a4538 71 ck->conflict_nb = 0;
tass 123:dd26752a4538 72 ck->announce_nb = 0;
tass 123:dd26752a4538 73 ck->cb = cb;
tass 123:dd26752a4538 74 ck->device = dev;
tass 123:dd26752a4538 75 ck->ip.addr = ip->addr;
tass 123:dd26752a4538 76 ck->timer = NULL;
tass 123:dd26752a4538 77 }
tass 123:dd26752a4538 78
tass 123:dd26752a4538 79 static void pico_slaacv4_cancel_timers(struct slaacv4_cookie *tmp)
tass 123:dd26752a4538 80 {
tass 123:dd26752a4538 81 pico_timer_cancel(tmp->timer);
tass 123:dd26752a4538 82
tass 123:dd26752a4538 83 tmp->timer = NULL;
tass 123:dd26752a4538 84 }
tass 123:dd26752a4538 85
tass 128:ae39e6e81531 86 static void pico_slaacv4_send_announce_timer(pico_time __attribute__((unused)) now, void *arg)
tass 123:dd26752a4538 87 {
tass 123:dd26752a4538 88 struct slaacv4_cookie *tmp = (struct slaacv4_cookie *)arg;
tass 123:dd26752a4538 89 struct pico_ip4 netmask = {.addr = 0x0000FFFF};
tass 123:dd26752a4538 90
tass 123:dd26752a4538 91 if (tmp->announce_nb < ANNOUNCE_NB)
tass 123:dd26752a4538 92 {
tass 123:dd26752a4538 93 pico_arp_request(tmp->device, &tmp->ip, PICO_ARP_ANNOUNCE);
tass 123:dd26752a4538 94 tmp->announce_nb++;
tass 123:dd26752a4538 95 tmp->timer = pico_timer_add(ANNOUNCE_INTERVAL*1000,pico_slaacv4_send_announce_timer, arg);
tass 123:dd26752a4538 96 }
tass 123:dd26752a4538 97 else
tass 123:dd26752a4538 98 {
tass 123:dd26752a4538 99 tmp->state = SLAACV4_CLAIMED;
tass 123:dd26752a4538 100 pico_ipv4_link_add(tmp->device, tmp->ip, netmask);
tass 123:dd26752a4538 101 if (tmp->cb != NULL)
tass 123:dd26752a4538 102 tmp->cb(&tmp->ip, PICO_SLAACV4_SUCCESS);
tass 123:dd26752a4538 103 }
tass 123:dd26752a4538 104 }
tass 123:dd26752a4538 105
tass 128:ae39e6e81531 106 static void pico_slaacv4_send_probe_timer(pico_time __attribute__((unused)) now, void *arg)
tass 123:dd26752a4538 107 {
tass 123:dd26752a4538 108
tass 123:dd26752a4538 109 struct slaacv4_cookie *tmp = (struct slaacv4_cookie *)arg;
tass 123:dd26752a4538 110
tass 123:dd26752a4538 111 if (tmp->probe_try_nb < PROBE_NB)
tass 123:dd26752a4538 112 {
tass 123:dd26752a4538 113 pico_arp_request(tmp->device, &tmp->ip, PICO_ARP_PROBE);
tass 123:dd26752a4538 114 tmp->probe_try_nb++;
tass 123:dd26752a4538 115 tmp->timer = pico_timer_add(PROBE_WAIT * 1000, pico_slaacv4_send_probe_timer, tmp);
tass 123:dd26752a4538 116 }
tass 123:dd26752a4538 117 else
tass 123:dd26752a4538 118 {
tass 123:dd26752a4538 119 tmp->state = SLAACV4_ANNOUNCING;
tass 123:dd26752a4538 120 tmp->timer = pico_timer_add(ANNOUNCE_WAIT*1000,pico_slaacv4_send_announce_timer, arg);
tass 123:dd26752a4538 121 }
tass 123:dd26752a4538 122 }
tass 123:dd26752a4538 123
tass 123:dd26752a4538 124
tass 123:dd26752a4538 125
tass 123:dd26752a4538 126 static void pico_slaacv4_receive_ipconflict(void)
tass 123:dd26752a4538 127 {
tass 123:dd26752a4538 128 struct slaacv4_cookie *tmp = &slaacv4_local;
tass 123:dd26752a4538 129
tass 123:dd26752a4538 130 tmp->conflict_nb++;
tass 123:dd26752a4538 131 pico_slaacv4_cancel_timers(tmp);
tass 123:dd26752a4538 132
tass 123:dd26752a4538 133 if(tmp->state == SLAACV4_CLAIMED)
tass 123:dd26752a4538 134 {
tass 123:dd26752a4538 135 pico_ipv4_link_del(tmp->device,tmp->ip);
tass 123:dd26752a4538 136 }
tass 123:dd26752a4538 137
tass 123:dd26752a4538 138 if (tmp->conflict_nb < MAX_CONFLICTS)
tass 123:dd26752a4538 139 {
tass 123:dd26752a4538 140 tmp->state = SLAACV4_CLAIMING;
tass 123:dd26752a4538 141 tmp->probe_try_nb = 0;
tass 123:dd26752a4538 142 tmp->announce_nb = 0;
tass 123:dd26752a4538 143 tmp->ip.addr = long_be(pico_slaacv4_getip(tmp->device, (uint8_t)1));
tass 123:dd26752a4538 144 pico_arp_register_ipconflict(&tmp->ip, &tmp->device->eth->mac, pico_slaacv4_receive_ipconflict);
tass 123:dd26752a4538 145 pico_arp_request(tmp->device, &tmp->ip, PICO_ARP_PROBE);
tass 123:dd26752a4538 146 tmp->probe_try_nb++;
tass 123:dd26752a4538 147 tmp->timer = pico_timer_add(PROBE_WAIT * 1000, pico_slaacv4_send_probe_timer, tmp);
tass 123:dd26752a4538 148 }
tass 123:dd26752a4538 149 else
tass 123:dd26752a4538 150 {
tass 123:dd26752a4538 151 if (tmp->cb != NULL)
tass 123:dd26752a4538 152 {
tass 123:dd26752a4538 153 tmp->cb(&tmp->ip, PICO_SLAACV4_ERROR);
tass 123:dd26752a4538 154 }
tass 123:dd26752a4538 155 tmp->state = SLAACV4_ERROR;
tass 123:dd26752a4538 156 }
tass 123:dd26752a4538 157
tass 123:dd26752a4538 158 }
tass 123:dd26752a4538 159
tass 123:dd26752a4538 160 uint8_t pico_slaacv4_claimip(struct pico_device *dev, void (*cb)(struct pico_ip4 *ip, uint8_t code))
tass 123:dd26752a4538 161 {
tass 123:dd26752a4538 162 struct pico_ip4 ip;
tass 123:dd26752a4538 163
tass 123:dd26752a4538 164 ip.addr = long_be(pico_slaacv4_getip(dev, 0));
tass 123:dd26752a4538 165
tass 123:dd26752a4538 166 pico_slaacv4_init_cookie(&ip, dev, &slaacv4_local, cb);
tass 123:dd26752a4538 167 pico_arp_register_ipconflict(&ip, &dev->eth->mac, pico_slaacv4_receive_ipconflict);
tass 123:dd26752a4538 168 pico_arp_request(dev, &ip, PICO_ARP_PROBE);
tass 123:dd26752a4538 169 slaacv4_local.state = SLAACV4_CLAIMING;
tass 123:dd26752a4538 170 slaacv4_local.probe_try_nb++;
tass 123:dd26752a4538 171 slaacv4_local.timer = pico_timer_add(PROBE_WAIT * 1000, pico_slaacv4_send_probe_timer, &slaacv4_local);
tass 123:dd26752a4538 172
tass 123:dd26752a4538 173 return 0;
tass 123:dd26752a4538 174 }
tass 123:dd26752a4538 175
tass 123:dd26752a4538 176 void pico_slaacv4_unregisterip(void)
tass 123:dd26752a4538 177 {
tass 123:dd26752a4538 178 struct slaacv4_cookie *tmp = &slaacv4_local;
tass 123:dd26752a4538 179 struct pico_ip4 empty = { .addr = 0x00000000 };
tass 123:dd26752a4538 180
tass 123:dd26752a4538 181 if (tmp->state == SLAACV4_CLAIMED)
tass 123:dd26752a4538 182 {
tass 123:dd26752a4538 183 pico_ipv4_link_del(tmp->device,tmp->ip);
tass 123:dd26752a4538 184 }
tass 123:dd26752a4538 185
tass 123:dd26752a4538 186 pico_slaacv4_cancel_timers(tmp);
tass 123:dd26752a4538 187 pico_slaacv4_init_cookie(&empty, NULL, tmp, NULL);
tass 123:dd26752a4538 188 pico_arp_register_ipconflict(&tmp->ip, NULL, NULL);
tass 123:dd26752a4538 189
tass 123:dd26752a4538 190 }
tass 123:dd26752a4538 191
tass 123:dd26752a4538 192 #endif