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:
111:4003cf17bc15
Child:
149:5f4cb161cec3
Syncronized with master branch

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