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