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