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 Belgium NV
Date:
Mon Dec 16 11:25:54 2013 +0100
Revision:
131:4758606c9316
Parent:
128:ae39e6e81531
Child:
133:5b075f5e141a
Syncronized with master branch

Who changed what in which revision?

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