CDC/ECM driver for mbed, based on USBDevice by mbed-official. Uses PicoTCP to access Ethernet USB device. License: GPLv2

Dependents:   USBEthernet_TEST

Fork of USB_Ethernet by Daniele Lacamera

Committer:
daniele
Date:
Sat Aug 03 13:16:14 2013 +0000
Revision:
2:540f6e142d59
Moved to single package

Who changed what in which revision?

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