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