cbab8cb0fe42acecb7a2691d22732f0c6f26cc71
[oweals/gnunet.git] / src / transport / plugin_transport_wlan.c
1 /*
2  This file is part of GNUnet
3  (C) 2010 2011 Christian Grothoff (and other contributing authors)
4
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.
9
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.
14
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.
19  */
20
21 /**
22  * @file transport/plugin_transport_wlan.c
23  * @brief transport plugin for wlan
24  * @author David Brodski
25  */
26
27 //TODO split rx and tx structures for better handling
28
29 #include "platform.h"
30 #include "gnunet_hello_lib.h"
31 #include "gnunet_protocols.h"
32 #include "gnunet_util_lib.h"
33 #include "gnunet_statistics_service.h"
34 #include "gnunet_transport_service.h"
35 #include "gnunet_transport_plugin.h"
36 #include "plugin_transport_wlan.h"
37 #include "gnunet_common.h"
38 #include "gnunet_crypto_lib.h"
39 #include "gnunet_fragmentation_lib.h"
40 #include "gnunet_constants.h"
41 //#include "wlan/ieee80211.h"
42 //#include  <netinet/ip.h>
43
44 #include <string.h>
45
46 #define PROTOCOL_PREFIX "wlan"
47
48 #define PLUGIN_LOG_NAME "wlan-plugin"
49
50 /**
51  * Max size of packet
52  */
53 #define WLAN_MTU 1430
54
55 /**
56  * time out of a session
57  */
58 #define SESSION_TIMEOUT GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT
59
60 /**
61  * time out of a mac endpoint
62  */
63 #define MACENDPOINT_TIMEOUT GNUNET_TIME_relative_multiply (GNUNET_CONSTANTS_IDLE_CONNECTION_TIMEOUT, 2)
64
65 /**
66  * scaling factor for hello beacon
67  */
68 #define HELLO_BEACON_SCALING_FACTOR 30
69
70 /**
71  * scaling factor for restarting the helper
72  */
73 #define HELPER_RESTART_SCALING_FACTOR 2
74
75 /**
76  * max size of fragment queue
77  */
78 #define FRAGMENT_QUEUE_SIZE 10
79 /**
80  * max messages in fragment queue per session/client
81  */
82 #define FRAGMENT_QUEUE_MESSAGES_OUT_PER_SESSION 1
83
84 /**
85  * max messages in fragment queue per MAC
86  */
87 #define FRAGMENT_QUEUE_MESSAGES_OUT_PER_MACENDPOINT 1
88
89 /**
90  * max messages in in queue
91  */
92 #define MESSAGES_IN_QUEUE_SIZE 10
93 /**
94  * max messages in in queue per session/client
95  */
96 #define MESSAGES_IN_DEFRAG_QUEUE_PER_MAC 1
97
98 /**
99  * LLC fields for better compatibility
100  */
101 #define WLAN_LLC_DSAP_FIELD 0x1f
102 #define WLAN_LLC_SSAP_FIELD 0x1f
103
104
105 /**
106  * DEBUG switch
107  */
108 #define DEBUG_wlan GNUNET_EXTRA_LOGGING
109 #define DEBUG_wlan_retransmission GNUNET_EXTRA_LOGGING
110 #define DEBUG_wlan_ip_udp_packets_on_air GNUNET_NO
111 #define DEBUG_wlan_msg_dump GNUNET_EXTRA_LOGGING
112
113
114 #define IEEE80211_ADDR_LEN      6       /* size of 802.11 address */
115
116 #define IEEE80211_FC0_VERSION_MASK              0x03
117 #define IEEE80211_FC0_VERSION_SHIFT             0
118 #define IEEE80211_FC0_VERSION_0                 0x00
119 #define IEEE80211_FC0_TYPE_MASK                 0x0c
120 #define IEEE80211_FC0_TYPE_SHIFT                2
121 #define IEEE80211_FC0_TYPE_MGT                  0x00
122 #define IEEE80211_FC0_TYPE_CTL                  0x04
123 #define IEEE80211_FC0_TYPE_DATA                 0x08
124
125 /*
126  * Structure of an internet header, naked of options.
127  */
128 struct iph
129 {
130 #if __BYTE_ORDER == __LITTLE_ENDIAN
131   unsigned int ip_hl:4;         /* header length */
132   unsigned int ip_v:4;          /* version */
133 #endif
134 #if __BYTE_ORDER == __BIG_ENDIAN
135   unsigned int ip_v:4;          /* version */
136   unsigned int ip_hl:4;         /* header length */
137 #endif
138   u_int8_t ip_tos;              /* type of service */
139   u_short ip_len;               /* total length */
140   u_short ip_id;                /* identification */
141   u_short ip_off;               /* fragment offset field */
142 #define IP_RF 0x8000            /* reserved fragment flag */
143 #define IP_DF 0x4000            /* dont fragment flag */
144 #define IP_MF 0x2000            /* more fragments flag */
145 #define IP_OFFMASK 0x1fff       /* mask for fragmenting bits */
146   u_int8_t ip_ttl;              /* time to live */
147   u_int8_t ip_p;                /* protocol */
148   u_short ip_sum;               /* checksum */
149   struct in_addr ip_src, ip_dst;        /* source and dest address */
150 };
151
152 struct udphdr
153 {
154   u_int16_t source;
155   u_int16_t dest;
156   u_int16_t len;
157   u_int16_t check;
158 };
159
160 /*
161  * generic definitions for IEEE 802.11 frames
162  */
163 struct ieee80211_frame
164 {
165   u_int8_t i_fc[2];
166   u_int8_t i_dur[2];
167   u_int8_t i_addr1[IEEE80211_ADDR_LEN];
168   u_int8_t i_addr2[IEEE80211_ADDR_LEN];
169   u_int8_t i_addr3[IEEE80211_ADDR_LEN];
170   u_int8_t i_seq[2];
171   u_int8_t llc[4];
172 #if DEBUG_wlan_ip_udp_packets_on_air > 1
173   struct iph ip;
174   struct udphdr udp;
175 #endif
176 } GNUNET_PACKED;
177
178 /**
179  * Encapsulation of all of the state of the plugin.
180  */
181 struct Plugin
182 {
183   /**
184    * Our environment.
185    */
186   struct GNUNET_TRANSPORT_PluginEnvironment *env;
187
188   /**
189    * List of open connections. head
190    */
191   struct MacEndpoint *mac_head;
192
193   /**
194    * List of open connections. tail
195    */
196   struct MacEndpoint *mac_tail;
197
198   /**
199    * Number of connections
200    */
201   unsigned int mac_count;
202
203   /**
204    * encapsulation of data from the local wlan helper program
205    */
206   struct GNUNET_SERVER_MessageStreamTokenizer *suid_tokenizer;
207
208   /**
209    * encapsulation of packets received from the wlan helper
210    */
211   struct GNUNET_SERVER_MessageStreamTokenizer *data_tokenizer;
212
213   /**
214    * stdout pipe handle for the gnunet-wlan-helper process
215    */
216   struct GNUNET_DISK_PipeHandle *server_stdout;
217
218   /**
219    * stdout file handle for the gnunet-wlan-helper process
220    */
221   const struct GNUNET_DISK_FileHandle *server_stdout_handle;
222
223   /**
224    * stdin pipe handle for the gnunet-wlan-helper process
225    */
226   struct GNUNET_DISK_PipeHandle *server_stdin;
227
228   /**
229    * stdin file handle for the gnunet-wlan-helper process
230    */
231   const struct GNUNET_DISK_FileHandle *server_stdin_handle;
232
233   /**
234    * ID of the gnunet-wlan-server std read task
235    */
236   GNUNET_SCHEDULER_TaskIdentifier server_read_task;
237
238   /**
239    * ID of the gnunet-wlan-server std read task
240    */
241   GNUNET_SCHEDULER_TaskIdentifier server_write_task;
242
243   /**
244    * ID of the delay task for writing
245    */
246   GNUNET_SCHEDULER_TaskIdentifier server_write_delay_task;
247
248   /**
249    * The process id of the wlan process
250    */
251   struct GNUNET_OS_Process *server_proc;
252
253   /**
254    * The interface of the wlan card given to us by the user.
255    */
256   char *interface;
257
258   /**
259    * Mode of operation for the helper, 0 = normal, 1 = first loopback, 2 = second loopback
260    */
261   long long unsigned int testmode;
262
263   /**
264    * The mac_address of the wlan card given to us by the helper.
265    */
266   struct MacAddress mac_address;
267
268   /**
269    * Sessions currently pending for transmission
270    * to a peer, if any.
271    */
272   struct Sessionqueue *pending_Sessions_head;
273
274   /**
275    * Sessions currently pending for transmission
276    * to a peer (tail), if any.
277    */
278   struct Sessionqueue *pending_Sessions_tail;
279
280   /**
281    * number of pending sessions
282    */
283   unsigned int pendingsessions;
284
285   /**
286    * Messages in the sending queues
287    */
288   int pending_Fragment_Messages;
289
290   /**
291    * messages ready for send, head
292    */
293   struct FragmentMessage_queue *sending_messages_head;
294   /**
295    * messages ready for send, tail
296    */
297   struct FragmentMessage_queue *sending_messages_tail;
298   /**
299    * time of the next "hello-beacon"
300    */
301   struct GNUNET_TIME_Absolute beacon_time;
302
303   /**
304    * queue to send acks for received fragments (head)
305    */
306   struct AckSendQueue *ack_send_queue_head;
307
308   /**
309    * queue to send acks for received fragments (tail)
310    */
311   struct AckSendQueue *ack_send_queue_tail;
312
313   /**
314    * Tracker for bandwidth limit
315    */
316   struct GNUNET_BANDWIDTH_Tracker tracker;
317 };
318
319 /**
320  * Struct to store data if file write did not accept the whole packet
321  */
322 struct Finish_send
323 {
324   /**
325    * pointer to the global plugin struct
326    */
327   struct Plugin *plugin;
328
329   /**
330    * head of the next part to send to the helper
331    */
332   char *head_of_next_write;
333
334   /**
335    * Start of the message to send, needed for free
336    */
337   struct GNUNET_MessageHeader *msgstart;
338
339   /**
340    * rest size to send
341    */
342   ssize_t size;
343 };
344
345 /**
346  * Queue of sessions, for the general session queue and the pending session queue
347  */
348 //TODO DOXIGEN
349 struct Sessionqueue
350 {
351   struct Sessionqueue *next;
352   struct Sessionqueue *prev;
353   struct Session *content;
354 };
355
356 /**
357  * Queue of fragmented messages, for the sending queue of the plugin
358  */
359 //TODO DOXIGEN
360 struct FragmentMessage_queue
361 {
362   struct FragmentMessage_queue *next;
363   struct FragmentMessage_queue *prev;
364   struct FragmentMessage *content;
365 };
366
367 /**
368  * Queue for the fragments received
369  */
370 //TODO DOXIGEN
371 struct Receive_Fragment_Queue
372 {
373   struct Receive_Fragment_Queue *next;
374   struct Receive_Fragment_Queue *prev;
375   uint16_t num;
376   const char *msg;
377   uint16_t size;
378   struct Radiotap_rx rxinfo;
379 };
380
381 //TODO DOXIGEN
382 struct MacEndpoint_id_fragment_triple
383 {
384   struct MacEndpoint *endpoint;
385   uint32_t message_id;
386   struct FragmentMessage *fm;
387 };
388
389 //TODO DOXIGEN
390 struct Plugin_Session_pair
391 {
392   struct Plugin *plugin;
393   struct Session *session;
394 };
395
396 /**
397  * Information kept for each message that is yet to
398  * be transmitted.
399  */
400 struct PendingMessage
401 {
402   /**
403    * dll next
404    */
405   struct PendingMessage *next;
406   /**
407    * dll prev
408    */
409   struct PendingMessage *prev;
410
411   /**
412    * The pending message
413    */
414   struct WlanHeader *msg;
415
416   /**
417    * Size of the message
418    */
419   size_t message_size;
420
421   /**
422    * Continuation function to call once the message
423    * has been sent.  Can be NULL if there is no
424    * continuation to call.
425    */
426   GNUNET_TRANSPORT_TransmitContinuation transmit_cont;
427
428   /**
429    * Cls for transmit_cont
430    */
431   void *transmit_cont_cls;
432
433   /**
434    * Timeout value for the pending message.
435    */
436   struct GNUNET_TIME_Absolute timeout;
437
438 };
439
440 /**
441  * Queue for acks to send for fragments recived
442  */
443 struct AckSendQueue
444 {
445
446   /**
447    * next ack in the ack send queue
448    */
449   struct AckSendQueue *next;
450   /**
451    * previous ack in the ack send queue
452    */
453   struct AckSendQueue *prev;
454   /**
455    * pointer to the session this ack belongs to
456    */
457   struct MacEndpoint *endpoint;
458   /**
459    * ID of message, to distinguish between the messages, picked randomly.
460    */
461   uint32_t message_id;
462
463   /**
464    * msg to send
465    */
466   struct GNUNET_MessageHeader *hdr;
467   /**
468    * pointer to the ieee wlan header
469    */
470   struct ieee80211_frame *ieeewlanheader;
471   /**
472    * pointer to the radiotap header
473    */
474   struct Radiotap_Send *radioHeader;
475 };
476
477 /**
478  * Session infos gathered from a messages
479  */
480
481 struct Session_light
482 {
483   /**
484    * the session this message belongs to
485    */
486   struct Session *session;
487   /**
488    * peer mac address
489    */
490   struct MacAddress addr;
491
492   /**
493    * mac endpoint
494    */
495   struct MacEndpoint *macendpoint;
496 };
497
498 /**
499  * Session handle for connections.
500  */
501 struct Session
502 {
503
504   /**
505    * API requirement.
506    */
507   struct SessionHeader header;
508
509   /**
510    * Message currently pending for transmission
511    * to this peer, if any. head
512    */
513   struct PendingMessage *pending_message_head;
514
515   /**
516    * Message currently pending for transmission
517    * to this peer, if any. tail
518    */
519   struct PendingMessage *pending_message_tail;
520
521   /**
522    * To whom are we talking to (set to our identity
523    * if we are still waiting for the welcome message)
524    */
525   struct GNUNET_PeerIdentity target;
526
527   /**
528    * Address of the other peer (either based on our 'connect'
529    * call or on our 'accept' call).
530    */
531   void *connect_addr;
532
533   /**
534    * Last activity on this connection.  Used to select preferred
535    * connection and timeout
536    */
537   struct GNUNET_TIME_Absolute last_activity;
538
539   /**
540    * Timeout task.
541    */
542   GNUNET_SCHEDULER_TaskIdentifier timeout_task;
543
544   /**
545    * peer connection
546    */
547   struct MacEndpoint *mac;
548
549   /**
550    * count of messages in the fragment out queue for this session
551    */
552
553   int fragment_messages_out_count;
554
555 };
556
557 /**
558  * Struct to represent one network card connection
559  */
560 struct MacEndpoint
561 {
562   /**
563    * Pointer to the global plugin struct.
564    */
565   struct Plugin *plugin;
566   /**
567    * Struct to hold the session reachable over this mac; head
568    */
569   struct Sessionqueue *sessions_head;
570   /**
571    * Struct to hold the session reachable over this mac; tail
572    */
573   struct Sessionqueue *sessions_tail;
574   /**
575    * Messages currently sending
576    * to a peer, if any.
577    */
578   struct FragmentMessage *sending_messages_head;
579
580   /**
581    * Messages currently sending
582    * to a peer (tail), if any.
583    */
584   struct FragmentMessage *sending_messages_tail;
585   /**
586    * dll next
587    */
588   struct MacEndpoint *next;
589   /**
590    * dll prev
591    */
592   struct MacEndpoint *prev;
593
594   /**
595    * peer mac address
596    */
597   struct MacAddress addr;
598
599   /**
600    * Defrag context for this mac endpoint
601    */
602   struct GNUNET_DEFRAGMENT_Context *defrag;
603
604   /**
605    * count of messages in the fragment out queue for this mac endpoint
606    */
607
608   int fragment_messages_out_count;
609
610   //TODO DOXIGEN
611   uint8_t rate;
612   uint16_t tx_power;
613   uint8_t antenna;
614
615   /**
616    * Duplicates received
617    */
618   int dups;
619
620   /**
621    * Fragments received
622    */
623   int fragc;
624
625   /**
626    * Acks received
627    */
628   int acks;
629
630   /**
631    * Last activity on this endpoint.  Used to select preferred
632    * connection.
633    */
634   struct GNUNET_TIME_Absolute last_activity;
635
636   /**
637    * Timeout task.
638    */
639   GNUNET_SCHEDULER_TaskIdentifier timeout_task;
640 };
641
642 /**
643  * Struct for Messages in the fragment queue
644  */
645
646 struct FragmentMessage
647 {
648
649   /**
650    * Session this message belongs to
651    */
652
653   struct Session *session;
654
655   /**
656    * This is a doubly-linked list.
657    */
658   struct FragmentMessage *next;
659
660   /**
661    * This is a doubly-linked list.
662    */
663   struct FragmentMessage *prev;
664
665   /**
666    * Fragmentation context
667    */
668   struct GNUNET_FRAGMENT_Context *fragcontext;
669
670   /**
671    * Timeout value for the message.
672    */
673   struct GNUNET_TIME_Absolute timeout;
674
675   /**
676    * Timeout task.
677    */
678   GNUNET_SCHEDULER_TaskIdentifier timeout_task;
679
680   /**
681    * Fragment to send
682    */
683   char *frag;
684
685   /**
686    * size of message
687    */
688   size_t size;
689
690   /**
691    * pointer to the ieee wlan header
692    */
693   struct ieee80211_frame *ieeewlanheader;
694   /**
695    * pointer to the radiotap header
696    */
697   struct Radiotap_Send *radioHeader;
698 };
699
700 static void
701 do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
702 static void
703 free_session (struct Plugin *plugin, struct Sessionqueue *queue,
704               int do_free_macendpoint);
705 static struct MacEndpoint *
706 create_macendpoint (struct Plugin *plugin, const struct MacAddress *addr);
707
708 static void
709 finish_sending (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
710
711 /**
712  * Generates a nice hexdump of a memory area.
713  *
714  * \param  mem     pointer to memory to dump
715  * \param  length  how many bytes to dump
716  */
717 static void
718 hexdump (const void *mem, unsigned length)
719 {
720   char line[80];
721   char *src = (char *) mem;
722
723   printf ("dumping %u bytes from %p\r\n"
724           "       0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F    0123456789ABCDEF\r\n",
725           length, src);
726   unsigned i;
727   int j;
728
729   for (i = 0; i < length; i += 16, src += 16)
730   {
731     char *t = line;
732
733     t += sprintf (t, "%04x:  ", i);
734     for (j = 0; j < 16; j++)
735     {
736       if (i + j < length)
737         t += sprintf (t, "%02X", src[j] & 0xff);
738       else
739         t += sprintf (t, "  ");
740
741       t += sprintf (t, j % 2 ? " " : "-");
742     }
743
744     t += sprintf (t, "  ");
745     for (j = 0; j < 16; j++)
746     {
747       if (i + j < length)
748       {
749         if (isprint ((unsigned char) src[j]))
750           t += sprintf (t, "%c", src[j]);
751         else
752           t += sprintf (t, ".");
753       }
754       else
755       {
756         t += sprintf (t, " ");
757       }
758     }
759
760     t += sprintf (t, "\r\n");
761     printf ("%s", line);
762   }
763 }
764
765 /**
766  * Function to find a MacEndpoint with a specific mac addr
767  * @param plugin pointer to the plugin struct
768  * @param addr pointer to the mac address
769  * @param create_new GNUNET_YES if a new end point should be created
770  * @return
771  */
772 static struct MacEndpoint *
773 get_macendpoint (struct Plugin *plugin, const struct MacAddress *addr,
774                  int create_new)
775 {
776   struct MacEndpoint *queue = plugin->mac_head;
777
778   while (queue != NULL)
779   {
780     //GNUNET_assert (queue->sessions_head != NULL);
781     if (memcmp (addr, &queue->addr, sizeof (struct MacAddress)) == 0)
782       return queue;             /* session found */
783     queue = queue->next;
784   }
785
786   if (create_new == GNUNET_YES)
787   {
788     return create_macendpoint (plugin, addr);
789   }
790   else
791   {
792     return NULL;
793   }
794
795 }
796
797 /**
798  * search for a session with the macendpoint and peer id
799  *
800  * @param plugin pointer to the plugin struct
801  * @param endpoint pointer to the mac endpoint of the peer
802  * @param peer pointer to the peerid
803  * @return returns the session
804  */
805 static struct Session *
806 search_session (struct Plugin *plugin, const struct MacEndpoint *endpoint,
807                 const struct GNUNET_PeerIdentity *peer)
808 {
809   GNUNET_assert (endpoint != NULL);
810   struct Sessionqueue *queue = endpoint->sessions_head;
811
812   while (queue != NULL)
813   {
814     GNUNET_assert (queue->content != NULL);
815     if (memcmp
816         (peer, &queue->content->target,
817          sizeof (struct GNUNET_PeerIdentity)) == 0)
818       return queue->content;    /* session found */
819     queue = queue->next;
820   }
821   return NULL;
822 }
823
824 /**
825  * Function called for a quick conversion of the binary address to
826  * a numeric address.  Note that the caller must not free the
827  * address and that the next call to this function is allowed
828  * to override the address again.
829  *
830  * @param cls closure
831  * @param addr binary address
832  * @param addrlen length of the address
833  * @return string representing the same address
834  */
835 static const char *
836 wlan_plugin_address_to_string (void *cls, const void *addr, size_t addrlen)
837 {
838   static char ret[40];
839   const struct MacAddress *mac;
840
841   if (addrlen != sizeof (struct MacAddress))
842   {
843     GNUNET_break (0);
844     return NULL;
845   }
846   mac = addr;
847   GNUNET_snprintf (ret, sizeof (ret), "%s Mac-Address %X:%X:%X:%X:%X:%X",
848                    PROTOCOL_PREFIX, mac->mac[0], mac->mac[1], mac->mac[2],
849                    mac->mac[3], mac->mac[4], mac->mac[5]);
850
851   return ret;
852 }
853
854 /**
855  * Function for the scheduler if a session times out
856  * @param cls pointer to the Sessionqueue
857  * @param tc pointer to the GNUNET_SCHEDULER_TaskContext
858  */
859 static void
860 session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
861 {
862   struct Sessionqueue *queue = cls;
863
864   GNUNET_assert (queue != NULL);
865   GNUNET_assert (queue->content != NULL);
866   queue->content->timeout_task = GNUNET_SCHEDULER_NO_TASK;
867   if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
868   {
869     return;
870   }
871   if (GNUNET_TIME_absolute_get_remaining
872       (GNUNET_TIME_absolute_add
873        (queue->content->last_activity, SESSION_TIMEOUT)).rel_value == 0)
874   {
875
876     GNUNET_assert (queue->content->mac != NULL);
877     GNUNET_assert (queue->content->mac->plugin != NULL);
878     GNUNET_STATISTICS_update (queue->content->mac->plugin->env->stats,
879                               _("# wlan session timeouts"), 1, GNUNET_NO);
880     free_session (queue->content->mac->plugin, queue, GNUNET_YES);
881   }
882   else
883   {
884     queue->content->timeout_task =
885         GNUNET_SCHEDULER_add_delayed (SESSION_TIMEOUT, &session_timeout, queue);
886   }
887 }
888
889 /**
890  * create a new session
891  *
892  * @param plugin pointer to the plugin struct
893  * @param endpoint pointer to the mac endpoint of the peer
894  * @param peer peer identity to use for this session
895  * @return returns the session
896  */
897
898 static struct Session *
899 create_session (struct Plugin *plugin, struct MacEndpoint *endpoint,
900                 const struct GNUNET_PeerIdentity *peer)
901 {
902   GNUNET_assert (endpoint != NULL);
903   GNUNET_assert (plugin != NULL);
904   GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan session created"), 1,
905                             GNUNET_NO);
906   struct Sessionqueue *queue =
907       GNUNET_malloc (sizeof (struct Sessionqueue) + sizeof (struct Session));
908
909   GNUNET_CONTAINER_DLL_insert_tail (endpoint->sessions_head,
910                                     endpoint->sessions_tail, queue);
911
912   queue->content = (struct Session *) &queue[1];
913   queue->content->mac = endpoint;
914   memcpy (&(queue->content->target), peer, sizeof (struct GNUNET_PeerIdentity));
915   queue->content->last_activity = GNUNET_TIME_absolute_get ();
916   queue->content->timeout_task =
917       GNUNET_SCHEDULER_add_delayed (SESSION_TIMEOUT, &session_timeout, queue);
918
919 #if DEBUG_wlan
920   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
921                    "New session %p with endpoint %p: %s\n", queue->content,
922                    endpoint, wlan_plugin_address_to_string (NULL,
923                                                             endpoint->addr.mac,
924                                                             6));
925 #endif
926
927   return queue->content;
928 }
929
930 /**
931  * Get session from address, create if no session exists
932  *
933  * @param plugin pointer to the plugin struct
934  * @param addr pointer to the mac address of the peer
935  * @param peer pointer to the peerid
936  * @return returns the session
937  */
938 static struct Session *
939 get_session (struct Plugin *plugin, const struct MacAddress *addr,
940              const struct GNUNET_PeerIdentity *peer)
941 {
942   struct MacEndpoint *mac;
943
944   mac = get_macendpoint (plugin, addr, GNUNET_YES);
945   struct Session *session = search_session (plugin, mac, peer);
946
947   if (session != NULL)
948     return session;
949   return create_session (plugin, mac, peer);
950 }
951
952 /**
953  * Queue the session to send data
954  * checks if there is a message pending
955  * checks if this session is not allready in the queue
956  * @param plugin pointer to the plugin
957  * @param session pointer to the session to add
958  */
959 static void
960 queue_session (struct Plugin *plugin, struct Session *session)
961 {
962   struct Sessionqueue *queue = plugin->pending_Sessions_head;
963
964   if (session->pending_message_head != NULL)
965   {
966     while (queue != NULL)
967     {
968       // content is never NULL
969       GNUNET_assert (queue->content != NULL);
970       // is session already in queue?
971       if (session == queue->content)
972       {
973         return;
974       }
975       // try next
976       queue = queue->next;
977     }
978
979     // Session is not in the queue
980
981     queue = GNUNET_malloc (sizeof (struct Sessionqueue));
982     queue->content = session;
983
984     //insert at the tail
985     GNUNET_CONTAINER_DLL_insert_tail (plugin->pending_Sessions_head,
986                                       plugin->pending_Sessions_tail, queue);
987     plugin->pendingsessions++;
988     GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"),
989                            plugin->pendingsessions, GNUNET_NO);
990   }
991
992 }
993
994 /**
995  * Function to schedule the write task, executed after a delay
996  * @param cls pointer to the plugin struct
997  * @param tc GNUNET_SCHEDULER_TaskContext pointer
998  */
999 static void
1000 delay_fragment_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1001 {
1002   struct Plugin *plugin = cls;
1003
1004   plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK;
1005
1006   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
1007     return;
1008
1009   // GNUNET_TIME_UNIT_FOREVER_REL is needed to clean up old msg
1010   if (plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK)
1011   {
1012     plugin->server_write_task =
1013         GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
1014                                          plugin->server_stdin_handle,
1015                                          &do_transmit, plugin);
1016   }
1017 }
1018
1019 /**
1020  * Function to calculate the time of the next periodic "hello-beacon"
1021  * @param plugin pointer to the plugin struct
1022  */
1023
1024 static void
1025 set_next_beacon_time (struct Plugin *const plugin)
1026 {
1027   //under 10 known peers: once a second
1028   if (plugin->mac_count < 10)
1029   {
1030     plugin->beacon_time =
1031         GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
1032                                   GNUNET_TIME_relative_multiply
1033                                   (GNUNET_TIME_UNIT_SECONDS,
1034                                    HELLO_BEACON_SCALING_FACTOR));
1035   }
1036   //under 30 known peers: every 10 seconds
1037   else if (plugin->mac_count < 30)
1038   {
1039     plugin->beacon_time =
1040         GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
1041                                   GNUNET_TIME_relative_multiply
1042                                   (GNUNET_TIME_UNIT_SECONDS,
1043                                    10 * HELLO_BEACON_SCALING_FACTOR));
1044   }
1045   //over 30 known peers: once a minute
1046   else
1047   {
1048     plugin->beacon_time =
1049         GNUNET_TIME_absolute_add (GNUNET_TIME_absolute_get (),
1050                                   GNUNET_TIME_relative_multiply
1051                                   (GNUNET_TIME_UNIT_MINUTES,
1052                                    HELLO_BEACON_SCALING_FACTOR));
1053   }
1054 }
1055
1056 /**
1057  * Function to set the timer for the next timeout of the fragment queue
1058  * @param plugin the handle to the plugin struct
1059  */
1060
1061 static void
1062 set_next_send (struct Plugin *const plugin)
1063 {
1064   struct GNUNET_TIME_Relative next_send;
1065
1066   //cancel old task
1067   if (plugin->server_write_delay_task != GNUNET_SCHEDULER_NO_TASK)
1068   {
1069     GNUNET_SCHEDULER_cancel (plugin->server_write_delay_task);
1070     plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK;
1071   }
1072
1073   //check if some acks are in the queue
1074   if (plugin->ack_send_queue_head != NULL)
1075   {
1076     next_send = GNUNET_TIME_UNIT_ZERO;
1077   }
1078
1079   //check if there are some fragments in the queue
1080   else if (plugin->sending_messages_head != NULL)
1081   {
1082     next_send = GNUNET_TIME_UNIT_ZERO;
1083   }
1084   else
1085   {
1086     next_send = GNUNET_TIME_absolute_get_remaining (plugin->beacon_time);
1087   }
1088
1089 #if DEBUG_wlan
1090   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
1091                    "Next packet is send in: %u\n", next_send.rel_value);
1092 #endif
1093
1094   if (next_send.rel_value == GNUNET_TIME_UNIT_ZERO.rel_value)
1095   {
1096     if (plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK)
1097     {
1098       plugin->server_write_task =
1099           GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
1100                                            plugin->server_stdin_handle,
1101                                            &do_transmit, plugin);
1102     }
1103   }
1104   else
1105   {
1106     if (plugin->server_write_delay_task == GNUNET_SCHEDULER_NO_TASK)
1107     {
1108       plugin->server_write_delay_task =
1109           GNUNET_SCHEDULER_add_delayed (next_send, &delay_fragment_task,
1110                                         plugin);
1111     }
1112   }
1113 }
1114
1115 /**
1116  * Function to get the next queued Session, removes the session from the queue
1117  * @param plugin pointer to the plugin struct
1118  * @return pointer to the session found, returns NULL if there is now session in the queue
1119  */
1120 static struct Session *
1121 get_next_queue_session (struct Plugin *plugin)
1122 {
1123   struct Session *session;
1124   struct Sessionqueue *sessionqueue;
1125   struct Sessionqueue *sessionqueue_alt;
1126   struct PendingMessage *pm;
1127
1128   sessionqueue = plugin->pending_Sessions_head;
1129
1130   while (sessionqueue != NULL)
1131   {
1132     session = sessionqueue->content;
1133
1134     GNUNET_assert (session != NULL);
1135     pm = session->pending_message_head;
1136
1137     if (pm == NULL)
1138     {
1139 #if DEBUG_wlan
1140       GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
1141                        "pending message is empty, should not happen. session %p\n",
1142                        session);
1143 #endif
1144       sessionqueue_alt = sessionqueue;
1145       sessionqueue = sessionqueue->next;
1146       plugin->pendingsessions--;
1147       GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"),
1148                              plugin->pendingsessions, GNUNET_NO);
1149       GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head,
1150                                    plugin->pending_Sessions_tail,
1151                                    sessionqueue_alt);
1152
1153       GNUNET_free (sessionqueue_alt);
1154       continue;
1155
1156     }
1157
1158     //check for message timeout
1159     if (GNUNET_TIME_absolute_get_remaining (pm->timeout).rel_value > 0)
1160     {
1161       //check if session has no message in the fragment queue
1162       if ((session->mac->fragment_messages_out_count <
1163            FRAGMENT_QUEUE_MESSAGES_OUT_PER_MACENDPOINT) &&
1164           (session->fragment_messages_out_count <
1165            FRAGMENT_QUEUE_MESSAGES_OUT_PER_SESSION))
1166       {
1167         plugin->pendingsessions--;
1168         GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"),
1169                                plugin->pendingsessions, GNUNET_NO);
1170         GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head,
1171                                      plugin->pending_Sessions_tail,
1172                                      sessionqueue);
1173         GNUNET_free (sessionqueue);
1174
1175         return session;
1176       }
1177       else
1178       {
1179         sessionqueue = sessionqueue->next;
1180       }
1181     }
1182     else
1183     {
1184       GNUNET_CONTAINER_DLL_remove (session->pending_message_head,
1185                                    session->pending_message_tail, pm);
1186
1187       //call the cont func that it did not work
1188       if (pm->transmit_cont != NULL)
1189         pm->transmit_cont (pm->transmit_cont_cls, &(session->target),
1190                            GNUNET_SYSERR);
1191       GNUNET_free (pm->msg);
1192       GNUNET_free (pm);
1193
1194       if (session->pending_message_head == NULL)
1195       {
1196         sessionqueue_alt = sessionqueue;
1197         sessionqueue = sessionqueue->next;
1198         plugin->pendingsessions--;
1199         GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"),
1200                                plugin->pendingsessions, GNUNET_NO);
1201         GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head,
1202                                      plugin->pending_Sessions_tail,
1203                                      sessionqueue_alt);
1204
1205         GNUNET_free (sessionqueue_alt);
1206       }
1207     }
1208
1209   }
1210   return NULL;
1211 }
1212
1213 /**
1214  * frees the space of a message in the fragment queue (send queue)
1215  * @param plugin the plugin struct
1216  * @param fm message to free
1217  */
1218 static void
1219 free_fragment_message (struct Plugin *plugin, struct FragmentMessage *fm)
1220 {
1221   struct Session *session = fm->session;
1222   struct MacEndpoint *endpoint = session->mac;
1223   struct FragmentMessage_queue *fmq;
1224   struct FragmentMessage_queue *fmq_next;
1225
1226   fmq = plugin->sending_messages_head;
1227   while (fmq != NULL)
1228   {
1229     fmq_next = fmq->next;
1230     if (fmq->content == fm)
1231     {
1232       GNUNET_CONTAINER_DLL_remove (plugin->sending_messages_head,
1233                                    plugin->sending_messages_tail, fmq);
1234       GNUNET_free (fmq);
1235     }
1236     fmq = fmq_next;
1237   }
1238
1239   (session->mac->fragment_messages_out_count)--;
1240   session->fragment_messages_out_count--;
1241   plugin->pending_Fragment_Messages--;
1242   GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending fragments"),
1243                          plugin->pending_Fragment_Messages, GNUNET_NO);
1244   GNUNET_CONTAINER_DLL_remove (endpoint->sending_messages_head,
1245                                endpoint->sending_messages_tail, fm);
1246   GNUNET_FRAGMENT_context_destroy (fm->fragcontext);
1247   if (fm->timeout_task != GNUNET_SCHEDULER_NO_TASK)
1248   {
1249     GNUNET_SCHEDULER_cancel (fm->timeout_task);
1250     fm->timeout_task = GNUNET_SCHEDULER_NO_TASK;
1251   }
1252
1253   GNUNET_free (fm);
1254
1255   queue_session (plugin, session);
1256 #if DEBUG_wlan
1257   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
1258                    "Free pending fragment messages %p, session %p\n", fm,
1259                    session);
1260 #endif
1261 }
1262
1263 /**
1264  * function to fill the radiotap header
1265  * @param plugin pointer to the plugin struct
1266  * @param endpoint pointer to the endpoint
1267  * @param header pointer to the radiotap header
1268  * @return GNUNET_YES at success
1269  */
1270 static int
1271 getRadiotapHeader (struct Plugin *plugin, struct MacEndpoint *endpoint,
1272                    struct Radiotap_Send *header)
1273 {
1274
1275   if (endpoint != NULL)
1276   {
1277     header->rate = endpoint->rate;
1278     header->tx_power = endpoint->tx_power;
1279     header->antenna = endpoint->antenna;
1280   }
1281   else
1282   {
1283     header->rate = 255;
1284     header->tx_power = 0;
1285     header->antenna = 0;
1286   }
1287
1288   return GNUNET_YES;
1289 }
1290
1291 /**
1292  * function to generate the wlan hardware header for one packet
1293  * @param Header address to write the header to
1294  * @param to_mac_addr address of the recipient
1295  * @param plugin pointer to the plugin struct
1296  * @param size size of the whole packet, needed to calculate the time to send the packet
1297  * @return GNUNET_YES if there was no error
1298  */
1299 static int
1300 getWlanHeader (struct ieee80211_frame *Header,
1301                const struct MacAddress *to_mac_addr, struct Plugin *plugin,
1302                unsigned int size)
1303 {
1304   uint16_t *tmp16;
1305   const int rate = 11000000;
1306
1307   Header->i_fc[0] = IEEE80211_FC0_TYPE_DATA;
1308   Header->i_fc[1] = 0x00;
1309   memcpy (&Header->i_addr3, &mac_bssid, sizeof (mac_bssid));
1310   memcpy (&Header->i_addr2, plugin->mac_address.mac,
1311           sizeof (plugin->mac_address));
1312   memcpy (&Header->i_addr1, to_mac_addr, sizeof (struct MacAddress));
1313
1314   tmp16 = (uint16_t *) Header->i_dur;
1315   *tmp16 = (uint16_t) htole16 ((size * 1000000) / rate + 290);
1316   Header->llc[0] = WLAN_LLC_DSAP_FIELD;
1317   Header->llc[1] = WLAN_LLC_SSAP_FIELD;
1318
1319 #if DEBUG_wlan_ip_udp_packets_on_air > 1
1320   uint crc = 0;
1321   uint16_t *x;
1322   int count;
1323
1324   Header->ip.ip_dst.s_addr = *((uint32_t *) & to_mac_addr->mac[2]);
1325   Header->ip.ip_src.s_addr = *((uint32_t *) & plugin->mac_address.mac[2]);
1326   Header->ip.ip_v = 4;
1327   Header->ip.ip_hl = 5;
1328   Header->ip.ip_p = 17;
1329   Header->ip.ip_ttl = 1;
1330   Header->ip.ip_len = htons (size + 8);
1331   Header->ip.ip_sum = 0;
1332   x = (uint16_t *) & Header->ip;
1333   count = sizeof (struct iph);
1334   while (count > 1)
1335   {
1336     /* This is the inner loop */
1337     crc += (unsigned short) *x++;
1338     count -= 2;
1339   }
1340   /* Add left-over byte, if any */
1341   if (count > 0)
1342     crc += *(unsigned char *) x;
1343   crc = (crc & 0xffff) + (crc >> 16);
1344   Header->ip.ip_sum = htons (~(unsigned short) crc);
1345   Header->udp.len = htons (size - sizeof (struct ieee80211_frame));
1346
1347 #endif
1348
1349   return GNUNET_YES;
1350 }
1351
1352 /**
1353  * 32bit CRC
1354  *
1355  * @param msgbuf pointer tor the data
1356  * @param msgbuf_size size of the data
1357  *
1358  * @return 32bit crc value
1359  */
1360
1361 uint32_t
1362 getcrc32 (const char *msgbuf, size_t msgbuf_size)
1363 {
1364
1365   return GNUNET_CRYPTO_crc32_n (msgbuf, msgbuf_size);;
1366 }
1367
1368 /**
1369  * 16bit CRC
1370  *
1371  * @param msgbuf pointer tor the data
1372  * @param msgbuf_size size of the data
1373  *
1374  * @return 16bit crc value
1375  */
1376
1377 uint16_t
1378 getcrc16 (const char *msgbuf, size_t msgbuf_size)
1379 {
1380   //TODO calc some crc
1381   return 0;
1382 }
1383
1384 /**
1385  * function to add a fragment of a message to send
1386  * @param cls FragmentMessage this message belongs to
1387  * @param hdr pointer to the start of the message
1388  */
1389
1390 void
1391 add_message_for_send (void *cls, const struct GNUNET_MessageHeader *hdr)
1392 {
1393
1394   struct FragmentMessage *fm = cls;
1395   struct FragmentMessage_queue *fmqueue;
1396
1397   GNUNET_assert (cls != NULL);
1398   GNUNET_assert (fm->frag == NULL);
1399   struct MacEndpoint *endpoint = fm->session->mac;
1400   struct Plugin *plugin = endpoint->plugin;
1401   struct GNUNET_MessageHeader *msgheader;
1402   struct GNUNET_MessageHeader *msgheader2;
1403   uint16_t size;
1404
1405 #if DEBUG_wlan_retransmission > 1
1406   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
1407                    "Adding fragment of message %p to send, session %p, endpoint %p, type %u\n",
1408                    fm, fm->session, endpoint, hdr->type);
1409 #endif
1410
1411   size =
1412       sizeof (struct GNUNET_MessageHeader) + sizeof (struct Radiotap_Send) +
1413       sizeof (struct ieee80211_frame) + ntohs (hdr->size);
1414   fm->frag = GNUNET_malloc (size);
1415   fm->size = size;
1416
1417   msgheader = (struct GNUNET_MessageHeader *) fm->frag;
1418   msgheader->size = htons (size);
1419   msgheader->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
1420
1421   fm->radioHeader = (struct Radiotap_Send *) &msgheader[1];
1422   fm->ieeewlanheader = (struct ieee80211_frame *) &fm->radioHeader[1];
1423   msgheader2 = (struct GNUNET_MessageHeader *) &fm->ieeewlanheader[1];
1424   memcpy (msgheader2, hdr, ntohs (hdr->size));
1425
1426   fmqueue = GNUNET_malloc (sizeof (struct FragmentMessage_queue));
1427   fmqueue->content = fm;
1428
1429   GNUNET_CONTAINER_DLL_insert_tail (plugin->sending_messages_head,
1430                                     plugin->sending_messages_tail, fmqueue);
1431   set_next_send (plugin);
1432 }
1433
1434
1435 /**
1436  * We have been notified that wlan-helper has written something to stdout.
1437  * Handle the output, then reschedule this function to be called again once
1438  * more is available.
1439  *
1440  * @param cls the plugin handle
1441  * @param tc the scheduling context
1442  */
1443 static void
1444 wlan_plugin_helper_read (void *cls,
1445                          const struct GNUNET_SCHEDULER_TaskContext *tc)
1446 {
1447   struct Plugin *plugin = cls;
1448
1449   plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK;
1450
1451   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
1452     return;
1453
1454   char mybuf[WLAN_MTU + sizeof (struct GNUNET_MessageHeader)];
1455   ssize_t bytes;
1456
1457   bytes =
1458       GNUNET_DISK_file_read (plugin->server_stdout_handle, mybuf,
1459                              sizeof (mybuf));
1460   if (bytes <= 0)
1461   {
1462 #if DEBUG_wlan
1463     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
1464                      _
1465                      ("Finished reading from wlan-helper stdout with code: %d\n"),
1466                      bytes);
1467 #endif
1468     return;
1469   }
1470   GNUNET_SERVER_mst_receive (plugin->suid_tokenizer, NULL, mybuf, bytes,
1471                              GNUNET_NO, GNUNET_NO);
1472
1473   GNUNET_assert (plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK);
1474   plugin->server_read_task =
1475       GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
1476                                       plugin->server_stdout_handle,
1477                                       &wlan_plugin_helper_read, plugin);
1478 }
1479
1480 /**
1481  * Start the gnunet-wlan-helper process.
1482  *
1483  * @param plugin the transport plugin
1484  * @return GNUNET_YES if process was started, GNUNET_SYSERR on error
1485  */
1486 static int
1487 wlan_transport_start_wlan_helper (struct Plugin *plugin)
1488 {
1489   const char *filenamehw = "gnunet-transport-wlan-helper";
1490   char *filenameloopback = "gnunet-transport-wlan-helper-dummy";
1491   char *absolute_filename = NULL;
1492
1493   plugin->server_stdout = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_NO, GNUNET_YES);
1494   if (plugin->server_stdout == NULL)
1495     return GNUNET_SYSERR;
1496
1497   plugin->server_stdin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO);
1498   if (plugin->server_stdin == NULL)
1499     return GNUNET_SYSERR;
1500
1501   if ((plugin->testmode == 1) || (plugin->testmode == 2))
1502   {
1503     if (GNUNET_OS_check_helper_binary (filenameloopback) == GNUNET_YES)
1504     {
1505       absolute_filename = strdup (filenameloopback);
1506     }
1507     else
1508     {
1509       char cwd[FILENAME_MAX];
1510
1511       GNUNET_assert (getcwd (cwd, sizeof (cwd)) != NULL);
1512
1513       GNUNET_asprintf (&absolute_filename, "%s%s%s", cwd, DIR_SEPARATOR_STR,
1514                        filenameloopback);
1515
1516       if (GNUNET_DISK_file_test (filenameloopback) != GNUNET_YES)
1517       {
1518         GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
1519                          "Helper `%s' not found! %i\n", absolute_filename);
1520         GNUNET_break (0);
1521       }
1522     }
1523   }
1524
1525   /* Start the server process */
1526
1527   if (plugin->testmode == 0)
1528   {
1529
1530 #if DEBUG_wlan
1531     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
1532                      "Starting gnunet-wlan-helper process cmd: %s %s %i\n",
1533                      filenamehw, plugin->interface, plugin->testmode);
1534 #endif
1535
1536     if (GNUNET_OS_check_helper_binary (filenamehw) == GNUNET_YES)
1537     {
1538       plugin->server_proc =
1539           GNUNET_OS_start_process (plugin->server_stdin, plugin->server_stdout,
1540                                    filenamehw, filenamehw, plugin->interface,
1541                                    NULL);
1542     }
1543     else if (GNUNET_OS_check_helper_binary (filenamehw) == GNUNET_NO)
1544     {
1545       GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
1546                        "gnunet-transport-wlan-helper is not suid, please change it or look at the doku\n");
1547       GNUNET_break (0);
1548     }
1549     else
1550     {
1551       GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
1552                        "gnunet-transport-wlan-helper not found, please look if it exists and is the $PATH variable!\n");
1553       GNUNET_break (0);
1554     }
1555
1556   }
1557   else if (plugin->testmode == 1)
1558   {
1559
1560 #if DEBUG_wlan
1561     GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, PLUGIN_LOG_NAME,
1562                      "Starting gnunet-wlan-helper loopback 1 process cmd: %s %s %i\n",
1563                      absolute_filename, plugin->interface, plugin->testmode);
1564 #endif
1565     plugin->server_proc =
1566         GNUNET_OS_start_process (plugin->server_stdin, plugin->server_stdout,
1567                                  absolute_filename, absolute_filename, "1",
1568                                  NULL);
1569     if (plugin->server_proc == NULL)
1570     {
1571       GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
1572                        "`%s' not found, please look if it exists and is in the $PATH variable!\n",
1573                        absolute_filename);
1574       GNUNET_break (0);
1575     }
1576   }
1577   else if (plugin->testmode == 2)
1578   {
1579 #if DEBUG_wlan
1580     GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, PLUGIN_LOG_NAME,
1581                      "Starting gnunet-wlan-helper loopback 2 process cmd: %s %s %i\n",
1582                      absolute_filename, plugin->interface, plugin->testmode);
1583 #endif
1584
1585     plugin->server_proc =
1586         GNUNET_OS_start_process (plugin->server_stdin, plugin->server_stdout,
1587                                  absolute_filename, absolute_filename, "2",
1588                                  NULL);
1589     if (plugin->server_proc == NULL)
1590     {
1591       GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
1592                        "`%s' not found, please look if it exists and is in the $PATH variable!\n",
1593                        absolute_filename);
1594       GNUNET_break (0);
1595     }
1596   }
1597   if (absolute_filename != NULL)
1598     GNUNET_free (absolute_filename);
1599   if (plugin->server_proc == NULL)
1600   {
1601 #if DEBUG_wlan
1602     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
1603                      "Failed to start gnunet-wlan-helper process\n");
1604 #endif
1605     return GNUNET_SYSERR;
1606   }
1607
1608
1609
1610   /* Close the write end of the read pipe */
1611   GNUNET_DISK_pipe_close_end (plugin->server_stdout,
1612                               GNUNET_DISK_PIPE_END_WRITE);
1613
1614   /* Close the read end of the write pipe */
1615   GNUNET_DISK_pipe_close_end (plugin->server_stdin, GNUNET_DISK_PIPE_END_READ);
1616
1617   plugin->server_stdout_handle =
1618       GNUNET_DISK_pipe_handle (plugin->server_stdout,
1619                                GNUNET_DISK_PIPE_END_READ);
1620   plugin->server_stdin_handle =
1621       GNUNET_DISK_pipe_handle (plugin->server_stdin,
1622                                GNUNET_DISK_PIPE_END_WRITE);
1623
1624   GNUNET_assert (plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK);
1625
1626 #if DEBUG_wlan
1627   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
1628                    "Adding server_read_task for the wlan-helper\n");
1629 #endif
1630
1631   plugin->server_read_task =
1632       GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
1633                                       plugin->server_stdout_handle,
1634                                       &wlan_plugin_helper_read, plugin);
1635
1636   return GNUNET_YES;
1637 }
1638
1639 /**
1640  * Stops the gnunet-wlan-helper process.
1641  *
1642  * @param plugin the transport plugin
1643  * @return GNUNET_YES if process was started, GNUNET_SYSERR on error
1644  */
1645 static int
1646 wlan_transport_stop_wlan_helper (struct Plugin *plugin)
1647 {
1648 #if DEBUG_wlan
1649   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
1650                    "Stoping WLAN helper process\n");
1651 #endif
1652
1653   if (plugin->server_write_delay_task != GNUNET_SCHEDULER_NO_TASK)
1654   {
1655     GNUNET_SCHEDULER_cancel (plugin->server_write_delay_task);
1656     plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK;
1657   }
1658
1659   if (plugin->server_write_task != GNUNET_SCHEDULER_NO_TASK)
1660   {
1661     GNUNET_SCHEDULER_cancel (plugin->server_write_task);
1662     plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
1663   }
1664
1665   if (plugin->server_read_task != GNUNET_SCHEDULER_NO_TASK)
1666   {
1667     GNUNET_SCHEDULER_cancel (plugin->server_read_task);
1668     plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK;
1669   }
1670
1671   GNUNET_DISK_pipe_close (plugin->server_stdout);
1672   GNUNET_DISK_pipe_close (plugin->server_stdin);
1673   GNUNET_OS_process_kill (plugin->server_proc, SIGKILL);
1674   GNUNET_OS_process_wait (plugin->server_proc);
1675   GNUNET_OS_process_close (plugin->server_proc);
1676
1677   return GNUNET_YES;
1678 }
1679
1680 /**
1681  * function for delayed restart of the helper process
1682  * @param cls Finish_send struct if message should be finished
1683  * @param tc TaskContext
1684  */
1685 static void
1686 delay_restart_helper (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1687 {
1688   struct Finish_send *finish = cls;
1689   struct Plugin *plugin;
1690
1691   plugin = finish->plugin;
1692
1693   plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
1694   if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
1695   {
1696     GNUNET_free_non_null (finish->msgstart);
1697     GNUNET_free (finish);
1698     return;
1699   }
1700
1701   wlan_transport_start_wlan_helper (plugin);
1702
1703   if (finish->size != 0)
1704   {
1705     plugin->server_write_task =
1706         GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
1707                                          plugin->server_stdin_handle,
1708                                          &finish_sending, finish);
1709   }
1710   else
1711   {
1712     set_next_send (plugin);
1713     GNUNET_free_non_null (finish->msgstart);
1714     GNUNET_free (finish);
1715   }
1716
1717 }
1718
1719 /**
1720  * Function to restart the helper
1721  * @param plugin pointer to the global plugin struct
1722  * @param finish pointer to the Finish_send struct to finish
1723  */
1724 static void
1725 restart_helper (struct Plugin *plugin, struct Finish_send *finish)
1726 {
1727   static struct GNUNET_TIME_Relative next_try = { 1000 };
1728   GNUNET_assert (finish != NULL);
1729
1730   wlan_transport_stop_wlan_helper (plugin);
1731   plugin->server_write_task =
1732       GNUNET_SCHEDULER_add_delayed (next_try, &delay_restart_helper, finish);
1733   GNUNET_TIME_relative_multiply (next_try, HELPER_RESTART_SCALING_FACTOR);
1734
1735 }
1736
1737 /**
1738  * function to finish a sending if not all could have been writen befor
1739  * @param cls pointer to the Finish_send struct
1740  * @param tc TaskContext
1741  */
1742 static void
1743 finish_sending (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
1744 {
1745   struct Finish_send *finish = cls;
1746   struct Plugin *plugin;
1747   ssize_t bytes;
1748
1749   plugin = finish->plugin;
1750   plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
1751
1752   if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
1753   {
1754     GNUNET_free (finish->msgstart);
1755     GNUNET_free (finish);
1756     return;
1757   }
1758   bytes =
1759       GNUNET_DISK_file_write (plugin->server_stdin_handle,
1760                               finish->head_of_next_write, finish->size);
1761
1762   if (bytes != finish->size)
1763   {
1764     if (bytes != GNUNET_SYSERR)
1765     {
1766       finish->head_of_next_write += bytes;
1767       finish->size -= bytes;
1768       plugin->server_write_task =
1769           GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
1770                                            plugin->server_stdin_handle,
1771                                            &finish_sending, finish);
1772     }
1773     else
1774     {
1775       restart_helper (plugin, finish);
1776     }
1777   }
1778   else
1779   {
1780     GNUNET_free (finish->msgstart);
1781     GNUNET_free (finish);
1782     set_next_send (plugin);
1783   }
1784 }
1785
1786 /**
1787  * function to send a hello beacon
1788  * @param plugin pointer to the plugin struct
1789  */
1790 static void
1791 send_hello_beacon (struct Plugin *plugin)
1792 {
1793
1794 #if DEBUG_wlan
1795   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
1796                    "Sending hello beacon\n");
1797 #endif
1798
1799   uint16_t size;
1800   ssize_t bytes;
1801   uint16_t hello_size;
1802   struct GNUNET_MessageHeader *msgheader;
1803   struct ieee80211_frame *ieeewlanheader;
1804   struct Radiotap_Send *radioHeader;
1805   struct GNUNET_MessageHeader *msgheader2;
1806   const struct GNUNET_MessageHeader *hello;
1807   struct Finish_send *finish;
1808
1809   GNUNET_assert (plugin != NULL);
1810
1811   GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan hello beacons send"),
1812                             1, GNUNET_NO);
1813
1814   hello = plugin->env->get_our_hello ();
1815   hello_size = GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) hello);
1816   GNUNET_assert (sizeof (struct WlanHeader) + hello_size <= WLAN_MTU);
1817   size =
1818       sizeof (struct GNUNET_MessageHeader) + sizeof (struct Radiotap_Send) +
1819       sizeof (struct ieee80211_frame) + hello_size;
1820
1821   msgheader = GNUNET_malloc (size);
1822   msgheader->size = htons (size);
1823   msgheader->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
1824
1825   radioHeader = (struct Radiotap_Send *) &msgheader[1];
1826   getRadiotapHeader (plugin, NULL, radioHeader);
1827   ieeewlanheader = (struct ieee80211_frame *) &radioHeader[1];
1828   getWlanHeader (ieeewlanheader, &bc_all_mac, plugin, size);
1829
1830   msgheader2 = (struct GNUNET_MessageHeader *) &ieeewlanheader[1];
1831   /*msgheader2->size =
1832    * htons (GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) hello) +
1833    * sizeof (struct GNUNET_MessageHeader));
1834    *
1835    * msgheader2->type = htons (GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT); */
1836   memcpy (msgheader2, hello, hello_size);
1837
1838   bytes = GNUNET_DISK_file_write (plugin->server_stdin_handle, msgheader, size);
1839
1840   if (bytes == GNUNET_SYSERR)
1841   {
1842     GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
1843                      _
1844                      ("Error writing to wlan healper. errno == %d, ERROR: %s\n"),
1845                      errno, strerror (errno));
1846     finish = GNUNET_malloc (sizeof (struct Finish_send));
1847     finish->plugin = plugin;
1848     finish->head_of_next_write = NULL;
1849     finish->size = 0;
1850     finish->msgstart = NULL;
1851     restart_helper (plugin, finish);
1852
1853     set_next_beacon_time (plugin);
1854
1855   }
1856   else
1857   {
1858     GNUNET_assert (bytes == size);
1859     set_next_beacon_time (plugin);
1860     set_next_send (plugin);
1861   }
1862   GNUNET_free (msgheader);
1863
1864
1865 }
1866
1867 /**
1868  * function to add an ack to send it for a received fragment
1869  * @param cls MacEndpoint this ack belongs to
1870  * @param msg_id id of the message
1871  * @param hdr pointer to the hdr where the ack is stored
1872  *
1873  */
1874
1875 static void
1876 add_ack_for_send (void *cls, uint32_t msg_id,
1877                   const struct GNUNET_MessageHeader *hdr)
1878 {
1879
1880   struct AckSendQueue *ack;
1881
1882   GNUNET_assert (cls != NULL);
1883   struct MacEndpoint *endpoint = cls;
1884   struct Plugin *plugin = endpoint->plugin;
1885   struct GNUNET_MessageHeader *msgheader;
1886   struct GNUNET_MessageHeader *msgheader2;
1887   uint16_t size;
1888
1889   size =
1890       sizeof (struct GNUNET_MessageHeader) + sizeof (struct Radiotap_Send) +
1891       sizeof (struct ieee80211_frame) + ntohs (hdr->size) +
1892       sizeof (struct AckSendQueue);
1893
1894   ack = GNUNET_malloc (size);
1895   ack->message_id = msg_id;
1896   ack->endpoint = endpoint;
1897
1898   size =
1899       sizeof (struct GNUNET_MessageHeader) + sizeof (struct Radiotap_Send) +
1900       sizeof (struct ieee80211_frame) + ntohs (hdr->size);
1901
1902   msgheader = (struct GNUNET_MessageHeader *) &ack[1];
1903   ack->hdr = (struct GNUNET_MessageHeader *) &ack[1];
1904   msgheader->size = htons (size);
1905   msgheader->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
1906
1907   ack->radioHeader = (struct Radiotap_Send *) &msgheader[1];
1908   ack->ieeewlanheader = (struct ieee80211_frame *) &(ack->radioHeader)[1];
1909   msgheader2 = (struct GNUNET_MessageHeader *) &(ack->ieeewlanheader)[1];
1910   memcpy (msgheader2, hdr, ntohs (hdr->size));
1911
1912   GNUNET_CONTAINER_DLL_insert_tail (plugin->ack_send_queue_head,
1913                                     plugin->ack_send_queue_tail, ack);
1914
1915 #if DEBUG_wlan_retransmission > 1
1916   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
1917                    "Adding ack with message id %u to send, AckSendQueue %p, endpoint %p\n",
1918                    msg_id, ack, endpoint);
1919 #endif
1920
1921   set_next_send (plugin);
1922 }
1923
1924 /**
1925  * Function for the scheduler if a FragmentMessage times out
1926  * @param cls pointer to the FragmentMessage
1927  * @param tc pointer to the GNUNET_SCHEDULER_TaskContext
1928  */
1929 static void
1930 fragmentmessage_timeout (void *cls,
1931                          const struct GNUNET_SCHEDULER_TaskContext *tc)
1932 {
1933   struct FragmentMessage *fm = cls;
1934
1935   GNUNET_assert (fm != NULL);
1936   fm->timeout_task = GNUNET_SCHEDULER_NO_TASK;
1937   if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
1938   {
1939     return;
1940   }
1941   free_fragment_message (fm->session->mac->plugin, fm);
1942 }
1943
1944 /**
1945  * Function to check if there is some space in the fragment queue
1946  * inserts a message if space is available
1947  * @param plugin the plugin struct
1948  */
1949
1950 static void
1951 check_fragment_queue (struct Plugin *plugin)
1952 {
1953   struct Session *session;
1954   struct FragmentMessage *fm;
1955   struct GNUNET_PeerIdentity pid;
1956
1957   struct PendingMessage *pm;
1958
1959   if (plugin->pending_Fragment_Messages < FRAGMENT_QUEUE_SIZE)
1960   {
1961     session = get_next_queue_session (plugin);
1962     if (session != NULL)
1963     {
1964       pm = session->pending_message_head;
1965       GNUNET_assert (pm != NULL);
1966       GNUNET_CONTAINER_DLL_remove (session->pending_message_head,
1967                                    session->pending_message_tail, pm);
1968       session->mac->fragment_messages_out_count++;
1969       session->fragment_messages_out_count++;
1970       plugin->pending_Fragment_Messages++;
1971       GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending fragments"),
1972                              plugin->pending_Fragment_Messages, GNUNET_NO);
1973
1974       fm = GNUNET_malloc (sizeof (struct FragmentMessage));
1975       fm->session = session;
1976       fm->timeout.abs_value = pm->timeout.abs_value;
1977       fm->frag = NULL;
1978       fm->fragcontext =
1979           GNUNET_FRAGMENT_context_create (plugin->env->stats, WLAN_MTU,
1980                                           &plugin->tracker,
1981                                           GNUNET_TIME_UNIT_SECONDS,
1982                                           &(pm->msg->header),
1983                                           &add_message_for_send, fm);
1984       fm->timeout_task =
1985           GNUNET_SCHEDULER_add_delayed (GNUNET_TIME_absolute_get_remaining
1986                                         (fm->timeout), fragmentmessage_timeout,
1987                                         fm);
1988       GNUNET_CONTAINER_DLL_insert_tail (session->mac->sending_messages_head,
1989                                         session->mac->sending_messages_tail,
1990                                         fm);
1991
1992       if (pm->transmit_cont != NULL)
1993       {
1994         pid = session->target;
1995         pm->transmit_cont (pm->transmit_cont_cls, &pid, GNUNET_OK);
1996 #if DEBUG_wlan
1997         GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
1998                          "called pm->transmit_cont for %p\n", session);
1999 #endif
2000       }
2001       else
2002       {
2003 #if DEBUG_wlan
2004         GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2005                          "no pm->transmit_cont for %p\n", session);
2006 #endif
2007       }
2008       GNUNET_free (pm);
2009
2010       if (session->pending_message_head != NULL)
2011       {
2012         //requeue session
2013         queue_session (plugin, session);
2014       }
2015
2016     }
2017   }
2018
2019   //check if timeout changed
2020   set_next_send (plugin);
2021 }
2022
2023 /**
2024  * Function to send an ack, does not free the ack
2025  * @param plugin pointer to the plugin
2026  */
2027 static void
2028 send_ack (struct Plugin *plugin)
2029 {
2030
2031   ssize_t bytes;
2032   struct AckSendQueue *ack;
2033   struct Finish_send *finish;
2034
2035   ack = plugin->ack_send_queue_head;
2036
2037
2038 #if DEBUG_wlan
2039   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2040                    "Sending ack for message_id %u for mac endpoint %p, size %u\n",
2041                    ack->message_id, ack->endpoint,
2042                    ntohs (ack->hdr->size) - sizeof (struct Radiotap_Send));
2043 #endif
2044
2045   GNUNET_assert (plugin != NULL);
2046   GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan acks send"), 1,
2047                             GNUNET_NO);
2048
2049   getRadiotapHeader (plugin, ack->endpoint, ack->radioHeader);
2050   getWlanHeader (ack->ieeewlanheader, &ack->endpoint->addr, plugin,
2051                  ntohs (ack->hdr->size));
2052
2053   bytes =
2054       GNUNET_DISK_file_write (plugin->server_stdin_handle, ack->hdr,
2055                               ntohs (ack->hdr->size));
2056   if (bytes == GNUNET_SYSERR)
2057   {
2058     GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
2059                      _
2060                      ("Error writing to wlan healper. errno == %d, ERROR: %s\n"),
2061                      errno, strerror (errno));
2062     finish = GNUNET_malloc (sizeof (struct Finish_send));
2063     finish->plugin = plugin;
2064     finish->head_of_next_write = NULL;
2065     finish->size = 0;
2066     finish->msgstart = NULL;
2067     restart_helper (plugin, finish);
2068   }
2069   else
2070   {
2071     GNUNET_assert (bytes == ntohs (ack->hdr->size));
2072     GNUNET_CONTAINER_DLL_remove (plugin->ack_send_queue_head,
2073                                  plugin->ack_send_queue_tail, ack);
2074     GNUNET_free (ack);
2075     set_next_send (plugin);
2076   }
2077 }
2078
2079 /**
2080  * Function called when wlan helper is ready to get some data
2081  *
2082  * @param cls closure
2083  * @param tc GNUNET_SCHEDULER_TaskContext
2084  */
2085 static void
2086 do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2087 {
2088   struct Plugin *plugin = cls;
2089
2090   GNUNET_assert (plugin != NULL);
2091
2092   plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
2093   if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
2094     return;
2095
2096   struct Session *session;
2097   struct FragmentMessage *fm;
2098   struct Finish_send *finish;
2099   struct FragmentMessage_queue *fmq;
2100   ssize_t bytes;
2101
2102   if (plugin->ack_send_queue_head != NULL)
2103   {
2104     send_ack (plugin);
2105     return;
2106   }
2107
2108   //test if a "hello-beacon" has to be send
2109   if (GNUNET_TIME_absolute_get_remaining (plugin->beacon_time).rel_value == 0)
2110   {
2111     send_hello_beacon (plugin);
2112     return;
2113   }
2114
2115   if (plugin->sending_messages_head != NULL)
2116   {
2117     GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan fragments send"), 1,
2118                               GNUNET_NO);
2119
2120     fmq = plugin->sending_messages_head;
2121     fm = fmq->content;
2122     GNUNET_CONTAINER_DLL_remove (plugin->sending_messages_head,
2123                                  plugin->sending_messages_tail, fmq);
2124     GNUNET_free (fmq);
2125
2126     session = fm->session;
2127     GNUNET_assert (session != NULL);
2128
2129 #if DEBUG_wlan
2130     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2131                      "Sending GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT for fragment message %p, size: %u\n",
2132                      fm, fm->size);
2133 #endif
2134
2135     getRadiotapHeader (plugin, session->mac, fm->radioHeader);
2136     getWlanHeader (fm->ieeewlanheader, &(fm->session->mac->addr), plugin,
2137                    fm->size);
2138
2139     bytes =
2140         GNUNET_DISK_file_write (plugin->server_stdin_handle, fm->frag,
2141                                 fm->size);
2142
2143
2144     if (bytes != fm->size)
2145     {
2146       finish = GNUNET_malloc (sizeof (struct Finish_send));
2147       finish->plugin = plugin;
2148       finish->msgstart = (struct GNUNET_MessageHeader *) fm->frag;
2149       GNUNET_assert (plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK);
2150
2151       if (bytes == GNUNET_SYSERR)
2152       {
2153         GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
2154                          _
2155                          ("Error writing to wlan healper. errno == %d, ERROR: %s\n"),
2156                          errno, strerror (errno));
2157
2158         finish->head_of_next_write = fm->frag;
2159         finish->size = fm->size;
2160         restart_helper (plugin, finish);
2161       }
2162       else
2163       {
2164         finish->head_of_next_write = fm->frag + bytes;
2165         finish->size = fm->size - bytes;
2166         plugin->server_write_task =
2167             GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
2168                                              plugin->server_stdin_handle,
2169                                              &finish_sending, finish);
2170       }
2171
2172       fm->frag = NULL;
2173     }
2174     else
2175     {
2176       GNUNET_free (fm->frag);
2177       fm->frag = NULL;
2178       set_next_send (plugin);
2179     }
2180     GNUNET_FRAGMENT_context_transmission_done (fm->fragcontext);
2181     return;
2182   }
2183
2184   GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, PLUGIN_LOG_NAME,
2185                    "do_transmit did nothing, should not happen!\n");
2186 }
2187
2188 /**
2189  * Another peer has suggested an address for this
2190  * peer and transport plugin.  Check that this could be a valid
2191  * address.  If so, consider adding it to the list
2192  * of addresses.
2193  *
2194  * @param cls closure
2195  * @param addr pointer to the address
2196  * @param addrlen length of addr
2197  * @return GNUNET_OK if this is a plausible address for this peer
2198  *         and transport
2199  */
2200 static int
2201 wlan_plugin_address_suggested (void *cls, const void *addr, size_t addrlen)
2202 {
2203   //struct Plugin *plugin = cls;
2204
2205   /* check if the address is plausible; if so,
2206    * add it to our list! */
2207
2208   GNUNET_assert (cls != NULL);
2209   //FIXME mitm is not checked
2210   //Mac Address has 6 bytes
2211   if (addrlen == 6)
2212   {
2213     /* TODO check for bad addresses like multicast, broadcast, etc */
2214 #if DEBUG_wlan
2215     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2216                      "wlan_plugin_address_suggested got good address, size %u!\n",
2217                      addrlen);
2218 #endif
2219     return GNUNET_OK;
2220   }
2221 #if DEBUG_wlan
2222   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2223                    "wlan_plugin_address_suggested got bad address, size %u!\n",
2224                    addrlen);
2225 #endif
2226   return GNUNET_SYSERR;
2227 }
2228
2229 /**
2230  * Function that can be used by the transport service to transmit
2231  * a message using the plugin.
2232  *
2233  * @param cls closure
2234  * @param target who should receive this message
2235  * @param priority how important is the message
2236  * @param msgbuf the message to transmit
2237  * @param msgbuf_size number of bytes in 'msgbuf'
2238  * @param timeout when should we time out
2239  * @param session which session must be used (or NULL for "any")
2240  * @param addr the address to use (can be NULL if the plugin
2241  *                is "on its own" (i.e. re-use existing TCP connection))
2242  * @param addrlen length of the address in bytes
2243  * @param force_address GNUNET_YES if the plugin MUST use the given address,
2244  *                otherwise the plugin may use other addresses or
2245  *                existing connections (if available)
2246  * @param cont continuation to call once the message has
2247  *        been transmitted (or if the transport is ready
2248  *        for the next transmission call; or if the
2249  *        peer disconnected...)
2250  * @param cont_cls closure for cont
2251  * @return number of bytes used (on the physical network, with overheads);
2252  *         -1 on hard errors (i.e. address invalid); 0 is a legal value
2253  *         and does NOT mean that the message was not transmitted (DV)
2254  */
2255 static ssize_t
2256 wlan_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target,
2257                   const char *msgbuf, size_t msgbuf_size, unsigned int priority,
2258                   struct GNUNET_TIME_Relative timeout, struct Session *session,
2259                   const void *addr, size_t addrlen, int force_address,
2260                   GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
2261 {
2262   struct Plugin *plugin = cls;
2263   struct PendingMessage *newmsg;
2264   struct WlanHeader *wlanheader;
2265
2266   GNUNET_assert (plugin != NULL);
2267   //check if msglen > 0
2268   GNUNET_assert (msgbuf_size > 0);
2269
2270   //get session if needed
2271   if (session == NULL)
2272   {
2273     if (wlan_plugin_address_suggested (plugin, addr, addrlen) == GNUNET_OK)
2274     {
2275       session = get_session (plugin, addr, target);
2276     }
2277     else
2278     {
2279       GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
2280                        _("Wlan Address len %d is wrong\n"), addrlen);
2281       return -1;
2282     }
2283   }
2284
2285   GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan messages queued"), 1,
2286                             GNUNET_NO);
2287
2288   //queue message:
2289
2290   //queue message in session
2291   //test if there is no other message in the "queue"
2292   //FIXME: to many send requests
2293   if (session->pending_message_head != NULL)
2294   {
2295     newmsg = session->pending_message_head;
2296     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2297                      "wlan_plugin_send: a pending message is already in the queue for this client\n remaining time to send this message is %u, queued fragment messages for this mac connection %u\n",
2298                      GNUNET_TIME_absolute_get_remaining (newmsg->
2299                                                          timeout).rel_value,
2300                      session->mac->fragment_messages_out_count);
2301   }
2302
2303   newmsg = GNUNET_malloc (sizeof (struct PendingMessage));
2304   newmsg->msg = GNUNET_malloc (msgbuf_size + sizeof (struct WlanHeader));
2305   wlanheader = newmsg->msg;
2306   //copy msg to buffer, not fragmented / segmented yet, but with message header
2307   wlanheader->header.size = htons (msgbuf_size + sizeof (struct WlanHeader));
2308   wlanheader->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA);
2309   memcpy (&(wlanheader->target), target, sizeof (struct GNUNET_PeerIdentity));
2310   memcpy (&(wlanheader->source), plugin->env->my_identity,
2311           sizeof (struct GNUNET_PeerIdentity));
2312   wlanheader->crc = 0;
2313   memcpy (&wlanheader[1], msgbuf, msgbuf_size);
2314   wlanheader->crc =
2315       htonl (getcrc32
2316              ((char *) wlanheader, msgbuf_size + sizeof (struct WlanHeader)));
2317   //GNUNET_log_from(GNUNET_ERROR_TYPE_INFO, PLUGIN_LOG_NAME,  "Wlan message Header crc: %u, %u\n",getcrc32((char*) wlanheader, msgbuf_size + sizeof(struct WlanHeader)), wlanheader->crc);
2318   //hexdump(newmsg->msg, msgbuf_size + sizeof(struct WlanHeader));
2319
2320   newmsg->transmit_cont = cont;
2321   newmsg->transmit_cont_cls = cont_cls;
2322   newmsg->timeout = GNUNET_TIME_relative_to_absolute (timeout);
2323
2324   newmsg->timeout.abs_value = newmsg->timeout.abs_value - 500;
2325
2326   newmsg->message_size = msgbuf_size + sizeof (struct WlanHeader);
2327
2328   GNUNET_CONTAINER_DLL_insert_tail (session->pending_message_head,
2329                                     session->pending_message_tail, newmsg);
2330
2331 #if DEBUG_wlan
2332   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2333                    "New message for %p with size (incl wlan header) %u added\n",
2334                    session, newmsg->message_size);
2335 #endif
2336 #if DEBUG_wlan_msg_dump > 1
2337   hexdump (msgbuf, GNUNET_MIN (msgbuf_size, 256));
2338 #endif
2339   //queue session
2340   queue_session (plugin, session);
2341
2342   check_fragment_queue (plugin);
2343   //FIXME not the correct size
2344   return msgbuf_size;
2345
2346 }
2347
2348 /**
2349  * function to free a mac endpoint
2350  * @param plugin pointer to the plugin struct
2351  * @param endpoint pointer to the MacEndpoint to free
2352  */
2353 static void
2354 free_macendpoint (struct Plugin *plugin, struct MacEndpoint *endpoint)
2355 {
2356   struct Sessionqueue *sessions;
2357   struct Sessionqueue *sessions_next;
2358
2359   GNUNET_assert (endpoint != NULL);
2360
2361   sessions = endpoint->sessions_head;
2362   while (sessions != NULL)
2363   {
2364     sessions_next = sessions->next;
2365     free_session (plugin, sessions, GNUNET_NO);
2366     sessions = sessions_next;
2367   }
2368
2369   GNUNET_CONTAINER_DLL_remove (plugin->mac_head, plugin->mac_tail, endpoint);
2370   if (endpoint->timeout_task != GNUNET_SCHEDULER_NO_TASK)
2371   {
2372     GNUNET_SCHEDULER_cancel (endpoint->timeout_task);
2373     endpoint->timeout_task = GNUNET_SCHEDULER_NO_TASK;
2374   }
2375   plugin->mac_count--;
2376   GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan mac endpoints"),
2377                          plugin->mac_count, GNUNET_NO);
2378   GNUNET_free (endpoint);
2379
2380 }
2381
2382 /**
2383  * function to free a session
2384  * @param plugin pointer to the plugin
2385  * @param queue pointer to the sessionqueue element to free
2386  * @param free_macendpoint if GNUNET_YES and mac endpoint would be empty, free mac endpoint
2387  */
2388 static void
2389 free_session (struct Plugin *plugin, struct Sessionqueue *queue,
2390               int do_free_macendpoint)
2391 {
2392   struct Sessionqueue *pendingsession;
2393   struct Sessionqueue *pendingsession_tmp;
2394   struct PendingMessage *pm;
2395   struct MacEndpoint *endpoint;
2396   struct FragmentMessage *fm;
2397   struct FragmentMessage *fmnext;
2398   int check = 0;
2399
2400   GNUNET_assert (plugin != NULL);
2401   GNUNET_assert (queue != NULL);
2402   GNUNET_assert (queue->content != NULL);
2403
2404   //session found
2405   //is this session pending for send
2406   pendingsession = plugin->pending_Sessions_head;
2407   while (pendingsession != NULL)
2408   {
2409     pendingsession_tmp = pendingsession;
2410     pendingsession = pendingsession->next;
2411     GNUNET_assert (pendingsession_tmp->content != NULL);
2412     if (pendingsession_tmp->content == queue->content)
2413     {
2414       plugin->pendingsessions--;
2415       GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"),
2416                              plugin->pendingsessions, GNUNET_NO);
2417       GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head,
2418                                    plugin->pending_Sessions_tail,
2419                                    pendingsession_tmp);
2420       GNUNET_free (pendingsession_tmp);
2421
2422       GNUNET_assert (check == 0);
2423       check = 1;
2424     }
2425   }
2426
2427   endpoint = queue->content->mac;
2428   fm = endpoint->sending_messages_head;
2429   while (fm != NULL)
2430   {
2431     fmnext = fm->next;
2432     if (fm->session == queue->content)
2433     {
2434       free_fragment_message (plugin, fm);
2435     }
2436     fm = fmnext;
2437   }
2438
2439   // remove PendingMessage
2440   pm = queue->content->pending_message_head;
2441   while (pm != NULL)
2442   {
2443     GNUNET_CONTAINER_DLL_remove (queue->content->pending_message_head,
2444                                  queue->content->pending_message_tail, pm);
2445     GNUNET_free (pm->msg);
2446     GNUNET_free (pm);
2447     pm = queue->content->pending_message_head;
2448   }
2449
2450   GNUNET_CONTAINER_DLL_remove (endpoint->sessions_head, endpoint->sessions_tail,
2451                                queue);
2452   //Check that no ohter session on this endpoint for this session exits
2453   GNUNET_assert (search_session (plugin, endpoint, &queue->content->target) ==
2454                  NULL);
2455   if (endpoint->sessions_head == NULL && do_free_macendpoint == GNUNET_YES)
2456   {
2457     free_macendpoint (plugin, endpoint);
2458     //check if no endpoint with the same address exists
2459     GNUNET_assert (get_macendpoint (plugin, &endpoint->addr, GNUNET_NO) ==
2460                    NULL);
2461   }
2462
2463   if (queue->content->timeout_task != GNUNET_SCHEDULER_NO_TASK)
2464   {
2465     GNUNET_SCHEDULER_cancel (queue->content->timeout_task);
2466     queue->content->timeout_task = GNUNET_SCHEDULER_NO_TASK;
2467   }
2468   GNUNET_free (queue);
2469
2470   check_fragment_queue (plugin);
2471 }
2472
2473 /**
2474  * Function that can be used to force the plugin to disconnect
2475  * from the given peer and cancel all previous transmissions
2476  * (and their continuation).
2477  *
2478  * @param cls closure
2479  * @param target peer from which to disconnect
2480  */
2481 static void
2482 wlan_plugin_disconnect (void *cls, const struct GNUNET_PeerIdentity *target)
2483 {
2484   struct Plugin *plugin = cls;
2485   struct Sessionqueue *queue;
2486   struct Sessionqueue *queue_next;
2487   struct MacEndpoint *endpoint = plugin->mac_head;
2488   struct MacEndpoint *endpoint_next;
2489
2490   // just look at all the session for the needed one
2491   while (endpoint != NULL)
2492   {
2493     queue = endpoint->sessions_head;
2494     endpoint_next = endpoint->next;
2495     while (queue != NULL)
2496     {
2497       // content is never NULL
2498       GNUNET_assert (queue->content != NULL);
2499       queue_next = queue->next;
2500       if (memcmp
2501           (target, &(queue->content->target),
2502            sizeof (struct GNUNET_PeerIdentity)) == 0)
2503       {
2504         free_session (plugin, queue, GNUNET_YES);
2505       }
2506       // try next
2507       queue = queue_next;
2508     }
2509     endpoint = endpoint_next;
2510   }
2511 }
2512
2513 /**
2514  * Convert the transports address to a nice, human-readable
2515  * format.
2516  *
2517  * @param cls closure
2518  * @param type name of the transport that generated the address
2519  * @param addr one of the addresses of the host, NULL for the last address
2520  *        the specific address format depends on the transport
2521  * @param addrlen length of the address
2522  * @param numeric should (IP) addresses be displayed in numeric form?
2523  * @param timeout after how long should we give up?
2524  * @param asc function to call on each string
2525  * @param asc_cls closure for asc
2526  */
2527 static void
2528 wlan_plugin_address_pretty_printer (void *cls, const char *type,
2529                                     const void *addr, size_t addrlen,
2530                                     int numeric,
2531                                     struct GNUNET_TIME_Relative timeout,
2532                                     GNUNET_TRANSPORT_AddressStringCallback asc,
2533                                     void *asc_cls)
2534 {
2535   char *ret;
2536   const unsigned char *input;
2537
2538   //GNUNET_assert(cls !=NULL);
2539   if (addrlen != sizeof (struct MacAddress))
2540   {
2541     /* invalid address (MAC addresses have 6 bytes) */
2542     //GNUNET_break (0);
2543 #if DEBUG_wlan
2544     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2545                      "Func wlan_plugin_address_pretty_printer got size: %u, worng size!\n",
2546                      addrlen);
2547 #endif
2548     asc (asc_cls, NULL);
2549     return;
2550   }
2551   input = (const unsigned char *) addr;
2552   GNUNET_asprintf (&ret,
2553                    "Transport %s: %s Mac-Address %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
2554                    type, PROTOCOL_PREFIX, input[0], input[1], input[2],
2555                    input[3], input[4], input[5]);
2556 #if DEBUG_wlan
2557   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2558                    "Func wlan_plugin_address_pretty_printer got size: %u, nummeric %u, type %s; made string: %s\n",
2559                    addrlen, numeric, type, ret);
2560 #endif
2561   asc (asc_cls, ret);
2562   //only one mac address per plugin
2563   asc (asc_cls, NULL);
2564 }
2565
2566
2567
2568 /**
2569  * handels the data after all fragments are put together
2570  * @param cls macendpoint this messages belongs to
2571  * @param hdr pointer to the data
2572  */
2573 static void
2574 wlan_data_message_handler (void *cls, const struct GNUNET_MessageHeader *hdr)
2575 {
2576   struct MacEndpoint *endpoint = (struct MacEndpoint *) cls;
2577   struct Plugin *plugin = endpoint->plugin;
2578   struct WlanHeader *wlanheader;
2579   struct Session *session;
2580
2581   const struct GNUNET_MessageHeader *temp_hdr;
2582   struct GNUNET_PeerIdentity tmpsource;
2583   int crc;
2584
2585   GNUNET_assert (plugin != NULL);
2586
2587   if (ntohs (hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_DATA)
2588   {
2589
2590 #if DEBUG_wlan
2591     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2592                      "Func wlan_data_message_handler got GNUNET_MESSAGE_TYPE_WLAN_DATA size: %u\n",
2593                      ntohs (hdr->size));
2594 #endif
2595
2596     if (ntohs (hdr->size) <
2597         sizeof (struct WlanHeader) + sizeof (struct GNUNET_MessageHeader))
2598     {
2599       //packet not big enought
2600       return;
2601     }
2602
2603     GNUNET_STATISTICS_update (plugin->env->stats,
2604                               _("# wlan whole messages received"), 1,
2605                               GNUNET_NO);
2606     wlanheader = (struct WlanHeader *) hdr;
2607
2608     session = search_session (plugin, endpoint, &wlanheader->source);
2609
2610     temp_hdr = (const struct GNUNET_MessageHeader *) &wlanheader[1];
2611     crc = ntohl (wlanheader->crc);
2612     wlanheader->crc = 0;
2613     if (getcrc32 ((char *) wlanheader, ntohs (wlanheader->header.size)) != crc)
2614     {
2615       //wrong crc, dispose message
2616       GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, PLUGIN_LOG_NAME,
2617                        "Wlan message header crc was wrong: %u != %u\n",
2618                        getcrc32 ((char *) wlanheader,
2619                                  ntohs (wlanheader->header.size)), crc);
2620       hexdump ((void *) hdr, ntohs (hdr->size));
2621       return;
2622     }
2623
2624     //if not in session list
2625     if (session == NULL)
2626     {
2627 #if DEBUG_wlan
2628       GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2629                        "WLAN client not in session list: packet size = %u, inner size = %u, header size = %u\n",
2630                        ntohs (wlanheader->header.size), ntohs (temp_hdr->size),
2631                        sizeof (struct WlanHeader));
2632 #endif
2633       //try if it is a hello message
2634       if (ntohs (wlanheader->header.size) >=
2635           ntohs (temp_hdr->size) + sizeof (struct WlanHeader))
2636       {
2637         if (ntohs (temp_hdr->type) == GNUNET_MESSAGE_TYPE_HELLO)
2638         {
2639           if (GNUNET_HELLO_get_id
2640               ((const struct GNUNET_HELLO_Message *) temp_hdr,
2641                &tmpsource) == GNUNET_OK)
2642           {
2643             session = create_session (plugin, endpoint, &tmpsource);
2644           }
2645           else
2646           {
2647             GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, PLUGIN_LOG_NAME,
2648                              "WLAN client not in session list and hello message is not okay\n");
2649             return;
2650           }
2651
2652         }
2653         else
2654         {
2655           GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, PLUGIN_LOG_NAME,
2656                            "WLAN client not in session list and not a hello message\n");
2657           return;
2658         }
2659       }
2660       else
2661       {
2662         GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, PLUGIN_LOG_NAME,
2663                          "WLAN client not in session list and message size in does not fit\npacket size = %u, inner size = %u, header size = %u\n",
2664                          ntohs (wlanheader->header.size),
2665                          ntohs (temp_hdr->size), sizeof (struct WlanHeader));
2666         return;
2667       }
2668     }
2669
2670     //"receive" the message
2671
2672     if (memcmp
2673         (&wlanheader->source, &session->target,
2674          sizeof (struct GNUNET_PeerIdentity)) != 0)
2675     {
2676       //wrong peer id
2677 #if DEBUG_wlan
2678       GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2679                        "WLAN peer source id doesn't match packet peer source id: session %p\n",
2680                        session);
2681 #endif
2682       return;
2683     }
2684
2685     if (memcmp
2686         (&wlanheader->target, plugin->env->my_identity,
2687          sizeof (struct GNUNET_PeerIdentity)) != 0)
2688     {
2689       //wrong peer id
2690 #if DEBUG_wlan
2691       GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2692                        "WLAN peer target id doesn't match our peer id: session %p\n",
2693                        session);
2694 #endif
2695       return;
2696     }
2697
2698     GNUNET_SERVER_mst_receive (plugin->data_tokenizer, session,
2699                                (const char *) temp_hdr,
2700                                ntohs (hdr->size) - sizeof (struct WlanHeader),
2701                                GNUNET_YES, GNUNET_NO);
2702
2703     return;
2704   }
2705   else
2706   {
2707     GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, PLUGIN_LOG_NAME,
2708                      "wlan_data_message_handler got wrong message type: %u\n",
2709                      ntohs (hdr->size));
2710     return;
2711   }
2712 }
2713
2714 /**
2715  * function to process the a message, give it to the higher layer
2716  * @param cls pointer to the plugin
2717  * @param client pointer to the session this message belongs to
2718  * @param hdr start of the message
2719  */
2720 //TODO ATS informations
2721 static void
2722 process_data (void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
2723 {
2724
2725   GNUNET_assert (client != NULL);
2726   GNUNET_assert (cls != NULL);
2727   struct Session *session = (struct Session *) client;
2728   struct Plugin *plugin = (struct Plugin *) cls;
2729
2730   struct GNUNET_ATS_Information distance;
2731
2732   distance.type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
2733   distance.value = htonl (1);
2734
2735 #if DEBUG_wlan
2736   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2737                    "Calling plugin->env->receive for session %p; %s; size: %u\n",
2738                    session, wlan_plugin_address_to_string (NULL,
2739                                                            session->mac->
2740                                                            addr.mac, 6),
2741                    htons (hdr->size));
2742 #endif
2743
2744   plugin->env->receive (plugin->env->cls, &(session->target), hdr,
2745                         (const struct GNUNET_ATS_Information *) &distance, 1,
2746                         session, (const char *) &session->mac->addr,
2747                         sizeof (session->mac->addr));
2748 }
2749
2750 /**
2751  * Function used for to process the data received from the wlan interface
2752  *
2753  * @param cls the plugin handle
2754  * @param session_light pointer to the struct holding known informations
2755  * @param hdr hdr of the GNUNET_MessageHeader
2756  * @param rxinfo pointer to the radiotap informations got with this packet FIXME: give ATS for info
2757  */
2758 static void
2759 wlan_data_helper (void *cls, struct Session_light *session_light,
2760                   const struct GNUNET_MessageHeader *hdr,
2761                   const struct Radiotap_rx *rxinfo)
2762 {
2763   struct Plugin *plugin = cls;
2764   struct FragmentMessage *fm;
2765   struct FragmentMessage *fm2;
2766   struct GNUNET_PeerIdentity tmpsource;
2767
2768   GNUNET_assert (plugin != NULL);
2769
2770   //ADVERTISEMENT
2771   if (ntohs (hdr->type) == GNUNET_MESSAGE_TYPE_HELLO)
2772   {
2773
2774     //TODO better DOS protection, error handling
2775     //TODO test first than create session
2776     GNUNET_assert (session_light != NULL);
2777
2778 #if DEBUG_wlan
2779     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2780                      "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_HELLO size: %u; %s\n",
2781                      ntohs (hdr->size), wlan_plugin_address_to_string (NULL,
2782                                                                        session_light->addr.
2783                                                                        mac, 6));
2784 #endif
2785
2786     if (session_light->macendpoint == NULL)
2787     {
2788       session_light->macendpoint =
2789           get_macendpoint (plugin, &session_light->addr, GNUNET_YES);
2790     }
2791
2792
2793     if (GNUNET_HELLO_get_id
2794         ((const struct GNUNET_HELLO_Message *) hdr, &tmpsource) == GNUNET_OK)
2795     {
2796       session_light->session =
2797           search_session (plugin, session_light->macendpoint, &tmpsource);
2798       if (session_light->session == NULL)
2799       {
2800         session_light->session =
2801             create_session (plugin, session_light->macendpoint, &tmpsource);
2802       }
2803       GNUNET_STATISTICS_update (plugin->env->stats,
2804                                 _("# wlan hello messages received"), 1,
2805                                 GNUNET_NO);
2806       plugin->env->receive (plugin->env->cls, &session_light->session->target,
2807                             hdr, NULL, 0, session_light->session,
2808                             (const char *) &session_light->session->mac->addr,
2809                             sizeof (session_light->session->mac->addr));
2810     }
2811     else
2812     {
2813       GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, PLUGIN_LOG_NAME,
2814                        "WLAN client not in session list and hello message is not okay\n");
2815       return;
2816     }
2817   }
2818
2819   //FRAGMENT
2820
2821   else if (ntohs (hdr->type) == GNUNET_MESSAGE_TYPE_FRAGMENT)
2822   {
2823
2824     GNUNET_assert (session_light != NULL);
2825     if (session_light->macendpoint == NULL)
2826     {
2827       session_light->macendpoint =
2828           get_macendpoint (plugin, &session_light->addr, GNUNET_YES);
2829     }
2830
2831 #if DEBUG_wlan
2832     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2833                      "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_FRAGMENT with size: %u; mac endpoint %p: %s\n",
2834                      ntohs (hdr->size), session_light->macendpoint,
2835                      wlan_plugin_address_to_string (NULL,
2836                                                     session_light->addr.mac,
2837                                                     6));
2838 #endif
2839
2840     GNUNET_STATISTICS_update (plugin->env->stats,
2841                               _("# wlan fragments received"), 1, GNUNET_NO);
2842     int ret =
2843         GNUNET_DEFRAGMENT_process_fragment (session_light->macendpoint->defrag,
2844                                             hdr);
2845
2846     if (ret == GNUNET_NO)
2847     {
2848       session_light->macendpoint->dups++;
2849     }
2850     else if (ret == GNUNET_OK)
2851     {
2852       session_light->macendpoint->fragc++;
2853     }
2854     set_next_send (plugin);
2855
2856   }
2857
2858   //ACK
2859
2860   else if (ntohs (hdr->type) == GNUNET_MESSAGE_TYPE_FRAGMENT_ACK)
2861   {
2862     GNUNET_assert (session_light != NULL);
2863     if (session_light->macendpoint == NULL)
2864     {
2865       session_light->macendpoint =
2866           get_macendpoint (plugin, &session_light->addr, GNUNET_NO);
2867     }
2868
2869     if (session_light->macendpoint == NULL)
2870     {
2871 #if DEBUG_wlan
2872       GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2873                        "Macendpoint does not exist for this GNUNET_MESSAGE_TYPE_FRAGMENT_ACK size: %u; %s\n",
2874                        ntohs (hdr->size), wlan_plugin_address_to_string (NULL,
2875                                                                          session_light->addr.mac,
2876                                                                          6));
2877 #endif
2878       return;
2879     }
2880
2881 #if DEBUG_wlan
2882     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2883                      "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_FRAGMENT_ACK size: %u; mac endpoint: %p; %s\n",
2884                      ntohs (hdr->size), session_light->macendpoint,
2885                      wlan_plugin_address_to_string (NULL,
2886                                                     session_light->addr.mac,
2887                                                     6));
2888 #endif
2889     fm = session_light->macendpoint->sending_messages_head;
2890     while (fm != NULL)
2891     {
2892       fm2 = fm->next;
2893       GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan acks received"),
2894                                 1, GNUNET_NO);
2895       int ret = GNUNET_FRAGMENT_process_ack (fm->fragcontext, hdr);
2896
2897       if (ret == GNUNET_OK)
2898       {
2899 #if DEBUG_wlan_retransmission > 1
2900         GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2901                          "Got last ack, finished fragment message %p\n", fm);
2902 #endif
2903         session_light->macendpoint->acks++;
2904         fm->session->last_activity = GNUNET_TIME_absolute_get ();
2905         session_light->macendpoint->last_activity = fm->session->last_activity;
2906         free_fragment_message (plugin, fm);
2907         check_fragment_queue (plugin);
2908         return;
2909       }
2910       if (ret == GNUNET_NO)
2911       {
2912 #if DEBUG_wlan_retransmission > 1
2913         GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2914                          "Got ack for: %p\n", fm);
2915 #endif
2916         session_light->macendpoint->acks++;
2917         return;
2918       }
2919       if (ret == GNUNET_SYSERR)
2920       {
2921
2922       }
2923
2924       fm = fm2;
2925     }
2926
2927 #if DEBUG_wlan_retransmission > 1
2928     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2929                      "WLAN fragment not in fragment list\n");
2930 #endif
2931     return;
2932
2933   }
2934   else
2935   {
2936     // TODO Wrong data?
2937     GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, PLUGIN_LOG_NAME,
2938                      "WLAN packet inside the WLAN helper packet has not the right type: %u size: %u\n",
2939                      ntohs (hdr->type), ntohs (hdr->size));
2940     GNUNET_break (0);
2941     return;
2942   }
2943
2944 #if 0
2945   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
2946                    "Helper finished\n");
2947 #endif
2948
2949 }
2950
2951 /**
2952  * Function to print mac addresses nice *
2953  * @param pointer to 6 byte with the mac address
2954  * @return pointer to the chars which hold the print out
2955  */
2956 const char *
2957 macprinter (const u_int8_t * mac)
2958 {
2959   static char macstr[20];
2960
2961   GNUNET_snprintf (macstr, sizeof (macstr), "%X:%X:%X:%X:%X:%X", mac[0], mac[1],
2962                    mac[2], mac[3], mac[4], mac[5]);
2963   return macstr;
2964 }
2965
2966 /**
2967  * Function for the scheduler if a mac endpoint times out
2968  * @param cls pointer to the MacEndpoint
2969  * @param tc pointer to the GNUNET_SCHEDULER_TaskContext
2970  */
2971 static void
2972 macendpoint_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
2973 {
2974   struct MacEndpoint *endpoint = cls;
2975
2976   GNUNET_assert (endpoint != NULL);
2977   endpoint->timeout_task = GNUNET_SCHEDULER_NO_TASK;
2978   if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
2979   {
2980     return;
2981   }
2982   if (GNUNET_TIME_absolute_get_remaining
2983       (GNUNET_TIME_absolute_add
2984        (endpoint->last_activity, MACENDPOINT_TIMEOUT)).rel_value == 0)
2985   {
2986     GNUNET_assert (endpoint->plugin != NULL);
2987     GNUNET_STATISTICS_update (endpoint->plugin->env->stats,
2988                               _("# wlan mac endpoints timeouts"), 1, GNUNET_NO);
2989     free_macendpoint (endpoint->plugin, endpoint);
2990   }
2991   else
2992   {
2993     endpoint->timeout_task =
2994         GNUNET_SCHEDULER_add_delayed (MACENDPOINT_TIMEOUT, &macendpoint_timeout,
2995                                       endpoint);
2996   }
2997 }
2998
2999 /**
3000  * function to create an macendpoint
3001  * @param plugin pointer to the plugin struct
3002  * @param addr pointer to the macaddress
3003  * @return returns a macendpoint
3004  */
3005 static struct MacEndpoint *
3006 create_macendpoint (struct Plugin *plugin, const struct MacAddress *addr)
3007 {
3008   struct MacEndpoint *newend = GNUNET_malloc (sizeof (struct MacEndpoint));
3009
3010   GNUNET_assert (plugin != NULL);
3011   GNUNET_STATISTICS_update (plugin->env->stats,
3012                             _("# wlan mac endpoints created"), 1, GNUNET_NO);
3013   newend->addr = *addr;
3014   newend->plugin = plugin;
3015   newend->addr = *addr;
3016   newend->fragment_messages_out_count = 0;
3017   newend->defrag =
3018       GNUNET_DEFRAGMENT_context_create (plugin->env->stats, WLAN_MTU,
3019                                         MESSAGES_IN_DEFRAG_QUEUE_PER_MAC,
3020                                         newend, &wlan_data_message_handler,
3021                                         &add_ack_for_send);
3022   newend->last_activity = GNUNET_TIME_absolute_get ();
3023   newend->timeout_task =
3024       GNUNET_SCHEDULER_add_delayed (MACENDPOINT_TIMEOUT, &macendpoint_timeout,
3025                                     newend);
3026
3027   plugin->mac_count++;
3028   GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan mac endpoints"),
3029                          plugin->mac_count, GNUNET_NO);
3030   GNUNET_CONTAINER_DLL_insert_tail (plugin->mac_head, plugin->mac_tail, newend);
3031 #if DEBUG_wlan
3032   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
3033                    "New Mac Endpoint %p: %s\n", newend,
3034                    wlan_plugin_address_to_string (NULL, newend->addr.mac, 6));
3035 #endif
3036   return newend;
3037 }
3038
3039 /**
3040  * Function used for to process the data from the suid process
3041  *
3042  * @param cls the plugin handle
3043  * @param client client that send the data (not used)
3044  * @param hdr header of the GNUNET_MessageHeader
3045  */
3046 static void
3047 wlan_process_helper (void *cls, void *client,
3048                      const struct GNUNET_MessageHeader *hdr)
3049 {
3050   struct Plugin *plugin = cls;
3051   struct ieee80211_frame *wlanIeeeHeader = NULL;
3052   struct Session_light *session_light = NULL;
3053   struct Radiotap_rx *rxinfo;
3054   const struct GNUNET_MessageHeader *temp_hdr = NULL;
3055
3056   int datasize = 0;
3057   int pos;
3058
3059   GNUNET_assert (plugin != NULL);
3060   switch (ntohs (hdr->type))
3061   {
3062   case GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA:
3063 #if DEBUG_wlan
3064     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
3065                      "Func wlan_process_helper got GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA size: %u\n",
3066                      ntohs (hdr->size));
3067 #endif
3068
3069     GNUNET_STATISTICS_update (plugin->env->stats,
3070                               _("# wlan WLAN_HELPER_DATA received"), 1,
3071                               GNUNET_NO);
3072     //call wlan_process_helper with the message inside, later with wlan: analyze signal
3073     if (ntohs (hdr->size) <
3074         sizeof (struct ieee80211_frame) +
3075         2 * sizeof (struct GNUNET_MessageHeader) + sizeof (struct Radiotap_rx))
3076     {
3077 #if DEBUG_wlan
3078       GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
3079                        "Size of packet is too small; size: %u min size: %u\n",
3080                        ntohs (hdr->size),
3081                        sizeof (struct ieee80211_frame) +
3082                        sizeof (struct GNUNET_MessageHeader));
3083 #endif
3084       //GNUNET_break (0);
3085       /* FIXME: restart SUID process */
3086       return;
3087     }
3088
3089     rxinfo = (struct Radiotap_rx *) &hdr[1];
3090     wlanIeeeHeader = (struct ieee80211_frame *) &rxinfo[1];
3091
3092     //process only if it is an broadcast or for this computer both with the gnunet bssid
3093
3094     //check for bssid
3095     if (memcmp
3096         (&(wlanIeeeHeader->i_addr3), &mac_bssid,
3097          sizeof (struct MacAddress)) == 0)
3098     {
3099       //check for broadcast or mac
3100       if ((memcmp
3101            (&(wlanIeeeHeader->i_addr1), &bc_all_mac,
3102             sizeof (struct MacAddress)) == 0) ||
3103           (memcmp
3104            (&(wlanIeeeHeader->i_addr1), &(plugin->mac_address),
3105             sizeof (struct MacAddress)) == 0))
3106       {
3107         //if packet is from us return
3108         if ((memcmp
3109              (&(wlanIeeeHeader->i_addr2), &(plugin->mac_address),
3110               sizeof (struct MacAddress)) == 0))
3111         {
3112           return;
3113         }
3114         // process the inner data
3115
3116
3117         datasize =
3118             ntohs (hdr->size) - sizeof (struct ieee80211_frame) -
3119             sizeof (struct GNUNET_MessageHeader) - sizeof (struct Radiotap_rx);
3120
3121         session_light = GNUNET_malloc (sizeof (struct Session_light));
3122         memcpy (&session_light->addr, &(wlanIeeeHeader->i_addr2),
3123                 sizeof (struct MacAddress));
3124         //session_light->session = search_session(plugin,session_light->addr);
3125         GNUNET_STATISTICS_update (plugin->env->stats,
3126                                   _("# wlan messages for this client received"),
3127                                   1, GNUNET_NO);
3128
3129         pos = 0;
3130         while (pos < datasize)
3131         {
3132           temp_hdr = (struct GNUNET_MessageHeader *) &wlanIeeeHeader[1] + pos;
3133           if (ntohs (temp_hdr->size) <= datasize + pos)
3134           {
3135             GNUNET_STATISTICS_update (plugin->env->stats,
3136                                       _
3137                                       ("# wlan messages inside WLAN_HELPER_DATA received"),
3138                                       1, GNUNET_NO);
3139             wlan_data_helper (plugin, session_light, temp_hdr, rxinfo);
3140           }
3141           else
3142           {
3143 #if DEBUG_wlan
3144             GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
3145                              "Size of packet is too small; size: %u > size of packet: %u\n",
3146                              ntohs (temp_hdr->size), datasize + pos);
3147 #endif
3148           }
3149           pos += ntohs (temp_hdr->size);
3150
3151         }
3152
3153         //clean up
3154         GNUNET_free (session_light);
3155       }
3156       else
3157       {
3158 #if DEBUG_wlan
3159         GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
3160                          "Func wlan_process_helper got wrong MAC: %s\n",
3161                          macprinter (wlanIeeeHeader->i_addr1));
3162 #endif
3163       }
3164     }
3165     else
3166     {
3167 #if DEBUG_wlan
3168       GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
3169                        "Func wlan_process_helper got wrong BSSID: %s\n",
3170                        macprinter (wlanIeeeHeader->i_addr2));
3171 #endif
3172     }
3173     break;
3174   case GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL:
3175     //TODO more control messages
3176     if (ntohs (hdr->size) != sizeof (struct Wlan_Helper_Control_Message))
3177     {
3178       GNUNET_break (0);
3179       /* FIXME: restart SUID process */
3180       return;
3181     }
3182     memcpy (&plugin->mac_address, &hdr[1], sizeof (struct MacAddress));
3183 #if DEBUG_wlan
3184     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
3185                      "Received WLAN_HELPER_CONTROL message with transport of address %s\n",
3186                      wlan_plugin_address_to_string (cls, &plugin->mac_address,
3187                                                     sizeof (struct
3188                                                             MacAddress)));
3189 #endif
3190     plugin->env->notify_address (plugin->env->cls, GNUNET_YES,
3191                                  &plugin->mac_address,
3192                                  sizeof (struct MacAddress));
3193     break;
3194   default:
3195 #if DEBUG_wlan
3196     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
3197                      "Func wlan_process_helper got unknown message with number %u, size %u\n",
3198                      ntohs (hdr->type), ntohs (hdr->size));
3199
3200 #endif
3201 #if DEBUG_wlan_msg_dump > 1
3202     hexdump (hdr, GNUNET_MIN (ntohs (hdr->size), 256));
3203 #endif
3204     GNUNET_break (0);
3205     return;
3206   }
3207 }
3208
3209 /**
3210  * Exit point from the plugin.
3211  * @param cls pointer to the api struct
3212  */
3213
3214 //FIXME cleanup
3215 void *
3216 libgnunet_plugin_transport_wlan_done (void *cls)
3217 {
3218   struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
3219   struct Plugin *plugin = api->cls;
3220   struct MacEndpoint *endpoint = plugin->mac_head;
3221   struct MacEndpoint *endpoint_next;
3222
3223 #if DEBUG_wlan
3224   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
3225                    "libgnunet_plugin_transport_wlan_done started\n");
3226 #endif
3227
3228   wlan_transport_stop_wlan_helper (plugin);
3229
3230   GNUNET_assert (cls != NULL);
3231   //free sessions
3232   while (endpoint != NULL)
3233   {
3234     endpoint_next = endpoint->next;
3235     free_macendpoint (plugin, endpoint);
3236     endpoint = endpoint_next;
3237
3238   }
3239
3240
3241   if (plugin->suid_tokenizer != NULL)
3242     GNUNET_SERVER_mst_destroy (plugin->suid_tokenizer);
3243
3244   if (plugin->data_tokenizer != NULL)
3245     GNUNET_SERVER_mst_destroy (plugin->data_tokenizer);
3246
3247   GNUNET_free_non_null (plugin->interface);
3248   GNUNET_free (plugin);
3249   GNUNET_free (api);
3250   return NULL;
3251 }
3252
3253 /**
3254  * Entry point for the plugin.
3255  *
3256  * @param cls closure, the 'struct GNUNET_TRANSPORT_PluginEnvironment*'
3257  * @return the 'struct GNUNET_TRANSPORT_PluginFunctions*' or NULL on error
3258  */
3259 void *
3260 libgnunet_plugin_transport_wlan_init (void *cls)
3261 {
3262   //struct GNUNET_SERVICE_Context *service;
3263   struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
3264   struct GNUNET_TRANSPORT_PluginFunctions *api;
3265   struct Plugin *plugin;
3266
3267   GNUNET_assert (cls != NULL);
3268
3269   plugin = GNUNET_malloc (sizeof (struct Plugin));
3270   plugin->env = env;
3271   plugin->pendingsessions = 0;
3272   GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"),
3273                          plugin->pendingsessions, GNUNET_NO);
3274   plugin->mac_count = 0;
3275   GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan mac endpoints"),
3276                          plugin->mac_count, GNUNET_NO);
3277   plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
3278   plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK;
3279   plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK;
3280   GNUNET_BANDWIDTH_tracker_init (&plugin->tracker,
3281                                  GNUNET_BANDWIDTH_value_init (100 * 1024 *
3282                                                               1024 / 8), 100);
3283
3284   plugin->suid_tokenizer =
3285       GNUNET_SERVER_mst_create (&wlan_process_helper, plugin);
3286
3287   plugin->data_tokenizer = GNUNET_SERVER_mst_create (&process_data, plugin);
3288
3289   //plugin->sessions = GNUNET_malloc (sizeof (struct Sessionqueue));
3290   //plugin->pending_Sessions_head = GNUNET_malloc (sizeof (struct Sessionqueue));
3291
3292   api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
3293   api->cls = plugin;
3294   api->send = &wlan_plugin_send;
3295   api->disconnect = &wlan_plugin_disconnect;
3296   api->address_pretty_printer = &wlan_plugin_address_pretty_printer;
3297   api->check_address = &wlan_plugin_address_suggested;
3298   api->address_to_string = &wlan_plugin_address_to_string;
3299
3300   //read config
3301
3302   if (GNUNET_CONFIGURATION_have_value (env->cfg, "transport-wlan", "TESTMODE"))
3303   {
3304     if (GNUNET_SYSERR ==
3305         GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-wlan",
3306                                                "TESTMODE", &(plugin->testmode)))
3307       plugin->testmode = 0;     //default value
3308   }
3309
3310   if (GNUNET_CONFIGURATION_have_value (env->cfg, "transport-wlan", "INTERFACE"))
3311   {
3312     if (GNUNET_CONFIGURATION_get_value_string
3313         (env->cfg, "transport-wlan", "INTERFACE",
3314          &(plugin->interface)) != GNUNET_YES)
3315     {
3316       libgnunet_plugin_transport_wlan_done (api);
3317       return NULL;
3318     }
3319   }
3320
3321   //start the plugin
3322   wlan_transport_start_wlan_helper (plugin);
3323   set_next_beacon_time (plugin);
3324   set_next_send (plugin);
3325 #if DEBUG_wlan
3326   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
3327                    "wlan init finished\n");
3328 #endif
3329
3330   return api;
3331 }
3332
3333 /* end of plugin_transport_wlan.c */