CDC/ECM driver for mbed, based on USBDevice by mbed-official. Uses PicoTCP to access Ethernet USB device. License: GPLv2
Fork of USB_Ethernet by
pico_stack.c
00001 /********************************************************************* 00002 PicoTCP. Copyright (c) 2012 TASS Belgium NV. Some rights reserved. 00003 See LICENSE and COPYING for usage. 00004 00005 . 00006 00007 Authors: Daniele Lacamera 00008 *********************************************************************/ 00009 00010 00011 #include "pico_config.h" 00012 #include "pico_frame.h" 00013 #include "pico_device.h" 00014 #include "pico_protocol.h" 00015 #include "pico_stack.h" 00016 #include "pico_addressing.h" 00017 #include "pico_dns_client.h" 00018 00019 #include "pico_eth.h" 00020 #include "pico_arp.h" 00021 #include "pico_ipv4.h" 00022 #include "pico_ipv6.h" 00023 #include "pico_icmp4.h" 00024 #include "pico_igmp.h" 00025 #include "pico_udp.h" 00026 #include "pico_tcp.h" 00027 #include "pico_socket.h" 00028 #include "heap.h" 00029 00030 #define IS_LIMITED_BCAST(f) ( ((struct pico_ipv4_hdr *) f->net_hdr)->dst.addr == PICO_IP4_BCAST ) 00031 00032 #ifdef PICO_SUPPORT_MCAST 00033 # define PICO_SIZE_MCAST 3 00034 const uint8_t PICO_ETHADDR_MCAST[6] = {0x01, 0x00, 0x5e, 0x00, 0x00, 0x00}; 00035 #endif 00036 00037 volatile unsigned long pico_tick; 00038 volatile pico_err_t pico_err; 00039 00040 static uint32_t _rand_seed; 00041 00042 void pico_rand_feed(uint32_t feed) 00043 { 00044 if (!feed) 00045 return; 00046 _rand_seed *= 1664525; 00047 _rand_seed += 1013904223; 00048 _rand_seed ^= ~(feed); 00049 } 00050 00051 uint32_t pico_rand(void) 00052 { 00053 pico_rand_feed(pico_tick); 00054 return _rand_seed; 00055 } 00056 00057 /* NOTIFICATIONS: distributed notifications for stack internal errors. 00058 */ 00059 00060 int pico_notify_socket_unreachable(struct pico_frame *f) 00061 { 00062 if (0) {} 00063 #ifdef PICO_SUPPORT_ICMP4 00064 else if (IS_IPV4(f)) { 00065 pico_icmp4_port_unreachable(f); 00066 } 00067 #endif 00068 #ifdef PICO_SUPPORT_ICMP6 00069 else if (IS_IPV6(f)) { 00070 pico_icmp6_port_unreachable(f); 00071 } 00072 #endif 00073 00074 return 0; 00075 } 00076 00077 int pico_notify_proto_unreachable(struct pico_frame *f) 00078 { 00079 if (0) {} 00080 #ifdef PICO_SUPPORT_ICMP4 00081 else if (IS_IPV4(f)) { 00082 pico_icmp4_proto_unreachable(f); 00083 } 00084 #endif 00085 #ifdef PICO_SUPPORT_ICMP6 00086 else if (IS_IPV6(f)) { 00087 pico_icmp6_proto_unreachable(f); 00088 } 00089 #endif 00090 return 0; 00091 } 00092 00093 int pico_notify_dest_unreachable(struct pico_frame *f) 00094 { 00095 if (0) {} 00096 #ifdef PICO_SUPPORT_ICMP4 00097 else if (IS_IPV4(f)) { 00098 pico_icmp4_dest_unreachable(f); 00099 } 00100 #endif 00101 #ifdef PICO_SUPPORT_ICMP6 00102 else if (IS_IPV6(f)) { 00103 pico_icmp6_dest_unreachable(f); 00104 } 00105 #endif 00106 return 0; 00107 } 00108 00109 int pico_notify_ttl_expired(struct pico_frame *f) 00110 { 00111 if (0) {} 00112 #ifdef PICO_SUPPORT_ICMP4 00113 else if (IS_IPV4(f)) { 00114 pico_icmp4_ttl_expired(f); 00115 } 00116 #endif 00117 #ifdef PICO_SUPPORT_ICMP6 00118 else if (IS_IPV6(f)) { 00119 pico_icmp6_ttl_expired(f); 00120 } 00121 #endif 00122 return 0; 00123 } 00124 00125 00126 /* Transport layer */ 00127 int pico_transport_receive(struct pico_frame *f, uint8_t proto) 00128 { 00129 int ret = -1; 00130 switch (proto) { 00131 00132 #ifdef PICO_SUPPORT_ICMP4 00133 case PICO_PROTO_ICMP4: 00134 ret = pico_enqueue(pico_proto_icmp4.q_in, f); 00135 break; 00136 #endif 00137 00138 #ifdef PICO_SUPPORT_IGMP 00139 case PICO_PROTO_IGMP: 00140 ret = pico_enqueue(pico_proto_igmp.q_in, f); 00141 break; 00142 #endif 00143 00144 #ifdef PICO_SUPPORT_UDP 00145 case PICO_PROTO_UDP: 00146 ret = pico_enqueue(pico_proto_udp.q_in, f); 00147 break; 00148 #endif 00149 00150 #ifdef PICO_SUPPORT_TCP 00151 case PICO_PROTO_TCP: 00152 ret = pico_enqueue(pico_proto_tcp.q_in, f); 00153 break; 00154 #endif 00155 00156 default: 00157 /* Protocol not available */ 00158 dbg("pkt: no such protocol (%d)\n", proto); 00159 pico_notify_proto_unreachable(f); 00160 pico_frame_discard(f); 00161 ret = -1; 00162 } 00163 return ret; 00164 } 00165 00166 int pico_transport_send(struct pico_frame *f) 00167 { 00168 if (!f || !f->sock || !f->sock->proto) { 00169 pico_frame_discard(f); 00170 return -1; 00171 } 00172 return f->sock->proto->push(f->sock->net, f); 00173 } 00174 00175 int pico_network_receive(struct pico_frame *f) 00176 { 00177 if (0) {} 00178 #ifdef PICO_SUPPORT_IPV4 00179 else if (IS_IPV4(f)) { 00180 pico_enqueue(pico_proto_ipv4.q_in, f); 00181 } 00182 #endif 00183 #ifdef PICO_SUPPORT_IPV6 00184 else if (IS_IPV6(f)) { 00185 pico_enqueue(pico_proto_ipv6.q_in, f); 00186 } 00187 #endif 00188 else { 00189 dbg("Network not found.\n"); 00190 pico_frame_discard(f); 00191 return -1; 00192 } 00193 return f->buffer_len; 00194 } 00195 00196 00197 /* Network layer: interface towards socket for frame sending */ 00198 int pico_network_send(struct pico_frame *f) 00199 { 00200 if (!f || !f->sock || !f->sock->net) { 00201 pico_frame_discard(f); 00202 return -1; 00203 } 00204 return f->sock->net->push(f->sock->net, f); 00205 } 00206 00207 int pico_destination_is_local(struct pico_frame *f) 00208 { 00209 if (0) { } 00210 #ifdef PICO_SUPPORT_IPV4 00211 else if (IS_IPV4(f)) { 00212 struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *)f->net_hdr; 00213 if (pico_ipv4_link_find(&hdr->dst)) 00214 return 1; 00215 } 00216 #endif 00217 #ifdef PICO_SUPPORT_IPV6 00218 else if (IS_IPV6(f)) { 00219 } 00220 #endif 00221 return 0; 00222 } 00223 00224 int pico_source_is_local(struct pico_frame *f) 00225 { 00226 if (0) { } 00227 #ifdef PICO_SUPPORT_IPV4 00228 else if (IS_IPV4(f)) { 00229 struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *)f->net_hdr; 00230 if (hdr->src.addr == PICO_IPV4_INADDR_ANY) 00231 return 1; 00232 if (pico_ipv4_link_find(&hdr->src)) 00233 return 1; 00234 } 00235 #endif 00236 #ifdef PICO_SUPPORT_IPV6 00237 else if (IS_IPV6(f)) { 00238 /* XXX */ 00239 } 00240 #endif 00241 return 0; 00242 00243 00244 } 00245 00246 00247 /* DATALINK LEVEL: interface from network to the device 00248 * and vice versa. 00249 */ 00250 00251 /* The pico_ethernet_receive() function is used by 00252 * those devices supporting ETH in order to push packets up 00253 * into the stack. 00254 */ 00255 int pico_ethernet_receive(struct pico_frame *f) 00256 { 00257 struct pico_eth_hdr *hdr; 00258 if (!f || !f->dev || !f->datalink_hdr) 00259 goto discard; 00260 hdr = (struct pico_eth_hdr *) f->datalink_hdr; 00261 if ( (memcmp(hdr->daddr, f->dev->eth->mac.addr, PICO_SIZE_ETH) != 0) && 00262 #ifdef PICO_SUPPORT_MCAST 00263 (memcmp(hdr->daddr, PICO_ETHADDR_MCAST, PICO_SIZE_MCAST) != 0) && 00264 #endif 00265 (memcmp(hdr->daddr, PICO_ETHADDR_ALL, PICO_SIZE_ETH) != 0) ) 00266 goto discard; 00267 00268 f->net_hdr = f->datalink_hdr + sizeof(struct pico_eth_hdr); 00269 if (hdr->proto == PICO_IDETH_ARP) 00270 return pico_arp_receive(f); 00271 if ((hdr->proto == PICO_IDETH_IPV4) || (hdr->proto == PICO_IDETH_IPV6)) 00272 return pico_network_receive(f); 00273 discard: 00274 pico_frame_discard(f); 00275 return -1; 00276 } 00277 00278 static int destination_is_bcast(struct pico_frame *f) 00279 { 00280 if (!f) 00281 return 0; 00282 00283 if (IS_IPV6(f)) 00284 return 0; 00285 #ifdef PICO_SUPPORT_IPV4 00286 else { 00287 struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr; 00288 return pico_ipv4_is_broadcast(hdr->dst.addr); 00289 } 00290 #endif 00291 return 0; 00292 } 00293 00294 #ifdef PICO_SUPPORT_MCAST 00295 static int destination_is_mcast(struct pico_frame *f) 00296 { 00297 if (!f) 00298 return 0; 00299 00300 if (IS_IPV6(f)) 00301 return 0; 00302 #ifdef PICO_SUPPORT_IPV4 00303 else { 00304 struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr; 00305 return pico_ipv4_is_multicast(hdr->dst.addr); 00306 } 00307 #endif 00308 return 0; 00309 } 00310 00311 static struct pico_eth *pico_ethernet_mcast_translate(struct pico_frame *f, uint8_t *pico_mcast_mac) 00312 { 00313 struct pico_ipv4_hdr *hdr = (struct pico_ipv4_hdr *) f->net_hdr; 00314 00315 /* place 23 lower bits of IP in lower 23 bits of MAC */ 00316 pico_mcast_mac[5] = (long_be(hdr->dst.addr) & 0x000000FF); 00317 pico_mcast_mac[4] = (long_be(hdr->dst.addr) & 0x0000FF00) >> 8; 00318 pico_mcast_mac[3] = (long_be(hdr->dst.addr) & 0x007F0000) >> 16; 00319 00320 return (struct pico_eth *)pico_mcast_mac; 00321 } 00322 00323 00324 #endif /* PICO_SUPPORT_MCAST */ 00325 00326 /* This is called by dev loop in order to ensure correct ethernet addressing. 00327 * Returns 0 if the destination is unknown, and -1 if the packet is not deliverable 00328 * due to ethernet addressing (i.e., no arp association was possible. 00329 * 00330 * Only IP packets must pass by this. ARP will always use direct dev->send() function, so 00331 * we assume IP is used. 00332 */ 00333 int pico_ethernet_send(struct pico_frame *f) 00334 { 00335 struct pico_eth *dstmac = NULL; 00336 int ret = -1; 00337 00338 if (IS_IPV6(f)) { 00339 /*TODO: Neighbor solicitation */ 00340 dstmac = NULL; 00341 } 00342 00343 else if (IS_IPV4(f)) { 00344 if (IS_BCAST(f) || destination_is_bcast(f)) { 00345 dstmac = (struct pico_eth *) PICO_ETHADDR_ALL; 00346 } 00347 #ifdef PICO_SUPPORT_MCAST 00348 else if (destination_is_mcast(f)) { 00349 uint8_t pico_mcast_mac[6] = {0x01, 0x00, 0x5e, 0x00, 0x00, 0x00}; 00350 dstmac = pico_ethernet_mcast_translate(f, pico_mcast_mac); 00351 } 00352 #endif 00353 else { 00354 dstmac = pico_arp_get(f); 00355 if (!dstmac) 00356 return 0; 00357 } 00358 /* This sets destination and source address, then pushes the packet to the device. */ 00359 if (dstmac && (f->start > f->buffer) && ((f->start - f->buffer) >= PICO_SIZE_ETHHDR)) { 00360 struct pico_eth_hdr *hdr; 00361 f->start -= PICO_SIZE_ETHHDR; 00362 f->len += PICO_SIZE_ETHHDR; 00363 f->datalink_hdr = f->start; 00364 hdr = (struct pico_eth_hdr *) f->datalink_hdr; 00365 memcpy(hdr->saddr, f->dev->eth->mac.addr, PICO_SIZE_ETH); 00366 memcpy(hdr->daddr, dstmac, PICO_SIZE_ETH); 00367 hdr->proto = PICO_IDETH_IPV4; 00368 if(!memcmp(hdr->daddr, hdr->saddr, PICO_SIZE_ETH)){ 00369 dbg("sending out packet destined for our own mac\n"); 00370 return pico_ethernet_receive(f); 00371 }else if(IS_LIMITED_BCAST(f)){ 00372 ret = pico_device_broadcast(f); 00373 }else { 00374 ret = f->dev->send(f->dev, f->start, f->len); 00375 /* Frame is discarded after this return by the caller */ 00376 } 00377 00378 if(!ret) pico_frame_discard(f); 00379 return ret; 00380 } else { 00381 return -1; 00382 } 00383 } /* End IPV4 ethernet addressing */ 00384 return -1; 00385 00386 } 00387 00388 void pico_store_network_origin(void *src, struct pico_frame *f) 00389 { 00390 #ifdef PICO_SUPPORT_IPV4 00391 struct pico_ip4 *ip4; 00392 #endif 00393 00394 #ifdef PICO_SUPPORT_IPV6 00395 struct pico_ip6 *ip6; 00396 #endif 00397 00398 #ifdef PICO_SUPPORT_IPV4 00399 if (IS_IPV4(f)) { 00400 struct pico_ipv4_hdr *hdr; 00401 hdr = (struct pico_ipv4_hdr *) f->net_hdr; 00402 ip4 = (struct pico_ip4 *) src; 00403 ip4->addr = hdr->src.addr; 00404 } 00405 #endif 00406 #ifdef PICO_SUPPORT_IPV6 00407 if (IS_IPV6(f)) { 00408 struct pico_ipv6_hdr *hdr; 00409 hdr = (struct pico_ipv6_hdr *) f->net_hdr; 00410 ip6 = (struct pico_ip6 *) src; 00411 memcpy(ip6->addr, hdr->src.addr, PICO_SIZE_IP6); 00412 } 00413 #endif 00414 } 00415 00416 00417 /* LOWEST LEVEL: interface towards devices. */ 00418 /* Device driver will call this function which returns immediately. 00419 * Incoming packet will be processed later on in the dev loop. 00420 */ 00421 int pico_stack_recv(struct pico_device *dev, uint8_t *buffer, int len) 00422 { 00423 struct pico_frame *f; 00424 int ret; 00425 if (len <= 0) 00426 return -1; 00427 f = pico_frame_alloc(len); 00428 if (!f) 00429 return -1; 00430 00431 /* Association to the device that just received the frame. */ 00432 f->dev = dev; 00433 00434 /* Setup the start pointer, lenght. */ 00435 f->start = f->buffer; 00436 f->len = f->buffer_len; 00437 if (f->len > 8) { 00438 int mid_frame = (f->buffer_len >> 2)<<1; 00439 mid_frame -= (mid_frame % 4); 00440 pico_rand_feed(*(uint32_t*)(f->buffer + mid_frame)); 00441 } 00442 memcpy(f->buffer, buffer, len); 00443 ret = pico_enqueue(dev->q_in, f); 00444 if (ret <= 0) { 00445 pico_frame_discard(f); 00446 } 00447 return ret; 00448 } 00449 00450 int pico_sendto_dev(struct pico_frame *f) 00451 { 00452 if (!f->dev) { 00453 pico_frame_discard(f); 00454 return -1; 00455 } else { 00456 if (f->len > 8) { 00457 int mid_frame = (f->buffer_len >> 2)<<1; 00458 mid_frame -= (mid_frame % 4); 00459 pico_rand_feed(*(uint32_t*)(f->buffer + mid_frame)); 00460 } 00461 return pico_enqueue(f->dev->q_out, f); 00462 } 00463 } 00464 00465 struct pico_timer 00466 { 00467 unsigned long expire; 00468 void *arg; 00469 void (*timer)(unsigned long timestamp, void *arg); 00470 }; 00471 00472 typedef struct pico_timer pico_timer; 00473 00474 DECLARE_HEAP(pico_timer, expire); 00475 00476 static heap_pico_timer *Timers; 00477 00478 void pico_check_timers(void) 00479 { 00480 struct pico_timer timer; 00481 struct pico_timer *t = heap_first(Timers); 00482 pico_tick = PICO_TIME_MS(); 00483 while((t) && (t->expire < pico_tick)) { 00484 t->timer(pico_tick, t->arg); 00485 heap_peek(Timers, &timer); 00486 t = heap_first(Timers); 00487 } 00488 } 00489 00490 00491 #define PROTO_DEF_NR 11 00492 #define PROTO_DEF_AVG_NR 4 00493 #define PROTO_DEF_SCORE 32 00494 #define PROTO_MIN_SCORE 32 00495 #define PROTO_MAX_SCORE 128 00496 #define PROTO_LAT_IND 3 /* latecy indication 0-3 (lower is better latency performance), x1, x2, x4, x8 */ 00497 #define PROTO_MAX_LOOP (PROTO_MAX_SCORE<<PROTO_LAT_IND) /* max global loop score, so per tick */ 00498 00499 static int calc_score(int *score, int *index, int avg[][PROTO_DEF_AVG_NR], int *ret) 00500 { 00501 int temp, i, j, sum; 00502 int max_total = PROTO_MAX_LOOP, total = 0; 00503 00504 //dbg("USED SCORES> "); 00505 00506 for (i = 0; i < PROTO_DEF_NR; i++) { 00507 00508 /* if used looped score */ 00509 if (ret[i] < score[i]) { 00510 temp = score[i] - ret[i]; /* remaining loop score */ 00511 00512 //dbg("%3d - ",temp); 00513 00514 if (index[i] >= PROTO_DEF_AVG_NR) 00515 index[i] = 0; /* reset index */ 00516 j = index[i]; 00517 avg[i][j] = temp; 00518 00519 index[i]++; 00520 00521 if (ret[i] == 0 && (score[i]<<1 <= PROTO_MAX_SCORE) && ((total+(score[i]<<1)) < max_total) ) { /* used all loop score -> increase next score directly */ 00522 score[i] <<= 1; 00523 total += score[i]; 00524 continue; 00525 } 00526 00527 sum = 0; 00528 for (j = 0; j < PROTO_DEF_AVG_NR; j++) 00529 sum += avg[i][j]; /* calculate sum */ 00530 00531 sum >>= 2; /* divide by 4 to get average used score */ 00532 00533 /* criterion to increase next loop score */ 00534 if (sum > (score[i] - (score[i]>>2)) && (score[i]<<1 <= PROTO_MAX_SCORE) && ((total+(score[i]<<1)) < max_total)) { /* > 3/4 */ 00535 score[i] <<= 1; /* double loop score */ 00536 total += score[i]; 00537 continue; 00538 } 00539 00540 /* criterion to decrease next loop score */ 00541 if (sum < (score[i]>>2) && (score[i]>>1 >= PROTO_MIN_SCORE)) { /* < 1/4 */ 00542 score[i] >>= 1; /* half loop score */ 00543 total += score[i]; 00544 continue; 00545 } 00546 00547 /* also add non-changed scores */ 00548 total += score[i]; 00549 } 00550 else if (ret[i] == score[i]) { 00551 /* no used loop score - gradually decrease */ 00552 00553 // dbg("%3d - ",0); 00554 00555 if (index[i] >= PROTO_DEF_AVG_NR) 00556 index[i] = 0; /* reset index */ 00557 j = index[i]; 00558 avg[i][j] = 0; 00559 00560 index[i]++; 00561 00562 sum = 0; 00563 for (j = 0; j < PROTO_DEF_AVG_NR; j++) 00564 sum += avg[i][j]; /* calculate sum */ 00565 00566 sum >>= 2; /* divide by 4 to get average used score */ 00567 00568 if ((sum == 0) && (score[i]>>1 >= PROTO_MIN_SCORE)) { 00569 score[i] >>= 1; /* half loop score */ 00570 total += score[i]; 00571 for (j = 0; j < PROTO_DEF_AVG_NR; j++) 00572 avg[i][j] = score[i]; 00573 } 00574 00575 } 00576 } 00577 00578 //dbg("\n"); 00579 00580 return 0; 00581 } 00582 00583 00584 00585 /* 00586 00587 . 00588 .vS. 00589 <aoSo. 00590 .XoS22. 00591 .S2S22. ._... ...... ..._. 00592 :=|2S2X2|=++; <vSX2XX2z+ |vSSSXSSs>. :iXXZUZXXe= 00593 )2SS2SS2S2S2I =oS2S2S2S2X22;. _vuXS22S2S2S22i ._wZZXZZZXZZXZX= 00594 )22S2S2S2S2Sl |S2S2S22S2SSSXc: .S2SS2S2S22S2SS= .]#XZZZXZXZZZZZZ: 00595 )oSS2SS2S2Sol |2}!"""!32S22S(. uS2S2Se**12oS2e ]dXZZXX2?YYXXXZ* 00596 .:2S2So:..-. . :]S2S2e;=X2SS2o .)oc ]XZZXZ( =nX: 00597 .S2S22. ___s_i,.)oS2So(;2SS2So, ` 3XZZZZc, - 00598 .S2SSo. =oXXXSSS2XoS2S2o( XS2S2XSos;. ]ZZZZXXXX|= 00599 .S2S22. .)S2S2S22S2S2S2S2o( "X2SS2S2S2Sus,, +3XZZZZZXZZoos_ 00600 .S2S22. .]2S2SS22S222S2SS2o( ]S22S2S2S222So :3XXZZZZZZZZXXv 00601 .S2S22. =u2SS2e"~---"{2S2So( -"12S2S2SSS2Su. "?SXXXZXZZZZXo 00602 .S2SSo. )SS22z; :S2S2o( ={vS2S2S22v .<vXZZZZZZZ; 00603 .S2S2S: ]oSS2c; =22S2o( -"S2SS2n ~4XXZXZ( 00604 .2S2S2i )2S2S2[. .)XS2So( <;. .2S2S2o :<. ]XZZZX( 00605 nX2S2S,,_s_=3oSS2SoaasuXXS2S2o( .oXoasi_aioSSS22l.]dZoaas_aadXZZXZ' 00606 vS2SSSXXX2; )S2S2S2SoS2S2S2S2o( iS2S222XSoSS22So.)nXZZXXXZZXXZZXZo 00607 +32S22S2Sn -+S2S2S2S2So22S2So( 12S2SS2S2SS22S}- )SXXZZZZZZZZZXX!- 00608 .)S22222i .i2S2S2o>;:S2S2o( .<vSoSoSo2S(; :nXXXXXZXXX( 00609 .-~~~~- --- . - - --~~~-- --^^~~- 00610 . 00611 00612 00613 ... curious about our source code? We are hiring! mailto:<recruiting@tass.be> 00614 00615 00616 */ 00617 00618 void pico_stack_tick(void) 00619 { 00620 static int score[PROTO_DEF_NR] = {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}; 00621 static int index[PROTO_DEF_NR] = {0,0,0,0,0,0}; 00622 static int avg[PROTO_DEF_NR][PROTO_DEF_AVG_NR]; 00623 static int ret[PROTO_DEF_NR] = {0}; 00624 00625 pico_check_timers(); 00626 00627 //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]); 00628 00629 //score = pico_protocols_loop(100); 00630 00631 ret[0] = pico_devices_loop(score[0],PICO_LOOP_DIR_IN); 00632 pico_rand_feed(ret[0]); 00633 00634 ret[1] = pico_protocol_datalink_loop(score[1], PICO_LOOP_DIR_IN); 00635 pico_rand_feed(ret[1]); 00636 00637 ret[2] = pico_protocol_network_loop(score[2], PICO_LOOP_DIR_IN); 00638 pico_rand_feed(ret[2]); 00639 00640 ret[3] = pico_protocol_transport_loop(score[3], PICO_LOOP_DIR_IN); 00641 pico_rand_feed(ret[3]); 00642 00643 00644 ret[5] = score[5]; 00645 #if defined (PICO_SUPPORT_IPV4) || defined (PICO_SUPPORT_IPV6) 00646 #if defined (PICO_SUPPORT_TCP) || defined (PICO_SUPPORT_UDP) 00647 ret[5] = pico_sockets_loop(score[5]); // swapped 00648 pico_rand_feed(ret[5]); 00649 #endif 00650 #endif 00651 00652 ret[4] = pico_protocol_socket_loop(score[4], PICO_LOOP_DIR_IN); 00653 pico_rand_feed(ret[4]); 00654 00655 00656 ret[6] = pico_protocol_socket_loop(score[6], PICO_LOOP_DIR_OUT); 00657 pico_rand_feed(ret[6]); 00658 00659 ret[7] = pico_protocol_transport_loop(score[7], PICO_LOOP_DIR_OUT); 00660 pico_rand_feed(ret[7]); 00661 00662 ret[8] = pico_protocol_network_loop(score[8], PICO_LOOP_DIR_OUT); 00663 pico_rand_feed(ret[8]); 00664 00665 ret[9] = pico_protocol_datalink_loop(score[9], PICO_LOOP_DIR_OUT); 00666 pico_rand_feed(ret[9]); 00667 00668 ret[10] = pico_devices_loop(score[10],PICO_LOOP_DIR_OUT); 00669 pico_rand_feed(ret[10]); 00670 00671 /* calculate new loop scores for next iteration */ 00672 calc_score(score, index,(int (*)[]) avg, ret); 00673 } 00674 00675 void pico_stack_loop(void) 00676 { 00677 while(1) { 00678 pico_stack_tick(); 00679 PICO_IDLE(); 00680 } 00681 } 00682 00683 void pico_timer_add(unsigned long expire, void (*timer)(unsigned long, void *), void *arg) 00684 { 00685 pico_timer t; 00686 t.expire = PICO_TIME_MS() + expire; 00687 t.arg = arg; 00688 t.timer = timer; 00689 heap_insert(Timers, &t); 00690 if (Timers->n > PICO_MAX_TIMERS) { 00691 dbg("Warning: I have %d timers\n", Timers->n); 00692 } 00693 } 00694 00695 void pico_stack_init(void) 00696 { 00697 00698 #ifdef PICO_SUPPORT_IPV4 00699 pico_protocol_init(&pico_proto_ipv4); 00700 #endif 00701 00702 #ifdef PICO_SUPPORT_IPV6 00703 pico_protocol_init(&pico_proto_ipv6); 00704 #endif 00705 00706 #ifdef PICO_SUPPORT_ICMP4 00707 pico_protocol_init(&pico_proto_icmp4); 00708 #endif 00709 00710 #ifdef PICO_SUPPORT_IGMP 00711 pico_protocol_init(&pico_proto_igmp); 00712 #endif 00713 00714 #ifdef PICO_SUPPORT_UDP 00715 pico_protocol_init(&pico_proto_udp); 00716 #endif 00717 00718 #ifdef PICO_SUPPORT_TCP 00719 pico_protocol_init(&pico_proto_tcp); 00720 #endif 00721 00722 #ifdef PICO_SUPPORT_DNS_CLIENT 00723 pico_dns_client_init(); 00724 #endif 00725 00726 pico_rand_feed(123456); 00727 00728 /* Initialize timer heap */ 00729 Timers = heap_init(); 00730 pico_stack_tick(); 00731 pico_stack_tick(); 00732 pico_stack_tick(); 00733 } 00734
Generated on Wed Jul 13 2022 02:20:45 by 1.7.2