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