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

Dependents:   USBEthernet_TEST

Fork of USB_Ethernet by Daniele Lacamera

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

Who changed what in which revision?

UserRevisionLine numberNew contents of line
daniele 2:540f6e142d59 1 /*********************************************************************
daniele 2:540f6e142d59 2 PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved.
daniele 2:540f6e142d59 3 See LICENSE and COPYING for usage.
daniele 2:540f6e142d59 4
daniele 2:540f6e142d59 5 .
daniele 2:540f6e142d59 6
daniele 2:540f6e142d59 7 Authors: Daniele Lacamera
daniele 2:540f6e142d59 8 *********************************************************************/
daniele 2:540f6e142d59 9
daniele 2:540f6e142d59 10
daniele 2:540f6e142d59 11 #include "pico_protocol.h"
daniele 2:540f6e142d59 12 #include "pico_tree.h"
daniele 2:540f6e142d59 13
daniele 2:540f6e142d59 14 static int pico_proto_cmp(void *ka, void *kb)
daniele 2:540f6e142d59 15 {
daniele 2:540f6e142d59 16 struct pico_protocol *a = ka, *b=kb;
daniele 2:540f6e142d59 17 if (a->hash < b->hash)
daniele 2:540f6e142d59 18 return -1;
daniele 2:540f6e142d59 19 if (a->hash > b->hash)
daniele 2:540f6e142d59 20 return 1;
daniele 2:540f6e142d59 21 return 0;
daniele 2:540f6e142d59 22 }
daniele 2:540f6e142d59 23
daniele 2:540f6e142d59 24 PICO_TREE_DECLARE(Datalink_proto_tree,pico_proto_cmp);
daniele 2:540f6e142d59 25 PICO_TREE_DECLARE(Network_proto_tree,pico_proto_cmp);
daniele 2:540f6e142d59 26 PICO_TREE_DECLARE(Transport_proto_tree,pico_proto_cmp);
daniele 2:540f6e142d59 27 PICO_TREE_DECLARE(Socket_proto_tree,pico_proto_cmp);
daniele 2:540f6e142d59 28
daniele 2:540f6e142d59 29 static int proto_loop(struct pico_protocol *proto, int loop_score, int direction)
daniele 2:540f6e142d59 30 {
daniele 2:540f6e142d59 31 struct pico_frame *f;
daniele 2:540f6e142d59 32
daniele 2:540f6e142d59 33 if (direction == PICO_LOOP_DIR_IN) {
daniele 2:540f6e142d59 34
daniele 2:540f6e142d59 35 while(loop_score >0) {
daniele 2:540f6e142d59 36 if (proto->q_in->frames <= 0)
daniele 2:540f6e142d59 37 break;
daniele 2:540f6e142d59 38
daniele 2:540f6e142d59 39 f = pico_dequeue(proto->q_in);
daniele 2:540f6e142d59 40 if ((f) &&(proto->process_in(proto, f) > 0)) {
daniele 2:540f6e142d59 41 loop_score--;
daniele 2:540f6e142d59 42 }
daniele 2:540f6e142d59 43 }
daniele 2:540f6e142d59 44
daniele 2:540f6e142d59 45 } else if (direction == PICO_LOOP_DIR_OUT) {
daniele 2:540f6e142d59 46
daniele 2:540f6e142d59 47 while(loop_score >0) {
daniele 2:540f6e142d59 48 if (proto->q_out->frames <= 0)
daniele 2:540f6e142d59 49 break;
daniele 2:540f6e142d59 50
daniele 2:540f6e142d59 51 f = pico_dequeue(proto->q_out);
daniele 2:540f6e142d59 52 if ((f) &&(proto->process_out(proto, f) > 0)) {
daniele 2:540f6e142d59 53 loop_score--;
daniele 2:540f6e142d59 54 }
daniele 2:540f6e142d59 55 }
daniele 2:540f6e142d59 56 }
daniele 2:540f6e142d59 57
daniele 2:540f6e142d59 58 return loop_score;
daniele 2:540f6e142d59 59 }
daniele 2:540f6e142d59 60
daniele 2:540f6e142d59 61 #define DL_LOOP_MIN 1
daniele 2:540f6e142d59 62
daniele 2:540f6e142d59 63 int pico_protocol_datalink_loop(int loop_score, int direction)
daniele 2:540f6e142d59 64 {
daniele 2:540f6e142d59 65 struct pico_protocol *start;
daniele 2:540f6e142d59 66 static struct pico_protocol *next = NULL, *next_in = NULL, *next_out = NULL;
daniele 2:540f6e142d59 67 static struct pico_tree_node * next_node, * in_node, * out_node;
daniele 2:540f6e142d59 68
daniele 2:540f6e142d59 69 if (next_in == NULL) {
daniele 2:540f6e142d59 70 in_node = pico_tree_firstNode(Datalink_proto_tree.root);
daniele 2:540f6e142d59 71 if (in_node)
daniele 2:540f6e142d59 72 next_in = in_node->keyValue;
daniele 2:540f6e142d59 73 }
daniele 2:540f6e142d59 74 if (next_out == NULL) {
daniele 2:540f6e142d59 75 out_node = pico_tree_firstNode(Datalink_proto_tree.root);
daniele 2:540f6e142d59 76 if (out_node)
daniele 2:540f6e142d59 77 next_out = out_node->keyValue;
daniele 2:540f6e142d59 78 }
daniele 2:540f6e142d59 79
daniele 2:540f6e142d59 80 if (direction == PICO_LOOP_DIR_IN)
daniele 2:540f6e142d59 81 {
daniele 2:540f6e142d59 82 next_node = in_node;
daniele 2:540f6e142d59 83 next = next_in;
daniele 2:540f6e142d59 84 }
daniele 2:540f6e142d59 85 else if (direction == PICO_LOOP_DIR_OUT)
daniele 2:540f6e142d59 86 {
daniele 2:540f6e142d59 87 next_node = out_node;
daniele 2:540f6e142d59 88 next = next_out;
daniele 2:540f6e142d59 89 }
daniele 2:540f6e142d59 90
daniele 2:540f6e142d59 91 /* init start node */
daniele 2:540f6e142d59 92 start = next;
daniele 2:540f6e142d59 93
daniele 2:540f6e142d59 94 /* round-robin all datalink protocols, break if traversed all protocols */
daniele 2:540f6e142d59 95 while (loop_score > DL_LOOP_MIN && next != NULL) {
daniele 2:540f6e142d59 96 loop_score = proto_loop(next, loop_score, direction);
daniele 2:540f6e142d59 97
daniele 2:540f6e142d59 98 //next = RB_NEXT(pico_protocol_tree, &Datalink_proto_tree, next);
daniele 2:540f6e142d59 99 next_node = pico_tree_next(next_node);
daniele 2:540f6e142d59 100 next = next_node->keyValue;
daniele 2:540f6e142d59 101
daniele 2:540f6e142d59 102 if (next == NULL)
daniele 2:540f6e142d59 103 {
daniele 2:540f6e142d59 104 next_node = pico_tree_firstNode(Datalink_proto_tree.root);
daniele 2:540f6e142d59 105 next = next_node->keyValue;
daniele 2:540f6e142d59 106 }
daniele 2:540f6e142d59 107 if (next == start)
daniele 2:540f6e142d59 108 break;
daniele 2:540f6e142d59 109 }
daniele 2:540f6e142d59 110
daniele 2:540f6e142d59 111 if (direction == PICO_LOOP_DIR_IN)
daniele 2:540f6e142d59 112 {
daniele 2:540f6e142d59 113 in_node = next_node;
daniele 2:540f6e142d59 114 next_in = next;
daniele 2:540f6e142d59 115 }
daniele 2:540f6e142d59 116 else if (direction == PICO_LOOP_DIR_OUT)
daniele 2:540f6e142d59 117 {
daniele 2:540f6e142d59 118 out_node = next_node;
daniele 2:540f6e142d59 119 next_out = next;
daniele 2:540f6e142d59 120 }
daniele 2:540f6e142d59 121
daniele 2:540f6e142d59 122 return loop_score;
daniele 2:540f6e142d59 123 }
daniele 2:540f6e142d59 124
daniele 2:540f6e142d59 125
daniele 2:540f6e142d59 126 #define NW_LOOP_MIN 1
daniele 2:540f6e142d59 127
daniele 2:540f6e142d59 128 int pico_protocol_network_loop(int loop_score, int direction)
daniele 2:540f6e142d59 129 {
daniele 2:540f6e142d59 130 struct pico_protocol *start;
daniele 2:540f6e142d59 131 static struct pico_protocol *next = NULL, *next_in = NULL, *next_out = NULL;
daniele 2:540f6e142d59 132 static struct pico_tree_node * next_node, * in_node, * out_node;
daniele 2:540f6e142d59 133
daniele 2:540f6e142d59 134 if (next_in == NULL) {
daniele 2:540f6e142d59 135 in_node = pico_tree_firstNode(Network_proto_tree.root);
daniele 2:540f6e142d59 136 if (in_node)
daniele 2:540f6e142d59 137 next_in = in_node->keyValue;
daniele 2:540f6e142d59 138 }
daniele 2:540f6e142d59 139 if (next_out == NULL) {
daniele 2:540f6e142d59 140 out_node = pico_tree_firstNode(Network_proto_tree.root);
daniele 2:540f6e142d59 141 if (out_node)
daniele 2:540f6e142d59 142 next_out = out_node->keyValue;
daniele 2:540f6e142d59 143 }
daniele 2:540f6e142d59 144 if (direction == PICO_LOOP_DIR_IN)
daniele 2:540f6e142d59 145 {
daniele 2:540f6e142d59 146 next_node = in_node;
daniele 2:540f6e142d59 147 next = next_in;
daniele 2:540f6e142d59 148 }
daniele 2:540f6e142d59 149 else if (direction == PICO_LOOP_DIR_OUT)
daniele 2:540f6e142d59 150 {
daniele 2:540f6e142d59 151 next_node = out_node;
daniele 2:540f6e142d59 152 next = next_out;
daniele 2:540f6e142d59 153 }
daniele 2:540f6e142d59 154
daniele 2:540f6e142d59 155 /* init start node */
daniele 2:540f6e142d59 156 start = next;
daniele 2:540f6e142d59 157
daniele 2:540f6e142d59 158 /* round-robin all network protocols, break if traversed all protocols */
daniele 2:540f6e142d59 159 while (loop_score > NW_LOOP_MIN && next != NULL) {
daniele 2:540f6e142d59 160 loop_score = proto_loop(next, loop_score, direction);
daniele 2:540f6e142d59 161
daniele 2:540f6e142d59 162 next_node = pico_tree_next(next_node);
daniele 2:540f6e142d59 163 next = next_node->keyValue;
daniele 2:540f6e142d59 164
daniele 2:540f6e142d59 165 if (next == NULL)
daniele 2:540f6e142d59 166 {
daniele 2:540f6e142d59 167 next_node = pico_tree_firstNode(Network_proto_tree.root);
daniele 2:540f6e142d59 168 next = next_node->keyValue;
daniele 2:540f6e142d59 169 }
daniele 2:540f6e142d59 170 if (next == start)
daniele 2:540f6e142d59 171 break;
daniele 2:540f6e142d59 172 }
daniele 2:540f6e142d59 173
daniele 2:540f6e142d59 174 if (direction == PICO_LOOP_DIR_IN)
daniele 2:540f6e142d59 175 {
daniele 2:540f6e142d59 176 in_node = next_node;
daniele 2:540f6e142d59 177 next_in = next;
daniele 2:540f6e142d59 178 }
daniele 2:540f6e142d59 179 else if (direction == PICO_LOOP_DIR_OUT)
daniele 2:540f6e142d59 180 {
daniele 2:540f6e142d59 181 out_node = next_node;
daniele 2:540f6e142d59 182 next_out = next;
daniele 2:540f6e142d59 183 }
daniele 2:540f6e142d59 184
daniele 2:540f6e142d59 185 return loop_score;
daniele 2:540f6e142d59 186 }
daniele 2:540f6e142d59 187
daniele 2:540f6e142d59 188 #define TP_LOOP_MIN 1
daniele 2:540f6e142d59 189
daniele 2:540f6e142d59 190 int pico_protocol_transport_loop(int loop_score, int direction)
daniele 2:540f6e142d59 191 {
daniele 2:540f6e142d59 192 struct pico_protocol *start;
daniele 2:540f6e142d59 193 static struct pico_protocol *next = NULL, *next_in = NULL, *next_out = NULL;
daniele 2:540f6e142d59 194 static struct pico_tree_node * next_node, * in_node, * out_node;
daniele 2:540f6e142d59 195
daniele 2:540f6e142d59 196 if (next_in == NULL) {
daniele 2:540f6e142d59 197 in_node = pico_tree_firstNode(Transport_proto_tree.root);
daniele 2:540f6e142d59 198 if (in_node)
daniele 2:540f6e142d59 199 next_in = in_node->keyValue;
daniele 2:540f6e142d59 200 }
daniele 2:540f6e142d59 201 if (next_out == NULL) {
daniele 2:540f6e142d59 202 out_node = pico_tree_firstNode(Transport_proto_tree.root);
daniele 2:540f6e142d59 203 if (out_node)
daniele 2:540f6e142d59 204 next_out = out_node->keyValue;
daniele 2:540f6e142d59 205 }
daniele 2:540f6e142d59 206
daniele 2:540f6e142d59 207 if (direction == PICO_LOOP_DIR_IN)
daniele 2:540f6e142d59 208 {
daniele 2:540f6e142d59 209 next_node = in_node;
daniele 2:540f6e142d59 210 next = next_in;
daniele 2:540f6e142d59 211 }
daniele 2:540f6e142d59 212 else if (direction == PICO_LOOP_DIR_OUT)
daniele 2:540f6e142d59 213 {
daniele 2:540f6e142d59 214 next_node = out_node;
daniele 2:540f6e142d59 215 next = next_out;
daniele 2:540f6e142d59 216 }
daniele 2:540f6e142d59 217
daniele 2:540f6e142d59 218 /* init start node */
daniele 2:540f6e142d59 219 start = next;
daniele 2:540f6e142d59 220
daniele 2:540f6e142d59 221 /* round-robin all transport protocols, break if traversed all protocols */
daniele 2:540f6e142d59 222 while (loop_score > DL_LOOP_MIN && next != NULL) {
daniele 2:540f6e142d59 223 loop_score = proto_loop(next, loop_score, direction);
daniele 2:540f6e142d59 224
daniele 2:540f6e142d59 225 //next = RB_NEXT(pico_protocol_tree, &Transport_proto_tree, next);
daniele 2:540f6e142d59 226 next_node = pico_tree_next(next_node);
daniele 2:540f6e142d59 227 next = next_node->keyValue;
daniele 2:540f6e142d59 228
daniele 2:540f6e142d59 229 if (next == NULL)
daniele 2:540f6e142d59 230 {
daniele 2:540f6e142d59 231 next_node = pico_tree_firstNode(Transport_proto_tree.root);
daniele 2:540f6e142d59 232 next = next_node->keyValue;
daniele 2:540f6e142d59 233 }
daniele 2:540f6e142d59 234 if (next == start)
daniele 2:540f6e142d59 235 break;
daniele 2:540f6e142d59 236 }
daniele 2:540f6e142d59 237
daniele 2:540f6e142d59 238 if (direction == PICO_LOOP_DIR_IN)
daniele 2:540f6e142d59 239 {
daniele 2:540f6e142d59 240 in_node = next_node;
daniele 2:540f6e142d59 241 next_in = next;
daniele 2:540f6e142d59 242 }
daniele 2:540f6e142d59 243 else if (direction == PICO_LOOP_DIR_OUT)
daniele 2:540f6e142d59 244 {
daniele 2:540f6e142d59 245 out_node = next_node;
daniele 2:540f6e142d59 246 next_out = next;
daniele 2:540f6e142d59 247 }
daniele 2:540f6e142d59 248
daniele 2:540f6e142d59 249 return loop_score;
daniele 2:540f6e142d59 250 }
daniele 2:540f6e142d59 251
daniele 2:540f6e142d59 252
daniele 2:540f6e142d59 253 #define SOCK_LOOP_MIN 1
daniele 2:540f6e142d59 254
daniele 2:540f6e142d59 255 int pico_protocol_socket_loop(int loop_score, int direction)
daniele 2:540f6e142d59 256 {
daniele 2:540f6e142d59 257 struct pico_protocol *start;
daniele 2:540f6e142d59 258 static struct pico_protocol *next = NULL, *next_in = NULL, *next_out = NULL;
daniele 2:540f6e142d59 259 static struct pico_tree_node * next_node, * in_node, * out_node;
daniele 2:540f6e142d59 260
daniele 2:540f6e142d59 261 if (next_in == NULL) {
daniele 2:540f6e142d59 262 in_node = pico_tree_firstNode(Socket_proto_tree.root);
daniele 2:540f6e142d59 263 if(in_node)
daniele 2:540f6e142d59 264 next_in = in_node->keyValue;
daniele 2:540f6e142d59 265 }
daniele 2:540f6e142d59 266 if (next_out == NULL) {
daniele 2:540f6e142d59 267 out_node = pico_tree_firstNode(Socket_proto_tree.root);
daniele 2:540f6e142d59 268 if(out_node)
daniele 2:540f6e142d59 269 next_out = out_node->keyValue;
daniele 2:540f6e142d59 270 }
daniele 2:540f6e142d59 271
daniele 2:540f6e142d59 272 if (direction == PICO_LOOP_DIR_IN)
daniele 2:540f6e142d59 273 {
daniele 2:540f6e142d59 274 next_node = in_node;
daniele 2:540f6e142d59 275 next = next_in;
daniele 2:540f6e142d59 276 }
daniele 2:540f6e142d59 277 else if (direction == PICO_LOOP_DIR_OUT)
daniele 2:540f6e142d59 278 {
daniele 2:540f6e142d59 279 next_node = out_node;
daniele 2:540f6e142d59 280 next = next_out;
daniele 2:540f6e142d59 281 }
daniele 2:540f6e142d59 282
daniele 2:540f6e142d59 283 /* init start node */
daniele 2:540f6e142d59 284 start = next;
daniele 2:540f6e142d59 285
daniele 2:540f6e142d59 286 /* round-robin all transport protocols, break if traversed all protocols */
daniele 2:540f6e142d59 287 while (loop_score > SOCK_LOOP_MIN && next != NULL) {
daniele 2:540f6e142d59 288 loop_score = proto_loop(next, loop_score,direction);
daniele 2:540f6e142d59 289
daniele 2:540f6e142d59 290 next_node = pico_tree_next(next_node);
daniele 2:540f6e142d59 291 next = next_node->keyValue;
daniele 2:540f6e142d59 292
daniele 2:540f6e142d59 293 if (next == NULL)
daniele 2:540f6e142d59 294 {
daniele 2:540f6e142d59 295 next_node = pico_tree_firstNode(next_node);
daniele 2:540f6e142d59 296 next = next_node->keyValue;
daniele 2:540f6e142d59 297 }
daniele 2:540f6e142d59 298 if (next == start)
daniele 2:540f6e142d59 299 break;
daniele 2:540f6e142d59 300 }
daniele 2:540f6e142d59 301
daniele 2:540f6e142d59 302 if (direction == PICO_LOOP_DIR_IN)
daniele 2:540f6e142d59 303 {
daniele 2:540f6e142d59 304 in_node = next_node;
daniele 2:540f6e142d59 305 next_in = next;
daniele 2:540f6e142d59 306 }
daniele 2:540f6e142d59 307 else if (direction == PICO_LOOP_DIR_OUT)
daniele 2:540f6e142d59 308 {
daniele 2:540f6e142d59 309 out_node = next_node;
daniele 2:540f6e142d59 310 next_out = next;
daniele 2:540f6e142d59 311 }
daniele 2:540f6e142d59 312
daniele 2:540f6e142d59 313 return loop_score;
daniele 2:540f6e142d59 314 }
daniele 2:540f6e142d59 315
daniele 2:540f6e142d59 316 int pico_protocols_loop(int loop_score)
daniele 2:540f6e142d59 317 {
daniele 2:540f6e142d59 318 /*
daniele 2:540f6e142d59 319 loop_score = pico_protocol_datalink_loop(loop_score);
daniele 2:540f6e142d59 320 loop_score = pico_protocol_network_loop(loop_score);
daniele 2:540f6e142d59 321 loop_score = pico_protocol_transport_loop(loop_score);
daniele 2:540f6e142d59 322 loop_score = pico_protocol_socket_loop(loop_score);
daniele 2:540f6e142d59 323 */
daniele 2:540f6e142d59 324 return loop_score;
daniele 2:540f6e142d59 325 }
daniele 2:540f6e142d59 326
daniele 2:540f6e142d59 327 void pico_protocol_init(struct pico_protocol *p)
daniele 2:540f6e142d59 328 {
daniele 2:540f6e142d59 329 if (!p)
daniele 2:540f6e142d59 330 return;
daniele 2:540f6e142d59 331
daniele 2:540f6e142d59 332 p->hash = pico_hash(p->name);
daniele 2:540f6e142d59 333 switch (p->layer) {
daniele 2:540f6e142d59 334 case PICO_LAYER_DATALINK:
daniele 2:540f6e142d59 335 pico_tree_insert(&Datalink_proto_tree, p);
daniele 2:540f6e142d59 336 break;
daniele 2:540f6e142d59 337 case PICO_LAYER_NETWORK:
daniele 2:540f6e142d59 338 pico_tree_insert(&Network_proto_tree,p);
daniele 2:540f6e142d59 339 break;
daniele 2:540f6e142d59 340 case PICO_LAYER_TRANSPORT:
daniele 2:540f6e142d59 341 pico_tree_insert(&Transport_proto_tree,p);
daniele 2:540f6e142d59 342 break;
daniele 2:540f6e142d59 343 case PICO_LAYER_SOCKET:
daniele 2:540f6e142d59 344 pico_tree_insert(&Socket_proto_tree,p);
daniele 2:540f6e142d59 345 break;
daniele 2:540f6e142d59 346 }
daniele 2:540f6e142d59 347 dbg("Protocol %s registered (layer: %d).\n", p->name, p->layer);
daniele 2:540f6e142d59 348
daniele 2:540f6e142d59 349 }
daniele 2:540f6e142d59 350