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