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 15:43:37 2014 +0200
Revision:
150:551effcf6a39
Parent:
149:5f4cb161cec3
Child:
152:a3d286bf94e5
Fixed some warnings

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_config.h"
tass 68:0847e35d08a6 12 #include "pico_frame.h"
tass 68:0847e35d08a6 13 #include "pico_device.h"
tass 68:0847e35d08a6 14 #include "pico_protocol.h"
tass 68:0847e35d08a6 15 #include "pico_stack.h"
tass 68:0847e35d08a6 16 #include "pico_addressing.h"
tass 68:0847e35d08a6 17 #include "pico_dns_client.h"
tass 68:0847e35d08a6 18
tass 68:0847e35d08a6 19 #include "pico_eth.h"
tass 68:0847e35d08a6 20 #include "pico_arp.h"
tass 68:0847e35d08a6 21 #include "pico_ipv4.h"
tass 68:0847e35d08a6 22 #include "pico_ipv6.h"
tass 68:0847e35d08a6 23 #include "pico_icmp4.h"
tass picotcp@tass.be 149:5f4cb161cec3 24 #include "pico_icmp6.h"
tass 68:0847e35d08a6 25 #include "pico_igmp.h"
tass 68:0847e35d08a6 26 #include "pico_udp.h"
tass 68:0847e35d08a6 27 #include "pico_tcp.h"
tass 68:0847e35d08a6 28 #include "pico_socket.h"
tass 68:0847e35d08a6 29 #include "heap.h"
tass 68:0847e35d08a6 30
TASS Belgium NV 131:4758606c9316 31 #define IS_LIMITED_BCAST(f) (((struct pico_ipv4_hdr *) f->net_hdr)->dst.addr == PICO_IP4_BCAST)
tass 68:0847e35d08a6 32
tass picotcp@tass.be 149:5f4cb161cec3 33 const uint8_t PICO_ETHADDR_ALL[6] = {
tass picotcp@tass.be 149:5f4cb161cec3 34 0xff, 0xff, 0xff, 0xff, 0xff, 0xff
tass picotcp@tass.be 149:5f4cb161cec3 35 };
tass picotcp@tass.be 149:5f4cb161cec3 36
tass 68:0847e35d08a6 37 # define PICO_SIZE_MCAST 3
TASS Belgium NV 131:4758606c9316 38 const uint8_t PICO_ETHADDR_MCAST[6] = {
TASS Belgium NV 131:4758606c9316 39 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00
TASS Belgium NV 131:4758606c9316 40 };
tass 68:0847e35d08a6 41
tass picotcp@tass.be 149:5f4cb161cec3 42 #ifdef PICO_SUPPORT_IPV6
tass picotcp@tass.be 149:5f4cb161cec3 43 # define PICO_SIZE_MCAST6 2
tass picotcp@tass.be 149:5f4cb161cec3 44 const uint8_t PICO_ETHADDR_MCAST6[6] = {
tass picotcp@tass.be 149:5f4cb161cec3 45 0x33, 0x33, 0x00, 0x00, 0x00, 0x00
tass picotcp@tass.be 149:5f4cb161cec3 46 };
tass picotcp@tass.be 149:5f4cb161cec3 47 #endif
tass picotcp@tass.be 149:5f4cb161cec3 48
tass picotcp@tass.be 149:5f4cb161cec3 49
tass 128:ae39e6e81531 50 volatile pico_time pico_tick;
tass 68:0847e35d08a6 51 volatile pico_err_t pico_err;
tass 68:0847e35d08a6 52
tass 68:0847e35d08a6 53 static uint32_t _rand_seed;
tass 68:0847e35d08a6 54
tass 68:0847e35d08a6 55 void pico_rand_feed(uint32_t feed)
tass 68:0847e35d08a6 56 {
TASS Belgium NV 131:4758606c9316 57 if (!feed)
TASS Belgium NV 131:4758606c9316 58 return;
TASS Belgium NV 131:4758606c9316 59
TASS Belgium NV 131:4758606c9316 60 _rand_seed *= 1664525;
TASS Belgium NV 131:4758606c9316 61 _rand_seed += 1013904223;
TASS Belgium NV 131:4758606c9316 62 _rand_seed ^= ~(feed);
tass 68:0847e35d08a6 63 }
tass 68:0847e35d08a6 64
tass 68:0847e35d08a6 65 uint32_t pico_rand(void)
tass 68:0847e35d08a6 66 {
TASS Belgium NV 131:4758606c9316 67 pico_rand_feed((uint32_t)pico_tick);
TASS Belgium NV 131:4758606c9316 68 return _rand_seed;
tass 68:0847e35d08a6 69 }
tass 68:0847e35d08a6 70
tass 68:0847e35d08a6 71 /* NOTIFICATIONS: distributed notifications for stack internal errors.
tass 68:0847e35d08a6 72 */
tass 68:0847e35d08a6 73
tass 68:0847e35d08a6 74 int pico_notify_socket_unreachable(struct pico_frame *f)
tass 68:0847e35d08a6 75 {
TASS Belgium NV 131:4758606c9316 76 if (0) {}
TASS Belgium NV 131:4758606c9316 77
TASS Belgium NV 131:4758606c9316 78 #ifdef PICO_SUPPORT_ICMP4
TASS Belgium NV 131:4758606c9316 79 else if (IS_IPV4(f)) {
TASS Belgium NV 131:4758606c9316 80 pico_icmp4_port_unreachable(f);
TASS Belgium NV 131:4758606c9316 81 }
tass 68:0847e35d08a6 82 #endif
TASS Belgium NV 131:4758606c9316 83 #ifdef PICO_SUPPORT_ICMP6
TASS Belgium NV 131:4758606c9316 84 else if (IS_IPV6(f)) {
TASS Belgium NV 131:4758606c9316 85 pico_icmp6_port_unreachable(f);
TASS Belgium NV 131:4758606c9316 86 }
tass 68:0847e35d08a6 87 #endif
tass 68:0847e35d08a6 88
TASS Belgium NV 131:4758606c9316 89 return 0;
tass 68:0847e35d08a6 90 }
tass 68:0847e35d08a6 91
tass 68:0847e35d08a6 92 int pico_notify_proto_unreachable(struct pico_frame *f)
tass 68:0847e35d08a6 93 {
TASS Belgium NV 131:4758606c9316 94 if (0) {}
TASS Belgium NV 131:4758606c9316 95
TASS Belgium NV 131:4758606c9316 96 #ifdef PICO_SUPPORT_ICMP4
TASS Belgium NV 131:4758606c9316 97 else if (IS_IPV4(f)) {
TASS Belgium NV 131:4758606c9316 98 pico_icmp4_proto_unreachable(f);
TASS Belgium NV 131:4758606c9316 99 }
tass 68:0847e35d08a6 100 #endif
TASS Belgium NV 131:4758606c9316 101 #ifdef PICO_SUPPORT_ICMP6
TASS Belgium NV 131:4758606c9316 102 else if (IS_IPV6(f)) {
TASS Belgium NV 131:4758606c9316 103 pico_icmp6_proto_unreachable(f);
TASS Belgium NV 131:4758606c9316 104 }
tass 68:0847e35d08a6 105 #endif
TASS Belgium NV 131:4758606c9316 106 return 0;
tass 68:0847e35d08a6 107 }
tass 68:0847e35d08a6 108
tass 68:0847e35d08a6 109 int pico_notify_dest_unreachable(struct pico_frame *f)
tass 68:0847e35d08a6 110 {
TASS Belgium NV 131:4758606c9316 111 if (0) {}
TASS Belgium NV 131:4758606c9316 112
TASS Belgium NV 131:4758606c9316 113 #ifdef PICO_SUPPORT_ICMP4
TASS Belgium NV 131:4758606c9316 114 else if (IS_IPV4(f)) {
TASS Belgium NV 131:4758606c9316 115 pico_icmp4_dest_unreachable(f);
TASS Belgium NV 131:4758606c9316 116 }
tass 68:0847e35d08a6 117 #endif
TASS Belgium NV 131:4758606c9316 118 #ifdef PICO_SUPPORT_ICMP6
TASS Belgium NV 131:4758606c9316 119 else if (IS_IPV6(f)) {
TASS Belgium NV 131:4758606c9316 120 pico_icmp6_dest_unreachable(f);
TASS Belgium NV 131:4758606c9316 121 }
tass 68:0847e35d08a6 122 #endif
TASS Belgium NV 131:4758606c9316 123 return 0;
tass 68:0847e35d08a6 124 }
tass 68:0847e35d08a6 125
tass 68:0847e35d08a6 126 int pico_notify_ttl_expired(struct pico_frame *f)
tass 68:0847e35d08a6 127 {
TASS Belgium NV 131:4758606c9316 128 if (0) {}
TASS Belgium NV 131:4758606c9316 129
TASS Belgium NV 131:4758606c9316 130 #ifdef PICO_SUPPORT_ICMP4
TASS Belgium NV 131:4758606c9316 131 else if (IS_IPV4(f)) {
TASS Belgium NV 131:4758606c9316 132 pico_icmp4_ttl_expired(f);
TASS Belgium NV 131:4758606c9316 133 }
tass 68:0847e35d08a6 134 #endif
TASS Belgium NV 131:4758606c9316 135 #ifdef PICO_SUPPORT_ICMP6
TASS Belgium NV 131:4758606c9316 136 else if (IS_IPV6(f)) {
TASS Belgium NV 131:4758606c9316 137 pico_icmp6_ttl_expired(f);
TASS Belgium NV 131:4758606c9316 138 }
tass 68:0847e35d08a6 139 #endif
TASS Belgium NV 131:4758606c9316 140 return 0;
tass 68:0847e35d08a6 141 }
tass 68:0847e35d08a6 142
tass 68:0847e35d08a6 143
tass 68:0847e35d08a6 144 /* Transport layer */
tass 70:cd218dd180e5 145 int32_t pico_transport_receive(struct pico_frame *f, uint8_t proto)
tass 68:0847e35d08a6 146 {
TASS Belgium NV 131:4758606c9316 147 int32_t ret = -1;
TASS Belgium NV 131:4758606c9316 148 switch (proto) {
tass 68:0847e35d08a6 149
tass 68:0847e35d08a6 150 #ifdef PICO_SUPPORT_ICMP4
TASS Belgium NV 131:4758606c9316 151 case PICO_PROTO_ICMP4:
TASS Belgium NV 131:4758606c9316 152 ret = pico_enqueue(pico_proto_icmp4.q_in, f);
TASS Belgium NV 131:4758606c9316 153 break;
tass 68:0847e35d08a6 154 #endif
tass 68:0847e35d08a6 155
tass picotcp@tass.be 149:5f4cb161cec3 156 #ifdef PICO_SUPPORT_ICMP6
tass picotcp@tass.be 149:5f4cb161cec3 157 case PICO_PROTO_ICMP6:
tass picotcp@tass.be 149:5f4cb161cec3 158 ret = pico_enqueue(pico_proto_icmp6.q_in, f);
tass picotcp@tass.be 149:5f4cb161cec3 159 break;
tass picotcp@tass.be 149:5f4cb161cec3 160 #endif
tass picotcp@tass.be 149:5f4cb161cec3 161
tass picotcp@tass.be 149:5f4cb161cec3 162
tass 68:0847e35d08a6 163 #ifdef PICO_SUPPORT_IGMP
TASS Belgium NV 131:4758606c9316 164 case PICO_PROTO_IGMP:
TASS Belgium NV 131:4758606c9316 165 ret = pico_enqueue(pico_proto_igmp.q_in, f);
TASS Belgium NV 131:4758606c9316 166 break;
tass 68:0847e35d08a6 167 #endif
tass 68:0847e35d08a6 168
tass 68:0847e35d08a6 169 #ifdef PICO_SUPPORT_UDP
TASS Belgium NV 131:4758606c9316 170 case PICO_PROTO_UDP:
TASS Belgium NV 131:4758606c9316 171 ret = pico_enqueue(pico_proto_udp.q_in, f);
TASS Belgium NV 131:4758606c9316 172 break;
tass 68:0847e35d08a6 173 #endif
tass 68:0847e35d08a6 174
tass 68:0847e35d08a6 175 #ifdef PICO_SUPPORT_TCP
TASS Belgium NV 131:4758606c9316 176 case PICO_PROTO_TCP:
TASS Belgium NV 131:4758606c9316 177 ret = pico_enqueue(pico_proto_tcp.q_in, f);
TASS Belgium NV 131:4758606c9316 178 break;
tass 68:0847e35d08a6 179 #endif
tass 68:0847e35d08a6 180
TASS Belgium NV 131:4758606c9316 181 default:
TASS Belgium NV 131:4758606c9316 182 /* Protocol not available */
TASS Belgium NV 131:4758606c9316 183 dbg("pkt: no such protocol (%d)\n", proto);
TASS Belgium NV 131:4758606c9316 184 pico_notify_proto_unreachable(f);
TASS Belgium NV 131:4758606c9316 185 pico_frame_discard(f);
TASS Belgium NV 131:4758606c9316 186 ret = -1;
TASS Belgium NV 131:4758606c9316 187 }
TASS Belgium NV 131:4758606c9316 188 return ret;
tass 68:0847e35d08a6 189 }
tass 68:0847e35d08a6 190
tass 70:cd218dd180e5 191 int32_t pico_network_receive(struct pico_frame *f)
tass 68:0847e35d08a6 192 {
TASS Belgium NV 131:4758606c9316 193 if (0) {}
TASS Belgium NV 131:4758606c9316 194
tass 68:0847e35d08a6 195 #ifdef PICO_SUPPORT_IPV4
TASS Belgium NV 131:4758606c9316 196 else if (IS_IPV4(f)) {
TASS Belgium NV 131:4758606c9316 197 pico_enqueue(pico_proto_ipv4.q_in, f);
TASS Belgium NV 131:4758606c9316 198 }
tass 68:0847e35d08a6 199 #endif
tass 68:0847e35d08a6 200 #ifdef PICO_SUPPORT_IPV6
TASS Belgium NV 131:4758606c9316 201 else if (IS_IPV6(f)) {
TASS Belgium NV 131:4758606c9316 202 pico_enqueue(pico_proto_ipv6.q_in, f);
TASS Belgium NV 131:4758606c9316 203 }
tass 68:0847e35d08a6 204 #endif
TASS Belgium NV 131:4758606c9316 205 else {
TASS Belgium NV 131:4758606c9316 206 dbg("Network not found.\n");
TASS Belgium NV 131:4758606c9316 207 pico_frame_discard(f);
TASS Belgium NV 131:4758606c9316 208 return -1;
TASS Belgium NV 131:4758606c9316 209 }
TASS Belgium NV 131:4758606c9316 210 return (int32_t)f->buffer_len;
tass 68:0847e35d08a6 211 }
tass 68:0847e35d08a6 212
tass 68:0847e35d08a6 213
tass 68:0847e35d08a6 214 /* Network layer: interface towards socket for frame sending */
tass 88:0e827d0d8017 215 int32_t pico_network_send(struct pico_frame *f)
tass 68:0847e35d08a6 216 {
TASS Belgium NV 131:4758606c9316 217 if (!f || !f->sock || !f->sock->net) {
TASS Belgium NV 131:4758606c9316 218 pico_frame_discard(f);
TASS Belgium NV 131:4758606c9316 219 return -1;
TASS Belgium NV 131:4758606c9316 220 }
TASS Belgium NV 131:4758606c9316 221
TASS Belgium NV 131:4758606c9316 222 return f->sock->net->push(f->sock->net, f);
tass 68:0847e35d08a6 223 }
tass 68:0847e35d08a6 224
tass 68:0847e35d08a6 225 int pico_source_is_local(struct pico_frame *f)
tass 68:0847e35d08a6 226 {
TASS Belgium NV 131:4758606c9316 227 if (0) { }
TASS Belgium NV 131:4758606c9316 228
tass 68:0847e35d08a6 229 #ifdef PICO_SUPPORT_IPV4
TASS Belgium NV 131:4758606c9316 230 else if (IS_IPV4(f)) {
TASS Belgium NV 131:4758606c9316 231 struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *)f->net_hdr;
TASS Belgium NV 131:4758606c9316 232 if (hdr->src.addr == PICO_IPV4_INADDR_ANY)
TASS Belgium NV 131:4758606c9316 233 return 1;
TASS Belgium NV 131:4758606c9316 234
TASS Belgium NV 131:4758606c9316 235 if (pico_ipv4_link_find(&hdr->src))
TASS Belgium NV 131:4758606c9316 236 return 1;
TASS Belgium NV 131:4758606c9316 237 }
tass 68:0847e35d08a6 238 #endif
tass 68:0847e35d08a6 239 #ifdef PICO_SUPPORT_IPV6
TASS Belgium NV 131:4758606c9316 240 else if (IS_IPV6(f)) {
TASS Belgium NV 131:4758606c9316 241 /* XXX */
TASS Belgium NV 131:4758606c9316 242 }
tass 68:0847e35d08a6 243 #endif
TASS Belgium NV 131:4758606c9316 244 return 0;
tass 68:0847e35d08a6 245
tass 68:0847e35d08a6 246
tass 68:0847e35d08a6 247 }
tass 68:0847e35d08a6 248
tass 68:0847e35d08a6 249
tass 68:0847e35d08a6 250 /* DATALINK LEVEL: interface from network to the device
tass 68:0847e35d08a6 251 * and vice versa.
tass 68:0847e35d08a6 252 */
tass 68:0847e35d08a6 253
TASS Belgium NV 131:4758606c9316 254 /* The pico_ethernet_receive() function is used by
TASS Belgium NV 131:4758606c9316 255 * those devices supporting ETH in order to push packets up
TASS Belgium NV 131:4758606c9316 256 * into the stack.
tass 68:0847e35d08a6 257 */
tass picotcp@tass.be 137:a1c8bfa9d691 258
tass picotcp@tass.be 137:a1c8bfa9d691 259 static int32_t pico_ll_receive(struct pico_frame *f)
tass picotcp@tass.be 137:a1c8bfa9d691 260 {
tass picotcp@tass.be 137:a1c8bfa9d691 261 struct pico_eth_hdr *hdr = (struct pico_eth_hdr *) f->datalink_hdr;
tass picotcp@tass.be 137:a1c8bfa9d691 262 f->net_hdr = f->datalink_hdr + sizeof(struct pico_eth_hdr);
tass picotcp@tass.be 149:5f4cb161cec3 263
tass picotcp@tass.be 149:5f4cb161cec3 264 #if (defined PICO_SUPPORT_IPV4) && (defined PICO_SUPPORT_ETH)
tass picotcp@tass.be 150:551effcf6a39 265 if (hdr->proto == PICO_IDETH_ARP)
tass picotcp@tass.be 137:a1c8bfa9d691 266 return pico_arp_receive(f);
tass picotcp@tass.be 149:5f4cb161cec3 267 #endif
tass picotcp@tass.be 149:5f4cb161cec3 268 #if defined (PICO_SUPPORT_IPV4) || defined (PICO_SUPPORT_IPV6)
tass picotcp@tass.be 150:551effcf6a39 269 if ((hdr->proto == PICO_IDETH_IPV4) || (hdr->proto == PICO_IDETH_IPV6))
tass picotcp@tass.be 137:a1c8bfa9d691 270 return pico_network_receive(f);
tass picotcp@tass.be 149:5f4cb161cec3 271 #endif
tass picotcp@tass.be 150:551effcf6a39 272 pico_frame_discard(f);
tass picotcp@tass.be 150:551effcf6a39 273 return -1;
tass picotcp@tass.be 137:a1c8bfa9d691 274 }
tass picotcp@tass.be 137:a1c8bfa9d691 275
tass picotcp@tass.be 137:a1c8bfa9d691 276 static void pico_ll_check_bcast(struct pico_frame *f)
tass picotcp@tass.be 137:a1c8bfa9d691 277 {
tass picotcp@tass.be 137:a1c8bfa9d691 278 struct pico_eth_hdr *hdr = (struct pico_eth_hdr *) f->datalink_hdr;
tass picotcp@tass.be 137:a1c8bfa9d691 279 /* Indicate a link layer broadcast packet */
tass picotcp@tass.be 137:a1c8bfa9d691 280 if (memcmp(hdr->daddr, PICO_ETHADDR_ALL, PICO_SIZE_ETH) == 0)
tass picotcp@tass.be 137:a1c8bfa9d691 281 f->flags |= PICO_FRAME_FLAG_BCAST;
tass picotcp@tass.be 137:a1c8bfa9d691 282 }
tass picotcp@tass.be 137:a1c8bfa9d691 283
tass 70:cd218dd180e5 284 int32_t pico_ethernet_receive(struct pico_frame *f)
tass 68:0847e35d08a6 285 {
TASS Belgium NV 131:4758606c9316 286 struct pico_eth_hdr *hdr;
TASS Belgium NV 131:4758606c9316 287 if (!f || !f->dev || !f->datalink_hdr)
tass picotcp@tass.be 137:a1c8bfa9d691 288 {
tass picotcp@tass.be 137:a1c8bfa9d691 289 pico_frame_discard(f);
tass picotcp@tass.be 137:a1c8bfa9d691 290 return -1;
tass picotcp@tass.be 137:a1c8bfa9d691 291 }
TASS Belgium NV 131:4758606c9316 292
TASS Belgium NV 131:4758606c9316 293 hdr = (struct pico_eth_hdr *) f->datalink_hdr;
TASS Belgium NV 131:4758606c9316 294 if ((memcmp(hdr->daddr, f->dev->eth->mac.addr, PICO_SIZE_ETH) != 0) &&
TASS Belgium NV 131:4758606c9316 295 (memcmp(hdr->daddr, PICO_ETHADDR_MCAST, PICO_SIZE_MCAST) != 0) &&
tass picotcp@tass.be 149:5f4cb161cec3 296 #ifdef PICO_SUPPORT_IPV6
tass picotcp@tass.be 149:5f4cb161cec3 297 (memcmp(hdr->daddr, PICO_ETHADDR_MCAST6, PICO_SIZE_MCAST6) != 0) &&
tass picotcp@tass.be 149:5f4cb161cec3 298 #endif
TASS Belgium NV 131:4758606c9316 299 (memcmp(hdr->daddr, PICO_ETHADDR_ALL, PICO_SIZE_ETH) != 0))
tass picotcp@tass.be 137:a1c8bfa9d691 300 {
tass picotcp@tass.be 137:a1c8bfa9d691 301 pico_frame_discard(f);
tass picotcp@tass.be 137:a1c8bfa9d691 302 return -1;
tass picotcp@tass.be 137:a1c8bfa9d691 303 }
TASS Belgium NV 131:4758606c9316 304
tass picotcp@tass.be 137:a1c8bfa9d691 305 pico_ll_check_bcast(f);
tass 68:0847e35d08a6 306
tass picotcp@tass.be 137:a1c8bfa9d691 307 return pico_ll_receive(f);
tass 68:0847e35d08a6 308 }
tass 68:0847e35d08a6 309
tass 68:0847e35d08a6 310 static int destination_is_bcast(struct pico_frame *f)
tass 68:0847e35d08a6 311 {
TASS Belgium NV 131:4758606c9316 312 if (!f)
TASS Belgium NV 131:4758606c9316 313 return 0;
tass 68:0847e35d08a6 314
TASS Belgium NV 131:4758606c9316 315 if (IS_IPV6(f))
TASS Belgium NV 131:4758606c9316 316 return 0;
TASS Belgium NV 131:4758606c9316 317
tass 68:0847e35d08a6 318 #ifdef PICO_SUPPORT_IPV4
TASS Belgium NV 131:4758606c9316 319 else {
TASS Belgium NV 131:4758606c9316 320 struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr;
TASS Belgium NV 131:4758606c9316 321 return pico_ipv4_is_broadcast(hdr->dst.addr);
TASS Belgium NV 131:4758606c9316 322 }
tass picotcp@tass.be 134:cc4e6d2654d9 323 #else
tass picotcp@tass.be 134:cc4e6d2654d9 324 return 0;
tass 68:0847e35d08a6 325 #endif
tass 68:0847e35d08a6 326 }
tass 68:0847e35d08a6 327
tass 68:0847e35d08a6 328 static int destination_is_mcast(struct pico_frame *f)
tass 68:0847e35d08a6 329 {
tass picotcp@tass.be 149:5f4cb161cec3 330 int ret = 0;
TASS Belgium NV 131:4758606c9316 331 if (!f)
TASS Belgium NV 131:4758606c9316 332 return 0;
tass 68:0847e35d08a6 333
tass picotcp@tass.be 149:5f4cb161cec3 334 #ifdef PICO_SUPPORT_IPV6
tass picotcp@tass.be 149:5f4cb161cec3 335 if (IS_IPV6(f)) {
tass picotcp@tass.be 149:5f4cb161cec3 336 struct pico_ipv6_hdr *hdr = (struct pico_ipv6_hdr *) f->net_hdr;
tass picotcp@tass.be 149:5f4cb161cec3 337 ret = pico_ipv6_is_multicast(hdr->dst.addr);
tass picotcp@tass.be 149:5f4cb161cec3 338 }
TASS Belgium NV 131:4758606c9316 339
tass picotcp@tass.be 149:5f4cb161cec3 340 #endif
tass 68:0847e35d08a6 341 #ifdef PICO_SUPPORT_IPV4
TASS Belgium NV 131:4758606c9316 342 else {
TASS Belgium NV 131:4758606c9316 343 struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr;
tass picotcp@tass.be 149:5f4cb161cec3 344 ret = pico_ipv4_is_multicast(hdr->dst.addr);
TASS Belgium NV 131:4758606c9316 345 }
tass 68:0847e35d08a6 346 #endif
tass picotcp@tass.be 149:5f4cb161cec3 347
tass picotcp@tass.be 149:5f4cb161cec3 348 return ret;
tass 68:0847e35d08a6 349 }
tass 68:0847e35d08a6 350
tass 68:0847e35d08a6 351 static struct pico_eth *pico_ethernet_mcast_translate(struct pico_frame *f, uint8_t *pico_mcast_mac)
tass 68:0847e35d08a6 352 {
TASS Belgium NV 131:4758606c9316 353 struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr;
tass 68:0847e35d08a6 354
TASS Belgium NV 131:4758606c9316 355 /* place 23 lower bits of IP in lower 23 bits of MAC */
tass picotcp@tass.be 149:5f4cb161cec3 356 pico_mcast_mac[5] = (long_be(hdr->dst.addr) & 0x000000FFu);
tass picotcp@tass.be 149:5f4cb161cec3 357 pico_mcast_mac[4] = (uint8_t)((long_be(hdr->dst.addr) & 0x0000FF00u) >> 8u);
tass picotcp@tass.be 149:5f4cb161cec3 358 pico_mcast_mac[3] = (uint8_t)((long_be(hdr->dst.addr) & 0x007F0000u) >> 16u);
tass 68:0847e35d08a6 359
TASS Belgium NV 131:4758606c9316 360 return (struct pico_eth *)pico_mcast_mac;
tass 68:0847e35d08a6 361 }
tass 68:0847e35d08a6 362
tass 68:0847e35d08a6 363
tass picotcp@tass.be 149:5f4cb161cec3 364 #ifdef PICO_SUPPORT_IPV6
tass picotcp@tass.be 149:5f4cb161cec3 365 static struct pico_eth *pico_ethernet_mcast6_translate(struct pico_frame *f, uint8_t *pico_mcast6_mac)
tass picotcp@tass.be 149:5f4cb161cec3 366 {
tass picotcp@tass.be 149:5f4cb161cec3 367 struct pico_ipv6_hdr *hdr = (struct pico_ipv6_hdr *)f->net_hdr;
tass picotcp@tass.be 137:a1c8bfa9d691 368
tass picotcp@tass.be 149:5f4cb161cec3 369 /* first 2 octets are 0x33, last four are the last four of dst */
tass picotcp@tass.be 149:5f4cb161cec3 370 pico_mcast6_mac[5] = hdr->dst.addr[PICO_SIZE_IP6 - 1];
tass picotcp@tass.be 149:5f4cb161cec3 371 pico_mcast6_mac[4] = hdr->dst.addr[PICO_SIZE_IP6 - 2];
tass picotcp@tass.be 149:5f4cb161cec3 372 pico_mcast6_mac[3] = hdr->dst.addr[PICO_SIZE_IP6 - 3];
tass picotcp@tass.be 149:5f4cb161cec3 373 pico_mcast6_mac[2] = hdr->dst.addr[PICO_SIZE_IP6 - 4];
tass picotcp@tass.be 149:5f4cb161cec3 374
tass picotcp@tass.be 149:5f4cb161cec3 375 return (struct pico_eth *)pico_mcast6_mac;
tass picotcp@tass.be 149:5f4cb161cec3 376 }
tass picotcp@tass.be 149:5f4cb161cec3 377 #endif
tass picotcp@tass.be 149:5f4cb161cec3 378
tass picotcp@tass.be 149:5f4cb161cec3 379 struct pico_eth *pico_ethernet_ipv6_dst(struct pico_frame *f)
tass picotcp@tass.be 137:a1c8bfa9d691 380 {
tass picotcp@tass.be 149:5f4cb161cec3 381 struct pico_eth *dstmac = NULL;
tass picotcp@tass.be 149:5f4cb161cec3 382 #ifdef PICO_SUPPORT_IPV6
tass picotcp@tass.be 149:5f4cb161cec3 383 if (destination_is_mcast(f)) {
tass picotcp@tass.be 149:5f4cb161cec3 384 uint8_t pico_mcast6_mac[6] = {
tass picotcp@tass.be 149:5f4cb161cec3 385 0x33, 0x33, 0x00, 0x00, 0x00, 0x00
tass picotcp@tass.be 149:5f4cb161cec3 386 };
tass picotcp@tass.be 149:5f4cb161cec3 387 dstmac = pico_ethernet_mcast6_translate(f, pico_mcast6_mac);
tass picotcp@tass.be 149:5f4cb161cec3 388 } else {
tass picotcp@tass.be 149:5f4cb161cec3 389 dstmac = pico_nd_get(f);
tass picotcp@tass.be 149:5f4cb161cec3 390 }
tass picotcp@tass.be 149:5f4cb161cec3 391
tass picotcp@tass.be 149:5f4cb161cec3 392 #else
tass picotcp@tass.be 137:a1c8bfa9d691 393 (void)f;
tass picotcp@tass.be 149:5f4cb161cec3 394 pico_err = PICO_ERR_EPROTONOSUPPORT;
tass picotcp@tass.be 149:5f4cb161cec3 395 #endif
tass picotcp@tass.be 149:5f4cb161cec3 396 return dstmac;
tass picotcp@tass.be 137:a1c8bfa9d691 397 }
tass picotcp@tass.be 137:a1c8bfa9d691 398
tass picotcp@tass.be 137:a1c8bfa9d691 399
tass 68:0847e35d08a6 400
tass 68:0847e35d08a6 401 /* This is called by dev loop in order to ensure correct ethernet addressing.
tass 68:0847e35d08a6 402 * Returns 0 if the destination is unknown, and -1 if the packet is not deliverable
TASS Belgium NV 131:4758606c9316 403 * due to ethernet addressing (i.e., no arp association was possible.
tass 68:0847e35d08a6 404 *
tass 68:0847e35d08a6 405 * Only IP packets must pass by this. ARP will always use direct dev->send() function, so
tass 68:0847e35d08a6 406 * we assume IP is used.
tass 68:0847e35d08a6 407 */
tass picotcp@tass.be 137:a1c8bfa9d691 408
tass picotcp@tass.be 137:a1c8bfa9d691 409 static int32_t pico_ethsend_local(struct pico_frame *f, struct pico_eth_hdr *hdr, int *ret)
tass picotcp@tass.be 137:a1c8bfa9d691 410 {
tass picotcp@tass.be 137:a1c8bfa9d691 411 /* Check own mac */
tass picotcp@tass.be 137:a1c8bfa9d691 412 if(!memcmp(hdr->daddr, hdr->saddr, PICO_SIZE_ETH)) {
tass picotcp@tass.be 137:a1c8bfa9d691 413 dbg("sending out packet destined for our own mac\n");
tass picotcp@tass.be 137:a1c8bfa9d691 414 *ret = (int32_t)pico_ethernet_receive(f);
tass picotcp@tass.be 137:a1c8bfa9d691 415 return 1;
tass picotcp@tass.be 137:a1c8bfa9d691 416 }
tass picotcp@tass.be 137:a1c8bfa9d691 417
tass picotcp@tass.be 137:a1c8bfa9d691 418 return 0;
tass picotcp@tass.be 137:a1c8bfa9d691 419 }
tass picotcp@tass.be 137:a1c8bfa9d691 420
tass picotcp@tass.be 137:a1c8bfa9d691 421 static int32_t pico_ethsend_bcast(struct pico_frame *f, int *ret)
tass picotcp@tass.be 137:a1c8bfa9d691 422 {
tass picotcp@tass.be 137:a1c8bfa9d691 423 if (IS_LIMITED_BCAST(f)) {
tass picotcp@tass.be 137:a1c8bfa9d691 424 *ret = pico_device_broadcast(f);
tass picotcp@tass.be 137:a1c8bfa9d691 425 return 1;
tass picotcp@tass.be 137:a1c8bfa9d691 426 }
tass picotcp@tass.be 137:a1c8bfa9d691 427
tass picotcp@tass.be 137:a1c8bfa9d691 428 return 0;
tass picotcp@tass.be 137:a1c8bfa9d691 429 }
tass picotcp@tass.be 137:a1c8bfa9d691 430
tass picotcp@tass.be 137:a1c8bfa9d691 431 static int32_t pico_ethsend_dispatch(struct pico_frame *f, int *ret)
tass picotcp@tass.be 137:a1c8bfa9d691 432 {
tass picotcp@tass.be 137:a1c8bfa9d691 433 *ret = f->dev->send(f->dev, f->start, (int) f->len);
tass picotcp@tass.be 137:a1c8bfa9d691 434 if (*ret <= 0)
tass picotcp@tass.be 137:a1c8bfa9d691 435 return 0;
tass picotcp@tass.be 137:a1c8bfa9d691 436 else {
tass picotcp@tass.be 137:a1c8bfa9d691 437 pico_frame_discard(f);
tass picotcp@tass.be 137:a1c8bfa9d691 438 return 1;
tass picotcp@tass.be 137:a1c8bfa9d691 439 }
tass picotcp@tass.be 137:a1c8bfa9d691 440 }
tass picotcp@tass.be 137:a1c8bfa9d691 441
tass 70:cd218dd180e5 442 int32_t pico_ethernet_send(struct pico_frame *f)
tass 68:0847e35d08a6 443 {
TASS Belgium NV 131:4758606c9316 444 const struct pico_eth *dstmac = NULL;
TASS Belgium NV 131:4758606c9316 445 int32_t ret = -1;
tass picotcp@tass.be 149:5f4cb161cec3 446 uint16_t proto = PICO_IDETH_IPV4;
tass 68:0847e35d08a6 447
tass picotcp@tass.be 149:5f4cb161cec3 448 if (IS_IPV6(f)) {
tass picotcp@tass.be 149:5f4cb161cec3 449 dstmac = pico_ethernet_ipv6_dst(f);
tass picotcp@tass.be 149:5f4cb161cec3 450 if (!dstmac)
tass picotcp@tass.be 149:5f4cb161cec3 451 return 0;
tass picotcp@tass.be 137:a1c8bfa9d691 452
tass picotcp@tass.be 149:5f4cb161cec3 453 proto = PICO_IDETH_IPV6;
tass picotcp@tass.be 149:5f4cb161cec3 454 }
tass picotcp@tass.be 149:5f4cb161cec3 455
tass picotcp@tass.be 149:5f4cb161cec3 456 else if (IS_BCAST(f) || destination_is_bcast(f))
tass picotcp@tass.be 137:a1c8bfa9d691 457 dstmac = (const struct pico_eth *) PICO_ETHADDR_ALL;
tass picotcp@tass.be 137:a1c8bfa9d691 458
tass picotcp@tass.be 137:a1c8bfa9d691 459 else if (destination_is_mcast(f)) {
tass picotcp@tass.be 137:a1c8bfa9d691 460 uint8_t pico_mcast_mac[6] = {
tass picotcp@tass.be 137:a1c8bfa9d691 461 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00
tass picotcp@tass.be 137:a1c8bfa9d691 462 };
tass picotcp@tass.be 137:a1c8bfa9d691 463 dstmac = pico_ethernet_mcast_translate(f, pico_mcast_mac);
tass picotcp@tass.be 137:a1c8bfa9d691 464 }
tass picotcp@tass.be 137:a1c8bfa9d691 465 else {
tass picotcp@tass.be 149:5f4cb161cec3 466 #if (defined PICO_SUPPORT_IPV4) && (defined PICO_SUPPORT_ETH)
tass picotcp@tass.be 137:a1c8bfa9d691 467 dstmac = pico_arp_get(f);
tass picotcp@tass.be 137:a1c8bfa9d691 468 if (!dstmac)
tass picotcp@tass.be 149:5f4cb161cec3 469 #endif
tass picotcp@tass.be 149:5f4cb161cec3 470 return 0;
tass 68:0847e35d08a6 471 }
TASS Belgium NV 131:4758606c9316 472
tass picotcp@tass.be 137:a1c8bfa9d691 473 /* This sets destination and source address, then pushes the packet to the device. */
tass picotcp@tass.be 137:a1c8bfa9d691 474 if (dstmac && (f->start > f->buffer) && ((f->start - f->buffer) >= PICO_SIZE_ETHHDR)) {
tass picotcp@tass.be 137:a1c8bfa9d691 475 struct pico_eth_hdr *hdr;
tass picotcp@tass.be 137:a1c8bfa9d691 476 f->start -= PICO_SIZE_ETHHDR;
tass picotcp@tass.be 137:a1c8bfa9d691 477 f->len += PICO_SIZE_ETHHDR;
tass picotcp@tass.be 137:a1c8bfa9d691 478 f->datalink_hdr = f->start;
tass picotcp@tass.be 137:a1c8bfa9d691 479 hdr = (struct pico_eth_hdr *) f->datalink_hdr;
tass picotcp@tass.be 137:a1c8bfa9d691 480 memcpy(hdr->saddr, f->dev->eth->mac.addr, PICO_SIZE_ETH);
tass picotcp@tass.be 137:a1c8bfa9d691 481 memcpy(hdr->daddr, dstmac, PICO_SIZE_ETH);
tass picotcp@tass.be 149:5f4cb161cec3 482 hdr->proto = proto;
tass 68:0847e35d08a6 483
tass picotcp@tass.be 137:a1c8bfa9d691 484 if (pico_ethsend_local(f, hdr, &ret) || pico_ethsend_bcast(f, &ret) || pico_ethsend_dispatch(f, &ret)) {
TASS Belgium NV 131:4758606c9316 485 return ret;
TASS Belgium NV 131:4758606c9316 486 } else {
TASS Belgium NV 131:4758606c9316 487 return -1;
TASS Belgium NV 131:4758606c9316 488 }
tass picotcp@tass.be 137:a1c8bfa9d691 489 }
TASS Belgium NV 131:4758606c9316 490
TASS Belgium NV 131:4758606c9316 491 return -1;
tass 68:0847e35d08a6 492 }
tass 68:0847e35d08a6 493
tass 68:0847e35d08a6 494 void pico_store_network_origin(void *src, struct pico_frame *f)
tass 68:0847e35d08a6 495 {
tass 68:0847e35d08a6 496 #ifdef PICO_SUPPORT_IPV4
TASS Belgium NV 131:4758606c9316 497 struct pico_ip4 *ip4;
tass 68:0847e35d08a6 498 #endif
tass 68:0847e35d08a6 499
tass 68:0847e35d08a6 500 #ifdef PICO_SUPPORT_IPV6
TASS Belgium NV 131:4758606c9316 501 struct pico_ip6 *ip6;
tass 68:0847e35d08a6 502 #endif
tass 68:0847e35d08a6 503
tass 68:0847e35d08a6 504 #ifdef PICO_SUPPORT_IPV4
TASS Belgium NV 131:4758606c9316 505 if (IS_IPV4(f)) {
TASS Belgium NV 131:4758606c9316 506 struct pico_ipv4_hdr *hdr;
TASS Belgium NV 131:4758606c9316 507 hdr = (struct pico_ipv4_hdr *) f->net_hdr;
TASS Belgium NV 131:4758606c9316 508 ip4 = (struct pico_ip4 *) src;
TASS Belgium NV 131:4758606c9316 509 ip4->addr = hdr->src.addr;
TASS Belgium NV 131:4758606c9316 510 }
TASS Belgium NV 131:4758606c9316 511
tass 68:0847e35d08a6 512 #endif
tass 68:0847e35d08a6 513 #ifdef PICO_SUPPORT_IPV6
TASS Belgium NV 131:4758606c9316 514 if (IS_IPV6(f)) {
TASS Belgium NV 131:4758606c9316 515 struct pico_ipv6_hdr *hdr;
TASS Belgium NV 131:4758606c9316 516 hdr = (struct pico_ipv6_hdr *) f->net_hdr;
TASS Belgium NV 131:4758606c9316 517 ip6 = (struct pico_ip6 *) src;
TASS Belgium NV 131:4758606c9316 518 memcpy(ip6->addr, hdr->src.addr, PICO_SIZE_IP6);
TASS Belgium NV 131:4758606c9316 519 }
TASS Belgium NV 131:4758606c9316 520
tass 68:0847e35d08a6 521 #endif
tass 68:0847e35d08a6 522 }
tass 68:0847e35d08a6 523
tass 68:0847e35d08a6 524
tass 68:0847e35d08a6 525 /* LOWEST LEVEL: interface towards devices. */
tass 68:0847e35d08a6 526 /* Device driver will call this function which returns immediately.
tass 68:0847e35d08a6 527 * Incoming packet will be processed later on in the dev loop.
tass 68:0847e35d08a6 528 */
tass 70:cd218dd180e5 529 int32_t pico_stack_recv(struct pico_device *dev, uint8_t *buffer, uint32_t len)
tass 68:0847e35d08a6 530 {
TASS Belgium NV 131:4758606c9316 531 struct pico_frame *f;
TASS Belgium NV 131:4758606c9316 532 int32_t ret;
TASS Belgium NV 131:4758606c9316 533 if (len <= 0)
TASS Belgium NV 131:4758606c9316 534 return -1;
tass 68:0847e35d08a6 535
TASS Belgium NV 131:4758606c9316 536 f = pico_frame_alloc(len);
TASS Belgium NV 131:4758606c9316 537 if (!f)
tass picotcp@tass.be 137:a1c8bfa9d691 538 {
tass picotcp@tass.be 137:a1c8bfa9d691 539 dbg("Cannot alloc incoming frame!\n");
TASS Belgium NV 131:4758606c9316 540 return -1;
tass picotcp@tass.be 137:a1c8bfa9d691 541 }
TASS Belgium NV 131:4758606c9316 542
TASS Belgium NV 131:4758606c9316 543 /* Association to the device that just received the frame. */
TASS Belgium NV 131:4758606c9316 544 f->dev = dev;
tass 68:0847e35d08a6 545
tass picotcp@tass.be 137:a1c8bfa9d691 546 /* Setup the start pointer, length. */
TASS Belgium NV 131:4758606c9316 547 f->start = f->buffer;
TASS Belgium NV 131:4758606c9316 548 f->len = f->buffer_len;
TASS Belgium NV 131:4758606c9316 549 if (f->len > 8) {
TASS Belgium NV 131:4758606c9316 550 uint32_t mid_frame = (f->buffer_len >> 2) << 1;
TASS Belgium NV 131:4758606c9316 551 mid_frame -= (mid_frame % 4);
TASS Belgium NV 131:4758606c9316 552 pico_rand_feed(*(uint32_t*)(f->buffer + mid_frame));
TASS Belgium NV 131:4758606c9316 553 }
TASS Belgium NV 131:4758606c9316 554
TASS Belgium NV 131:4758606c9316 555 memcpy(f->buffer, buffer, len);
TASS Belgium NV 131:4758606c9316 556 ret = pico_enqueue(dev->q_in, f);
TASS Belgium NV 131:4758606c9316 557 if (ret <= 0) {
TASS Belgium NV 131:4758606c9316 558 pico_frame_discard(f);
TASS Belgium NV 131:4758606c9316 559 }
TASS Belgium NV 131:4758606c9316 560
TASS Belgium NV 131:4758606c9316 561 return ret;
tass 68:0847e35d08a6 562 }
tass 68:0847e35d08a6 563
tass picotcp@tass.be 149:5f4cb161cec3 564 int32_t pico_stack_recv_zerocopy(struct pico_device *dev, uint8_t *buffer, uint32_t len)
tass picotcp@tass.be 149:5f4cb161cec3 565 {
tass picotcp@tass.be 149:5f4cb161cec3 566 struct pico_frame *f;
tass picotcp@tass.be 149:5f4cb161cec3 567 int ret;
tass picotcp@tass.be 149:5f4cb161cec3 568 if (len <= 0)
tass picotcp@tass.be 149:5f4cb161cec3 569 return -1;
tass picotcp@tass.be 149:5f4cb161cec3 570
tass picotcp@tass.be 149:5f4cb161cec3 571 f = pico_frame_alloc_skeleton(len);
tass picotcp@tass.be 149:5f4cb161cec3 572 if (!f)
tass picotcp@tass.be 149:5f4cb161cec3 573 {
tass picotcp@tass.be 149:5f4cb161cec3 574 dbg("Cannot alloc incoming frame!\n");
tass picotcp@tass.be 149:5f4cb161cec3 575 return -1;
tass picotcp@tass.be 149:5f4cb161cec3 576 }
tass picotcp@tass.be 149:5f4cb161cec3 577
tass picotcp@tass.be 149:5f4cb161cec3 578 if (pico_frame_skeleton_set_buffer(f, buffer) < 0)
tass picotcp@tass.be 149:5f4cb161cec3 579 {
tass picotcp@tass.be 149:5f4cb161cec3 580 dbg("Invalid zero-copy buffer!\n");
tass picotcp@tass.be 149:5f4cb161cec3 581 PICO_FREE(f->usage_count);
tass picotcp@tass.be 149:5f4cb161cec3 582 PICO_FREE(f);
tass picotcp@tass.be 149:5f4cb161cec3 583 return -1;
tass picotcp@tass.be 149:5f4cb161cec3 584 }
tass picotcp@tass.be 149:5f4cb161cec3 585
tass picotcp@tass.be 149:5f4cb161cec3 586 f->dev = dev;
tass picotcp@tass.be 149:5f4cb161cec3 587 ret = pico_enqueue(dev->q_in, f);
tass picotcp@tass.be 149:5f4cb161cec3 588 if (ret <= 0) {
tass picotcp@tass.be 149:5f4cb161cec3 589 pico_frame_discard(f);
tass picotcp@tass.be 149:5f4cb161cec3 590 }
tass picotcp@tass.be 149:5f4cb161cec3 591
tass picotcp@tass.be 149:5f4cb161cec3 592 return ret;
tass picotcp@tass.be 149:5f4cb161cec3 593 }
tass picotcp@tass.be 149:5f4cb161cec3 594
tass 70:cd218dd180e5 595 int32_t pico_sendto_dev(struct pico_frame *f)
tass 68:0847e35d08a6 596 {
TASS Belgium NV 131:4758606c9316 597 if (!f->dev) {
TASS Belgium NV 131:4758606c9316 598 pico_frame_discard(f);
TASS Belgium NV 131:4758606c9316 599 return -1;
TASS Belgium NV 131:4758606c9316 600 } else {
TASS Belgium NV 131:4758606c9316 601 if (f->len > 8) {
TASS Belgium NV 131:4758606c9316 602 uint32_t mid_frame = (f->buffer_len >> 2) << 1;
TASS Belgium NV 131:4758606c9316 603 mid_frame -= (mid_frame % 4);
TASS Belgium NV 131:4758606c9316 604 pico_rand_feed(*(uint32_t*)(f->buffer + mid_frame));
TASS Belgium NV 131:4758606c9316 605 }
TASS Belgium NV 131:4758606c9316 606
TASS Belgium NV 131:4758606c9316 607 return pico_enqueue(f->dev->q_out, f);
tass 68:0847e35d08a6 608 }
tass 68:0847e35d08a6 609 }
tass 68:0847e35d08a6 610
tass 68:0847e35d08a6 611 struct pico_timer
tass 68:0847e35d08a6 612 {
TASS Belgium NV 131:4758606c9316 613 void *arg;
TASS Belgium NV 131:4758606c9316 614 void (*timer)(pico_time timestamp, void *arg);
tass 68:0847e35d08a6 615 };
tass 68:0847e35d08a6 616
tass 70:cd218dd180e5 617 struct pico_timer_ref
tass 70:cd218dd180e5 618 {
TASS Belgium NV 131:4758606c9316 619 pico_time expire;
TASS Belgium NV 131:4758606c9316 620 struct pico_timer *tmr;
tass 70:cd218dd180e5 621 };
tass 68:0847e35d08a6 622
tass 70:cd218dd180e5 623 typedef struct pico_timer_ref pico_timer_ref;
tass 68:0847e35d08a6 624
tass 70:cd218dd180e5 625 DECLARE_HEAP(pico_timer_ref, expire);
tass 70:cd218dd180e5 626
tass 70:cd218dd180e5 627 static heap_pico_timer_ref *Timers;
tass 68:0847e35d08a6 628
tass 68:0847e35d08a6 629 void pico_check_timers(void)
tass 68:0847e35d08a6 630 {
TASS Belgium NV 131:4758606c9316 631 struct pico_timer *t;
TASS Belgium NV 131:4758606c9316 632 struct pico_timer_ref tref_unused, *tref = heap_first(Timers);
TASS Belgium NV 131:4758606c9316 633 pico_tick = PICO_TIME_MS();
TASS Belgium NV 131:4758606c9316 634 while((tref) && (tref->expire < pico_tick)) {
TASS Belgium NV 131:4758606c9316 635 t = tref->tmr;
TASS Belgium NV 131:4758606c9316 636 if (t && t->timer)
TASS Belgium NV 131:4758606c9316 637 t->timer(pico_tick, t->arg);
TASS Belgium NV 131:4758606c9316 638
TASS Belgium NV 131:4758606c9316 639 if (t)
tass picotcp@tass.be 149:5f4cb161cec3 640 PICO_FREE(t);
TASS Belgium NV 131:4758606c9316 641
TASS Belgium NV 131:4758606c9316 642 t = NULL;
TASS Belgium NV 131:4758606c9316 643 heap_peek(Timers, &tref_unused);
TASS Belgium NV 131:4758606c9316 644 tref = heap_first(Timers);
TASS Belgium NV 131:4758606c9316 645 }
tass 70:cd218dd180e5 646 }
tass 70:cd218dd180e5 647
tass 70:cd218dd180e5 648 void pico_timer_cancel(struct pico_timer *t)
tass 70:cd218dd180e5 649 {
TASS Belgium NV 131:4758606c9316 650 uint32_t i;
TASS Belgium NV 131:4758606c9316 651 struct pico_timer_ref *tref = Timers->top;
TASS Belgium NV 131:4758606c9316 652 if (!t)
TASS Belgium NV 131:4758606c9316 653 return;
TASS Belgium NV 131:4758606c9316 654
TASS Belgium NV 131:4758606c9316 655 for (i = 1; i <= Timers->n; i++) {
TASS Belgium NV 131:4758606c9316 656 if (tref[i].tmr == t) {
TASS Belgium NV 131:4758606c9316 657 Timers->top[i].tmr = NULL;
tass picotcp@tass.be 149:5f4cb161cec3 658 PICO_FREE(t);
TASS Belgium NV 131:4758606c9316 659 break;
TASS Belgium NV 131:4758606c9316 660 }
tass 70:cd218dd180e5 661 }
tass 68:0847e35d08a6 662 }
tass 68:0847e35d08a6 663
tass 68:0847e35d08a6 664 #define PROTO_DEF_NR 11
tass 68:0847e35d08a6 665 #define PROTO_DEF_AVG_NR 4
tass 68:0847e35d08a6 666 #define PROTO_DEF_SCORE 32
tass 68:0847e35d08a6 667 #define PROTO_MIN_SCORE 32
tass 68:0847e35d08a6 668 #define PROTO_MAX_SCORE 128
tass 68:0847e35d08a6 669 #define PROTO_LAT_IND 3 /* latecy indication 0-3 (lower is better latency performance), x1, x2, x4, x8 */
TASS Belgium NV 131:4758606c9316 670 #define PROTO_MAX_LOOP (PROTO_MAX_SCORE << PROTO_LAT_IND) /* max global loop score, so per tick */
tass 68:0847e35d08a6 671
tass 68:0847e35d08a6 672 static int calc_score(int *score, int *index, int avg[][PROTO_DEF_AVG_NR], int *ret)
tass 68:0847e35d08a6 673 {
TASS Belgium NV 131:4758606c9316 674 int temp, i, j, sum;
TASS Belgium NV 131:4758606c9316 675 int max_total = PROTO_MAX_LOOP, total = 0;
tass 68:0847e35d08a6 676
TASS Belgium NV 131:4758606c9316 677 /* dbg("USED SCORES> "); */
tass 68:0847e35d08a6 678
TASS Belgium NV 131:4758606c9316 679 for (i = 0; i < PROTO_DEF_NR; i++) {
tass 68:0847e35d08a6 680
TASS Belgium NV 131:4758606c9316 681 /* if used looped score */
TASS Belgium NV 131:4758606c9316 682 if (ret[i] < score[i]) {
TASS Belgium NV 131:4758606c9316 683 temp = score[i] - ret[i]; /* remaining loop score */
TASS Belgium NV 131:4758606c9316 684
TASS Belgium NV 131:4758606c9316 685 /* dbg("%3d - ",temp); */
tass 68:0847e35d08a6 686
TASS Belgium NV 131:4758606c9316 687 if (index[i] >= PROTO_DEF_AVG_NR)
TASS Belgium NV 131:4758606c9316 688 index[i] = 0; /* reset index */
TASS Belgium NV 131:4758606c9316 689
TASS Belgium NV 131:4758606c9316 690 j = index[i];
TASS Belgium NV 131:4758606c9316 691 avg[i][j] = temp;
tass 68:0847e35d08a6 692
TASS Belgium NV 131:4758606c9316 693 index[i]++;
tass 68:0847e35d08a6 694
tass picotcp@tass.be 149:5f4cb161cec3 695 if (ret[i] == 0 && ((score[i] * 2) <= PROTO_MAX_SCORE) && ((total + (score[i] * 2)) < max_total)) { /* used all loop score -> increase next score directly */
tass picotcp@tass.be 149:5f4cb161cec3 696 score[i] *= 2;
TASS Belgium NV 131:4758606c9316 697 total += score[i];
TASS Belgium NV 131:4758606c9316 698 continue;
TASS Belgium NV 131:4758606c9316 699 }
tass 68:0847e35d08a6 700
TASS Belgium NV 131:4758606c9316 701 sum = 0;
TASS Belgium NV 131:4758606c9316 702 for (j = 0; j < PROTO_DEF_AVG_NR; j++)
TASS Belgium NV 131:4758606c9316 703 sum += avg[i][j]; /* calculate sum */
tass 68:0847e35d08a6 704
tass picotcp@tass.be 149:5f4cb161cec3 705 sum /= 4; /* divide by 4 to get average used score */
tass 68:0847e35d08a6 706
TASS Belgium NV 131:4758606c9316 707 /* criterion to increase next loop score */
tass picotcp@tass.be 149:5f4cb161cec3 708 if (sum > (score[i] - (score[i] / 4)) && ((score[i] * 2) <= PROTO_MAX_SCORE) && ((total + (score[i] / 2)) < max_total)) { /* > 3/4 */
tass picotcp@tass.be 149:5f4cb161cec3 709 score[i] *= 2; /* double loop score */
TASS Belgium NV 131:4758606c9316 710 total += score[i];
TASS Belgium NV 131:4758606c9316 711 continue;
TASS Belgium NV 131:4758606c9316 712 }
tass 68:0847e35d08a6 713
TASS Belgium NV 131:4758606c9316 714 /* criterion to decrease next loop score */
tass picotcp@tass.be 149:5f4cb161cec3 715 if ((sum < (score[i] / 4)) && ((score[i] / 2) >= PROTO_MIN_SCORE)) { /* < 1/4 */
tass picotcp@tass.be 149:5f4cb161cec3 716 score[i] /= 2; /* half loop score */
TASS Belgium NV 131:4758606c9316 717 total += score[i];
TASS Belgium NV 131:4758606c9316 718 continue;
TASS Belgium NV 131:4758606c9316 719 }
tass 68:0847e35d08a6 720
TASS Belgium NV 131:4758606c9316 721 /* also add non-changed scores */
TASS Belgium NV 131:4758606c9316 722 total += score[i];
TASS Belgium NV 131:4758606c9316 723 }
TASS Belgium NV 131:4758606c9316 724 else if (ret[i] == score[i]) {
TASS Belgium NV 131:4758606c9316 725 /* no used loop score - gradually decrease */
tass 68:0847e35d08a6 726
TASS Belgium NV 131:4758606c9316 727 /* dbg("%3d - ",0); */
TASS Belgium NV 131:4758606c9316 728
TASS Belgium NV 131:4758606c9316 729 if (index[i] >= PROTO_DEF_AVG_NR)
TASS Belgium NV 131:4758606c9316 730 index[i] = 0; /* reset index */
TASS Belgium NV 131:4758606c9316 731
TASS Belgium NV 131:4758606c9316 732 j = index[i];
TASS Belgium NV 131:4758606c9316 733 avg[i][j] = 0;
tass 68:0847e35d08a6 734
TASS Belgium NV 131:4758606c9316 735 index[i]++;
tass 68:0847e35d08a6 736
TASS Belgium NV 131:4758606c9316 737 sum = 0;
TASS Belgium NV 131:4758606c9316 738 for (j = 0; j < PROTO_DEF_AVG_NR; j++)
TASS Belgium NV 131:4758606c9316 739 sum += avg[i][j]; /* calculate sum */
tass 68:0847e35d08a6 740
tass picotcp@tass.be 149:5f4cb161cec3 741 sum /= 2; /* divide by 4 to get average used score */
tass 68:0847e35d08a6 742
tass picotcp@tass.be 149:5f4cb161cec3 743 if ((sum == 0) && ((score[i] / 2) >= PROTO_MIN_SCORE)) {
tass picotcp@tass.be 149:5f4cb161cec3 744 score[i] /= 2; /* half loop score */
TASS Belgium NV 131:4758606c9316 745 total += score[i];
TASS Belgium NV 131:4758606c9316 746 for (j = 0; j < PROTO_DEF_AVG_NR; j++)
TASS Belgium NV 131:4758606c9316 747 avg[i][j] = score[i];
TASS Belgium NV 131:4758606c9316 748 }
TASS Belgium NV 131:4758606c9316 749
TASS Belgium NV 131:4758606c9316 750 }
tass 68:0847e35d08a6 751 }
TASS Belgium NV 131:4758606c9316 752 /* dbg("\n"); */
tass 68:0847e35d08a6 753
TASS Belgium NV 131:4758606c9316 754 return 0;
tass 68:0847e35d08a6 755 }
tass 68:0847e35d08a6 756
tass 68:0847e35d08a6 757
tass 68:0847e35d08a6 758
TASS Belgium NV 131:4758606c9316 759 /*
tass 68:0847e35d08a6 760
TASS Belgium NV 131:4758606c9316 761 .
TASS Belgium NV 131:4758606c9316 762 .vS.
TASS Belgium NV 131:4758606c9316 763 <aoSo.
TASS Belgium NV 131:4758606c9316 764 .XoS22.
TASS Belgium NV 131:4758606c9316 765 .S2S22. ._... ...... ..._.
TASS Belgium NV 131:4758606c9316 766 :=|2S2X2|=++; <vSX2XX2z+ |vSSSXSSs>. :iXXZUZXXe=
TASS Belgium NV 131:4758606c9316 767 )2SS2SS2S2S2I =oS2S2S2S2X22;. _vuXS22S2S2S22i ._wZZXZZZXZZXZX=
TASS Belgium NV 131:4758606c9316 768 )22S2S2S2S2Sl |S2S2S22S2SSSXc: .S2SS2S2S22S2SS= .]#XZZZXZXZZZZZZ:
TASS Belgium NV 131:4758606c9316 769 )oSS2SS2S2Sol |2}!"""!32S22S(. uS2S2Se**12oS2e ]dXZZXX2?YYXXXZ*
TASS Belgium NV 131:4758606c9316 770 .:2S2So:..-. . :]S2S2e;=X2SS2o .)oc ]XZZXZ( =nX:
TASS Belgium NV 131:4758606c9316 771 .S2S22. ___s_i,.)oS2So(;2SS2So, ` 3XZZZZc, -
TASS Belgium NV 131:4758606c9316 772 .S2SSo. =oXXXSSS2XoS2S2o( XS2S2XSos;. ]ZZZZXXXX|=
TASS Belgium NV 131:4758606c9316 773 .S2S22. .)S2S2S22S2S2S2S2o( "X2SS2S2S2Sus,, +3XZZZZZXZZoos_
TASS Belgium NV 131:4758606c9316 774 .S2S22. .]2S2SS22S222S2SS2o( ]S22S2S2S222So :3XXZZZZZZZZXXv
TASS Belgium NV 131:4758606c9316 775 .S2S22. =u2SS2e"~---"{2S2So( -"12S2S2SSS2Su. "?SXXXZXZZZZXo
TASS Belgium NV 131:4758606c9316 776 .S2SSo. )SS22z; :S2S2o( ={vS2S2S22v .<vXZZZZZZZ;
TASS Belgium NV 131:4758606c9316 777 .S2S2S: ]oSS2c; =22S2o( -"S2SS2n ~4XXZXZ(
TASS Belgium NV 131:4758606c9316 778 .2S2S2i )2S2S2[. .)XS2So( <;. .2S2S2o :<. ]XZZZX(
TASS Belgium NV 131:4758606c9316 779 nX2S2S,,_s_=3oSS2SoaasuXXS2S2o( .oXoasi_aioSSS22l.]dZoaas_aadXZZXZ'
TASS Belgium NV 131:4758606c9316 780 vS2SSSXXX2; )S2S2S2SoS2S2S2S2o( iS2S222XSoSS22So.)nXZZXXXZZXXZZXZo
TASS Belgium NV 131:4758606c9316 781 x32S22S2Sn -+S2S2S2S2So22S2So( 12S2SS2S2SS22S}- )SXXZZZZZZZZZXX!-
TASS Belgium NV 131:4758606c9316 782 .)S22222i .i2S2S2o>;:S2S2o( .<vSoSoSo2S(; :nXXXXXZXXX(
TASS Belgium NV 131:4758606c9316 783 .-~~~~- --- . - - --~~~-- --^^~~-
TASS Belgium NV 131:4758606c9316 784 .
tass 68:0847e35d08a6 785
tass 68:0847e35d08a6 786
TASS Belgium NV 131:4758606c9316 787 ... curious about our source code? We are hiring! mailto:<recruiting@tass.be>
TASS Belgium NV 131:4758606c9316 788
TASS Belgium NV 131:4758606c9316 789
TASS Belgium NV 131:4758606c9316 790 */
tass 68:0847e35d08a6 791
tass 68:0847e35d08a6 792 void pico_stack_tick(void)
tass 68:0847e35d08a6 793 {
TASS Belgium NV 131:4758606c9316 794 static int score[PROTO_DEF_NR] = {
TASS Belgium NV 131:4758606c9316 795 PROTO_DEF_SCORE, PROTO_DEF_SCORE, PROTO_DEF_SCORE, PROTO_DEF_SCORE, PROTO_DEF_SCORE, PROTO_DEF_SCORE, PROTO_DEF_SCORE, PROTO_DEF_SCORE, PROTO_DEF_SCORE, PROTO_DEF_SCORE, PROTO_DEF_SCORE
TASS Belgium NV 131:4758606c9316 796 };
TASS Belgium NV 131:4758606c9316 797 static int index[PROTO_DEF_NR] = {
TASS Belgium NV 131:4758606c9316 798 0, 0, 0, 0, 0, 0
TASS Belgium NV 131:4758606c9316 799 };
tass 68:0847e35d08a6 800 static int avg[PROTO_DEF_NR][PROTO_DEF_AVG_NR];
TASS Belgium NV 131:4758606c9316 801 static int ret[PROTO_DEF_NR] = {
TASS Belgium NV 131:4758606c9316 802 0
TASS Belgium NV 131:4758606c9316 803 };
tass 68:0847e35d08a6 804
tass 68:0847e35d08a6 805 pico_check_timers();
tass 68:0847e35d08a6 806
TASS Belgium NV 131:4758606c9316 807 /* dbg("LOOP_SCORES> %3d - %3d - %3d - %3d - %3d - %3d - %3d - %3d - %3d - %3d - %3d\n",score[0],score[1],score[2],score[3],score[4],score[5],score[6],score[7],score[8],score[9],score[10]); */
tass 68:0847e35d08a6 808
TASS Belgium NV 131:4758606c9316 809 /* score = pico_protocols_loop(100); */
tass 68:0847e35d08a6 810
TASS Belgium NV 131:4758606c9316 811 ret[0] = pico_devices_loop(score[0], PICO_LOOP_DIR_IN);
tass 70:cd218dd180e5 812 pico_rand_feed((uint32_t)ret[0]);
tass 68:0847e35d08a6 813
tass 68:0847e35d08a6 814 ret[1] = pico_protocol_datalink_loop(score[1], PICO_LOOP_DIR_IN);
tass 70:cd218dd180e5 815 pico_rand_feed((uint32_t)ret[1]);
tass 68:0847e35d08a6 816
tass 68:0847e35d08a6 817 ret[2] = pico_protocol_network_loop(score[2], PICO_LOOP_DIR_IN);
tass 70:cd218dd180e5 818 pico_rand_feed((uint32_t)ret[2]);
tass 68:0847e35d08a6 819
tass 68:0847e35d08a6 820 ret[3] = pico_protocol_transport_loop(score[3], PICO_LOOP_DIR_IN);
tass 70:cd218dd180e5 821 pico_rand_feed((uint32_t)ret[3]);
tass 68:0847e35d08a6 822
tass 68:0847e35d08a6 823
tass 68:0847e35d08a6 824 ret[5] = score[5];
tass 68:0847e35d08a6 825 #if defined (PICO_SUPPORT_IPV4) || defined (PICO_SUPPORT_IPV6)
tass 68:0847e35d08a6 826 #if defined (PICO_SUPPORT_TCP) || defined (PICO_SUPPORT_UDP)
TASS Belgium NV 131:4758606c9316 827 ret[5] = pico_sockets_loop(score[5]); /* swapped */
tass 70:cd218dd180e5 828 pico_rand_feed((uint32_t)ret[5]);
tass 68:0847e35d08a6 829 #endif
tass 68:0847e35d08a6 830 #endif
tass 68:0847e35d08a6 831
tass 68:0847e35d08a6 832 ret[4] = pico_protocol_socket_loop(score[4], PICO_LOOP_DIR_IN);
tass 70:cd218dd180e5 833 pico_rand_feed((uint32_t)ret[4]);
tass 68:0847e35d08a6 834
tass 68:0847e35d08a6 835
tass 68:0847e35d08a6 836 ret[6] = pico_protocol_socket_loop(score[6], PICO_LOOP_DIR_OUT);
tass 70:cd218dd180e5 837 pico_rand_feed((uint32_t)ret[6]);
tass 68:0847e35d08a6 838
tass 68:0847e35d08a6 839 ret[7] = pico_protocol_transport_loop(score[7], PICO_LOOP_DIR_OUT);
tass 70:cd218dd180e5 840 pico_rand_feed((uint32_t)ret[7]);
tass 68:0847e35d08a6 841
tass 68:0847e35d08a6 842 ret[8] = pico_protocol_network_loop(score[8], PICO_LOOP_DIR_OUT);
tass 70:cd218dd180e5 843 pico_rand_feed((uint32_t)ret[8]);
tass 68:0847e35d08a6 844
tass 68:0847e35d08a6 845 ret[9] = pico_protocol_datalink_loop(score[9], PICO_LOOP_DIR_OUT);
tass 70:cd218dd180e5 846 pico_rand_feed((uint32_t)ret[9]);
tass 68:0847e35d08a6 847
TASS Belgium NV 131:4758606c9316 848 ret[10] = pico_devices_loop(score[10], PICO_LOOP_DIR_OUT);
tass 70:cd218dd180e5 849 pico_rand_feed((uint32_t)ret[10]);
tass 68:0847e35d08a6 850
tass 68:0847e35d08a6 851 /* calculate new loop scores for next iteration */
TASS Belgium NV 131:4758606c9316 852 calc_score(score, index, (int (*)[])avg, ret);
tass 68:0847e35d08a6 853 }
tass 68:0847e35d08a6 854
tass 68:0847e35d08a6 855 void pico_stack_loop(void)
tass 68:0847e35d08a6 856 {
TASS Belgium NV 131:4758606c9316 857 while(1) {
TASS Belgium NV 131:4758606c9316 858 pico_stack_tick();
TASS Belgium NV 131:4758606c9316 859 PICO_IDLE();
TASS Belgium NV 131:4758606c9316 860 }
tass 68:0847e35d08a6 861 }
tass 68:0847e35d08a6 862
tass 128:ae39e6e81531 863 struct pico_timer *pico_timer_add(pico_time expire, void (*timer)(pico_time, void *), void *arg)
tass 68:0847e35d08a6 864 {
tass picotcp@tass.be 149:5f4cb161cec3 865 struct pico_timer *t = PICO_ZALLOC(sizeof(struct pico_timer));
TASS Belgium NV 131:4758606c9316 866 struct pico_timer_ref tref;
TASS Belgium NV 131:4758606c9316 867 if (!t) {
TASS Belgium NV 131:4758606c9316 868 pico_err = PICO_ERR_ENOMEM;
TASS Belgium NV 131:4758606c9316 869 return NULL;
TASS Belgium NV 131:4758606c9316 870 }
TASS Belgium NV 131:4758606c9316 871
TASS Belgium NV 131:4758606c9316 872 tref.expire = PICO_TIME_MS() + expire;
TASS Belgium NV 131:4758606c9316 873 t->arg = arg;
TASS Belgium NV 131:4758606c9316 874 t->timer = timer;
TASS Belgium NV 131:4758606c9316 875 tref.tmr = t;
tass picotcp@tass.be 138:0a7a449980e6 876 heap_insert(Timers, &tref);
TASS Belgium NV 131:4758606c9316 877 if (Timers->n > PICO_MAX_TIMERS) {
tass picotcp@tass.be 149:5f4cb161cec3 878 dbg("Warning: I have %d timers\n", Timers->n);
TASS Belgium NV 131:4758606c9316 879 }
TASS Belgium NV 131:4758606c9316 880
TASS Belgium NV 131:4758606c9316 881 return t;
tass 68:0847e35d08a6 882 }
tass 68:0847e35d08a6 883
tass picotcp@tass.be 149:5f4cb161cec3 884 int pico_stack_init(void)
tass 68:0847e35d08a6 885 {
tass 68:0847e35d08a6 886
tass 68:0847e35d08a6 887 #ifdef PICO_SUPPORT_IPV4
TASS Belgium NV 131:4758606c9316 888 pico_protocol_init(&pico_proto_ipv4);
tass 68:0847e35d08a6 889 #endif
tass 68:0847e35d08a6 890
tass 68:0847e35d08a6 891 #ifdef PICO_SUPPORT_IPV6
TASS Belgium NV 131:4758606c9316 892 pico_protocol_init(&pico_proto_ipv6);
tass 68:0847e35d08a6 893 #endif
tass 68:0847e35d08a6 894
tass 68:0847e35d08a6 895 #ifdef PICO_SUPPORT_ICMP4
TASS Belgium NV 131:4758606c9316 896 pico_protocol_init(&pico_proto_icmp4);
tass 68:0847e35d08a6 897 #endif
tass 68:0847e35d08a6 898
tass picotcp@tass.be 149:5f4cb161cec3 899 #ifdef PICO_SUPPORT_ICMP6
tass picotcp@tass.be 149:5f4cb161cec3 900 pico_protocol_init(&pico_proto_icmp6);
tass picotcp@tass.be 149:5f4cb161cec3 901 #endif
tass picotcp@tass.be 149:5f4cb161cec3 902
tass 68:0847e35d08a6 903 #ifdef PICO_SUPPORT_IGMP
TASS Belgium NV 131:4758606c9316 904 pico_protocol_init(&pico_proto_igmp);
tass 68:0847e35d08a6 905 #endif
tass 68:0847e35d08a6 906
tass 68:0847e35d08a6 907 #ifdef PICO_SUPPORT_UDP
TASS Belgium NV 131:4758606c9316 908 pico_protocol_init(&pico_proto_udp);
tass 68:0847e35d08a6 909 #endif
tass 68:0847e35d08a6 910
tass 68:0847e35d08a6 911 #ifdef PICO_SUPPORT_TCP
TASS Belgium NV 131:4758606c9316 912 pico_protocol_init(&pico_proto_tcp);
tass 68:0847e35d08a6 913 #endif
tass 68:0847e35d08a6 914
tass 68:0847e35d08a6 915 #ifdef PICO_SUPPORT_DNS_CLIENT
TASS Belgium NV 131:4758606c9316 916 pico_dns_client_init();
tass 68:0847e35d08a6 917 #endif
tass 68:0847e35d08a6 918
TASS Belgium NV 131:4758606c9316 919 pico_rand_feed(123456);
tass 68:0847e35d08a6 920
TASS Belgium NV 131:4758606c9316 921 /* Initialize timer heap */
TASS Belgium NV 131:4758606c9316 922 Timers = heap_init();
tass picotcp@tass.be 149:5f4cb161cec3 923 if (!Timers)
tass picotcp@tass.be 149:5f4cb161cec3 924 return -1;
tass picotcp@tass.be 149:5f4cb161cec3 925
tass picotcp@tass.be 149:5f4cb161cec3 926 #if ((defined PICO_SUPPORT_IPV4) && (defined PICO_SUPPORT_ETH))
tass picotcp@tass.be 149:5f4cb161cec3 927 /* Initialize ARP module */
tass picotcp@tass.be 133:5b075f5e141a 928 pico_arp_init();
tass picotcp@tass.be 149:5f4cb161cec3 929 #endif
tass picotcp@tass.be 149:5f4cb161cec3 930
tass picotcp@tass.be 149:5f4cb161cec3 931 #ifdef PICO_SUPPORT_IPV6
tass picotcp@tass.be 149:5f4cb161cec3 932 /* Initialize Neighbor discovery module */
tass picotcp@tass.be 149:5f4cb161cec3 933 pico_ipv6_nd_init();
tass picotcp@tass.be 149:5f4cb161cec3 934 #endif
TASS Belgium NV 131:4758606c9316 935 pico_stack_tick();
TASS Belgium NV 131:4758606c9316 936 pico_stack_tick();
TASS Belgium NV 131:4758606c9316 937 pico_stack_tick();
tass picotcp@tass.be 149:5f4cb161cec3 938 return 0;
tass 68:0847e35d08a6 939 }
tass 68:0847e35d08a6 940