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