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 10:13:37 2014 +0100
Revision:
133:5b075f5e141a
Parent:
131:4758606c9316
Child:
134:cc4e6d2654d9
Update from master branch

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tass 68:0847e35d08a6 1 /*********************************************************************
TASS Belgium NV 131:4758606c9316 2 PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
TASS Belgium NV 131:4758606c9316 3 See LICENSE and COPYING for usage.
tass 68:0847e35d08a6 4
TASS Belgium NV 131:4758606c9316 5 .
tass 68:0847e35d08a6 6
TASS Belgium NV 131:4758606c9316 7 Authors: Daniele Lacamera
TASS Belgium NV 131:4758606c9316 8 *********************************************************************/
tass 68:0847e35d08a6 9
tass 68:0847e35d08a6 10
tass 68:0847e35d08a6 11 #include "pico_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 68:0847e35d08a6 307 #endif
TASS Belgium NV 131:4758606c9316 308 return 0;
tass 68:0847e35d08a6 309 }
tass 68:0847e35d08a6 310
tass 68:0847e35d08a6 311 #ifdef PICO_SUPPORT_MCAST
tass 68:0847e35d08a6 312 static int destination_is_mcast(struct pico_frame *f)
tass 68:0847e35d08a6 313 {
TASS Belgium NV 131:4758606c9316 314 if (!f)
TASS Belgium NV 131:4758606c9316 315 return 0;
tass 68:0847e35d08a6 316
TASS Belgium NV 131:4758606c9316 317 if (IS_IPV6(f))
TASS Belgium NV 131:4758606c9316 318 return 0;
TASS Belgium NV 131:4758606c9316 319
tass 68:0847e35d08a6 320 #ifdef PICO_SUPPORT_IPV4
TASS Belgium NV 131:4758606c9316 321 else {
TASS Belgium NV 131:4758606c9316 322 struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr;
TASS Belgium NV 131:4758606c9316 323 return pico_ipv4_is_multicast(hdr->dst.addr);
TASS Belgium NV 131:4758606c9316 324 }
tass 68:0847e35d08a6 325 #endif
TASS Belgium NV 131:4758606c9316 326 return 0;
tass 68:0847e35d08a6 327 }
tass 68:0847e35d08a6 328
tass 68:0847e35d08a6 329 static struct pico_eth *pico_ethernet_mcast_translate(struct pico_frame *f, uint8_t *pico_mcast_mac)
tass 68:0847e35d08a6 330 {
TASS Belgium NV 131:4758606c9316 331 struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr;
tass 68:0847e35d08a6 332
TASS Belgium NV 131:4758606c9316 333 /* place 23 lower bits of IP in lower 23 bits of MAC */
TASS Belgium NV 131:4758606c9316 334 pico_mcast_mac[5] = (long_be(hdr->dst.addr) & 0x000000FF);
TASS Belgium NV 131:4758606c9316 335 pico_mcast_mac[4] = (uint8_t)((long_be(hdr->dst.addr) & 0x0000FF00) >> 8);
TASS Belgium NV 131:4758606c9316 336 pico_mcast_mac[3] = (uint8_t)((long_be(hdr->dst.addr) & 0x007F0000) >> 16);
tass 68:0847e35d08a6 337
TASS Belgium NV 131:4758606c9316 338 return (struct pico_eth *)pico_mcast_mac;
tass 68:0847e35d08a6 339 }
tass 68:0847e35d08a6 340
tass 68:0847e35d08a6 341
tass 68:0847e35d08a6 342 #endif /* PICO_SUPPORT_MCAST */
tass 68:0847e35d08a6 343
tass 68:0847e35d08a6 344 /* This is called by dev loop in order to ensure correct ethernet addressing.
tass 68:0847e35d08a6 345 * Returns 0 if the destination is unknown, and -1 if the packet is not deliverable
TASS Belgium NV 131:4758606c9316 346 * due to ethernet addressing (i.e., no arp association was possible.
tass 68:0847e35d08a6 347 *
tass 68:0847e35d08a6 348 * Only IP packets must pass by this. ARP will always use direct dev->send() function, so
tass 68:0847e35d08a6 349 * we assume IP is used.
tass 68:0847e35d08a6 350 */
tass 70:cd218dd180e5 351 int32_t pico_ethernet_send(struct pico_frame *f)
tass 68:0847e35d08a6 352 {
TASS Belgium NV 131:4758606c9316 353 const struct pico_eth *dstmac = NULL;
TASS Belgium NV 131:4758606c9316 354 int32_t ret = -1;
tass 68:0847e35d08a6 355
TASS Belgium NV 131:4758606c9316 356 if (IS_IPV6(f)) {
TASS Belgium NV 131:4758606c9316 357 /*TODO: Neighbor solicitation */
TASS Belgium NV 131:4758606c9316 358 dstmac = NULL;
tass 68:0847e35d08a6 359 }
TASS Belgium NV 131:4758606c9316 360
TASS Belgium NV 131:4758606c9316 361 else if (IS_IPV4(f)) {
TASS Belgium NV 131:4758606c9316 362 if (IS_BCAST(f) || destination_is_bcast(f)) {
TASS Belgium NV 131:4758606c9316 363 dstmac = (const struct pico_eth *const) PICO_ETHADDR_ALL;
TASS Belgium NV 131:4758606c9316 364 }
tass 68:0847e35d08a6 365
TASS Belgium NV 131:4758606c9316 366 #ifdef PICO_SUPPORT_MCAST
TASS Belgium NV 131:4758606c9316 367 else if (destination_is_mcast(f)) {
TASS Belgium NV 131:4758606c9316 368 uint8_t pico_mcast_mac[6] = {
TASS Belgium NV 131:4758606c9316 369 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00
TASS Belgium NV 131:4758606c9316 370 };
TASS Belgium NV 131:4758606c9316 371 dstmac = pico_ethernet_mcast_translate(f, pico_mcast_mac);
TASS Belgium NV 131:4758606c9316 372 }
TASS Belgium NV 131:4758606c9316 373 #endif
TASS Belgium NV 131:4758606c9316 374 else {
TASS Belgium NV 131:4758606c9316 375 dstmac = pico_arp_get(f);
TASS Belgium NV 131:4758606c9316 376 if (!dstmac)
TASS Belgium NV 131:4758606c9316 377 return 0;
TASS Belgium NV 131:4758606c9316 378 }
TASS Belgium NV 131:4758606c9316 379 /* This sets destination and source address, then pushes the packet to the device. */
TASS Belgium NV 131:4758606c9316 380 if (dstmac && (f->start > f->buffer) && ((f->start - f->buffer) >= PICO_SIZE_ETHHDR)) {
TASS Belgium NV 131:4758606c9316 381 struct pico_eth_hdr *hdr;
TASS Belgium NV 131:4758606c9316 382 f->start -= PICO_SIZE_ETHHDR;
TASS Belgium NV 131:4758606c9316 383 f->len += PICO_SIZE_ETHHDR;
TASS Belgium NV 131:4758606c9316 384 f->datalink_hdr = f->start;
TASS Belgium NV 131:4758606c9316 385 hdr = (struct pico_eth_hdr *) f->datalink_hdr;
TASS Belgium NV 131:4758606c9316 386 memcpy(hdr->saddr, f->dev->eth->mac.addr, PICO_SIZE_ETH);
TASS Belgium NV 131:4758606c9316 387 memcpy(hdr->daddr, dstmac, PICO_SIZE_ETH);
TASS Belgium NV 131:4758606c9316 388 hdr->proto = PICO_IDETH_IPV4;
TASS Belgium NV 131:4758606c9316 389 if(!memcmp(hdr->daddr, hdr->saddr, PICO_SIZE_ETH)) {
TASS Belgium NV 131:4758606c9316 390 dbg("sending out packet destined for our own mac\n");
TASS Belgium NV 131:4758606c9316 391 return pico_ethernet_receive(f);
TASS Belgium NV 131:4758606c9316 392 }else if(IS_LIMITED_BCAST(f)) {
TASS Belgium NV 131:4758606c9316 393 ret = pico_device_broadcast(f);
TASS Belgium NV 131:4758606c9316 394 }else {
TASS Belgium NV 131:4758606c9316 395 ret = (int32_t)f->dev->send(f->dev, f->start, (int) f->len);
TASS Belgium NV 131:4758606c9316 396 /* Frame is discarded after this return by the caller */
TASS Belgium NV 131:4758606c9316 397 }
TASS Belgium NV 131:4758606c9316 398
TASS Belgium NV 131:4758606c9316 399 if(!ret) pico_frame_discard(f);
TASS Belgium NV 131:4758606c9316 400
TASS Belgium NV 131:4758606c9316 401 return ret;
TASS Belgium NV 131:4758606c9316 402 } else {
TASS Belgium NV 131:4758606c9316 403 return -1;
TASS Belgium NV 131:4758606c9316 404 }
TASS Belgium NV 131:4758606c9316 405 } /* End IPV4 ethernet addressing */
TASS Belgium NV 131:4758606c9316 406
TASS Belgium NV 131:4758606c9316 407 return -1;
tass 68:0847e35d08a6 408
tass 68:0847e35d08a6 409 }
tass 68:0847e35d08a6 410
tass 68:0847e35d08a6 411 void pico_store_network_origin(void *src, struct pico_frame *f)
tass 68:0847e35d08a6 412 {
tass 68:0847e35d08a6 413 #ifdef PICO_SUPPORT_IPV4
TASS Belgium NV 131:4758606c9316 414 struct pico_ip4 *ip4;
tass 68:0847e35d08a6 415 #endif
tass 68:0847e35d08a6 416
tass 68:0847e35d08a6 417 #ifdef PICO_SUPPORT_IPV6
TASS Belgium NV 131:4758606c9316 418 struct pico_ip6 *ip6;
tass 68:0847e35d08a6 419 #endif
tass 68:0847e35d08a6 420
tass 68:0847e35d08a6 421 #ifdef PICO_SUPPORT_IPV4
TASS Belgium NV 131:4758606c9316 422 if (IS_IPV4(f)) {
TASS Belgium NV 131:4758606c9316 423 struct pico_ipv4_hdr *hdr;
TASS Belgium NV 131:4758606c9316 424 hdr = (struct pico_ipv4_hdr *) f->net_hdr;
TASS Belgium NV 131:4758606c9316 425 ip4 = (struct pico_ip4 *) src;
TASS Belgium NV 131:4758606c9316 426 ip4->addr = hdr->src.addr;
TASS Belgium NV 131:4758606c9316 427 }
TASS Belgium NV 131:4758606c9316 428
tass 68:0847e35d08a6 429 #endif
tass 68:0847e35d08a6 430 #ifdef PICO_SUPPORT_IPV6
TASS Belgium NV 131:4758606c9316 431 if (IS_IPV6(f)) {
TASS Belgium NV 131:4758606c9316 432 struct pico_ipv6_hdr *hdr;
TASS Belgium NV 131:4758606c9316 433 hdr = (struct pico_ipv6_hdr *) f->net_hdr;
TASS Belgium NV 131:4758606c9316 434 ip6 = (struct pico_ip6 *) src;
TASS Belgium NV 131:4758606c9316 435 memcpy(ip6->addr, hdr->src.addr, PICO_SIZE_IP6);
TASS Belgium NV 131:4758606c9316 436 }
TASS Belgium NV 131:4758606c9316 437
tass 68:0847e35d08a6 438 #endif
tass 68:0847e35d08a6 439 }
tass 68:0847e35d08a6 440
tass 68:0847e35d08a6 441
tass 68:0847e35d08a6 442 /* LOWEST LEVEL: interface towards devices. */
tass 68:0847e35d08a6 443 /* Device driver will call this function which returns immediately.
tass 68:0847e35d08a6 444 * Incoming packet will be processed later on in the dev loop.
tass 68:0847e35d08a6 445 */
tass 70:cd218dd180e5 446 int32_t pico_stack_recv(struct pico_device *dev, uint8_t *buffer, uint32_t len)
tass 68:0847e35d08a6 447 {
TASS Belgium NV 131:4758606c9316 448 struct pico_frame *f;
TASS Belgium NV 131:4758606c9316 449 int32_t ret;
TASS Belgium NV 131:4758606c9316 450 if (len <= 0)
TASS Belgium NV 131:4758606c9316 451 return -1;
tass 68:0847e35d08a6 452
TASS Belgium NV 131:4758606c9316 453 f = pico_frame_alloc(len);
TASS Belgium NV 131:4758606c9316 454 if (!f)
TASS Belgium NV 131:4758606c9316 455 return -1;
TASS Belgium NV 131:4758606c9316 456
TASS Belgium NV 131:4758606c9316 457 /* Association to the device that just received the frame. */
TASS Belgium NV 131:4758606c9316 458 f->dev = dev;
tass 68:0847e35d08a6 459
TASS Belgium NV 131:4758606c9316 460 /* Setup the start pointer, lenght. */
TASS Belgium NV 131:4758606c9316 461 f->start = f->buffer;
TASS Belgium NV 131:4758606c9316 462 f->len = f->buffer_len;
TASS Belgium NV 131:4758606c9316 463 if (f->len > 8) {
TASS Belgium NV 131:4758606c9316 464 uint32_t mid_frame = (f->buffer_len >> 2) << 1;
TASS Belgium NV 131:4758606c9316 465 mid_frame -= (mid_frame % 4);
TASS Belgium NV 131:4758606c9316 466 pico_rand_feed(*(uint32_t*)(f->buffer + mid_frame));
TASS Belgium NV 131:4758606c9316 467 }
TASS Belgium NV 131:4758606c9316 468
TASS Belgium NV 131:4758606c9316 469 memcpy(f->buffer, buffer, len);
TASS Belgium NV 131:4758606c9316 470 ret = pico_enqueue(dev->q_in, f);
TASS Belgium NV 131:4758606c9316 471 if (ret <= 0) {
TASS Belgium NV 131:4758606c9316 472 pico_frame_discard(f);
TASS Belgium NV 131:4758606c9316 473 }
TASS Belgium NV 131:4758606c9316 474
TASS Belgium NV 131:4758606c9316 475 return ret;
tass 68:0847e35d08a6 476 }
tass 68:0847e35d08a6 477
tass 70:cd218dd180e5 478 int32_t pico_sendto_dev(struct pico_frame *f)
tass 68:0847e35d08a6 479 {
TASS Belgium NV 131:4758606c9316 480 if (!f->dev) {
TASS Belgium NV 131:4758606c9316 481 pico_frame_discard(f);
TASS Belgium NV 131:4758606c9316 482 return -1;
TASS Belgium NV 131:4758606c9316 483 } else {
TASS Belgium NV 131:4758606c9316 484 if (f->len > 8) {
TASS Belgium NV 131:4758606c9316 485 uint32_t mid_frame = (f->buffer_len >> 2) << 1;
TASS Belgium NV 131:4758606c9316 486 mid_frame -= (mid_frame % 4);
TASS Belgium NV 131:4758606c9316 487 pico_rand_feed(*(uint32_t*)(f->buffer + mid_frame));
TASS Belgium NV 131:4758606c9316 488 }
TASS Belgium NV 131:4758606c9316 489
TASS Belgium NV 131:4758606c9316 490 return pico_enqueue(f->dev->q_out, f);
tass 68:0847e35d08a6 491 }
tass 68:0847e35d08a6 492 }
tass 68:0847e35d08a6 493
tass 68:0847e35d08a6 494 struct pico_timer
tass 68:0847e35d08a6 495 {
TASS Belgium NV 131:4758606c9316 496 uint32_t expire;
TASS Belgium NV 131:4758606c9316 497 void *arg;
TASS Belgium NV 131:4758606c9316 498 void (*timer)(pico_time timestamp, void *arg);
tass 68:0847e35d08a6 499 };
tass 68:0847e35d08a6 500
tass 70:cd218dd180e5 501 struct pico_timer_ref
tass 70:cd218dd180e5 502 {
TASS Belgium NV 131:4758606c9316 503 pico_time expire;
TASS Belgium NV 131:4758606c9316 504 struct pico_timer *tmr;
tass 70:cd218dd180e5 505 };
tass 68:0847e35d08a6 506
tass 70:cd218dd180e5 507 typedef struct pico_timer_ref pico_timer_ref;
tass 68:0847e35d08a6 508
tass 70:cd218dd180e5 509 DECLARE_HEAP(pico_timer_ref, expire);
tass 70:cd218dd180e5 510
tass 70:cd218dd180e5 511 static heap_pico_timer_ref *Timers;
tass 68:0847e35d08a6 512
tass 68:0847e35d08a6 513 void pico_check_timers(void)
tass 68:0847e35d08a6 514 {
TASS Belgium NV 131:4758606c9316 515 struct pico_timer *t;
TASS Belgium NV 131:4758606c9316 516 struct pico_timer_ref tref_unused, *tref = heap_first(Timers);
TASS Belgium NV 131:4758606c9316 517 pico_tick = PICO_TIME_MS();
TASS Belgium NV 131:4758606c9316 518 while((tref) && (tref->expire < pico_tick)) {
TASS Belgium NV 131:4758606c9316 519 t = tref->tmr;
TASS Belgium NV 131:4758606c9316 520 if (t && t->timer)
TASS Belgium NV 131:4758606c9316 521 t->timer(pico_tick, t->arg);
TASS Belgium NV 131:4758606c9316 522
TASS Belgium NV 131:4758606c9316 523 if (t)
TASS Belgium NV 131:4758606c9316 524 pico_free(t);
TASS Belgium NV 131:4758606c9316 525
TASS Belgium NV 131:4758606c9316 526 t = NULL;
TASS Belgium NV 131:4758606c9316 527 heap_peek(Timers, &tref_unused);
TASS Belgium NV 131:4758606c9316 528 tref = heap_first(Timers);
TASS Belgium NV 131:4758606c9316 529 }
tass 70:cd218dd180e5 530 }
tass 70:cd218dd180e5 531
tass 70:cd218dd180e5 532 void pico_timer_cancel(struct pico_timer *t)
tass 70:cd218dd180e5 533 {
TASS Belgium NV 131:4758606c9316 534 uint32_t i;
TASS Belgium NV 131:4758606c9316 535 struct pico_timer_ref *tref = Timers->top;
TASS Belgium NV 131:4758606c9316 536 if (!t)
TASS Belgium NV 131:4758606c9316 537 return;
TASS Belgium NV 131:4758606c9316 538
TASS Belgium NV 131:4758606c9316 539 for (i = 1; i <= Timers->n; i++) {
TASS Belgium NV 131:4758606c9316 540 if (tref[i].tmr == t) {
TASS Belgium NV 131:4758606c9316 541 Timers->top[i].tmr = NULL;
TASS Belgium NV 131:4758606c9316 542 pico_free(t);
TASS Belgium NV 131:4758606c9316 543 break;
TASS Belgium NV 131:4758606c9316 544 }
tass 70:cd218dd180e5 545 }
tass 68:0847e35d08a6 546 }
tass 68:0847e35d08a6 547
tass 68:0847e35d08a6 548
tass 68:0847e35d08a6 549 #define PROTO_DEF_NR 11
tass 68:0847e35d08a6 550 #define PROTO_DEF_AVG_NR 4
tass 68:0847e35d08a6 551 #define PROTO_DEF_SCORE 32
tass 68:0847e35d08a6 552 #define PROTO_MIN_SCORE 32
tass 68:0847e35d08a6 553 #define PROTO_MAX_SCORE 128
tass 68:0847e35d08a6 554 #define PROTO_LAT_IND 3 /* latecy indication 0-3 (lower is better latency performance), x1, x2, x4, x8 */
TASS Belgium NV 131:4758606c9316 555 #define PROTO_MAX_LOOP (PROTO_MAX_SCORE << PROTO_LAT_IND) /* max global loop score, so per tick */
tass 68:0847e35d08a6 556
tass 68:0847e35d08a6 557 static int calc_score(int *score, int *index, int avg[][PROTO_DEF_AVG_NR], int *ret)
tass 68:0847e35d08a6 558 {
TASS Belgium NV 131:4758606c9316 559 int temp, i, j, sum;
TASS Belgium NV 131:4758606c9316 560 int max_total = PROTO_MAX_LOOP, total = 0;
tass 68:0847e35d08a6 561
TASS Belgium NV 131:4758606c9316 562 /* dbg("USED SCORES> "); */
tass 68:0847e35d08a6 563
TASS Belgium NV 131:4758606c9316 564 for (i = 0; i < PROTO_DEF_NR; i++) {
tass 68:0847e35d08a6 565
TASS Belgium NV 131:4758606c9316 566 /* if used looped score */
TASS Belgium NV 131:4758606c9316 567 if (ret[i] < score[i]) {
TASS Belgium NV 131:4758606c9316 568 temp = score[i] - ret[i]; /* remaining loop score */
TASS Belgium NV 131:4758606c9316 569
TASS Belgium NV 131:4758606c9316 570 /* dbg("%3d - ",temp); */
tass 68:0847e35d08a6 571
TASS Belgium NV 131:4758606c9316 572 if (index[i] >= PROTO_DEF_AVG_NR)
TASS Belgium NV 131:4758606c9316 573 index[i] = 0; /* reset index */
TASS Belgium NV 131:4758606c9316 574
TASS Belgium NV 131:4758606c9316 575 j = index[i];
TASS Belgium NV 131:4758606c9316 576 avg[i][j] = temp;
tass 68:0847e35d08a6 577
TASS Belgium NV 131:4758606c9316 578 index[i]++;
tass 68:0847e35d08a6 579
TASS Belgium NV 131:4758606c9316 580 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 581 score[i] <<= 1;
TASS Belgium NV 131:4758606c9316 582 total += score[i];
TASS Belgium NV 131:4758606c9316 583 continue;
TASS Belgium NV 131:4758606c9316 584 }
tass 68:0847e35d08a6 585
TASS Belgium NV 131:4758606c9316 586 sum = 0;
TASS Belgium NV 131:4758606c9316 587 for (j = 0; j < PROTO_DEF_AVG_NR; j++)
TASS Belgium NV 131:4758606c9316 588 sum += avg[i][j]; /* calculate sum */
tass 68:0847e35d08a6 589
TASS Belgium NV 131:4758606c9316 590 sum >>= 2; /* divide by 4 to get average used score */
tass 68:0847e35d08a6 591
TASS Belgium NV 131:4758606c9316 592 /* criterion to increase next loop score */
TASS Belgium NV 131:4758606c9316 593 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 594 score[i] <<= 1; /* double loop score */
TASS Belgium NV 131:4758606c9316 595 total += score[i];
TASS Belgium NV 131:4758606c9316 596 continue;
TASS Belgium NV 131:4758606c9316 597 }
tass 68:0847e35d08a6 598
TASS Belgium NV 131:4758606c9316 599 /* criterion to decrease next loop score */
TASS Belgium NV 131:4758606c9316 600 if (sum < (score[i] >> 2) && (score[i] >> 1 >= PROTO_MIN_SCORE)) { /* < 1/4 */
TASS Belgium NV 131:4758606c9316 601 score[i] >>= 1; /* half loop score */
TASS Belgium NV 131:4758606c9316 602 total += score[i];
TASS Belgium NV 131:4758606c9316 603 continue;
TASS Belgium NV 131:4758606c9316 604 }
tass 68:0847e35d08a6 605
TASS Belgium NV 131:4758606c9316 606 /* also add non-changed scores */
TASS Belgium NV 131:4758606c9316 607 total += score[i];
TASS Belgium NV 131:4758606c9316 608 }
TASS Belgium NV 131:4758606c9316 609 else if (ret[i] == score[i]) {
TASS Belgium NV 131:4758606c9316 610 /* no used loop score - gradually decrease */
tass 68:0847e35d08a6 611
TASS Belgium NV 131:4758606c9316 612 /* dbg("%3d - ",0); */
TASS Belgium NV 131:4758606c9316 613
TASS Belgium NV 131:4758606c9316 614 if (index[i] >= PROTO_DEF_AVG_NR)
TASS Belgium NV 131:4758606c9316 615 index[i] = 0; /* reset index */
TASS Belgium NV 131:4758606c9316 616
TASS Belgium NV 131:4758606c9316 617 j = index[i];
TASS Belgium NV 131:4758606c9316 618 avg[i][j] = 0;
tass 68:0847e35d08a6 619
TASS Belgium NV 131:4758606c9316 620 index[i]++;
tass 68:0847e35d08a6 621
TASS Belgium NV 131:4758606c9316 622 sum = 0;
TASS Belgium NV 131:4758606c9316 623 for (j = 0; j < PROTO_DEF_AVG_NR; j++)
TASS Belgium NV 131:4758606c9316 624 sum += avg[i][j]; /* calculate sum */
tass 68:0847e35d08a6 625
TASS Belgium NV 131:4758606c9316 626 sum >>= 2; /* divide by 4 to get average used score */
tass 68:0847e35d08a6 627
TASS Belgium NV 131:4758606c9316 628 if ((sum == 0) && (score[i] >> 1 >= PROTO_MIN_SCORE)) {
TASS Belgium NV 131:4758606c9316 629 score[i] >>= 1; /* half loop score */
TASS Belgium NV 131:4758606c9316 630 total += score[i];
TASS Belgium NV 131:4758606c9316 631 for (j = 0; j < PROTO_DEF_AVG_NR; j++)
TASS Belgium NV 131:4758606c9316 632 avg[i][j] = score[i];
TASS Belgium NV 131:4758606c9316 633 }
TASS Belgium NV 131:4758606c9316 634
TASS Belgium NV 131:4758606c9316 635 }
tass 68:0847e35d08a6 636 }
TASS Belgium NV 131:4758606c9316 637 /* dbg("\n"); */
tass 68:0847e35d08a6 638
TASS Belgium NV 131:4758606c9316 639 return 0;
tass 68:0847e35d08a6 640 }
tass 68:0847e35d08a6 641
tass 68:0847e35d08a6 642
tass 68:0847e35d08a6 643
TASS Belgium NV 131:4758606c9316 644 /*
tass 68:0847e35d08a6 645
TASS Belgium NV 131:4758606c9316 646 .
TASS Belgium NV 131:4758606c9316 647 .vS.
TASS Belgium NV 131:4758606c9316 648 <aoSo.
TASS Belgium NV 131:4758606c9316 649 .XoS22.
TASS Belgium NV 131:4758606c9316 650 .S2S22. ._... ...... ..._.
TASS Belgium NV 131:4758606c9316 651 :=|2S2X2|=++; <vSX2XX2z+ |vSSSXSSs>. :iXXZUZXXe=
TASS Belgium NV 131:4758606c9316 652 )2SS2SS2S2S2I =oS2S2S2S2X22;. _vuXS22S2S2S22i ._wZZXZZZXZZXZX=
TASS Belgium NV 131:4758606c9316 653 )22S2S2S2S2Sl |S2S2S22S2SSSXc: .S2SS2S2S22S2SS= .]#XZZZXZXZZZZZZ:
TASS Belgium NV 131:4758606c9316 654 )oSS2SS2S2Sol |2}!"""!32S22S(. uS2S2Se**12oS2e ]dXZZXX2?YYXXXZ*
TASS Belgium NV 131:4758606c9316 655 .:2S2So:..-. . :]S2S2e;=X2SS2o .)oc ]XZZXZ( =nX:
TASS Belgium NV 131:4758606c9316 656 .S2S22. ___s_i,.)oS2So(;2SS2So, ` 3XZZZZc, -
TASS Belgium NV 131:4758606c9316 657 .S2SSo. =oXXXSSS2XoS2S2o( XS2S2XSos;. ]ZZZZXXXX|=
TASS Belgium NV 131:4758606c9316 658 .S2S22. .)S2S2S22S2S2S2S2o( "X2SS2S2S2Sus,, +3XZZZZZXZZoos_
TASS Belgium NV 131:4758606c9316 659 .S2S22. .]2S2SS22S222S2SS2o( ]S22S2S2S222So :3XXZZZZZZZZXXv
TASS Belgium NV 131:4758606c9316 660 .S2S22. =u2SS2e"~---"{2S2So( -"12S2S2SSS2Su. "?SXXXZXZZZZXo
TASS Belgium NV 131:4758606c9316 661 .S2SSo. )SS22z; :S2S2o( ={vS2S2S22v .<vXZZZZZZZ;
TASS Belgium NV 131:4758606c9316 662 .S2S2S: ]oSS2c; =22S2o( -"S2SS2n ~4XXZXZ(
TASS Belgium NV 131:4758606c9316 663 .2S2S2i )2S2S2[. .)XS2So( <;. .2S2S2o :<. ]XZZZX(
TASS Belgium NV 131:4758606c9316 664 nX2S2S,,_s_=3oSS2SoaasuXXS2S2o( .oXoasi_aioSSS22l.]dZoaas_aadXZZXZ'
TASS Belgium NV 131:4758606c9316 665 vS2SSSXXX2; )S2S2S2SoS2S2S2S2o( iS2S222XSoSS22So.)nXZZXXXZZXXZZXZo
TASS Belgium NV 131:4758606c9316 666 x32S22S2Sn -+S2S2S2S2So22S2So( 12S2SS2S2SS22S}- )SXXZZZZZZZZZXX!-
TASS Belgium NV 131:4758606c9316 667 .)S22222i .i2S2S2o>;:S2S2o( .<vSoSoSo2S(; :nXXXXXZXXX(
TASS Belgium NV 131:4758606c9316 668 .-~~~~- --- . - - --~~~-- --^^~~-
TASS Belgium NV 131:4758606c9316 669 .
tass 68:0847e35d08a6 670
tass 68:0847e35d08a6 671
TASS Belgium NV 131:4758606c9316 672 ... curious about our source code? We are hiring! mailto:<recruiting@tass.be>
TASS Belgium NV 131:4758606c9316 673
TASS Belgium NV 131:4758606c9316 674
TASS Belgium NV 131:4758606c9316 675 */
tass 68:0847e35d08a6 676
tass 68:0847e35d08a6 677 void pico_stack_tick(void)
tass 68:0847e35d08a6 678 {
TASS Belgium NV 131:4758606c9316 679 static int score[PROTO_DEF_NR] = {
TASS Belgium NV 131:4758606c9316 680 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 681 };
TASS Belgium NV 131:4758606c9316 682 static int index[PROTO_DEF_NR] = {
TASS Belgium NV 131:4758606c9316 683 0, 0, 0, 0, 0, 0
TASS Belgium NV 131:4758606c9316 684 };
tass 68:0847e35d08a6 685 static int avg[PROTO_DEF_NR][PROTO_DEF_AVG_NR];
TASS Belgium NV 131:4758606c9316 686 static int ret[PROTO_DEF_NR] = {
TASS Belgium NV 131:4758606c9316 687 0
TASS Belgium NV 131:4758606c9316 688 };
tass 68:0847e35d08a6 689
tass 68:0847e35d08a6 690 pico_check_timers();
tass 68:0847e35d08a6 691
TASS Belgium NV 131:4758606c9316 692 /* 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 693
TASS Belgium NV 131:4758606c9316 694 /* score = pico_protocols_loop(100); */
tass 68:0847e35d08a6 695
TASS Belgium NV 131:4758606c9316 696 ret[0] = pico_devices_loop(score[0], PICO_LOOP_DIR_IN);
tass 70:cd218dd180e5 697 pico_rand_feed((uint32_t)ret[0]);
tass 68:0847e35d08a6 698
tass 68:0847e35d08a6 699 ret[1] = pico_protocol_datalink_loop(score[1], PICO_LOOP_DIR_IN);
tass 70:cd218dd180e5 700 pico_rand_feed((uint32_t)ret[1]);
tass 68:0847e35d08a6 701
tass 68:0847e35d08a6 702 ret[2] = pico_protocol_network_loop(score[2], PICO_LOOP_DIR_IN);
tass 70:cd218dd180e5 703 pico_rand_feed((uint32_t)ret[2]);
tass 68:0847e35d08a6 704
tass 68:0847e35d08a6 705 ret[3] = pico_protocol_transport_loop(score[3], PICO_LOOP_DIR_IN);
tass 70:cd218dd180e5 706 pico_rand_feed((uint32_t)ret[3]);
tass 68:0847e35d08a6 707
tass 68:0847e35d08a6 708
tass 68:0847e35d08a6 709 ret[5] = score[5];
tass 68:0847e35d08a6 710 #if defined (PICO_SUPPORT_IPV4) || defined (PICO_SUPPORT_IPV6)
tass 68:0847e35d08a6 711 #if defined (PICO_SUPPORT_TCP) || defined (PICO_SUPPORT_UDP)
TASS Belgium NV 131:4758606c9316 712 ret[5] = pico_sockets_loop(score[5]); /* swapped */
tass 70:cd218dd180e5 713 pico_rand_feed((uint32_t)ret[5]);
tass 68:0847e35d08a6 714 #endif
tass 68:0847e35d08a6 715 #endif
tass 68:0847e35d08a6 716
tass 68:0847e35d08a6 717 ret[4] = pico_protocol_socket_loop(score[4], PICO_LOOP_DIR_IN);
tass 70:cd218dd180e5 718 pico_rand_feed((uint32_t)ret[4]);
tass 68:0847e35d08a6 719
tass 68:0847e35d08a6 720
tass 68:0847e35d08a6 721 ret[6] = pico_protocol_socket_loop(score[6], PICO_LOOP_DIR_OUT);
tass 70:cd218dd180e5 722 pico_rand_feed((uint32_t)ret[6]);
tass 68:0847e35d08a6 723
tass 68:0847e35d08a6 724 ret[7] = pico_protocol_transport_loop(score[7], PICO_LOOP_DIR_OUT);
tass 70:cd218dd180e5 725 pico_rand_feed((uint32_t)ret[7]);
tass 68:0847e35d08a6 726
tass 68:0847e35d08a6 727 ret[8] = pico_protocol_network_loop(score[8], PICO_LOOP_DIR_OUT);
tass 70:cd218dd180e5 728 pico_rand_feed((uint32_t)ret[8]);
tass 68:0847e35d08a6 729
tass 68:0847e35d08a6 730 ret[9] = pico_protocol_datalink_loop(score[9], PICO_LOOP_DIR_OUT);
tass 70:cd218dd180e5 731 pico_rand_feed((uint32_t)ret[9]);
tass 68:0847e35d08a6 732
TASS Belgium NV 131:4758606c9316 733 ret[10] = pico_devices_loop(score[10], PICO_LOOP_DIR_OUT);
tass 70:cd218dd180e5 734 pico_rand_feed((uint32_t)ret[10]);
tass 68:0847e35d08a6 735
tass 68:0847e35d08a6 736 /* calculate new loop scores for next iteration */
TASS Belgium NV 131:4758606c9316 737 calc_score(score, index, (int (*)[])avg, ret);
tass 68:0847e35d08a6 738 }
tass 68:0847e35d08a6 739
tass 68:0847e35d08a6 740 void pico_stack_loop(void)
tass 68:0847e35d08a6 741 {
TASS Belgium NV 131:4758606c9316 742 while(1) {
TASS Belgium NV 131:4758606c9316 743 pico_stack_tick();
TASS Belgium NV 131:4758606c9316 744 PICO_IDLE();
TASS Belgium NV 131:4758606c9316 745 }
tass 68:0847e35d08a6 746 }
tass 68:0847e35d08a6 747
tass 128:ae39e6e81531 748 struct pico_timer *pico_timer_add(pico_time expire, void (*timer)(pico_time, void *), void *arg)
tass 68:0847e35d08a6 749 {
TASS Belgium NV 131:4758606c9316 750 struct pico_timer *t = pico_zalloc(sizeof(struct pico_timer));
TASS Belgium NV 131:4758606c9316 751 struct pico_timer_ref tref;
TASS Belgium NV 131:4758606c9316 752 if (!t) {
TASS Belgium NV 131:4758606c9316 753 pico_err = PICO_ERR_ENOMEM;
TASS Belgium NV 131:4758606c9316 754 return NULL;
TASS Belgium NV 131:4758606c9316 755 }
TASS Belgium NV 131:4758606c9316 756
TASS Belgium NV 131:4758606c9316 757 tref.expire = PICO_TIME_MS() + expire;
TASS Belgium NV 131:4758606c9316 758 t->arg = arg;
TASS Belgium NV 131:4758606c9316 759 t->timer = timer;
TASS Belgium NV 131:4758606c9316 760 tref.tmr = t;
TASS Belgium NV 131:4758606c9316 761 heap_insert(Timers, &tref);
TASS Belgium NV 131:4758606c9316 762 if (Timers->n > PICO_MAX_TIMERS) {
TASS Belgium NV 131:4758606c9316 763 dbg("Warning: I have %d timers\n", Timers->n);
TASS Belgium NV 131:4758606c9316 764 }
TASS Belgium NV 131:4758606c9316 765
TASS Belgium NV 131:4758606c9316 766 return t;
tass 68:0847e35d08a6 767 }
tass 68:0847e35d08a6 768
tass 68:0847e35d08a6 769 void pico_stack_init(void)
tass 68:0847e35d08a6 770 {
tass 68:0847e35d08a6 771
tass 68:0847e35d08a6 772 #ifdef PICO_SUPPORT_IPV4
TASS Belgium NV 131:4758606c9316 773 pico_protocol_init(&pico_proto_ipv4);
tass 68:0847e35d08a6 774 #endif
tass 68:0847e35d08a6 775
tass 68:0847e35d08a6 776 #ifdef PICO_SUPPORT_IPV6
TASS Belgium NV 131:4758606c9316 777 pico_protocol_init(&pico_proto_ipv6);
tass 68:0847e35d08a6 778 #endif
tass 68:0847e35d08a6 779
tass 68:0847e35d08a6 780 #ifdef PICO_SUPPORT_ICMP4
TASS Belgium NV 131:4758606c9316 781 pico_protocol_init(&pico_proto_icmp4);
tass 68:0847e35d08a6 782 #endif
tass 68:0847e35d08a6 783
tass 68:0847e35d08a6 784 #ifdef PICO_SUPPORT_IGMP
TASS Belgium NV 131:4758606c9316 785 pico_protocol_init(&pico_proto_igmp);
tass 68:0847e35d08a6 786 #endif
tass 68:0847e35d08a6 787
tass 68:0847e35d08a6 788 #ifdef PICO_SUPPORT_UDP
TASS Belgium NV 131:4758606c9316 789 pico_protocol_init(&pico_proto_udp);
tass 68:0847e35d08a6 790 #endif
tass 68:0847e35d08a6 791
tass 68:0847e35d08a6 792 #ifdef PICO_SUPPORT_TCP
TASS Belgium NV 131:4758606c9316 793 pico_protocol_init(&pico_proto_tcp);
tass 68:0847e35d08a6 794 #endif
tass 68:0847e35d08a6 795
tass 68:0847e35d08a6 796 #ifdef PICO_SUPPORT_DNS_CLIENT
TASS Belgium NV 131:4758606c9316 797 pico_dns_client_init();
tass 68:0847e35d08a6 798 #endif
tass 68:0847e35d08a6 799
TASS Belgium NV 131:4758606c9316 800 pico_rand_feed(123456);
tass 68:0847e35d08a6 801
TASS Belgium NV 131:4758606c9316 802 /* Initialize timer heap */
TASS Belgium NV 131:4758606c9316 803 Timers = heap_init();
tass picotcp@tass.be 133:5b075f5e141a 804 pico_arp_init();
TASS Belgium NV 131:4758606c9316 805 pico_stack_tick();
TASS Belgium NV 131:4758606c9316 806 pico_stack_tick();
TASS Belgium NV 131:4758606c9316 807 pico_stack_tick();
tass 68:0847e35d08a6 808 }
tass 68:0847e35d08a6 809