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