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 RTOSgeneric mbed Ethernet driverhigh performance NXP LPC1768 specific Ethernet driverMulti-threading support for mbed RTOSBerkeley sockets and integration with the New Socket APIFork of the apps running on top of the New Socket APIScheduling 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.
stack/pico_stack.c@152:a3d286bf94e5, 2015-09-28 (annotated)
- Committer:
- tass
- Date:
- Mon Sep 28 13:16:18 2015 +0200
- Revision:
- 152:a3d286bf94e5
- Parent:
- 150:551effcf6a39
- Child:
- 154:6c0e92a80c4a
Mercurial: latest development version of PicoTCP
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
tass | 68:0847e35d08a6 | 1 | /********************************************************************* |
tass | 152:a3d286bf94e5 | 2 | PicoTCP. Copyright (c) 2012-2015 Altran Intelligent Systems. 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 | 152:a3d286bf94e5 | 19 | #include "pico_olsr.h" |
tass | 152:a3d286bf94e5 | 20 | #include "pico_aodv.h" |
tass | 68:0847e35d08a6 | 21 | #include "pico_eth.h" |
tass | 68:0847e35d08a6 | 22 | #include "pico_arp.h" |
tass | 68:0847e35d08a6 | 23 | #include "pico_ipv4.h" |
tass | 68:0847e35d08a6 | 24 | #include "pico_ipv6.h" |
tass | 68:0847e35d08a6 | 25 | #include "pico_icmp4.h" |
tass picotcp@tass.be | 149:5f4cb161cec3 | 26 | #include "pico_icmp6.h" |
tass | 68:0847e35d08a6 | 27 | #include "pico_igmp.h" |
tass | 68:0847e35d08a6 | 28 | #include "pico_udp.h" |
tass | 68:0847e35d08a6 | 29 | #include "pico_tcp.h" |
tass | 68:0847e35d08a6 | 30 | #include "pico_socket.h" |
tass | 68:0847e35d08a6 | 31 | #include "heap.h" |
tass | 68:0847e35d08a6 | 32 | |
TASS Belgium NV |
131:4758606c9316 | 33 | #define IS_LIMITED_BCAST(f) (((struct pico_ipv4_hdr *) f->net_hdr)->dst.addr == PICO_IP4_BCAST) |
tass | 68:0847e35d08a6 | 34 | |
tass picotcp@tass.be | 149:5f4cb161cec3 | 35 | const uint8_t PICO_ETHADDR_ALL[6] = { |
tass picotcp@tass.be | 149:5f4cb161cec3 | 36 | 0xff, 0xff, 0xff, 0xff, 0xff, 0xff |
tass picotcp@tass.be | 149:5f4cb161cec3 | 37 | }; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 38 | |
tass | 68:0847e35d08a6 | 39 | # define PICO_SIZE_MCAST 3 |
TASS Belgium NV |
131:4758606c9316 | 40 | const uint8_t PICO_ETHADDR_MCAST[6] = { |
TASS Belgium NV |
131:4758606c9316 | 41 | 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 |
TASS Belgium NV |
131:4758606c9316 | 42 | }; |
tass | 68:0847e35d08a6 | 43 | |
tass picotcp@tass.be | 149:5f4cb161cec3 | 44 | #ifdef PICO_SUPPORT_IPV6 |
tass picotcp@tass.be | 149:5f4cb161cec3 | 45 | # define PICO_SIZE_MCAST6 2 |
tass picotcp@tass.be | 149:5f4cb161cec3 | 46 | const uint8_t PICO_ETHADDR_MCAST6[6] = { |
tass picotcp@tass.be | 149:5f4cb161cec3 | 47 | 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 |
tass picotcp@tass.be | 149:5f4cb161cec3 | 48 | }; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 49 | #endif |
tass picotcp@tass.be | 149:5f4cb161cec3 | 50 | |
tass picotcp@tass.be | 149:5f4cb161cec3 | 51 | |
tass | 128:ae39e6e81531 | 52 | volatile pico_time pico_tick; |
tass | 68:0847e35d08a6 | 53 | volatile pico_err_t pico_err; |
tass | 68:0847e35d08a6 | 54 | |
tass | 68:0847e35d08a6 | 55 | static uint32_t _rand_seed; |
tass | 68:0847e35d08a6 | 56 | |
tass | 152:a3d286bf94e5 | 57 | void WEAK pico_rand_feed(uint32_t feed) |
tass | 68:0847e35d08a6 | 58 | { |
TASS Belgium NV |
131:4758606c9316 | 59 | if (!feed) |
TASS Belgium NV |
131:4758606c9316 | 60 | return; |
TASS Belgium NV |
131:4758606c9316 | 61 | |
TASS Belgium NV |
131:4758606c9316 | 62 | _rand_seed *= 1664525; |
TASS Belgium NV |
131:4758606c9316 | 63 | _rand_seed += 1013904223; |
TASS Belgium NV |
131:4758606c9316 | 64 | _rand_seed ^= ~(feed); |
tass | 68:0847e35d08a6 | 65 | } |
tass | 68:0847e35d08a6 | 66 | |
tass | 152:a3d286bf94e5 | 67 | uint32_t WEAK pico_rand(void) |
tass | 68:0847e35d08a6 | 68 | { |
TASS Belgium NV |
131:4758606c9316 | 69 | pico_rand_feed((uint32_t)pico_tick); |
TASS Belgium NV |
131:4758606c9316 | 70 | return _rand_seed; |
tass | 68:0847e35d08a6 | 71 | } |
tass | 68:0847e35d08a6 | 72 | |
tass | 152:a3d286bf94e5 | 73 | void pico_to_lowercase(char *str) |
tass | 152:a3d286bf94e5 | 74 | { |
tass | 152:a3d286bf94e5 | 75 | int i = 0; |
tass | 152:a3d286bf94e5 | 76 | if (!str) |
tass | 152:a3d286bf94e5 | 77 | return; |
tass | 152:a3d286bf94e5 | 78 | |
tass | 152:a3d286bf94e5 | 79 | while(str[i]) { |
tass | 152:a3d286bf94e5 | 80 | if ((str[i] <= 'Z') && (str[i] >= 'A')) |
tass | 152:a3d286bf94e5 | 81 | str[i] = (char) (str[i] - (char)('A' - 'a')); |
tass | 152:a3d286bf94e5 | 82 | |
tass | 152:a3d286bf94e5 | 83 | i++; |
tass | 152:a3d286bf94e5 | 84 | } |
tass | 152:a3d286bf94e5 | 85 | } |
tass | 152:a3d286bf94e5 | 86 | |
tass | 68:0847e35d08a6 | 87 | /* NOTIFICATIONS: distributed notifications for stack internal errors. |
tass | 68:0847e35d08a6 | 88 | */ |
tass | 68:0847e35d08a6 | 89 | |
tass | 68:0847e35d08a6 | 90 | int pico_notify_socket_unreachable(struct pico_frame *f) |
tass | 68:0847e35d08a6 | 91 | { |
TASS Belgium NV |
131:4758606c9316 | 92 | if (0) {} |
TASS Belgium NV |
131:4758606c9316 | 93 | |
TASS Belgium NV |
131:4758606c9316 | 94 | #ifdef PICO_SUPPORT_ICMP4 |
TASS Belgium NV |
131:4758606c9316 | 95 | else if (IS_IPV4(f)) { |
TASS Belgium NV |
131:4758606c9316 | 96 | pico_icmp4_port_unreachable(f); |
TASS Belgium NV |
131:4758606c9316 | 97 | } |
tass | 68:0847e35d08a6 | 98 | #endif |
TASS Belgium NV |
131:4758606c9316 | 99 | #ifdef PICO_SUPPORT_ICMP6 |
TASS Belgium NV |
131:4758606c9316 | 100 | else if (IS_IPV6(f)) { |
TASS Belgium NV |
131:4758606c9316 | 101 | pico_icmp6_port_unreachable(f); |
TASS Belgium NV |
131:4758606c9316 | 102 | } |
tass | 68:0847e35d08a6 | 103 | #endif |
tass | 68:0847e35d08a6 | 104 | |
TASS Belgium NV |
131:4758606c9316 | 105 | return 0; |
tass | 68:0847e35d08a6 | 106 | } |
tass | 68:0847e35d08a6 | 107 | |
tass | 68:0847e35d08a6 | 108 | int pico_notify_proto_unreachable(struct pico_frame *f) |
tass | 68:0847e35d08a6 | 109 | { |
TASS Belgium NV |
131:4758606c9316 | 110 | if (0) {} |
TASS Belgium NV |
131:4758606c9316 | 111 | |
TASS Belgium NV |
131:4758606c9316 | 112 | #ifdef PICO_SUPPORT_ICMP4 |
TASS Belgium NV |
131:4758606c9316 | 113 | else if (IS_IPV4(f)) { |
TASS Belgium NV |
131:4758606c9316 | 114 | pico_icmp4_proto_unreachable(f); |
TASS Belgium NV |
131:4758606c9316 | 115 | } |
tass | 68:0847e35d08a6 | 116 | #endif |
TASS Belgium NV |
131:4758606c9316 | 117 | #ifdef PICO_SUPPORT_ICMP6 |
TASS Belgium NV |
131:4758606c9316 | 118 | else if (IS_IPV6(f)) { |
TASS Belgium NV |
131:4758606c9316 | 119 | pico_icmp6_proto_unreachable(f); |
TASS Belgium NV |
131:4758606c9316 | 120 | } |
tass | 68:0847e35d08a6 | 121 | #endif |
TASS Belgium NV |
131:4758606c9316 | 122 | return 0; |
tass | 68:0847e35d08a6 | 123 | } |
tass | 68:0847e35d08a6 | 124 | |
tass | 68:0847e35d08a6 | 125 | int pico_notify_dest_unreachable(struct pico_frame *f) |
tass | 68:0847e35d08a6 | 126 | { |
TASS Belgium NV |
131:4758606c9316 | 127 | if (0) {} |
TASS Belgium NV |
131:4758606c9316 | 128 | |
TASS Belgium NV |
131:4758606c9316 | 129 | #ifdef PICO_SUPPORT_ICMP4 |
TASS Belgium NV |
131:4758606c9316 | 130 | else if (IS_IPV4(f)) { |
TASS Belgium NV |
131:4758606c9316 | 131 | pico_icmp4_dest_unreachable(f); |
TASS Belgium NV |
131:4758606c9316 | 132 | } |
tass | 68:0847e35d08a6 | 133 | #endif |
TASS Belgium NV |
131:4758606c9316 | 134 | #ifdef PICO_SUPPORT_ICMP6 |
TASS Belgium NV |
131:4758606c9316 | 135 | else if (IS_IPV6(f)) { |
TASS Belgium NV |
131:4758606c9316 | 136 | pico_icmp6_dest_unreachable(f); |
TASS Belgium NV |
131:4758606c9316 | 137 | } |
tass | 68:0847e35d08a6 | 138 | #endif |
TASS Belgium NV |
131:4758606c9316 | 139 | return 0; |
tass | 68:0847e35d08a6 | 140 | } |
tass | 68:0847e35d08a6 | 141 | |
tass | 68:0847e35d08a6 | 142 | int pico_notify_ttl_expired(struct pico_frame *f) |
tass | 68:0847e35d08a6 | 143 | { |
TASS Belgium NV |
131:4758606c9316 | 144 | if (0) {} |
TASS Belgium NV |
131:4758606c9316 | 145 | |
TASS Belgium NV |
131:4758606c9316 | 146 | #ifdef PICO_SUPPORT_ICMP4 |
TASS Belgium NV |
131:4758606c9316 | 147 | else if (IS_IPV4(f)) { |
TASS Belgium NV |
131:4758606c9316 | 148 | pico_icmp4_ttl_expired(f); |
TASS Belgium NV |
131:4758606c9316 | 149 | } |
tass | 68:0847e35d08a6 | 150 | #endif |
TASS Belgium NV |
131:4758606c9316 | 151 | #ifdef PICO_SUPPORT_ICMP6 |
TASS Belgium NV |
131:4758606c9316 | 152 | else if (IS_IPV6(f)) { |
TASS Belgium NV |
131:4758606c9316 | 153 | pico_icmp6_ttl_expired(f); |
TASS Belgium NV |
131:4758606c9316 | 154 | } |
tass | 68:0847e35d08a6 | 155 | #endif |
TASS Belgium NV |
131:4758606c9316 | 156 | return 0; |
tass | 68:0847e35d08a6 | 157 | } |
tass | 68:0847e35d08a6 | 158 | |
tass | 152:a3d286bf94e5 | 159 | int pico_notify_frag_expired(struct pico_frame *f) |
tass | 152:a3d286bf94e5 | 160 | { |
tass | 152:a3d286bf94e5 | 161 | if (0) {} |
tass | 152:a3d286bf94e5 | 162 | |
tass | 152:a3d286bf94e5 | 163 | #ifdef PICO_SUPPORT_ICMP4 |
tass | 152:a3d286bf94e5 | 164 | else if (IS_IPV4(f)) { |
tass | 152:a3d286bf94e5 | 165 | pico_icmp4_frag_expired(f); |
tass | 152:a3d286bf94e5 | 166 | } |
tass | 152:a3d286bf94e5 | 167 | #endif |
tass | 152:a3d286bf94e5 | 168 | #ifdef PICO_SUPPORT_ICMP6 |
tass | 152:a3d286bf94e5 | 169 | else if (IS_IPV6(f)) { |
tass | 152:a3d286bf94e5 | 170 | pico_icmp6_frag_expired(f); |
tass | 152:a3d286bf94e5 | 171 | } |
tass | 152:a3d286bf94e5 | 172 | #endif |
tass | 152:a3d286bf94e5 | 173 | return 0; |
tass | 152:a3d286bf94e5 | 174 | } |
tass | 152:a3d286bf94e5 | 175 | |
tass | 152:a3d286bf94e5 | 176 | int pico_notify_pkt_too_big(struct pico_frame *f) |
tass | 152:a3d286bf94e5 | 177 | { |
tass | 152:a3d286bf94e5 | 178 | if (0) {} |
tass | 152:a3d286bf94e5 | 179 | |
tass | 152:a3d286bf94e5 | 180 | #ifdef PICO_SUPPORT_ICMP4 |
tass | 152:a3d286bf94e5 | 181 | else if (IS_IPV4(f)) { |
tass | 152:a3d286bf94e5 | 182 | pico_icmp4_mtu_exceeded(f); |
tass | 152:a3d286bf94e5 | 183 | } |
tass | 152:a3d286bf94e5 | 184 | #endif |
tass | 152:a3d286bf94e5 | 185 | #ifdef PICO_SUPPORT_ICMP6 |
tass | 152:a3d286bf94e5 | 186 | else if (IS_IPV6(f)) { |
tass | 152:a3d286bf94e5 | 187 | pico_icmp6_pkt_too_big(f); |
tass | 152:a3d286bf94e5 | 188 | } |
tass | 152:a3d286bf94e5 | 189 | #endif |
tass | 152:a3d286bf94e5 | 190 | return 0; |
tass | 152:a3d286bf94e5 | 191 | } |
tass | 152:a3d286bf94e5 | 192 | |
tass | 68:0847e35d08a6 | 193 | |
tass | 68:0847e35d08a6 | 194 | /* Transport layer */ |
tass | 152:a3d286bf94e5 | 195 | MOCKABLE int32_t pico_transport_receive(struct pico_frame *f, uint8_t proto) |
tass | 68:0847e35d08a6 | 196 | { |
TASS Belgium NV |
131:4758606c9316 | 197 | int32_t ret = -1; |
TASS Belgium NV |
131:4758606c9316 | 198 | switch (proto) { |
tass | 68:0847e35d08a6 | 199 | |
tass | 68:0847e35d08a6 | 200 | #ifdef PICO_SUPPORT_ICMP4 |
TASS Belgium NV |
131:4758606c9316 | 201 | case PICO_PROTO_ICMP4: |
TASS Belgium NV |
131:4758606c9316 | 202 | ret = pico_enqueue(pico_proto_icmp4.q_in, f); |
TASS Belgium NV |
131:4758606c9316 | 203 | break; |
tass | 68:0847e35d08a6 | 204 | #endif |
tass | 68:0847e35d08a6 | 205 | |
tass picotcp@tass.be | 149:5f4cb161cec3 | 206 | #ifdef PICO_SUPPORT_ICMP6 |
tass picotcp@tass.be | 149:5f4cb161cec3 | 207 | case PICO_PROTO_ICMP6: |
tass picotcp@tass.be | 149:5f4cb161cec3 | 208 | ret = pico_enqueue(pico_proto_icmp6.q_in, f); |
tass picotcp@tass.be | 149:5f4cb161cec3 | 209 | break; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 210 | #endif |
tass picotcp@tass.be | 149:5f4cb161cec3 | 211 | |
tass picotcp@tass.be | 149:5f4cb161cec3 | 212 | |
tass | 152:a3d286bf94e5 | 213 | #if defined(PICO_SUPPORT_IGMP) && defined(PICO_SUPPORT_MCAST) |
TASS Belgium NV |
131:4758606c9316 | 214 | case PICO_PROTO_IGMP: |
TASS Belgium NV |
131:4758606c9316 | 215 | ret = pico_enqueue(pico_proto_igmp.q_in, f); |
TASS Belgium NV |
131:4758606c9316 | 216 | break; |
tass | 68:0847e35d08a6 | 217 | #endif |
tass | 68:0847e35d08a6 | 218 | |
tass | 68:0847e35d08a6 | 219 | #ifdef PICO_SUPPORT_UDP |
TASS Belgium NV |
131:4758606c9316 | 220 | case PICO_PROTO_UDP: |
TASS Belgium NV |
131:4758606c9316 | 221 | ret = pico_enqueue(pico_proto_udp.q_in, f); |
TASS Belgium NV |
131:4758606c9316 | 222 | break; |
tass | 68:0847e35d08a6 | 223 | #endif |
tass | 68:0847e35d08a6 | 224 | |
tass | 68:0847e35d08a6 | 225 | #ifdef PICO_SUPPORT_TCP |
TASS Belgium NV |
131:4758606c9316 | 226 | case PICO_PROTO_TCP: |
TASS Belgium NV |
131:4758606c9316 | 227 | ret = pico_enqueue(pico_proto_tcp.q_in, f); |
TASS Belgium NV |
131:4758606c9316 | 228 | break; |
tass | 68:0847e35d08a6 | 229 | #endif |
tass | 68:0847e35d08a6 | 230 | |
TASS Belgium NV |
131:4758606c9316 | 231 | default: |
TASS Belgium NV |
131:4758606c9316 | 232 | /* Protocol not available */ |
TASS Belgium NV |
131:4758606c9316 | 233 | dbg("pkt: no such protocol (%d)\n", proto); |
TASS Belgium NV |
131:4758606c9316 | 234 | pico_notify_proto_unreachable(f); |
TASS Belgium NV |
131:4758606c9316 | 235 | pico_frame_discard(f); |
TASS Belgium NV |
131:4758606c9316 | 236 | ret = -1; |
TASS Belgium NV |
131:4758606c9316 | 237 | } |
TASS Belgium NV |
131:4758606c9316 | 238 | return ret; |
tass | 68:0847e35d08a6 | 239 | } |
tass | 68:0847e35d08a6 | 240 | |
tass | 70:cd218dd180e5 | 241 | int32_t pico_network_receive(struct pico_frame *f) |
tass | 68:0847e35d08a6 | 242 | { |
TASS Belgium NV |
131:4758606c9316 | 243 | if (0) {} |
TASS Belgium NV |
131:4758606c9316 | 244 | |
tass | 68:0847e35d08a6 | 245 | #ifdef PICO_SUPPORT_IPV4 |
TASS Belgium NV |
131:4758606c9316 | 246 | else if (IS_IPV4(f)) { |
TASS Belgium NV |
131:4758606c9316 | 247 | pico_enqueue(pico_proto_ipv4.q_in, f); |
TASS Belgium NV |
131:4758606c9316 | 248 | } |
tass | 68:0847e35d08a6 | 249 | #endif |
tass | 68:0847e35d08a6 | 250 | #ifdef PICO_SUPPORT_IPV6 |
TASS Belgium NV |
131:4758606c9316 | 251 | else if (IS_IPV6(f)) { |
TASS Belgium NV |
131:4758606c9316 | 252 | pico_enqueue(pico_proto_ipv6.q_in, f); |
TASS Belgium NV |
131:4758606c9316 | 253 | } |
tass | 68:0847e35d08a6 | 254 | #endif |
TASS Belgium NV |
131:4758606c9316 | 255 | else { |
TASS Belgium NV |
131:4758606c9316 | 256 | dbg("Network not found.\n"); |
TASS Belgium NV |
131:4758606c9316 | 257 | pico_frame_discard(f); |
TASS Belgium NV |
131:4758606c9316 | 258 | return -1; |
TASS Belgium NV |
131:4758606c9316 | 259 | } |
TASS Belgium NV |
131:4758606c9316 | 260 | return (int32_t)f->buffer_len; |
tass | 68:0847e35d08a6 | 261 | } |
tass | 68:0847e35d08a6 | 262 | |
tass | 68:0847e35d08a6 | 263 | /* Network layer: interface towards socket for frame sending */ |
tass | 88:0e827d0d8017 | 264 | int32_t pico_network_send(struct pico_frame *f) |
tass | 68:0847e35d08a6 | 265 | { |
TASS Belgium NV |
131:4758606c9316 | 266 | if (!f || !f->sock || !f->sock->net) { |
TASS Belgium NV |
131:4758606c9316 | 267 | pico_frame_discard(f); |
TASS Belgium NV |
131:4758606c9316 | 268 | return -1; |
TASS Belgium NV |
131:4758606c9316 | 269 | } |
TASS Belgium NV |
131:4758606c9316 | 270 | |
TASS Belgium NV |
131:4758606c9316 | 271 | return f->sock->net->push(f->sock->net, f); |
tass | 68:0847e35d08a6 | 272 | } |
tass | 68:0847e35d08a6 | 273 | |
tass | 68:0847e35d08a6 | 274 | int pico_source_is_local(struct pico_frame *f) |
tass | 68:0847e35d08a6 | 275 | { |
TASS Belgium NV |
131:4758606c9316 | 276 | if (0) { } |
TASS Belgium NV |
131:4758606c9316 | 277 | |
tass | 68:0847e35d08a6 | 278 | #ifdef PICO_SUPPORT_IPV4 |
TASS Belgium NV |
131:4758606c9316 | 279 | else if (IS_IPV4(f)) { |
TASS Belgium NV |
131:4758606c9316 | 280 | struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *)f->net_hdr; |
TASS Belgium NV |
131:4758606c9316 | 281 | if (hdr->src.addr == PICO_IPV4_INADDR_ANY) |
TASS Belgium NV |
131:4758606c9316 | 282 | return 1; |
TASS Belgium NV |
131:4758606c9316 | 283 | |
TASS Belgium NV |
131:4758606c9316 | 284 | if (pico_ipv4_link_find(&hdr->src)) |
TASS Belgium NV |
131:4758606c9316 | 285 | return 1; |
TASS Belgium NV |
131:4758606c9316 | 286 | } |
tass | 68:0847e35d08a6 | 287 | #endif |
tass | 68:0847e35d08a6 | 288 | #ifdef PICO_SUPPORT_IPV6 |
TASS Belgium NV |
131:4758606c9316 | 289 | else if (IS_IPV6(f)) { |
tass | 152:a3d286bf94e5 | 290 | struct pico_ipv6_hdr *hdr = (struct pico_ipv6_hdr *)f->net_hdr; |
tass | 152:a3d286bf94e5 | 291 | if (pico_ipv6_is_unspecified(hdr->src.addr) || pico_ipv6_link_find(&hdr->src)) |
tass | 152:a3d286bf94e5 | 292 | return 1; |
TASS Belgium NV |
131:4758606c9316 | 293 | } |
tass | 68:0847e35d08a6 | 294 | #endif |
TASS Belgium NV |
131:4758606c9316 | 295 | return 0; |
tass | 68:0847e35d08a6 | 296 | } |
tass | 68:0847e35d08a6 | 297 | |
tass | 152:a3d286bf94e5 | 298 | #ifdef PICO_SUPPORT_ETH |
tass | 68:0847e35d08a6 | 299 | /* DATALINK LEVEL: interface from network to the device |
tass | 68:0847e35d08a6 | 300 | * and vice versa. |
tass | 68:0847e35d08a6 | 301 | */ |
tass | 68:0847e35d08a6 | 302 | |
TASS Belgium NV |
131:4758606c9316 | 303 | /* The pico_ethernet_receive() function is used by |
TASS Belgium NV |
131:4758606c9316 | 304 | * those devices supporting ETH in order to push packets up |
TASS Belgium NV |
131:4758606c9316 | 305 | * into the stack. |
tass | 68:0847e35d08a6 | 306 | */ |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 307 | |
tass | 68:0847e35d08a6 | 308 | static int destination_is_bcast(struct pico_frame *f) |
tass | 68:0847e35d08a6 | 309 | { |
TASS Belgium NV |
131:4758606c9316 | 310 | if (!f) |
TASS Belgium NV |
131:4758606c9316 | 311 | return 0; |
tass | 68:0847e35d08a6 | 312 | |
TASS Belgium NV |
131:4758606c9316 | 313 | if (IS_IPV6(f)) |
TASS Belgium NV |
131:4758606c9316 | 314 | return 0; |
TASS Belgium NV |
131:4758606c9316 | 315 | |
tass | 68:0847e35d08a6 | 316 | #ifdef PICO_SUPPORT_IPV4 |
TASS Belgium NV |
131:4758606c9316 | 317 | else { |
TASS Belgium NV |
131:4758606c9316 | 318 | struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr; |
TASS Belgium NV |
131:4758606c9316 | 319 | return pico_ipv4_is_broadcast(hdr->dst.addr); |
TASS Belgium NV |
131:4758606c9316 | 320 | } |
tass picotcp@tass.be | 134:cc4e6d2654d9 | 321 | #else |
tass picotcp@tass.be | 134:cc4e6d2654d9 | 322 | return 0; |
tass | 68:0847e35d08a6 | 323 | #endif |
tass | 68:0847e35d08a6 | 324 | } |
tass | 68:0847e35d08a6 | 325 | |
tass | 68:0847e35d08a6 | 326 | static int destination_is_mcast(struct pico_frame *f) |
tass | 68:0847e35d08a6 | 327 | { |
tass picotcp@tass.be | 149:5f4cb161cec3 | 328 | int ret = 0; |
TASS Belgium NV |
131:4758606c9316 | 329 | if (!f) |
TASS Belgium NV |
131:4758606c9316 | 330 | return 0; |
tass | 68:0847e35d08a6 | 331 | |
tass picotcp@tass.be | 149:5f4cb161cec3 | 332 | #ifdef PICO_SUPPORT_IPV6 |
tass picotcp@tass.be | 149:5f4cb161cec3 | 333 | if (IS_IPV6(f)) { |
tass picotcp@tass.be | 149:5f4cb161cec3 | 334 | struct pico_ipv6_hdr *hdr = (struct pico_ipv6_hdr *) f->net_hdr; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 335 | ret = pico_ipv6_is_multicast(hdr->dst.addr); |
tass picotcp@tass.be | 149:5f4cb161cec3 | 336 | } |
TASS Belgium NV |
131:4758606c9316 | 337 | |
tass picotcp@tass.be | 149:5f4cb161cec3 | 338 | #endif |
tass | 68:0847e35d08a6 | 339 | #ifdef PICO_SUPPORT_IPV4 |
TASS Belgium NV |
131:4758606c9316 | 340 | else { |
TASS Belgium NV |
131:4758606c9316 | 341 | struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 342 | ret = pico_ipv4_is_multicast(hdr->dst.addr); |
TASS Belgium NV |
131:4758606c9316 | 343 | } |
tass | 68:0847e35d08a6 | 344 | #endif |
tass picotcp@tass.be | 149:5f4cb161cec3 | 345 | |
tass picotcp@tass.be | 149:5f4cb161cec3 | 346 | return ret; |
tass | 68:0847e35d08a6 | 347 | } |
tass | 68:0847e35d08a6 | 348 | |
tass | 152:a3d286bf94e5 | 349 | #ifdef PICO_SUPPORT_IPV4 |
tass | 152:a3d286bf94e5 | 350 | static int32_t pico_ipv4_ethernet_receive(struct pico_frame *f) |
tass | 152:a3d286bf94e5 | 351 | { |
tass | 152:a3d286bf94e5 | 352 | if (IS_IPV4(f)) { |
tass | 152:a3d286bf94e5 | 353 | pico_enqueue(pico_proto_ipv4.q_in, f); |
tass | 152:a3d286bf94e5 | 354 | } else { |
tass | 152:a3d286bf94e5 | 355 | (void)pico_icmp4_param_problem(f, 0); |
tass | 152:a3d286bf94e5 | 356 | pico_frame_discard(f); |
tass | 152:a3d286bf94e5 | 357 | return -1; |
tass | 152:a3d286bf94e5 | 358 | } |
tass | 152:a3d286bf94e5 | 359 | |
tass | 152:a3d286bf94e5 | 360 | return (int32_t)f->buffer_len; |
tass | 152:a3d286bf94e5 | 361 | } |
tass | 152:a3d286bf94e5 | 362 | #endif |
tass | 152:a3d286bf94e5 | 363 | |
tass | 152:a3d286bf94e5 | 364 | #ifdef PICO_SUPPORT_IPV6 |
tass | 152:a3d286bf94e5 | 365 | static int32_t pico_ipv6_ethernet_receive(struct pico_frame *f) |
tass | 152:a3d286bf94e5 | 366 | { |
tass | 152:a3d286bf94e5 | 367 | if (IS_IPV6(f)) { |
tass | 152:a3d286bf94e5 | 368 | pico_enqueue(pico_proto_ipv6.q_in, f); |
tass | 152:a3d286bf94e5 | 369 | } else { |
tass | 152:a3d286bf94e5 | 370 | /* Wrong version for link layer type */ |
tass | 152:a3d286bf94e5 | 371 | pico_frame_discard(f); |
tass | 152:a3d286bf94e5 | 372 | return -1; |
tass | 152:a3d286bf94e5 | 373 | } |
tass | 152:a3d286bf94e5 | 374 | |
tass | 152:a3d286bf94e5 | 375 | return (int32_t)f->buffer_len; |
tass | 152:a3d286bf94e5 | 376 | } |
tass | 152:a3d286bf94e5 | 377 | #endif |
tass | 152:a3d286bf94e5 | 378 | |
tass | 152:a3d286bf94e5 | 379 | static int32_t pico_ll_receive(struct pico_frame *f) |
tass | 152:a3d286bf94e5 | 380 | { |
tass | 152:a3d286bf94e5 | 381 | struct pico_eth_hdr *hdr = (struct pico_eth_hdr *) f->datalink_hdr; |
tass | 152:a3d286bf94e5 | 382 | f->net_hdr = f->datalink_hdr + sizeof(struct pico_eth_hdr); |
tass | 152:a3d286bf94e5 | 383 | |
tass | 152:a3d286bf94e5 | 384 | #if (defined PICO_SUPPORT_IPV4) && (defined PICO_SUPPORT_ETH) |
tass | 152:a3d286bf94e5 | 385 | if (hdr->proto == PICO_IDETH_ARP) |
tass | 152:a3d286bf94e5 | 386 | return pico_arp_receive(f); |
tass | 152:a3d286bf94e5 | 387 | |
tass | 152:a3d286bf94e5 | 388 | #endif |
tass | 152:a3d286bf94e5 | 389 | |
tass | 152:a3d286bf94e5 | 390 | #if defined (PICO_SUPPORT_IPV4) |
tass | 152:a3d286bf94e5 | 391 | if (hdr->proto == PICO_IDETH_IPV4) |
tass | 152:a3d286bf94e5 | 392 | return pico_ipv4_ethernet_receive(f); |
tass | 152:a3d286bf94e5 | 393 | |
tass | 152:a3d286bf94e5 | 394 | #endif |
tass | 152:a3d286bf94e5 | 395 | |
tass | 152:a3d286bf94e5 | 396 | #if defined (PICO_SUPPORT_IPV6) |
tass | 152:a3d286bf94e5 | 397 | if (hdr->proto == PICO_IDETH_IPV6) |
tass | 152:a3d286bf94e5 | 398 | return pico_ipv6_ethernet_receive(f); |
tass | 152:a3d286bf94e5 | 399 | |
tass | 152:a3d286bf94e5 | 400 | #endif |
tass | 152:a3d286bf94e5 | 401 | |
tass | 152:a3d286bf94e5 | 402 | pico_frame_discard(f); |
tass | 152:a3d286bf94e5 | 403 | return -1; |
tass | 152:a3d286bf94e5 | 404 | } |
tass | 152:a3d286bf94e5 | 405 | |
tass | 152:a3d286bf94e5 | 406 | static void pico_ll_check_bcast(struct pico_frame *f) |
tass | 152:a3d286bf94e5 | 407 | { |
tass | 152:a3d286bf94e5 | 408 | struct pico_eth_hdr *hdr = (struct pico_eth_hdr *) f->datalink_hdr; |
tass | 152:a3d286bf94e5 | 409 | /* Indicate a link layer broadcast packet */ |
tass | 152:a3d286bf94e5 | 410 | if (memcmp(hdr->daddr, PICO_ETHADDR_ALL, PICO_SIZE_ETH) == 0) |
tass | 152:a3d286bf94e5 | 411 | f->flags |= PICO_FRAME_FLAG_BCAST; |
tass | 152:a3d286bf94e5 | 412 | } |
tass | 152:a3d286bf94e5 | 413 | |
tass | 152:a3d286bf94e5 | 414 | int32_t pico_ethernet_receive(struct pico_frame *f) |
tass | 152:a3d286bf94e5 | 415 | { |
tass | 152:a3d286bf94e5 | 416 | struct pico_eth_hdr *hdr; |
tass | 152:a3d286bf94e5 | 417 | if (!f || !f->dev || !f->datalink_hdr) |
tass | 152:a3d286bf94e5 | 418 | { |
tass | 152:a3d286bf94e5 | 419 | pico_frame_discard(f); |
tass | 152:a3d286bf94e5 | 420 | return -1; |
tass | 152:a3d286bf94e5 | 421 | } |
tass | 152:a3d286bf94e5 | 422 | |
tass | 152:a3d286bf94e5 | 423 | hdr = (struct pico_eth_hdr *) f->datalink_hdr; |
tass | 152:a3d286bf94e5 | 424 | if ((memcmp(hdr->daddr, f->dev->eth->mac.addr, PICO_SIZE_ETH) != 0) && |
tass | 152:a3d286bf94e5 | 425 | (memcmp(hdr->daddr, PICO_ETHADDR_MCAST, PICO_SIZE_MCAST) != 0) && |
tass | 152:a3d286bf94e5 | 426 | #ifdef PICO_SUPPORT_IPV6 |
tass | 152:a3d286bf94e5 | 427 | (memcmp(hdr->daddr, PICO_ETHADDR_MCAST6, PICO_SIZE_MCAST6) != 0) && |
tass | 152:a3d286bf94e5 | 428 | #endif |
tass | 152:a3d286bf94e5 | 429 | (memcmp(hdr->daddr, PICO_ETHADDR_ALL, PICO_SIZE_ETH) != 0)) |
tass | 152:a3d286bf94e5 | 430 | { |
tass | 152:a3d286bf94e5 | 431 | pico_frame_discard(f); |
tass | 152:a3d286bf94e5 | 432 | return -1; |
tass | 152:a3d286bf94e5 | 433 | } |
tass | 152:a3d286bf94e5 | 434 | |
tass | 152:a3d286bf94e5 | 435 | pico_ll_check_bcast(f); |
tass | 152:a3d286bf94e5 | 436 | return pico_ll_receive(f); |
tass | 152:a3d286bf94e5 | 437 | } |
tass | 152:a3d286bf94e5 | 438 | |
tass | 68:0847e35d08a6 | 439 | static struct pico_eth *pico_ethernet_mcast_translate(struct pico_frame *f, uint8_t *pico_mcast_mac) |
tass | 68:0847e35d08a6 | 440 | { |
TASS Belgium NV |
131:4758606c9316 | 441 | struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr; |
tass | 68:0847e35d08a6 | 442 | |
TASS Belgium NV |
131:4758606c9316 | 443 | /* place 23 lower bits of IP in lower 23 bits of MAC */ |
tass picotcp@tass.be | 149:5f4cb161cec3 | 444 | pico_mcast_mac[5] = (long_be(hdr->dst.addr) & 0x000000FFu); |
tass picotcp@tass.be | 149:5f4cb161cec3 | 445 | pico_mcast_mac[4] = (uint8_t)((long_be(hdr->dst.addr) & 0x0000FF00u) >> 8u); |
tass picotcp@tass.be | 149:5f4cb161cec3 | 446 | pico_mcast_mac[3] = (uint8_t)((long_be(hdr->dst.addr) & 0x007F0000u) >> 16u); |
tass | 68:0847e35d08a6 | 447 | |
TASS Belgium NV |
131:4758606c9316 | 448 | return (struct pico_eth *)pico_mcast_mac; |
tass | 68:0847e35d08a6 | 449 | } |
tass | 68:0847e35d08a6 | 450 | |
tass | 68:0847e35d08a6 | 451 | |
tass picotcp@tass.be | 149:5f4cb161cec3 | 452 | #ifdef PICO_SUPPORT_IPV6 |
tass picotcp@tass.be | 149:5f4cb161cec3 | 453 | static struct pico_eth *pico_ethernet_mcast6_translate(struct pico_frame *f, uint8_t *pico_mcast6_mac) |
tass picotcp@tass.be | 149:5f4cb161cec3 | 454 | { |
tass picotcp@tass.be | 149:5f4cb161cec3 | 455 | struct pico_ipv6_hdr *hdr = (struct pico_ipv6_hdr *)f->net_hdr; |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 456 | |
tass picotcp@tass.be | 149:5f4cb161cec3 | 457 | /* first 2 octets are 0x33, last four are the last four of dst */ |
tass picotcp@tass.be | 149:5f4cb161cec3 | 458 | pico_mcast6_mac[5] = hdr->dst.addr[PICO_SIZE_IP6 - 1]; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 459 | pico_mcast6_mac[4] = hdr->dst.addr[PICO_SIZE_IP6 - 2]; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 460 | pico_mcast6_mac[3] = hdr->dst.addr[PICO_SIZE_IP6 - 3]; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 461 | pico_mcast6_mac[2] = hdr->dst.addr[PICO_SIZE_IP6 - 4]; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 462 | |
tass picotcp@tass.be | 149:5f4cb161cec3 | 463 | return (struct pico_eth *)pico_mcast6_mac; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 464 | } |
tass picotcp@tass.be | 149:5f4cb161cec3 | 465 | #endif |
tass picotcp@tass.be | 149:5f4cb161cec3 | 466 | |
tass | 152:a3d286bf94e5 | 467 | static int pico_ethernet_ipv6_dst(struct pico_frame *f, struct pico_eth *const dstmac) |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 468 | { |
tass | 152:a3d286bf94e5 | 469 | int retval = -1; |
tass | 152:a3d286bf94e5 | 470 | if (!dstmac) |
tass | 152:a3d286bf94e5 | 471 | return -1; |
tass | 152:a3d286bf94e5 | 472 | |
tass picotcp@tass.be | 149:5f4cb161cec3 | 473 | #ifdef PICO_SUPPORT_IPV6 |
tass picotcp@tass.be | 149:5f4cb161cec3 | 474 | if (destination_is_mcast(f)) { |
tass picotcp@tass.be | 149:5f4cb161cec3 | 475 | uint8_t pico_mcast6_mac[6] = { |
tass picotcp@tass.be | 149:5f4cb161cec3 | 476 | 0x33, 0x33, 0x00, 0x00, 0x00, 0x00 |
tass picotcp@tass.be | 149:5f4cb161cec3 | 477 | }; |
tass | 152:a3d286bf94e5 | 478 | pico_ethernet_mcast6_translate(f, pico_mcast6_mac); |
tass | 152:a3d286bf94e5 | 479 | memcpy(dstmac, pico_mcast6_mac, PICO_SIZE_ETH); |
tass | 152:a3d286bf94e5 | 480 | retval = 0; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 481 | } else { |
tass | 152:a3d286bf94e5 | 482 | struct pico_eth *neighbor = pico_ipv6_get_neighbor(f); |
tass | 152:a3d286bf94e5 | 483 | if (neighbor) |
tass | 152:a3d286bf94e5 | 484 | { |
tass | 152:a3d286bf94e5 | 485 | memcpy(dstmac, neighbor, PICO_SIZE_ETH); |
tass | 152:a3d286bf94e5 | 486 | retval = 0; |
tass | 152:a3d286bf94e5 | 487 | } |
tass picotcp@tass.be | 149:5f4cb161cec3 | 488 | } |
tass picotcp@tass.be | 149:5f4cb161cec3 | 489 | |
tass picotcp@tass.be | 149:5f4cb161cec3 | 490 | #else |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 491 | (void)f; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 492 | pico_err = PICO_ERR_EPROTONOSUPPORT; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 493 | #endif |
tass | 152:a3d286bf94e5 | 494 | return retval; |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 495 | } |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 496 | |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 497 | |
tass | 152:a3d286bf94e5 | 498 | /* Ethernet send, first attempt: try our own address. |
tass | 152:a3d286bf94e5 | 499 | * Returns 0 if the packet is not for us. |
tass | 152:a3d286bf94e5 | 500 | * Returns 1 if the packet is cloned to our own receive queue, so the caller can discard the original frame. |
tass | 152:a3d286bf94e5 | 501 | * */ |
tass | 152:a3d286bf94e5 | 502 | static int32_t pico_ethsend_local(struct pico_frame *f, struct pico_eth_hdr *hdr) |
tass | 152:a3d286bf94e5 | 503 | { |
tass | 152:a3d286bf94e5 | 504 | if (!hdr) |
tass | 152:a3d286bf94e5 | 505 | return 0; |
tass | 68:0847e35d08a6 | 506 | |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 507 | /* Check own mac */ |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 508 | if(!memcmp(hdr->daddr, hdr->saddr, PICO_SIZE_ETH)) { |
tass | 152:a3d286bf94e5 | 509 | struct pico_frame *clone = pico_frame_copy(f); |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 510 | dbg("sending out packet destined for our own mac\n"); |
tass | 152:a3d286bf94e5 | 511 | (void)pico_ethernet_receive(clone); |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 512 | return 1; |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 513 | } |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 514 | |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 515 | return 0; |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 516 | } |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 517 | |
tass | 152:a3d286bf94e5 | 518 | /* Ethernet send, second attempt: try bcast. |
tass | 152:a3d286bf94e5 | 519 | * Returns 0 if the packet is not bcast, so it will be handled somewhere else. |
tass | 152:a3d286bf94e5 | 520 | * Returns 1 if the packet is handled by the pico_device_broadcast() function, so it can be discarded. |
tass | 152:a3d286bf94e5 | 521 | * */ |
tass | 152:a3d286bf94e5 | 522 | static int32_t pico_ethsend_bcast(struct pico_frame *f) |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 523 | { |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 524 | if (IS_LIMITED_BCAST(f)) { |
tass | 152:a3d286bf94e5 | 525 | (void)pico_device_broadcast(f); /* We can discard broadcast even if it's not sent. */ |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 526 | return 1; |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 527 | } |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 528 | |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 529 | return 0; |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 530 | } |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 531 | |
tass | 152:a3d286bf94e5 | 532 | /* Ethernet send, third attempt: try unicast. |
tass | 152:a3d286bf94e5 | 533 | * If the device driver is busy, we return 0, so the stack won't discard the frame. |
tass | 152:a3d286bf94e5 | 534 | * In case of success, we can safely return 1. |
tass | 152:a3d286bf94e5 | 535 | */ |
tass | 152:a3d286bf94e5 | 536 | static int32_t pico_ethsend_dispatch(struct pico_frame *f) |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 537 | { |
tass | 152:a3d286bf94e5 | 538 | int ret = f->dev->send(f->dev, f->start, (int) f->len); |
tass | 152:a3d286bf94e5 | 539 | if (ret <= 0) |
tass | 152:a3d286bf94e5 | 540 | return 0; /* Failure to deliver! */ |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 541 | else { |
tass | 152:a3d286bf94e5 | 542 | return 1; /* Frame is in flight by now. */ |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 543 | } |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 544 | } |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 545 | |
tass | 152:a3d286bf94e5 | 546 | |
tass | 152:a3d286bf94e5 | 547 | |
tass | 152:a3d286bf94e5 | 548 | |
tass | 152:a3d286bf94e5 | 549 | /* This function looks for the destination mac address |
tass | 152:a3d286bf94e5 | 550 | * in order to send the frame being processed. |
tass | 152:a3d286bf94e5 | 551 | */ |
tass | 152:a3d286bf94e5 | 552 | |
tass | 152:a3d286bf94e5 | 553 | int32_t MOCKABLE pico_ethernet_send(struct pico_frame *f) |
tass | 68:0847e35d08a6 | 554 | { |
tass | 152:a3d286bf94e5 | 555 | struct pico_eth dstmac; |
tass | 152:a3d286bf94e5 | 556 | uint8_t dstmac_valid = 0; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 557 | uint16_t proto = PICO_IDETH_IPV4; |
tass | 68:0847e35d08a6 | 558 | |
tass | 152:a3d286bf94e5 | 559 | #ifdef PICO_SUPPORT_IPV6 |
tass | 152:a3d286bf94e5 | 560 | /* Step 1: If the frame has an IPv6 packet, |
tass | 152:a3d286bf94e5 | 561 | * destination address is taken from the ND tables |
tass | 152:a3d286bf94e5 | 562 | */ |
tass picotcp@tass.be | 149:5f4cb161cec3 | 563 | if (IS_IPV6(f)) { |
tass | 152:a3d286bf94e5 | 564 | if (pico_ethernet_ipv6_dst(f, &dstmac) < 0) |
tass | 152:a3d286bf94e5 | 565 | { |
tass | 152:a3d286bf94e5 | 566 | pico_ipv6_nd_postpone(f); |
tass | 152:a3d286bf94e5 | 567 | return 0; /* I don't care if frame was actually postponed. If there is no room in the ND table, discard safely. */ |
tass | 152:a3d286bf94e5 | 568 | } |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 569 | |
tass | 152:a3d286bf94e5 | 570 | dstmac_valid = 1; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 571 | proto = PICO_IDETH_IPV6; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 572 | } |
tass | 152:a3d286bf94e5 | 573 | else |
tass | 152:a3d286bf94e5 | 574 | #endif |
tass picotcp@tass.be | 149:5f4cb161cec3 | 575 | |
tass | 152:a3d286bf94e5 | 576 | /* In case of broadcast (IPV4 only), dst mac is FF:FF:... */ |
tass | 152:a3d286bf94e5 | 577 | if (IS_BCAST(f) || destination_is_bcast(f)) |
tass | 152:a3d286bf94e5 | 578 | { |
tass | 152:a3d286bf94e5 | 579 | memcpy(&dstmac, PICO_ETHADDR_ALL, PICO_SIZE_ETH); |
tass | 152:a3d286bf94e5 | 580 | dstmac_valid = 1; |
tass | 152:a3d286bf94e5 | 581 | } |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 582 | |
tass | 152:a3d286bf94e5 | 583 | /* In case of multicast, dst mac is translated from the group address */ |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 584 | else if (destination_is_mcast(f)) { |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 585 | uint8_t pico_mcast_mac[6] = { |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 586 | 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 587 | }; |
tass | 152:a3d286bf94e5 | 588 | pico_ethernet_mcast_translate(f, pico_mcast_mac); |
tass | 152:a3d286bf94e5 | 589 | memcpy(&dstmac, pico_mcast_mac, PICO_SIZE_ETH); |
tass | 152:a3d286bf94e5 | 590 | dstmac_valid = 1; |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 591 | } |
tass | 152:a3d286bf94e5 | 592 | |
tass | 152:a3d286bf94e5 | 593 | #if (defined PICO_SUPPORT_IPV4) |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 594 | else { |
tass | 152:a3d286bf94e5 | 595 | struct pico_eth *arp_get; |
tass | 152:a3d286bf94e5 | 596 | arp_get = pico_arp_get(f); |
tass | 152:a3d286bf94e5 | 597 | if (arp_get) { |
tass | 152:a3d286bf94e5 | 598 | memcpy(&dstmac, arp_get, PICO_SIZE_ETH); |
tass | 152:a3d286bf94e5 | 599 | dstmac_valid = 1; |
tass | 152:a3d286bf94e5 | 600 | } else { |
tass | 152:a3d286bf94e5 | 601 | /* At this point, ARP will discard the frame in any case. |
tass | 152:a3d286bf94e5 | 602 | * It is safe to return without discarding. |
tass | 152:a3d286bf94e5 | 603 | */ |
tass | 152:a3d286bf94e5 | 604 | pico_arp_postpone(f); |
tass | 152:a3d286bf94e5 | 605 | return 0; |
tass | 152:a3d286bf94e5 | 606 | /* Same case as for IPv6 ... */ |
tass | 152:a3d286bf94e5 | 607 | } |
tass | 152:a3d286bf94e5 | 608 | |
tass | 152:a3d286bf94e5 | 609 | } |
tass picotcp@tass.be | 149:5f4cb161cec3 | 610 | #endif |
TASS Belgium NV |
131:4758606c9316 | 611 | |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 612 | /* This sets destination and source address, then pushes the packet to the device. */ |
tass | 152:a3d286bf94e5 | 613 | if (dstmac_valid) { |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 614 | struct pico_eth_hdr *hdr; |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 615 | hdr = (struct pico_eth_hdr *) f->datalink_hdr; |
tass | 152:a3d286bf94e5 | 616 | if ((f->start > f->buffer) && ((f->start - f->buffer) >= PICO_SIZE_ETHHDR)) |
tass | 152:a3d286bf94e5 | 617 | { |
tass | 152:a3d286bf94e5 | 618 | f->start -= PICO_SIZE_ETHHDR; |
tass | 152:a3d286bf94e5 | 619 | f->len += PICO_SIZE_ETHHDR; |
tass | 152:a3d286bf94e5 | 620 | f->datalink_hdr = f->start; |
tass | 152:a3d286bf94e5 | 621 | hdr = (struct pico_eth_hdr *) f->datalink_hdr; |
tass | 152:a3d286bf94e5 | 622 | memcpy(hdr->saddr, f->dev->eth->mac.addr, PICO_SIZE_ETH); |
tass | 152:a3d286bf94e5 | 623 | memcpy(hdr->daddr, &dstmac, PICO_SIZE_ETH); |
tass | 152:a3d286bf94e5 | 624 | hdr->proto = proto; |
tass | 152:a3d286bf94e5 | 625 | } |
tass | 68:0847e35d08a6 | 626 | |
tass | 152:a3d286bf94e5 | 627 | if (pico_ethsend_local(f, hdr) || pico_ethsend_bcast(f) || pico_ethsend_dispatch(f)) { |
tass | 152:a3d286bf94e5 | 628 | /* one of the above functions has delivered the frame accordingly. (returned != 0) |
tass | 152:a3d286bf94e5 | 629 | * It is safe to directly return success. |
tass | 152:a3d286bf94e5 | 630 | * */ |
tass | 152:a3d286bf94e5 | 631 | return 0; |
TASS Belgium NV |
131:4758606c9316 | 632 | } |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 633 | } |
TASS Belgium NV |
131:4758606c9316 | 634 | |
tass | 152:a3d286bf94e5 | 635 | /* Failure: do not dequeue the frame, keep it for later. */ |
TASS Belgium NV |
131:4758606c9316 | 636 | return -1; |
tass | 68:0847e35d08a6 | 637 | } |
tass | 68:0847e35d08a6 | 638 | |
tass | 152:a3d286bf94e5 | 639 | #endif /* PICO_SUPPORT_ETH */ |
tass | 152:a3d286bf94e5 | 640 | |
tass | 152:a3d286bf94e5 | 641 | |
tass | 68:0847e35d08a6 | 642 | void pico_store_network_origin(void *src, struct pico_frame *f) |
tass | 68:0847e35d08a6 | 643 | { |
tass | 68:0847e35d08a6 | 644 | #ifdef PICO_SUPPORT_IPV4 |
TASS Belgium NV |
131:4758606c9316 | 645 | struct pico_ip4 *ip4; |
tass | 68:0847e35d08a6 | 646 | #endif |
tass | 68:0847e35d08a6 | 647 | |
tass | 68:0847e35d08a6 | 648 | #ifdef PICO_SUPPORT_IPV6 |
TASS Belgium NV |
131:4758606c9316 | 649 | struct pico_ip6 *ip6; |
tass | 68:0847e35d08a6 | 650 | #endif |
tass | 68:0847e35d08a6 | 651 | |
tass | 68:0847e35d08a6 | 652 | #ifdef PICO_SUPPORT_IPV4 |
TASS Belgium NV |
131:4758606c9316 | 653 | if (IS_IPV4(f)) { |
TASS Belgium NV |
131:4758606c9316 | 654 | struct pico_ipv4_hdr *hdr; |
TASS Belgium NV |
131:4758606c9316 | 655 | hdr = (struct pico_ipv4_hdr *) f->net_hdr; |
TASS Belgium NV |
131:4758606c9316 | 656 | ip4 = (struct pico_ip4 *) src; |
TASS Belgium NV |
131:4758606c9316 | 657 | ip4->addr = hdr->src.addr; |
TASS Belgium NV |
131:4758606c9316 | 658 | } |
TASS Belgium NV |
131:4758606c9316 | 659 | |
tass | 68:0847e35d08a6 | 660 | #endif |
tass | 68:0847e35d08a6 | 661 | #ifdef PICO_SUPPORT_IPV6 |
TASS Belgium NV |
131:4758606c9316 | 662 | if (IS_IPV6(f)) { |
TASS Belgium NV |
131:4758606c9316 | 663 | struct pico_ipv6_hdr *hdr; |
TASS Belgium NV |
131:4758606c9316 | 664 | hdr = (struct pico_ipv6_hdr *) f->net_hdr; |
TASS Belgium NV |
131:4758606c9316 | 665 | ip6 = (struct pico_ip6 *) src; |
TASS Belgium NV |
131:4758606c9316 | 666 | memcpy(ip6->addr, hdr->src.addr, PICO_SIZE_IP6); |
TASS Belgium NV |
131:4758606c9316 | 667 | } |
TASS Belgium NV |
131:4758606c9316 | 668 | |
tass | 68:0847e35d08a6 | 669 | #endif |
tass | 68:0847e35d08a6 | 670 | } |
tass | 68:0847e35d08a6 | 671 | |
tass | 152:a3d286bf94e5 | 672 | int pico_address_compare(union pico_address *a, union pico_address *b, uint16_t proto) |
tass | 152:a3d286bf94e5 | 673 | { |
tass | 152:a3d286bf94e5 | 674 | #ifdef PICO_SUPPORT_IPV6 |
tass | 152:a3d286bf94e5 | 675 | if (proto == PICO_PROTO_IPV6) { |
tass | 152:a3d286bf94e5 | 676 | return pico_ipv6_compare(&a->ip6, &b->ip6); |
tass | 152:a3d286bf94e5 | 677 | } |
tass | 152:a3d286bf94e5 | 678 | |
tass | 152:a3d286bf94e5 | 679 | #endif |
tass | 152:a3d286bf94e5 | 680 | #ifdef PICO_SUPPORT_IPV4 |
tass | 152:a3d286bf94e5 | 681 | if (proto == PICO_PROTO_IPV4) { |
tass | 152:a3d286bf94e5 | 682 | return pico_ipv4_compare(&a->ip4, &b->ip4); |
tass | 152:a3d286bf94e5 | 683 | } |
tass | 152:a3d286bf94e5 | 684 | |
tass | 152:a3d286bf94e5 | 685 | #endif |
tass | 152:a3d286bf94e5 | 686 | return 0; |
tass | 152:a3d286bf94e5 | 687 | |
tass | 152:a3d286bf94e5 | 688 | } |
tass | 152:a3d286bf94e5 | 689 | |
tass | 152:a3d286bf94e5 | 690 | int pico_frame_dst_is_unicast(struct pico_frame *f) |
tass | 152:a3d286bf94e5 | 691 | { |
tass | 152:a3d286bf94e5 | 692 | if (0) { |
tass | 152:a3d286bf94e5 | 693 | return 0; |
tass | 152:a3d286bf94e5 | 694 | } |
tass | 152:a3d286bf94e5 | 695 | |
tass | 152:a3d286bf94e5 | 696 | #ifdef PICO_SUPPORT_IPV4 |
tass | 152:a3d286bf94e5 | 697 | if (IS_IPV4(f)) { |
tass | 152:a3d286bf94e5 | 698 | struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *)f->net_hdr; |
tass | 152:a3d286bf94e5 | 699 | if (pico_ipv4_is_multicast(hdr->dst.addr) || pico_ipv4_is_broadcast(hdr->dst.addr)) |
tass | 152:a3d286bf94e5 | 700 | return 0; |
tass | 152:a3d286bf94e5 | 701 | |
tass | 152:a3d286bf94e5 | 702 | return 1; |
tass | 152:a3d286bf94e5 | 703 | } |
tass | 152:a3d286bf94e5 | 704 | |
tass | 152:a3d286bf94e5 | 705 | #endif |
tass | 152:a3d286bf94e5 | 706 | |
tass | 152:a3d286bf94e5 | 707 | #ifdef PICO_SUPPORT_IPV6 |
tass | 152:a3d286bf94e5 | 708 | if (IS_IPV6(f)) { |
tass | 152:a3d286bf94e5 | 709 | struct pico_ipv6_hdr *hdr = (struct pico_ipv6_hdr *)f->net_hdr; |
tass | 152:a3d286bf94e5 | 710 | if (pico_ipv6_is_multicast(hdr->dst.addr) || pico_ipv6_is_unspecified(hdr->dst.addr)) |
tass | 152:a3d286bf94e5 | 711 | return 0; |
tass | 152:a3d286bf94e5 | 712 | |
tass | 152:a3d286bf94e5 | 713 | return 1; |
tass | 152:a3d286bf94e5 | 714 | } |
tass | 152:a3d286bf94e5 | 715 | |
tass | 152:a3d286bf94e5 | 716 | #endif |
tass | 152:a3d286bf94e5 | 717 | else return 0; |
tass | 152:a3d286bf94e5 | 718 | } |
tass | 152:a3d286bf94e5 | 719 | |
tass | 68:0847e35d08a6 | 720 | |
tass | 68:0847e35d08a6 | 721 | /* LOWEST LEVEL: interface towards devices. */ |
tass | 68:0847e35d08a6 | 722 | /* Device driver will call this function which returns immediately. |
tass | 68:0847e35d08a6 | 723 | * Incoming packet will be processed later on in the dev loop. |
tass | 68:0847e35d08a6 | 724 | */ |
tass | 70:cd218dd180e5 | 725 | int32_t pico_stack_recv(struct pico_device *dev, uint8_t *buffer, uint32_t len) |
tass | 68:0847e35d08a6 | 726 | { |
TASS Belgium NV |
131:4758606c9316 | 727 | struct pico_frame *f; |
TASS Belgium NV |
131:4758606c9316 | 728 | int32_t ret; |
TASS Belgium NV |
131:4758606c9316 | 729 | if (len <= 0) |
TASS Belgium NV |
131:4758606c9316 | 730 | return -1; |
tass | 68:0847e35d08a6 | 731 | |
TASS Belgium NV |
131:4758606c9316 | 732 | f = pico_frame_alloc(len); |
TASS Belgium NV |
131:4758606c9316 | 733 | if (!f) |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 734 | { |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 735 | dbg("Cannot alloc incoming frame!\n"); |
TASS Belgium NV |
131:4758606c9316 | 736 | return -1; |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 737 | } |
TASS Belgium NV |
131:4758606c9316 | 738 | |
TASS Belgium NV |
131:4758606c9316 | 739 | /* Association to the device that just received the frame. */ |
TASS Belgium NV |
131:4758606c9316 | 740 | f->dev = dev; |
tass | 68:0847e35d08a6 | 741 | |
tass picotcp@tass.be | 137:a1c8bfa9d691 | 742 | /* Setup the start pointer, length. */ |
TASS Belgium NV |
131:4758606c9316 | 743 | f->start = f->buffer; |
TASS Belgium NV |
131:4758606c9316 | 744 | f->len = f->buffer_len; |
TASS Belgium NV |
131:4758606c9316 | 745 | if (f->len > 8) { |
tass | 152:a3d286bf94e5 | 746 | uint32_t rand, mid_frame = (f->buffer_len >> 2) << 1; |
TASS Belgium NV |
131:4758606c9316 | 747 | mid_frame -= (mid_frame % 4); |
tass | 152:a3d286bf94e5 | 748 | memcpy(&rand, f->buffer + mid_frame, sizeof(uint32_t)); |
tass | 152:a3d286bf94e5 | 749 | pico_rand_feed(rand); |
TASS Belgium NV |
131:4758606c9316 | 750 | } |
TASS Belgium NV |
131:4758606c9316 | 751 | |
TASS Belgium NV |
131:4758606c9316 | 752 | memcpy(f->buffer, buffer, len); |
TASS Belgium NV |
131:4758606c9316 | 753 | ret = pico_enqueue(dev->q_in, f); |
TASS Belgium NV |
131:4758606c9316 | 754 | if (ret <= 0) { |
TASS Belgium NV |
131:4758606c9316 | 755 | pico_frame_discard(f); |
TASS Belgium NV |
131:4758606c9316 | 756 | } |
TASS Belgium NV |
131:4758606c9316 | 757 | |
TASS Belgium NV |
131:4758606c9316 | 758 | return ret; |
tass | 68:0847e35d08a6 | 759 | } |
tass | 68:0847e35d08a6 | 760 | |
tass | 152:a3d286bf94e5 | 761 | static int32_t _pico_stack_recv_zerocopy(struct pico_device *dev, uint8_t *buffer, uint32_t len, int ext_buffer, void (*notify_free)(uint8_t *)) |
tass picotcp@tass.be | 149:5f4cb161cec3 | 762 | { |
tass picotcp@tass.be | 149:5f4cb161cec3 | 763 | struct pico_frame *f; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 764 | int ret; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 765 | if (len <= 0) |
tass picotcp@tass.be | 149:5f4cb161cec3 | 766 | return -1; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 767 | |
tass | 152:a3d286bf94e5 | 768 | f = pico_frame_alloc_skeleton(len, ext_buffer); |
tass picotcp@tass.be | 149:5f4cb161cec3 | 769 | if (!f) |
tass picotcp@tass.be | 149:5f4cb161cec3 | 770 | { |
tass picotcp@tass.be | 149:5f4cb161cec3 | 771 | dbg("Cannot alloc incoming frame!\n"); |
tass picotcp@tass.be | 149:5f4cb161cec3 | 772 | return -1; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 773 | } |
tass picotcp@tass.be | 149:5f4cb161cec3 | 774 | |
tass picotcp@tass.be | 149:5f4cb161cec3 | 775 | if (pico_frame_skeleton_set_buffer(f, buffer) < 0) |
tass picotcp@tass.be | 149:5f4cb161cec3 | 776 | { |
tass picotcp@tass.be | 149:5f4cb161cec3 | 777 | dbg("Invalid zero-copy buffer!\n"); |
tass picotcp@tass.be | 149:5f4cb161cec3 | 778 | PICO_FREE(f->usage_count); |
tass picotcp@tass.be | 149:5f4cb161cec3 | 779 | PICO_FREE(f); |
tass picotcp@tass.be | 149:5f4cb161cec3 | 780 | return -1; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 781 | } |
tass picotcp@tass.be | 149:5f4cb161cec3 | 782 | |
tass | 152:a3d286bf94e5 | 783 | if (notify_free) { |
tass | 152:a3d286bf94e5 | 784 | f->notify_free = notify_free; |
tass | 152:a3d286bf94e5 | 785 | } |
tass | 152:a3d286bf94e5 | 786 | |
tass picotcp@tass.be | 149:5f4cb161cec3 | 787 | f->dev = dev; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 788 | ret = pico_enqueue(dev->q_in, f); |
tass picotcp@tass.be | 149:5f4cb161cec3 | 789 | if (ret <= 0) { |
tass picotcp@tass.be | 149:5f4cb161cec3 | 790 | pico_frame_discard(f); |
tass picotcp@tass.be | 149:5f4cb161cec3 | 791 | } |
tass picotcp@tass.be | 149:5f4cb161cec3 | 792 | |
tass picotcp@tass.be | 149:5f4cb161cec3 | 793 | return ret; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 794 | } |
tass picotcp@tass.be | 149:5f4cb161cec3 | 795 | |
tass | 152:a3d286bf94e5 | 796 | int32_t pico_stack_recv_zerocopy(struct pico_device *dev, uint8_t *buffer, uint32_t len) |
tass | 152:a3d286bf94e5 | 797 | { |
tass | 152:a3d286bf94e5 | 798 | return _pico_stack_recv_zerocopy(dev, buffer, len, 0, NULL); |
tass | 152:a3d286bf94e5 | 799 | } |
tass | 152:a3d286bf94e5 | 800 | |
tass | 152:a3d286bf94e5 | 801 | int32_t pico_stack_recv_zerocopy_ext_buffer(struct pico_device *dev, uint8_t *buffer, uint32_t len) |
tass | 152:a3d286bf94e5 | 802 | { |
tass | 152:a3d286bf94e5 | 803 | return _pico_stack_recv_zerocopy(dev, buffer, len, 1, NULL); |
tass | 152:a3d286bf94e5 | 804 | } |
tass | 152:a3d286bf94e5 | 805 | |
tass | 152:a3d286bf94e5 | 806 | int32_t pico_stack_recv_zerocopy_ext_buffer_notify(struct pico_device *dev, uint8_t *buffer, uint32_t len, void (*notify_free)(uint8_t *buffer)) |
tass | 152:a3d286bf94e5 | 807 | { |
tass | 152:a3d286bf94e5 | 808 | return _pico_stack_recv_zerocopy(dev, buffer, len, 1, notify_free); |
tass | 152:a3d286bf94e5 | 809 | } |
tass | 152:a3d286bf94e5 | 810 | |
tass | 70:cd218dd180e5 | 811 | int32_t pico_sendto_dev(struct pico_frame *f) |
tass | 68:0847e35d08a6 | 812 | { |
TASS Belgium NV |
131:4758606c9316 | 813 | if (!f->dev) { |
TASS Belgium NV |
131:4758606c9316 | 814 | pico_frame_discard(f); |
TASS Belgium NV |
131:4758606c9316 | 815 | return -1; |
TASS Belgium NV |
131:4758606c9316 | 816 | } else { |
TASS Belgium NV |
131:4758606c9316 | 817 | if (f->len > 8) { |
tass | 152:a3d286bf94e5 | 818 | uint32_t rand, mid_frame = (f->buffer_len >> 2) << 1; |
TASS Belgium NV |
131:4758606c9316 | 819 | mid_frame -= (mid_frame % 4); |
tass | 152:a3d286bf94e5 | 820 | memcpy(&rand, f->buffer + mid_frame, sizeof(uint32_t)); |
tass | 152:a3d286bf94e5 | 821 | pico_rand_feed(rand); |
TASS Belgium NV |
131:4758606c9316 | 822 | } |
TASS Belgium NV |
131:4758606c9316 | 823 | |
TASS Belgium NV |
131:4758606c9316 | 824 | return pico_enqueue(f->dev->q_out, f); |
tass | 68:0847e35d08a6 | 825 | } |
tass | 68:0847e35d08a6 | 826 | } |
tass | 68:0847e35d08a6 | 827 | |
tass | 68:0847e35d08a6 | 828 | struct pico_timer |
tass | 68:0847e35d08a6 | 829 | { |
TASS Belgium NV |
131:4758606c9316 | 830 | void *arg; |
TASS Belgium NV |
131:4758606c9316 | 831 | void (*timer)(pico_time timestamp, void *arg); |
tass | 68:0847e35d08a6 | 832 | }; |
tass | 68:0847e35d08a6 | 833 | |
tass | 70:cd218dd180e5 | 834 | struct pico_timer_ref |
tass | 70:cd218dd180e5 | 835 | { |
TASS Belgium NV |
131:4758606c9316 | 836 | pico_time expire; |
TASS Belgium NV |
131:4758606c9316 | 837 | struct pico_timer *tmr; |
tass | 70:cd218dd180e5 | 838 | }; |
tass | 68:0847e35d08a6 | 839 | |
tass | 70:cd218dd180e5 | 840 | typedef struct pico_timer_ref pico_timer_ref; |
tass | 68:0847e35d08a6 | 841 | |
tass | 70:cd218dd180e5 | 842 | DECLARE_HEAP(pico_timer_ref, expire); |
tass | 70:cd218dd180e5 | 843 | |
tass | 70:cd218dd180e5 | 844 | static heap_pico_timer_ref *Timers; |
tass | 68:0847e35d08a6 | 845 | |
tass | 152:a3d286bf94e5 | 846 | int32_t pico_seq_compare(uint32_t a, uint32_t b) |
tass | 152:a3d286bf94e5 | 847 | { |
tass | 152:a3d286bf94e5 | 848 | uint32_t thresh = ((uint32_t)(-1)) >> 1; |
tass | 152:a3d286bf94e5 | 849 | |
tass | 152:a3d286bf94e5 | 850 | if (a > b) /* return positive number, if not wrapped */ |
tass | 152:a3d286bf94e5 | 851 | { |
tass | 152:a3d286bf94e5 | 852 | if ((a - b) > thresh) /* b wrapped */ |
tass | 152:a3d286bf94e5 | 853 | return -(int32_t)(b - a); /* b = very small, a = very big */ |
tass | 152:a3d286bf94e5 | 854 | else |
tass | 152:a3d286bf94e5 | 855 | return (int32_t)(a - b); /* a = biggest, b = a bit smaller */ |
tass | 152:a3d286bf94e5 | 856 | |
tass | 152:a3d286bf94e5 | 857 | } |
tass | 152:a3d286bf94e5 | 858 | |
tass | 152:a3d286bf94e5 | 859 | if (a < b) /* return negative number, if not wrapped */ |
tass | 152:a3d286bf94e5 | 860 | { |
tass | 152:a3d286bf94e5 | 861 | if ((b - a) > thresh) /* a wrapped */ |
tass | 152:a3d286bf94e5 | 862 | return (int32_t)(a - b); /* a = very small, b = very big */ |
tass | 152:a3d286bf94e5 | 863 | else |
tass | 152:a3d286bf94e5 | 864 | return -(int32_t)(b - a); /* b = biggest, a = a bit smaller */ |
tass | 152:a3d286bf94e5 | 865 | |
tass | 152:a3d286bf94e5 | 866 | } |
tass | 152:a3d286bf94e5 | 867 | |
tass | 152:a3d286bf94e5 | 868 | return 0; |
tass | 152:a3d286bf94e5 | 869 | } |
tass | 152:a3d286bf94e5 | 870 | |
tass | 152:a3d286bf94e5 | 871 | static void pico_check_timers(void) |
tass | 68:0847e35d08a6 | 872 | { |
TASS Belgium NV |
131:4758606c9316 | 873 | struct pico_timer *t; |
TASS Belgium NV |
131:4758606c9316 | 874 | struct pico_timer_ref tref_unused, *tref = heap_first(Timers); |
TASS Belgium NV |
131:4758606c9316 | 875 | pico_tick = PICO_TIME_MS(); |
TASS Belgium NV |
131:4758606c9316 | 876 | while((tref) && (tref->expire < pico_tick)) { |
TASS Belgium NV |
131:4758606c9316 | 877 | t = tref->tmr; |
TASS Belgium NV |
131:4758606c9316 | 878 | if (t && t->timer) |
TASS Belgium NV |
131:4758606c9316 | 879 | t->timer(pico_tick, t->arg); |
TASS Belgium NV |
131:4758606c9316 | 880 | |
TASS Belgium NV |
131:4758606c9316 | 881 | if (t) |
tass | 152:a3d286bf94e5 | 882 | { |
tass picotcp@tass.be | 149:5f4cb161cec3 | 883 | PICO_FREE(t); |
tass | 152:a3d286bf94e5 | 884 | } |
TASS Belgium NV |
131:4758606c9316 | 885 | |
TASS Belgium NV |
131:4758606c9316 | 886 | t = NULL; |
TASS Belgium NV |
131:4758606c9316 | 887 | heap_peek(Timers, &tref_unused); |
TASS Belgium NV |
131:4758606c9316 | 888 | tref = heap_first(Timers); |
TASS Belgium NV |
131:4758606c9316 | 889 | } |
tass | 70:cd218dd180e5 | 890 | } |
tass | 70:cd218dd180e5 | 891 | |
tass | 152:a3d286bf94e5 | 892 | void MOCKABLE pico_timer_cancel(struct pico_timer *t) |
tass | 70:cd218dd180e5 | 893 | { |
TASS Belgium NV |
131:4758606c9316 | 894 | uint32_t i; |
TASS Belgium NV |
131:4758606c9316 | 895 | struct pico_timer_ref *tref = Timers->top; |
TASS Belgium NV |
131:4758606c9316 | 896 | if (!t) |
TASS Belgium NV |
131:4758606c9316 | 897 | return; |
TASS Belgium NV |
131:4758606c9316 | 898 | |
TASS Belgium NV |
131:4758606c9316 | 899 | for (i = 1; i <= Timers->n; i++) { |
TASS Belgium NV |
131:4758606c9316 | 900 | if (tref[i].tmr == t) { |
TASS Belgium NV |
131:4758606c9316 | 901 | Timers->top[i].tmr = NULL; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 902 | PICO_FREE(t); |
TASS Belgium NV |
131:4758606c9316 | 903 | break; |
TASS Belgium NV |
131:4758606c9316 | 904 | } |
tass | 70:cd218dd180e5 | 905 | } |
tass | 68:0847e35d08a6 | 906 | } |
tass | 68:0847e35d08a6 | 907 | |
tass | 68:0847e35d08a6 | 908 | #define PROTO_DEF_NR 11 |
tass | 68:0847e35d08a6 | 909 | #define PROTO_DEF_AVG_NR 4 |
tass | 68:0847e35d08a6 | 910 | #define PROTO_DEF_SCORE 32 |
tass | 68:0847e35d08a6 | 911 | #define PROTO_MIN_SCORE 32 |
tass | 68:0847e35d08a6 | 912 | #define PROTO_MAX_SCORE 128 |
tass | 152:a3d286bf94e5 | 913 | #define PROTO_LAT_IND 3 /* latency indication 0-3 (lower is better latency performance), x1, x2, x4, x8 */ |
TASS Belgium NV |
131:4758606c9316 | 914 | #define PROTO_MAX_LOOP (PROTO_MAX_SCORE << PROTO_LAT_IND) /* max global loop score, so per tick */ |
tass | 68:0847e35d08a6 | 915 | |
tass | 68:0847e35d08a6 | 916 | static int calc_score(int *score, int *index, int avg[][PROTO_DEF_AVG_NR], int *ret) |
tass | 68:0847e35d08a6 | 917 | { |
TASS Belgium NV |
131:4758606c9316 | 918 | int temp, i, j, sum; |
TASS Belgium NV |
131:4758606c9316 | 919 | int max_total = PROTO_MAX_LOOP, total = 0; |
tass | 68:0847e35d08a6 | 920 | |
TASS Belgium NV |
131:4758606c9316 | 921 | /* dbg("USED SCORES> "); */ |
tass | 68:0847e35d08a6 | 922 | |
TASS Belgium NV |
131:4758606c9316 | 923 | for (i = 0; i < PROTO_DEF_NR; i++) { |
tass | 68:0847e35d08a6 | 924 | |
TASS Belgium NV |
131:4758606c9316 | 925 | /* if used looped score */ |
TASS Belgium NV |
131:4758606c9316 | 926 | if (ret[i] < score[i]) { |
TASS Belgium NV |
131:4758606c9316 | 927 | temp = score[i] - ret[i]; /* remaining loop score */ |
TASS Belgium NV |
131:4758606c9316 | 928 | |
TASS Belgium NV |
131:4758606c9316 | 929 | /* dbg("%3d - ",temp); */ |
tass | 68:0847e35d08a6 | 930 | |
TASS Belgium NV |
131:4758606c9316 | 931 | if (index[i] >= PROTO_DEF_AVG_NR) |
TASS Belgium NV |
131:4758606c9316 | 932 | index[i] = 0; /* reset index */ |
TASS Belgium NV |
131:4758606c9316 | 933 | |
TASS Belgium NV |
131:4758606c9316 | 934 | j = index[i]; |
TASS Belgium NV |
131:4758606c9316 | 935 | avg[i][j] = temp; |
tass | 68:0847e35d08a6 | 936 | |
TASS Belgium NV |
131:4758606c9316 | 937 | index[i]++; |
tass | 68:0847e35d08a6 | 938 | |
tass picotcp@tass.be | 149:5f4cb161cec3 | 939 | if (ret[i] == 0 && ((score[i] * 2) <= PROTO_MAX_SCORE) && ((total + (score[i] * 2)) < max_total)) { /* used all loop score -> increase next score directly */ |
tass picotcp@tass.be | 149:5f4cb161cec3 | 940 | score[i] *= 2; |
TASS Belgium NV |
131:4758606c9316 | 941 | total += score[i]; |
TASS Belgium NV |
131:4758606c9316 | 942 | continue; |
TASS Belgium NV |
131:4758606c9316 | 943 | } |
tass | 68:0847e35d08a6 | 944 | |
TASS Belgium NV |
131:4758606c9316 | 945 | sum = 0; |
TASS Belgium NV |
131:4758606c9316 | 946 | for (j = 0; j < PROTO_DEF_AVG_NR; j++) |
TASS Belgium NV |
131:4758606c9316 | 947 | sum += avg[i][j]; /* calculate sum */ |
tass | 68:0847e35d08a6 | 948 | |
tass picotcp@tass.be | 149:5f4cb161cec3 | 949 | sum /= 4; /* divide by 4 to get average used score */ |
tass | 68:0847e35d08a6 | 950 | |
TASS Belgium NV |
131:4758606c9316 | 951 | /* criterion to increase next loop score */ |
tass picotcp@tass.be | 149:5f4cb161cec3 | 952 | if (sum > (score[i] - (score[i] / 4)) && ((score[i] * 2) <= PROTO_MAX_SCORE) && ((total + (score[i] / 2)) < max_total)) { /* > 3/4 */ |
tass picotcp@tass.be | 149:5f4cb161cec3 | 953 | score[i] *= 2; /* double loop score */ |
TASS Belgium NV |
131:4758606c9316 | 954 | total += score[i]; |
TASS Belgium NV |
131:4758606c9316 | 955 | continue; |
TASS Belgium NV |
131:4758606c9316 | 956 | } |
tass | 68:0847e35d08a6 | 957 | |
TASS Belgium NV |
131:4758606c9316 | 958 | /* criterion to decrease next loop score */ |
tass picotcp@tass.be | 149:5f4cb161cec3 | 959 | if ((sum < (score[i] / 4)) && ((score[i] / 2) >= PROTO_MIN_SCORE)) { /* < 1/4 */ |
tass picotcp@tass.be | 149:5f4cb161cec3 | 960 | score[i] /= 2; /* half loop score */ |
TASS Belgium NV |
131:4758606c9316 | 961 | total += score[i]; |
TASS Belgium NV |
131:4758606c9316 | 962 | continue; |
TASS Belgium NV |
131:4758606c9316 | 963 | } |
tass | 68:0847e35d08a6 | 964 | |
TASS Belgium NV |
131:4758606c9316 | 965 | /* also add non-changed scores */ |
TASS Belgium NV |
131:4758606c9316 | 966 | total += score[i]; |
TASS Belgium NV |
131:4758606c9316 | 967 | } |
TASS Belgium NV |
131:4758606c9316 | 968 | else if (ret[i] == score[i]) { |
TASS Belgium NV |
131:4758606c9316 | 969 | /* no used loop score - gradually decrease */ |
tass | 68:0847e35d08a6 | 970 | |
TASS Belgium NV |
131:4758606c9316 | 971 | /* dbg("%3d - ",0); */ |
TASS Belgium NV |
131:4758606c9316 | 972 | |
TASS Belgium NV |
131:4758606c9316 | 973 | if (index[i] >= PROTO_DEF_AVG_NR) |
TASS Belgium NV |
131:4758606c9316 | 974 | index[i] = 0; /* reset index */ |
TASS Belgium NV |
131:4758606c9316 | 975 | |
TASS Belgium NV |
131:4758606c9316 | 976 | j = index[i]; |
TASS Belgium NV |
131:4758606c9316 | 977 | avg[i][j] = 0; |
tass | 68:0847e35d08a6 | 978 | |
TASS Belgium NV |
131:4758606c9316 | 979 | index[i]++; |
tass | 68:0847e35d08a6 | 980 | |
TASS Belgium NV |
131:4758606c9316 | 981 | sum = 0; |
TASS Belgium NV |
131:4758606c9316 | 982 | for (j = 0; j < PROTO_DEF_AVG_NR; j++) |
TASS Belgium NV |
131:4758606c9316 | 983 | sum += avg[i][j]; /* calculate sum */ |
tass | 68:0847e35d08a6 | 984 | |
tass picotcp@tass.be | 149:5f4cb161cec3 | 985 | sum /= 2; /* divide by 4 to get average used score */ |
tass | 68:0847e35d08a6 | 986 | |
tass picotcp@tass.be | 149:5f4cb161cec3 | 987 | if ((sum == 0) && ((score[i] / 2) >= PROTO_MIN_SCORE)) { |
tass picotcp@tass.be | 149:5f4cb161cec3 | 988 | score[i] /= 2; /* half loop score */ |
TASS Belgium NV |
131:4758606c9316 | 989 | total += score[i]; |
TASS Belgium NV |
131:4758606c9316 | 990 | for (j = 0; j < PROTO_DEF_AVG_NR; j++) |
TASS Belgium NV |
131:4758606c9316 | 991 | avg[i][j] = score[i]; |
TASS Belgium NV |
131:4758606c9316 | 992 | } |
TASS Belgium NV |
131:4758606c9316 | 993 | |
TASS Belgium NV |
131:4758606c9316 | 994 | } |
tass | 68:0847e35d08a6 | 995 | } |
TASS Belgium NV |
131:4758606c9316 | 996 | /* dbg("\n"); */ |
tass | 68:0847e35d08a6 | 997 | |
TASS Belgium NV |
131:4758606c9316 | 998 | return 0; |
tass | 68:0847e35d08a6 | 999 | } |
tass | 68:0847e35d08a6 | 1000 | |
tass | 68:0847e35d08a6 | 1001 | void pico_stack_tick(void) |
tass | 68:0847e35d08a6 | 1002 | { |
TASS Belgium NV |
131:4758606c9316 | 1003 | static int score[PROTO_DEF_NR] = { |
TASS Belgium NV |
131:4758606c9316 | 1004 | 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 | 1005 | }; |
TASS Belgium NV |
131:4758606c9316 | 1006 | static int index[PROTO_DEF_NR] = { |
TASS Belgium NV |
131:4758606c9316 | 1007 | 0, 0, 0, 0, 0, 0 |
TASS Belgium NV |
131:4758606c9316 | 1008 | }; |
tass | 68:0847e35d08a6 | 1009 | static int avg[PROTO_DEF_NR][PROTO_DEF_AVG_NR]; |
TASS Belgium NV |
131:4758606c9316 | 1010 | static int ret[PROTO_DEF_NR] = { |
TASS Belgium NV |
131:4758606c9316 | 1011 | 0 |
TASS Belgium NV |
131:4758606c9316 | 1012 | }; |
tass | 68:0847e35d08a6 | 1013 | |
tass | 68:0847e35d08a6 | 1014 | pico_check_timers(); |
tass | 68:0847e35d08a6 | 1015 | |
TASS Belgium NV |
131:4758606c9316 | 1016 | /* 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 | 1017 | |
TASS Belgium NV |
131:4758606c9316 | 1018 | /* score = pico_protocols_loop(100); */ |
tass | 68:0847e35d08a6 | 1019 | |
TASS Belgium NV |
131:4758606c9316 | 1020 | ret[0] = pico_devices_loop(score[0], PICO_LOOP_DIR_IN); |
tass | 70:cd218dd180e5 | 1021 | pico_rand_feed((uint32_t)ret[0]); |
tass | 68:0847e35d08a6 | 1022 | |
tass | 68:0847e35d08a6 | 1023 | ret[1] = pico_protocol_datalink_loop(score[1], PICO_LOOP_DIR_IN); |
tass | 70:cd218dd180e5 | 1024 | pico_rand_feed((uint32_t)ret[1]); |
tass | 68:0847e35d08a6 | 1025 | |
tass | 68:0847e35d08a6 | 1026 | ret[2] = pico_protocol_network_loop(score[2], PICO_LOOP_DIR_IN); |
tass | 70:cd218dd180e5 | 1027 | pico_rand_feed((uint32_t)ret[2]); |
tass | 68:0847e35d08a6 | 1028 | |
tass | 68:0847e35d08a6 | 1029 | ret[3] = pico_protocol_transport_loop(score[3], PICO_LOOP_DIR_IN); |
tass | 70:cd218dd180e5 | 1030 | pico_rand_feed((uint32_t)ret[3]); |
tass | 68:0847e35d08a6 | 1031 | |
tass | 68:0847e35d08a6 | 1032 | |
tass | 68:0847e35d08a6 | 1033 | ret[5] = score[5]; |
tass | 68:0847e35d08a6 | 1034 | #if defined (PICO_SUPPORT_IPV4) || defined (PICO_SUPPORT_IPV6) |
tass | 68:0847e35d08a6 | 1035 | #if defined (PICO_SUPPORT_TCP) || defined (PICO_SUPPORT_UDP) |
TASS Belgium NV |
131:4758606c9316 | 1036 | ret[5] = pico_sockets_loop(score[5]); /* swapped */ |
tass | 70:cd218dd180e5 | 1037 | pico_rand_feed((uint32_t)ret[5]); |
tass | 68:0847e35d08a6 | 1038 | #endif |
tass | 68:0847e35d08a6 | 1039 | #endif |
tass | 68:0847e35d08a6 | 1040 | |
tass | 68:0847e35d08a6 | 1041 | ret[4] = pico_protocol_socket_loop(score[4], PICO_LOOP_DIR_IN); |
tass | 70:cd218dd180e5 | 1042 | pico_rand_feed((uint32_t)ret[4]); |
tass | 68:0847e35d08a6 | 1043 | |
tass | 68:0847e35d08a6 | 1044 | |
tass | 68:0847e35d08a6 | 1045 | ret[6] = pico_protocol_socket_loop(score[6], PICO_LOOP_DIR_OUT); |
tass | 70:cd218dd180e5 | 1046 | pico_rand_feed((uint32_t)ret[6]); |
tass | 68:0847e35d08a6 | 1047 | |
tass | 68:0847e35d08a6 | 1048 | ret[7] = pico_protocol_transport_loop(score[7], PICO_LOOP_DIR_OUT); |
tass | 70:cd218dd180e5 | 1049 | pico_rand_feed((uint32_t)ret[7]); |
tass | 68:0847e35d08a6 | 1050 | |
tass | 68:0847e35d08a6 | 1051 | ret[8] = pico_protocol_network_loop(score[8], PICO_LOOP_DIR_OUT); |
tass | 70:cd218dd180e5 | 1052 | pico_rand_feed((uint32_t)ret[8]); |
tass | 68:0847e35d08a6 | 1053 | |
tass | 68:0847e35d08a6 | 1054 | ret[9] = pico_protocol_datalink_loop(score[9], PICO_LOOP_DIR_OUT); |
tass | 70:cd218dd180e5 | 1055 | pico_rand_feed((uint32_t)ret[9]); |
tass | 68:0847e35d08a6 | 1056 | |
TASS Belgium NV |
131:4758606c9316 | 1057 | ret[10] = pico_devices_loop(score[10], PICO_LOOP_DIR_OUT); |
tass | 70:cd218dd180e5 | 1058 | pico_rand_feed((uint32_t)ret[10]); |
tass | 68:0847e35d08a6 | 1059 | |
tass | 68:0847e35d08a6 | 1060 | /* calculate new loop scores for next iteration */ |
TASS Belgium NV |
131:4758606c9316 | 1061 | calc_score(score, index, (int (*)[])avg, ret); |
tass | 68:0847e35d08a6 | 1062 | } |
tass | 68:0847e35d08a6 | 1063 | |
tass | 68:0847e35d08a6 | 1064 | void pico_stack_loop(void) |
tass | 68:0847e35d08a6 | 1065 | { |
TASS Belgium NV |
131:4758606c9316 | 1066 | while(1) { |
TASS Belgium NV |
131:4758606c9316 | 1067 | pico_stack_tick(); |
TASS Belgium NV |
131:4758606c9316 | 1068 | PICO_IDLE(); |
TASS Belgium NV |
131:4758606c9316 | 1069 | } |
tass | 68:0847e35d08a6 | 1070 | } |
tass | 68:0847e35d08a6 | 1071 | |
tass | 152:a3d286bf94e5 | 1072 | MOCKABLE struct pico_timer *pico_timer_add(pico_time expire, void (*timer)(pico_time, void *), void *arg) |
tass | 68:0847e35d08a6 | 1073 | { |
tass picotcp@tass.be | 149:5f4cb161cec3 | 1074 | struct pico_timer *t = PICO_ZALLOC(sizeof(struct pico_timer)); |
TASS Belgium NV |
131:4758606c9316 | 1075 | struct pico_timer_ref tref; |
TASS Belgium NV |
131:4758606c9316 | 1076 | if (!t) { |
TASS Belgium NV |
131:4758606c9316 | 1077 | pico_err = PICO_ERR_ENOMEM; |
TASS Belgium NV |
131:4758606c9316 | 1078 | return NULL; |
TASS Belgium NV |
131:4758606c9316 | 1079 | } |
TASS Belgium NV |
131:4758606c9316 | 1080 | |
TASS Belgium NV |
131:4758606c9316 | 1081 | tref.expire = PICO_TIME_MS() + expire; |
TASS Belgium NV |
131:4758606c9316 | 1082 | t->arg = arg; |
TASS Belgium NV |
131:4758606c9316 | 1083 | t->timer = timer; |
TASS Belgium NV |
131:4758606c9316 | 1084 | tref.tmr = t; |
tass picotcp@tass.be | 138:0a7a449980e6 | 1085 | heap_insert(Timers, &tref); |
TASS Belgium NV |
131:4758606c9316 | 1086 | if (Timers->n > PICO_MAX_TIMERS) { |
tass | 152:a3d286bf94e5 | 1087 | dbg("Warning: I have %d timers\n", (int)Timers->n); |
TASS Belgium NV |
131:4758606c9316 | 1088 | } |
TASS Belgium NV |
131:4758606c9316 | 1089 | |
TASS Belgium NV |
131:4758606c9316 | 1090 | return t; |
tass | 68:0847e35d08a6 | 1091 | } |
tass | 68:0847e35d08a6 | 1092 | |
tass picotcp@tass.be | 149:5f4cb161cec3 | 1093 | int pico_stack_init(void) |
tass | 68:0847e35d08a6 | 1094 | { |
tass | 68:0847e35d08a6 | 1095 | |
tass | 68:0847e35d08a6 | 1096 | #ifdef PICO_SUPPORT_IPV4 |
TASS Belgium NV |
131:4758606c9316 | 1097 | pico_protocol_init(&pico_proto_ipv4); |
tass | 68:0847e35d08a6 | 1098 | #endif |
tass | 68:0847e35d08a6 | 1099 | |
tass | 68:0847e35d08a6 | 1100 | #ifdef PICO_SUPPORT_IPV6 |
TASS Belgium NV |
131:4758606c9316 | 1101 | pico_protocol_init(&pico_proto_ipv6); |
tass | 68:0847e35d08a6 | 1102 | #endif |
tass | 68:0847e35d08a6 | 1103 | |
tass | 68:0847e35d08a6 | 1104 | #ifdef PICO_SUPPORT_ICMP4 |
TASS Belgium NV |
131:4758606c9316 | 1105 | pico_protocol_init(&pico_proto_icmp4); |
tass | 68:0847e35d08a6 | 1106 | #endif |
tass | 68:0847e35d08a6 | 1107 | |
tass picotcp@tass.be | 149:5f4cb161cec3 | 1108 | #ifdef PICO_SUPPORT_ICMP6 |
tass picotcp@tass.be | 149:5f4cb161cec3 | 1109 | pico_protocol_init(&pico_proto_icmp6); |
tass picotcp@tass.be | 149:5f4cb161cec3 | 1110 | #endif |
tass picotcp@tass.be | 149:5f4cb161cec3 | 1111 | |
tass | 152:a3d286bf94e5 | 1112 | #if defined(PICO_SUPPORT_IGMP) && defined(PICO_SUPPORT_MCAST) |
TASS Belgium NV |
131:4758606c9316 | 1113 | pico_protocol_init(&pico_proto_igmp); |
tass | 68:0847e35d08a6 | 1114 | #endif |
tass | 68:0847e35d08a6 | 1115 | |
tass | 68:0847e35d08a6 | 1116 | #ifdef PICO_SUPPORT_UDP |
TASS Belgium NV |
131:4758606c9316 | 1117 | pico_protocol_init(&pico_proto_udp); |
tass | 68:0847e35d08a6 | 1118 | #endif |
tass | 68:0847e35d08a6 | 1119 | |
tass | 68:0847e35d08a6 | 1120 | #ifdef PICO_SUPPORT_TCP |
TASS Belgium NV |
131:4758606c9316 | 1121 | pico_protocol_init(&pico_proto_tcp); |
tass | 68:0847e35d08a6 | 1122 | #endif |
tass | 68:0847e35d08a6 | 1123 | |
tass | 68:0847e35d08a6 | 1124 | #ifdef PICO_SUPPORT_DNS_CLIENT |
TASS Belgium NV |
131:4758606c9316 | 1125 | pico_dns_client_init(); |
tass | 68:0847e35d08a6 | 1126 | #endif |
tass | 68:0847e35d08a6 | 1127 | |
TASS Belgium NV |
131:4758606c9316 | 1128 | pico_rand_feed(123456); |
tass | 68:0847e35d08a6 | 1129 | |
TASS Belgium NV |
131:4758606c9316 | 1130 | /* Initialize timer heap */ |
TASS Belgium NV |
131:4758606c9316 | 1131 | Timers = heap_init(); |
tass picotcp@tass.be | 149:5f4cb161cec3 | 1132 | if (!Timers) |
tass picotcp@tass.be | 149:5f4cb161cec3 | 1133 | return -1; |
tass picotcp@tass.be | 149:5f4cb161cec3 | 1134 | |
tass picotcp@tass.be | 149:5f4cb161cec3 | 1135 | #if ((defined PICO_SUPPORT_IPV4) && (defined PICO_SUPPORT_ETH)) |
tass picotcp@tass.be | 149:5f4cb161cec3 | 1136 | /* Initialize ARP module */ |
tass picotcp@tass.be | 133:5b075f5e141a | 1137 | pico_arp_init(); |
tass picotcp@tass.be | 149:5f4cb161cec3 | 1138 | #endif |
tass picotcp@tass.be | 149:5f4cb161cec3 | 1139 | |
tass picotcp@tass.be | 149:5f4cb161cec3 | 1140 | #ifdef PICO_SUPPORT_IPV6 |
tass picotcp@tass.be | 149:5f4cb161cec3 | 1141 | /* Initialize Neighbor discovery module */ |
tass picotcp@tass.be | 149:5f4cb161cec3 | 1142 | pico_ipv6_nd_init(); |
tass picotcp@tass.be | 149:5f4cb161cec3 | 1143 | #endif |
tass | 152:a3d286bf94e5 | 1144 | |
tass | 152:a3d286bf94e5 | 1145 | #ifdef PICO_SUPPORT_OLSR |
tass | 152:a3d286bf94e5 | 1146 | pico_olsr_init(); |
tass | 152:a3d286bf94e5 | 1147 | #endif |
tass | 152:a3d286bf94e5 | 1148 | #ifdef PICO_SUPPORT_AODV |
tass | 152:a3d286bf94e5 | 1149 | pico_aodv_init(); |
tass | 152:a3d286bf94e5 | 1150 | #endif |
tass | 152:a3d286bf94e5 | 1151 | |
TASS Belgium NV |
131:4758606c9316 | 1152 | pico_stack_tick(); |
TASS Belgium NV |
131:4758606c9316 | 1153 | pico_stack_tick(); |
TASS Belgium NV |
131:4758606c9316 | 1154 | pico_stack_tick(); |
tass picotcp@tass.be | 149:5f4cb161cec3 | 1155 | return 0; |
tass | 68:0847e35d08a6 | 1156 | } |
tass | 68:0847e35d08a6 | 1157 |