2 This file is part of GNUnet
3 (C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Christian Grothoff (and other contributing authors)
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
7 by the Free Software Foundation; either version 3, or (at your
8 option) any later version.
10 GNUnet is distributed in the hope that it will be useful, but
11 WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 General Public License for more details.
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
17 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA.
22 * @file transport/plugin_transport_wlan.c
23 * @brief transport plugin for wlan
24 * @author David Brodski
28 #include "gnunet_hello_lib.h"
29 #include "gnunet_protocols.h"
30 #include "gnunet_util_lib.h"
31 #include "gnunet_statistics_service.h"
32 #include "gnunet_transport_service.h"
33 #include "gnunet_transport_plugin.h"
34 #include "plugin_transport_wlan.h"
35 #include "gnunet_common.h"
36 #include "gnunet_crypto_lib.h"
38 #define PROTOCOL_PREFIX "wlan"
41 * Max size of packet from helper
46 * Time until retransmission of a fragment in ms
48 #define FRAGMENT_TIMEOUT GNUNET_TIME_UNIT_SECONDS
50 #define FRAGMENT_QUEUE_SIZE 10
52 #define HALLO_BEACON_SCALING_FACTOR 900
54 #define DEBUG_wlan GNUNET_NO
56 #define MESSAGE_LENGHT_UNKNOWN -1
57 #define NO_MESSAGE_OR_MESSAGE_FINISHED -2
60 * After how long do we expire an address that we
61 * learned from another peer if it is not reconfirmed
64 #define LEARNED_ADDRESS_EXPIRATION GNUNET_TIME_relative_multiply (GNUNET_TIME_UNIT_HOURS, 6)
67 * Initial handshake message for a session.
72 * Type is GNUNET_MESSAGE_TYPE_TRANSPORT_TCP_WELCOME.
74 struct GNUNET_MessageHeader header;
77 * Identit*mac_y of the node connecting (TCP client)
79 struct GNUNET_PeerIdentity clientIdentity;
84 * Encapsulation of all of the state of the plugin.
91 struct GNUNET_TRANSPORT_PluginEnvironment *env;
94 * List of open sessions. head
96 struct Sessionqueue *sessions;
99 * List of open sessions. tail
101 struct Sessionqueue *sessions_tail;
110 * encapsulation of data from the local wlan helper program
113 struct GNUNET_SERVER_MessageStreamTokenizer * suid_tokenizer;
116 * encapsulation of packets received
119 struct GNUNET_SERVER_MessageStreamTokenizer * data_tokenizer;
122 * stdout pipe handle for the gnunet-wlan-helper process
124 struct GNUNET_DISK_PipeHandle *server_stdout;
127 * stdout file handle for the gnunet-wlan-helper process
129 const struct GNUNET_DISK_FileHandle *server_stdout_handle;
132 * stdin pipe handle for the gnunet-wlan-helper process
134 struct GNUNET_DISK_PipeHandle *server_stdin;
137 * stdin file handle for the gnunet-wlan-helper process
139 const struct GNUNET_DISK_FileHandle *server_stdin_handle;
142 * ID of the gnunet-wlan-server std read task
144 GNUNET_SCHEDULER_TaskIdentifier server_read_task;
147 * ID of the gnunet-wlan-server std read task
149 GNUNET_SCHEDULER_TaskIdentifier server_write_task;
152 * ID of the delay task for writing
154 GNUNET_SCHEDULER_TaskIdentifier server_write_delay_task;
157 * The process id of the wlan process
159 struct GNUNET_OS_Process *server_proc;
162 * The interface of the wlan card given to us by the user.
167 * The mac_address of the wlan card given to us by the helper.
169 struct MacAddress mac_address;
172 * Sessions currently pending for transmission
173 * to this peer, if any.
175 struct Sessionqueue * pending_Sessions;
178 * Sessions currently pending for transmission
179 * to this peer (tail), if any.
181 struct Sessionqueue * pending_Sessions_tail;
184 * number of pending sessions
186 unsigned int pendingsessions;
189 * Messages in the fragmentation queue, head
192 struct FragmentMessage * pending_Fragment_Messages_head;
195 * Messages in the fragmentation queue, tail
198 struct FragmentMessage * pending_Fragment_Messages_tail;
201 * number of pending fragment message
204 unsigned int pending_fragment_messages;
207 * time of the next "hello-beacon"
210 struct GNUNET_TIME_Absolute beacon_time;
213 * queue to send acks for received fragments
216 struct AckSendQueue * ack_send_queue_head;
218 struct AckSendQueue * ack_send_queue_tail;
224 struct Plugin * plugin;
226 struct GNUNET_MessageHeader * msgstart;
231 * Queue of sessions, for the general session queue and the pending session queue
236 struct Sessionqueue * next;
237 struct Sessionqueue * prev;
238 struct Session * content;
242 * Queue of ack received for messages send
247 struct AckQueue * next;
248 struct AckQueue * prev;
249 int fragment_num; //TODO change it to offset if better
253 * Queue for the fragments received
258 struct RecQueue * next;
259 struct RecQueue * prev;
266 * Information kept for each message that is yet to
269 struct PendingMessage
273 * The pending message
278 * Size of the message
283 * Continuation function to call once the message
284 * has been sent. Can be NULL if there is no
285 * continuation to call.
287 GNUNET_TRANSPORT_TransmitContinuation transmit_cont;
290 * Cls for transmit_cont
292 void * transmit_cont_cls;
295 * Timeout value for the pending message.
297 struct GNUNET_TIME_Absolute timeout;
302 * Queue for acks to send for fragments recived
308 struct AckSendQueue * next;
309 struct AckSendQueue * prev;
311 struct Session * session;
313 * ID of message, to distinguish between the messages, picked randomly.
315 uint32_t message_id GNUNET_PACKED;
318 * Offset or number of this fragment, for fragmentation/segmentation (design choice, TBD)
320 uint16_t fragment_off_or_num GNUNET_PACKED;
325 * Session infos gathered from a messages
331 * the session this message belongs to
333 struct Session * session;
341 * Session handle for connections.
349 struct SessionHeader header;
352 * Pointer to the global plugin struct.
354 struct Plugin *plugin;
357 * Message currently pending for transmission
358 * to this peer, if any.
360 struct PendingMessage *pending_message;
363 * To whom are we talking to (set to our identity
364 * if we are still waiting for the welcome message)
366 struct GNUNET_PeerIdentity target;
369 * encapsulation of the receive data
371 //struct GNUNET_SERVER_MessageStreamTokenizer * receive_token;
374 * offset of the next fragment for the receive_token, -1 means last message finished
380 * size of the message received,
381 * MESSAGE_LENGHT_UNKNOWN means that the size is not known,
382 * NO_MESSAGE_OR_MESSAGE_FINISHED means no message received
388 * Sorted queue with the fragments received; head
391 struct RecQueue * frag_head;
394 * Sorted queue with the fragments received; tail
397 struct RecQueue * frag_tail;
405 * Address of the other peer (either based on our 'connect'
406 * call or on our 'accept' call).
411 * Last activity on this connection. Used to select preferred
414 struct GNUNET_TIME_Absolute last_activity;
417 * current number for message incoming, to distinguish between the messages
419 uint32_t message_id_in;
422 * current number for message outgoing, to distinguish between the messages
424 uint32_t message_id_out;
427 * does this session have a message in the fragment queue
435 * Struct for Messages in the fragment queue
438 struct FragmentMessage
441 * Session this message belongs to
444 struct Session *session;
447 * This is a doubly-linked list.
449 struct FragmentMessage *next;
452 * This is a doubly-linked list.
454 struct FragmentMessage *prev;
457 * The pending message
462 * Timeout value for the pending message.
464 struct GNUNET_TIME_Absolute timeout;
467 * Timeout value for the pending fragments.
468 * Stores the time when the next msg fragment ack has to be received
470 struct GNUNET_TIME_Absolute next_ack;
473 * Sorted queue with the acks received for fragments; head
476 struct AckQueue * head;
479 * Sorted queue with the acks received for fragments; tail
482 struct AckQueue * tail;
485 * Size of the message
490 * pos / next fragment number in the message, for fragmentation/segmentation,
491 * some acks can be missing but there is still time
493 uint32_t message_pos;
498 * Header for messages which need fragmentation
503 struct GNUNET_MessageHeader header;
506 * checksum/error correction
508 uint32_t crc GNUNET_PACKED;
511 * To whom are we talking to (set to our identity
512 * if we are still waiting for the welcome message)
514 struct GNUNET_PeerIdentity target;
516 // followed by payload
521 * Header for messages which need fragmentation
523 struct FragmentationHeader
526 struct GNUNET_MessageHeader header;
529 * To whom are we talking to (set to our identity
530 * if we are still waiting for the welcome message)
532 // struct GNUNET_PeerIdentity target GNUNET_PACKED;
535 * ID of message, to distinguish between the messages, picked randomly.
537 uint32_t message_id GNUNET_PACKED;
540 * Offset or number of this fragment, for fragmentation/segmentation (design choice, TBD)
542 uint16_t fragment_off_or_num GNUNET_PACKED;
545 * CRC of fragment (for error checking)
547 uint16_t message_crc GNUNET_PACKED;
551 * // 0x1 ack => Use two different message types in header.type! (FRAG_MESSAGE; FRAG_ACK)
552 * // 0x2 has data (not only ack)
553 * // 0x4 last fragment of message
556 // uint32_t flags GNUNET_PACKED;
559 * checksum/error correction
561 // uint32_t crc GNUNET_PACKED;
563 // followed by payload unless ACK
568 getRadiotapHeader(struct RadiotapHeader * Header);
571 getWlanHeader(struct IeeeHeader * Header,const char * to_mac_addr,
572 struct Plugin * plugin);
575 wlan_plugin_address_suggested(void *cls, const void *addr, size_t addrlen);
578 getcrc16(const char *msgbuf, size_t msgbuf_size);
581 do_transmit(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
584 check_fragment_queue(struct Plugin * plugin);
587 getcrc32(const char *msgbuf, size_t msgbuf_size);
590 free_rec_frag_queue(struct Session * session);
593 wlan_data_helper(void *cls, struct Session_light * session_light,
594 const struct GNUNET_MessageHeader * hdr);
597 wlan_process_helper(void *cls, void *client,
598 const struct GNUNET_MessageHeader *hdr);
601 finish_sending(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
604 wlan_data_massage_handler(struct Plugin * plugin,
605 struct Session_light * session_light,
606 const struct GNUNET_MessageHeader * hdr);
609 wlan_plugin_address_to_string(void *cls, const void *addr, size_t addrlen);
612 * get the next message number, at the moment just a random one
613 * @return returns the next valid message-number for sending packets
616 get_next_message_id()
618 return GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
622 * start next message number generator
623 * (not necessary at the moment)
626 start_next_message_id()
628 //GNUNET_CRYPTO_random_init;
632 * search for a session with the addr
634 * @param plugin pointer to the plugin struct
635 * @param addr pointer to the mac address of the peer
636 * @return returns the session
639 static struct Session *
640 search_session(struct Plugin *plugin, const uint8_t * addr)
642 struct Sessionqueue * queue = plugin->sessions;
643 struct Sessionqueue * lastitem = NULL;
645 //just look at all the session for the needed one
646 while (queue != NULL)
648 // content is never NULL
649 GNUNET_assert (queue->content != NULL);
650 char * addr2 = queue->content->addr;
651 if (memcmp(addr, addr2, 6) == 0)
654 return queue->content;
664 * create a new session
666 * @param plugin pointer to the plugin struct
667 * @param addr pointer to the mac address of the peer
668 * @return returns the session
671 static struct Session *
672 create_session(struct Plugin *plugin, const uint8_t * addr)
674 struct Sessionqueue * queue = GNUNET_malloc (sizeof (struct Sessionqueue));
676 GNUNET_CONTAINER_DLL_insert_tail(plugin->sessions, plugin->sessions_tail, queue);
678 queue->content = GNUNET_malloc (sizeof (struct Session));
679 queue->content->plugin = plugin;
680 memcpy(queue->content->addr, addr, 6);
681 queue->content->message_id_out = get_next_message_id();
682 queue->content->has_fragment = 0;
683 queue->content->rec_size = NO_MESSAGE_OR_MESSAGE_FINISHED;
685 plugin->session_count++;
688 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
689 "New session %p with %s\n", queue->content ,wlan_plugin_address_to_string(NULL,addr, 6));
692 return queue->content;
696 * get Session from address, create if no session exists
698 * @param plugin pointer to the plugin struct
699 * @param addr pointer to the mac address of the peer
700 * @return returns the session
702 //TODO add other possibilities to find the right session (are there other?)
703 static struct Session *
704 get_Session(struct Plugin *plugin, const uint8_t * addr)
706 struct Session * session = search_session(plugin, addr);
712 return create_session(plugin, addr);
714 /* -- not needed, layer above already has it--
715 //queue welcome message for new sessions, not realy needed
716 //struct WelcomeMessage welcome;
717 struct PendingMessage *pm;
718 pm = GNUNET_malloc (sizeof (struct PendingMessage));
719 pm->msg = GNUNET_malloc(GNUNET_HELLO_size(* (plugin->env->our_hello)));
720 pm->message_size = GNUNET_HELLO_size(* (plugin->env->our_hello));
721 //welcome.header.size = htons (GNUNET_HELLO_size(* (plugin->env->our_hello)));
722 //welcome.header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT);
723 //welcome.clientIdentity = *plugin->env->my_identity;
724 memcpy ( (pm->msg), * plugin->env->our_hello, GNUNET_HELLO_size(* (plugin->env->our_hello)));
725 pm->timeout = GNUNET_TIME_UNIT_FOREVER_ABS;
726 queue->content->pending_message = pm;
727 plugin->pendingsessions ++;
728 GNUNET_CONTAINER_DLL_insert_tail(plugin->pending_Sessions, plugin->pending_Sessions_tail, queue);
730 check_fragment_queue(plugin);
735 * Queue the session to send data
739 queue_Session(struct Plugin *plugin, struct Session * session)
741 struct Sessionqueue * queue = plugin->pending_Sessions;
742 struct Sessionqueue * lastitem = NULL;
744 while (queue != NULL)
746 // content is never NULL
747 GNUNET_assert (queue->content != NULL);
748 // is session already in queue?
749 if (session == queue->content)
758 // Session is not in the queue
760 queue = GNUNET_malloc (sizeof (struct Sessionqueue));
761 queue->content = session;
764 GNUNET_CONTAINER_DLL_insert_after (plugin->pending_Sessions,
765 plugin->pending_Sessions_tail,
766 plugin->pending_Sessions_tail, queue);
767 plugin->pendingsessions++;
773 free_acks(struct FragmentMessage * fm)
775 struct AckQueue * fq;
776 while (fm->head != NULL)
779 GNUNET_CONTAINER_DLL_remove(fm->head, fm->tail, fq);
789 * Function to schedule the write task, executed after a delay
792 delay_fragment_task(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
794 struct Plugin * plugin = cls;
795 plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK;
797 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
800 // GNUNET_TIME_UNIT_FOREVER_REL is needed to clean up old msg
801 if (plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK)
803 plugin->server_write_task = GNUNET_SCHEDULER_add_write_file(
804 GNUNET_TIME_UNIT_FOREVER_REL, plugin->server_stdin_handle,
805 &do_transmit, plugin);
811 * Function to calculate the time of the next periodic "hello-beacon"
814 set_next_beacon_time(struct Plugin * const plugin)
816 //under 10 known peers: once a second
817 if (plugin->session_count < 10)
819 plugin->beacon_time = GNUNET_TIME_absolute_add(
820 GNUNET_TIME_absolute_get(), GNUNET_TIME_relative_multiply(
821 GNUNET_TIME_UNIT_SECONDS, HALLO_BEACON_SCALING_FACTOR));
823 //under 30 known peers: every 10 seconds
824 else if (plugin->session_count < 30)
826 plugin->beacon_time = GNUNET_TIME_absolute_add(
827 GNUNET_TIME_absolute_get(), GNUNET_TIME_relative_multiply(
828 GNUNET_TIME_UNIT_SECONDS, 10 * HALLO_BEACON_SCALING_FACTOR));
830 //over 30 known peers: once a minute
833 plugin->beacon_time = GNUNET_TIME_absolute_add(
834 GNUNET_TIME_absolute_get(), GNUNET_TIME_relative_multiply(
835 GNUNET_TIME_UNIT_MINUTES, HALLO_BEACON_SCALING_FACTOR));
840 struct GNUNET_TIME_Relative
841 get_next_frag_timeout(struct FragmentMessage * fm)
843 return GNUNET_TIME_relative_min(GNUNET_TIME_absolute_get_remaining(
844 fm->next_ack), GNUNET_TIME_absolute_get_remaining(fm->timeout));
849 * Function to get the timeout value for acks for this session
852 struct GNUNET_TIME_Relative
853 get_ack_timeout(struct FragmentMessage * fm)
855 return FRAGMENT_TIMEOUT;
859 * Function to set the timer for the next timeout of the fragment queue
860 * @param plugin the handle to the plugin struct
863 check_next_fragment_timeout(struct Plugin * const plugin)
865 struct FragmentMessage * fm;
866 struct GNUNET_TIME_Relative next_send;
868 next_send = GNUNET_TIME_absolute_get_remaining(plugin->beacon_time);
871 if (plugin->server_write_delay_task != GNUNET_SCHEDULER_NO_TASK)
873 GNUNET_SCHEDULER_cancel(plugin->server_write_delay_task);
874 plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK;
876 fm = plugin->pending_Fragment_Messages_head;
878 GNUNET_assert(plugin->server_write_delay_task == GNUNET_SCHEDULER_NO_TASK);
880 //check if some acks are in the queue
881 if (plugin->ack_send_queue_head != NULL)
883 next_send = GNUNET_TIME_relative_get_zero();
885 //check if there are some fragments in the queue
889 = GNUNET_TIME_relative_min(next_send, get_next_frag_timeout(fm));
891 plugin->server_write_delay_task = GNUNET_SCHEDULER_add_delayed(next_send,
892 &delay_fragment_task, plugin);
897 * Function to get the next queued Session, removes the session from the queue
900 static struct Session *
901 get_next_queue_Session(struct Plugin * plugin)
903 struct Session * session;
904 struct Sessionqueue * sessionqueue;
905 struct Sessionqueue * sessionqueue_alt;
906 struct PendingMessage * pm;
907 sessionqueue = plugin->pending_Sessions;
908 while (sessionqueue != NULL)
910 session = sessionqueue->content;
911 pm = session->pending_message;
913 //check for message timeout
914 if (GNUNET_TIME_absolute_get_remaining(pm->timeout).rel_value > 0)
916 //check if session has no message in the fragment queue
917 if (!session->has_fragment)
919 plugin->pendingsessions--;
920 GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions,
921 plugin->pending_Sessions_tail, sessionqueue);
922 GNUNET_free(sessionqueue);
928 sessionqueue = sessionqueue->next;
934 session->pending_message = NULL;
935 //call the cont func that it did not work
936 if (pm->transmit_cont != NULL)
937 pm->transmit_cont(pm->transmit_cont_cls, &(session->target),
939 GNUNET_free(pm->msg);
942 sessionqueue_alt = sessionqueue;
943 sessionqueue = sessionqueue->next;
944 plugin->pendingsessions--;
945 GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions,
946 plugin->pending_Sessions_tail, sessionqueue_alt);
948 GNUNET_free(sessionqueue_alt);
957 * Function to sort the message into the message fragment queue
958 * @param plugin the plugin struct
959 * @param fm message to sort into the queue
962 sort_fragment_into_queue(struct Plugin * plugin, struct FragmentMessage * fm)
964 struct FragmentMessage * fm2;
965 //sort into the list at the right position
967 fm2 = plugin->pending_Fragment_Messages_head;
971 if (GNUNET_TIME_absolute_get_difference(fm2->next_ack, fm->next_ack).rel_value
982 GNUNET_CONTAINER_DLL_insert_after(plugin->pending_Fragment_Messages_head,
983 plugin->pending_Fragment_Messages_tail,fm2,fm);
987 * frees the space of a message in the fragment queue (send queue)
988 * @param plugin the plugin struct
989 * @param fm message to free
992 free_fragment_message(struct Plugin * plugin, struct FragmentMessage * fm)
997 GNUNET_free_non_null(fm->msg);
998 GNUNET_CONTAINER_DLL_remove (plugin->pending_Fragment_Messages_head,
999 plugin->pending_Fragment_Messages_tail, fm);
1001 plugin->pending_fragment_messages--;
1002 check_fragment_queue(plugin);
1005 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Pending fragment messages: %u\n", plugin->pending_fragment_messages);
1011 * Function to check if there is some space in the fragment queue
1012 * inserts a message if space is available
1013 * @param plugin the plugin struct
1017 check_fragment_queue(struct Plugin * plugin)
1019 struct Session * session;
1020 struct FragmentMessage * fm;
1021 struct GNUNET_PeerIdentity pid;
1023 struct PendingMessage * pm;
1025 if (plugin->pending_fragment_messages < FRAGMENT_QUEUE_SIZE)
1027 session = get_next_queue_Session(plugin);
1028 if (session != NULL)
1030 pm = session->pending_message;
1031 session->pending_message = NULL;
1032 session->has_fragment = 1;
1033 GNUNET_assert(pm != NULL);
1035 fm = GNUNET_malloc(sizeof(struct FragmentMessage));
1036 fm->message_size = pm->message_size;
1038 fm->session = session;
1039 fm->timeout.abs_value = pm->timeout.abs_value;
1040 fm->message_pos = 0;
1041 fm->next_ack = GNUNET_TIME_absolute_get();
1043 if (pm->transmit_cont != NULL) {
1044 pid = session->target;
1045 pm->transmit_cont(pm->transmit_cont_cls, &pid,
1048 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "called pm->transmit_cont for %p\n", session);
1054 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "no pm->transmit_cont for %p\n", session);
1059 sort_fragment_into_queue(plugin, fm);
1060 plugin->pending_fragment_messages++;
1062 //generate new message id
1063 session->message_id_out = get_next_message_id();
1065 //check if timeout changed
1066 check_next_fragment_timeout(plugin);
1072 * Funktion to check if all fragments where send and the acks received
1073 * frees the space if finished
1074 * @param plugin the plugin struct
1075 * @param fm the message to check
1078 check_finished_fragment(struct Plugin * plugin, struct FragmentMessage * fm)
1080 struct AckQueue * ack;
1083 if (fm->message_size >= (WLAN_MTU - sizeof(struct FragmentationHeader))
1084 * fm->tail->fragment_num)
1088 //check if all acks are present
1091 if (counter == ack->fragment_num)
1102 fm->session->has_fragment = 0;
1103 free_fragment_message(plugin, fm);
1106 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Finished a fragmented message\n");
1110 check_next_fragment_timeout(plugin);
1116 * Function to set the next fragment number
1117 * @param fm use this FragmentMessage
1121 set_next_message_fragment_pos(struct FragmentMessage * fm)
1123 struct AckQueue * akt = NULL;
1124 //check if retransmit is needed
1125 if (GNUNET_TIME_absolute_get_remaining(fm->next_ack).rel_value == 0)
1128 // be positive and try again later :-D
1129 fm->next_ack = GNUNET_TIME_relative_to_absolute(get_ack_timeout(fm));
1130 // find first missing fragment
1132 fm->message_pos = 0;
1136 //test if ack 0 (or X) was already received
1139 //if fragment is present, take next
1140 if (akt->fragment_num == fm->message_pos)
1144 //next ack is bigger then the fragment number
1145 //in case there is something like this: (acks) 1, 2, 5, 6, ...
1146 //and we send 3 again, the next number should be 4
1147 else if (akt->fragment_num > fm->message_pos)
1159 send_hello_beacon(struct Plugin * plugin)
1163 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Sending hello beacon\n");
1168 struct GNUNET_MessageHeader * msgheader = NULL;
1169 struct IeeeHeader * ieeewlanheader = NULL;
1170 struct RadiotapHeader * radioHeader = NULL;
1171 struct GNUNET_MessageHeader * msgheader2 = NULL;
1173 GNUNET_assert(sizeof(struct WlanHeader) + GNUNET_HELLO_size(
1174 *(plugin->env->our_hello)) <= WLAN_MTU);
1175 size = sizeof(struct GNUNET_MessageHeader) + sizeof(struct RadiotapHeader)
1176 + sizeof(struct IeeeHeader) + sizeof(struct GNUNET_MessageHeader)
1177 + GNUNET_HELLO_size(*(plugin->env->our_hello));
1179 msgheader = GNUNET_malloc(size);
1180 msgheader->size = htons(size);
1181 msgheader->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
1183 radioHeader = (struct RadiotapHeader*) &msgheader[1];
1184 getRadiotapHeader(radioHeader);
1185 ieeewlanheader = (struct IeeeHeader*) &radioHeader[1];
1186 getWlanHeader(ieeewlanheader, bc_all_mac, plugin);
1188 msgheader2 = (struct GNUNET_MessageHeader*) &ieeewlanheader[1];
1189 msgheader2->size = htons(GNUNET_HELLO_size(*(plugin->env->our_hello))
1190 + sizeof(struct GNUNET_MessageHeader));
1192 msgheader2->type = htons(GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT);
1193 memcpy(&msgheader2[1], *plugin->env->our_hello, GNUNET_HELLO_size(
1194 *(plugin->env->our_hello)));
1196 bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, msgheader, size);
1198 if (bytes == GNUNET_SYSERR)
1200 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1201 _("Error writing to wlan healper. errno == %d, ERROR: %s\n"),
1202 errno, strerror(errno));
1205 GNUNET_assert(bytes != GNUNET_SYSERR);
1206 GNUNET_assert(bytes == size);
1207 GNUNET_free(msgheader);
1209 set_next_beacon_time(plugin);
1210 check_next_fragment_timeout(plugin);
1214 send_ack(struct Plugin * plugin, struct AckSendQueue * ack)
1219 struct GNUNET_MessageHeader * msgheader = NULL;
1220 struct IeeeHeader * ieeewlanheader = NULL;
1221 struct RadiotapHeader * radioHeader = NULL;
1222 struct FragmentationHeader * msgheader2 = NULL;
1224 GNUNET_assert(sizeof(struct FragmentationHeader) <= WLAN_MTU);
1227 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1228 "Sending ack for message_id %u with fragment number %u\n",
1229 ack->message_id, ack->fragment_off_or_num);
1232 size = sizeof(struct GNUNET_MessageHeader) + sizeof(struct RadiotapHeader)
1233 + sizeof(struct IeeeHeader) + sizeof(struct FragmentationHeader);
1234 msgheader = GNUNET_malloc(size);
1235 msgheader->size = htons(size);
1236 msgheader->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
1238 radioHeader = (struct RadiotapHeader*) &msgheader[1];
1239 getRadiotapHeader(radioHeader);
1240 ieeewlanheader = (struct IeeeHeader*) &radioHeader[1];
1241 getWlanHeader(ieeewlanheader, ack->session->addr, plugin);
1243 msgheader2 = (struct FragmentationHeader*) &ieeewlanheader[1];
1244 msgheader2->header.size = htons(sizeof(struct FragmentationHeader));
1245 msgheader2->header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT_ACK);
1246 msgheader2->message_id = htonl(ack->message_id);
1247 msgheader2->fragment_off_or_num = htons(ack->fragment_off_or_num);
1249 bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, msgheader, size);
1250 if (bytes == GNUNET_SYSERR)
1252 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1253 _("Error writing to wlan healper. errno == %d, ERROR: %s\n"),
1254 errno, strerror(errno));
1257 GNUNET_assert(bytes != GNUNET_SYSERR);
1258 GNUNET_assert(bytes == size);
1259 GNUNET_free(msgheader);
1260 check_next_fragment_timeout(plugin);
1264 * Function called when wlan helper is ready to get some data
1266 * @param cls closure
1267 * @param tc GNUNET_SCHEDULER_TaskContext
1271 do_transmit(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1274 struct Plugin * plugin = cls;
1275 plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
1277 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
1280 struct Session * session = NULL;
1281 struct FragmentMessage * fm = NULL;
1282 struct IeeeHeader * ieeewlanheader = NULL;
1283 struct RadiotapHeader * radioHeader = NULL;
1284 struct GNUNET_MessageHeader * msgheader = NULL;
1286 struct FragmentationHeader fragheader;
1287 struct FragmentationHeader * fragheaderptr = NULL;
1288 struct Finish_send * finish = NULL;
1289 struct AckSendQueue * ack;
1292 const char * copystart = NULL;
1293 uint16_t copysize = 0;
1294 uint copyoffset = 0;
1296 if (plugin->ack_send_queue_head != NULL)
1298 ack = plugin->ack_send_queue_head;
1299 GNUNET_CONTAINER_DLL_remove(plugin->ack_send_queue_head,
1300 plugin->ack_send_queue_tail, ack);
1301 send_ack(plugin, ack);
1306 //test if a "hello-beacon" has to be send
1307 if (GNUNET_TIME_absolute_get_remaining(plugin->beacon_time).rel_value == 0)
1309 send_hello_beacon(plugin);
1315 fm = plugin->pending_Fragment_Messages_head;
1318 session = fm->session;
1319 GNUNET_assert(session != NULL);
1321 // test if message timed out
1322 if (GNUNET_TIME_absolute_get_remaining(fm->timeout).rel_value == 0)
1325 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "message timeout\n");
1328 GNUNET_assert(plugin->pending_fragment_messages > 0);
1329 plugin->pending_fragment_messages--;
1330 GNUNET_CONTAINER_DLL_remove(plugin->pending_Fragment_Messages_head,
1331 plugin->pending_Fragment_Messages_tail, fm);
1333 GNUNET_free(fm->msg);
1336 check_fragment_queue(plugin);
1341 //if (fm->message_size > WLAN_MTU)
1343 size += sizeof(struct FragmentationHeader);
1345 set_next_message_fragment_pos(fm);
1347 copyoffset = (WLAN_MTU - sizeof(struct FragmentationHeader))
1349 fragheader.fragment_off_or_num = htons(fm->message_pos);
1350 fragheader.message_id = htonl(session->message_id_out);
1351 GNUNET_assert(copyoffset < fm->message_size);
1352 copystart = fm->msg + copyoffset;
1353 copysize = GNUNET_MIN(fm->message_size - copyoffset,
1354 WLAN_MTU - sizeof(struct FragmentationHeader));
1355 fragheader.header.size = htons(copysize
1356 + sizeof(struct FragmentationHeader));
1357 fragheader.header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT);
1362 // there is no need to split
1363 copystart = fm->msg;
1364 copysize = fm->message_size;
1369 GNUNET_ERROR_TYPE_DEBUG,
1370 "Sending GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT with message_id %u with fragment number %i, size: %u, time until timeout %u\n",
1371 session->message_id_out, fm->message_pos, copysize
1372 + sizeof(struct FragmentationHeader),
1373 GNUNET_TIME_absolute_get_remaining(fm->timeout));
1377 size += sizeof(struct RadiotapHeader) + sizeof(struct IeeeHeader)
1378 + sizeof(struct GNUNET_MessageHeader);
1379 msgheader = GNUNET_malloc(size);
1380 msgheader->size = htons(size);
1381 msgheader->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
1383 radioHeader = (struct RadiotapHeader*) &msgheader[1];
1384 getRadiotapHeader(radioHeader);
1386 ieeewlanheader = (struct IeeeHeader *) &radioHeader[1];
1387 getWlanHeader(ieeewlanheader, fm->session->addr, plugin);
1389 //could be faster if content is just send and not copyed before
1390 //fragmentheader is needed
1391 //if (fm->message_size > WLAN_MTU)
1393 fragheader.message_crc = htons(getcrc16(copystart, copysize));
1394 memcpy(&ieeewlanheader[1], &fragheader,
1395 sizeof(struct FragmentationHeader));
1396 fragheaderptr = (struct FragmentationHeader *) &ieeewlanheader[1];
1397 memcpy(&fragheaderptr[1], copystart, copysize);
1401 memcpy(&ieeewlanheader[1], copystart, copysize);
1404 bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle,
1406 if (bytes == GNUNET_SYSERR)
1409 GNUNET_ERROR_TYPE_ERROR,
1410 _("Error writing to wlan healper. errno == %d, ERROR: %s\n"),
1411 errno, strerror(errno));
1414 GNUNET_assert(bytes != GNUNET_SYSERR);
1418 finish = GNUNET_malloc(sizeof( struct Finish_send));
1419 finish->plugin = plugin;
1420 finish->msgheader = (char *) msgheader + bytes;
1421 finish->size = size - bytes;
1422 finish->msgstart = msgheader;
1424 GNUNET_assert(plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK);
1426 plugin->server_write_task = GNUNET_SCHEDULER_add_write_file(
1427 GNUNET_TIME_UNIT_FOREVER_REL, plugin->server_stdin_handle,
1428 &finish_sending, finish);
1433 GNUNET_assert(bytes == size);
1435 GNUNET_free(msgheader);
1436 check_next_fragment_timeout(plugin);
1439 //check if this was the last fragment of this message, if true then queue at the end of the list
1440 if (copysize + copyoffset >= fm->message_size)
1442 GNUNET_assert(copysize + copyoffset == fm->message_size);
1444 GNUNET_CONTAINER_DLL_remove (plugin->pending_Fragment_Messages_head,
1445 plugin->pending_Fragment_Messages_tail, fm);
1447 GNUNET_CONTAINER_DLL_insert_tail(plugin->pending_Fragment_Messages_head,
1448 plugin->pending_Fragment_Messages_tail, fm);
1449 // if fragments have opimized timeouts
1450 //sort_fragment_into_queue(plugin,fm);
1457 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
1458 "do_transmit did nothing, should not happen!\n");
1462 finish_sending(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1464 struct Finish_send * finish;
1465 struct Plugin * plugin;
1469 plugin = finish->plugin;
1471 plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
1473 bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle,
1474 finish->msgheader, finish->size);
1475 GNUNET_assert(bytes != GNUNET_SYSERR);
1477 GNUNET_assert(plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK);
1478 if (bytes != finish->size)
1481 finish->plugin = plugin;
1482 finish->msgheader = finish->msgheader + bytes;
1483 finish->size = finish->size - bytes;
1484 plugin->server_write_task = GNUNET_SCHEDULER_add_write_file(
1485 GNUNET_TIME_UNIT_FOREVER_REL, plugin->server_stdin_handle,
1486 &finish_sending, finish);
1490 GNUNET_free(finish->msgstart);
1491 GNUNET_free(finish);
1492 check_next_fragment_timeout(plugin);
1498 getRadiotapHeader(struct RadiotapHeader * Header)
1505 * function to generate the wlan hardware header for one packet
1506 * @param Header address to write the header to
1507 * @param to_mac_addr address of the recipient
1508 * @param plugin pointer to the plugin struct
1509 * @return GNUNET_YES if there was no error
1513 getWlanHeader(struct IeeeHeader * Header,const char * const to_mac_addr,
1514 struct Plugin * plugin)
1516 memcpy(&Header->mac2, macbc, sizeof(macbc));
1517 memcpy(&Header->mac3, plugin->mac_address.mac, sizeof(plugin->mac_address));
1518 memcpy(&Header->mac1, to_mac_addr, sizeof(plugin->mac_address));
1525 * @param msgbuf pointer tor the data
1526 * @param msgbuf_size size of the data
1528 * @return 32bit crc value
1532 getcrc32(const char *msgbuf, size_t msgbuf_size)
1534 //TODO calc some crc
1541 * @param msgbuf pointer tor the data
1542 * @param msgbuf_size size of the data
1544 * @return 16bit crc value
1548 getcrc16(const char *msgbuf, size_t msgbuf_size)
1550 //TODO calc some crc
1555 * Function that can be used by the transport service to transmit
1556 * a message using the plugin.
1558 * @param cls closure
1559 * @param target who should receive this message
1560 * @param priority how important is the message
1561 * @param msgbuf the message to transmit
1562 * @param msgbuf_size number of bytes in 'msgbuf'
1563 * @param timeout when should we time out
1564 * @param session which session must be used (or NULL for "any")
1565 * @param addr the address to use (can be NULL if the plugin
1566 * is "on its own" (i.e. re-use existing TCP connection))
1567 * @param addrlen length of the address in bytes
1568 * @param force_address GNUNET_YES if the plugin MUST use the given address,
1569 * otherwise the plugin may use other addresses or
1570 * existing connections (if available)
1571 * @param cont continuation to call once the message has
1572 * been transmitted (or if the transport is ready
1573 * for the next transmission call; or if the
1574 * peer disconnected...)
1575 * @param cont_cls closure for cont
1576 * @return number of bytes used (on the physical network, with overheads);
1577 * -1 on hard errors (i.e. address invalid); 0 is a legal value
1578 * and does NOT mean that the message was not transmitted (DV)
1581 wlan_plugin_send(void *cls, const struct GNUNET_PeerIdentity * target,
1582 const char *msgbuf, size_t msgbuf_size, unsigned int priority,
1583 struct GNUNET_TIME_Relative timeout, struct Session *session,
1584 const void *addr, size_t addrlen, int force_address,
1585 GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
1587 struct Plugin * plugin = cls;
1588 struct PendingMessage * newmsg = NULL;
1589 struct WlanHeader * wlanheader = NULL;
1590 struct GNUNET_MessageHeader * innermsg =
1591 (struct GNUNET_MessageHeader *) msgbuf;
1593 //check if msglen > 0
1594 GNUNET_assert(msgbuf_size > 0);
1596 //get session if needed
1597 if (session == NULL)
1599 if (wlan_plugin_address_suggested(plugin, addr, addrlen) == GNUNET_OK)
1601 session = get_Session(plugin, addr);
1605 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1606 _("Wlan Address len %d is wrong\n"), addrlen);
1613 GNUNET_ERROR_TYPE_DEBUG,
1614 "wlan_plugin_send got %u bytes data, packet says it has %u bytes for %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n",
1615 msgbuf_size, ntohs(innermsg->size), session->addr[0], session->addr[1],
1616 session->addr[2], session->addr[3], session->addr[4], session->addr[5]);
1619 //TODO target "problem" not solved
1620 session->target = *target;
1623 //first queue session
1624 queue_Session(plugin, session);
1626 //queue message in session
1627 //test if there is no other message in the "queue"
1628 //FIXME: to many send requests
1629 //GNUNET_assert (session->pending_message == NULL);
1630 if (session->pending_message != NULL)
1632 newmsg = session->pending_message;
1634 GNUNET_ERROR_TYPE_ERROR,
1635 "wlan_plugin_send: a pending message is already in the queue for this client\n remaining time to send this message is %u\n",
1636 GNUNET_TIME_absolute_get_remaining(newmsg->timeout).rel_value);
1640 newmsg = GNUNET_malloc(sizeof(struct PendingMessage));
1641 (newmsg->msg) = GNUNET_malloc(msgbuf_size + sizeof(struct WlanHeader));
1642 wlanheader = (struct WlanHeader *) newmsg->msg;
1643 //copy msg to buffer, not fragmented / segmented yet, but with message header
1644 wlanheader->header.size = htons(msgbuf_size + sizeof(struct WlanHeader));
1645 wlanheader->header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_DATA);
1646 memcpy(&(wlanheader->target), target, sizeof(struct GNUNET_PeerIdentity));
1647 wlanheader->crc = htonl(getcrc32(msgbuf, msgbuf_size));
1648 memcpy(&wlanheader[1], msgbuf, msgbuf_size);
1649 newmsg->transmit_cont = cont;
1650 newmsg->transmit_cont_cls = cont_cls;
1651 newmsg->timeout = GNUNET_TIME_relative_to_absolute(timeout);
1653 newmsg->timeout.abs_value = newmsg->timeout.abs_value - 500;
1655 newmsg->message_size = msgbuf_size + sizeof(struct WlanHeader);
1657 session->pending_message = newmsg;
1659 check_fragment_queue(plugin);
1660 //FIXME not the correct size
1666 static struct FragmentMessage *
1667 get_fragment_message_from_session(struct Session * session)
1669 struct FragmentMessage * fm = session->plugin->pending_Fragment_Messages_head;
1672 if (fm->session == session)
1682 * Function that can be used to force the plugin to disconnect
1683 * from the given peer and cancel all previous transmissions
1684 * (and their continuation).
1686 * @param cls closure
1687 * @param target peer from which to disconnect
1690 wlan_plugin_disconnect(void *cls, const struct GNUNET_PeerIdentity *target)
1692 struct Plugin *plugin = cls;
1693 struct Sessionqueue * queue = plugin->sessions;
1694 struct Sessionqueue * pendingsession = plugin->pending_Sessions;
1695 struct PendingMessage * pm = NULL;
1696 struct FragmentMessage * fm;
1698 // just look at all the session for the needed one
1699 while (queue != NULL)
1701 // content is never NULL
1702 GNUNET_assert (queue->content != NULL);
1703 if (memcmp(target, &(queue->content->target),
1704 sizeof(struct GNUNET_PeerIdentity)) == 0)
1707 //is this session pending for send
1708 while (pendingsession != NULL)
1710 if (pendingsession->content == queue->content)
1712 plugin->pendingsessions--;
1713 GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions,
1714 plugin->pending_Sessions_tail, pendingsession);
1715 GNUNET_free(pendingsession);
1718 pendingsession = pendingsession->next;
1721 //is something of this session in the fragment queue?
1722 fm = get_fragment_message_from_session(queue->content);
1723 free_fragment_message(plugin, fm);
1725 //dispose all received fragments
1726 free_rec_frag_queue(queue->content);
1728 // remove PendingMessage
1729 pm = queue->content->pending_message;
1732 GNUNET_free_non_null(pm->msg);
1736 GNUNET_free(queue->content);
1737 GNUNET_CONTAINER_DLL_remove(plugin->sessions, plugin->sessions_tail, queue);
1739 plugin->session_count--;
1744 queue = queue->next;
1749 * Convert the transports address to a nice, human-readable
1752 * @param cls closure
1753 * @param type name of the transport that generated the address
1754 * @param addr one of the addresses of the host, NULL for the last address
1755 * the specific address format depends on the transport
1756 * @param addrlen length of the address
1757 * @param numeric should (IP) addresses be displayed in numeric form?
1758 * @param timeout after how long should we give up?
1759 * @param asc function to call on each string
1760 * @param asc_cls closure for asc
1763 wlan_plugin_address_pretty_printer(void *cls, const char *type,
1764 const void *addr, size_t addrlen, int numeric,
1765 struct GNUNET_TIME_Relative timeout,
1766 GNUNET_TRANSPORT_AddressStringCallback asc, void *asc_cls)
1769 const unsigned char * input;
1771 //GNUNET_assert(cls !=NULL);
1774 /* invalid address (MAC addresses have 6 bytes) */
1779 input = (const unsigned char*) addr;
1780 GNUNET_snprintf(ret, sizeof(ret), "%s Mac-Address %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
1781 PROTOCOL_PREFIX, input[0], input[1], input[2], input[3], input[4],
1787 * Another peer has suggested an address for this
1788 * peer and transport plugin. Check that this could be a valid
1789 * address. If so, consider adding it to the list
1792 * @param cls closure
1793 * @param addr pointer to the address
1794 * @param addrlen length of addr
1795 * @return GNUNET_OK if this is a plausible address for this peer
1800 wlan_plugin_address_suggested(void *cls, const void *addr, size_t addrlen)
1802 //struct Plugin *plugin = cls;
1804 /* check if the address is plausible; if so,
1805 add it to our list! */
1807 GNUNET_assert(cls !=NULL);
1808 //FIXME mitm is not checked
1809 //Mac Address has 6 bytes
1812 /* TODO check for bad addresses like multicast, broadcast, etc */
1817 return GNUNET_SYSERR;
1820 return GNUNET_SYSERR;
1824 * Function called for a quick conversion of the binary address to
1825 * a numeric address. Note that the caller must not free the
1826 * address and that the next call to this function is allowed
1827 * to override the address again.
1829 * @param cls closure
1830 * @param addr binary address
1831 * @param addrlen length of the address
1832 * @return string representing the same address
1835 wlan_plugin_address_to_string(void *cls, const void *addr, size_t addrlen)
1837 static char ret[40];
1838 const unsigned char * input;
1840 //GNUNET_assert(cls !=NULL);
1843 /* invalid address (MAC addresses have 6 bytes) */
1847 input = (const unsigned char*) addr;
1848 GNUNET_snprintf(ret, sizeof(ret), "%s Mac-Address %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
1849 PROTOCOL_PREFIX, input[0], input[1], input[2], input[3], input[4],
1855 * Function to test if fragment number already exists in the fragments received
1857 * @param session session the fragment belongs to
1858 * @param fh Fragmentheader of the fragment
1859 * @return GNUNET_YES if fragment exists already, GNUNET_NO if it does not exists in the queue of the session
1863 is_double_msg(struct Session * session, struct FragmentationHeader * fh)
1865 struct RecQueue * rec_queue = session->frag_head;
1866 while (rec_queue != NULL)
1868 if (rec_queue->num == fh->fragment_off_or_num)
1872 rec_queue = rec_queue->next;
1879 * Function to insert a fragment in a queue of a session
1880 * @param session session the fragment belongs to
1881 * @param rec_queue fragment to add
1885 insert_fragment_in_queue(struct Session * session, struct RecQueue * rec_queue)
1887 struct RecQueue * rec_queue2 = session->frag_head;
1888 struct WlanHeader * wlanheader = NULL;
1889 //first received fragment of message
1890 if (session->rec_size == NO_MESSAGE_OR_MESSAGE_FINISHED)
1892 session->rec_size = MESSAGE_LENGHT_UNKNOWN;
1894 //this is the first fragment of the message (fragment id 0)
1895 if (rec_queue->num == 0)
1897 wlanheader = (struct WlanHeader *) rec_queue->msg;
1898 session->rec_size = ntohs(wlanheader->header.size);
1902 while (rec_queue2 != NULL)
1904 if (rec_queue2->num > rec_queue->num)
1906 //next element number is grater than the current num
1907 GNUNET_CONTAINER_DLL_insert_before(session->frag_head, session->frag_tail, rec_queue2, rec_queue);
1910 rec_queue = rec_queue->next;
1912 //no element has a grater number
1913 GNUNET_CONTAINER_DLL_insert_tail(session->frag_head, session->frag_tail, rec_queue);
1917 * Function to dispose the fragments received for a message
1918 * @param session session to free the fragments from
1922 free_rec_frag_queue(struct Session * session)
1924 struct RecQueue * rec_queue = session->frag_head;
1925 struct RecQueue * rec_queue2;
1926 while (rec_queue != NULL)
1928 rec_queue2 = rec_queue;
1929 rec_queue = rec_queue->next;
1930 GNUNET_free(rec_queue2);
1932 session->frag_head = NULL;
1933 session->frag_tail = NULL;
1934 session->rec_size = NO_MESSAGE_OR_MESSAGE_FINISHED;
1938 * Function to check if all fragments of a message have been received
1939 * @param plugin the plugin handle
1940 * @param session_light information of the message sender
1941 * @param session session the message belongs to
1945 check_rec_finished_msg(struct Plugin* plugin,
1946 struct Session_light * session_light, struct Session * session)
1948 struct RecQueue * rec_queue = session->frag_head;
1949 int packetsize = session->rec_size;
1953 //some fragment should be received
1954 GNUNET_assert(session->rec_size != NO_MESSAGE_OR_MESSAGE_FINISHED);
1955 //check if first fragment is present
1956 if (session->rec_size == MESSAGE_LENGHT_UNKNOWN)
1960 while (rec_queue != NULL)
1962 sum += rec_queue->size;
1963 //check if all fragment numbers are present
1964 if (rec_queue->num != aktnum)
1969 rec_queue = rec_queue->next;
1971 //sum should always be smaller or equal of
1972 GNUNET_assert(sum <= packetsize);
1973 if (sum == packetsize)
1977 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1978 "check_rec_finished_msg: A message for %p is complete\n", session);
1981 //copy fragments together
1982 msg = GNUNET_malloc(packetsize);
1983 rec_queue = session->frag_head;
1985 while (rec_queue != NULL)
1987 //TODO SAVE SOME COPY OPS AND CHECK CRC WITHOUT COPY
1988 memcpy(msg + aktnum, rec_queue->msg, rec_queue->size);
1989 aktnum += rec_queue->size;
1990 rec_queue = rec_queue->next;
1992 free_rec_frag_queue(session);
1993 //call wlan_process_helper to process the message
1994 wlan_data_massage_handler(plugin, session_light,
1995 (struct GNUNET_MessageHeader*) msg);
1996 //wlan_data_helper (plugin, session_light, (struct GNUNET_MessageHeader*) msg);
2003 process_data(void *cls, void *client,
2004 const struct GNUNET_MessageHeader *hdr){
2006 GNUNET_assert(client != NULL);
2007 GNUNET_assert(cls != NULL);
2008 struct Session * session = (struct Session * )client;
2009 struct Plugin * plugin = (struct Plugin * ) cls;
2011 struct GNUNET_TRANSPORT_ATS_Information distance[2];
2012 distance[0].type = htonl(GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE);
2013 distance[0].value = htonl(1);
2014 distance[1].type = htonl(GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
2015 distance[1].value = htonl(0);
2018 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2019 "Calling plugin->env->receive for session %p; %s\n", session,
2020 wlan_plugin_address_to_string(NULL, session->addr, 6));
2023 plugin->env->receive(plugin->env->cls, &(session->target), hdr,
2024 (const struct GNUNET_TRANSPORT_ATS_Information *) &distance, 2,
2025 session, session->addr, sizeof(session->addr));
2029 * handels the data after all fragments are put together
2031 * @param session_light
2032 * @param hdr pointer to the data
2035 wlan_data_massage_handler(struct Plugin * plugin,
2036 struct Session_light * session_light,
2037 const struct GNUNET_MessageHeader * hdr)
2039 struct WlanHeader * wlanheader = NULL;
2040 struct Session * session = NULL;
2041 const char * tempmsg = NULL;
2042 const struct GNUNET_MessageHeader * temp_hdr = NULL;
2043 struct GNUNET_PeerIdentity tmptarget;
2045 if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_DATA)
2050 GNUNET_ERROR_TYPE_DEBUG,
2051 "Func wlan_data_massage_handler got GNUNET_MESSAGE_TYPE_WLAN_DATA size: %u\n",
2055 GNUNET_assert(session_light != NULL);
2056 if (session_light->session == NULL)
2058 session_light->session = search_session(plugin, session_light->addr);
2060 session = session_light->session;
2061 wlanheader = (struct WlanHeader *) hdr;
2062 tempmsg = (char*) &wlanheader[1];
2063 temp_hdr = (const struct GNUNET_MessageHeader *) &wlanheader[1];
2065 if (getcrc32(tempmsg, ntohs(wlanheader->header.size)) != ntohl(
2068 //wrong crc, dispose message
2069 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
2070 "Wlan message Header crc was wrong\n");
2074 //if not in session list
2075 if (session == NULL)
2079 GNUNET_ERROR_TYPE_DEBUG,
2080 "WLAN client not in session list: packet size = %u, inner size = %u, header size = %u\n",
2081 ntohs(wlanheader->header.size), ntohs(temp_hdr->size),
2082 sizeof(struct WlanHeader));
2084 //try if it is a hello message
2085 if (ntohs(wlanheader->header.size) >= ntohs(temp_hdr->size)
2086 + sizeof(struct WlanHeader))
2088 if (ntohs(temp_hdr->type) == GNUNET_MESSAGE_TYPE_HELLO)
2090 if (GNUNET_HELLO_get_id(
2091 (const struct GNUNET_HELLO_Message *) temp_hdr,
2092 &tmptarget) == GNUNET_OK)
2094 session = create_session(plugin, session_light->addr);
2095 session_light->session = session;
2096 memcpy(&session->target, &tmptarget,
2097 sizeof(struct GNUNET_PeerIdentity));
2101 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
2102 "WLAN client not in session list and hello message not okay\n");
2109 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
2110 "WLAN client not in session list and not a hello message\n");
2117 GNUNET_ERROR_TYPE_WARNING,
2118 "WLAN client not in session list and message size in does not fit\npacket size = %u, inner size = %u, header size = %u\n",
2119 ntohs(wlanheader->header.size), ntohs(temp_hdr->size),
2120 sizeof(struct WlanHeader));
2125 //"receive" the message
2128 GNUNET_SERVER_mst_receive(plugin->data_tokenizer, session, (const char *) temp_hdr,
2129 ntohs(hdr->size) - sizeof(struct WlanHeader), GNUNET_YES, GNUNET_NO);
2136 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
2137 "wlan_data_massage_handler got wrong message type\n");
2143 * function to add an ack to send it for a received fragment
2144 * @param plugin pointer to the global plugin structure
2145 * @param session pointer to the session this ack belongs to
2146 * @param fh pointer to the fragmentation header which we would like to acknolage
2150 add_ack_for_send(struct Plugin * plugin, struct Session * session,
2151 struct FragmentationHeader * fh)
2153 struct AckSendQueue * ack;
2155 GNUNET_assert(plugin != NULL);
2156 GNUNET_assert(session != NULL);
2157 GNUNET_assert(fh != NULL);
2159 ack = GNUNET_malloc(sizeof(struct AckSendQueue));
2160 ack->fragment_off_or_num = ntohs(fh->fragment_off_or_num);
2161 ack->message_id = ntohl(fh->message_id);
2162 ack->session = session;
2164 GNUNET_CONTAINER_DLL_insert_tail(plugin->ack_send_queue_head,
2165 plugin->ack_send_queue_tail, ack);
2170 * Function used for to process the data received from the wlan interface
2172 * @param cls the plugin handle
2173 * @param session_light FIXME: document
2174 * @param hdr hdr of the GNUNET_MessageHeader
2177 wlan_data_helper(void *cls, struct Session_light * session_light,
2178 const struct GNUNET_MessageHeader * hdr)
2180 struct Plugin *plugin = cls;
2181 struct Session * session = NULL;
2183 struct FragmentationHeader * fh = NULL;
2184 struct FragmentMessage * fm = NULL;
2186 const char * tempmsg = NULL;
2188 struct AckQueue * ack = NULL;
2189 struct AckQueue * ack2 = NULL;
2191 struct RecQueue * rec_queue = NULL;
2193 if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT)
2196 //TODO better DOS protection, error handling
2197 //TODO test first than create session
2198 GNUNET_assert(session_light != NULL);
2202 GNUNET_ERROR_TYPE_DEBUG,
2203 "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT size: %u; %s\n",
2204 ntohs(hdr->size), wlan_plugin_address_to_string(NULL,session_light->addr, 6));
2207 if (session_light->session == NULL)
2209 session_light->session = get_Session(plugin, session_light->addr);
2211 GNUNET_assert(GNUNET_HELLO_get_id(
2212 (const struct GNUNET_HELLO_Message *) &hdr[1],
2213 &(session_light->session->target) ) != GNUNET_SYSERR);
2218 else if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT)
2221 GNUNET_assert(session_light != NULL);
2222 if (session_light->session == NULL)
2224 session_light->session = search_session(plugin, session_light->addr);
2226 session = session_light->session;
2228 fh = (struct FragmentationHeader *) hdr;
2229 tempmsg = (char*) &fh[1];
2233 GNUNET_ERROR_TYPE_DEBUG,
2234 "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT with message_id %u with fragment number %i, size: %u; %s\n",
2235 ntohl(fh->message_id), ntohs(fh->fragment_off_or_num), ntohs(
2236 hdr->size), wlan_plugin_address_to_string(NULL,session_light->addr, 6));
2239 if (getcrc16(tempmsg, ntohs(fh->header.size)) != ntohs(fh->message_crc))
2241 //wrong crc, dispose message
2242 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "WLAN fragment crc was wrong\n");
2246 //if in the session list
2247 if (session != NULL)
2249 //TODO fragments do not timeout
2250 //check if message_id is right or it is a new msg
2251 if ((session->message_id_in == ntohs(fh->message_id))
2252 || (session->rec_size == NO_MESSAGE_OR_MESSAGE_FINISHED))
2254 session->message_id_in = ntohs(fh->message_id);
2255 if (is_double_msg(session, fh) != GNUNET_YES)
2258 //TODO ask if it is right like this
2259 if (plugin->env->traffic_report != NULL)
2261 plugin->env->traffic_report(plugin->env->cls,
2262 &session->target, ntohs(fh->header.size));
2265 = GNUNET_malloc(sizeof (struct RecQueue) +
2266 ntohs(fh->header.size) - sizeof(struct FragmentationHeader));
2267 rec_queue->size = ntohs(fh->header.size)
2268 - sizeof(struct FragmentationHeader);
2269 rec_queue->num = ntohs(fh->fragment_off_or_num);
2270 rec_queue->msg = (char*) &rec_queue[1];
2271 //copy msg to buffer
2272 memcpy((char *) rec_queue->msg, tempmsg, rec_queue->size);
2273 insert_fragment_in_queue(session, rec_queue);
2274 check_rec_finished_msg(plugin, session_light, session);
2278 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
2279 "WLAN fragment is a clone\n");
2286 GNUNET_ERROR_TYPE_INFO,
2287 "WLAN fragment message_id and session message_id are not the same and a message is already (partly) received\n");
2293 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
2294 "WLAN client not in session list\n");
2295 wlan_data_massage_handler(plugin, session_light,
2296 (struct GNUNET_MessageHeader *) tempmsg);
2297 session = session_light->session;
2298 //test if a session was created
2299 if (session == NULL)
2305 //TODO make and send ack
2306 add_ack_for_send(plugin, session, fh);
2307 check_next_fragment_timeout(plugin);
2312 else if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT_ACK)
2317 GNUNET_ERROR_TYPE_DEBUG,
2318 "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT_ACK size: %u; %s\n",
2319 ntohs(hdr->size), wlan_plugin_address_to_string(NULL,session_light->addr, 6));
2322 GNUNET_assert(session_light != NULL);
2323 if (session_light->session == NULL)
2325 session_light->session = search_session(plugin, session_light->addr);
2326 GNUNET_assert(session_light->session != NULL);
2328 session = session_light->session;
2329 fh = (struct FragmentationHeader *) hdr;
2330 if (session->message_id_out == ntohl(fh->message_id))
2332 fm = get_fragment_message_from_session(session);
2337 while (ack2 != NULL)
2340 if (ack2->fragment_num != ntohs(fh->fragment_off_or_num))
2342 // check if next ack has bigger number
2343 if (ack2->fragment_num > ntohs(fh->fragment_off_or_num))
2345 ack = GNUNET_malloc(sizeof(struct AckQueue));
2346 ack->fragment_num = ntohs(fh->fragment_off_or_num);
2347 GNUNET_CONTAINER_DLL_insert_before(fm->head,fm->tail,ack2,ack);
2349 check_finished_fragment(plugin, fm);
2358 GNUNET_ERROR_TYPE_DEBUG,
2359 "WLAN got double ack for message id %u and fragment num %u\n",
2360 session->message_id_out, ack2->fragment_num);
2367 //all acks are have smaller numbers
2368 ack = GNUNET_malloc(sizeof(struct AckQueue));
2369 ack->fragment_num = ntohs(fh->fragment_off_or_num);
2370 GNUNET_CONTAINER_DLL_insert_tail(fm->head,fm->tail,ack);
2371 check_finished_fragment(plugin, fm);
2376 GNUNET_ERROR_TYPE_WARNING,
2377 "WLAN fragment not in fragment list but id %u of ack is right\n",
2378 ntohl(fh->message_id));
2387 GNUNET_ERROR_TYPE_DEBUG,
2388 _("WLAN got ack but session->message_id_out %u and fragment id %u mismatch\n"),
2389 session->message_id_out, ntohl(fh->message_id));
2397 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
2398 "WLAN packet inside the WLAN helper packet has not the right type\n");
2403 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2404 "Helper finished\n");
2410 * Function used for to process the data from the suid process
2412 * @param cls the plugin handle
2413 * @param client client that send the data (not used)
2414 * @param hdr header of the GNUNET_MessageHeader
2418 wlan_process_helper(void *cls, void *client,
2419 const struct GNUNET_MessageHeader *hdr)
2421 struct Plugin *plugin = cls;
2422 struct IeeeHeader * wlanIeeeHeader = NULL;
2423 struct Session_light * session_light = NULL;
2424 const struct GNUNET_MessageHeader * temp_hdr = NULL;
2429 if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA)
2433 GNUNET_ERROR_TYPE_DEBUG,
2434 "Func wlan_process_helper got GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA size: %u\n",
2438 //call wlan_process_helper with the message inside, later with wlan: analyze signal
2439 GNUNET_assert(ntohs(hdr->size) >= sizeof(struct IeeeHeader) + sizeof(struct GNUNET_MessageHeader));
2440 wlanIeeeHeader = (struct IeeeHeader *) &hdr[1];
2442 //process only if it is an broadcast or for this computer both with the gnunet bssid
2445 if (memcmp(&(wlanIeeeHeader->mac2), macbc, sizeof(struct MacAddress))
2448 //check for broadcast or mac
2449 if (memcmp(&(wlanIeeeHeader->mac1), bc_all_mac,
2450 sizeof(struct MacAddress) == 0) || memcmp(
2451 &(wlanIeeeHeader->mac1), &(plugin->mac_address),
2452 sizeof(struct MacAddress)) == 0)
2455 // process the inner data
2458 datasize = ntohs(hdr->size) - sizeof(struct IeeeHeader)
2459 - sizeof(struct GNUNET_MessageHeader);
2461 session_light = GNUNET_malloc(sizeof(struct Session_light));
2462 memcpy(session_light->addr, &(wlanIeeeHeader->mac3),
2463 sizeof(struct MacAddress));
2464 //session_light->session = search_session(plugin,session_light->addr);
2467 temp_hdr = (struct GNUNET_MessageHeader *) &wlanIeeeHeader[1];
2468 while (pos < datasize)
2470 temp_hdr = (struct GNUNET_MessageHeader *) &wlanIeeeHeader[1]
2473 wlan_data_helper(plugin, session_light, temp_hdr);
2474 pos += ntohs(temp_hdr->size);
2479 GNUNET_free(session_light);
2484 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2485 "Func wlan_process_helper got wrong MAC: %s\n",
2486 wlanIeeeHeader->mac1);
2493 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2494 "Func wlan_process_helper got wrong BSSID: %s\n",
2495 wlanIeeeHeader->mac2);
2503 else if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL)
2508 GNUNET_ERROR_TYPE_DEBUG,
2509 "Func wlan_process_helper got GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL size: %u\n",
2513 //TODO more control messages
2514 //TODO use struct wlan_helper_control
2515 if (ntohs(hdr->size) == sizeof(struct Wlan_Helper_Control_Message))
2517 //plugin->mac_address = GNUNET_malloc(sizeof(struct MacAddress));
2518 memcpy(&(plugin->mac_address), &hdr[1], sizeof(struct MacAddress));
2519 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2520 "Notifying transport of address %s\n",
2521 wlan_plugin_address_to_string(cls, &(plugin->mac_address), ntohs(
2522 hdr->size) - sizeof(struct GNUNET_MessageHeader)));
2523 plugin->env->notify_address(plugin->env->cls, "wlan",
2524 &plugin->mac_address, sizeof(struct MacAddress),
2525 GNUNET_TIME_UNIT_FOREVER_REL);
2529 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Wrong wlan mac address %s\n",
2530 plugin->mac_address);
2538 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
2539 "WLAN helper packet has not the right type\n");
2545 * We have been notified that wlan-helper has written something to stdout.
2546 * Handle the output, then reschedule this function to be called again once
2547 * more is available.
2549 * @param cls the plugin handle
2550 * @param tc the scheduling context
2554 wlan_plugin_helper_read(void *cls,
2555 const struct GNUNET_SCHEDULER_TaskContext *tc)
2557 struct Plugin *plugin = cls;
2558 plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK;
2562 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2563 "Start reading from STDIN\n");
2566 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
2569 char mybuf[WLAN_MTU + sizeof(struct GNUNET_MessageHeader)];
2572 bytes = GNUNET_DISK_file_read(plugin->server_stdout_handle, mybuf,
2577 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2578 _("Finished reading from wlan-helper stdout with code: %d\n"),
2583 GNUNET_SERVER_mst_receive(plugin->suid_tokenizer, NULL, mybuf, bytes, GNUNET_NO,
2586 GNUNET_assert(plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK);
2587 plugin->server_read_task = GNUNET_SCHEDULER_add_read_file(
2588 GNUNET_TIME_UNIT_FOREVER_REL, plugin->server_stdout_handle,
2589 &wlan_plugin_helper_read, plugin);
2593 * Start the gnunet-wlan-helper process.
2595 * @param plugin the transport plugin
2596 * @param testmode should we use the dummy driver for testing?
2597 * @return GNUNET_YES if process was started, GNUNET_SYSERR on error
2600 wlan_transport_start_wlan_helper(struct Plugin *plugin, int testmode)
2602 const char * filename = "gnunet-transport-wlan-helper";
2603 plugin->server_stdout = GNUNET_DISK_pipe(GNUNET_YES, GNUNET_NO, GNUNET_YES);
2604 if (plugin->server_stdout == NULL)
2605 return GNUNET_SYSERR;
2607 plugin->server_stdin = GNUNET_DISK_pipe(GNUNET_YES, GNUNET_YES, GNUNET_NO);
2608 if (plugin->server_stdin == NULL)
2609 return GNUNET_SYSERR;
2612 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2613 "Starting gnunet-wlan-helper process cmd: %s %s %i\n", filename,
2614 plugin->interface, testmode);
2616 /* Start the server process */
2618 plugin->server_proc = GNUNET_OS_start_process(plugin->server_stdin,
2619 plugin->server_stdout, filename, filename, plugin->interface, ((testmode
2620 == 1) ? "1" : (testmode == 2) ? "2" : "0"), NULL);
2621 if (plugin->server_proc == NULL)
2624 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2625 "Failed to start gnunet-wlan-helper process\n");
2627 return GNUNET_SYSERR;
2630 /* Close the write end of the read pipe */
2631 GNUNET_DISK_pipe_close_end(plugin->server_stdout, GNUNET_DISK_PIPE_END_WRITE);
2633 /* Close the read end of the write pipe */
2634 GNUNET_DISK_pipe_close_end(plugin->server_stdin, GNUNET_DISK_PIPE_END_READ);
2636 plugin->server_stdout_handle = GNUNET_DISK_pipe_handle(plugin->server_stdout,
2637 GNUNET_DISK_PIPE_END_READ);
2638 plugin->server_stdin_handle = GNUNET_DISK_pipe_handle(plugin->server_stdin,
2639 GNUNET_DISK_PIPE_END_WRITE);
2641 GNUNET_assert(plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK);
2644 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2645 "Adding server_read_task for the wlan-helper\n");
2650 plugin->server_read_task = GNUNET_SCHEDULER_add_read_file(
2651 GNUNET_TIME_UNIT_FOREVER_REL, plugin->server_stdout_handle,
2652 &wlan_plugin_helper_read, plugin);
2658 * Exit point from the plugin.
2659 * @param cls pointer to the api struct
2664 libgnunet_plugin_transport_wlan_done(void *cls)
2666 struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
2667 struct Plugin *plugin = api->cls;
2670 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2671 "libgnunet_plugin_transport_wlan_done started\n");
2674 GNUNET_assert(cls !=NULL);
2676 if (plugin->suid_tokenizer != NULL)
2677 GNUNET_SERVER_mst_destroy(plugin->suid_tokenizer);
2679 if (plugin->data_tokenizer != NULL)
2680 GNUNET_SERVER_mst_destroy(plugin->data_tokenizer);
2683 GNUNET_free_non_null(plugin->interface);
2684 GNUNET_free (plugin);
2690 * Entry point for the plugin.
2692 * @param cls closure, the 'struct GNUNET_TRANSPORT_PluginEnvironment*'
2693 * @return the 'struct GNUNET_TRANSPORT_PluginFunctions*' or NULL on error
2696 libgnunet_plugin_transport_wlan_init(void *cls)
2698 //struct GNUNET_SERVICE_Context *service;
2699 struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
2700 struct GNUNET_TRANSPORT_PluginFunctions *api;
2701 struct Plugin *plugin;
2702 static unsigned long long testmode = 0;
2704 GNUNET_assert(cls !=NULL);
2706 plugin = GNUNET_malloc (sizeof (struct Plugin));
2708 plugin->pendingsessions = 0;
2709 plugin->session_count = 0;
2710 plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
2711 plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK;
2712 plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK;
2714 set_next_beacon_time(plugin);
2716 if (GNUNET_CONFIGURATION_have_value(env->cfg, "transport-wlan", "TESTMODE"))
2718 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number(env->cfg,
2719 "transport-wlan", "TESTMODE", &testmode))
2723 if (GNUNET_CONFIGURATION_have_value(env->cfg, "transport-wlan", "INTERFACE"))
2725 if (GNUNET_CONFIGURATION_get_value_string(env->cfg, "transport-wlan",
2726 "INTERFACE", &(plugin->interface)) != GNUNET_YES)
2728 libgnunet_plugin_transport_wlan_done(plugin);
2733 wlan_transport_start_wlan_helper(plugin, testmode);
2734 plugin->suid_tokenizer = GNUNET_SERVER_mst_create(&wlan_process_helper, plugin);
2736 plugin->data_tokenizer = GNUNET_SERVER_mst_create(&process_data, plugin);
2738 //plugin->sessions = GNUNET_malloc (sizeof (struct Sessionqueue));
2739 //plugin->pending_Sessions = GNUNET_malloc (sizeof (struct Sessionqueue));
2741 api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
2743 api->send = &wlan_plugin_send;
2744 api->disconnect = &wlan_plugin_disconnect;
2745 api->address_pretty_printer = &wlan_plugin_address_pretty_printer;
2746 api->check_address = &wlan_plugin_address_suggested;
2747 api->address_to_string = &wlan_plugin_address_to_string;
2749 start_next_message_id();
2752 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "wlan init finished\n");
2758 /* end of plugin_transport_wlan.c */