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