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_YES
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 to the local wlan server prog
113 struct GNUNET_SERVER_MessageStreamTokenizer * consoltoken;
116 * stdout pipe handle for the gnunet-wlan-helper process
118 struct GNUNET_DISK_PipeHandle *server_stdout;
121 * stdout file handle for the gnunet-wlan-helper process
123 const struct GNUNET_DISK_FileHandle *server_stdout_handle;
126 * stdin pipe handle for the gnunet-wlan-helper process
128 struct GNUNET_DISK_PipeHandle *server_stdin;
131 * stdin file handle for the gnunet-wlan-helper process
133 const struct GNUNET_DISK_FileHandle *server_stdin_handle;
136 * ID of the gnunet-wlan-server std read task
138 GNUNET_SCHEDULER_TaskIdentifier server_read_task;
141 * ID of the gnunet-wlan-server std read task
143 GNUNET_SCHEDULER_TaskIdentifier server_write_task;
146 * ID of the delay task for writing
148 GNUNET_SCHEDULER_TaskIdentifier server_write_delay_task;
151 * The process id of the wlan process
153 struct GNUNET_OS_Process *server_proc;
156 * The interface of the wlan card given to us by the user.
161 * The mac_address of the wlan card given to us by the helper.
163 struct MacAddress mac_address;
166 * Sessions currently pending for transmission
167 * to this peer, if any.
169 struct Sessionqueue * pending_Sessions;
172 * Sessions currently pending for transmission
173 * to this peer (tail), if any.
175 struct Sessionqueue * pending_Sessions_tail;
178 * number of pending sessions
180 unsigned int pendingsessions;
183 * Messages in the fragmentation queue, head
186 struct FragmentMessage * pending_Fragment_Messages_head;
189 * Messages in the fragmentation queue, tail
192 struct FragmentMessage * pending_Fragment_Messages_tail;
195 * number of pending fragment message
198 unsigned int pending_fragment_messages;
201 * time of the next "hello-beacon"
204 struct GNUNET_TIME_Absolute beacon_time;
207 * queue to send acks for received fragments
210 struct AckSendQueue * ack_send_queue_head;
212 struct AckSendQueue * ack_send_queue_tail;
218 struct Plugin * plugin;
220 struct GNUNET_MessageHeader * msgstart;
225 * Queue of sessions, for the general session queue and the pending session queue
230 struct Sessionqueue * next;
231 struct Sessionqueue * prev;
232 struct Session * content;
236 * Queue of ack received for messages send
241 struct AckQueue * next;
242 struct AckQueue * prev;
243 int fragment_num; //TODO change it to offset if better
247 * Queue for the fragments received
252 struct RecQueue * next;
253 struct RecQueue * prev;
260 * Information kept for each message that is yet to
263 struct PendingMessage
267 * The pending message
272 * Size of the message
277 * Continuation function to call once the message
278 * has been sent. Can be NULL if there is no
279 * continuation to call.
281 GNUNET_TRANSPORT_TransmitContinuation transmit_cont;
284 * Cls for transmit_cont
286 void * transmit_cont_cls;
289 * Timeout value for the pending message.
291 struct GNUNET_TIME_Absolute timeout;
296 * Queue for acks to send for fragments recived
302 struct AckSendQueue * next;
303 struct AckSendQueue * prev;
305 struct Session * session;
307 * ID of message, to distinguish between the messages, picked randomly.
309 uint32_t message_id GNUNET_PACKED;
312 * Offset or number of this fragment, for fragmentation/segmentation (design choice, TBD)
314 uint16_t fragment_off_or_num GNUNET_PACKED;
319 * Session infos gathered from a messages
325 * the session this message belongs to
327 struct Session * session;
335 * Session handle for connections.
343 struct SessionHeader header;
346 * Pointer to the global plugin struct.
348 struct Plugin *plugin;
351 * Message currently pending for transmission
352 * to this peer, if any.
354 struct PendingMessage *pending_message;
357 * To whom are we talking to (set to our identity
358 * if we are still waiting for the welcome message)
360 struct GNUNET_PeerIdentity target;
363 * encapsulation of the receive data
365 //struct GNUNET_SERVER_MessageStreamTokenizer * receive_token;
368 * offset of the next fragment for the receive_token, -1 means last message finished
374 * size of the message received,
375 * MESSAGE_LENGHT_UNKNOWN means that the size is not known,
376 * NO_MESSAGE_OR_MESSAGE_FINISHED means no message received
382 * Sorted queue with the fragments received; head
385 struct RecQueue * frag_head;
388 * Sorted queue with the fragments received; tail
391 struct RecQueue * frag_tail;
399 * Address of the other peer (either based on our 'connect'
400 * call or on our 'accept' call).
405 * Last activity on this connection. Used to select preferred
408 struct GNUNET_TIME_Absolute last_activity;
411 * current number for message incoming, to distinguish between the messages
413 uint32_t message_id_in;
416 * current number for message outgoing, to distinguish between the messages
418 uint32_t message_id_out;
421 * does this session have a message in the fragment queue
429 * Struct for Messages in the fragment queue
432 struct FragmentMessage
435 * Session this message belongs to
438 struct Session *session;
441 * This is a doubly-linked list.
443 struct FragmentMessage *next;
446 * This is a doubly-linked list.
448 struct FragmentMessage *prev;
451 * The pending message
456 * Timeout value for the pending message.
458 struct GNUNET_TIME_Absolute timeout;
461 * Timeout value for the pending fragments.
462 * Stores the time when the next msg fragment ack has to be received
464 struct GNUNET_TIME_Absolute next_ack;
467 * Sorted queue with the acks received for fragments; head
470 struct AckQueue * head;
473 * Sorted queue with the acks received for fragments; tail
476 struct AckQueue * tail;
479 * Size of the message
484 * pos / next fragment number in the message, for fragmentation/segmentation,
485 * some acks can be missing but there is still time
487 uint32_t message_pos;
492 * Header for messages which need fragmentation
497 struct GNUNET_MessageHeader header;
500 * checksum/error correction
502 uint32_t crc GNUNET_PACKED;
505 * To whom are we talking to (set to our identity
506 * if we are still waiting for the welcome message)
508 struct GNUNET_PeerIdentity target;
510 // followed by payload
515 * Header for messages which need fragmentation
517 struct FragmentationHeader
520 struct GNUNET_MessageHeader header;
523 * To whom are we talking to (set to our identity
524 * if we are still waiting for the welcome message)
526 // struct GNUNET_PeerIdentity target GNUNET_PACKED;
529 * ID of message, to distinguish between the messages, picked randomly.
531 uint32_t message_id GNUNET_PACKED;
534 * Offset or number of this fragment, for fragmentation/segmentation (design choice, TBD)
536 uint16_t fragment_off_or_num GNUNET_PACKED;
539 * CRC of fragment (for error checking)
541 uint16_t message_crc GNUNET_PACKED;
545 * // 0x1 ack => Use two different message types in header.type! (FRAG_MESSAGE; FRAG_ACK)
546 * // 0x2 has data (not only ack)
547 * // 0x4 last fragment of message
550 // uint32_t flags GNUNET_PACKED;
553 * checksum/error correction
555 // uint32_t crc GNUNET_PACKED;
557 // followed by payload unless ACK
562 getRadiotapHeader(struct RadiotapHeader * Header);
565 getWlanHeader(struct IeeeHeader * Header,const char * to_mac_addr,
566 struct Plugin * plugin);
569 wlan_plugin_address_suggested(void *cls, const void *addr, size_t addrlen);
572 getcrc16(const char *msgbuf, size_t msgbuf_size);
575 do_transmit(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
578 check_fragment_queue(struct Plugin * plugin);
581 getcrc32(const char *msgbuf, size_t msgbuf_size);
584 free_rec_frag_queue(struct Session * session);
587 wlan_data_helper(void *cls, struct Session_light * session_light,
588 const struct GNUNET_MessageHeader * hdr);
591 wlan_process_helper(void *cls, void *client,
592 const struct GNUNET_MessageHeader *hdr);
595 finish_sending(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
598 wlan_data_massage_handler(struct Plugin * plugin,
599 struct Session_light * session_light,
600 const struct GNUNET_MessageHeader * hdr);
603 wlan_plugin_address_to_string(void *cls, const void *addr, size_t addrlen);
606 * get the next message number, at the moment just a random one
607 * @return returns the next valid message-number for sending packets
610 get_next_message_id()
612 return GNUNET_CRYPTO_random_u32(GNUNET_CRYPTO_QUALITY_NONCE, UINT32_MAX);
616 * start next message number generator
617 * (not necessary at the moment)
620 start_next_message_id()
622 //GNUNET_CRYPTO_random_init;
626 * search for a session with the addr
628 * @param plugin pointer to the plugin struct
629 * @param addr pointer to the mac address of the peer
630 * @return returns the session
633 static struct Session *
634 search_session(struct Plugin *plugin, const uint8_t * addr)
636 struct Sessionqueue * queue = plugin->sessions;
637 struct Sessionqueue * lastitem = NULL;
639 //just look at all the session for the needed one
640 while (queue != NULL)
642 // content is never NULL
643 GNUNET_assert (queue->content != NULL);
644 char * addr2 = queue->content->addr;
645 if (memcmp(addr, addr2, 6) == 0)
648 return queue->content;
658 * create a new session
660 * @param plugin pointer to the plugin struct
661 * @param addr pointer to the mac address of the peer
662 * @return returns the session
665 static struct Session *
666 create_session(struct Plugin *plugin, const uint8_t * addr)
668 struct Sessionqueue * queue = GNUNET_malloc (sizeof (struct Sessionqueue));
670 GNUNET_CONTAINER_DLL_insert_tail(plugin->sessions, plugin->sessions_tail, queue);
672 queue->content = GNUNET_malloc (sizeof (struct Session));
673 queue->content->plugin = plugin;
674 memcpy(queue->content->addr, addr, 6);
675 queue->content->message_id_out = get_next_message_id();
676 queue->content->has_fragment = 0;
677 queue->content->rec_size = NO_MESSAGE_OR_MESSAGE_FINISHED;
679 plugin->session_count++;
682 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
683 "New session %p with %s\n", queue->content ,wlan_plugin_address_to_string(NULL,addr, 6));
686 return queue->content;
690 * get Session from address, create if no session exists
692 * @param plugin pointer to the plugin struct
693 * @param addr pointer to the mac address of the peer
694 * @return returns the session
696 //TODO add other possibilities to find the right session (are there other?)
697 static struct Session *
698 get_Session(struct Plugin *plugin, const uint8_t * addr)
700 struct Session * session = search_session(plugin, addr);
706 return create_session(plugin, addr);
708 /* -- not needed, layer above already has it--
709 //queue welcome message for new sessions, not realy needed
710 //struct WelcomeMessage welcome;
711 struct PendingMessage *pm;
712 pm = GNUNET_malloc (sizeof (struct PendingMessage));
713 pm->msg = GNUNET_malloc(GNUNET_HELLO_size(* (plugin->env->our_hello)));
714 pm->message_size = GNUNET_HELLO_size(* (plugin->env->our_hello));
715 //welcome.header.size = htons (GNUNET_HELLO_size(* (plugin->env->our_hello)));
716 //welcome.header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT);
717 //welcome.clientIdentity = *plugin->env->my_identity;
718 memcpy ( (pm->msg), * plugin->env->our_hello, GNUNET_HELLO_size(* (plugin->env->our_hello)));
719 pm->timeout = GNUNET_TIME_UNIT_FOREVER_ABS;
720 queue->content->pending_message = pm;
721 plugin->pendingsessions ++;
722 GNUNET_CONTAINER_DLL_insert_tail(plugin->pending_Sessions, plugin->pending_Sessions_tail, queue);
724 check_fragment_queue(plugin);
729 * Queue the session to send data
733 queue_Session(struct Plugin *plugin, struct Session * session)
735 struct Sessionqueue * queue = plugin->pending_Sessions;
736 struct Sessionqueue * lastitem = NULL;
738 while (queue != NULL)
740 // content is never NULL
741 GNUNET_assert (queue->content != NULL);
742 // is session already in queue?
743 if (session == queue->content)
752 // Session is not in the queue
754 queue = GNUNET_malloc (sizeof (struct Sessionqueue));
755 queue->content = session;
758 GNUNET_CONTAINER_DLL_insert_after (plugin->pending_Sessions,
759 plugin->pending_Sessions_tail,
760 plugin->pending_Sessions_tail, queue);
761 plugin->pendingsessions++;
767 free_acks(struct FragmentMessage * fm)
769 struct AckQueue * fq;
770 while (fm->head != NULL)
773 GNUNET_CONTAINER_DLL_remove(fm->head, fm->tail, fq);
783 * Function to schedule the write task, executed after a delay
786 delay_fragment_task(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
788 struct Plugin * plugin = cls;
789 plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK;
791 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
794 // GNUNET_TIME_UNIT_FOREVER_REL is needed to clean up old msg
795 if (plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK)
797 plugin->server_write_task = GNUNET_SCHEDULER_add_write_file(
798 GNUNET_TIME_UNIT_FOREVER_REL, plugin->server_stdin_handle,
799 &do_transmit, plugin);
805 * Function to calculate the time of the next periodic "hello-beacon"
808 set_next_beacon_time(struct Plugin * const plugin)
810 //under 10 known peers: once a second
811 if (plugin->session_count < 10)
813 plugin->beacon_time = GNUNET_TIME_absolute_add(
814 GNUNET_TIME_absolute_get(), GNUNET_TIME_relative_multiply(
815 GNUNET_TIME_UNIT_SECONDS, HALLO_BEACON_SCALING_FACTOR));
817 //under 30 known peers: every 10 seconds
818 else if (plugin->session_count < 30)
820 plugin->beacon_time = GNUNET_TIME_absolute_add(
821 GNUNET_TIME_absolute_get(), GNUNET_TIME_relative_multiply(
822 GNUNET_TIME_UNIT_SECONDS, 10 * HALLO_BEACON_SCALING_FACTOR));
824 //over 30 known peers: once a minute
827 plugin->beacon_time = GNUNET_TIME_absolute_add(
828 GNUNET_TIME_absolute_get(), GNUNET_TIME_relative_multiply(
829 GNUNET_TIME_UNIT_MINUTES, HALLO_BEACON_SCALING_FACTOR));
834 struct GNUNET_TIME_Relative
835 get_next_frag_timeout(struct FragmentMessage * fm)
837 return GNUNET_TIME_relative_min(GNUNET_TIME_absolute_get_remaining(
838 fm->next_ack), GNUNET_TIME_absolute_get_remaining(fm->timeout));
843 * Function to get the timeout value for acks for this session
846 struct GNUNET_TIME_Relative
847 get_ack_timeout(struct FragmentMessage * fm)
849 return FRAGMENT_TIMEOUT;
853 * Function to set the timer for the next timeout of the fragment queue
854 * @param plugin the handle to the plugin struct
857 check_next_fragment_timeout(struct Plugin * const plugin)
859 struct FragmentMessage * fm;
860 struct GNUNET_TIME_Relative next_send;
862 next_send = GNUNET_TIME_absolute_get_remaining(plugin->beacon_time);
865 if (plugin->server_write_delay_task != GNUNET_SCHEDULER_NO_TASK)
867 GNUNET_SCHEDULER_cancel(plugin->server_write_delay_task);
868 plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK;
870 fm = plugin->pending_Fragment_Messages_head;
872 GNUNET_assert(plugin->server_write_delay_task == GNUNET_SCHEDULER_NO_TASK);
874 //check if some acks are in the queue
875 if (plugin->ack_send_queue_head != NULL)
877 next_send = GNUNET_TIME_relative_get_zero();
879 //check if there are some fragments in the queue
883 = GNUNET_TIME_relative_min(next_send, get_next_frag_timeout(fm));
885 plugin->server_write_delay_task = GNUNET_SCHEDULER_add_delayed(next_send,
886 &delay_fragment_task, plugin);
891 * Function to get the next queued Session, removes the session from the queue
894 static struct Session *
895 get_next_queue_Session(struct Plugin * plugin)
897 struct Session * session;
898 struct Sessionqueue * sessionqueue;
899 struct Sessionqueue * sessionqueue_alt;
900 struct PendingMessage * pm;
901 sessionqueue = plugin->pending_Sessions;
902 while (sessionqueue != NULL)
904 session = sessionqueue->content;
905 pm = session->pending_message;
907 //check for message timeout
908 if (GNUNET_TIME_absolute_get_remaining(pm->timeout).rel_value > 0)
910 //check if session has no message in the fragment queue
911 if (!session->has_fragment)
913 plugin->pendingsessions--;
914 GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions,
915 plugin->pending_Sessions_tail, sessionqueue);
916 GNUNET_free(sessionqueue);
922 sessionqueue = sessionqueue->next;
928 session->pending_message = NULL;
929 //call the cont func that it did not work
930 if (pm->transmit_cont != NULL)
931 pm->transmit_cont(pm->transmit_cont_cls, &(session->target),
933 GNUNET_free(pm->msg);
936 sessionqueue_alt = sessionqueue;
937 sessionqueue = sessionqueue->next;
938 plugin->pendingsessions--;
939 GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions,
940 plugin->pending_Sessions_tail, sessionqueue_alt);
942 GNUNET_free(sessionqueue_alt);
951 * Function to sort the message into the message fragment queue
952 * @param plugin the plugin struct
953 * @param fm message to sort into the queue
956 sort_fragment_into_queue(struct Plugin * plugin, struct FragmentMessage * fm)
958 struct FragmentMessage * fm2;
959 //sort into the list at the right position
961 fm2 = plugin->pending_Fragment_Messages_head;
965 if (GNUNET_TIME_absolute_get_difference(fm2->next_ack, fm->next_ack).rel_value
976 GNUNET_CONTAINER_DLL_insert_after(plugin->pending_Fragment_Messages_head,
977 plugin->pending_Fragment_Messages_tail,fm2,fm);
981 * frees the space of a message in the fragment queue (send queue)
982 * @param plugin the plugin struct
983 * @param fm message to free
986 free_fragment_message(struct Plugin * plugin, struct FragmentMessage * fm)
991 GNUNET_free_non_null(fm->msg);
992 GNUNET_CONTAINER_DLL_remove (plugin->pending_Fragment_Messages_head,
993 plugin->pending_Fragment_Messages_tail, fm);
995 plugin->pending_fragment_messages--;
996 check_fragment_queue(plugin);
999 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Pending fragment messages: %u\n", plugin->pending_fragment_messages);
1005 * Function to check if there is some space in the fragment queue
1006 * inserts a message if space is available
1007 * @param plugin the plugin struct
1011 check_fragment_queue(struct Plugin * plugin)
1013 struct Session * session;
1014 struct FragmentMessage * fm;
1015 struct GNUNET_PeerIdentity pid;
1017 struct PendingMessage * pm;
1019 if (plugin->pending_fragment_messages < FRAGMENT_QUEUE_SIZE)
1021 session = get_next_queue_Session(plugin);
1022 if (session != NULL)
1024 pm = session->pending_message;
1025 session->pending_message = NULL;
1026 session->has_fragment = 1;
1027 GNUNET_assert(pm != NULL);
1029 fm = GNUNET_malloc(sizeof(struct FragmentMessage));
1030 fm->message_size = pm->message_size;
1032 fm->session = session;
1033 fm->timeout.abs_value = pm->timeout.abs_value;
1034 fm->message_pos = 0;
1035 fm->next_ack = GNUNET_TIME_absolute_get();
1037 if (pm->transmit_cont != NULL) {
1038 pid = session->target;
1039 pm->transmit_cont(pm->transmit_cont_cls, &pid,
1042 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "called pm->transmit_cont for %p\n", session);
1048 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "no pm->transmit_cont for %p\n", session);
1053 sort_fragment_into_queue(plugin, fm);
1054 plugin->pending_fragment_messages++;
1056 //generate new message id
1057 session->message_id_out = get_next_message_id();
1059 //check if timeout changed
1060 check_next_fragment_timeout(plugin);
1066 * Funktion to check if all fragments where send and the acks received
1067 * frees the space if finished
1068 * @param plugin the plugin struct
1069 * @param fm the message to check
1072 check_finished_fragment(struct Plugin * plugin, struct FragmentMessage * fm)
1074 struct AckQueue * ack;
1077 if (fm->message_size >= (WLAN_MTU - sizeof(struct FragmentationHeader))
1078 * fm->tail->fragment_num)
1082 //check if all acks are present
1085 if (counter == ack->fragment_num)
1096 fm->session->has_fragment = 0;
1097 free_fragment_message(plugin, fm);
1100 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Finished a fragmented message\n");
1104 check_next_fragment_timeout(plugin);
1110 * Function to set the next fragment number
1111 * @param fm use this FragmentMessage
1115 set_next_message_fragment_pos(struct FragmentMessage * fm)
1117 struct AckQueue * akt = NULL;
1118 //check if retransmit is needed
1119 if (GNUNET_TIME_absolute_get_remaining(fm->next_ack).rel_value == 0)
1122 // be positive and try again later :-D
1123 fm->next_ack = GNUNET_TIME_relative_to_absolute(get_ack_timeout(fm));
1124 // find first missing fragment
1126 fm->message_pos = 0;
1130 //test if ack 0 (or X) was already received
1133 //if fragment is present, take next
1134 if (akt->fragment_num == fm->message_pos)
1138 //next ack is bigger then the fragment number
1139 //in case there is something like this: (acks) 1, 2, 5, 6, ...
1140 //and we send 3 again, the next number should be 4
1141 else if (akt->fragment_num > fm->message_pos)
1153 send_hello_beacon(struct Plugin * plugin)
1157 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Sending hello beacon\n");
1162 struct GNUNET_MessageHeader * msgheader = NULL;
1163 struct IeeeHeader * ieeewlanheader = NULL;
1164 struct RadiotapHeader * radioHeader = NULL;
1165 struct GNUNET_MessageHeader * msgheader2 = NULL;
1167 GNUNET_assert(sizeof(struct WlanHeader) + GNUNET_HELLO_size(
1168 *(plugin->env->our_hello)) <= WLAN_MTU);
1169 size = sizeof(struct GNUNET_MessageHeader) + sizeof(struct RadiotapHeader)
1170 + sizeof(struct IeeeHeader) + sizeof(struct GNUNET_MessageHeader)
1171 + GNUNET_HELLO_size(*(plugin->env->our_hello));
1173 msgheader = GNUNET_malloc(size);
1174 msgheader->size = htons(size);
1175 msgheader->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
1177 radioHeader = (struct RadiotapHeader*) &msgheader[1];
1178 getRadiotapHeader(radioHeader);
1179 ieeewlanheader = (struct IeeeHeader*) &radioHeader[1];
1180 getWlanHeader(ieeewlanheader, bc_all_mac, plugin);
1182 msgheader2 = (struct GNUNET_MessageHeader*) &ieeewlanheader[1];
1183 msgheader2->size = htons(GNUNET_HELLO_size(*(plugin->env->our_hello))
1184 + sizeof(struct GNUNET_MessageHeader));
1186 msgheader2->type = htons(GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT);
1187 memcpy(&msgheader2[1], *plugin->env->our_hello, GNUNET_HELLO_size(
1188 *(plugin->env->our_hello)));
1190 bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, msgheader, size);
1192 if (bytes == GNUNET_SYSERR)
1194 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1195 _("Error writing to wlan healper. errno == %d, ERROR: %s\n"),
1196 errno, strerror(errno));
1199 GNUNET_assert(bytes != GNUNET_SYSERR);
1200 GNUNET_assert(bytes == size);
1201 GNUNET_free(msgheader);
1203 set_next_beacon_time(plugin);
1204 check_next_fragment_timeout(plugin);
1208 send_ack(struct Plugin * plugin, struct AckSendQueue * ack)
1213 struct GNUNET_MessageHeader * msgheader = NULL;
1214 struct IeeeHeader * ieeewlanheader = NULL;
1215 struct RadiotapHeader * radioHeader = NULL;
1216 struct FragmentationHeader * msgheader2 = NULL;
1218 GNUNET_assert(sizeof(struct FragmentationHeader) <= WLAN_MTU);
1221 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1222 "Sending ack for message_id %u with fragment number %u\n",
1223 ack->message_id, ack->fragment_off_or_num);
1226 size = sizeof(struct GNUNET_MessageHeader) + sizeof(struct RadiotapHeader)
1227 + sizeof(struct IeeeHeader) + sizeof(struct FragmentationHeader);
1228 msgheader = GNUNET_malloc(size);
1229 msgheader->size = htons(size);
1230 msgheader->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
1232 radioHeader = (struct RadiotapHeader*) &msgheader[1];
1233 getRadiotapHeader(radioHeader);
1234 ieeewlanheader = (struct IeeeHeader*) &radioHeader[1];
1235 getWlanHeader(ieeewlanheader, ack->session->addr, plugin);
1237 msgheader2 = (struct FragmentationHeader*) &ieeewlanheader[1];
1238 msgheader2->header.size = htons(sizeof(struct FragmentationHeader));
1239 msgheader2->header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT_ACK);
1240 msgheader2->message_id = htonl(ack->message_id);
1241 msgheader2->fragment_off_or_num = htons(ack->fragment_off_or_num);
1243 bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle, msgheader, size);
1244 if (bytes == GNUNET_SYSERR)
1246 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1247 _("Error writing to wlan healper. errno == %d, ERROR: %s\n"),
1248 errno, strerror(errno));
1251 GNUNET_assert(bytes != GNUNET_SYSERR);
1252 GNUNET_assert(bytes == size);
1253 GNUNET_free(msgheader);
1254 check_next_fragment_timeout(plugin);
1258 * Function called when wlan helper is ready to get some data
1260 * @param cls closure
1261 * @param tc GNUNET_SCHEDULER_TaskContext
1265 do_transmit(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1268 struct Plugin * plugin = cls;
1269 plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
1271 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
1274 struct Session * session = NULL;
1275 struct FragmentMessage * fm = NULL;
1276 struct IeeeHeader * ieeewlanheader = NULL;
1277 struct RadiotapHeader * radioHeader = NULL;
1278 struct GNUNET_MessageHeader * msgheader = NULL;
1280 struct FragmentationHeader fragheader;
1281 struct FragmentationHeader * fragheaderptr = NULL;
1282 struct Finish_send * finish = NULL;
1283 struct AckSendQueue * ack;
1286 const char * copystart = NULL;
1287 uint16_t copysize = 0;
1288 uint copyoffset = 0;
1290 if (plugin->ack_send_queue_head != NULL)
1292 ack = plugin->ack_send_queue_head;
1293 GNUNET_CONTAINER_DLL_remove(plugin->ack_send_queue_head,
1294 plugin->ack_send_queue_tail, ack);
1295 send_ack(plugin, ack);
1300 //test if a "hello-beacon" has to be send
1301 if (GNUNET_TIME_absolute_get_remaining(plugin->beacon_time).rel_value == 0)
1303 send_hello_beacon(plugin);
1309 fm = plugin->pending_Fragment_Messages_head;
1312 session = fm->session;
1313 GNUNET_assert(session != NULL);
1315 // test if message timed out
1316 if (GNUNET_TIME_absolute_get_remaining(fm->timeout).rel_value == 0)
1319 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "message timeout\n");
1322 GNUNET_assert(plugin->pending_fragment_messages > 0);
1323 plugin->pending_fragment_messages--;
1324 GNUNET_CONTAINER_DLL_remove(plugin->pending_Fragment_Messages_head,
1325 plugin->pending_Fragment_Messages_tail, fm);
1327 GNUNET_free(fm->msg);
1330 check_fragment_queue(plugin);
1335 //if (fm->message_size > WLAN_MTU)
1337 size += sizeof(struct FragmentationHeader);
1339 set_next_message_fragment_pos(fm);
1341 copyoffset = (WLAN_MTU - sizeof(struct FragmentationHeader))
1343 fragheader.fragment_off_or_num = htons(fm->message_pos);
1344 fragheader.message_id = htonl(session->message_id_out);
1345 GNUNET_assert(copyoffset < fm->message_size);
1346 copystart = fm->msg + copyoffset;
1347 copysize = GNUNET_MIN(fm->message_size - copyoffset,
1348 WLAN_MTU - sizeof(struct FragmentationHeader));
1349 fragheader.header.size = htons(copysize
1350 + sizeof(struct FragmentationHeader));
1351 fragheader.header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT);
1356 // there is no need to split
1357 copystart = fm->msg;
1358 copysize = fm->message_size;
1363 GNUNET_ERROR_TYPE_DEBUG,
1364 "Sending GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT with message_id %u with fragment number %i, size: %u, time until timeout %u\n",
1365 session->message_id_out, fm->message_pos, copysize
1366 + sizeof(struct FragmentationHeader),
1367 GNUNET_TIME_absolute_get_remaining(fm->timeout));
1371 size += sizeof(struct RadiotapHeader) + sizeof(struct IeeeHeader)
1372 + sizeof(struct GNUNET_MessageHeader);
1373 msgheader = GNUNET_malloc(size);
1374 msgheader->size = htons(size);
1375 msgheader->type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
1377 radioHeader = (struct RadiotapHeader*) &msgheader[1];
1378 getRadiotapHeader(radioHeader);
1380 ieeewlanheader = (struct IeeeHeader *) &radioHeader[1];
1381 getWlanHeader(ieeewlanheader, fm->session->addr, plugin);
1383 //could be faster if content is just send and not copyed before
1384 //fragmentheader is needed
1385 //if (fm->message_size > WLAN_MTU)
1387 fragheader.message_crc = htons(getcrc16(copystart, copysize));
1388 memcpy(&ieeewlanheader[1], &fragheader,
1389 sizeof(struct FragmentationHeader));
1390 fragheaderptr = (struct FragmentationHeader *) &ieeewlanheader[1];
1391 memcpy(&fragheaderptr[1], copystart, copysize);
1395 memcpy(&ieeewlanheader[1], copystart, copysize);
1398 bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle,
1400 if (bytes == GNUNET_SYSERR)
1403 GNUNET_ERROR_TYPE_ERROR,
1404 _("Error writing to wlan healper. errno == %d, ERROR: %s\n"),
1405 errno, strerror(errno));
1408 GNUNET_assert(bytes != GNUNET_SYSERR);
1412 finish = GNUNET_malloc(sizeof( struct Finish_send));
1413 finish->plugin = plugin;
1414 finish->msgheader = (char *) msgheader + bytes;
1415 finish->size = size - bytes;
1416 finish->msgstart = msgheader;
1418 GNUNET_assert(plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK);
1420 plugin->server_write_task = GNUNET_SCHEDULER_add_write_file(
1421 GNUNET_TIME_UNIT_FOREVER_REL, plugin->server_stdin_handle,
1422 &finish_sending, finish);
1427 GNUNET_assert(bytes == size);
1429 GNUNET_free(msgheader);
1430 check_next_fragment_timeout(plugin);
1433 //check if this was the last fragment of this message, if true then queue at the end of the list
1434 if (copysize + copyoffset >= fm->message_size)
1436 GNUNET_assert(copysize + copyoffset == fm->message_size);
1438 GNUNET_CONTAINER_DLL_remove (plugin->pending_Fragment_Messages_head,
1439 plugin->pending_Fragment_Messages_tail, fm);
1441 GNUNET_CONTAINER_DLL_insert_tail(plugin->pending_Fragment_Messages_head,
1442 plugin->pending_Fragment_Messages_tail, fm);
1443 // if fragments have opimized timeouts
1444 //sort_fragment_into_queue(plugin,fm);
1451 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
1452 "do_transmit did nothing, should not happen!\n");
1456 finish_sending(void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1458 struct Finish_send * finish;
1459 struct Plugin * plugin;
1463 plugin = finish->plugin;
1465 plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
1467 bytes = GNUNET_DISK_file_write(plugin->server_stdin_handle,
1468 finish->msgheader, finish->size);
1469 GNUNET_assert(bytes != GNUNET_SYSERR);
1471 GNUNET_assert(plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK);
1472 if (bytes != finish->size)
1475 finish->plugin = plugin;
1476 finish->msgheader = finish->msgheader + bytes;
1477 finish->size = finish->size - bytes;
1478 plugin->server_write_task = GNUNET_SCHEDULER_add_write_file(
1479 GNUNET_TIME_UNIT_FOREVER_REL, plugin->server_stdin_handle,
1480 &finish_sending, finish);
1484 GNUNET_free(finish->msgstart);
1485 GNUNET_free(finish);
1486 check_next_fragment_timeout(plugin);
1492 getRadiotapHeader(struct RadiotapHeader * Header)
1499 * function to generate the wlan hardware header for one packet
1500 * @param Header address to write the header to
1501 * @param to_mac_addr address of the recipient
1502 * @param plugin pointer to the plugin struct
1503 * @return GNUNET_YES if there was no error
1507 getWlanHeader(struct IeeeHeader * Header,const char * const to_mac_addr,
1508 struct Plugin * plugin)
1510 memcpy(&Header->mac2, macbc, sizeof(macbc));
1511 memcpy(&Header->mac3, plugin->mac_address.mac, sizeof(plugin->mac_address));
1512 memcpy(&Header->mac1, to_mac_addr, sizeof(plugin->mac_address));
1519 * @param msgbuf pointer tor the data
1520 * @param msgbuf_size size of the data
1522 * @return 32bit crc value
1526 getcrc32(const char *msgbuf, size_t msgbuf_size)
1528 //TODO calc some crc
1535 * @param msgbuf pointer tor the data
1536 * @param msgbuf_size size of the data
1538 * @return 16bit crc value
1542 getcrc16(const char *msgbuf, size_t msgbuf_size)
1544 //TODO calc some crc
1549 * Function that can be used by the transport service to transmit
1550 * a message using the plugin.
1552 * @param cls closure
1553 * @param target who should receive this message
1554 * @param priority how important is the message
1555 * @param msgbuf the message to transmit
1556 * @param msgbuf_size number of bytes in 'msgbuf'
1557 * @param timeout when should we time out
1558 * @param session which session must be used (or NULL for "any")
1559 * @param addr the address to use (can be NULL if the plugin
1560 * is "on its own" (i.e. re-use existing TCP connection))
1561 * @param addrlen length of the address in bytes
1562 * @param force_address GNUNET_YES if the plugin MUST use the given address,
1563 * otherwise the plugin may use other addresses or
1564 * existing connections (if available)
1565 * @param cont continuation to call once the message has
1566 * been transmitted (or if the transport is ready
1567 * for the next transmission call; or if the
1568 * peer disconnected...)
1569 * @param cont_cls closure for cont
1570 * @return number of bytes used (on the physical network, with overheads);
1571 * -1 on hard errors (i.e. address invalid); 0 is a legal value
1572 * and does NOT mean that the message was not transmitted (DV)
1575 wlan_plugin_send(void *cls, const struct GNUNET_PeerIdentity * target,
1576 const char *msgbuf, size_t msgbuf_size, unsigned int priority,
1577 struct GNUNET_TIME_Relative timeout, struct Session *session,
1578 const void *addr, size_t addrlen, int force_address,
1579 GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
1581 struct Plugin * plugin = cls;
1582 struct PendingMessage * newmsg = NULL;
1583 struct WlanHeader * wlanheader = NULL;
1584 struct GNUNET_MessageHeader * innermsg =
1585 (struct GNUNET_MessageHeader *) msgbuf;
1587 //check if msglen > 0
1588 GNUNET_assert(msgbuf_size > 0);
1590 //get session if needed
1591 if (session == NULL)
1593 if (wlan_plugin_address_suggested(plugin, addr, addrlen) == GNUNET_OK)
1595 session = get_Session(plugin, addr);
1599 GNUNET_log(GNUNET_ERROR_TYPE_ERROR,
1600 _("Wlan Address len %d is wrong\n"), addrlen);
1607 GNUNET_ERROR_TYPE_DEBUG,
1608 "wlan_plugin_send got %u bytes data, packet says it has %u bytes for %.2X:%.2X:%.2X:%.2X:%.2X:%.2X\n",
1609 msgbuf_size, ntohs(innermsg->size), session->addr[0], session->addr[1],
1610 session->addr[2], session->addr[3], session->addr[4], session->addr[5]);
1613 //TODO target "problem" not solved
1614 session->target = *target;
1617 //first queue session
1618 queue_Session(plugin, session);
1620 //queue message in session
1621 //test if there is no other message in the "queue"
1622 //FIXME: to many send requests
1623 //GNUNET_assert (session->pending_message == NULL);
1624 if (session->pending_message != NULL)
1626 newmsg = session->pending_message;
1628 GNUNET_ERROR_TYPE_ERROR,
1629 "wlan_plugin_send: a pending message is already in the queue for this client\n remaining time to send this message is %u\n",
1630 GNUNET_TIME_absolute_get_remaining(newmsg->timeout).rel_value);
1634 newmsg = GNUNET_malloc(sizeof(struct PendingMessage));
1635 (newmsg->msg) = GNUNET_malloc(msgbuf_size + sizeof(struct WlanHeader));
1636 wlanheader = (struct WlanHeader *) newmsg->msg;
1637 //copy msg to buffer, not fragmented / segmented yet, but with message header
1638 wlanheader->header.size = htons(msgbuf_size + sizeof(struct WlanHeader));
1639 wlanheader->header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_DATA);
1640 memcpy(&(wlanheader->target), target, sizeof(struct GNUNET_PeerIdentity));
1641 wlanheader->crc = htonl(getcrc32(msgbuf, msgbuf_size));
1642 memcpy(&wlanheader[1], msgbuf, msgbuf_size);
1643 newmsg->transmit_cont = cont;
1644 newmsg->transmit_cont_cls = cont_cls;
1645 newmsg->timeout = GNUNET_TIME_relative_to_absolute(timeout);
1647 newmsg->timeout.abs_value = newmsg->timeout.abs_value - 500;
1649 newmsg->message_size = msgbuf_size + sizeof(struct WlanHeader);
1651 session->pending_message = newmsg;
1653 check_fragment_queue(plugin);
1654 //FIXME not the correct size
1660 static struct FragmentMessage *
1661 get_fragment_message_from_session(struct Session * session)
1663 struct FragmentMessage * fm = session->plugin->pending_Fragment_Messages_head;
1666 if (fm->session == session)
1676 * Function that can be used to force the plugin to disconnect
1677 * from the given peer and cancel all previous transmissions
1678 * (and their continuation).
1680 * @param cls closure
1681 * @param target peer from which to disconnect
1684 wlan_plugin_disconnect(void *cls, const struct GNUNET_PeerIdentity *target)
1686 struct Plugin *plugin = cls;
1687 struct Sessionqueue * queue = plugin->sessions;
1688 struct Sessionqueue * pendingsession = plugin->pending_Sessions;
1689 struct PendingMessage * pm = NULL;
1690 struct FragmentMessage * fm;
1692 // just look at all the session for the needed one
1693 while (queue != NULL)
1695 // content is never NULL
1696 GNUNET_assert (queue->content != NULL);
1697 if (memcmp(target, &(queue->content->target),
1698 sizeof(struct GNUNET_PeerIdentity)) == 0)
1701 //is this session pending for send
1702 while (pendingsession != NULL)
1704 if (pendingsession->content == queue->content)
1706 plugin->pendingsessions--;
1707 GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions,
1708 plugin->pending_Sessions_tail, pendingsession);
1709 GNUNET_free(pendingsession);
1712 pendingsession = pendingsession->next;
1715 //is something of this session in the fragment queue?
1716 fm = get_fragment_message_from_session(queue->content);
1717 free_fragment_message(plugin, fm);
1719 //dispose all received fragments
1720 free_rec_frag_queue(queue->content);
1722 // remove PendingMessage
1723 pm = queue->content->pending_message;
1726 GNUNET_free_non_null(pm->msg);
1730 GNUNET_free(queue->content);
1731 GNUNET_CONTAINER_DLL_remove(plugin->sessions, plugin->sessions_tail, queue);
1733 plugin->session_count--;
1738 queue = queue->next;
1743 * Convert the transports address to a nice, human-readable
1746 * @param cls closure
1747 * @param type name of the transport that generated the address
1748 * @param addr one of the addresses of the host, NULL for the last address
1749 * the specific address format depends on the transport
1750 * @param addrlen length of the address
1751 * @param numeric should (IP) addresses be displayed in numeric form?
1752 * @param timeout after how long should we give up?
1753 * @param asc function to call on each string
1754 * @param asc_cls closure for asc
1757 wlan_plugin_address_pretty_printer(void *cls, const char *type,
1758 const void *addr, size_t addrlen, int numeric,
1759 struct GNUNET_TIME_Relative timeout,
1760 GNUNET_TRANSPORT_AddressStringCallback asc, void *asc_cls)
1763 const unsigned char * input;
1765 //GNUNET_assert(cls !=NULL);
1768 /* invalid address (MAC addresses have 6 bytes) */
1773 input = (const unsigned char*) addr;
1774 GNUNET_snprintf(ret, sizeof(ret), "%s Mac-Address %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
1775 PROTOCOL_PREFIX, input[0], input[1], input[2], input[3], input[4],
1781 * Another peer has suggested an address for this
1782 * peer and transport plugin. Check that this could be a valid
1783 * address. If so, consider adding it to the list
1786 * @param cls closure
1787 * @param addr pointer to the address
1788 * @param addrlen length of addr
1789 * @return GNUNET_OK if this is a plausible address for this peer
1794 wlan_plugin_address_suggested(void *cls, const void *addr, size_t addrlen)
1796 //struct Plugin *plugin = cls;
1798 /* check if the address is plausible; if so,
1799 add it to our list! */
1801 GNUNET_assert(cls !=NULL);
1802 //FIXME mitm is not checked
1803 //Mac Address has 6 bytes
1806 /* TODO check for bad addresses like multicast, broadcast, etc */
1811 return GNUNET_SYSERR;
1814 return GNUNET_SYSERR;
1818 * Function called for a quick conversion of the binary address to
1819 * a numeric address. Note that the caller must not free the
1820 * address and that the next call to this function is allowed
1821 * to override the address again.
1823 * @param cls closure
1824 * @param addr binary address
1825 * @param addrlen length of the address
1826 * @return string representing the same address
1829 wlan_plugin_address_to_string(void *cls, const void *addr, size_t addrlen)
1831 static char ret[40];
1832 const unsigned char * input;
1834 //GNUNET_assert(cls !=NULL);
1837 /* invalid address (MAC addresses have 6 bytes) */
1841 input = (const unsigned char*) addr;
1842 GNUNET_snprintf(ret, sizeof(ret), "%s Mac-Address %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
1843 PROTOCOL_PREFIX, input[0], input[1], input[2], input[3], input[4],
1849 * Function to test if fragment number already exists in the fragments received
1851 * @param session session the fragment belongs to
1852 * @param fh Fragmentheader of the fragment
1853 * @return GNUNET_YES if fragment exists already, GNUNET_NO if it does not exists in the queue of the session
1857 is_double_msg(struct Session * session, struct FragmentationHeader * fh)
1859 struct RecQueue * rec_queue = session->frag_head;
1860 while (rec_queue != NULL)
1862 if (rec_queue->num == fh->fragment_off_or_num)
1866 rec_queue = rec_queue->next;
1873 * Function to insert a fragment in a queue of a session
1874 * @param session session the fragment belongs to
1875 * @param rec_queue fragment to add
1879 insert_fragment_in_queue(struct Session * session, struct RecQueue * rec_queue)
1881 struct RecQueue * rec_queue2 = session->frag_head;
1882 struct WlanHeader * wlanheader = NULL;
1883 //first received fragment of message
1884 if (session->rec_size == NO_MESSAGE_OR_MESSAGE_FINISHED)
1886 session->rec_size = MESSAGE_LENGHT_UNKNOWN;
1888 //this is the first fragment of the message (fragment id 0)
1889 if (rec_queue->num == 0)
1891 wlanheader = (struct WlanHeader *) rec_queue->msg;
1892 session->rec_size = ntohs(wlanheader->header.size);
1896 while (rec_queue2 != NULL)
1898 if (rec_queue2->num > rec_queue->num)
1900 //next element number is grater than the current num
1901 GNUNET_CONTAINER_DLL_insert_before(session->frag_head, session->frag_tail, rec_queue2, rec_queue);
1904 rec_queue = rec_queue->next;
1906 //no element has a grater number
1907 GNUNET_CONTAINER_DLL_insert_tail(session->frag_head, session->frag_tail, rec_queue);
1911 * Function to dispose the fragments received for a message
1912 * @param session session to free the fragments from
1916 free_rec_frag_queue(struct Session * session)
1918 struct RecQueue * rec_queue = session->frag_head;
1919 struct RecQueue * rec_queue2;
1920 while (rec_queue != NULL)
1922 rec_queue2 = rec_queue;
1923 rec_queue = rec_queue->next;
1924 GNUNET_free(rec_queue2);
1926 session->frag_head = NULL;
1927 session->frag_tail = NULL;
1928 session->rec_size = NO_MESSAGE_OR_MESSAGE_FINISHED;
1932 * Function to check if all fragments of a message have been received
1933 * @param plugin the plugin handle
1934 * @param session_light information of the message sender
1935 * @param session session the message belongs to
1939 check_rec_finished_msg(struct Plugin* plugin,
1940 struct Session_light * session_light, struct Session * session)
1942 struct RecQueue * rec_queue = session->frag_head;
1943 int packetsize = session->rec_size;
1947 //some fragment should be received
1948 GNUNET_assert(session->rec_size != NO_MESSAGE_OR_MESSAGE_FINISHED);
1949 //check if first fragment is present
1950 if (session->rec_size == MESSAGE_LENGHT_UNKNOWN)
1954 while (rec_queue != NULL)
1956 sum += rec_queue->size;
1957 //check if all fragment numbers are present
1958 if (rec_queue->num != aktnum)
1963 rec_queue = rec_queue->next;
1965 //sum should always be smaller or equal of
1966 GNUNET_assert(sum <= packetsize);
1967 if (sum == packetsize)
1971 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
1972 "check_rec_finished_msg: A message for %p is complete\n", session);
1975 //copy fragments together
1976 msg = GNUNET_malloc(packetsize);
1977 rec_queue = session->frag_head;
1979 while (rec_queue != NULL)
1981 memcpy(msg + aktnum, rec_queue->msg, rec_queue->size);
1982 aktnum += rec_queue->size;
1983 rec_queue = rec_queue->next;
1985 free_rec_frag_queue(session);
1986 //call wlan_process_helper to process the message
1987 wlan_data_massage_handler(plugin, session_light,
1988 (struct GNUNET_MessageHeader*) msg);
1989 //wlan_data_helper (plugin, session_light, (struct GNUNET_MessageHeader*) msg);
1996 wlan_data_massage_handler(struct Plugin * plugin,
1997 struct Session_light * session_light,
1998 const struct GNUNET_MessageHeader * hdr)
2000 struct WlanHeader * wlanheader = NULL;
2001 struct Session * session = NULL;
2002 const char * tempmsg = NULL;
2003 const struct GNUNET_MessageHeader * temp_hdr = NULL;
2004 struct GNUNET_PeerIdentity tmptarget;
2006 if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_DATA)
2011 GNUNET_ERROR_TYPE_DEBUG,
2012 "Func wlan_data_massage_handler got GNUNET_MESSAGE_TYPE_WLAN_DATA size: %u\n",
2016 GNUNET_assert(session_light != NULL);
2017 if (session_light->session == NULL)
2019 session_light->session = search_session(plugin, session_light->addr);
2021 session = session_light->session;
2022 wlanheader = (struct WlanHeader *) hdr;
2023 tempmsg = (char*) &wlanheader[1];
2024 temp_hdr = (const struct GNUNET_MessageHeader *) &wlanheader[1];
2026 if (getcrc32(tempmsg, ntohs(wlanheader->header.size)) != ntohl(
2029 //wrong crc, dispose message
2030 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
2031 "Wlan message Header crc was wrong\n");
2035 //if not in session list
2036 if (session == NULL)
2040 GNUNET_ERROR_TYPE_DEBUG,
2041 "WLAN client not in session list: packet size = %u, inner size = %u, header size = %u\n",
2042 ntohs(wlanheader->header.size), ntohs(temp_hdr->size),
2043 sizeof(struct WlanHeader));
2045 //try if it is a hello message
2046 if (ntohs(wlanheader->header.size) >= ntohs(temp_hdr->size)
2047 + sizeof(struct WlanHeader))
2049 if (ntohs(temp_hdr->type) == GNUNET_MESSAGE_TYPE_HELLO)
2051 if (GNUNET_HELLO_get_id(
2052 (const struct GNUNET_HELLO_Message *) temp_hdr,
2053 &tmptarget) == GNUNET_OK)
2055 session = create_session(plugin, session_light->addr);
2056 session_light->session = session;
2057 memcpy(&session->target, &tmptarget,
2058 sizeof(struct GNUNET_PeerIdentity));
2062 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
2063 "WLAN client not in session list and hello message not okay\n");
2070 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
2071 "WLAN client not in session list and not a hello message\n");
2078 GNUNET_ERROR_TYPE_WARNING,
2079 "WLAN client not in session list and message size in does not fit\npacket size = %u, inner size = %u, header size = %u\n",
2080 ntohs(wlanheader->header.size), ntohs(temp_hdr->size),
2081 sizeof(struct WlanHeader));
2086 //"receive" the message
2087 struct GNUNET_TRANSPORT_ATS_Information distance[2];
2088 distance[0].type = htonl(GNUNET_TRANSPORT_ATS_QUALITY_NET_DISTANCE);
2089 distance[0].value = htonl(1);
2090 distance[1].type = htonl(GNUNET_TRANSPORT_ATS_ARRAY_TERMINATOR);
2091 distance[1].value = htonl(0);
2094 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2095 "Calling plugin->env->receive for session %p; %s\n", session,
2096 wlan_plugin_address_to_string(NULL, session->addr, 6));
2098 plugin->env->receive(plugin->env->cls, &(session->target), temp_hdr,
2099 (const struct GNUNET_TRANSPORT_ATS_Information *) &distance, 2,
2100 session, session->addr, sizeof(session->addr));
2105 GNUNET_log(GNUNET_ERROR_TYPE_WARNING,
2106 "wlan_data_massage_handler got wrong message type\n");
2112 * function to add an ack to send it for a received fragment
2113 * @param plugin pointer to the global plugin structure
2114 * @param session pointer to the session this ack belongs to
2115 * @param fh pointer to the fragmentation header which we would like to acknolage
2119 add_ack_for_send(struct Plugin * plugin, struct Session * session,
2120 struct FragmentationHeader * fh)
2122 struct AckSendQueue * ack;
2124 GNUNET_assert(plugin != NULL);
2125 GNUNET_assert(session != NULL);
2126 GNUNET_assert(fh != NULL);
2128 ack = GNUNET_malloc(sizeof(struct AckSendQueue));
2129 ack->fragment_off_or_num = ntohs(fh->fragment_off_or_num);
2130 ack->message_id = ntohl(fh->message_id);
2131 ack->session = session;
2133 GNUNET_CONTAINER_DLL_insert_tail(plugin->ack_send_queue_head,
2134 plugin->ack_send_queue_tail, ack);
2139 * Function used for to process the data received from the wlan interface
2141 * @param cls the plugin handle
2142 * @param client client which send the data (not used)
2143 * @param hdr hdr of the GNUNET_MessageHeader
2146 wlan_data_helper(void *cls, struct Session_light * session_light,
2147 const struct GNUNET_MessageHeader * hdr)
2149 struct Plugin *plugin = cls;
2150 struct Session * session = NULL;
2152 struct FragmentationHeader * fh = NULL;
2153 struct FragmentMessage * fm = NULL;
2155 const char * tempmsg = NULL;
2157 struct AckQueue * ack = NULL;
2158 struct AckQueue * ack2 = NULL;
2160 struct RecQueue * rec_queue = NULL;
2162 if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT)
2165 //TODO better DOS protection, error handling
2166 //TODO test first than create session
2167 GNUNET_assert(session_light != NULL);
2171 GNUNET_ERROR_TYPE_DEBUG,
2172 "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT size: %u; %s\n",
2173 ntohs(hdr->size), wlan_plugin_address_to_string(NULL,session_light->addr, 6));
2176 if (session_light->session == NULL)
2178 session_light->session = get_Session(plugin, session_light->addr);
2180 GNUNET_assert(GNUNET_HELLO_get_id(
2181 (const struct GNUNET_HELLO_Message *) &hdr[1],
2182 &(session_light->session->target) ) != GNUNET_SYSERR);
2187 else if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT)
2190 GNUNET_assert(session_light != NULL);
2191 if (session_light->session == NULL)
2193 session_light->session = search_session(plugin, session_light->addr);
2195 session = session_light->session;
2197 fh = (struct FragmentationHeader *) hdr;
2198 tempmsg = (char*) &fh[1];
2202 GNUNET_ERROR_TYPE_DEBUG,
2203 "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT with message_id %u with fragment number %i, size: %u; %s\n",
2204 ntohl(fh->message_id), ntohs(fh->fragment_off_or_num), ntohs(
2205 hdr->size), wlan_plugin_address_to_string(NULL,session_light->addr, 6));
2208 if (getcrc16(tempmsg, ntohs(fh->header.size)) != ntohs(fh->message_crc))
2210 //wrong crc, dispose message
2211 GNUNET_log(GNUNET_ERROR_TYPE_INFO, "WLAN fragment crc was wrong\n");
2215 //if in the session list
2216 if (session != NULL)
2218 //TODO fragments do not timeout
2219 //check if message_id is right or it is a new msg
2220 if ((session->message_id_in == ntohs(fh->message_id))
2221 || (session->rec_size == NO_MESSAGE_OR_MESSAGE_FINISHED))
2223 session->message_id_in = ntohs(fh->message_id);
2224 if (is_double_msg(session, fh) != GNUNET_YES)
2227 //TODO ask if it is right like this
2228 if (plugin->env->traffic_report != NULL)
2230 plugin->env->traffic_report(plugin->env->cls,
2231 &session->target, ntohs(fh->header.size));
2234 = GNUNET_malloc(sizeof (struct RecQueue) +
2235 ntohs(fh->header.size) - sizeof(struct FragmentationHeader));
2236 rec_queue->size = ntohs(fh->header.size)
2237 - sizeof(struct FragmentationHeader);
2238 rec_queue->num = ntohs(fh->fragment_off_or_num);
2239 rec_queue->msg = (char*) &rec_queue[1];
2240 //copy msg to buffer
2241 memcpy((char *) rec_queue->msg, tempmsg, rec_queue->size);
2242 insert_fragment_in_queue(session, rec_queue);
2243 check_rec_finished_msg(plugin, session_light, session);
2247 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
2248 "WLAN fragment is a clone\n");
2255 GNUNET_ERROR_TYPE_INFO,
2256 "WLAN fragment message_id and session message_id are not the same and a message is already (partly) received\n");
2262 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
2263 "WLAN client not in session list and it is a fragment message\n");
2264 wlan_data_massage_handler(plugin, session_light,
2265 (struct GNUNET_MessageHeader *) tempmsg);
2266 session = session_light->session;
2267 //test if a session was created
2268 if (session == NULL)
2274 //TODO make and send ack
2275 add_ack_for_send(plugin, session, fh);
2276 check_next_fragment_timeout(plugin);
2281 else if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT_ACK)
2286 GNUNET_ERROR_TYPE_DEBUG,
2287 "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT_ACK size: %u; %s\n",
2288 ntohs(hdr->size), wlan_plugin_address_to_string(NULL,session_light->addr, 6));
2291 GNUNET_assert(session_light != NULL);
2292 if (session_light->session == NULL)
2294 session_light->session = search_session(plugin, session_light->addr);
2295 GNUNET_assert(session_light->session != NULL);
2297 session = session_light->session;
2298 fh = (struct FragmentationHeader *) hdr;
2299 if (session->message_id_out == ntohl(fh->message_id))
2301 fm = get_fragment_message_from_session(session);
2306 while (ack2 != NULL)
2309 if (ack2->fragment_num != ntohs(fh->fragment_off_or_num))
2311 // check if next ack has bigger number
2312 if (ack2->fragment_num > ntohs(fh->fragment_off_or_num))
2314 ack = GNUNET_malloc(sizeof(struct AckQueue));
2315 ack->fragment_num = ntohs(fh->fragment_off_or_num);
2316 GNUNET_CONTAINER_DLL_insert_before(fm->head,fm->tail,ack2,ack);
2318 check_finished_fragment(plugin, fm);
2327 GNUNET_ERROR_TYPE_DEBUG,
2328 "WLAN got double ack for message id %u and fragment num %u\n",
2329 session->message_id_out, ack2->fragment_num);
2336 //all acks are have smaller numbers
2337 ack = GNUNET_malloc(sizeof(struct AckQueue));
2338 ack->fragment_num = ntohs(fh->fragment_off_or_num);
2339 GNUNET_CONTAINER_DLL_insert_tail(fm->head,fm->tail,ack);
2340 check_finished_fragment(plugin, fm);
2345 GNUNET_ERROR_TYPE_WARNING,
2346 "WLAN fragment not in fragment list but id %u of ack is right\n",
2347 ntohl(fh->message_id));
2356 GNUNET_ERROR_TYPE_DEBUG,
2357 _("WLAN got ack but session->message_id_out %u and fragment id %u mismatch\n"),
2358 session->message_id_out, ntohl(fh->message_id));
2366 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
2367 "WLAN packet inside the WLAN helper packet has not the right type\n");
2372 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2373 "Helper finished\n");
2379 * Function used for to process the data from the suid process
2381 * @param cls the plugin handle
2382 * @param client client that send the data (not used)
2383 * @param hdr header of the GNUNET_MessageHeader
2387 wlan_process_helper(void *cls, void *client,
2388 const struct GNUNET_MessageHeader *hdr)
2390 struct Plugin *plugin = cls;
2391 struct IeeeHeader * wlanIeeeHeader = NULL;
2392 struct Session_light * session_light = NULL;
2393 const struct GNUNET_MessageHeader * temp_hdr = NULL;
2398 if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA)
2402 GNUNET_ERROR_TYPE_DEBUG,
2403 "Func wlan_process_helper got GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA size: %u\n",
2407 //call wlan_process_helper with the message inside, later with wlan: analyze signal
2408 GNUNET_assert(ntohs(hdr->size) >= sizeof(struct IeeeHeader) + sizeof(struct GNUNET_MessageHeader));
2409 wlanIeeeHeader = (struct IeeeHeader *) &hdr[1];
2411 //process only if it is an broadcast or for this computer both with the gnunet bssid
2414 if (memcmp(&(wlanIeeeHeader->mac2), macbc, sizeof(struct MacAddress))
2417 //check for broadcast or mac
2418 if (memcmp(&(wlanIeeeHeader->mac1), bc_all_mac,
2419 sizeof(struct MacAddress) == 0) || memcmp(
2420 &(wlanIeeeHeader->mac1), &(plugin->mac_address),
2421 sizeof(struct MacAddress)) == 0)
2424 // process the inner data
2427 datasize = ntohs(hdr->size) - sizeof(struct IeeeHeader)
2428 - sizeof(struct GNUNET_MessageHeader);
2430 session_light = GNUNET_malloc(sizeof(struct Session_light));
2431 memcpy(session_light->addr, &(wlanIeeeHeader->mac3),
2432 sizeof(struct MacAddress));
2433 //session_light->session = search_session(plugin,session_light->addr);
2436 temp_hdr = (struct GNUNET_MessageHeader *) &wlanIeeeHeader[1];
2437 while (pos < datasize)
2439 temp_hdr = (struct GNUNET_MessageHeader *) &wlanIeeeHeader[1]
2442 wlan_data_helper(plugin, session_light, temp_hdr);
2443 pos += ntohs(temp_hdr->size);
2448 GNUNET_free(session_light);
2453 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2454 "Func wlan_process_helper got wrong MAC: %s\n",
2455 wlanIeeeHeader->mac1);
2462 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2463 "Func wlan_process_helper got wrong BSSID: %s\n",
2464 wlanIeeeHeader->mac2);
2472 else if (ntohs(hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL)
2477 GNUNET_ERROR_TYPE_DEBUG,
2478 "Func wlan_process_helper got GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL size: %u\n",
2482 //TODO more control messages
2483 //TODO use struct wlan_helper_control
2484 if (ntohs(hdr->size) == sizeof(struct Wlan_Helper_Control_Message))
2486 //plugin->mac_address = GNUNET_malloc(sizeof(struct MacAddress));
2487 memcpy(&(plugin->mac_address), &hdr[1], sizeof(struct MacAddress));
2488 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2489 "Notifying transport of address %s\n",
2490 wlan_plugin_address_to_string(cls, &(plugin->mac_address), ntohs(
2491 hdr->size) - sizeof(struct GNUNET_MessageHeader)));
2492 plugin->env->notify_address(plugin->env->cls, "wlan",
2493 &plugin->mac_address, sizeof(struct MacAddress),
2494 GNUNET_TIME_UNIT_FOREVER_REL);
2498 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "Wrong wlan mac address %s\n",
2499 plugin->mac_address);
2507 GNUNET_log(GNUNET_ERROR_TYPE_INFO,
2508 "WLAN helper packet has not the right type\n");
2514 * We have been notified that wlan-helper has written something to stdout.
2515 * Handle the output, then reschedule this function to be called again once
2516 * more is available.
2518 * @param cls the plugin handle
2519 * @param tc the scheduling context
2523 wlan_plugin_helper_read(void *cls,
2524 const struct GNUNET_SCHEDULER_TaskContext *tc)
2526 struct Plugin *plugin = cls;
2527 plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK;
2531 GNUNET_log (GNUNET_ERROR_TYPE_DEBUG,
2532 "Start reading from STDIN\n");
2535 if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
2538 char mybuf[WLAN_MTU + sizeof(struct GNUNET_MessageHeader)];
2541 bytes = GNUNET_DISK_file_read(plugin->server_stdout_handle, mybuf,
2546 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2547 _("Finished reading from wlan-helper stdout with code: %d\n"),
2552 GNUNET_SERVER_mst_receive(plugin->consoltoken, NULL, mybuf, bytes, GNUNET_NO,
2555 GNUNET_assert(plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK);
2556 plugin->server_read_task = GNUNET_SCHEDULER_add_read_file(
2557 GNUNET_TIME_UNIT_FOREVER_REL, plugin->server_stdout_handle,
2558 &wlan_plugin_helper_read, plugin);
2562 * Start the gnunet-wlan-helper process.
2564 * @param plugin the transport plugin
2565 * @param testmode should we use the dummy driver for testing?
2566 * @return GNUNET_YES if process was started, GNUNET_SYSERR on error
2569 wlan_transport_start_wlan_helper(struct Plugin *plugin, int testmode)
2571 const char * filename = "gnunet-transport-wlan-helper";
2572 plugin->server_stdout = GNUNET_DISK_pipe(GNUNET_YES, GNUNET_NO, GNUNET_YES);
2573 if (plugin->server_stdout == NULL)
2574 return GNUNET_SYSERR;
2576 plugin->server_stdin = GNUNET_DISK_pipe(GNUNET_YES, GNUNET_YES, GNUNET_NO);
2577 if (plugin->server_stdin == NULL)
2578 return GNUNET_SYSERR;
2581 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2582 "Starting gnunet-wlan-helper process cmd: %s %s %i\n", filename,
2583 plugin->interface, testmode);
2585 /* Start the server process */
2587 plugin->server_proc = GNUNET_OS_start_process(plugin->server_stdin,
2588 plugin->server_stdout, filename, filename, plugin->interface, ((testmode
2589 == 1) ? "1" : (testmode == 2) ? "2" : "0"), NULL);
2590 if (plugin->server_proc == NULL)
2593 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2594 "Failed to start gnunet-wlan-helper process\n");
2596 return GNUNET_SYSERR;
2599 /* Close the write end of the read pipe */
2600 GNUNET_DISK_pipe_close_end(plugin->server_stdout, GNUNET_DISK_PIPE_END_WRITE);
2602 /* Close the read end of the write pipe */
2603 GNUNET_DISK_pipe_close_end(plugin->server_stdin, GNUNET_DISK_PIPE_END_READ);
2605 plugin->server_stdout_handle = GNUNET_DISK_pipe_handle(plugin->server_stdout,
2606 GNUNET_DISK_PIPE_END_READ);
2607 plugin->server_stdin_handle = GNUNET_DISK_pipe_handle(plugin->server_stdin,
2608 GNUNET_DISK_PIPE_END_WRITE);
2610 GNUNET_assert(plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK);
2613 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2614 "Adding server_read_task for the wlan-helper\n");
2619 plugin->server_read_task = GNUNET_SCHEDULER_add_read_file(
2620 GNUNET_TIME_UNIT_FOREVER_REL, plugin->server_stdout_handle,
2621 &wlan_plugin_helper_read, plugin);
2627 * Exit point from the plugin.
2628 * @param cls pointer to the api struct
2633 libgnunet_plugin_transport_wlan_done(void *cls)
2635 struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
2636 struct Plugin *plugin = api->cls;
2639 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG,
2640 "libgnunet_plugin_transport_wlan_done started\n");
2643 GNUNET_assert(cls !=NULL);
2645 if (plugin->consoltoken != NULL)
2646 GNUNET_SERVER_mst_destroy(plugin->consoltoken);
2648 GNUNET_free_non_null(plugin->interface);
2649 GNUNET_free (plugin);
2655 * Entry point for the plugin.
2657 * @param cls closure, the 'struct GNUNET_TRANSPORT_PluginEnvironment*'
2658 * @return the 'struct GNUNET_TRANSPORT_PluginFunctions*' or NULL on error
2661 libgnunet_plugin_transport_wlan_init(void *cls)
2663 //struct GNUNET_SERVICE_Context *service;
2664 struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
2665 struct GNUNET_TRANSPORT_PluginFunctions *api;
2666 struct Plugin *plugin;
2667 static unsigned long long testmode = 0;
2669 GNUNET_assert(cls !=NULL);
2671 plugin = GNUNET_malloc (sizeof (struct Plugin));
2673 plugin->pendingsessions = 0;
2674 plugin->session_count = 0;
2675 plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
2676 plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK;
2677 plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK;
2679 set_next_beacon_time(plugin);
2681 if (GNUNET_CONFIGURATION_have_value(env->cfg, "transport-wlan", "TESTMODE"))
2683 if (GNUNET_SYSERR == GNUNET_CONFIGURATION_get_value_number(env->cfg,
2684 "transport-wlan", "TESTMODE", &testmode))
2688 if (GNUNET_CONFIGURATION_have_value(env->cfg, "transport-wlan", "INTERFACE"))
2690 if (GNUNET_CONFIGURATION_get_value_string(env->cfg, "transport-wlan",
2691 "INTERFACE", &(plugin->interface)) != GNUNET_YES)
2693 libgnunet_plugin_transport_wlan_done(plugin);
2698 wlan_transport_start_wlan_helper(plugin, testmode);
2699 plugin->consoltoken = GNUNET_SERVER_mst_create(&wlan_process_helper, plugin);
2701 //plugin->sessions = GNUNET_malloc (sizeof (struct Sessionqueue));
2702 //plugin->pending_Sessions = GNUNET_malloc (sizeof (struct Sessionqueue));
2704 api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
2706 api->send = &wlan_plugin_send;
2707 api->disconnect = &wlan_plugin_disconnect;
2708 api->address_pretty_printer = &wlan_plugin_address_pretty_printer;
2709 api->check_address = &wlan_plugin_address_suggested;
2710 api->address_to_string = &wlan_plugin_address_to_string;
2712 start_next_message_id();
2715 GNUNET_log(GNUNET_ERROR_TYPE_DEBUG, "wlan init finished\n");
2721 /* end of plugin_transport_wlan.c */