diff options
author | David Brodski <david@brodski.eu> | 2011-02-28 19:09:42 +0000 |
---|---|---|
committer | David Brodski <david@brodski.eu> | 2011-02-28 19:09:42 +0000 |
commit | 5d275099239802e3c79f6685dd6cda3104d2624a (patch) | |
tree | 7d7dd5a47687f91db927d5155cf4af37c034782c /src/transport/plugin_transport_wlan.c | |
parent | 3bd57067a779a8803c16fb2f372089c153087661 (diff) | |
download | gnunet-5d275099239802e3c79f6685dd6cda3104d2624a.tar.gz gnunet-5d275099239802e3c79f6685dd6cda3104d2624a.zip |
Fixed many errors, send and receive with acks works now
Diffstat (limited to 'src/transport/plugin_transport_wlan.c')
-rw-r--r-- | src/transport/plugin_transport_wlan.c | 1786 |
1 files changed, 1052 insertions, 734 deletions
diff --git a/src/transport/plugin_transport_wlan.c b/src/transport/plugin_transport_wlan.c index 050286881..c0e062aa1 100644 --- a/src/transport/plugin_transport_wlan.c +++ b/src/transport/plugin_transport_wlan.c | |||
@@ -1,22 +1,22 @@ | |||
1 | /* | 1 | /* |
2 | This file is part of GNUnet | 2 | This file is part of GNUnet |
3 | (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Christian Grothoff (and other contributing authors) | 3 | (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Christian Grothoff (and other contributing authors) |
4 | 4 | ||
5 | GNUnet is free software; you can redistribute it and/or modify | 5 | GNUnet is free software; you can redistribute it and/or modify |
6 | it under the terms of the GNU General Public License as published | 6 | it under the terms of the GNU General Public License as published |
7 | by the Free Software Foundation; either version 3, or (at your | 7 | by the Free Software Foundation; either version 3, or (at your |
8 | option) any later version. | 8 | option) any later version. |
9 | 9 | ||
10 | GNUnet is distributed in the hope that it will be useful, but | 10 | GNUnet is distributed in the hope that it will be useful, but |
11 | WITHOUT ANY WARRANTY; without even the implied warranty of | 11 | WITHOUT ANY WARRANTY; without even the implied warranty of |
12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 12 | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
13 | General Public License for more details. | 13 | General Public License for more details. |
14 | 14 | ||
15 | You should have received a copy of the GNU General Public License | 15 | You should have received a copy of the GNU General Public License |
16 | along with GNUnet; see the file COPYING. If not, write to the | 16 | along with GNUnet; see the file COPYING. If not, write to the |
17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, | 17 | Free Software Foundation, Inc., 59 Temple Place - Suite 330, |
18 | Boston, MA 02111-1307, USA. | 18 | Boston, MA 02111-1307, USA. |
19 | */ | 19 | */ |
20 | 20 | ||
21 | /** | 21 | /** |
22 | * @file transport/plugin_transport_wlan.c | 22 | * @file transport/plugin_transport_wlan.c |
@@ -45,16 +45,17 @@ | |||
45 | /** | 45 | /** |
46 | * Time until retransmission of a fragment in ms | 46 | * Time until retransmission of a fragment in ms |
47 | */ | 47 | */ |
48 | #define FRAGMENT_TIMEOUT GNUNET_TIME_UNIT_SECONDS | 48 | #define FRAGMENT_TIMEOUT GNUNET_TIME_UNIT_SECONDS |
49 | 49 | ||
50 | #define FRAGMENT_QUEUE_SIZE 10 | 50 | #define FRAGMENT_QUEUE_SIZE 10 |
51 | 51 | ||
52 | #define HALLO_BEACON_SCALING_FACTOR 900 | ||
53 | |||
52 | #define DEBUG_wlan GNUNET_YES | 54 | #define DEBUG_wlan GNUNET_YES |
53 | 55 | ||
54 | #define MESSAGE_LENGHT_UNKNOWN -1 | 56 | #define MESSAGE_LENGHT_UNKNOWN -1 |
55 | #define NO_MESSAGE_OR_MESSAGE_FINISHED -2 | 57 | #define NO_MESSAGE_OR_MESSAGE_FINISHED -2 |
56 | 58 | ||
57 | |||
58 | /** | 59 | /** |
59 | * After how long do we expire an address that we | 60 | * After how long do we expire an address that we |
60 | * learned from another peer if it is not reconfirmed | 61 | * learned from another peer if it is not reconfirmed |
@@ -79,7 +80,6 @@ struct WelcomeMessage | |||
79 | 80 | ||
80 | }; | 81 | }; |
81 | 82 | ||
82 | |||
83 | /** | 83 | /** |
84 | * Encapsulation of all of the state of the plugin. | 84 | * Encapsulation of all of the state of the plugin. |
85 | */ | 85 | */ |
@@ -112,7 +112,6 @@ struct Plugin | |||
112 | 112 | ||
113 | struct GNUNET_SERVER_MessageStreamTokenizer * consoltoken; | 113 | struct GNUNET_SERVER_MessageStreamTokenizer * consoltoken; |
114 | 114 | ||
115 | |||
116 | /** | 115 | /** |
117 | * stdout pipe handle for the gnunet-wlan-helper process | 116 | * stdout pipe handle for the gnunet-wlan-helper process |
118 | */ | 117 | */ |
@@ -170,9 +169,9 @@ struct Plugin | |||
170 | struct Sessionqueue * pending_Sessions; | 169 | struct Sessionqueue * pending_Sessions; |
171 | 170 | ||
172 | /** | 171 | /** |
173 | * Sessions currently pending for transmission | 172 | * Sessions currently pending for transmission |
174 | * to this peer (tail), if any. | 173 | * to this peer (tail), if any. |
175 | */ | 174 | */ |
176 | struct Sessionqueue * pending_Sessions_tail; | 175 | struct Sessionqueue * pending_Sessions_tail; |
177 | 176 | ||
178 | /** | 177 | /** |
@@ -193,8 +192,8 @@ struct Plugin | |||
193 | struct FragmentMessage * pending_Fragment_Messages_tail; | 192 | struct FragmentMessage * pending_Fragment_Messages_tail; |
194 | 193 | ||
195 | /** | 194 | /** |
196 | * number of pending fragment message | 195 | * number of pending fragment message |
197 | */ | 196 | */ |
198 | 197 | ||
199 | unsigned int pending_fragment_messages; | 198 | unsigned int pending_fragment_messages; |
200 | 199 | ||
@@ -204,6 +203,14 @@ struct Plugin | |||
204 | 203 | ||
205 | struct GNUNET_TIME_Absolute beacon_time; | 204 | struct GNUNET_TIME_Absolute beacon_time; |
206 | 205 | ||
206 | /** | ||
207 | * queue to send acks for received fragments | ||
208 | */ | ||
209 | |||
210 | struct AckSendQueue * ack_send_queue_head; | ||
211 | |||
212 | struct AckSendQueue * ack_send_queue_tail; | ||
213 | |||
207 | }; | 214 | }; |
208 | 215 | ||
209 | struct Finish_send | 216 | struct Finish_send |
@@ -220,9 +227,9 @@ struct Finish_send | |||
220 | 227 | ||
221 | struct Sessionqueue | 228 | struct Sessionqueue |
222 | { | 229 | { |
223 | struct Sessionqueue * next; | 230 | struct Sessionqueue * next; |
224 | struct Sessionqueue * prev; | 231 | struct Sessionqueue * prev; |
225 | struct Session * content; | 232 | struct Session * content; |
226 | }; | 233 | }; |
227 | 234 | ||
228 | /** | 235 | /** |
@@ -231,24 +238,22 @@ struct Sessionqueue | |||
231 | 238 | ||
232 | struct AckQueue | 239 | struct AckQueue |
233 | { | 240 | { |
234 | struct AckQueue * next; | 241 | struct AckQueue * next; |
235 | struct AckQueue * prev; | 242 | struct AckQueue * prev; |
236 | int fragment_num; //TODO change it to offset if better | 243 | int fragment_num; //TODO change it to offset if better |
237 | }; | 244 | }; |
238 | 245 | ||
239 | |||
240 | |||
241 | /** | 246 | /** |
242 | * Queue for the fragments received | 247 | * Queue for the fragments received |
243 | */ | 248 | */ |
244 | 249 | ||
245 | struct RecQueue | 250 | struct RecQueue |
246 | { | 251 | { |
247 | struct RecQueue * next; | 252 | struct RecQueue * next; |
248 | struct RecQueue * prev; | 253 | struct RecQueue * prev; |
249 | uint16_t num; | 254 | uint16_t num; |
250 | const char * msg; | 255 | const char * msg; |
251 | uint16_t size; | 256 | uint16_t size; |
252 | }; | 257 | }; |
253 | 258 | ||
254 | /** | 259 | /** |
@@ -264,6 +269,11 @@ struct PendingMessage | |||
264 | char *msg; | 269 | char *msg; |
265 | 270 | ||
266 | /** | 271 | /** |
272 | * Size of the message | ||
273 | */ | ||
274 | size_t message_size; | ||
275 | |||
276 | /** | ||
267 | * Continuation function to call once the message | 277 | * Continuation function to call once the message |
268 | * has been sent. Can be NULL if there is no | 278 | * has been sent. Can be NULL if there is no |
269 | * continuation to call. | 279 | * continuation to call. |
@@ -280,10 +290,28 @@ struct PendingMessage | |||
280 | */ | 290 | */ |
281 | struct GNUNET_TIME_Absolute timeout; | 291 | struct GNUNET_TIME_Absolute timeout; |
282 | 292 | ||
293 | }; | ||
294 | |||
295 | /** | ||
296 | * Queue for acks to send for fragments recived | ||
297 | */ | ||
298 | //TODO comments | ||
299 | struct AckSendQueue | ||
300 | { | ||
301 | |||
302 | struct AckSendQueue * next; | ||
303 | struct AckSendQueue * prev; | ||
304 | |||
305 | struct Session * session; | ||
283 | /** | 306 | /** |
284 | * Size of the message | 307 | * ID of message, to distinguish between the messages, picked randomly. |
285 | */ | 308 | */ |
286 | size_t message_size; | 309 | uint32_t message_id GNUNET_PACKED; |
310 | |||
311 | /** | ||
312 | * Offset or number of this fragment, for fragmentation/segmentation (design choice, TBD) | ||
313 | */ | ||
314 | uint16_t fragment_off_or_num GNUNET_PACKED; | ||
287 | 315 | ||
288 | }; | 316 | }; |
289 | 317 | ||
@@ -397,65 +425,66 @@ struct Session | |||
397 | 425 | ||
398 | }; | 426 | }; |
399 | 427 | ||
400 | 428 | /** | |
401 | 429 | * Struct for Messages in the fragment queue | |
430 | */ | ||
402 | 431 | ||
403 | struct FragmentMessage | 432 | struct FragmentMessage |
404 | { | 433 | { |
405 | /** | 434 | /** |
406 | * Session this message belongs to | 435 | * Session this message belongs to |
407 | */ | 436 | */ |
408 | 437 | ||
409 | struct Session *session; | 438 | struct Session *session; |
410 | 439 | ||
411 | /** | 440 | /** |
412 | * This is a doubly-linked list. | 441 | * This is a doubly-linked list. |
413 | */ | 442 | */ |
414 | struct FragmentMessage *next; | 443 | struct FragmentMessage *next; |
415 | 444 | ||
416 | /** | 445 | /** |
417 | * This is a doubly-linked list. | 446 | * This is a doubly-linked list. |
418 | */ | 447 | */ |
419 | struct FragmentMessage *prev; | 448 | struct FragmentMessage *prev; |
420 | 449 | ||
421 | /** | 450 | /** |
422 | * The pending message | 451 | * The pending message |
423 | */ | 452 | */ |
424 | char *msg; | 453 | char *msg; |
425 | 454 | ||
426 | /** | 455 | /** |
427 | * Timeout value for the pending message. | 456 | * Timeout value for the pending message. |
428 | */ | 457 | */ |
429 | struct GNUNET_TIME_Absolute timeout; | 458 | struct GNUNET_TIME_Absolute timeout; |
430 | 459 | ||
431 | /** | 460 | /** |
432 | * Timeout value for the pending fragments. | 461 | * Timeout value for the pending fragments. |
433 | * Stores the time when the next msg fragment ack has to be received | 462 | * Stores the time when the next msg fragment ack has to be received |
434 | */ | 463 | */ |
435 | struct GNUNET_TIME_Absolute next_ack; | 464 | struct GNUNET_TIME_Absolute next_ack; |
436 | 465 | ||
437 | /** | 466 | /** |
438 | * Sorted queue with the acks received for fragments; head | 467 | * Sorted queue with the acks received for fragments; head |
439 | */ | 468 | */ |
440 | 469 | ||
441 | struct AckQueue * head; | 470 | struct AckQueue * head; |
442 | 471 | ||
443 | /** | 472 | /** |
444 | * Sorted queue with the acks received for fragments; tail | 473 | * Sorted queue with the acks received for fragments; tail |
445 | */ | 474 | */ |
446 | 475 | ||
447 | struct AckQueue * tail; | 476 | struct AckQueue * tail; |
448 | 477 | ||
449 | /** | 478 | /** |
450 | * Size of the message | 479 | * Size of the message |
451 | */ | 480 | */ |
452 | size_t message_size; | 481 | size_t message_size; |
453 | 482 | ||
454 | /** | 483 | /** |
455 | * pos / next fragment number in the message, for fragmentation/segmentation, | 484 | * pos / next fragment number in the message, for fragmentation/segmentation, |
456 | * some acks can be missing but there is still time | 485 | * some acks can be missing but there is still time |
457 | */ | 486 | */ |
458 | uint32_t message_pos; | 487 | uint32_t message_pos; |
459 | 488 | ||
460 | }; | 489 | }; |
461 | 490 | ||
@@ -478,7 +507,7 @@ struct WlanHeader | |||
478 | */ | 507 | */ |
479 | struct GNUNET_PeerIdentity target; | 508 | struct GNUNET_PeerIdentity target; |
480 | 509 | ||
481 | // followed by payload | 510 | // followed by payload |
482 | 511 | ||
483 | }; | 512 | }; |
484 | 513 | ||
@@ -511,31 +540,30 @@ struct FragmentationHeader | |||
511 | */ | 540 | */ |
512 | uint16_t message_crc GNUNET_PACKED; | 541 | uint16_t message_crc GNUNET_PACKED; |
513 | 542 | ||
514 | /** | 543 | /** |
515 | * Flags | 544 | * Flags |
516 | * // 0x1 ack => Use two different message types in header.type! (FRAG_MESSAGE; FRAG_ACK) | 545 | * // 0x1 ack => Use two different message types in header.type! (FRAG_MESSAGE; FRAG_ACK) |
517 | * // 0x2 has data (not only ack) | 546 | * // 0x2 has data (not only ack) |
518 | * // 0x4 last fragment of message | 547 | * // 0x4 last fragment of message |
519 | * // 0x8 new message | 548 | * // 0x8 new message |
520 | */ | 549 | */ |
521 | // uint32_t flags GNUNET_PACKED; | 550 | // uint32_t flags GNUNET_PACKED; |
522 | 551 | ||
523 | /** | 552 | /** |
524 | * checksum/error correction | 553 | * checksum/error correction |
525 | */ | 554 | */ |
526 | // uint32_t crc GNUNET_PACKED; | 555 | // uint32_t crc GNUNET_PACKED; |
527 | 556 | ||
528 | // followed by payload unless ACK | 557 | // followed by payload unless ACK |
529 | 558 | ||
530 | }; | 559 | }; |
531 | 560 | ||
532 | //enum { ACK_FRAGMENT = 1, DATA_FRAGMENT = 2, LAST_FRAGMENT = 4, NEW_MESSAGE = 8 }; | ||
533 | |||
534 | int | 561 | int |
535 | getRadiotapHeader(struct RadiotapHeader * Header); | 562 | getRadiotapHeader(struct RadiotapHeader * Header); |
536 | 563 | ||
537 | int | 564 | int |
538 | getWlanHeader(struct IeeeHeader * Header); | 565 | getWlanHeader(struct IeeeHeader * Header,const char * to_mac_addr, |
566 | struct Plugin * plugin); | ||
539 | 567 | ||
540 | static int | 568 | static int |
541 | wlan_plugin_address_suggested(void *cls, const void *addr, size_t addrlen); | 569 | wlan_plugin_address_suggested(void *cls, const void *addr, size_t addrlen); |
@@ -556,16 +584,21 @@ static void | |||
556 | free_rec_frag_queue(struct Session * session); | 584 | free_rec_frag_queue(struct Session * session); |
557 | 585 | ||
558 | static void | 586 | static void |
559 | wlan_data_helper(void *cls, void * client, const struct GNUNET_MessageHeader * hdr); | 587 | wlan_data_helper(void *cls, struct Session_light * session_light, |
588 | const struct GNUNET_MessageHeader * hdr); | ||
560 | 589 | ||
561 | static void | 590 | static void |
562 | wlan_process_helper (void *cls, | 591 | wlan_process_helper(void *cls, void *client, |
563 | void *client, | 592 | const struct GNUNET_MessageHeader *hdr); |
564 | const struct GNUNET_MessageHeader *hdr); | ||
565 | 593 | ||
566 | static void | 594 | static void |
567 | finish_sending(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); | 595 | finish_sending(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc); |
568 | 596 | ||
597 | static void | ||
598 | wlan_data_massage_handler(struct Plugin * plugin, | ||
599 | struct Session_light * session_light, | ||
600 | const struct GNUNET_MessageHeader * hdr); | ||
601 | |||
569 | /** | 602 | /** |
570 | * get the next message number, at the moment just a random one | 603 | * get the next message number, at the moment just a random one |
571 | * @return returns the next valid message-number for sending packets | 604 | * @return returns the next valid message-number for sending packets |
@@ -627,7 +660,7 @@ search_session(struct Plugin *plugin, const uint8_t * addr) | |||
627 | */ | 660 | */ |
628 | 661 | ||
629 | static struct Session * | 662 | static struct Session * |
630 | create_session(struct Plugin *plugin,const uint8_t * addr) | 663 | create_session(struct Plugin *plugin, const uint8_t * addr) |
631 | { | 664 | { |
632 | struct Sessionqueue * queue = GNUNET_malloc (sizeof (struct Sessionqueue)); | 665 | struct Sessionqueue * queue = GNUNET_malloc (sizeof (struct Sessionqueue)); |
633 | 666 | ||
@@ -688,49 +721,52 @@ get_Session(struct Plugin *plugin, const uint8_t * addr) | |||
688 | */ | 721 | */ |
689 | //TODO doxigen | 722 | //TODO doxigen |
690 | static void | 723 | static void |
691 | queue_Session (struct Plugin *plugin, | 724 | queue_Session(struct Plugin *plugin, struct Session * session) |
692 | struct Session * session) | ||
693 | { | 725 | { |
694 | struct Sessionqueue * queue = plugin->pending_Sessions; | 726 | struct Sessionqueue * queue = plugin->pending_Sessions; |
695 | struct Sessionqueue * lastitem = NULL; | 727 | struct Sessionqueue * lastitem = NULL; |
696 | 728 | ||
697 | while (queue != NULL){ | 729 | while (queue != NULL) |
698 | // content is never NULL | 730 | { |
699 | GNUNET_assert (queue->content != NULL); | 731 | // content is never NULL |
700 | // is session already in queue? | 732 | GNUNET_assert (queue->content != NULL); |
701 | if (session == queue->content){ | 733 | // is session already in queue? |
702 | return; | 734 | if (session == queue->content) |
703 | } | 735 | { |
704 | // try next | 736 | return; |
705 | lastitem = queue; | 737 | } |
706 | queue = queue->next; | 738 | // try next |
707 | } | 739 | lastitem = queue; |
708 | 740 | queue = queue->next; | |
709 | // Session is not in the queue | 741 | } |
710 | 742 | ||
711 | queue = GNUNET_malloc (sizeof (struct Sessionqueue)); | 743 | // Session is not in the queue |
712 | queue->content = session; | 744 | |
713 | 745 | queue = GNUNET_malloc (sizeof (struct Sessionqueue)); | |
714 | //insert at the tail | 746 | queue->content = session; |
715 | GNUNET_CONTAINER_DLL_insert_after (plugin->pending_Sessions, | 747 | |
716 | plugin->pending_Sessions_tail, | 748 | //insert at the tail |
717 | plugin->pending_Sessions_tail, queue); | 749 | GNUNET_CONTAINER_DLL_insert_after (plugin->pending_Sessions, |
718 | plugin->pendingsessions ++; | 750 | plugin->pending_Sessions_tail, |
751 | plugin->pending_Sessions_tail, queue); | ||
752 | plugin->pendingsessions++; | ||
719 | 753 | ||
720 | } | 754 | } |
721 | 755 | ||
722 | //TODO doxigen | 756 | //TODO doxigen |
723 | static void | 757 | static void |
724 | free_acks (struct FragmentMessage * fm){ | 758 | free_acks(struct FragmentMessage * fm) |
725 | struct AckQueue * fq; | 759 | { |
726 | while (fm->head != NULL){ | 760 | struct AckQueue * fq; |
727 | fq = fm->head; | 761 | while (fm->head != NULL) |
728 | GNUNET_CONTAINER_DLL_remove(fm->head, fm->tail, fq); | 762 | { |
729 | GNUNET_free(fq); | 763 | fq = fm->head; |
730 | } | 764 | GNUNET_CONTAINER_DLL_remove(fm->head, fm->tail, fq); |
731 | //needed? | 765 | GNUNET_free(fq); |
732 | fm->head = NULL; | 766 | } |
733 | fm->tail = NULL; | 767 | //needed? |
768 | fm->head = NULL; | ||
769 | fm->tail = NULL; | ||
734 | } | 770 | } |
735 | 771 | ||
736 | //TODO doxigen | 772 | //TODO doxigen |
@@ -766,24 +802,25 @@ set_next_beacon_time(struct Plugin * const plugin) | |||
766 | if (plugin->session_count < 10) | 802 | if (plugin->session_count < 10) |
767 | { | 803 | { |
768 | plugin->beacon_time = GNUNET_TIME_absolute_add( | 804 | plugin->beacon_time = GNUNET_TIME_absolute_add( |
769 | GNUNET_TIME_absolute_get(), GNUNET_TIME_UNIT_SECONDS); | 805 | GNUNET_TIME_absolute_get(), GNUNET_TIME_relative_multiply( |
806 | GNUNET_TIME_UNIT_SECONDS, HALLO_BEACON_SCALING_FACTOR)); | ||
770 | } | 807 | } |
771 | //under 30 known peers: every 10 seconds | 808 | //under 30 known peers: every 10 seconds |
772 | else if (plugin->session_count < 30) | 809 | else if (plugin->session_count < 30) |
773 | { | 810 | { |
774 | plugin->beacon_time = GNUNET_TIME_absolute_add( | 811 | plugin->beacon_time = GNUNET_TIME_absolute_add( |
775 | GNUNET_TIME_absolute_get(), GNUNET_TIME_relative_multiply( | 812 | GNUNET_TIME_absolute_get(), GNUNET_TIME_relative_multiply( |
776 | GNUNET_TIME_UNIT_SECONDS, 10)); | 813 | GNUNET_TIME_UNIT_SECONDS, 10 * HALLO_BEACON_SCALING_FACTOR)); |
777 | } | 814 | } |
778 | //over 30 known peers: once a minute | 815 | //over 30 known peers: once a minute |
779 | else | 816 | else |
780 | { | 817 | { |
781 | plugin->beacon_time = GNUNET_TIME_absolute_add( | 818 | plugin->beacon_time = GNUNET_TIME_absolute_add( |
782 | GNUNET_TIME_absolute_get(), GNUNET_TIME_UNIT_MINUTES); | 819 | GNUNET_TIME_absolute_get(), GNUNET_TIME_relative_multiply( |
820 | GNUNET_TIME_UNIT_MINUTES, HALLO_BEACON_SCALING_FACTOR)); | ||
783 | } | 821 | } |
784 | } | 822 | } |
785 | 823 | ||
786 | |||
787 | //TODO doxigen | 824 | //TODO doxigen |
788 | struct GNUNET_TIME_Relative | 825 | struct GNUNET_TIME_Relative |
789 | get_next_frag_timeout(struct FragmentMessage * fm) | 826 | get_next_frag_timeout(struct FragmentMessage * fm) |
@@ -798,11 +835,11 @@ get_next_frag_timeout(struct FragmentMessage * fm) | |||
798 | */ | 835 | */ |
799 | 836 | ||
800 | struct GNUNET_TIME_Relative | 837 | struct GNUNET_TIME_Relative |
801 | get_ack_timeout (struct FragmentMessage * fm){ | 838 | get_ack_timeout(struct FragmentMessage * fm) |
802 | return FRAGMENT_TIMEOUT; | 839 | { |
840 | return FRAGMENT_TIMEOUT; | ||
803 | } | 841 | } |
804 | 842 | ||
805 | |||
806 | /** | 843 | /** |
807 | * Function to set the timer for the next timeout of the fragment queue | 844 | * Function to set the timer for the next timeout of the fragment queue |
808 | * @param plugin the handle to the plugin struct | 845 | * @param plugin the handle to the plugin struct |
@@ -825,8 +862,13 @@ check_next_fragment_timeout(struct Plugin * const plugin) | |||
825 | 862 | ||
826 | GNUNET_assert(plugin->server_write_delay_task == GNUNET_SCHEDULER_NO_TASK); | 863 | GNUNET_assert(plugin->server_write_delay_task == GNUNET_SCHEDULER_NO_TASK); |
827 | 864 | ||
865 | //check if some acks are in the queue | ||
866 | if (plugin->ack_send_queue_head != NULL) | ||
867 | { | ||
868 | next_send = GNUNET_TIME_relative_get_zero(); | ||
869 | } | ||
828 | //check if there are some fragments in the queue | 870 | //check if there are some fragments in the queue |
829 | if (fm != NULL) | 871 | else if (fm != NULL) |
830 | { | 872 | { |
831 | next_send | 873 | next_send |
832 | = GNUNET_TIME_relative_min(next_send, get_next_frag_timeout(fm)); | 874 | = GNUNET_TIME_relative_min(next_send, get_next_frag_timeout(fm)); |
@@ -835,62 +877,66 @@ check_next_fragment_timeout(struct Plugin * const plugin) | |||
835 | &delay_fragment_task, plugin); | 877 | &delay_fragment_task, plugin); |
836 | } | 878 | } |
837 | 879 | ||
838 | |||
839 | |||
840 | //TODO doxigen | 880 | //TODO doxigen |
841 | /** | 881 | /** |
842 | * Function to get the next queued Session, removes the session from the queue | 882 | * Function to get the next queued Session, removes the session from the queue |
843 | */ | 883 | */ |
844 | 884 | ||
845 | static struct Session * | 885 | static struct Session * |
846 | get_next_queue_Session (struct Plugin * plugin){ | 886 | get_next_queue_Session(struct Plugin * plugin) |
847 | struct Session * session; | 887 | { |
848 | struct Sessionqueue * sessionqueue; | 888 | struct Session * session; |
849 | struct Sessionqueue * sessionqueue_alt; | 889 | struct Sessionqueue * sessionqueue; |
850 | struct PendingMessage * pm; | 890 | struct Sessionqueue * sessionqueue_alt; |
851 | sessionqueue = plugin->pending_Sessions; | 891 | struct PendingMessage * pm; |
852 | while (sessionqueue != NULL){ | 892 | sessionqueue = plugin->pending_Sessions; |
853 | session = sessionqueue->content; | 893 | while (sessionqueue != NULL) |
854 | pm = session->pending_message; | 894 | { |
855 | 895 | session = sessionqueue->content; | |
856 | //check for message timeout | 896 | pm = session->pending_message; |
857 | if (GNUNET_TIME_absolute_get_remaining(pm->timeout).rel_value > 0){ | 897 | |
858 | //check if session has no message in the fragment queue | 898 | //check for message timeout |
859 | if (! session->has_fragment){ | 899 | if (GNUNET_TIME_absolute_get_remaining(pm->timeout).rel_value > 0) |
860 | plugin->pendingsessions --; | 900 | { |
861 | GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions, | 901 | //check if session has no message in the fragment queue |
862 | plugin->pending_Sessions_tail, sessionqueue); | 902 | if (!session->has_fragment) |
863 | GNUNET_free(sessionqueue); | 903 | { |
864 | 904 | plugin->pendingsessions--; | |
865 | return session; | 905 | GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions, |
866 | } else { | 906 | plugin->pending_Sessions_tail, sessionqueue); |
867 | sessionqueue = sessionqueue->next; | 907 | GNUNET_free(sessionqueue); |
868 | } | 908 | |
869 | } else { | 909 | return session; |
870 | 910 | } | |
871 | session->pending_message = NULL; | 911 | else |
872 | //call the cont func that it did not work | 912 | { |
873 | if (pm->transmit_cont != NULL) | 913 | sessionqueue = sessionqueue->next; |
874 | pm->transmit_cont (pm->transmit_cont_cls, | 914 | } |
875 | &(session->target), GNUNET_SYSERR); | 915 | } |
876 | GNUNET_free(pm->msg); | 916 | else |
877 | GNUNET_free(pm); | 917 | { |
878 | 918 | ||
879 | sessionqueue_alt = sessionqueue; | 919 | session->pending_message = NULL; |
880 | sessionqueue = sessionqueue->next; | 920 | //call the cont func that it did not work |
881 | plugin->pendingsessions --; | 921 | if (pm->transmit_cont != NULL) |
882 | GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions, | 922 | pm->transmit_cont(pm->transmit_cont_cls, &(session->target), |
883 | plugin->pending_Sessions_tail, sessionqueue_alt); | 923 | GNUNET_SYSERR); |
884 | 924 | GNUNET_free(pm->msg); | |
885 | GNUNET_free(sessionqueue_alt); | 925 | GNUNET_free(pm); |
886 | 926 | ||
887 | } | 927 | sessionqueue_alt = sessionqueue; |
888 | 928 | sessionqueue = sessionqueue->next; | |
889 | 929 | plugin->pendingsessions--; | |
890 | } | 930 | GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions, |
891 | return NULL; | 931 | plugin->pending_Sessions_tail, sessionqueue_alt); |
892 | } | ||
893 | 932 | ||
933 | GNUNET_free(sessionqueue_alt); | ||
934 | |||
935 | } | ||
936 | |||
937 | } | ||
938 | return NULL; | ||
939 | } | ||
894 | 940 | ||
895 | /** | 941 | /** |
896 | * Function to sort the message into the message fragment queue | 942 | * Function to sort the message into the message fragment queue |
@@ -898,22 +944,28 @@ get_next_queue_Session (struct Plugin * plugin){ | |||
898 | * @param fm message to sort into the queue | 944 | * @param fm message to sort into the queue |
899 | */ | 945 | */ |
900 | static void | 946 | static void |
901 | sort_fragment_into_queue (struct Plugin * plugin, struct FragmentMessage * fm){ | 947 | sort_fragment_into_queue(struct Plugin * plugin, struct FragmentMessage * fm) |
902 | struct FragmentMessage * fm2; | 948 | { |
903 | //sort into the list at the right position | 949 | struct FragmentMessage * fm2; |
904 | 950 | //sort into the list at the right position | |
905 | fm2 = plugin->pending_Fragment_Messages_head; | 951 | |
906 | 952 | fm2 = plugin->pending_Fragment_Messages_head; | |
907 | while (fm2 != NULL){ | 953 | |
908 | if (GNUNET_TIME_absolute_get_difference(fm2->next_ack, fm->next_ack).rel_value == 0){ | 954 | while (fm2 != NULL) |
909 | break; | 955 | { |
910 | } else { | 956 | if (GNUNET_TIME_absolute_get_difference(fm2->next_ack, fm->next_ack).rel_value |
911 | fm2 = fm2->next; | 957 | == 0) |
912 | } | 958 | { |
913 | } | 959 | break; |
914 | 960 | } | |
915 | GNUNET_CONTAINER_DLL_insert_after(plugin->pending_Fragment_Messages_head, | 961 | else |
916 | plugin->pending_Fragment_Messages_tail,fm2,fm); | 962 | { |
963 | fm2 = fm2->next; | ||
964 | } | ||
965 | } | ||
966 | |||
967 | GNUNET_CONTAINER_DLL_insert_after(plugin->pending_Fragment_Messages_head, | ||
968 | plugin->pending_Fragment_Messages_tail,fm2,fm); | ||
917 | } | 969 | } |
918 | 970 | ||
919 | /** | 971 | /** |
@@ -922,7 +974,7 @@ sort_fragment_into_queue (struct Plugin * plugin, struct FragmentMessage * fm){ | |||
922 | * @param fm message to free | 974 | * @param fm message to free |
923 | */ | 975 | */ |
924 | static void | 976 | static void |
925 | free_fragment_message(struct Plugin * plugin,struct FragmentMessage * fm) | 977 | free_fragment_message(struct Plugin * plugin, struct FragmentMessage * fm) |
926 | { | 978 | { |
927 | if (fm != NULL) | 979 | if (fm != NULL) |
928 | { | 980 | { |
@@ -931,8 +983,12 @@ free_fragment_message(struct Plugin * plugin,struct FragmentMessage * fm) | |||
931 | GNUNET_CONTAINER_DLL_remove (plugin->pending_Fragment_Messages_head, | 983 | GNUNET_CONTAINER_DLL_remove (plugin->pending_Fragment_Messages_head, |
932 | plugin->pending_Fragment_Messages_tail, fm); | 984 | plugin->pending_Fragment_Messages_tail, fm); |
933 | GNUNET_free(fm); | 985 | GNUNET_free(fm); |
934 | plugin->pending_fragment_messages --; | 986 | plugin->pending_fragment_messages--; |
935 | check_fragment_queue(plugin); | 987 | check_fragment_queue(plugin); |
988 | |||
989 | #if DEBUG_wlan | ||
990 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Pending fragment messages: %u\n", plugin->pending_fragment_messages); | ||
991 | #endif | ||
936 | } | 992 | } |
937 | } | 993 | } |
938 | 994 | ||
@@ -943,43 +999,58 @@ free_fragment_message(struct Plugin * plugin,struct FragmentMessage * fm) | |||
943 | */ | 999 | */ |
944 | 1000 | ||
945 | static void | 1001 | static void |
946 | check_fragment_queue (struct Plugin * plugin){ | 1002 | check_fragment_queue(struct Plugin * plugin) |
947 | struct Session * session; | 1003 | { |
948 | struct FragmentMessage * fm; | 1004 | struct Session * session; |
949 | 1005 | struct FragmentMessage * fm; | |
950 | struct PendingMessage * pm; | 1006 | struct GNUNET_PeerIdentity pid; |
951 | 1007 | ||
952 | if (plugin->pending_fragment_messages < FRAGMENT_QUEUE_SIZE){ | 1008 | struct PendingMessage * pm; |
953 | session = get_next_queue_Session(plugin); | 1009 | |
954 | if (session != NULL){ | 1010 | if (plugin->pending_fragment_messages < FRAGMENT_QUEUE_SIZE) |
955 | pm = session->pending_message; | 1011 | { |
956 | session->pending_message = NULL; | 1012 | session = get_next_queue_Session(plugin); |
957 | session->has_fragment = 1; | 1013 | if (session != NULL) |
958 | GNUNET_assert(pm != NULL); | 1014 | { |
959 | 1015 | pm = session->pending_message; | |
960 | fm = GNUNET_malloc(sizeof(struct FragmentMessage)); | 1016 | session->pending_message = NULL; |
961 | fm->message_size = pm->message_size; | 1017 | session->has_fragment = 1; |
962 | fm->msg = pm->msg; | 1018 | GNUNET_assert(pm != NULL); |
963 | fm->session = session; | 1019 | |
964 | fm->timeout.abs_value = pm->timeout.abs_value; | 1020 | fm = GNUNET_malloc(sizeof(struct FragmentMessage)); |
965 | fm->message_pos = 0; | 1021 | fm->message_size = pm->message_size; |
966 | fm->next_ack = GNUNET_TIME_absolute_get(); | 1022 | fm->msg = pm->msg; |
967 | 1023 | fm->session = session; | |
968 | if (pm->transmit_cont != NULL) | 1024 | fm->timeout.abs_value = pm->timeout.abs_value; |
969 | pm->transmit_cont (pm->transmit_cont_cls, | 1025 | fm->message_pos = 0; |
970 | &(session->target), GNUNET_OK); | 1026 | fm->next_ack = GNUNET_TIME_absolute_get(); |
971 | GNUNET_free(pm); | 1027 | |
972 | 1028 | if (pm->transmit_cont != NULL) { | |
973 | sort_fragment_into_queue(plugin,fm); | 1029 | pid = session->target; |
974 | plugin->pending_fragment_messages ++; | 1030 | pm->transmit_cont(pm->transmit_cont_cls, &pid, |
975 | 1031 | GNUNET_OK); | |
976 | //generate new message id | 1032 | #if DEBUG_wlan |
977 | session->message_id_out = get_next_message_id(); | 1033 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "called pm->transmit_cont\n"); |
978 | 1034 | #endif | |
979 | //check if timeout changed | 1035 | } |
980 | check_next_fragment_timeout(plugin); | 1036 | else |
981 | } | 1037 | { |
982 | } | 1038 | #if DEBUG_wlan |
1039 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "no pm->transmit_cont\n"); | ||
1040 | #endif | ||
1041 | } | ||
1042 | GNUNET_free(pm); | ||
1043 | |||
1044 | sort_fragment_into_queue(plugin, fm); | ||
1045 | plugin->pending_fragment_messages++; | ||
1046 | |||
1047 | //generate new message id | ||
1048 | session->message_id_out = get_next_message_id(); | ||
1049 | |||
1050 | //check if timeout changed | ||
1051 | check_next_fragment_timeout(plugin); | ||
1052 | } | ||
1053 | } | ||
983 | } | 1054 | } |
984 | 1055 | ||
985 | /** | 1056 | /** |
@@ -989,7 +1060,8 @@ check_fragment_queue (struct Plugin * plugin){ | |||
989 | * @param fm the message to check | 1060 | * @param fm the message to check |
990 | */ | 1061 | */ |
991 | static void | 1062 | static void |
992 | check_finished_fragment(struct Plugin * plugin, struct FragmentMessage * fm){ | 1063 | check_finished_fragment(struct Plugin * plugin, struct FragmentMessage * fm) |
1064 | { | ||
993 | struct AckQueue * ack; | 1065 | struct AckQueue * ack; |
994 | int counter = 0; | 1066 | int counter = 0; |
995 | 1067 | ||
@@ -1003,9 +1075,11 @@ check_finished_fragment(struct Plugin * plugin, struct FragmentMessage * fm){ | |||
1003 | { | 1075 | { |
1004 | if (counter == ack->fragment_num) | 1076 | if (counter == ack->fragment_num) |
1005 | { | 1077 | { |
1006 | counter ++; | 1078 | counter++; |
1007 | ack = ack->next; | 1079 | ack = ack->next; |
1008 | } else { | 1080 | } |
1081 | else | ||
1082 | { | ||
1009 | //ack is missing | 1083 | //ack is missing |
1010 | return; | 1084 | return; |
1011 | } | 1085 | } |
@@ -1013,11 +1087,165 @@ check_finished_fragment(struct Plugin * plugin, struct FragmentMessage * fm){ | |||
1013 | fm->session->has_fragment = 0; | 1087 | fm->session->has_fragment = 0; |
1014 | free_fragment_message(plugin, fm); | 1088 | free_fragment_message(plugin, fm); |
1015 | 1089 | ||
1090 | #if DEBUG_wlan | ||
1091 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Finished a fragmented message\n"); | ||
1092 | #endif | ||
1093 | |||
1094 | |||
1095 | check_next_fragment_timeout(plugin); | ||
1016 | 1096 | ||
1017 | } | 1097 | } |
1018 | } | 1098 | } |
1019 | 1099 | ||
1020 | /** | 1100 | /** |
1101 | * Function to set the next fragment number | ||
1102 | * @param fm use this FragmentMessage | ||
1103 | */ | ||
1104 | |||
1105 | void | ||
1106 | set_next_message_fragment_pos(struct FragmentMessage * fm) | ||
1107 | { | ||
1108 | struct AckQueue * akt = NULL; | ||
1109 | //check if retransmit is needed | ||
1110 | if (GNUNET_TIME_absolute_get_remaining(fm->next_ack).rel_value == 0) | ||
1111 | { | ||
1112 | |||
1113 | // be positive and try again later :-D | ||
1114 | fm->next_ack = GNUNET_TIME_relative_to_absolute(get_ack_timeout(fm)); | ||
1115 | // find first missing fragment | ||
1116 | |||
1117 | fm->message_pos = 0; | ||
1118 | } | ||
1119 | |||
1120 | akt = fm->head; | ||
1121 | //test if ack 0 (or X) was already received | ||
1122 | while (akt != NULL) | ||
1123 | { | ||
1124 | //if fragment is present, take next | ||
1125 | if (akt->fragment_num == fm->message_pos) | ||
1126 | { | ||
1127 | fm->message_pos++; | ||
1128 | } | ||
1129 | //next ack is bigger then the fragment number | ||
1130 | //in case there is something like this: (acks) 1, 2, 5, 6, ... | ||
1131 | //and we send 3 again, the next number should be 4 | ||
1132 | else if (akt->fragment_num > fm->message_pos) | ||
1133 | { | ||
1134 | break; | ||
1135 | } | ||
1136 | |||
1137 | akt = akt->next; | ||
1138 | |||
1139 | } | ||
1140 | |||
1141 | } | ||
1142 | |||
1143 | void | ||
1144 | send_hello_beacon(struct Plugin * plugin) | ||
1145 | { | ||
1146 | |||
1147 | #if DEBUG_wlan | ||
1148 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Sending hello beacon\n"); | ||
1149 | #endif | ||
1150 | |||
1151 | uint16_t size = 0; | ||
1152 | ssize_t bytes; | ||
1153 | struct GNUNET_MessageHeader * msgheader = NULL; | ||
1154 | struct IeeeHeader * ieeewlanheader = NULL; | ||
1155 | struct RadiotapHeader * radioHeader = NULL; | ||
1156 | struct GNUNET_MessageHeader * msgheader2 = NULL; | ||
1157 | |||
1158 | GNUNET_assert(sizeof(struct WlanHeader) + GNUNET_HELLO_size( | ||
1159 | *(plugin->env->our_hello)) <= WLAN_MTU); | ||
1160 | size = sizeof(struct GNUNET_MessageHeader) + sizeof(struct RadiotapHeader) | ||
1161 | + sizeof(struct IeeeHeader) + sizeof(struct GNUNET_MessageHeader) | ||
1162 | + GNUNET_HELLO_size(*(plugin->env->our_hello)); | ||
1163 | |||
1164 | msgheader = GNUNET_malloc(size); | ||
1165 | msgheader->size = htons(size); | ||
1166 | msgheader->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); | ||
1167 | |||
1168 | radioHeader = (struct RadiotapHeader*) &msgheader[1]; | ||
1169 | getRadiotapHeader(radioHeader); | ||
1170 | ieeewlanheader = (struct IeeeHeader*) &radioHeader[1]; | ||
1171 | getWlanHeader(ieeewlanheader, bc_all_mac, plugin); | ||
1172 | |||
1173 | msgheader2 = (struct GNUNET_MessageHeader*) &ieeewlanheader[1]; | ||
1174 | msgheader2->size = htons(GNUNET_HELLO_size(*(plugin->env->our_hello)) | ||
1175 | + sizeof(struct GNUNET_MessageHeader)); | ||
1176 | |||
1177 | msgheader2->type = htons(GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT); | ||
1178 | memcpy(&msgheader2[1], *plugin->env->our_hello, GNUNET_HELLO_size( | ||
1179 | *(plugin->env->our_hello))); | ||
1180 | |||
1181 | bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, msgheader, size); | ||
1182 | |||
1183 | if (bytes == GNUNET_SYSERR) | ||
1184 | { | ||
1185 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
1186 | _("Error writing to wlan healper. errno == %d, ERROR: %s\n"), | ||
1187 | errno, strerror(errno)); | ||
1188 | |||
1189 | } | ||
1190 | GNUNET_assert(bytes != GNUNET_SYSERR); | ||
1191 | GNUNET_assert(bytes == size); | ||
1192 | GNUNET_free(msgheader); | ||
1193 | |||
1194 | set_next_beacon_time(plugin); | ||
1195 | check_next_fragment_timeout(plugin); | ||
1196 | } | ||
1197 | |||
1198 | static void | ||
1199 | send_ack(struct Plugin * plugin, struct AckSendQueue * ack) | ||
1200 | { | ||
1201 | |||
1202 | uint16_t size = 0; | ||
1203 | ssize_t bytes; | ||
1204 | struct GNUNET_MessageHeader * msgheader = NULL; | ||
1205 | struct IeeeHeader * ieeewlanheader = NULL; | ||
1206 | struct RadiotapHeader * radioHeader = NULL; | ||
1207 | struct FragmentationHeader * msgheader2 = NULL; | ||
1208 | |||
1209 | GNUNET_assert(sizeof(struct FragmentationHeader) <= WLAN_MTU); | ||
1210 | |||
1211 | #if DEBUG_wlan | ||
1212 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1213 | "Sending ack for message_id %u with fragment number %u\n", | ||
1214 | ack->message_id, ack->fragment_off_or_num); | ||
1215 | #endif | ||
1216 | |||
1217 | size = sizeof(struct GNUNET_MessageHeader) + sizeof(struct RadiotapHeader) | ||
1218 | + sizeof(struct IeeeHeader) + sizeof(struct FragmentationHeader); | ||
1219 | msgheader = GNUNET_malloc(size); | ||
1220 | msgheader->size = htons(size); | ||
1221 | msgheader->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); | ||
1222 | |||
1223 | radioHeader = (struct RadiotapHeader*) &msgheader[1]; | ||
1224 | getRadiotapHeader(radioHeader); | ||
1225 | ieeewlanheader = (struct IeeeHeader*) &radioHeader[1]; | ||
1226 | getWlanHeader(ieeewlanheader, ack->session->addr, plugin); | ||
1227 | |||
1228 | msgheader2 = (struct FragmentationHeader*) &ieeewlanheader[1]; | ||
1229 | msgheader2->header.size = htons(sizeof(struct FragmentationHeader)); | ||
1230 | msgheader2->header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT_ACK); | ||
1231 | msgheader2->message_id = htonl(ack->message_id); | ||
1232 | msgheader2->fragment_off_or_num = htons(ack->fragment_off_or_num); | ||
1233 | |||
1234 | bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, msgheader, size); | ||
1235 | if (bytes == GNUNET_SYSERR) | ||
1236 | { | ||
1237 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
1238 | _("Error writing to wlan healper. errno == %d, ERROR: %s\n"), | ||
1239 | errno, strerror(errno)); | ||
1240 | |||
1241 | } | ||
1242 | GNUNET_assert(bytes != GNUNET_SYSERR); | ||
1243 | GNUNET_assert(bytes == size); | ||
1244 | GNUNET_free(msgheader); | ||
1245 | check_next_fragment_timeout(plugin); | ||
1246 | } | ||
1247 | |||
1248 | /** | ||
1021 | * Function called when wlan helper is ready to get some data | 1249 | * Function called when wlan helper is ready to get some data |
1022 | * | 1250 | * |
1023 | * @param cls closure | 1251 | * @param cls closure |
@@ -1031,8 +1259,6 @@ do_transmit(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1031 | struct Plugin * plugin = cls; | 1259 | struct Plugin * plugin = cls; |
1032 | plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK; | 1260 | plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK; |
1033 | 1261 | ||
1034 | ssize_t bytes; | ||
1035 | |||
1036 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) | 1262 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) |
1037 | return; | 1263 | return; |
1038 | 1264 | ||
@@ -1045,251 +1271,178 @@ do_transmit(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1045 | struct FragmentationHeader fragheader; | 1271 | struct FragmentationHeader fragheader; |
1046 | struct FragmentationHeader * fragheaderptr = NULL; | 1272 | struct FragmentationHeader * fragheaderptr = NULL; |
1047 | struct Finish_send * finish = NULL; | 1273 | struct Finish_send * finish = NULL; |
1274 | struct AckSendQueue * ack; | ||
1048 | uint16_t size = 0; | 1275 | uint16_t size = 0; |
1276 | ssize_t bytes; | ||
1049 | const char * copystart = NULL; | 1277 | const char * copystart = NULL; |
1050 | uint16_t copysize = 0; | 1278 | uint16_t copysize = 0; |
1051 | uint copyoffset = 0; | 1279 | uint copyoffset = 0; |
1052 | struct AckQueue * akt = NULL; | ||
1053 | 1280 | ||
1054 | 1281 | if (plugin->ack_send_queue_head != NULL) | |
1055 | struct GNUNET_MessageHeader * msgheader2 = NULL; | 1282 | { |
1283 | ack = plugin->ack_send_queue_head; | ||
1284 | GNUNET_CONTAINER_DLL_remove(plugin->ack_send_queue_head, | ||
1285 | plugin->ack_send_queue_tail, ack); | ||
1286 | send_ack(plugin, ack); | ||
1287 | GNUNET_free(ack); | ||
1288 | return; | ||
1289 | } | ||
1056 | 1290 | ||
1057 | //test if a "hello-beacon" has to be send | 1291 | //test if a "hello-beacon" has to be send |
1058 | if (0==1) | 1292 | if (GNUNET_TIME_absolute_get_remaining(plugin->beacon_time).rel_value == 0) |
1059 | //if (GNUNET_TIME_absolute_get_remaining(plugin->beacon_time).rel_value == 0) | ||
1060 | { | 1293 | { |
1061 | //check if the message is not to big | 1294 | send_hello_beacon(plugin); |
1062 | GNUNET_assert(sizeof(struct WlanHeader) + GNUNET_HELLO_size( | ||
1063 | *(plugin->env->our_hello)) <= WLAN_MTU); | ||
1064 | size = sizeof(struct GNUNET_MessageHeader) | ||
1065 | + sizeof(struct RadiotapHeader) + sizeof(struct IeeeHeader) | ||
1066 | + sizeof(struct GNUNET_MessageHeader) + GNUNET_HELLO_size( | ||
1067 | *(plugin->env->our_hello)); | ||
1068 | |||
1069 | msgheader = GNUNET_malloc(size); | ||
1070 | msgheader->size = htons(size); | ||
1071 | msgheader->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); | ||
1072 | |||
1073 | radioHeader = (struct RadiotapHeader *) &msgheader[1]; | ||
1074 | getRadiotapHeader(radioHeader); | ||
1075 | |||
1076 | ieeewlanheader = (struct IeeeHeader *) &radioHeader[1]; | ||
1077 | getWlanHeader(ieeewlanheader); | ||
1078 | |||
1079 | msgheader2 = (struct GNUNET_MessageHeader *) &ieeewlanheader[1]; | ||
1080 | msgheader2->size = htons(GNUNET_HELLO_size(*(plugin->env->our_hello)) | ||
1081 | + sizeof(struct GNUNET_MessageHeader)); | ||
1082 | msgheader2->type = htons(GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT); | ||
1083 | |||
1084 | memcpy(&msgheader2[1], *plugin->env->our_hello, GNUNET_HELLO_size( | ||
1085 | *(plugin->env->our_hello))); | ||
1086 | |||
1087 | bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, msgheader, | ||
1088 | size); | ||
1089 | if (bytes == GNUNET_SYSERR) | ||
1090 | { | ||
1091 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
1092 | _("Error writing to wlan healper. errno == %d, ERROR: %s\n"), | ||
1093 | errno, strerror(errno)); | ||
1094 | |||
1095 | } | ||
1096 | GNUNET_assert(bytes != GNUNET_SYSERR); | ||
1097 | GNUNET_assert(bytes == size); | ||
1098 | |||
1099 | GNUNET_free(msgheader); | ||
1100 | |||
1101 | set_next_beacon_time(plugin); | ||
1102 | check_next_fragment_timeout(plugin); | ||
1103 | 1295 | ||
1104 | return; | 1296 | return; |
1105 | 1297 | ||
1106 | } | 1298 | } |
1107 | 1299 | ||
1108 | |||
1109 | |||
1110 | fm = plugin->pending_Fragment_Messages_head; | 1300 | fm = plugin->pending_Fragment_Messages_head; |
1111 | GNUNET_assert(fm != NULL); | 1301 | if (fm != NULL) |
1112 | session = fm->session; | ||
1113 | GNUNET_assert(session != NULL); | ||
1114 | |||
1115 | // test if message timed out | ||
1116 | if (GNUNET_TIME_absolute_get_remaining(fm->timeout).rel_value == 0) | ||
1117 | { | ||
1118 | free_acks(fm); | ||
1119 | GNUNET_assert(plugin->pending_fragment_messages > 0); | ||
1120 | plugin->pending_fragment_messages--; | ||
1121 | GNUNET_CONTAINER_DLL_remove(plugin->pending_Fragment_Messages_head, | ||
1122 | plugin->pending_Fragment_Messages_tail, fm); | ||
1123 | |||
1124 | GNUNET_free(fm->msg); | ||
1125 | |||
1126 | GNUNET_free(fm); | ||
1127 | check_fragment_queue(plugin); | ||
1128 | } | ||
1129 | else | ||
1130 | { | 1302 | { |
1303 | session = fm->session; | ||
1304 | GNUNET_assert(session != NULL); | ||
1131 | 1305 | ||
1132 | if (fm->message_size > WLAN_MTU) | 1306 | // test if message timed out |
1307 | if (GNUNET_TIME_absolute_get_remaining(fm->timeout).rel_value == 0) | ||
1133 | { | 1308 | { |
1134 | size += sizeof(struct FragmentationHeader); | 1309 | #if DEBUG_wlan |
1135 | // check/set for retransmission | 1310 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "message timeout\n"); |
1136 | if (GNUNET_TIME_absolute_get_duration(fm->next_ack).rel_value == 0) | 1311 | #endif |
1137 | { | 1312 | free_acks(fm); |
1138 | 1313 | GNUNET_assert(plugin->pending_fragment_messages > 0); | |
1139 | // be positive and try again later :-D | 1314 | plugin->pending_fragment_messages--; |
1140 | fm->next_ack = GNUNET_TIME_relative_to_absolute(get_ack_timeout( | 1315 | GNUNET_CONTAINER_DLL_remove(plugin->pending_Fragment_Messages_head, |
1141 | fm)); | 1316 | plugin->pending_Fragment_Messages_tail, fm); |
1142 | // find first missing fragment | ||
1143 | akt = fm->head; | ||
1144 | fm->message_pos = 0; | ||
1145 | 1317 | ||
1146 | //test if ack 0 was already received | 1318 | GNUNET_free(fm->msg); |
1147 | while (akt != NULL) | ||
1148 | { | ||
1149 | //if fragment is present, take next | ||
1150 | if (akt->fragment_num == fm->message_pos) | ||
1151 | { | ||
1152 | fm->message_pos++; | ||
1153 | } | ||
1154 | //next ack is bigger then the fragment number | ||
1155 | //in case there is something like this: (acks) 1, 2, 5, 6, ... | ||
1156 | //and we send 3 again, the next number should be 4 | ||
1157 | else if (akt->fragment_num > fm->message_pos) | ||
1158 | { | ||
1159 | break; | ||
1160 | } | ||
1161 | 1319 | ||
1162 | akt = akt->next; | 1320 | GNUNET_free(fm); |
1321 | check_fragment_queue(plugin); | ||
1322 | } | ||
1323 | else | ||
1324 | { | ||
1163 | 1325 | ||
1164 | } | 1326 | //if (fm->message_size > WLAN_MTU) |
1327 | // { | ||
1328 | size += sizeof(struct FragmentationHeader); | ||
1165 | 1329 | ||
1166 | } | 1330 | set_next_message_fragment_pos(fm); |
1167 | 1331 | ||
1168 | copyoffset = (WLAN_MTU - sizeof(struct FragmentationHeader)) | 1332 | copyoffset = (WLAN_MTU - sizeof(struct FragmentationHeader)) |
1169 | * fm->message_pos; | 1333 | * fm->message_pos; |
1170 | fragheader.fragment_off_or_num = htons(fm->message_pos); | 1334 | fragheader.fragment_off_or_num = htons(fm->message_pos); |
1171 | fragheader.message_id = htonl(session->message_id_out); | 1335 | fragheader.message_id = htonl(session->message_id_out); |
1172 | |||
1173 | // start should be smaller then the packet size | ||
1174 | GNUNET_assert(copyoffset < fm->message_size); | 1336 | GNUNET_assert(copyoffset < fm->message_size); |
1175 | copystart = fm->msg + copyoffset; | 1337 | copystart = fm->msg + copyoffset; |
1176 | |||
1177 | //size of the fragment is either the MTU - overhead | ||
1178 | //or the missing part of the message in case this is the last fragment | ||
1179 | copysize = GNUNET_MIN(fm->message_size - copyoffset, | 1338 | copysize = GNUNET_MIN(fm->message_size - copyoffset, |
1180 | WLAN_MTU - sizeof(struct FragmentationHeader)); | 1339 | WLAN_MTU - sizeof(struct FragmentationHeader)); |
1181 | fragheader.header.size = htons(copysize | 1340 | fragheader.header.size = htons(copysize |
1182 | + sizeof(struct FragmentationHeader)); | 1341 | + sizeof(struct FragmentationHeader)); |
1183 | fragheader.header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT); | 1342 | fragheader.header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT); |
1184 | 1343 | ||
1185 | //get the next missing fragment | 1344 | /* } |
1186 | akt = fm->head; | 1345 | else |
1187 | fm->message_pos++; | 1346 | { |
1347 | // there is no need to split | ||
1348 | copystart = fm->msg; | ||
1349 | copysize = fm->message_size; | ||
1350 | }*/ | ||
1188 | 1351 | ||
1189 | //test if ack was already received | 1352 | #if DEBUG_wlan |
1190 | while (akt != NULL) | 1353 | GNUNET_log( |
1191 | { | 1354 | GNUNET_ERROR_TYPE_DEBUG, |
1192 | //if fragment is present, take next | 1355 | "Sending GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT with message_id %u with fragment number %i, size: %u, time until timeout %u\n", |
1193 | if (akt->fragment_num == fm->message_pos) | 1356 | session->message_id_out, fm->message_pos, copysize |
1194 | { | 1357 | + sizeof(struct FragmentationHeader), |
1195 | fm->message_pos++; | 1358 | GNUNET_TIME_absolute_get_remaining(fm->timeout)); |
1196 | } | 1359 | #endif |
1197 | //next ack is bigger then the fragment number | ||
1198 | //in case there is something like this: (acks) 1, 2, 5, 6, ... | ||
1199 | //and we send 3 again, the next number should be 4 | ||
1200 | else if (akt->fragment_num > fm->message_pos) | ||
1201 | { | ||
1202 | break; | ||
1203 | } | ||
1204 | |||
1205 | akt = akt->next; | ||
1206 | } | ||
1207 | } | ||
1208 | else | ||
1209 | { | ||
1210 | // there is no need to split | ||
1211 | copystart = fm->msg; | ||
1212 | copysize = fm->message_size; | ||
1213 | } | ||
1214 | 1360 | ||
1215 | size += copysize; | 1361 | size += copysize; |
1216 | size += sizeof(struct RadiotapHeader) + sizeof(struct IeeeHeader) | 1362 | size += sizeof(struct RadiotapHeader) + sizeof(struct IeeeHeader) |
1217 | + sizeof(struct GNUNET_MessageHeader); | 1363 | + sizeof(struct GNUNET_MessageHeader); |
1218 | msgheader = GNUNET_malloc(size); | 1364 | msgheader = GNUNET_malloc(size); |
1219 | msgheader->size = htons(size); | 1365 | msgheader->size = htons(size); |
1220 | msgheader->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); | 1366 | msgheader->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA); |
1221 | 1367 | ||
1222 | radioHeader = (struct RadiotapHeader*) &msgheader[1]; | 1368 | radioHeader = (struct RadiotapHeader*) &msgheader[1]; |
1223 | getRadiotapHeader(radioHeader); | 1369 | getRadiotapHeader(radioHeader); |
1224 | 1370 | ||
1225 | ieeewlanheader = (struct IeeeHeader *) &radioHeader[1]; | 1371 | ieeewlanheader = (struct IeeeHeader *) &radioHeader[1]; |
1226 | getWlanHeader(ieeewlanheader); | 1372 | getWlanHeader(ieeewlanheader, fm->session->addr, plugin); |
1227 | 1373 | ||
1228 | //could be faster if content is just send and not copyed before | 1374 | //could be faster if content is just send and not copyed before |
1229 | //fragmentheader is needed | 1375 | //fragmentheader is needed |
1230 | if (fm->message_size > WLAN_MTU) | 1376 | //if (fm->message_size > WLAN_MTU) |
1231 | { | 1377 | // { |
1232 | fragheader.message_crc = htons(getcrc16(copystart, copysize)); | 1378 | fragheader.message_crc = htons(getcrc16(copystart, copysize)); |
1233 | memcpy(&ieeewlanheader[1], &fragheader, | 1379 | memcpy(&ieeewlanheader[1], &fragheader, |
1234 | sizeof(struct FragmentationHeader)); | 1380 | sizeof(struct FragmentationHeader)); |
1235 | fragheaderptr = (struct FragmentationHeader *) &ieeewlanheader[1]; | 1381 | fragheaderptr = (struct FragmentationHeader *) &ieeewlanheader[1]; |
1236 | memcpy(&fragheaderptr[1], copystart, copysize); | 1382 | memcpy(&fragheaderptr[1], copystart, copysize); |
1237 | } | 1383 | /* } |
1238 | else | 1384 | else |
1239 | { | 1385 | { |
1240 | memcpy(&ieeewlanheader[1], copystart, copysize); | 1386 | memcpy(&ieeewlanheader[1], copystart, copysize); |
1241 | } | 1387 | }*/ |
1388 | |||
1389 | bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, | ||
1390 | msgheader, size); | ||
1391 | if (bytes == GNUNET_SYSERR) | ||
1392 | { | ||
1393 | GNUNET_log( | ||
1394 | GNUNET_ERROR_TYPE_ERROR, | ||
1395 | _("Error writing to wlan healper. errno == %d, ERROR: %s\n"), | ||
1396 | errno, strerror(errno)); | ||
1242 | 1397 | ||
1243 | bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, msgheader, size); | 1398 | } |
1244 | if (bytes == GNUNET_SYSERR){ | 1399 | GNUNET_assert(bytes != GNUNET_SYSERR); |
1245 | GNUNET_log(GNUNET_ERROR_TYPE_ERROR, | ||
1246 | _("Error writing to wlan healper. errno == %d, ERROR: %s\n"), errno, strerror(errno) ); | ||
1247 | 1400 | ||
1248 | } | 1401 | if (bytes != size) |
1249 | GNUNET_assert(bytes != GNUNET_SYSERR); | 1402 | { |
1403 | finish = GNUNET_malloc(sizeof( struct Finish_send)); | ||
1404 | finish->plugin = plugin; | ||
1405 | finish->msgheader = (char *) msgheader + bytes; | ||
1406 | finish->size = size - bytes; | ||
1407 | finish->msgstart = msgheader; | ||
1250 | 1408 | ||
1251 | if (bytes != size) | 1409 | GNUNET_assert(plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK); |
1252 | { | ||
1253 | finish = GNUNET_malloc(sizeof( struct Finish_send)); | ||
1254 | finish->plugin = plugin; | ||
1255 | finish->msgheader = (char * ) msgheader + bytes; | ||
1256 | finish->size = size - bytes; | ||
1257 | finish->msgstart = msgheader; | ||
1258 | 1410 | ||
1259 | GNUNET_assert(plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK); | 1411 | plugin->server_write_task = GNUNET_SCHEDULER_add_write_file( |
1412 | GNUNET_TIME_UNIT_FOREVER_REL, plugin->server_stdin_handle, | ||
1413 | &finish_sending, finish); | ||
1260 | 1414 | ||
1261 | plugin->server_write_task = GNUNET_SCHEDULER_add_write_file( | 1415 | } |
1262 | GNUNET_TIME_UNIT_FOREVER_REL, plugin->server_stdin_handle, | 1416 | else |
1263 | &finish_sending, finish); | 1417 | { |
1418 | GNUNET_assert(bytes == size); | ||
1264 | 1419 | ||
1265 | } | 1420 | GNUNET_free(msgheader); |
1266 | else | 1421 | check_next_fragment_timeout(plugin); |
1267 | { | 1422 | } |
1268 | GNUNET_assert(bytes == size); | ||
1269 | 1423 | ||
1270 | GNUNET_free(msgheader); | 1424 | //check if this was the last fragment of this message, if true then queue at the end of the list |
1271 | check_next_fragment_timeout(plugin); | 1425 | if (copysize + copyoffset >= fm->message_size) |
1272 | } | 1426 | { |
1427 | GNUNET_assert(copysize + copyoffset == fm->message_size); | ||
1273 | 1428 | ||
1274 | //check if this was the last fragment of this message, if true then queue at the end of the list | 1429 | GNUNET_CONTAINER_DLL_remove (plugin->pending_Fragment_Messages_head, |
1275 | if (copysize + copyoffset >= fm->message_size) | 1430 | plugin->pending_Fragment_Messages_tail, fm); |
1276 | { | ||
1277 | GNUNET_assert(copysize + copyoffset == fm->message_size); | ||
1278 | 1431 | ||
1279 | GNUNET_CONTAINER_DLL_remove (plugin->pending_Fragment_Messages_head, | 1432 | GNUNET_CONTAINER_DLL_insert_tail(plugin->pending_Fragment_Messages_head, |
1280 | plugin->pending_Fragment_Messages_tail, fm); | 1433 | plugin->pending_Fragment_Messages_tail, fm); |
1434 | // if fragments have opimized timeouts | ||
1435 | //sort_fragment_into_queue(plugin,fm); | ||
1281 | 1436 | ||
1282 | GNUNET_CONTAINER_DLL_insert_tail(plugin->pending_Fragment_Messages_head, | 1437 | } |
1283 | plugin->pending_Fragment_Messages_tail, fm); | ||
1284 | // if fragments have opimized timeouts | ||
1285 | //sort_fragment_into_queue(plugin,fm); | ||
1286 | 1438 | ||
1287 | } | 1439 | } |
1288 | 1440 | return; | |
1289 | } | 1441 | } |
1442 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, | ||
1443 | "do_transmit did nothing, should not happen!\n"); | ||
1290 | } | 1444 | } |
1291 | 1445 | ||
1292 | |||
1293 | static void | 1446 | static void |
1294 | finish_sending(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | 1447 | finish_sending(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) |
1295 | { | 1448 | { |
@@ -1302,7 +1455,8 @@ finish_sending(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1302 | 1455 | ||
1303 | plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK; | 1456 | plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK; |
1304 | 1457 | ||
1305 | bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, finish->msgheader, finish->size); | 1458 | bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, |
1459 | finish->msgheader, finish->size); | ||
1306 | GNUNET_assert(bytes != GNUNET_SYSERR); | 1460 | GNUNET_assert(bytes != GNUNET_SYSERR); |
1307 | 1461 | ||
1308 | GNUNET_assert(plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK); | 1462 | GNUNET_assert(plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK); |
@@ -1326,17 +1480,30 @@ finish_sending(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc) | |||
1326 | } | 1480 | } |
1327 | 1481 | ||
1328 | int | 1482 | int |
1329 | getRadiotapHeader(struct RadiotapHeader * Header){ | 1483 | getRadiotapHeader(struct RadiotapHeader * Header) |
1484 | { | ||
1330 | return GNUNET_YES; | 1485 | return GNUNET_YES; |
1331 | }; | 1486 | } |
1487 | ; | ||
1332 | 1488 | ||
1333 | int | 1489 | /** |
1334 | getWlanHeader(struct IeeeHeader * Header){ | 1490 | * function to generate the wlan hardware header for one packet |
1491 | * @param Header address to write the header to | ||
1492 | * @param to_mac_addr address of the recipient | ||
1493 | * @param plugin pointer to the plugin struct | ||
1494 | * @return GNUNET_YES if there was no error | ||
1495 | */ | ||
1335 | 1496 | ||
1497 | int | ||
1498 | getWlanHeader(struct IeeeHeader * Header,const char * const to_mac_addr, | ||
1499 | struct Plugin * plugin) | ||
1500 | { | ||
1501 | memcpy(&Header->mac2, macbc, sizeof(macbc)); | ||
1502 | memcpy(&Header->mac3, plugin->mac_address.mac, sizeof(plugin->mac_address)); | ||
1503 | memcpy(&Header->mac1, to_mac_addr, sizeof(plugin->mac_address)); | ||
1336 | return GNUNET_YES; | 1504 | return GNUNET_YES; |
1337 | } | 1505 | } |
1338 | 1506 | ||
1339 | |||
1340 | /** | 1507 | /** |
1341 | * 32bit CRC | 1508 | * 32bit CRC |
1342 | * | 1509 | * |
@@ -1347,10 +1514,10 @@ getWlanHeader(struct IeeeHeader * Header){ | |||
1347 | */ | 1514 | */ |
1348 | 1515 | ||
1349 | uint32_t | 1516 | uint32_t |
1350 | getcrc32 (const char *msgbuf, | 1517 | getcrc32(const char *msgbuf, size_t msgbuf_size) |
1351 | size_t msgbuf_size){ | 1518 | { |
1352 | //TODO calc some crc | 1519 | //TODO calc some crc |
1353 | return 0; | 1520 | return 0; |
1354 | } | 1521 | } |
1355 | 1522 | ||
1356 | /** | 1523 | /** |
@@ -1363,10 +1530,10 @@ getcrc32 (const char *msgbuf, | |||
1363 | */ | 1530 | */ |
1364 | 1531 | ||
1365 | uint16_t | 1532 | uint16_t |
1366 | getcrc16 (const char *msgbuf, | 1533 | getcrc16(const char *msgbuf, size_t msgbuf_size) |
1367 | size_t msgbuf_size){ | 1534 | { |
1368 | //TODO calc some crc | 1535 | //TODO calc some crc |
1369 | return 0; | 1536 | return 0; |
1370 | } | 1537 | } |
1371 | 1538 | ||
1372 | /** | 1539 | /** |
@@ -1396,22 +1563,18 @@ getcrc16 (const char *msgbuf, | |||
1396 | * and does NOT mean that the message was not transmitted (DV) | 1563 | * and does NOT mean that the message was not transmitted (DV) |
1397 | */ | 1564 | */ |
1398 | static ssize_t | 1565 | static ssize_t |
1399 | wlan_plugin_send (void *cls, | 1566 | wlan_plugin_send(void *cls, const struct GNUNET_PeerIdentity * target, |
1400 | const struct GNUNET_PeerIdentity * target, | 1567 | const char *msgbuf, size_t msgbuf_size, unsigned int priority, |
1401 | const char *msgbuf, | 1568 | struct GNUNET_TIME_Relative timeout, struct Session *session, |
1402 | size_t msgbuf_size, | 1569 | const void *addr, size_t addrlen, int force_address, |
1403 | unsigned int priority, | 1570 | GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls) |
1404 | struct GNUNET_TIME_Relative timeout, | ||
1405 | struct Session *session, | ||
1406 | const void *addr, | ||
1407 | size_t addrlen, | ||
1408 | int force_address, | ||
1409 | GNUNET_TRANSPORT_TransmitContinuation cont, | ||
1410 | void *cont_cls) | ||
1411 | { | 1571 | { |
1412 | struct Plugin * plugin = cls; | 1572 | struct Plugin * plugin = cls; |
1413 | struct PendingMessage * newmsg = NULL; | 1573 | struct PendingMessage * newmsg = NULL; |
1414 | struct WlanHeader * wlanheader = NULL; | 1574 | struct WlanHeader * wlanheader = NULL; |
1575 | struct GNUNET_MessageHeader * innermsg = | ||
1576 | (struct GNUNET_MessageHeader *) msgbuf; | ||
1577 | |||
1415 | //check if msglen > 0 | 1578 | //check if msglen > 0 |
1416 | GNUNET_assert(msgbuf_size > 0); | 1579 | GNUNET_assert(msgbuf_size > 0); |
1417 | 1580 | ||
@@ -1430,6 +1593,14 @@ wlan_plugin_send (void *cls, | |||
1430 | } | 1593 | } |
1431 | } | 1594 | } |
1432 | 1595 | ||
1596 | #if DEBUG_wlan | ||
1597 | GNUNET_log( | ||
1598 | GNUNET_ERROR_TYPE_DEBUG, | ||
1599 | "wlan_plugin_send got %u bytes data, packet says it has %u bytes for %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n", | ||
1600 | msgbuf_size, ntohs(innermsg->size), session->addr[0], session->addr[1], | ||
1601 | session->addr[2], session->addr[3], session->addr[4], session->addr[5]); | ||
1602 | #endif | ||
1603 | |||
1433 | //TODO target "problem" not solved | 1604 | //TODO target "problem" not solved |
1434 | session->target = *target; | 1605 | session->target = *target; |
1435 | 1606 | ||
@@ -1439,7 +1610,17 @@ wlan_plugin_send (void *cls, | |||
1439 | 1610 | ||
1440 | //queue message in session | 1611 | //queue message in session |
1441 | //test if there is no other message in the "queue" | 1612 | //test if there is no other message in the "queue" |
1442 | GNUNET_assert (session->pending_message == NULL); | 1613 | //FIXME: to many send requests |
1614 | //GNUNET_assert (session->pending_message == NULL); | ||
1615 | if (session->pending_message != NULL) | ||
1616 | { | ||
1617 | newmsg = session->pending_message; | ||
1618 | GNUNET_log( | ||
1619 | GNUNET_ERROR_TYPE_ERROR, | ||
1620 | "wlan_plugin_send: a pending message is already in the queue for this client\n remaining time to send this message is %u\n", | ||
1621 | GNUNET_TIME_absolute_get_remaining(newmsg->timeout).rel_value); | ||
1622 | return -1; | ||
1623 | } | ||
1443 | 1624 | ||
1444 | newmsg = GNUNET_malloc(sizeof(struct PendingMessage)); | 1625 | newmsg = GNUNET_malloc(sizeof(struct PendingMessage)); |
1445 | (newmsg->msg) = GNUNET_malloc(msgbuf_size + sizeof(struct WlanHeader)); | 1626 | (newmsg->msg) = GNUNET_malloc(msgbuf_size + sizeof(struct WlanHeader)); |
@@ -1453,6 +1634,9 @@ wlan_plugin_send (void *cls, | |||
1453 | newmsg->transmit_cont = cont; | 1634 | newmsg->transmit_cont = cont; |
1454 | newmsg->transmit_cont_cls = cont_cls; | 1635 | newmsg->transmit_cont_cls = cont_cls; |
1455 | newmsg->timeout = GNUNET_TIME_relative_to_absolute(timeout); | 1636 | newmsg->timeout = GNUNET_TIME_relative_to_absolute(timeout); |
1637 | |||
1638 | newmsg->timeout.abs_value = newmsg->timeout.abs_value - 500; | ||
1639 | |||
1456 | newmsg->message_size = msgbuf_size + sizeof(struct WlanHeader); | 1640 | newmsg->message_size = msgbuf_size + sizeof(struct WlanHeader); |
1457 | 1641 | ||
1458 | session->pending_message = newmsg; | 1642 | session->pending_message = newmsg; |
@@ -1510,7 +1694,7 @@ wlan_plugin_disconnect(void *cls, const struct GNUNET_PeerIdentity *target) | |||
1510 | { | 1694 | { |
1511 | if (pendingsession->content == queue->content) | 1695 | if (pendingsession->content == queue->content) |
1512 | { | 1696 | { |
1513 | plugin->pendingsessions --; | 1697 | plugin->pendingsessions--; |
1514 | GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions, | 1698 | GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions, |
1515 | plugin->pending_Sessions_tail, pendingsession); | 1699 | plugin->pending_Sessions_tail, pendingsession); |
1516 | GNUNET_free(pendingsession); | 1700 | GNUNET_free(pendingsession); |
@@ -1521,20 +1705,23 @@ wlan_plugin_disconnect(void *cls, const struct GNUNET_PeerIdentity *target) | |||
1521 | 1705 | ||
1522 | //is something of this session in the fragment queue? | 1706 | //is something of this session in the fragment queue? |
1523 | fm = get_fragment_message_from_session(queue->content); | 1707 | fm = get_fragment_message_from_session(queue->content); |
1524 | free_fragment_message(plugin,fm); | 1708 | free_fragment_message(plugin, fm); |
1525 | 1709 | ||
1526 | //dispose all received fragments | 1710 | //dispose all received fragments |
1527 | free_rec_frag_queue(queue->content); | 1711 | free_rec_frag_queue(queue->content); |
1528 | 1712 | ||
1529 | // remove PendingMessage | 1713 | // remove PendingMessage |
1530 | pm = queue->content->pending_message; | 1714 | pm = queue->content->pending_message; |
1531 | GNUNET_free(pm->msg); | 1715 | if (pm != NULL) |
1532 | GNUNET_free(pm); | 1716 | { |
1717 | GNUNET_free_non_null(pm->msg); | ||
1718 | GNUNET_free(pm); | ||
1719 | } | ||
1533 | 1720 | ||
1534 | GNUNET_free(queue->content); | 1721 | GNUNET_free(queue->content); |
1535 | GNUNET_CONTAINER_DLL_remove(plugin->sessions, plugin->sessions_tail, queue); | 1722 | GNUNET_CONTAINER_DLL_remove(plugin->sessions, plugin->sessions_tail, queue); |
1536 | GNUNET_free(queue); | 1723 | GNUNET_free(queue); |
1537 | plugin->session_count --; | 1724 | plugin->session_count--; |
1538 | 1725 | ||
1539 | return; | 1726 | return; |
1540 | } | 1727 | } |
@@ -1543,7 +1730,6 @@ wlan_plugin_disconnect(void *cls, const struct GNUNET_PeerIdentity *target) | |||
1543 | } | 1730 | } |
1544 | } | 1731 | } |
1545 | 1732 | ||
1546 | |||
1547 | /** | 1733 | /** |
1548 | * Convert the transports address to a nice, human-readable | 1734 | * Convert the transports address to a nice, human-readable |
1549 | * format. | 1735 | * format. |
@@ -1559,37 +1745,29 @@ wlan_plugin_disconnect(void *cls, const struct GNUNET_PeerIdentity *target) | |||
1559 | * @param asc_cls closure for asc | 1745 | * @param asc_cls closure for asc |
1560 | */ | 1746 | */ |
1561 | static void | 1747 | static void |
1562 | wlan_plugin_address_pretty_printer (void *cls, | 1748 | wlan_plugin_address_pretty_printer(void *cls, const char *type, |
1563 | const char *type, | 1749 | const void *addr, size_t addrlen, int numeric, |
1564 | const void *addr, | 1750 | struct GNUNET_TIME_Relative timeout, |
1565 | size_t addrlen, | 1751 | GNUNET_TRANSPORT_AddressStringCallback asc, void *asc_cls) |
1566 | int numeric, | ||
1567 | struct GNUNET_TIME_Relative timeout, | ||
1568 | GNUNET_TRANSPORT_AddressStringCallback | ||
1569 | asc, void *asc_cls) | ||
1570 | { | 1752 | { |
1571 | char ret[92]; | 1753 | char ret[92]; |
1572 | const unsigned char * input; | 1754 | const unsigned char * input; |
1573 | 1755 | ||
1574 | GNUNET_assert(cls !=NULL); | 1756 | GNUNET_assert(cls !=NULL); |
1575 | if (addrlen != 6) | 1757 | if (addrlen != 6) |
1576 | { | 1758 | { |
1577 | /* invalid address (MAC addresses have 6 bytes) */ | 1759 | /* invalid address (MAC addresses have 6 bytes) */ |
1578 | GNUNET_break (0); | 1760 | GNUNET_break (0); |
1579 | asc (asc_cls, NULL); | 1761 | asc(asc_cls, NULL); |
1580 | return; | 1762 | return; |
1581 | } | 1763 | } |
1582 | input = (const unsigned char*) addr; | 1764 | input = (const unsigned char*) addr; |
1583 | GNUNET_snprintf (ret, | 1765 | GNUNET_snprintf(ret, sizeof(ret), "%s Mac-Adress %.2X:%.2X:%.2X:%.2X:%.2X:%.2X", |
1584 | sizeof (ret), | 1766 | PROTOCOL_PREFIX, input[0], input[1], input[2], input[3], input[4], |
1585 | "%s Mac-Adress %X:%X:%X:%X:%X:%X", | 1767 | input[5]); |
1586 | PROTOCOL_PREFIX, | 1768 | asc(asc_cls, ret); |
1587 | input[0], input[1], input[2], input[3], input[4], input[5]); | ||
1588 | asc (asc_cls, ret); | ||
1589 | } | 1769 | } |
1590 | 1770 | ||
1591 | |||
1592 | |||
1593 | /** | 1771 | /** |
1594 | * Another peer has suggested an address for this | 1772 | * Another peer has suggested an address for this |
1595 | * peer and transport plugin. Check that this could be a valid | 1773 | * peer and transport plugin. Check that this could be a valid |
@@ -1603,31 +1781,30 @@ wlan_plugin_address_pretty_printer (void *cls, | |||
1603 | * and transport | 1781 | * and transport |
1604 | */ | 1782 | */ |
1605 | 1783 | ||
1606 | |||
1607 | static int | 1784 | static int |
1608 | wlan_plugin_address_suggested (void *cls, | 1785 | wlan_plugin_address_suggested(void *cls, const void *addr, size_t addrlen) |
1609 | const void *addr, | ||
1610 | size_t addrlen) | ||
1611 | { | 1786 | { |
1612 | //struct Plugin *plugin = cls; | 1787 | //struct Plugin *plugin = cls; |
1613 | 1788 | ||
1614 | /* check if the address is plausible; if so, | 1789 | /* check if the address is plausible; if so, |
1615 | add it to our list! */ | 1790 | add it to our list! */ |
1616 | 1791 | ||
1617 | GNUNET_assert(cls !=NULL); | 1792 | GNUNET_assert(cls !=NULL); |
1618 | //FIXME mitm is not checked | 1793 | //FIXME mitm is not checked |
1619 | //Mac Adress has 6 bytes | 1794 | //Mac Adress has 6 bytes |
1620 | if (addrlen == 6){ | 1795 | if (addrlen == 6) |
1621 | /* TODO check for bad addresses like milticast, broadcast, etc */ | 1796 | { |
1622 | return GNUNET_OK; | 1797 | /* TODO check for bad addresses like multicast, broadcast, etc */ |
1623 | } else { | 1798 | return GNUNET_OK; |
1624 | return GNUNET_SYSERR; | 1799 | } |
1625 | } | 1800 | else |
1801 | { | ||
1802 | return GNUNET_SYSERR; | ||
1803 | } | ||
1626 | 1804 | ||
1627 | return GNUNET_SYSERR; | 1805 | return GNUNET_SYSERR; |
1628 | } | 1806 | } |
1629 | 1807 | ||
1630 | |||
1631 | /** | 1808 | /** |
1632 | * Function called for a quick conversion of the binary address to | 1809 | * Function called for a quick conversion of the binary address to |
1633 | * a numeric address. Note that the caller must not free the | 1810 | * a numeric address. Note that the caller must not free the |
@@ -1639,14 +1816,12 @@ wlan_plugin_address_suggested (void *cls, | |||
1639 | * @param addrlen length of the address | 1816 | * @param addrlen length of the address |
1640 | * @return string representing the same address | 1817 | * @return string representing the same address |
1641 | */ | 1818 | */ |
1642 | static const char* | 1819 | static const char* |
1643 | wlan_plugin_address_to_string (void *cls, | 1820 | wlan_plugin_address_to_string(void *cls, const void *addr, size_t addrlen) |
1644 | const void *addr, | ||
1645 | size_t addrlen) | ||
1646 | { | 1821 | { |
1647 | static char ret[40]; | 1822 | static char ret[40]; |
1648 | const unsigned char * input; | 1823 | const unsigned char * input; |
1649 | 1824 | ||
1650 | GNUNET_assert(cls !=NULL); | 1825 | GNUNET_assert(cls !=NULL); |
1651 | if (addrlen != 6) | 1826 | if (addrlen != 6) |
1652 | { | 1827 | { |
@@ -1655,11 +1830,9 @@ wlan_plugin_address_to_string (void *cls, | |||
1655 | return NULL; | 1830 | return NULL; |
1656 | } | 1831 | } |
1657 | input = (const unsigned char*) addr; | 1832 | input = (const unsigned char*) addr; |
1658 | GNUNET_snprintf (ret, | 1833 | GNUNET_snprintf(ret, sizeof(ret), "%s Mac-Adress %.2X:%.2X:%.2X:%.2X:%.2X:%.2X", |
1659 | sizeof (ret), | 1834 | PROTOCOL_PREFIX, input[0], input[1], input[2], input[3], input[4], |
1660 | "%s Mac-Adress %X:%X:%X:%X:%X:%X", | 1835 | input[5]); |
1661 | PROTOCOL_PREFIX, | ||
1662 | input[0], input[1], input[2], input[3], input[4], input[5]); | ||
1663 | return ret; | 1836 | return ret; |
1664 | } | 1837 | } |
1665 | 1838 | ||
@@ -1707,7 +1880,7 @@ insert_fragment_in_queue(struct Session * session, struct RecQueue * rec_queue) | |||
1707 | if (rec_queue->num == 0) | 1880 | if (rec_queue->num == 0) |
1708 | { | 1881 | { |
1709 | wlanheader = (struct WlanHeader *) rec_queue->msg; | 1882 | wlanheader = (struct WlanHeader *) rec_queue->msg; |
1710 | session->rec_size = wlanheader->header.size; | 1883 | session->rec_size = ntohs(wlanheader->header.size); |
1711 | } | 1884 | } |
1712 | 1885 | ||
1713 | //sort into list | 1886 | //sort into list |
@@ -1754,7 +1927,9 @@ free_rec_frag_queue(struct Session * session) | |||
1754 | */ | 1927 | */ |
1755 | 1928 | ||
1756 | static void | 1929 | static void |
1757 | check_rec_finished_msg (struct Plugin* plugin, struct Session_light * session_light, struct Session * session){ | 1930 | check_rec_finished_msg(struct Plugin* plugin, |
1931 | struct Session_light * session_light, struct Session * session) | ||
1932 | { | ||
1758 | struct RecQueue * rec_queue = session->frag_head; | 1933 | struct RecQueue * rec_queue = session->frag_head; |
1759 | int packetsize = session->rec_size; | 1934 | int packetsize = session->rec_size; |
1760 | int sum = 0; | 1935 | int sum = 0; |
@@ -1763,105 +1938,73 @@ check_rec_finished_msg (struct Plugin* plugin, struct Session_light * session_li | |||
1763 | //some fragment should be received | 1938 | //some fragment should be received |
1764 | GNUNET_assert(session->rec_size != NO_MESSAGE_OR_MESSAGE_FINISHED); | 1939 | GNUNET_assert(session->rec_size != NO_MESSAGE_OR_MESSAGE_FINISHED); |
1765 | //check if first fragment is present | 1940 | //check if first fragment is present |
1766 | if (session->rec_size == MESSAGE_LENGHT_UNKNOWN){ | 1941 | if (session->rec_size == MESSAGE_LENGHT_UNKNOWN) |
1767 | return; | 1942 | { |
1768 | } | ||
1769 | while (rec_queue != NULL){ | ||
1770 | sum += rec_queue->size; | ||
1771 | //check if all fragment numbers are present | ||
1772 | if (rec_queue->num != aktnum){ | ||
1773 | return; | 1943 | return; |
1774 | } | 1944 | } |
1775 | aktnum ++; | 1945 | while (rec_queue != NULL) |
1776 | rec_queue = rec_queue->next; | 1946 | { |
1777 | } | 1947 | sum += rec_queue->size; |
1948 | //check if all fragment numbers are present | ||
1949 | if (rec_queue->num != aktnum) | ||
1950 | { | ||
1951 | return; | ||
1952 | } | ||
1953 | aktnum++; | ||
1954 | rec_queue = rec_queue->next; | ||
1955 | } | ||
1778 | //sum should always be smaller or equal of | 1956 | //sum should always be smaller or equal of |
1779 | GNUNET_assert(sum <= packetsize); | 1957 | GNUNET_assert(sum <= packetsize); |
1780 | if(sum == packetsize){ | 1958 | if (sum == packetsize) |
1959 | { | ||
1781 | 1960 | ||
1782 | #if DEBUG_wlan | 1961 | #if DEBUG_wlan |
1783 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 1962 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
1784 | "check_rec_finished_msg: A message with fragments is complete\n"); | 1963 | "check_rec_finished_msg: A message with fragments is complete\n"); |
1785 | #endif | 1964 | #endif |
1786 | 1965 | ||
1787 | //copy fragments together | 1966 | //copy fragments together |
1788 | msg = GNUNET_malloc(packetsize); | 1967 | msg = GNUNET_malloc(packetsize); |
1789 | rec_queue = session->frag_head; | 1968 | rec_queue = session->frag_head; |
1790 | aktnum = 0; | 1969 | aktnum = 0; |
1791 | while (rec_queue != NULL){ | 1970 | while (rec_queue != NULL) |
1792 | memcpy(msg + aktnum, rec_queue->msg, rec_queue->size); | 1971 | { |
1793 | aktnum += rec_queue->size; | 1972 | memcpy(msg + aktnum, rec_queue->msg, rec_queue->size); |
1794 | rec_queue = rec_queue->next; | 1973 | aktnum += rec_queue->size; |
1795 | } | 1974 | rec_queue = rec_queue->next; |
1796 | free_rec_frag_queue(session); | 1975 | } |
1797 | //call wlan_process_helper to process the message | 1976 | free_rec_frag_queue(session); |
1798 | wlan_data_helper (plugin, session_light, (struct GNUNET_MessageHeader*) msg); | 1977 | //call wlan_process_helper to process the message |
1978 | wlan_data_massage_handler(plugin, session_light, | ||
1979 | (struct GNUNET_MessageHeader*) msg); | ||
1980 | //wlan_data_helper (plugin, session_light, (struct GNUNET_MessageHeader*) msg); | ||
1799 | 1981 | ||
1800 | GNUNET_free(msg); | 1982 | GNUNET_free(msg); |
1801 | } | 1983 | } |
1802 | } | 1984 | } |
1803 | 1985 | ||
1804 | /** | ||
1805 | * Function used for to process the data received from the wlan interface | ||
1806 | * | ||
1807 | * @param cls the plugin handle | ||
1808 | * @param client client which send the data (not used) | ||
1809 | * @param hdr hdr of the GNUNET_MessageHeader | ||
1810 | */ | ||
1811 | static void | 1986 | static void |
1812 | wlan_data_helper(void *cls, void * client, const struct GNUNET_MessageHeader * hdr) | 1987 | wlan_data_massage_handler(struct Plugin * plugin, |
1988 | struct Session_light * session_light, | ||
1989 | const struct GNUNET_MessageHeader * hdr) | ||
1813 | { | 1990 | { |
1814 | struct Plugin *plugin = cls; | ||
1815 | struct Session * session = NULL; | ||
1816 | struct Session_light * session_light = NULL; | ||
1817 | |||
1818 | struct WlanHeader * wlanheader = NULL; | 1991 | struct WlanHeader * wlanheader = NULL; |
1819 | struct FragmentationHeader * fh = NULL; | 1992 | struct Session * session = NULL; |
1820 | struct FragmentMessage * fm = NULL; | ||
1821 | |||
1822 | const char * tempmsg = NULL; | 1993 | const char * tempmsg = NULL; |
1823 | |||
1824 | struct AckQueue * ack = NULL; | ||
1825 | struct AckQueue * ack2 = NULL; | ||
1826 | |||
1827 | struct RecQueue * rec_queue = NULL; | ||
1828 | const struct GNUNET_MessageHeader * temp_hdr = NULL; | 1994 | const struct GNUNET_MessageHeader * temp_hdr = NULL; |
1995 | struct GNUNET_PeerIdentity tmptarget; | ||
1829 | 1996 | ||
1830 | if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT) | 1997 | if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_DATA) |
1831 | { | 1998 | { |
1832 | 1999 | ||
1833 | #if DEBUG_wlan | 2000 | #if DEBUG_wlan |
1834 | GNUNET_log( | 2001 | GNUNET_log( |
1835 | GNUNET_ERROR_TYPE_DEBUG, | 2002 | GNUNET_ERROR_TYPE_DEBUG, |
1836 | "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT size: %i\n", | 2003 | "Func wlan_data_massage_handler got GNUNET_MESSAGE_TYPE_WLAN_DATA size: %u\n", |
1837 | ntohs(hdr->size)); | 2004 | ntohs(hdr->size)); |
1838 | #endif | 2005 | #endif |
1839 | 2006 | ||
1840 | //TODO better DOS protection, error handling | 2007 | GNUNET_assert(session_light != NULL); |
1841 | GNUNET_assert(client != NULL); | ||
1842 | session_light = (struct Session_light *) client; | ||
1843 | if (session_light->session == NULL) | ||
1844 | { | ||
1845 | session_light->session = get_Session(plugin, session_light->addr); | ||
1846 | } | ||
1847 | GNUNET_assert(GNUNET_HELLO_get_id( | ||
1848 | (const struct GNUNET_HELLO_Message *) &hdr[1], | ||
1849 | &(session_light->session->target) ) != GNUNET_SYSERR); | ||
1850 | |||
1851 | } | ||
1852 | |||
1853 | |||
1854 | else if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_DATA) | ||
1855 | { | ||
1856 | |||
1857 | #if DEBUG_wlan | ||
1858 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
1859 | "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_WLAN_DATA size: %i\n", | ||
1860 | ntohs(hdr->size)); | ||
1861 | #endif | ||
1862 | |||
1863 | GNUNET_assert(client != NULL); | ||
1864 | session_light = (struct Session_light *) client; | ||
1865 | if (session_light->session == NULL) | 2008 | if (session_light->session == NULL) |
1866 | { | 2009 | { |
1867 | session_light->session = search_session(plugin, session_light->addr); | 2010 | session_light->session = search_session(plugin, session_light->addr); |
@@ -1871,31 +2014,62 @@ wlan_data_helper(void *cls, void * client, const struct GNUNET_MessageHeader * h | |||
1871 | tempmsg = (char*) &wlanheader[1]; | 2014 | tempmsg = (char*) &wlanheader[1]; |
1872 | temp_hdr = (const struct GNUNET_MessageHeader *) &wlanheader[1]; | 2015 | temp_hdr = (const struct GNUNET_MessageHeader *) &wlanheader[1]; |
1873 | 2016 | ||
1874 | if (getcrc32(tempmsg, wlanheader->header.size) != wlanheader->crc) | 2017 | if (getcrc32(tempmsg, ntohs(wlanheader->header.size)) != ntohl( |
2018 | wlanheader->crc)) | ||
1875 | { | 2019 | { |
1876 | //wrong crc, dispose message | 2020 | //wrong crc, dispose message |
1877 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "WLAN message crc was wrong\n"); | 2021 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, |
2022 | "Wlan message Header crc was wrong\n"); | ||
1878 | return; | 2023 | return; |
1879 | } | 2024 | } |
1880 | 2025 | ||
1881 | //if not in session list | 2026 | //if not in session list |
1882 | if (session == NULL) | 2027 | if (session == NULL) |
1883 | { | 2028 | { |
1884 | 2029 | #if DEBUG_wlan | |
2030 | GNUNET_log( | ||
2031 | GNUNET_ERROR_TYPE_DEBUG, | ||
2032 | "WLAN client not in session list: packet size = %u, inner size = %u, header size = %u\n", | ||
2033 | ntohs(wlanheader->header.size), ntohs(temp_hdr->size), | ||
2034 | sizeof(struct WlanHeader)); | ||
2035 | #endif | ||
1885 | //try if it is a hello message | 2036 | //try if it is a hello message |
1886 | if (ntohs(temp_hdr->type) == GNUNET_MESSAGE_TYPE_HELLO) | 2037 | if (ntohs(wlanheader->header.size) >= ntohs(temp_hdr->size) |
2038 | + sizeof(struct WlanHeader)) | ||
1887 | { | 2039 | { |
1888 | session = create_session(plugin, session_light->addr); | 2040 | if (ntohs(temp_hdr->type) == GNUNET_MESSAGE_TYPE_HELLO) |
1889 | session_light->session = session; | 2041 | { |
1890 | GNUNET_assert(GNUNET_HELLO_get_id( | 2042 | if (GNUNET_HELLO_get_id( |
1891 | (const struct GNUNET_HELLO_Message *) temp_hdr, | 2043 | (const struct GNUNET_HELLO_Message *) temp_hdr, |
1892 | &session->target ) != GNUNET_SYSERR); | 2044 | &tmptarget) == GNUNET_OK) |
2045 | { | ||
2046 | session = create_session(plugin, session_light->addr); | ||
2047 | session_light->session = session; | ||
2048 | memcpy(&session->target, &tmptarget, | ||
2049 | sizeof(struct GNUNET_PeerIdentity)); | ||
2050 | } | ||
2051 | else | ||
2052 | { | ||
2053 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, | ||
2054 | "WLAN client not in session list and hello message not okay\n"); | ||
2055 | return; | ||
2056 | } | ||
1893 | 2057 | ||
2058 | } | ||
2059 | else | ||
2060 | { | ||
2061 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, | ||
2062 | "WLAN client not in session list and not a hello message\n"); | ||
2063 | return; | ||
2064 | } | ||
1894 | } | 2065 | } |
1895 | else | 2066 | else |
1896 | { | 2067 | { |
1897 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, | 2068 | GNUNET_log( |
1898 | "WLAN client not in session list and not a hello message\n"); | 2069 | GNUNET_ERROR_TYPE_WARNING, |
2070 | "WLAN client not in session list and message size in does not fit\npacket size = %u, inner size = %u, header size = %u\n", | ||
2071 | ntohs(wlanheader->header.size), ntohs(temp_hdr->size), | ||
2072 | sizeof(struct WlanHeader)); | ||
1899 | return; | 2073 | return; |
1900 | } | 2074 | } |
1901 | } | 2075 | } |
@@ -1906,24 +2080,102 @@ wlan_data_helper(void *cls, void * client, const struct GNUNET_MessageHeader * h | |||
1906 | distance[0].value = htonl(1); | 2080 | distance[0].value = htonl(1); |
1907 | distance[1].type = htonl(GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR); | 2081 | distance[1].type = htonl(GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR); |
1908 | distance[1].value = htonl(0); | 2082 | distance[1].value = htonl(0); |
2083 | |||
2084 | #if DEBUG_wlan | ||
2085 | GNUNET_log( | ||
2086 | GNUNET_ERROR_TYPE_DEBUG, | ||
2087 | "Calling plugin->env->receive\n"); | ||
2088 | #endif | ||
1909 | plugin->env->receive(plugin->env->cls, &(session->target), temp_hdr, | 2089 | plugin->env->receive(plugin->env->cls, &(session->target), temp_hdr, |
1910 | (const struct GNUNET_TRANSPORT_ATS_Information *) &distance, 2, | 2090 | (const struct GNUNET_TRANSPORT_ATS_Information *) &distance, 2, |
1911 | session, session->addr, sizeof(session->addr)); | 2091 | session, session->addr, sizeof(session->addr)); |
1912 | 2092 | return; | |
1913 | } | 2093 | } |
1914 | 2094 | else | |
1915 | else if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT) | ||
1916 | { | 2095 | { |
2096 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, | ||
2097 | "wlan_data_massage_handler got wrong message type\n"); | ||
2098 | return; | ||
2099 | } | ||
2100 | } | ||
2101 | |||
2102 | /** | ||
2103 | * function to add an ack to send it for a received fragment | ||
2104 | * @param plugin pointer to the global plugin structure | ||
2105 | * @param session pointer to the session this ack belongs to | ||
2106 | * @param fh pointer to the fragmentation header which we would like to acknolage | ||
2107 | */ | ||
2108 | |||
2109 | void | ||
2110 | add_ack_for_send(struct Plugin * plugin, struct Session * session, | ||
2111 | struct FragmentationHeader * fh) | ||
2112 | { | ||
2113 | struct AckSendQueue * ack; | ||
2114 | |||
2115 | GNUNET_assert(plugin != NULL); | ||
2116 | GNUNET_assert(session != NULL); | ||
2117 | GNUNET_assert(fh != NULL); | ||
2118 | |||
2119 | ack = GNUNET_malloc(sizeof(struct AckSendQueue)); | ||
2120 | ack->fragment_off_or_num = ntohs(fh->fragment_off_or_num); | ||
2121 | ack->message_id = ntohl(fh->message_id); | ||
2122 | ack->session = session; | ||
2123 | |||
2124 | GNUNET_CONTAINER_DLL_insert_tail(plugin->ack_send_queue_head, | ||
2125 | plugin->ack_send_queue_tail, ack); | ||
2126 | |||
2127 | } | ||
2128 | |||
2129 | /** | ||
2130 | * Function used for to process the data received from the wlan interface | ||
2131 | * | ||
2132 | * @param cls the plugin handle | ||
2133 | * @param client client which send the data (not used) | ||
2134 | * @param hdr hdr of the GNUNET_MessageHeader | ||
2135 | */ | ||
2136 | static void | ||
2137 | wlan_data_helper(void *cls, struct Session_light * session_light, | ||
2138 | const struct GNUNET_MessageHeader * hdr) | ||
2139 | { | ||
2140 | struct Plugin *plugin = cls; | ||
2141 | struct Session * session = NULL; | ||
1917 | 2142 | ||
2143 | struct FragmentationHeader * fh = NULL; | ||
2144 | struct FragmentMessage * fm = NULL; | ||
2145 | |||
2146 | const char * tempmsg = NULL; | ||
2147 | |||
2148 | struct AckQueue * ack = NULL; | ||
2149 | struct AckQueue * ack2 = NULL; | ||
2150 | |||
2151 | struct RecQueue * rec_queue = NULL; | ||
2152 | //ADVERTISEMENT | ||
2153 | if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT) | ||
2154 | { | ||
1918 | #if DEBUG_wlan | 2155 | #if DEBUG_wlan |
1919 | GNUNET_log( | 2156 | GNUNET_log( |
1920 | GNUNET_ERROR_TYPE_DEBUG, | 2157 | GNUNET_ERROR_TYPE_DEBUG, |
1921 | "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT size: %i\n", | 2158 | "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT size: %u\n", |
1922 | ntohs(hdr->size)); | 2159 | ntohs(hdr->size)); |
1923 | #endif | 2160 | #endif |
1924 | 2161 | ||
1925 | GNUNET_assert(client != NULL); | 2162 | //TODO better DOS protection, error handling |
1926 | session_light = (struct Session_light *) client; | 2163 | GNUNET_assert(session_light != NULL); |
2164 | if (session_light->session == NULL) | ||
2165 | { | ||
2166 | session_light->session = get_Session(plugin, session_light->addr); | ||
2167 | } | ||
2168 | GNUNET_assert(GNUNET_HELLO_get_id( | ||
2169 | (const struct GNUNET_HELLO_Message *) &hdr[1], | ||
2170 | &(session_light->session->target) ) != GNUNET_SYSERR); | ||
2171 | |||
2172 | } | ||
2173 | |||
2174 | //FRAGMENT | ||
2175 | else if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT) | ||
2176 | { | ||
2177 | |||
2178 | GNUNET_assert(session_light != NULL); | ||
1927 | if (session_light->session == NULL) | 2179 | if (session_light->session == NULL) |
1928 | { | 2180 | { |
1929 | session_light->session = search_session(plugin, session_light->addr); | 2181 | session_light->session = search_session(plugin, session_light->addr); |
@@ -1933,83 +2185,106 @@ wlan_data_helper(void *cls, void * client, const struct GNUNET_MessageHeader * h | |||
1933 | fh = (struct FragmentationHeader *) hdr; | 2185 | fh = (struct FragmentationHeader *) hdr; |
1934 | tempmsg = (char*) &fh[1]; | 2186 | tempmsg = (char*) &fh[1]; |
1935 | 2187 | ||
1936 | //if not in session list | 2188 | #if DEBUG_wlan |
2189 | GNUNET_log( | ||
2190 | GNUNET_ERROR_TYPE_DEBUG, | ||
2191 | "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT with message_id %u with fragment number %i, size: %u\n", | ||
2192 | ntohl(fh->message_id), ntohs(fh->fragment_off_or_num), ntohs( | ||
2193 | hdr->size)); | ||
2194 | #endif | ||
2195 | |||
2196 | if (getcrc16(tempmsg, ntohs(fh->header.size)) != ntohs(fh->message_crc)) | ||
2197 | { | ||
2198 | //wrong crc, dispose message | ||
2199 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "WLAN fragment crc was wrong\n"); | ||
2200 | return; | ||
2201 | } | ||
2202 | |||
2203 | //if in the session list | ||
1937 | if (session != NULL) | 2204 | if (session != NULL) |
1938 | { | 2205 | { |
1939 | if (getcrc16(tempmsg, fh->header.size) != fh->message_crc) | 2206 | //TODO fragments do not timeout |
2207 | //check if message_id is right or it is a new msg | ||
2208 | if ((session->message_id_in == ntohs(fh->message_id)) | ||
2209 | || (session->rec_size == NO_MESSAGE_OR_MESSAGE_FINISHED)) | ||
1940 | { | 2210 | { |
1941 | //wrong crc, dispose message | 2211 | session->message_id_in = ntohs(fh->message_id); |
1942 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | 2212 | if (is_double_msg(session, fh) != GNUNET_YES) |
1943 | "WLAN fragment crc was wrong\n"); | ||
1944 | return; | ||
1945 | } | ||
1946 | else | ||
1947 | { | ||
1948 | //todo fragments do not timeout | ||
1949 | //check if message_id is rigth or it is a new msg | ||
1950 | if ((session->message_id_in == ntohs(fh->message_id)) | ||
1951 | || (session->rec_size == NO_MESSAGE_OR_MESSAGE_FINISHED)) | ||
1952 | { | 2213 | { |
1953 | session->message_id_in = ntohs(fh->message_id); | 2214 | //report size |
1954 | if (is_double_msg(session, fh) != GNUNET_YES) | 2215 | //TODO ask if it is right like this |
2216 | if (plugin->env->traffic_report != NULL) | ||
1955 | { | 2217 | { |
1956 | rec_queue | 2218 | plugin->env->traffic_report(plugin->env->cls, |
1957 | = GNUNET_malloc(sizeof (struct RecQueue) + | 2219 | &session->target, ntohs(fh->header.size)); |
1958 | ntohs(fh->header.size) - sizeof(struct FragmentationHeader)); | ||
1959 | rec_queue->size = ntohs(fh->header.size | ||
1960 | - sizeof(struct FragmentationHeader)); | ||
1961 | rec_queue->num = ntohs(fh->fragment_off_or_num); | ||
1962 | rec_queue->msg = (char*) &rec_queue[1]; | ||
1963 | //copy msg to buffer | ||
1964 | memcpy((char*) rec_queue->msg, tempmsg, rec_queue->size); | ||
1965 | insert_fragment_in_queue(session, rec_queue); | ||
1966 | check_rec_finished_msg(plugin, session_light, session); | ||
1967 | } | ||
1968 | else | ||
1969 | { | ||
1970 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, | ||
1971 | "WLAN fragment is a clone\n"); | ||
1972 | return; | ||
1973 | } | 2220 | } |
2221 | rec_queue | ||
2222 | = GNUNET_malloc(sizeof (struct RecQueue) + | ||
2223 | ntohs(fh->header.size) - sizeof(struct FragmentationHeader)); | ||
2224 | rec_queue->size = ntohs(fh->header.size) | ||
2225 | - sizeof(struct FragmentationHeader); | ||
2226 | rec_queue->num = ntohs(fh->fragment_off_or_num); | ||
2227 | rec_queue->msg = (char*) &rec_queue[1]; | ||
2228 | //copy msg to buffer | ||
2229 | memcpy((char *) rec_queue->msg, tempmsg, rec_queue->size); | ||
2230 | insert_fragment_in_queue(session, rec_queue); | ||
2231 | check_rec_finished_msg(plugin, session_light, session); | ||
1974 | } | 2232 | } |
1975 | else | 2233 | else |
1976 | { | 2234 | { |
1977 | GNUNET_log( | 2235 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, |
1978 | GNUNET_ERROR_TYPE_INFO, | 2236 | "WLAN fragment is a clone\n"); |
1979 | "WLAN fragment message_id and session message_id are not the same and a message is already (partly) received\n"); | 2237 | |
1980 | return; | ||
1981 | } | 2238 | } |
1982 | } | 2239 | } |
2240 | else | ||
2241 | { | ||
2242 | GNUNET_log( | ||
2243 | GNUNET_ERROR_TYPE_INFO, | ||
2244 | "WLAN fragment message_id and session message_id are not the same and a message is already (partly) received\n"); | ||
2245 | |||
2246 | } | ||
1983 | } | 2247 | } |
1984 | else | 2248 | else |
1985 | { | 2249 | { |
1986 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, | 2250 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, |
1987 | "WLAN client not in session list and it is a fragment message\n"); | 2251 | "WLAN client not in session list and it is a fragment message\n"); |
1988 | return; | 2252 | wlan_data_massage_handler(plugin, session_light, |
2253 | (struct GNUNET_MessageHeader *) tempmsg); | ||
2254 | session = session_light->session; | ||
2255 | //test if a session was created | ||
2256 | if (session == NULL) | ||
2257 | { | ||
2258 | return; | ||
2259 | } | ||
1989 | } | 2260 | } |
1990 | 2261 | ||
2262 | //TODO make and send ack | ||
2263 | add_ack_for_send(plugin, session, fh); | ||
2264 | check_next_fragment_timeout(plugin); | ||
2265 | |||
1991 | } | 2266 | } |
1992 | 2267 | ||
2268 | //ACK | ||
1993 | else if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT_ACK) | 2269 | else if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT_ACK) |
1994 | { | 2270 | { |
1995 | 2271 | ||
1996 | #if DEBUG_wlan | 2272 | #if DEBUG_wlan |
1997 | GNUNET_log( | 2273 | GNUNET_log( |
1998 | GNUNET_ERROR_TYPE_DEBUG, | 2274 | GNUNET_ERROR_TYPE_DEBUG, |
1999 | "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT_ACK size: %i\n", | 2275 | "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT_ACK size: %u\n", |
2000 | ntohs(hdr->size)); | 2276 | ntohs(hdr->size)); |
2001 | #endif | 2277 | #endif |
2002 | 2278 | ||
2003 | GNUNET_assert(client != NULL); | 2279 | GNUNET_assert(session_light != NULL); |
2004 | session_light = (struct Session_light *) client; | ||
2005 | if (session_light->session == NULL) | 2280 | if (session_light->session == NULL) |
2006 | { | 2281 | { |
2007 | session_light->session = search_session(plugin, session_light->addr); | 2282 | session_light->session = search_session(plugin, session_light->addr); |
2008 | GNUNET_assert(session_light->session != NULL); | 2283 | GNUNET_assert(session_light->session != NULL); |
2009 | } | 2284 | } |
2010 | session = session_light->session; | 2285 | session = session_light->session; |
2011 | fh = (struct FragmentationHeader *) &hdr[1]; | 2286 | fh = (struct FragmentationHeader *) hdr; |
2012 | if (fh->message_id == session->message_id_out) | 2287 | if (session->message_id_out == ntohl(fh->message_id)) |
2013 | { | 2288 | { |
2014 | fm = get_fragment_message_from_session(session); | 2289 | fm = get_fragment_message_from_session(session); |
2015 | if (fm != NULL) | 2290 | if (fm != NULL) |
@@ -2019,13 +2294,13 @@ wlan_data_helper(void *cls, void * client, const struct GNUNET_MessageHeader * h | |||
2019 | while (ack2 != NULL) | 2294 | while (ack2 != NULL) |
2020 | { | 2295 | { |
2021 | // check for double | 2296 | // check for double |
2022 | if (ack2->fragment_num != fh->fragment_off_or_num) | 2297 | if (ack2->fragment_num != ntohs(fh->fragment_off_or_num)) |
2023 | { | 2298 | { |
2024 | // check if next ack has bigger number | 2299 | // check if next ack has bigger number |
2025 | if (ack2->fragment_num > fh->fragment_off_or_num) | 2300 | if (ack2->fragment_num > ntohs(fh->fragment_off_or_num)) |
2026 | { | 2301 | { |
2027 | ack = GNUNET_malloc(sizeof(struct AckQueue)); | 2302 | ack = GNUNET_malloc(sizeof(struct AckQueue)); |
2028 | ack->fragment_num = fh->fragment_off_or_num; | 2303 | ack->fragment_num = ntohs(fh->fragment_off_or_num); |
2029 | GNUNET_CONTAINER_DLL_insert_before(fm->head,fm->tail,ack2,ack); | 2304 | GNUNET_CONTAINER_DLL_insert_before(fm->head,fm->tail,ack2,ack); |
2030 | //check if finished | 2305 | //check if finished |
2031 | check_finished_fragment(plugin, fm); | 2306 | check_finished_fragment(plugin, fm); |
@@ -2035,22 +2310,42 @@ wlan_data_helper(void *cls, void * client, const struct GNUNET_MessageHeader * h | |||
2035 | else | 2310 | else |
2036 | { | 2311 | { |
2037 | //double ack | 2312 | //double ack |
2313 | #if DEBUG_wlan | ||
2314 | GNUNET_log( | ||
2315 | GNUNET_ERROR_TYPE_DEBUG, | ||
2316 | "WLAN got double ack for message id %u and fragment num %u\n", | ||
2317 | session->message_id_out, ack2->fragment_num); | ||
2318 | #endif | ||
2038 | return; | 2319 | return; |
2039 | } | 2320 | } |
2040 | ack2 = ack2->next; | 2321 | ack2 = ack2->next; |
2041 | } | 2322 | } |
2042 | //GNUNET_CONTAINER_DLL_insert_tail(fm->head,fm->tail,ack); | 2323 | |
2043 | //should never happen but... | 2324 | //all acks are have smaller numbers |
2044 | //check_finished_fragment(plugin, fm); | 2325 | ack = GNUNET_malloc(sizeof(struct AckQueue)); |
2326 | ack->fragment_num = ntohs(fh->fragment_off_or_num); | ||
2327 | GNUNET_CONTAINER_DLL_insert_tail(fm->head,fm->tail,ack); | ||
2328 | check_finished_fragment(plugin, fm); | ||
2045 | } | 2329 | } |
2046 | else | 2330 | else |
2047 | { | 2331 | { |
2048 | GNUNET_log(GNUNET_ERROR_TYPE_WARNING, | 2332 | GNUNET_log( |
2049 | "WLAN fragment not in fragment list but id is right\n"); | 2333 | GNUNET_ERROR_TYPE_WARNING, |
2334 | "WLAN fragment not in fragment list but id %u of ack is right\n", | ||
2335 | ntohl(fh->message_id)); | ||
2050 | return; | 2336 | return; |
2051 | } | 2337 | } |
2052 | 2338 | ||
2053 | } | 2339 | } |
2340 | else | ||
2341 | { | ||
2342 | #if DEBUG_wlan | ||
2343 | GNUNET_log( | ||
2344 | GNUNET_ERROR_TYPE_DEBUG, | ||
2345 | _("WLAN got ack but session->message_id_out %u and fragment id %u mismatch\n"), | ||
2346 | session->message_id_out, ntohl(fh->message_id)); | ||
2347 | #endif | ||
2348 | } | ||
2054 | 2349 | ||
2055 | } | 2350 | } |
2056 | else | 2351 | else |
@@ -2062,8 +2357,8 @@ wlan_data_helper(void *cls, void * client, const struct GNUNET_MessageHeader * h | |||
2062 | } | 2357 | } |
2063 | 2358 | ||
2064 | #if 0 | 2359 | #if 0 |
2065 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | 2360 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
2066 | "Helper finished\n"); | 2361 | "Helper finished\n"); |
2067 | #endif | 2362 | #endif |
2068 | 2363 | ||
2069 | } | 2364 | } |
@@ -2077,53 +2372,78 @@ wlan_data_helper(void *cls, void * client, const struct GNUNET_MessageHeader * h | |||
2077 | */ | 2372 | */ |
2078 | 2373 | ||
2079 | static void | 2374 | static void |
2080 | wlan_process_helper (void *cls, | 2375 | wlan_process_helper(void *cls, void *client, |
2081 | void *client, | 2376 | const struct GNUNET_MessageHeader *hdr) |
2082 | const struct GNUNET_MessageHeader *hdr) | ||
2083 | { | 2377 | { |
2084 | struct Plugin *plugin = cls; | 2378 | struct Plugin *plugin = cls; |
2085 | struct IeeeHeader * wlanIeeeHeader = NULL; | 2379 | struct IeeeHeader * wlanIeeeHeader = NULL; |
2086 | struct Session_light * session_light = NULL; | 2380 | struct Session_light * session_light = NULL; |
2087 | const struct GNUNET_MessageHeader * temp_hdr = NULL; | 2381 | const struct GNUNET_MessageHeader * temp_hdr = NULL; |
2088 | 2382 | ||
2383 | int datasize = 0; | ||
2089 | int pos = 0; | 2384 | int pos = 0; |
2090 | 2385 | ||
2091 | |||
2092 | if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA) | 2386 | if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA) |
2093 | { | 2387 | { |
2094 | #if DEBUG_wlan | 2388 | #if DEBUG_wlan |
2095 | GNUNET_log( | 2389 | GNUNET_log( |
2096 | GNUNET_ERROR_TYPE_DEBUG, | 2390 | GNUNET_ERROR_TYPE_DEBUG, |
2097 | "Func wlan_process_helper got GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA size: %i\n", | 2391 | "Func wlan_process_helper got GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA size: %u\n", |
2098 | ntohs(hdr->size)); | 2392 | ntohs(hdr->size)); |
2099 | #endif | 2393 | #endif |
2100 | 2394 | ||
2101 | //call wlan_process_helper with the message inside, later with wlan: analyze signal | 2395 | //call wlan_process_helper with the message inside, later with wlan: analyze signal |
2102 | GNUNET_assert(ntohs(hdr->size) >= sizeof(struct IeeeHeader)); | 2396 | GNUNET_assert(ntohs(hdr->size) >= sizeof(struct IeeeHeader) + sizeof(struct GNUNET_MessageHeader)); |
2103 | wlanIeeeHeader = (struct IeeeHeader *) &hdr[1]; | 2397 | wlanIeeeHeader = (struct IeeeHeader *) &hdr[1]; |
2398 | datasize = ntohs(hdr->size) - sizeof(struct IeeeHeader) | ||
2399 | - sizeof(struct GNUNET_MessageHeader); | ||
2104 | 2400 | ||
2105 | session_light = GNUNET_malloc(sizeof(struct Session_light)); | 2401 | session_light = GNUNET_malloc(sizeof(struct Session_light)); |
2106 | memcpy(session_light->addr, &(wlanIeeeHeader->mac3), sizeof(struct MacAddress)); | 2402 | memcpy(session_light->addr, &(wlanIeeeHeader->mac3), |
2403 | sizeof(struct MacAddress)); | ||
2107 | session_light->session = search_session(plugin, session_light->addr); | 2404 | session_light->session = search_session(plugin, session_light->addr); |
2108 | 2405 | ||
2109 | //process only if it is an broadcast or for this computer both with the gnunet bssid | 2406 | //process only if it is an broadcast or for this computer both with the gnunet bssid |
2407 | |||
2110 | //check for bssid | 2408 | //check for bssid |
2111 | if (memcmp(&(wlanIeeeHeader->mac2), macbc, sizeof(struct MacAddress))) | 2409 | if (memcmp(&(wlanIeeeHeader->mac2), macbc, sizeof(struct MacAddress)) |
2410 | == 0) | ||
2112 | { | 2411 | { |
2113 | //check for broadcast or mac | 2412 | //check for broadcast or mac |
2114 | if (memcmp(&(wlanIeeeHeader->mac1), bc_all_mac, sizeof(struct MacAddress)) | 2413 | if (memcmp(&(wlanIeeeHeader->mac1), bc_all_mac, |
2115 | || memcmp(&(wlanIeeeHeader->mac1), &(plugin->mac_address), | 2414 | sizeof(struct MacAddress) == 0) || memcmp( |
2116 | sizeof(struct MacAddress))) | 2415 | &(wlanIeeeHeader->mac1), &(plugin->mac_address), |
2416 | sizeof(struct MacAddress)) == 0) | ||
2117 | { | 2417 | { |
2118 | // process the inner data | 2418 | // process the inner data |
2119 | pos = 0; | 2419 | pos = 0; |
2120 | temp_hdr = (struct GNUNET_MessageHeader *) &wlanIeeeHeader[1]; | 2420 | temp_hdr = (struct GNUNET_MessageHeader *) &wlanIeeeHeader[1]; |
2121 | while (pos < hdr->size) | 2421 | while (pos < datasize) |
2122 | { | 2422 | { |
2423 | temp_hdr = (struct GNUNET_MessageHeader *) &wlanIeeeHeader[1] | ||
2424 | + pos; | ||
2425 | |||
2123 | wlan_data_helper(plugin, session_light, temp_hdr); | 2426 | wlan_data_helper(plugin, session_light, temp_hdr); |
2124 | pos += temp_hdr->size + sizeof(struct GNUNET_MessageHeader); | 2427 | pos += ntohs(temp_hdr->size); |
2428 | |||
2125 | } | 2429 | } |
2126 | } | 2430 | } |
2431 | else | ||
2432 | { | ||
2433 | #if DEBUG_wlan | ||
2434 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
2435 | "Func wlan_process_helper got wrong MAC: %s\n", | ||
2436 | wlanIeeeHeader->mac1); | ||
2437 | #endif | ||
2438 | } | ||
2439 | } | ||
2440 | else | ||
2441 | { | ||
2442 | #if DEBUG_wlan | ||
2443 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, | ||
2444 | "Func wlan_process_helper got wrong BSSID: %s\n", | ||
2445 | wlanIeeeHeader->mac2); | ||
2446 | #endif | ||
2127 | } | 2447 | } |
2128 | 2448 | ||
2129 | //clean up | 2449 | //clean up |
@@ -2131,29 +2451,26 @@ wlan_process_helper (void *cls, | |||
2131 | 2451 | ||
2132 | } | 2452 | } |
2133 | 2453 | ||
2134 | |||
2135 | |||
2136 | else if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL) | 2454 | else if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL) |
2137 | { | 2455 | { |
2138 | 2456 | ||
2139 | |||
2140 | #if DEBUG_wlan | 2457 | #if DEBUG_wlan |
2141 | GNUNET_log( | 2458 | GNUNET_log( |
2142 | GNUNET_ERROR_TYPE_DEBUG, | 2459 | GNUNET_ERROR_TYPE_DEBUG, |
2143 | "Func wlan_process_helper got GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL size: %i\n", | 2460 | "Func wlan_process_helper got GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL size: %u\n", |
2144 | ntohs(hdr->size)); | 2461 | ntohs(hdr->size)); |
2145 | #endif | 2462 | #endif |
2146 | 2463 | ||
2147 | //TODO more control | 2464 | //TODO more control messages |
2148 | //TODO use struct wlan_helper_control | 2465 | //TODO use struct wlan_helper_control |
2149 | if (ntohs(hdr->size) == sizeof(struct Wlan_Helper_Control_Message)) | 2466 | if (ntohs(hdr->size) == sizeof(struct Wlan_Helper_Control_Message)) |
2150 | { | 2467 | { |
2151 | //plugin->mac_address = GNUNET_malloc(sizeof(struct MacAddress)); | 2468 | //plugin->mac_address = GNUNET_malloc(sizeof(struct MacAddress)); |
2152 | memcpy(&(plugin->mac_address), &hdr[1], sizeof(struct MacAddress)); | 2469 | memcpy(&(plugin->mac_address), &hdr[1], sizeof(struct MacAddress)); |
2153 | GNUNET_log( | 2470 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
2154 | GNUNET_ERROR_TYPE_DEBUG, | ||
2155 | "Notifying transport of address %s\n", | 2471 | "Notifying transport of address %s\n", |
2156 | wlan_plugin_address_to_string(cls, &(plugin->mac_address), ntohs(hdr->size) - sizeof(struct GNUNET_MessageHeader))); | 2472 | wlan_plugin_address_to_string(cls, &(plugin->mac_address), ntohs( |
2473 | hdr->size) - sizeof(struct GNUNET_MessageHeader))); | ||
2157 | plugin->env->notify_address(plugin->env->cls, "wlan", | 2474 | plugin->env->notify_address(plugin->env->cls, "wlan", |
2158 | &plugin->mac_address, sizeof(struct MacAddress), | 2475 | &plugin->mac_address, sizeof(struct MacAddress), |
2159 | GNUNET_TIME_UNIT_FOREVER_REL); | 2476 | GNUNET_TIME_UNIT_FOREVER_REL); |
@@ -2166,11 +2483,11 @@ wlan_process_helper (void *cls, | |||
2166 | 2483 | ||
2167 | } | 2484 | } |
2168 | 2485 | ||
2169 | |||
2170 | else | 2486 | else |
2171 | { | 2487 | { |
2172 | // TODO Wrong data? | 2488 | // TODO Wrong data? |
2173 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, "WLAN helper packet has not the right type\n"); | 2489 | GNUNET_log(GNUNET_ERROR_TYPE_INFO, |
2490 | "WLAN helper packet has not the right type\n"); | ||
2174 | return; | 2491 | return; |
2175 | } | 2492 | } |
2176 | } | 2493 | } |
@@ -2185,43 +2502,44 @@ wlan_process_helper (void *cls, | |||
2185 | */ | 2502 | */ |
2186 | 2503 | ||
2187 | static void | 2504 | static void |
2188 | wlan_plugin_helper_read (void *cls, | 2505 | wlan_plugin_helper_read(void *cls, |
2189 | const struct GNUNET_SCHEDULER_TaskContext *tc) | 2506 | const struct GNUNET_SCHEDULER_TaskContext *tc) |
2190 | { | 2507 | { |
2191 | struct Plugin *plugin = cls; | 2508 | struct Plugin *plugin = cls; |
2192 | plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK; | 2509 | plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK; |
2193 | 2510 | ||
2194 | #if DEBUG_wlan | 2511 | /* |
2195 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2512 | #if DEBUG_wlan |
2196 | "Start reading from STDIN\n"); | 2513 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, |
2197 | #endif | 2514 | "Start reading from STDIN\n"); |
2198 | 2515 | #endif | |
2516 | */ | ||
2199 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) | 2517 | if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN) |
2200 | return; | 2518 | return; |
2201 | 2519 | ||
2202 | char mybuf[WLAN_MTU + sizeof(struct GNUNET_MessageHeader)]; | 2520 | char mybuf[WLAN_MTU + sizeof(struct GNUNET_MessageHeader)]; |
2203 | ssize_t bytes; | 2521 | ssize_t bytes; |
2204 | 2522 | ||
2205 | bytes = GNUNET_DISK_file_read (plugin->server_stdout_handle, | 2523 | bytes = GNUNET_DISK_file_read(plugin->server_stdout_handle, mybuf, |
2206 | mybuf, sizeof(mybuf)); | 2524 | sizeof(mybuf)); |
2207 | if (bytes <= 0) | 2525 | if (bytes <= 0) |
2208 | { | 2526 | { |
2209 | #if DEBUG_wlan | 2527 | #if DEBUG_wlan |
2210 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2528 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
2211 | _("Finished reading from wlan-helper stdout with code: %d\n"), bytes); | 2529 | _("Finished reading from wlan-helper stdout with code: %d\n"), |
2530 | bytes); | ||
2212 | #endif | 2531 | #endif |
2213 | return; | 2532 | return; |
2214 | } | 2533 | } |
2215 | GNUNET_SERVER_mst_receive(plugin->consoltoken, NULL, | 2534 | GNUNET_SERVER_mst_receive(plugin->consoltoken, NULL, mybuf, bytes, GNUNET_NO, |
2216 | mybuf, bytes, GNUNET_NO, GNUNET_NO); | 2535 | GNUNET_NO); |
2217 | 2536 | ||
2218 | GNUNET_assert(plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK); | 2537 | GNUNET_assert(plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK); |
2219 | plugin->server_read_task = | 2538 | plugin->server_read_task = GNUNET_SCHEDULER_add_read_file( |
2220 | GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL, | 2539 | GNUNET_TIME_UNIT_FOREVER_REL, plugin->server_stdout_handle, |
2221 | plugin->server_stdout_handle, &wlan_plugin_helper_read, plugin); | 2540 | &wlan_plugin_helper_read, plugin); |
2222 | } | 2541 | } |
2223 | 2542 | ||
2224 | |||
2225 | /** | 2543 | /** |
2226 | * Start the gnunet-wlan-helper process. | 2544 | * Start the gnunet-wlan-helper process. |
2227 | * | 2545 | * |
@@ -2242,18 +2560,19 @@ wlan_transport_start_wlan_helper(struct Plugin *plugin, int testmode) | |||
2242 | return GNUNET_SYSERR; | 2560 | return GNUNET_SYSERR; |
2243 | 2561 | ||
2244 | #if DEBUG_wlan | 2562 | #if DEBUG_wlan |
2245 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2563 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
2246 | "Starting gnunet-wlan-helper process cmd: %s %s %i\n", filename, plugin->interface, testmode); | 2564 | "Starting gnunet-wlan-helper process cmd: %s %s %i\n", filename, |
2565 | plugin->interface, testmode); | ||
2247 | #endif | 2566 | #endif |
2248 | /* Start the server process */ | 2567 | /* Start the server process */ |
2249 | 2568 | ||
2250 | |||
2251 | plugin->server_proc = GNUNET_OS_start_process(plugin->server_stdin, | 2569 | plugin->server_proc = GNUNET_OS_start_process(plugin->server_stdin, |
2252 | plugin->server_stdout, filename,filename, plugin->interface, ((testmode==1)?"1":(testmode==2)?"2":"0"), NULL); | 2570 | plugin->server_stdout, filename, filename, plugin->interface, ((testmode |
2571 | == 1) ? "1" : (testmode == 2) ? "2" : "0"), NULL); | ||
2253 | if (plugin->server_proc == NULL) | 2572 | if (plugin->server_proc == NULL) |
2254 | { | 2573 | { |
2255 | #if DEBUG_wlan | 2574 | #if DEBUG_wlan |
2256 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2575 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
2257 | "Failed to start gnunet-wlan-helper process\n"); | 2576 | "Failed to start gnunet-wlan-helper process\n"); |
2258 | #endif | 2577 | #endif |
2259 | return GNUNET_SYSERR; | 2578 | return GNUNET_SYSERR; |
@@ -2273,7 +2592,7 @@ wlan_transport_start_wlan_helper(struct Plugin *plugin, int testmode) | |||
2273 | GNUNET_assert(plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK); | 2592 | GNUNET_assert(plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK); |
2274 | 2593 | ||
2275 | #if DEBUG_wlan | 2594 | #if DEBUG_wlan |
2276 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2595 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
2277 | "Adding server_read_task for the wlan-helper\n"); | 2596 | "Adding server_read_task for the wlan-helper\n"); |
2278 | #endif | 2597 | #endif |
2279 | 2598 | ||
@@ -2286,27 +2605,27 @@ wlan_transport_start_wlan_helper(struct Plugin *plugin, int testmode) | |||
2286 | return GNUNET_YES; | 2605 | return GNUNET_YES; |
2287 | } | 2606 | } |
2288 | 2607 | ||
2289 | |||
2290 | /** | 2608 | /** |
2291 | * Exit point from the plugin. | 2609 | * Exit point from the plugin. |
2610 | * @param cls pointer to the api struct | ||
2292 | */ | 2611 | */ |
2293 | //TODO doxigen | 2612 | |
2294 | //FIXME cleanup | 2613 | //FIXME cleanup |
2295 | void * | 2614 | void * |
2296 | libgnunet_plugin_transport_wlan_done (void *cls) | 2615 | libgnunet_plugin_transport_wlan_done(void *cls) |
2297 | { | 2616 | { |
2298 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; | 2617 | struct GNUNET_TRANSPORT_PluginFunctions *api = cls; |
2299 | struct Plugin *plugin = api->cls; | 2618 | struct Plugin *plugin = api->cls; |
2300 | 2619 | ||
2301 | #if DEBUG_wlan | 2620 | #if DEBUG_wlan |
2302 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2621 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, |
2303 | "libgnunet_plugin_transport_wlan_done started\n"); | 2622 | "libgnunet_plugin_transport_wlan_done started\n"); |
2304 | #endif | 2623 | #endif |
2305 | 2624 | ||
2306 | GNUNET_assert(cls !=NULL); | 2625 | GNUNET_assert(cls !=NULL); |
2307 | 2626 | ||
2308 | if (plugin->consoltoken != NULL) | 2627 | if (plugin->consoltoken != NULL) |
2309 | GNUNET_SERVER_mst_destroy(plugin->consoltoken); | 2628 | GNUNET_SERVER_mst_destroy(plugin->consoltoken); |
2310 | 2629 | ||
2311 | GNUNET_free_non_null(plugin->interface); | 2630 | GNUNET_free_non_null(plugin->interface); |
2312 | GNUNET_free (plugin); | 2631 | GNUNET_free (plugin); |
@@ -2321,13 +2640,13 @@ libgnunet_plugin_transport_wlan_done (void *cls) | |||
2321 | * @return the 'struct GNUNET_TRANSPORT_PluginFunctions*' or NULL on error | 2640 | * @return the 'struct GNUNET_TRANSPORT_PluginFunctions*' or NULL on error |
2322 | */ | 2641 | */ |
2323 | void * | 2642 | void * |
2324 | libgnunet_plugin_transport_wlan_init (void *cls) | 2643 | libgnunet_plugin_transport_wlan_init(void *cls) |
2325 | { | 2644 | { |
2326 | //struct GNUNET_SERVICE_Context *service; | 2645 | //struct GNUNET_SERVICE_Context *service; |
2327 | struct GNUNET_TRANSPORT_PluginEnvironment *env = cls; | 2646 | struct GNUNET_TRANSPORT_PluginEnvironment *env = cls; |
2328 | struct GNUNET_TRANSPORT_PluginFunctions *api; | 2647 | struct GNUNET_TRANSPORT_PluginFunctions *api; |
2329 | struct Plugin *plugin; | 2648 | struct Plugin *plugin; |
2330 | static unsigned long long testmode =0; | 2649 | static unsigned long long testmode = 0; |
2331 | 2650 | ||
2332 | GNUNET_assert(cls !=NULL); | 2651 | GNUNET_assert(cls !=NULL); |
2333 | 2652 | ||
@@ -2339,26 +2658,27 @@ libgnunet_plugin_transport_wlan_init (void *cls) | |||
2339 | plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK; | 2658 | plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK; |
2340 | plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK; | 2659 | plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK; |
2341 | 2660 | ||
2661 | set_next_beacon_time(plugin); | ||
2342 | 2662 | ||
2343 | if (GNUNET_CONFIGURATION_have_value(env->cfg, "transport-wlan", "TESTMODE")) | 2663 | if (GNUNET_CONFIGURATION_have_value(env->cfg, "transport-wlan", "TESTMODE")) |
2344 | { | 2664 | { |
2345 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number(env->cfg, "transport-wlan", | 2665 | if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number(env->cfg, |
2346 | "TESTMODE", &testmode)) | 2666 | "transport-wlan", "TESTMODE", &testmode)) |
2347 | return NULL; | 2667 | return NULL; |
2348 | } | 2668 | } |
2349 | 2669 | ||
2350 | if (GNUNET_CONFIGURATION_have_value(env->cfg, | 2670 | if (GNUNET_CONFIGURATION_have_value(env->cfg, "transport-wlan", "INTERFACE")) |
2351 | "transport-wlan", "INTERFACE")) | 2671 | { |
2352 | { | 2672 | if (GNUNET_CONFIGURATION_get_value_string(env->cfg, "transport-wlan", |
2353 | if (GNUNET_CONFIGURATION_get_value_string (env->cfg, | 2673 | "INTERFACE", &(plugin->interface)) != GNUNET_YES) |
2354 | "transport-wlan","INTERFACE", &(plugin->interface)) != GNUNET_YES){ | 2674 | { |
2355 | libgnunet_plugin_transport_wlan_done(plugin); | 2675 | libgnunet_plugin_transport_wlan_done(plugin); |
2356 | return NULL; | 2676 | return NULL; |
2357 | } | 2677 | } |
2358 | } | 2678 | } |
2359 | 2679 | ||
2360 | wlan_transport_start_wlan_helper(plugin, testmode); | 2680 | wlan_transport_start_wlan_helper(plugin, testmode); |
2361 | plugin->consoltoken = GNUNET_SERVER_mst_create(&wlan_process_helper,plugin); | 2681 | plugin->consoltoken = GNUNET_SERVER_mst_create(&wlan_process_helper, plugin); |
2362 | 2682 | ||
2363 | //plugin->sessions = GNUNET_malloc (sizeof (struct Sessionqueue)); | 2683 | //plugin->sessions = GNUNET_malloc (sizeof (struct Sessionqueue)); |
2364 | //plugin->pending_Sessions = GNUNET_malloc (sizeof (struct Sessionqueue)); | 2684 | //plugin->pending_Sessions = GNUNET_malloc (sizeof (struct Sessionqueue)); |
@@ -2371,12 +2691,10 @@ libgnunet_plugin_transport_wlan_init (void *cls) | |||
2371 | api->check_address = &wlan_plugin_address_suggested; | 2691 | api->check_address = &wlan_plugin_address_suggested; |
2372 | api->address_to_string = &wlan_plugin_address_to_string; | 2692 | api->address_to_string = &wlan_plugin_address_to_string; |
2373 | 2693 | ||
2374 | |||
2375 | start_next_message_id(); | 2694 | start_next_message_id(); |
2376 | 2695 | ||
2377 | #if DEBUG_wlan | 2696 | #if DEBUG_wlan |
2378 | GNUNET_log (GNUNET_ERROR_TYPE_DEBUG, | 2697 | GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "wlan init finished\n"); |
2379 | "wlan init finished\n"); | ||
2380 | #endif | 2698 | #endif |
2381 | 2699 | ||
2382 | return api; | 2700 | return api; |