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
pico_protocol.c
00001 /********************************************************************* 00002 PicoTCP. Copyright (c) 2012-2015 Altran Intelligent Systems. Some rights reserved. 00003 See LICENSE and COPYING for usage. 00004 00005 . 00006 00007 Authors: Daniele Lacamera 00008 *********************************************************************/ 00009 00010 00011 #include "pico_protocol.h" 00012 #include "pico_tree.h" 00013 00014 struct pico_proto_rr 00015 { 00016 struct pico_tree *t; 00017 struct pico_tree_node *node_in, *node_out; 00018 }; 00019 00020 00021 static int pico_proto_cmp(void *ka, void *kb) 00022 { 00023 struct pico_protocol *a = ka, *b = kb; 00024 if (a->hash < b->hash) 00025 return -1; 00026 00027 if (a->hash > b->hash) 00028 return 1; 00029 00030 return 0; 00031 } 00032 00033 PICO_TREE_DECLARE(Datalink_proto_tree, pico_proto_cmp); 00034 PICO_TREE_DECLARE(Network_proto_tree, pico_proto_cmp); 00035 PICO_TREE_DECLARE(Transport_proto_tree, pico_proto_cmp); 00036 PICO_TREE_DECLARE(Socket_proto_tree, pico_proto_cmp); 00037 00038 /* Static variables to keep track of the round robin loop */ 00039 static struct pico_proto_rr proto_rr_datalink = { 00040 &Datalink_proto_tree, NULL, NULL 00041 }; 00042 static struct pico_proto_rr proto_rr_network = { 00043 &Network_proto_tree, NULL, NULL 00044 }; 00045 static struct pico_proto_rr proto_rr_transport = { 00046 &Transport_proto_tree, NULL, NULL 00047 }; 00048 static struct pico_proto_rr proto_rr_socket = { 00049 &Socket_proto_tree, NULL, NULL 00050 }; 00051 00052 static int proto_loop_in(struct pico_protocol *proto, int loop_score) 00053 { 00054 struct pico_frame *f; 00055 while(loop_score > 0) { 00056 if (proto->q_in->frames == 0) 00057 break; 00058 00059 f = pico_dequeue(proto->q_in); 00060 if ((f) && (proto->process_in(proto, f) > 0)) { 00061 loop_score--; 00062 } 00063 } 00064 return loop_score; 00065 } 00066 00067 static int proto_loop_out(struct pico_protocol *proto, int loop_score) 00068 { 00069 struct pico_frame *f; 00070 while(loop_score > 0) { 00071 if (proto->q_out->frames == 0) 00072 break; 00073 00074 f = pico_dequeue(proto->q_out); 00075 if ((f) && (proto->process_out(proto, f) > 0)) { 00076 loop_score--; 00077 } 00078 } 00079 return loop_score; 00080 } 00081 00082 static int proto_loop(struct pico_protocol *proto, int loop_score, int direction) 00083 { 00084 00085 if (direction == PICO_LOOP_DIR_IN) 00086 loop_score = proto_loop_in(proto, loop_score); 00087 else if (direction == PICO_LOOP_DIR_OUT) 00088 loop_score = proto_loop_out(proto, loop_score); 00089 00090 return loop_score; 00091 } 00092 00093 static struct pico_tree_node *roundrobin_init(struct pico_proto_rr *rr, int direction) 00094 { 00095 struct pico_tree_node *next_node = NULL; 00096 /* Initialization (takes place only once) */ 00097 if (rr->node_in == NULL) 00098 rr->node_in = pico_tree_firstNode(rr->t->root); 00099 00100 if (rr->node_out == NULL) 00101 rr->node_out = pico_tree_firstNode(rr->t->root); 00102 00103 if (direction == PICO_LOOP_DIR_IN) 00104 next_node = rr->node_in; 00105 else 00106 next_node = rr->node_out; 00107 00108 return next_node; 00109 } 00110 00111 static void roundrobin_end(struct pico_proto_rr *rr, int direction, struct pico_tree_node *last) 00112 { 00113 if (direction == PICO_LOOP_DIR_IN) 00114 rr->node_in = last; 00115 else 00116 rr->node_out = last; 00117 } 00118 00119 static int pico_protocol_generic_loop(struct pico_proto_rr *rr, int loop_score, int direction) 00120 { 00121 struct pico_protocol *start, *next; 00122 struct pico_tree_node *next_node = roundrobin_init(rr, direction); 00123 00124 if (!next_node) 00125 return loop_score; 00126 00127 next = next_node->keyValue; 00128 00129 /* init start node */ 00130 start = next; 00131 00132 /* round-robin all layer protocols, break if traversed all protocols */ 00133 while (loop_score > 1 && next != NULL) { 00134 loop_score = proto_loop(next, loop_score, direction); 00135 next_node = pico_tree_next(next_node); 00136 next = next_node->keyValue; 00137 if (next == NULL) 00138 { 00139 next_node = pico_tree_firstNode(rr->t->root); 00140 next = next_node->keyValue; 00141 } 00142 00143 if (next == start) 00144 break; 00145 } 00146 roundrobin_end(rr, direction, next_node); 00147 return loop_score; 00148 } 00149 00150 int pico_protocol_datalink_loop(int loop_score, int direction) 00151 { 00152 return pico_protocol_generic_loop(&proto_rr_datalink, loop_score, direction); 00153 } 00154 00155 int pico_protocol_network_loop(int loop_score, int direction) 00156 { 00157 return pico_protocol_generic_loop(&proto_rr_network, loop_score, direction); 00158 } 00159 00160 int pico_protocol_transport_loop(int loop_score, int direction) 00161 { 00162 return pico_protocol_generic_loop(&proto_rr_transport, loop_score, direction); 00163 } 00164 00165 int pico_protocol_socket_loop(int loop_score, int direction) 00166 { 00167 return pico_protocol_generic_loop(&proto_rr_socket, loop_score, direction); 00168 } 00169 00170 int pico_protocols_loop(int loop_score) 00171 { 00172 /* 00173 loop_score = pico_protocol_datalink_loop(loop_score); 00174 loop_score = pico_protocol_network_loop(loop_score); 00175 loop_score = pico_protocol_transport_loop(loop_score); 00176 loop_score = pico_protocol_socket_loop(loop_score); 00177 */ 00178 return loop_score; 00179 } 00180 00181 static void proto_layer_rr_reset(struct pico_proto_rr *rr) 00182 { 00183 rr->node_in = NULL; 00184 rr->node_out = NULL; 00185 } 00186 00187 void pico_protocol_init(struct pico_protocol *p) 00188 { 00189 if (!p) 00190 return; 00191 00192 p->hash = pico_hash(p->name, (uint32_t)strlen(p->name)); 00193 switch (p->layer) { 00194 case PICO_LAYER_DATALINK: 00195 pico_tree_insert(&Datalink_proto_tree, p); 00196 proto_layer_rr_reset(&proto_rr_datalink); 00197 break; 00198 case PICO_LAYER_NETWORK: 00199 pico_tree_insert(&Network_proto_tree, p); 00200 proto_layer_rr_reset(&proto_rr_network); 00201 break; 00202 case PICO_LAYER_TRANSPORT: 00203 pico_tree_insert(&Transport_proto_tree, p); 00204 proto_layer_rr_reset(&proto_rr_transport); 00205 break; 00206 case PICO_LAYER_SOCKET: 00207 pico_tree_insert(&Socket_proto_tree, p); 00208 proto_layer_rr_reset(&proto_rr_socket); 00209 break; 00210 } 00211 dbg("Protocol %s registered (layer: %d).\n", p->name, p->layer); 00212 00213 } 00214
Generated on Tue Jul 12 2022 15:59:22 by 1.7.2