Daniele Lacamera / PicoTCP-Experimental_CDC_ECM_Branch

Fork of PicoTCP by Daniele Lacamera

Committer:
tass
Date:
Fri May 17 12:09:59 2013 +0000
Revision:
1:cfe8984a32b4
Parent:
libraries/picotcp/stack/pico_protocol.c@0:d7f2341ab245
Update for smaller SOCKETQ

Who changed what in which revision?

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