Free (GPLv2) TCP/IP stack developed by TASS Belgium

Dependents:   lpc1768-picotcp-demo ZeroMQ_PicoTCP_Publisher_demo TCPSocket_HelloWorld_PicoTCP Pico_TCP_UDP_Test ... more

PicoTCP. Copyright (c) 2013 TASS Belgium NV.

Released under the GNU General Public License, version 2.

Different licensing models may exist, at the sole discretion of the Copyright holders.

Official homepage: http://www.picotcp.com

Bug tracker: https://github.com/tass-belgium/picotcp/issues

Development steps:

  • initial integration with mbed RTOS
  • generic mbed Ethernet driver
  • high performance NXP LPC1768 specific Ethernet driver
  • Multi-threading support for mbed RTOS
  • Berkeley sockets and integration with the New Socket API
  • Fork of the apps running on top of the New Socket API
  • Scheduling optimizations
  • Debugging/benchmarking/testing

Demo application (measuring TCP sender performance):

Import programlpc1768-picotcp-demo

A PicoTCP demo app testing the ethernet throughput on the lpc1768 mbed board.

Committer:
tass picotcp@tass.be
Date:
Wed Apr 09 14:31:41 2014 +0200
Revision:
149:5f4cb161cec3
Parent:
138:0a7a449980e6
Child:
152:a3d286bf94e5
Update from git masterbranch

Who changed what in which revision?

UserRevisionLine numberNew contents of line
tass 68:0847e35d08a6 1 /*********************************************************************
TASS Belgium NV 131:4758606c9316 2 PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
TASS Belgium NV 131:4758606c9316 3 See LICENSE and COPYING for usage.
tass 68:0847e35d08a6 4
TASS Belgium NV 131:4758606c9316 5 .
tass 68:0847e35d08a6 6
TASS Belgium NV 131:4758606c9316 7 Authors: Daniele Lacamera
TASS Belgium NV 131:4758606c9316 8 *********************************************************************/
tass 68:0847e35d08a6 9
tass 68:0847e35d08a6 10
tass 68:0847e35d08a6 11 #include "pico_config.h"
tass 68:0847e35d08a6 12 #include "pico_device.h"
tass 68:0847e35d08a6 13 #include "pico_stack.h"
tass 68:0847e35d08a6 14 #include "pico_protocol.h"
tass 68:0847e35d08a6 15 #include "pico_tree.h"
tass picotcp@tass.be 149:5f4cb161cec3 16 #include "pico_ipv6.h"
tass picotcp@tass.be 149:5f4cb161cec3 17 #include "pico_ipv4.h"
tass picotcp@tass.be 149:5f4cb161cec3 18 #include "pico_icmp6.h"
tass 68:0847e35d08a6 19
tass picotcp@tass.be 137:a1c8bfa9d691 20 struct pico_devices_rr_info {
tass picotcp@tass.be 137:a1c8bfa9d691 21 struct pico_tree_node *node_in, *node_out;
tass picotcp@tass.be 137:a1c8bfa9d691 22 };
tass picotcp@tass.be 137:a1c8bfa9d691 23
tass picotcp@tass.be 137:a1c8bfa9d691 24 static struct pico_devices_rr_info Devices_rr_info = {
tass picotcp@tass.be 137:a1c8bfa9d691 25 NULL, NULL
tass picotcp@tass.be 137:a1c8bfa9d691 26 };
tass 68:0847e35d08a6 27
tass 68:0847e35d08a6 28 static int pico_dev_cmp(void *ka, void *kb)
tass 68:0847e35d08a6 29 {
TASS Belgium NV 131:4758606c9316 30 struct pico_device *a = ka, *b = kb;
TASS Belgium NV 131:4758606c9316 31 if (a->hash < b->hash)
TASS Belgium NV 131:4758606c9316 32 return -1;
TASS Belgium NV 131:4758606c9316 33
TASS Belgium NV 131:4758606c9316 34 if (a->hash > b->hash)
TASS Belgium NV 131:4758606c9316 35 return 1;
TASS Belgium NV 131:4758606c9316 36
TASS Belgium NV 131:4758606c9316 37 return 0;
tass 68:0847e35d08a6 38 }
tass 68:0847e35d08a6 39
TASS Belgium NV 131:4758606c9316 40 PICO_TREE_DECLARE(Device_tree, pico_dev_cmp);
tass 68:0847e35d08a6 41
tass 68:0847e35d08a6 42 int pico_device_init(struct pico_device *dev, const char *name, uint8_t *mac)
tass 68:0847e35d08a6 43 {
tass picotcp@tass.be 149:5f4cb161cec3 44 #ifdef PICO_SUPPORT_IPV6
tass picotcp@tass.be 149:5f4cb161cec3 45 struct pico_ip6 linklocal = {{0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xaa, 0xaa, 0xaa, 0xff, 0xfe, 0xaa, 0xaa, 0xaa}};
tass picotcp@tass.be 149:5f4cb161cec3 46 struct pico_ip6 netmask6 = {{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}};
tass picotcp@tass.be 149:5f4cb161cec3 47 #endif
tass picotcp@tass.be 149:5f4cb161cec3 48
TASS Belgium NV 131:4758606c9316 49 uint32_t len = (uint32_t)strlen(name);
TASS Belgium NV 131:4758606c9316 50 if(len > MAX_DEVICE_NAME)
TASS Belgium NV 131:4758606c9316 51 len = MAX_DEVICE_NAME;
tass 68:0847e35d08a6 52
TASS Belgium NV 131:4758606c9316 53 memcpy(dev->name, name, len);
tass picotcp@tass.be 133:5b075f5e141a 54 dev->hash = pico_hash(dev->name, len);
TASS Belgium NV 131:4758606c9316 55
tass picotcp@tass.be 137:a1c8bfa9d691 56 Devices_rr_info.node_in = NULL;
tass picotcp@tass.be 137:a1c8bfa9d691 57 Devices_rr_info.node_out = NULL;
tass picotcp@tass.be 149:5f4cb161cec3 58 dev->q_in = PICO_ZALLOC(sizeof(struct pico_queue));
tass picotcp@tass.be 149:5f4cb161cec3 59 dev->q_out = PICO_ZALLOC(sizeof(struct pico_queue));
tass picotcp@tass.be 149:5f4cb161cec3 60 if (!dev->q_in || !dev->q_out)
tass picotcp@tass.be 149:5f4cb161cec3 61 return -1;
tass picotcp@tass.be 149:5f4cb161cec3 62
tass picotcp@tass.be 149:5f4cb161cec3 63 pico_tree_insert(&Device_tree, dev);
tass 68:0847e35d08a6 64
TASS Belgium NV 131:4758606c9316 65 if (mac) {
tass picotcp@tass.be 149:5f4cb161cec3 66 dev->eth = PICO_ZALLOC(sizeof(struct pico_ethdev));
tass picotcp@tass.be 149:5f4cb161cec3 67 if (dev->eth) {
tass picotcp@tass.be 149:5f4cb161cec3 68 memcpy(dev->eth->mac.addr, mac, PICO_SIZE_ETH);
tass picotcp@tass.be 149:5f4cb161cec3 69 #ifdef PICO_SUPPORT_IPV6
tass picotcp@tass.be 149:5f4cb161cec3 70 /* modified EUI-64 + invert universal/local bit */
tass picotcp@tass.be 149:5f4cb161cec3 71 linklocal.addr[8] = (mac[0] ^ 0x02);
tass picotcp@tass.be 149:5f4cb161cec3 72 linklocal.addr[9] = mac[1];
tass picotcp@tass.be 149:5f4cb161cec3 73 linklocal.addr[10] = mac[2];
tass picotcp@tass.be 149:5f4cb161cec3 74 linklocal.addr[13] = mac[3];
tass picotcp@tass.be 149:5f4cb161cec3 75 linklocal.addr[14] = mac[4];
tass picotcp@tass.be 149:5f4cb161cec3 76 linklocal.addr[15] = mac[5];
tass picotcp@tass.be 149:5f4cb161cec3 77 if (pico_ipv6_link_add(dev, linklocal, netmask6)) {
tass picotcp@tass.be 149:5f4cb161cec3 78 PICO_FREE(dev->q_in);
tass picotcp@tass.be 149:5f4cb161cec3 79 PICO_FREE(dev->q_out);
tass picotcp@tass.be 149:5f4cb161cec3 80 PICO_FREE(dev->eth);
tass picotcp@tass.be 149:5f4cb161cec3 81 return -1;
tass picotcp@tass.be 149:5f4cb161cec3 82 }
tass picotcp@tass.be 149:5f4cb161cec3 83
tass picotcp@tass.be 149:5f4cb161cec3 84 #endif
tass picotcp@tass.be 149:5f4cb161cec3 85 }
tass picotcp@tass.be 149:5f4cb161cec3 86
tass picotcp@tass.be 149:5f4cb161cec3 87
TASS Belgium NV 131:4758606c9316 88 } else {
TASS Belgium NV 131:4758606c9316 89 dev->eth = NULL;
tass picotcp@tass.be 149:5f4cb161cec3 90 #ifdef PICO_SUPPORT_IPV6
tass picotcp@tass.be 149:5f4cb161cec3 91 if (strcmp(dev->name, "loop")) {
tass picotcp@tass.be 149:5f4cb161cec3 92 do {
tass picotcp@tass.be 149:5f4cb161cec3 93 /* privacy extension + unset universal/local and individual/group bit */
tass picotcp@tass.be 149:5f4cb161cec3 94 len = pico_rand();
tass picotcp@tass.be 149:5f4cb161cec3 95 linklocal.addr[8] = (uint8_t)((len & 0xffu) & (uint8_t)(~0x03));
tass picotcp@tass.be 149:5f4cb161cec3 96 linklocal.addr[9] = (uint8_t)(len >> 8);
tass picotcp@tass.be 149:5f4cb161cec3 97 linklocal.addr[10] = (uint8_t)(len >> 16);
tass picotcp@tass.be 149:5f4cb161cec3 98 linklocal.addr[11] = (uint8_t)(len >> 24);
tass picotcp@tass.be 149:5f4cb161cec3 99 len = pico_rand();
tass picotcp@tass.be 149:5f4cb161cec3 100 linklocal.addr[12] = (uint8_t)len;
tass picotcp@tass.be 149:5f4cb161cec3 101 linklocal.addr[13] = (uint8_t)(len >> 8);
tass picotcp@tass.be 149:5f4cb161cec3 102 linklocal.addr[14] = (uint8_t)(len >> 16);
tass picotcp@tass.be 149:5f4cb161cec3 103 linklocal.addr[15] = (uint8_t)(len >> 24);
tass picotcp@tass.be 149:5f4cb161cec3 104 pico_rand_feed(dev->hash);
tass picotcp@tass.be 149:5f4cb161cec3 105 } while (pico_ipv6_link_get(&linklocal));
tass picotcp@tass.be 149:5f4cb161cec3 106
tass picotcp@tass.be 149:5f4cb161cec3 107 if (pico_ipv6_link_add(dev, linklocal, netmask6)) {
tass picotcp@tass.be 149:5f4cb161cec3 108 PICO_FREE(dev->q_in);
tass picotcp@tass.be 149:5f4cb161cec3 109 PICO_FREE(dev->q_out);
tass picotcp@tass.be 149:5f4cb161cec3 110 return -1;
tass picotcp@tass.be 149:5f4cb161cec3 111 }
tass picotcp@tass.be 149:5f4cb161cec3 112 }
tass picotcp@tass.be 149:5f4cb161cec3 113
tass picotcp@tass.be 149:5f4cb161cec3 114 #endif
TASS Belgium NV 131:4758606c9316 115 }
tass 68:0847e35d08a6 116
tass picotcp@tass.be 149:5f4cb161cec3 117 #ifdef PICO_SUPPORT_IPV6
tass picotcp@tass.be 149:5f4cb161cec3 118 if (dev->eth)
tass picotcp@tass.be 149:5f4cb161cec3 119 {
tass picotcp@tass.be 149:5f4cb161cec3 120 dev->hostvars.mtu = PICO_ETH_MTU;
tass picotcp@tass.be 149:5f4cb161cec3 121 dev->hostvars.basetime = PICO_ND_REACHABLE_TIME;
tass picotcp@tass.be 149:5f4cb161cec3 122 /* RFC 4861 $6.3.2 value between 0.5 and 1.5 times basetime */
tass picotcp@tass.be 149:5f4cb161cec3 123 dev->hostvars.reachabletime = ((5 + (pico_rand() % 10)) * PICO_ND_REACHABLE_TIME) / 10;
tass picotcp@tass.be 149:5f4cb161cec3 124 dev->hostvars.retranstime = PICO_ND_RETRANS_TIMER;
tass picotcp@tass.be 149:5f4cb161cec3 125 pico_icmp6_router_solicitation(dev, &linklocal);
tass picotcp@tass.be 149:5f4cb161cec3 126 }
tass picotcp@tass.be 149:5f4cb161cec3 127
tass picotcp@tass.be 149:5f4cb161cec3 128 dev->hostvars.hoplimit = PICO_IPV6_DEFAULT_HOP;
tass picotcp@tass.be 149:5f4cb161cec3 129 #endif
tass picotcp@tass.be 149:5f4cb161cec3 130
TASS Belgium NV 131:4758606c9316 131
TASS Belgium NV 131:4758606c9316 132 return 0;
tass 68:0847e35d08a6 133 }
tass 68:0847e35d08a6 134
tass picotcp@tass.be 137:a1c8bfa9d691 135 static void pico_queue_destroy(struct pico_queue *q)
tass picotcp@tass.be 137:a1c8bfa9d691 136 {
tass picotcp@tass.be 137:a1c8bfa9d691 137 if (q) {
tass picotcp@tass.be 137:a1c8bfa9d691 138 pico_queue_empty(q);
tass picotcp@tass.be 149:5f4cb161cec3 139 PICO_FREE(q);
tass picotcp@tass.be 137:a1c8bfa9d691 140 }
tass picotcp@tass.be 137:a1c8bfa9d691 141 }
tass picotcp@tass.be 137:a1c8bfa9d691 142
tass 68:0847e35d08a6 143 void pico_device_destroy(struct pico_device *dev)
tass 68:0847e35d08a6 144 {
TASS Belgium NV 131:4758606c9316 145 if (dev->destroy)
TASS Belgium NV 131:4758606c9316 146 dev->destroy(dev);
TASS Belgium NV 131:4758606c9316 147
tass picotcp@tass.be 137:a1c8bfa9d691 148 pico_queue_destroy(dev->q_in);
tass picotcp@tass.be 137:a1c8bfa9d691 149 pico_queue_destroy(dev->q_out);
tass 68:0847e35d08a6 150
TASS Belgium NV 131:4758606c9316 151 if (dev->eth)
tass picotcp@tass.be 149:5f4cb161cec3 152 PICO_FREE(dev->eth);
tass picotcp@tass.be 149:5f4cb161cec3 153
tass picotcp@tass.be 149:5f4cb161cec3 154 #ifdef PICO_SUPPORT_IPV4
tass picotcp@tass.be 149:5f4cb161cec3 155 pico_ipv4_cleanup_links(dev);
tass picotcp@tass.be 149:5f4cb161cec3 156 #endif
tass picotcp@tass.be 149:5f4cb161cec3 157 #ifdef PICO_SUPPORT_IPV6
tass picotcp@tass.be 149:5f4cb161cec3 158 pico_ipv6_cleanup_links(dev);
tass picotcp@tass.be 149:5f4cb161cec3 159 #endif
tass picotcp@tass.be 149:5f4cb161cec3 160 pico_tree_delete(&Device_tree, dev);
tass picotcp@tass.be 149:5f4cb161cec3 161
tass 68:0847e35d08a6 162
TASS Belgium NV 131:4758606c9316 163 pico_tree_delete(&Device_tree, dev);
tass picotcp@tass.be 137:a1c8bfa9d691 164 Devices_rr_info.node_in = NULL;
tass picotcp@tass.be 137:a1c8bfa9d691 165 Devices_rr_info.node_out = NULL;
tass picotcp@tass.be 149:5f4cb161cec3 166 PICO_FREE(dev);
tass 68:0847e35d08a6 167 }
tass 68:0847e35d08a6 168
tass picotcp@tass.be 137:a1c8bfa9d691 169 static int check_dev_serve_interrupt(struct pico_device *dev, int loop_score)
tass 68:0847e35d08a6 170 {
TASS Belgium NV 131:4758606c9316 171 if ((dev->__serving_interrupt) && (dev->dsr)) {
TASS Belgium NV 131:4758606c9316 172 /* call dsr routine */
TASS Belgium NV 131:4758606c9316 173 loop_score = dev->dsr(dev, loop_score);
TASS Belgium NV 131:4758606c9316 174 }
TASS Belgium NV 131:4758606c9316 175
tass picotcp@tass.be 137:a1c8bfa9d691 176 return loop_score;
tass picotcp@tass.be 137:a1c8bfa9d691 177 }
tass picotcp@tass.be 137:a1c8bfa9d691 178
tass picotcp@tass.be 137:a1c8bfa9d691 179 static int check_dev_serve_polling(struct pico_device *dev, int loop_score)
tass picotcp@tass.be 137:a1c8bfa9d691 180 {
TASS Belgium NV 131:4758606c9316 181 if (dev->poll) {
TASS Belgium NV 131:4758606c9316 182 loop_score = dev->poll(dev, loop_score);
tass 68:0847e35d08a6 183 }
tass 68:0847e35d08a6 184
TASS Belgium NV 131:4758606c9316 185 return loop_score;
tass 68:0847e35d08a6 186 }
tass 68:0847e35d08a6 187
tass picotcp@tass.be 137:a1c8bfa9d691 188 static int devloop_in(struct pico_device *dev, int loop_score)
tass picotcp@tass.be 137:a1c8bfa9d691 189 {
tass picotcp@tass.be 137:a1c8bfa9d691 190 struct pico_frame *f;
tass picotcp@tass.be 137:a1c8bfa9d691 191 while(loop_score > 0) {
tass picotcp@tass.be 137:a1c8bfa9d691 192 if (dev->q_in->frames <= 0)
tass picotcp@tass.be 137:a1c8bfa9d691 193 break;
tass picotcp@tass.be 137:a1c8bfa9d691 194
tass picotcp@tass.be 137:a1c8bfa9d691 195 /* Receive */
tass picotcp@tass.be 137:a1c8bfa9d691 196 f = pico_dequeue(dev->q_in);
tass picotcp@tass.be 137:a1c8bfa9d691 197 if (f) {
tass picotcp@tass.be 137:a1c8bfa9d691 198 if (dev->eth) {
tass picotcp@tass.be 137:a1c8bfa9d691 199 f->datalink_hdr = f->buffer;
tass picotcp@tass.be 137:a1c8bfa9d691 200 pico_ethernet_receive(f);
tass picotcp@tass.be 137:a1c8bfa9d691 201 } else {
tass picotcp@tass.be 137:a1c8bfa9d691 202 f->net_hdr = f->buffer;
tass picotcp@tass.be 137:a1c8bfa9d691 203 pico_network_receive(f);
tass picotcp@tass.be 137:a1c8bfa9d691 204 }
tass picotcp@tass.be 137:a1c8bfa9d691 205
tass picotcp@tass.be 137:a1c8bfa9d691 206 loop_score--;
tass picotcp@tass.be 137:a1c8bfa9d691 207 }
tass picotcp@tass.be 137:a1c8bfa9d691 208 }
tass picotcp@tass.be 137:a1c8bfa9d691 209 return loop_score;
tass picotcp@tass.be 137:a1c8bfa9d691 210 }
tass picotcp@tass.be 137:a1c8bfa9d691 211
tass picotcp@tass.be 137:a1c8bfa9d691 212 static int devloop_sendto_dev(struct pico_device *dev, struct pico_frame *f)
tass picotcp@tass.be 137:a1c8bfa9d691 213 {
tass picotcp@tass.be 137:a1c8bfa9d691 214
tass picotcp@tass.be 137:a1c8bfa9d691 215 int ret;
tass picotcp@tass.be 137:a1c8bfa9d691 216 if (dev->eth) {
tass picotcp@tass.be 137:a1c8bfa9d691 217 ret = pico_ethernet_send(f);
tass picotcp@tass.be 137:a1c8bfa9d691 218 if (0 <= ret) {
tass picotcp@tass.be 138:0a7a449980e6 219 return -1;
tass picotcp@tass.be 137:a1c8bfa9d691 220 } else {
tass picotcp@tass.be 137:a1c8bfa9d691 221 if (!pico_source_is_local(f)) {
tass picotcp@tass.be 137:a1c8bfa9d691 222 dbg("Destination unreachable -------> SEND ICMP\n");
tass picotcp@tass.be 137:a1c8bfa9d691 223 pico_notify_dest_unreachable(f);
tass picotcp@tass.be 137:a1c8bfa9d691 224 } else {
tass picotcp@tass.be 137:a1c8bfa9d691 225 dbg("Destination unreachable -------> LOCAL\n");
tass picotcp@tass.be 137:a1c8bfa9d691 226 }
tass picotcp@tass.be 137:a1c8bfa9d691 227
tass picotcp@tass.be 137:a1c8bfa9d691 228 pico_frame_discard(f);
tass picotcp@tass.be 137:a1c8bfa9d691 229 return 1;
tass picotcp@tass.be 137:a1c8bfa9d691 230 }
tass picotcp@tass.be 137:a1c8bfa9d691 231 } else {
tass picotcp@tass.be 138:0a7a449980e6 232 /* non-ethernet */
tass picotcp@tass.be 138:0a7a449980e6 233 if (dev->send(dev, f->start, (int)f->len) <= 0)
tass picotcp@tass.be 138:0a7a449980e6 234 return -1;
tass picotcp@tass.be 138:0a7a449980e6 235
tass picotcp@tass.be 137:a1c8bfa9d691 236 pico_frame_discard(f);
tass picotcp@tass.be 137:a1c8bfa9d691 237 return 1;
tass picotcp@tass.be 137:a1c8bfa9d691 238 }
tass picotcp@tass.be 137:a1c8bfa9d691 239 }
tass picotcp@tass.be 137:a1c8bfa9d691 240
tass picotcp@tass.be 137:a1c8bfa9d691 241 static int devloop_out(struct pico_device *dev, int loop_score)
tass picotcp@tass.be 137:a1c8bfa9d691 242 {
tass picotcp@tass.be 137:a1c8bfa9d691 243 struct pico_frame *f;
tass picotcp@tass.be 137:a1c8bfa9d691 244 while(loop_score > 0) {
tass picotcp@tass.be 137:a1c8bfa9d691 245 if (dev->q_out->frames <= 0)
tass picotcp@tass.be 137:a1c8bfa9d691 246 break;
tass picotcp@tass.be 137:a1c8bfa9d691 247
tass picotcp@tass.be 137:a1c8bfa9d691 248 /* Device dequeue + send */
tass picotcp@tass.be 137:a1c8bfa9d691 249 f = pico_dequeue(dev->q_out);
tass picotcp@tass.be 137:a1c8bfa9d691 250 if (!f)
tass picotcp@tass.be 137:a1c8bfa9d691 251 break;
tass picotcp@tass.be 137:a1c8bfa9d691 252
tass picotcp@tass.be 138:0a7a449980e6 253 if (devloop_sendto_dev(dev, f) < 0)
tass picotcp@tass.be 138:0a7a449980e6 254 break;
tass picotcp@tass.be 138:0a7a449980e6 255
tass picotcp@tass.be 138:0a7a449980e6 256 loop_score--;
tass picotcp@tass.be 137:a1c8bfa9d691 257 }
tass picotcp@tass.be 137:a1c8bfa9d691 258 return loop_score;
tass picotcp@tass.be 137:a1c8bfa9d691 259 }
tass picotcp@tass.be 137:a1c8bfa9d691 260
tass picotcp@tass.be 137:a1c8bfa9d691 261 static int devloop(struct pico_device *dev, int loop_score, int direction)
tass picotcp@tass.be 137:a1c8bfa9d691 262 {
tass picotcp@tass.be 137:a1c8bfa9d691 263 /* If device supports interrupts, read the value of the condition and trigger the dsr */
tass picotcp@tass.be 137:a1c8bfa9d691 264 loop_score = check_dev_serve_interrupt(dev, loop_score);
tass picotcp@tass.be 137:a1c8bfa9d691 265
tass picotcp@tass.be 137:a1c8bfa9d691 266 /* If device supports polling, give control. Loop score is managed internally,
tass picotcp@tass.be 137:a1c8bfa9d691 267 * remaining loop points are returned. */
tass picotcp@tass.be 137:a1c8bfa9d691 268 loop_score = check_dev_serve_polling(dev, loop_score);
tass picotcp@tass.be 137:a1c8bfa9d691 269
tass picotcp@tass.be 137:a1c8bfa9d691 270 if (direction == PICO_LOOP_DIR_OUT)
tass picotcp@tass.be 137:a1c8bfa9d691 271 loop_score = devloop_out(dev, loop_score);
tass picotcp@tass.be 137:a1c8bfa9d691 272 else
tass picotcp@tass.be 137:a1c8bfa9d691 273 loop_score = devloop_in(dev, loop_score);
tass picotcp@tass.be 137:a1c8bfa9d691 274
tass picotcp@tass.be 137:a1c8bfa9d691 275 return loop_score;
tass picotcp@tass.be 137:a1c8bfa9d691 276 }
tass picotcp@tass.be 137:a1c8bfa9d691 277
tass picotcp@tass.be 137:a1c8bfa9d691 278
tass picotcp@tass.be 137:a1c8bfa9d691 279 static struct pico_tree_node *pico_dev_roundrobin_start(int direction)
tass picotcp@tass.be 137:a1c8bfa9d691 280 {
tass picotcp@tass.be 137:a1c8bfa9d691 281 if (Devices_rr_info.node_in == NULL)
tass picotcp@tass.be 137:a1c8bfa9d691 282 Devices_rr_info.node_in = pico_tree_firstNode(Device_tree.root);
tass picotcp@tass.be 137:a1c8bfa9d691 283
tass picotcp@tass.be 137:a1c8bfa9d691 284 if (Devices_rr_info.node_out == NULL)
tass picotcp@tass.be 137:a1c8bfa9d691 285 Devices_rr_info.node_out = pico_tree_firstNode(Device_tree.root);
tass picotcp@tass.be 137:a1c8bfa9d691 286
tass picotcp@tass.be 137:a1c8bfa9d691 287 if (direction == PICO_LOOP_DIR_IN)
tass picotcp@tass.be 137:a1c8bfa9d691 288 return Devices_rr_info.node_in;
tass picotcp@tass.be 137:a1c8bfa9d691 289 else
tass picotcp@tass.be 137:a1c8bfa9d691 290 return Devices_rr_info.node_out;
tass picotcp@tass.be 137:a1c8bfa9d691 291 }
tass picotcp@tass.be 137:a1c8bfa9d691 292
tass picotcp@tass.be 137:a1c8bfa9d691 293 static void pico_dev_roundrobin_end(int direction, struct pico_tree_node *last)
tass picotcp@tass.be 137:a1c8bfa9d691 294 {
tass picotcp@tass.be 137:a1c8bfa9d691 295 if (direction == PICO_LOOP_DIR_IN)
tass picotcp@tass.be 137:a1c8bfa9d691 296 Devices_rr_info.node_in = last;
tass picotcp@tass.be 137:a1c8bfa9d691 297 else
tass picotcp@tass.be 137:a1c8bfa9d691 298 Devices_rr_info.node_out = last;
tass picotcp@tass.be 137:a1c8bfa9d691 299 }
tass 68:0847e35d08a6 300
tass 68:0847e35d08a6 301 #define DEV_LOOP_MIN 16
tass 68:0847e35d08a6 302
tass 68:0847e35d08a6 303 int pico_devices_loop(int loop_score, int direction)
tass 68:0847e35d08a6 304 {
tass picotcp@tass.be 137:a1c8bfa9d691 305 struct pico_device *start, *next;
tass picotcp@tass.be 137:a1c8bfa9d691 306 struct pico_tree_node *next_node = pico_dev_roundrobin_start(direction);
TASS Belgium NV 131:4758606c9316 307
tass picotcp@tass.be 137:a1c8bfa9d691 308 if (!next_node)
tass picotcp@tass.be 137:a1c8bfa9d691 309 return loop_score;
tass 68:0847e35d08a6 310
tass picotcp@tass.be 137:a1c8bfa9d691 311 next = next_node->keyValue;
TASS Belgium NV 131:4758606c9316 312 start = next;
tass 68:0847e35d08a6 313
TASS Belgium NV 131:4758606c9316 314 /* round-robin all devices, break if traversed all devices */
tass picotcp@tass.be 137:a1c8bfa9d691 315 while ((loop_score > DEV_LOOP_MIN) && (next != NULL)) {
TASS Belgium NV 131:4758606c9316 316 loop_score = devloop(next, loop_score, direction);
TASS Belgium NV 131:4758606c9316 317 next_node = pico_tree_next(next_node);
TASS Belgium NV 131:4758606c9316 318 next = next_node->keyValue;
TASS Belgium NV 131:4758606c9316 319 if (next == NULL)
TASS Belgium NV 131:4758606c9316 320 {
TASS Belgium NV 131:4758606c9316 321 next_node = pico_tree_firstNode(Device_tree.root);
TASS Belgium NV 131:4758606c9316 322 next = next_node->keyValue;
TASS Belgium NV 131:4758606c9316 323 }
tass 68:0847e35d08a6 324
TASS Belgium NV 131:4758606c9316 325 if (next == start)
TASS Belgium NV 131:4758606c9316 326 break;
tass 68:0847e35d08a6 327 }
tass picotcp@tass.be 137:a1c8bfa9d691 328 pico_dev_roundrobin_end(direction, next_node);
TASS Belgium NV 131:4758606c9316 329 return loop_score;
tass 68:0847e35d08a6 330 }
tass 68:0847e35d08a6 331
tass picotcp@tass.be 137:a1c8bfa9d691 332 struct pico_device *pico_get_device(const char*name)
tass 68:0847e35d08a6 333 {
TASS Belgium NV 131:4758606c9316 334 struct pico_device *dev;
TASS Belgium NV 131:4758606c9316 335 struct pico_tree_node *index;
TASS Belgium NV 131:4758606c9316 336 pico_tree_foreach(index, &Device_tree){
TASS Belgium NV 131:4758606c9316 337 dev = index->keyValue;
TASS Belgium NV 131:4758606c9316 338 if(strcmp(name, dev->name) == 0)
TASS Belgium NV 131:4758606c9316 339 return dev;
TASS Belgium NV 131:4758606c9316 340 }
TASS Belgium NV 131:4758606c9316 341 return NULL;
tass 68:0847e35d08a6 342 }
tass 68:0847e35d08a6 343
TASS Belgium NV 131:4758606c9316 344 int32_t pico_device_broadcast(struct pico_frame *f)
tass 68:0847e35d08a6 345 {
TASS Belgium NV 131:4758606c9316 346 struct pico_tree_node *index;
TASS Belgium NV 131:4758606c9316 347 int32_t ret = -1;
tass 68:0847e35d08a6 348
TASS Belgium NV 131:4758606c9316 349 pico_tree_foreach(index, &Device_tree)
TASS Belgium NV 131:4758606c9316 350 {
TASS Belgium NV 131:4758606c9316 351 struct pico_device *dev = index->keyValue;
TASS Belgium NV 131:4758606c9316 352 if(dev != f->dev)
TASS Belgium NV 131:4758606c9316 353 {
TASS Belgium NV 131:4758606c9316 354 struct pico_frame *copy = pico_frame_copy(f);
tass 68:0847e35d08a6 355
TASS Belgium NV 131:4758606c9316 356 if(!copy)
TASS Belgium NV 131:4758606c9316 357 return -1;
tass 68:0847e35d08a6 358
TASS Belgium NV 131:4758606c9316 359 copy->dev = dev;
TASS Belgium NV 131:4758606c9316 360 copy->dev->send(copy->dev, copy->start, (int)copy->len);
TASS Belgium NV 131:4758606c9316 361 pico_frame_discard(copy);
TASS Belgium NV 131:4758606c9316 362 }
TASS Belgium NV 131:4758606c9316 363 else
TASS Belgium NV 131:4758606c9316 364 {
tass picotcp@tass.be 137:a1c8bfa9d691 365 ret = f->dev->send(f->dev, f->start, (int)f->len);
TASS Belgium NV 131:4758606c9316 366 }
TASS Belgium NV 131:4758606c9316 367 }
TASS Belgium NV 131:4758606c9316 368
TASS Belgium NV 131:4758606c9316 369 return ret;
tass 68:0847e35d08a6 370 }