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 Jan 28 15:12:00 2016 +0100
Revision:
155:a70f34550c34
Parent:
154:6c0e92a80c4a
Adding TCP flag for FIN.

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tass 123:dd26752a4538 1 /*********************************************************************
tass 152:a3d286bf94e5 2 PicoTCP. Copyright (c) 2012-2015 Altran Intelligent Systems. 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 152:a3d286bf94e5 14 #define SLAACV4_NETWORK ((long_be(0xa9fe0000)))
tass 152:a3d286bf94e5 15 #define SLAACV4_NETMASK ((long_be(0xFFFF0000)))
tass 152:a3d286bf94e5 16 #define SLAACV4_MINRANGE (0x00000100) /* In host order */
tass 152:a3d286bf94e5 17 #define SLAACV4_MAXRANGE (0x0000FDFF) /* In host order */
tass 123:dd26752a4538 18
tass 152:a3d286bf94e5 19 #define SLAACV4_CREATE_IPV4(seed) ((long_be((seed % SLAACV4_MAXRANGE) + SLAACV4_MINRANGE) & ~SLAACV4_NETMASK) | SLAACV4_NETWORK)
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 picotcp@tass.be 149:5f4cb161cec3 41 enum slaacv4_state 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 picotcp@tass.be 133:5b075f5e141a 58 seed = pico_hash((const uint8_t *)dev->eth->mac.addr, PICO_SIZE_ETH);
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 picotcp@tass.be 149:5f4cb161cec3 88 static void pico_slaacv4_send_announce_timer(pico_time now, void *arg)
tass 123:dd26752a4538 89 {
TASS Belgium NV 131:4758606c9316 90 struct slaacv4_cookie *tmp = (struct slaacv4_cookie *)arg;
tass 154:6c0e92a80c4a 91 struct pico_ip4 netmask = { 0 };
tass 154:6c0e92a80c4a 92 netmask.addr = long_be(0xFFFF0000);
tass 154:6c0e92a80c4a 93
tass picotcp@tass.be 149:5f4cb161cec3 94 (void)now;
tass 123:dd26752a4538 95
TASS Belgium NV 131:4758606c9316 96 if (tmp->announce_nb < ANNOUNCE_NB)
TASS Belgium NV 131:4758606c9316 97 {
TASS Belgium NV 131:4758606c9316 98 pico_arp_request(tmp->device, &tmp->ip, PICO_ARP_ANNOUNCE);
TASS Belgium NV 131:4758606c9316 99 tmp->announce_nb++;
TASS Belgium NV 131:4758606c9316 100 tmp->timer = pico_timer_add(ANNOUNCE_INTERVAL * 1000, pico_slaacv4_send_announce_timer, arg);
TASS Belgium NV 131:4758606c9316 101 }
TASS Belgium NV 131:4758606c9316 102 else
TASS Belgium NV 131:4758606c9316 103 {
TASS Belgium NV 131:4758606c9316 104 tmp->state = SLAACV4_CLAIMED;
TASS Belgium NV 131:4758606c9316 105 pico_ipv4_link_add(tmp->device, tmp->ip, netmask);
TASS Belgium NV 131:4758606c9316 106 if (tmp->cb != NULL)
TASS Belgium NV 131:4758606c9316 107 tmp->cb(&tmp->ip, PICO_SLAACV4_SUCCESS);
TASS Belgium NV 131:4758606c9316 108 }
tass 123:dd26752a4538 109 }
tass 123:dd26752a4538 110
tass picotcp@tass.be 149:5f4cb161cec3 111 static void pico_slaacv4_send_probe_timer(pico_time now, void *arg)
tass 123:dd26752a4538 112 {
TASS Belgium NV 131:4758606c9316 113 struct slaacv4_cookie *tmp = (struct slaacv4_cookie *)arg;
tass picotcp@tass.be 149:5f4cb161cec3 114 (void)now;
tass 123:dd26752a4538 115
TASS Belgium NV 131:4758606c9316 116 if (tmp->probe_try_nb < PROBE_NB)
TASS Belgium NV 131:4758606c9316 117 {
TASS Belgium NV 131:4758606c9316 118 pico_arp_request(tmp->device, &tmp->ip, PICO_ARP_PROBE);
TASS Belgium NV 131:4758606c9316 119 tmp->probe_try_nb++;
TASS Belgium NV 131:4758606c9316 120 tmp->timer = pico_timer_add(PROBE_WAIT * 1000, pico_slaacv4_send_probe_timer, tmp);
TASS Belgium NV 131:4758606c9316 121 }
TASS Belgium NV 131:4758606c9316 122 else
TASS Belgium NV 131:4758606c9316 123 {
TASS Belgium NV 131:4758606c9316 124 tmp->state = SLAACV4_ANNOUNCING;
TASS Belgium NV 131:4758606c9316 125 tmp->timer = pico_timer_add(ANNOUNCE_WAIT * 1000, pico_slaacv4_send_announce_timer, arg);
TASS Belgium NV 131:4758606c9316 126 }
tass 123:dd26752a4538 127 }
tass 123:dd26752a4538 128
tass 123:dd26752a4538 129
tass 123:dd26752a4538 130
tass 123:dd26752a4538 131 static void pico_slaacv4_receive_ipconflict(void)
tass 123:dd26752a4538 132 {
TASS Belgium NV 131:4758606c9316 133 struct slaacv4_cookie *tmp = &slaacv4_local;
tass 123:dd26752a4538 134
TASS Belgium NV 131:4758606c9316 135 tmp->conflict_nb++;
TASS Belgium NV 131:4758606c9316 136 pico_slaacv4_cancel_timers(tmp);
tass 123:dd26752a4538 137
TASS Belgium NV 131:4758606c9316 138 if(tmp->state == SLAACV4_CLAIMED)
TASS Belgium NV 131:4758606c9316 139 {
TASS Belgium NV 131:4758606c9316 140 pico_ipv4_link_del(tmp->device, tmp->ip);
TASS Belgium NV 131:4758606c9316 141 }
tass 123:dd26752a4538 142
TASS Belgium NV 131:4758606c9316 143 if (tmp->conflict_nb < MAX_CONFLICTS)
tass 123:dd26752a4538 144 {
TASS Belgium NV 131:4758606c9316 145 tmp->state = SLAACV4_CLAIMING;
TASS Belgium NV 131:4758606c9316 146 tmp->probe_try_nb = 0;
TASS Belgium NV 131:4758606c9316 147 tmp->announce_nb = 0;
TASS Belgium NV 131:4758606c9316 148 tmp->ip.addr = long_be(pico_slaacv4_getip(tmp->device, (uint8_t)1));
TASS Belgium NV 131:4758606c9316 149 pico_arp_register_ipconflict(&tmp->ip, &tmp->device->eth->mac, pico_slaacv4_receive_ipconflict);
TASS Belgium NV 131:4758606c9316 150 pico_arp_request(tmp->device, &tmp->ip, PICO_ARP_PROBE);
TASS Belgium NV 131:4758606c9316 151 tmp->probe_try_nb++;
TASS Belgium NV 131:4758606c9316 152 tmp->timer = pico_timer_add(PROBE_WAIT * 1000, pico_slaacv4_send_probe_timer, tmp);
tass 123:dd26752a4538 153 }
TASS Belgium NV 131:4758606c9316 154 else
TASS Belgium NV 131:4758606c9316 155 {
TASS Belgium NV 131:4758606c9316 156 if (tmp->cb != NULL)
TASS Belgium NV 131:4758606c9316 157 {
TASS Belgium NV 131:4758606c9316 158 tmp->cb(&tmp->ip, PICO_SLAACV4_ERROR);
TASS Belgium NV 131:4758606c9316 159 }
TASS Belgium NV 131:4758606c9316 160
TASS Belgium NV 131:4758606c9316 161 tmp->state = SLAACV4_ERROR;
TASS Belgium NV 131:4758606c9316 162 }
tass 123:dd26752a4538 163
tass 123:dd26752a4538 164 }
tass 123:dd26752a4538 165
tass picotcp@tass.be 149:5f4cb161cec3 166 int pico_slaacv4_claimip(struct pico_device *dev, void (*cb)(struct pico_ip4 *ip, uint8_t code))
tass 123:dd26752a4538 167 {
TASS Belgium NV 131:4758606c9316 168 struct pico_ip4 ip;
tass 123:dd26752a4538 169
tass picotcp@tass.be 149:5f4cb161cec3 170 if (!dev->eth) {
tass picotcp@tass.be 149:5f4cb161cec3 171 pico_err = PICO_ERR_EPROTONOSUPPORT;
tass picotcp@tass.be 149:5f4cb161cec3 172 return -1;
tass picotcp@tass.be 149:5f4cb161cec3 173 }
tass picotcp@tass.be 149:5f4cb161cec3 174
tass 152:a3d286bf94e5 175 ip.addr = pico_slaacv4_getip(dev, 0);
tass 123:dd26752a4538 176
TASS Belgium NV 131:4758606c9316 177 pico_slaacv4_init_cookie(&ip, dev, &slaacv4_local, cb);
TASS Belgium NV 131:4758606c9316 178 pico_arp_register_ipconflict(&ip, &dev->eth->mac, pico_slaacv4_receive_ipconflict);
TASS Belgium NV 131:4758606c9316 179 pico_arp_request(dev, &ip, PICO_ARP_PROBE);
TASS Belgium NV 131:4758606c9316 180 slaacv4_local.state = SLAACV4_CLAIMING;
TASS Belgium NV 131:4758606c9316 181 slaacv4_local.probe_try_nb++;
TASS Belgium NV 131:4758606c9316 182 slaacv4_local.timer = pico_timer_add(PROBE_WAIT * 1000, pico_slaacv4_send_probe_timer, &slaacv4_local);
tass 123:dd26752a4538 183
TASS Belgium NV 131:4758606c9316 184 return 0;
tass 123:dd26752a4538 185 }
tass 123:dd26752a4538 186
tass 123:dd26752a4538 187 void pico_slaacv4_unregisterip(void)
tass 123:dd26752a4538 188 {
TASS Belgium NV 131:4758606c9316 189 struct slaacv4_cookie *tmp = &slaacv4_local;
TASS Belgium NV 131:4758606c9316 190 struct pico_ip4 empty = {
TASS Belgium NV 131:4758606c9316 191 .addr = 0x00000000
TASS Belgium NV 131:4758606c9316 192 };
tass 123:dd26752a4538 193
TASS Belgium NV 131:4758606c9316 194 if (tmp->state == SLAACV4_CLAIMED)
TASS Belgium NV 131:4758606c9316 195 {
TASS Belgium NV 131:4758606c9316 196 pico_ipv4_link_del(tmp->device, tmp->ip);
TASS Belgium NV 131:4758606c9316 197 }
tass 123:dd26752a4538 198
TASS Belgium NV 131:4758606c9316 199 pico_slaacv4_cancel_timers(tmp);
TASS Belgium NV 131:4758606c9316 200 pico_slaacv4_init_cookie(&empty, NULL, tmp, NULL);
TASS Belgium NV 131:4758606c9316 201 pico_arp_register_ipconflict(&tmp->ip, NULL, NULL);
tass 123:dd26752a4538 202
tass 123:dd26752a4538 203 }
tass 123:dd26752a4538 204
tass 123:dd26752a4538 205 #endif