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 picotcp@tass.be
Date:
Wed Apr 09 14:31:41 2014 +0200
Revision:
149:5f4cb161cec3
Parent:
131:4758606c9316
Child:
152:a3d286bf94e5
Update from git masterbranch

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tass 68:0847e35d08a6 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 68:0847e35d08a6 4
TASS Belgium NV 131:4758606c9316 5 .
tass 68:0847e35d08a6 6
TASS Belgium NV 131:4758606c9316 7 Authors: Daniele Lacamera
TASS Belgium NV 131:4758606c9316 8 *********************************************************************/
tass 68:0847e35d08a6 9
tass 68:0847e35d08a6 10
tass 68:0847e35d08a6 11 #include "pico_udp.h"
tass 68:0847e35d08a6 12 #include "pico_config.h"
tass 68:0847e35d08a6 13 #include "pico_eth.h"
tass 68:0847e35d08a6 14 #include "pico_socket.h"
tass 68:0847e35d08a6 15 #include "pico_stack.h"
tass 68:0847e35d08a6 16
tass picotcp@tass.be 149:5f4cb161cec3 17 #define UDP_FRAME_OVERHEAD (sizeof(struct pico_frame))
tass picotcp@tass.be 149:5f4cb161cec3 18
tass 68:0847e35d08a6 19
tass 68:0847e35d08a6 20 /* Queues */
TASS Belgium NV 131:4758606c9316 21 static struct pico_queue udp_in = {
TASS Belgium NV 131:4758606c9316 22 0
TASS Belgium NV 131:4758606c9316 23 };
TASS Belgium NV 131:4758606c9316 24 static struct pico_queue udp_out = {
TASS Belgium NV 131:4758606c9316 25 0
TASS Belgium NV 131:4758606c9316 26 };
tass 68:0847e35d08a6 27
tass 68:0847e35d08a6 28
tass 68:0847e35d08a6 29 /* Functions */
tass 68:0847e35d08a6 30
tass 68:0847e35d08a6 31 uint16_t pico_udp_checksum_ipv4(struct pico_frame *f)
tass 68:0847e35d08a6 32 {
TASS Belgium NV 131:4758606c9316 33 struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr;
TASS Belgium NV 131:4758606c9316 34 struct pico_udp_hdr *udp_hdr = (struct pico_udp_hdr *) f->transport_hdr;
TASS Belgium NV 131:4758606c9316 35 struct pico_socket *s = f->sock;
TASS Belgium NV 131:4758606c9316 36 struct pico_ipv4_pseudo_hdr pseudo;
tass 68:0847e35d08a6 37
TASS Belgium NV 131:4758606c9316 38 if (s) {
TASS Belgium NV 131:4758606c9316 39 /* Case of outgoing frame */
TASS Belgium NV 131:4758606c9316 40 /* dbg("UDP CRC: on outgoing frame\n"); */
TASS Belgium NV 131:4758606c9316 41 pseudo.src.addr = s->local_addr.ip4.addr;
TASS Belgium NV 131:4758606c9316 42 pseudo.dst.addr = s->remote_addr.ip4.addr;
TASS Belgium NV 131:4758606c9316 43 } else {
TASS Belgium NV 131:4758606c9316 44 /* Case of incomming frame */
TASS Belgium NV 131:4758606c9316 45 /* dbg("UDP CRC: on incomming frame\n"); */
TASS Belgium NV 131:4758606c9316 46 pseudo.src.addr = hdr->src.addr;
TASS Belgium NV 131:4758606c9316 47 pseudo.dst.addr = hdr->dst.addr;
TASS Belgium NV 131:4758606c9316 48 }
tass 68:0847e35d08a6 49
TASS Belgium NV 131:4758606c9316 50 pseudo.zeros = 0;
TASS Belgium NV 131:4758606c9316 51 pseudo.proto = PICO_PROTO_UDP;
TASS Belgium NV 131:4758606c9316 52 pseudo.len = short_be(f->transport_len);
TASS Belgium NV 131:4758606c9316 53
TASS Belgium NV 131:4758606c9316 54 return pico_dualbuffer_checksum(&pseudo, sizeof(struct pico_ipv4_pseudo_hdr), udp_hdr, f->transport_len);
tass 68:0847e35d08a6 55 }
tass 68:0847e35d08a6 56
tass picotcp@tass.be 149:5f4cb161cec3 57 #ifdef PICO_SUPPORT_IPV6
tass picotcp@tass.be 149:5f4cb161cec3 58 uint16_t pico_udp_checksum_ipv6(struct pico_frame *f)
tass picotcp@tass.be 149:5f4cb161cec3 59 {
tass picotcp@tass.be 149:5f4cb161cec3 60 struct pico_ipv6_hdr *ipv6_hdr = (struct pico_ipv6_hdr *)f->net_hdr;
tass picotcp@tass.be 149:5f4cb161cec3 61 struct pico_udp_hdr *udp_hdr = (struct pico_udp_hdr *)f->transport_hdr;
tass picotcp@tass.be 149:5f4cb161cec3 62 struct pico_ipv6_pseudo_hdr pseudo;
tass picotcp@tass.be 149:5f4cb161cec3 63 struct pico_socket *s = f->sock;
tass picotcp@tass.be 149:5f4cb161cec3 64 struct pico_remote_endpoint *remote_endpoint = (struct pico_remote_endpoint *)f->info;
tass picotcp@tass.be 149:5f4cb161cec3 65
tass picotcp@tass.be 149:5f4cb161cec3 66 /* XXX If the IPv6 packet contains a Routing header, the Destination
tass picotcp@tass.be 149:5f4cb161cec3 67 * Address used in the pseudo-header is that of the final destination */
tass picotcp@tass.be 149:5f4cb161cec3 68 if (s) {
tass picotcp@tass.be 149:5f4cb161cec3 69 /* Case of outgoing frame */
tass picotcp@tass.be 149:5f4cb161cec3 70 pseudo.src = s->local_addr.ip6;
tass picotcp@tass.be 149:5f4cb161cec3 71 if (remote_endpoint)
tass picotcp@tass.be 149:5f4cb161cec3 72 pseudo.dst = remote_endpoint->remote_addr.ip6;
tass picotcp@tass.be 149:5f4cb161cec3 73 else
tass picotcp@tass.be 149:5f4cb161cec3 74 pseudo.dst = s->remote_addr.ip6;
tass picotcp@tass.be 149:5f4cb161cec3 75 } else {
tass picotcp@tass.be 149:5f4cb161cec3 76 /* Case of incomming frame */
tass picotcp@tass.be 149:5f4cb161cec3 77 pseudo.src = ipv6_hdr->src;
tass picotcp@tass.be 149:5f4cb161cec3 78 pseudo.dst = ipv6_hdr->dst;
tass picotcp@tass.be 149:5f4cb161cec3 79 }
tass picotcp@tass.be 149:5f4cb161cec3 80
tass picotcp@tass.be 149:5f4cb161cec3 81 pseudo.len = long_be(f->transport_len);
tass picotcp@tass.be 149:5f4cb161cec3 82 pseudo.nxthdr = PICO_PROTO_UDP;
tass picotcp@tass.be 149:5f4cb161cec3 83
tass picotcp@tass.be 149:5f4cb161cec3 84 return pico_dualbuffer_checksum(&pseudo, sizeof(struct pico_ipv6_pseudo_hdr), udp_hdr, f->transport_len);
tass picotcp@tass.be 149:5f4cb161cec3 85 }
tass picotcp@tass.be 149:5f4cb161cec3 86 #endif
tass picotcp@tass.be 149:5f4cb161cec3 87
tass picotcp@tass.be 149:5f4cb161cec3 88
tass 68:0847e35d08a6 89
tass 68:0847e35d08a6 90 static int pico_udp_process_out(struct pico_protocol *self, struct pico_frame *f)
tass 68:0847e35d08a6 91 {
TASS Belgium NV 131:4758606c9316 92 IGNORE_PARAMETER(self);
tass picotcp@tass.be 149:5f4cb161cec3 93 return (int)pico_network_send(f);
tass 68:0847e35d08a6 94 }
tass 68:0847e35d08a6 95
tass 68:0847e35d08a6 96 static int pico_udp_push(struct pico_protocol *self, struct pico_frame *f)
tass 68:0847e35d08a6 97 {
TASS Belgium NV 131:4758606c9316 98 struct pico_udp_hdr *hdr = (struct pico_udp_hdr *) f->transport_hdr;
tass picotcp@tass.be 149:5f4cb161cec3 99 struct pico_remote_endpoint *remote_endpoint = (struct pico_remote_endpoint *) f->info;
tass 68:0847e35d08a6 100
TASS Belgium NV 131:4758606c9316 101 /* this (fragmented) frame should contain a transport header */
TASS Belgium NV 131:4758606c9316 102 if (f->transport_hdr != f->payload) {
TASS Belgium NV 131:4758606c9316 103 hdr->trans.sport = f->sock->local_port;
tass picotcp@tass.be 149:5f4cb161cec3 104 if (remote_endpoint) {
tass picotcp@tass.be 149:5f4cb161cec3 105 hdr->trans.dport = remote_endpoint->remote_port;
TASS Belgium NV 131:4758606c9316 106 } else {
TASS Belgium NV 131:4758606c9316 107 hdr->trans.dport = f->sock->remote_port;
TASS Belgium NV 131:4758606c9316 108 }
TASS Belgium NV 131:4758606c9316 109
TASS Belgium NV 131:4758606c9316 110 hdr->len = short_be(f->transport_len);
tass picotcp@tass.be 149:5f4cb161cec3 111
TASS Belgium NV 131:4758606c9316 112 /* do not perform CRC validation. If you want to, a system needs to be
TASS Belgium NV 131:4758606c9316 113 implemented to calculate the CRC over the total payload of a
tass picotcp@tass.be 149:5f4cb161cec3 114 fragmented payload
tass picotcp@tass.be 149:5f4cb161cec3 115 */
TASS Belgium NV 131:4758606c9316 116 hdr->crc = 0;
tass 68:0847e35d08a6 117 }
tass 68:0847e35d08a6 118
TASS Belgium NV 131:4758606c9316 119 if (pico_enqueue(self->q_out, f) > 0) {
TASS Belgium NV 131:4758606c9316 120 return f->payload_len;
TASS Belgium NV 131:4758606c9316 121 } else {
TASS Belgium NV 131:4758606c9316 122 return 0;
TASS Belgium NV 131:4758606c9316 123 }
tass 68:0847e35d08a6 124 }
tass 68:0847e35d08a6 125
tass 68:0847e35d08a6 126 /* Interface: protocol definition */
tass 68:0847e35d08a6 127 struct pico_protocol pico_proto_udp = {
TASS Belgium NV 131:4758606c9316 128 .name = "udp",
TASS Belgium NV 131:4758606c9316 129 .proto_number = PICO_PROTO_UDP,
TASS Belgium NV 131:4758606c9316 130 .layer = PICO_LAYER_TRANSPORT,
TASS Belgium NV 131:4758606c9316 131 .process_in = pico_transport_process_in,
TASS Belgium NV 131:4758606c9316 132 .process_out = pico_udp_process_out,
TASS Belgium NV 131:4758606c9316 133 .push = pico_udp_push,
TASS Belgium NV 131:4758606c9316 134 .q_in = &udp_in,
TASS Belgium NV 131:4758606c9316 135 .q_out = &udp_out,
tass 68:0847e35d08a6 136 };
tass 68:0847e35d08a6 137
tass 68:0847e35d08a6 138
tass 68:0847e35d08a6 139
tass 68:0847e35d08a6 140 struct pico_socket *pico_udp_open(void)
tass 68:0847e35d08a6 141 {
tass picotcp@tass.be 149:5f4cb161cec3 142 struct pico_socket_udp *u = PICO_ZALLOC(sizeof(struct pico_socket_udp));
TASS Belgium NV 131:4758606c9316 143 if (!u)
TASS Belgium NV 131:4758606c9316 144 return NULL;
TASS Belgium NV 131:4758606c9316 145
TASS Belgium NV 131:4758606c9316 146 u->mode = PICO_UDP_MODE_UNICAST;
tass 68:0847e35d08a6 147
tass 68:0847e35d08a6 148 #ifdef PICO_SUPPORT_MCAST
TASS Belgium NV 131:4758606c9316 149 u->mc_ttl = PICO_IP_DEFAULT_MULTICAST_TTL;
TASS Belgium NV 131:4758606c9316 150 /* enable multicast loopback by default */
TASS Belgium NV 131:4758606c9316 151 u->sock.opt_flags |= (1 << PICO_SOCKET_OPT_MULTICAST_LOOP);
tass 68:0847e35d08a6 152 #endif
tass 68:0847e35d08a6 153
TASS Belgium NV 131:4758606c9316 154 return &u->sock;
tass 68:0847e35d08a6 155 }
tass 68:0847e35d08a6 156
tass 70:cd218dd180e5 157 uint16_t pico_udp_recv(struct pico_socket *s, void *buf, uint16_t len, void *src, uint16_t *port)
tass 68:0847e35d08a6 158 {
TASS Belgium NV 131:4758606c9316 159 struct pico_frame *f = pico_queue_peek(&s->q_in);
TASS Belgium NV 131:4758606c9316 160 if (f) {
TASS Belgium NV 131:4758606c9316 161 if(!f->payload_len) {
TASS Belgium NV 131:4758606c9316 162 f->payload = f->transport_hdr + sizeof(struct pico_udp_hdr);
TASS Belgium NV 131:4758606c9316 163 f->payload_len = (uint16_t)(f->transport_len - sizeof(struct pico_udp_hdr));
TASS Belgium NV 131:4758606c9316 164 }
TASS Belgium NV 131:4758606c9316 165
tass picotcp@tass.be 149:5f4cb161cec3 166 /* dbg("expected: %d, got: %d\n", len, f->payload_len); */
TASS Belgium NV 131:4758606c9316 167 if (src)
TASS Belgium NV 131:4758606c9316 168 pico_store_network_origin(src, f);
TASS Belgium NV 131:4758606c9316 169
TASS Belgium NV 131:4758606c9316 170 if (port) {
TASS Belgium NV 131:4758606c9316 171 struct pico_trans *hdr = (struct pico_trans *)f->transport_hdr;
TASS Belgium NV 131:4758606c9316 172 *port = hdr->sport;
TASS Belgium NV 131:4758606c9316 173 }
TASS Belgium NV 131:4758606c9316 174
TASS Belgium NV 131:4758606c9316 175 if (f->payload_len > len) {
TASS Belgium NV 131:4758606c9316 176 memcpy(buf, f->payload, len);
TASS Belgium NV 131:4758606c9316 177 f->payload += len;
TASS Belgium NV 131:4758606c9316 178 f->payload_len = (uint16_t)(f->payload_len - len);
TASS Belgium NV 131:4758606c9316 179 return len;
TASS Belgium NV 131:4758606c9316 180 } else {
TASS Belgium NV 131:4758606c9316 181 uint16_t ret = f->payload_len;
TASS Belgium NV 131:4758606c9316 182 memcpy(buf, f->payload, f->payload_len);
TASS Belgium NV 131:4758606c9316 183 f = pico_dequeue(&s->q_in);
TASS Belgium NV 131:4758606c9316 184 pico_frame_discard(f);
TASS Belgium NV 131:4758606c9316 185 return ret;
TASS Belgium NV 131:4758606c9316 186 }
TASS Belgium NV 131:4758606c9316 187 } else return 0;
tass 68:0847e35d08a6 188 }
tass 68:0847e35d08a6 189