-makefile for new test_stream_local (commented)
[oweals/gnunet.git] / src / transport / plugin_transport_wlan.c
index b3faf4480b32a1e1de1dee621de49c5005356807..a3d90b5982988cd25589e4f9a2b809eb5342762d 100644 (file)
@@ -1,27 +1,28 @@
 /*
- This file is part of GNUnet
(C) 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Christian Grothoff (and other contributing authors)
 This file is part of GNUnet
 (C) 2010, 2011, 2012 Christian Grothoff (and other contributing authors)
 
- GNUnet is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published
- by the Free Software Foundation; either version 3, or (at your
- option) any later version.
 GNUnet is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published
 by the Free Software Foundation; either version 3, or (at your
 option) any later version.
 
- GNUnet is distributed in the hope that it will be useful, but
- WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
- General Public License for more details.
 GNUnet is distributed in the hope that it will be useful, but
 WITHOUT ANY WARRANTY; without even the implied warranty of
 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 General Public License for more details.
 
- You should have received a copy of the GNU General Public License
- along with GNUnet; see the file COPYING.  If not, write to the
- Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- Boston, MA 02111-1307, USA.
- */
 You should have received a copy of the GNU General Public License
 along with GNUnet; see the file COPYING.  If not, write to the
 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.
+*/
 
 /**
  * @file transport/plugin_transport_wlan.c
  * @brief transport plugin for wlan
  * @author David Brodski
+ * @author Christian Grothoff
  */
 
 //TODO split rx and tx structures for better handling
 #include "gnunet_crypto_lib.h"
 #include "gnunet_fragmentation_lib.h"
 #include "gnunet_constants.h"
-//#include "wlan/ieee80211.h"
-//#include  <netinet/ip.h>
 
-#include <string.h>
+/**
+ * DEBUG switch
+ */
+#define DEBUG_WLAN GNUNET_EXTRA_LOGGING
+
 
 #define PROTOCOL_PREFIX "wlan"
 
  */
 #define HELLO_BEACON_SCALING_FACTOR 30
 
+/**
+ * scaling factor for restarting the helper
+ */
+#define HELPER_RESTART_SCALING_FACTOR 2
+
 /**
  * max size of fragment queue
  */
  * max messages in in queue
  */
 #define MESSAGES_IN_QUEUE_SIZE 10
+
 /**
  * max messages in in queue per session/client
  */
 #define MESSAGES_IN_DEFRAG_QUEUE_PER_MAC 1
 
 /**
- * LLC fields for better compatibility
- */
-#define WLAN_LLC_DSAP_FIELD 0xf
-#define WLAN_LLC_SSAP_FIELD 0xf
-
-
-/**
- * DEBUG switch
- */
-#define DEBUG_wlan GNUNET_EXTRA_LOGGING
-#define DEBUG_wlan_retransmission GNUNET_EXTRA_LOGGING
-#define DEBUG_wlan_ip_udp_packets_on_air GNUNET_NO
-#define DEBUG_wlan_msg_dump GNUNET_EXTRA_LOGGING
-
-
-#define IEEE80211_ADDR_LEN      6       /* size of 802.11 address */
-
-#define IEEE80211_FC0_VERSION_MASK              0x03
-#define IEEE80211_FC0_VERSION_SHIFT             0
-#define IEEE80211_FC0_VERSION_0                 0x00
-#define IEEE80211_FC0_TYPE_MASK                 0x0c
-#define IEEE80211_FC0_TYPE_SHIFT                2
-#define IEEE80211_FC0_TYPE_MGT                  0x00
-#define IEEE80211_FC0_TYPE_CTL                  0x04
-#define IEEE80211_FC0_TYPE_DATA                 0x08
-
-/*
- * Structure of an internet header, naked of options.
+ * Link layer control fields for better compatibility
+ * (i.e. GNUnet over WLAN is not IP-over-WLAN).
  */
-struct iph
-{
-#if __BYTE_ORDER == __LITTLE_ENDIAN
-  unsigned int ip_hl:4;         /* header length */
-  unsigned int ip_v:4;          /* version */
-#endif
-#if __BYTE_ORDER == __BIG_ENDIAN
-  unsigned int ip_v:4;          /* version */
-  unsigned int ip_hl:4;         /* header length */
-#endif
-  u_int8_t ip_tos;              /* type of service */
-  u_short ip_len;               /* total length */
-  u_short ip_id;                /* identification */
-  u_short ip_off;               /* fragment offset field */
-#define IP_RF 0x8000            /* reserved fragment flag */
-#define IP_DF 0x4000            /* dont fragment flag */
-#define IP_MF 0x2000            /* more fragments flag */
-#define IP_OFFMASK 0x1fff       /* mask for fragmenting bits */
-  u_int8_t ip_ttl;              /* time to live */
-  u_int8_t ip_p;                /* protocol */
-  u_short ip_sum;               /* checksum */
-  struct in_addr ip_src, ip_dst;        /* source and dest address */
-};
+#define WLAN_LLC_DSAP_FIELD 0x1f
+#define WLAN_LLC_SSAP_FIELD 0x1f
 
-struct udphdr
-{
-  u_int16_t source;
-  u_int16_t dest;
-  u_int16_t len;
-  u_int16_t check;
-};
 
-/*
- * generic definitions for IEEE 802.11 frames
- */
-struct ieee80211_frame
-{
-  u_int8_t i_fc[2];
-  u_int8_t i_dur[2];
-  u_int8_t i_addr1[IEEE80211_ADDR_LEN];
-  u_int8_t i_addr2[IEEE80211_ADDR_LEN];
-  u_int8_t i_addr3[IEEE80211_ADDR_LEN];
-  u_int8_t i_seq[2];
-  u_int8_t llc[4];
-#if DEBUG_wlan_ip_udp_packets_on_air > 1
-  struct iph ip;
-  struct udphdr udp;
-#endif
-} GNUNET_PACKED;
 
 /**
  * Encapsulation of all of the state of the plugin.
@@ -206,22 +144,22 @@ struct Plugin
   struct GNUNET_SERVER_MessageStreamTokenizer *data_tokenizer;
 
   /**
-   * stdout pipe handle for the gnunet-wlan-helper process
+   * stdout pipe handle for the gnunet-helper-transport-wlan process
    */
   struct GNUNET_DISK_PipeHandle *server_stdout;
 
   /**
-   * stdout file handle for the gnunet-wlan-helper process
+   * stdout file handle for the gnunet-helper-transport-wlan process
    */
   const struct GNUNET_DISK_FileHandle *server_stdout_handle;
 
   /**
-   * stdin pipe handle for the gnunet-wlan-helper process
+   * stdin pipe handle for the gnunet-helper-transport-wlan process
    */
   struct GNUNET_DISK_PipeHandle *server_stdin;
 
   /**
-   * stdin file handle for the gnunet-wlan-helper process
+   * stdin file handle for the gnunet-helper-transport-wlan process
    */
   const struct GNUNET_DISK_FileHandle *server_stdin_handle;
 
@@ -250,10 +188,15 @@ struct Plugin
    */
   char *interface;
 
+  /**
+   * Mode of operation for the helper, 0 = normal, 1 = first loopback, 2 = second loopback
+   */
+  long long unsigned int testmode;
+
   /**
    * The mac_address of the wlan card given to us by the helper.
    */
-  struct MacAddress mac_address;
+  struct GNUNET_TRANSPORT_WLAN_MacAddress mac_address;
 
   /**
    * Sessions currently pending for transmission
@@ -281,10 +224,12 @@ struct Plugin
    * messages ready for send, head
    */
   struct FragmentMessage_queue *sending_messages_head;
+
   /**
    * messages ready for send, tail
    */
   struct FragmentMessage_queue *sending_messages_tail;
+
   /**
    * time of the next "hello-beacon"
    */
@@ -304,6 +249,11 @@ struct Plugin
    * Tracker for bandwidth limit
    */
   struct GNUNET_BANDWIDTH_Tracker tracker;
+
+  /**
+   * saves the current state of the helper process
+   */
+  int helper_is_running;
 };
 
 /**
@@ -311,27 +261,46 @@ struct Plugin
  */
 struct Finish_send
 {
+  /**
+   * pointer to the global plugin struct
+   */
   struct Plugin *plugin;
-  char *msgheader;
+
+  /**
+   * head of the next part to send to the helper
+   */
+  const char *head_of_next_write;
+
+  /**
+   * Start of the message to send, needed for free
+   */
   struct GNUNET_MessageHeader *msgstart;
+
+  /**
+   * rest size to send
+   */
   ssize_t size;
 };
 
 /**
  * Queue of sessions, for the general session queue and the pending session queue
  */
-//TODO DOXIGEN
+//TODO DOXYGEN
 struct Sessionqueue
 {
   struct Sessionqueue *next;
   struct Sessionqueue *prev;
   struct Session *content;
+#if !HAVE_UNALIGNED_64_ACCESS
+  void *dummy;                  /* for alignment, see #1909 */
+#endif
 };
 
+
 /**
  * Queue of fragmented messages, for the sending queue of the plugin
  */
-//TODO DOXIGEN
+//TODO DOXYGEN
 struct FragmentMessage_queue
 {
   struct FragmentMessage_queue *next;
@@ -339,21 +308,24 @@ struct FragmentMessage_queue
   struct FragmentMessage *content;
 };
 
+
 /**
  * Queue for the fragments received
  */
-//TODO DOXIGEN
+//TODO DOXYGEN
 struct Receive_Fragment_Queue
 {
   struct Receive_Fragment_Queue *next;
   struct Receive_Fragment_Queue *prev;
+
   uint16_t num;
-  const char *msg;
-  uint16_t size;
-  struct Radiotap_rx rxinfo;
+  // const char *msg;
+  //   uint16_t size;
+  struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rx_msg;
 };
 
-//TODO DOXIGEN
+
+//TODO DOXYGEN
 struct MacEndpoint_id_fragment_triple
 {
   struct MacEndpoint *endpoint;
@@ -361,13 +333,48 @@ struct MacEndpoint_id_fragment_triple
   struct FragmentMessage *fm;
 };
 
-//TODO DOXIGEN
+//TODO DOXYGEN
 struct Plugin_Session_pair
 {
   struct Plugin *plugin;
   struct Session *session;
 };
 
+
+GNUNET_NETWORK_STRUCT_BEGIN
+
+/**
+ * Header for messages which need fragmentation
+ */
+struct WlanHeader
+{
+
+  /**
+   * Message type is GNUNET_MESSAGE_TYPE_WLAN_DATA.
+   */
+  struct GNUNET_MessageHeader header;
+
+  /**
+   * checksum/error correction
+   */
+  uint32_t crc GNUNET_PACKED;
+
+  /**
+   * To whom are we talking to (set to our identity
+   * if we are still waiting for the welcome message)
+   */
+  struct GNUNET_PeerIdentity target;
+
+  /**
+   *  Where the packet came from
+   */
+  struct GNUNET_PeerIdentity source;
+
+// followed by payload
+
+};
+GNUNET_NETWORK_STRUCT_END
+
 /**
  * Information kept for each message that is yet to
  * be transmitted.
@@ -378,6 +385,7 @@ struct PendingMessage
    * dll next
    */
   struct PendingMessage *next;
+
   /**
    * dll prev
    */
@@ -412,6 +420,7 @@ struct PendingMessage
 
 };
 
+
 /**
  * Queue for acks to send for fragments recived
  */
@@ -422,53 +431,28 @@ struct AckSendQueue
    * next ack in the ack send queue
    */
   struct AckSendQueue *next;
+
   /**
    * previous ack in the ack send queue
    */
   struct AckSendQueue *prev;
+
   /**
    * pointer to the session this ack belongs to
    */
   struct MacEndpoint *endpoint;
+
   /**
    * ID of message, to distinguish between the messages, picked randomly.
    */
   uint32_t message_id;
 
   /**
-   * msg to send
-   */
-  struct GNUNET_MessageHeader *hdr;
-  /**
-   * pointer to the ieee wlan header
-   */
-  struct ieee80211_frame *ieeewlanheader;
-  /**
-   * pointer to the radiotap header
+   * pointer to the radiotap header with the ACK Message.
    */
-  struct Radiotap_Send *radioHeader;
+  const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *radioHeader;
 };
 
-/**
- * Session infos gathered from a messages
- */
-
-struct Session_light
-{
-  /**
-   * the session this message belongs to
-   */
-  struct Session *session;
-  /**
-   * peer mac address
-   */
-  struct MacAddress addr;
-
-  /**
-   * mac endpoint
-   */
-  struct MacEndpoint *macendpoint;
-};
 
 /**
  * Session handle for connections.
@@ -538,14 +522,17 @@ struct MacEndpoint
    * Pointer to the global plugin struct.
    */
   struct Plugin *plugin;
+
   /**
    * Struct to hold the session reachable over this mac; head
    */
   struct Sessionqueue *sessions_head;
+
   /**
    * Struct to hold the session reachable over this mac; tail
    */
   struct Sessionqueue *sessions_tail;
+
   /**
    * Messages currently sending
    * to a peer, if any.
@@ -557,10 +544,12 @@ struct MacEndpoint
    * to a peer (tail), if any.
    */
   struct FragmentMessage *sending_messages_tail;
+
   /**
    * dll next
    */
   struct MacEndpoint *next;
+
   /**
    * dll prev
    */
@@ -569,7 +558,7 @@ struct MacEndpoint
   /**
    * peer mac address
    */
-  struct MacAddress addr;
+  struct GNUNET_TRANSPORT_WLAN_MacAddress addr;
 
   /**
    * Defrag context for this mac endpoint
@@ -579,10 +568,9 @@ struct MacEndpoint
   /**
    * count of messages in the fragment out queue for this mac endpoint
    */
-
   int fragment_messages_out_count;
 
-  //TODO DOXIGEN
+  //TODO DOXYGEN
   uint8_t rate;
   uint16_t tx_power;
   uint8_t antenna;
@@ -617,14 +605,12 @@ struct MacEndpoint
 /**
  * Struct for Messages in the fragment queue
  */
-
 struct FragmentMessage
 {
 
   /**
    * Session this message belongs to
    */
-
   struct Session *session;
 
   /**
@@ -652,33 +638,29 @@ struct FragmentMessage
    */
   GNUNET_SCHEDULER_TaskIdentifier timeout_task;
 
-  /**
-   * Fragment to send
-   */
-  char *frag;
-
-  /**
-   * size of message
-   */
-  size_t size;
-
-  /**
-   * pointer to the ieee wlan header
-   */
-  struct ieee80211_frame *ieeewlanheader;
   /**
    * pointer to the radiotap header
    */
-  struct Radiotap_Send *radioHeader;
+  struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *radioHeader;
 };
 
+
 static void
 do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
+
+
 static void
 free_session (struct Plugin *plugin, struct Sessionqueue *queue,
               int do_free_macendpoint);
+
+
 static struct MacEndpoint *
-create_macendpoint (struct Plugin *plugin, const struct MacAddress *addr);
+create_macendpoint (struct Plugin *plugin, const struct GNUNET_TRANSPORT_WLAN_MacAddress *addr);
+
+
+static void
+finish_sending (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc);
+
 
 /**
  * Generates a nice hexdump of a memory area.
@@ -709,7 +691,8 @@ hexdump (const void *mem, unsigned length)
         t += sprintf (t, "%02X", src[j] & 0xff);
       else
         t += sprintf (t, "  ");
-      t += sprintf (t, j % 2 ? " " : "-");
+
+      t += sprintf (t, (j % 2) ? " " : "-");
     }
 
     t += sprintf (t, "  ");
@@ -733,6 +716,7 @@ hexdump (const void *mem, unsigned length)
   }
 }
 
+
 /**
  * Function to find a MacEndpoint with a specific mac addr
  * @param plugin pointer to the plugin struct
@@ -741,7 +725,7 @@ hexdump (const void *mem, unsigned length)
  * @return
  */
 static struct MacEndpoint *
-get_macendpoint (struct Plugin *plugin, const struct MacAddress *addr,
+get_macendpoint (struct Plugin *plugin, const struct GNUNET_TRANSPORT_WLAN_MacAddress *addr,
                  int create_new)
 {
   struct MacEndpoint *queue = plugin->mac_head;
@@ -749,7 +733,7 @@ get_macendpoint (struct Plugin *plugin, const struct MacAddress *addr,
   while (queue != NULL)
   {
     //GNUNET_assert (queue->sessions_head != NULL);
-    if (memcmp (addr, &queue->addr, sizeof (struct MacAddress)) == 0)
+    if (memcmp (addr, &queue->addr, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
       return queue;             /* session found */
     queue = queue->next;
   }
@@ -762,9 +746,9 @@ get_macendpoint (struct Plugin *plugin, const struct MacAddress *addr,
   {
     return NULL;
   }
-
 }
 
+
 /**
  * search for a session with the macendpoint and peer id
  *
@@ -807,9 +791,9 @@ static const char *
 wlan_plugin_address_to_string (void *cls, const void *addr, size_t addrlen)
 {
   static char ret[40];
-  const struct MacAddress *mac;
+  const struct GNUNET_TRANSPORT_WLAN_MacAddress *mac;
 
-  if (addrlen != sizeof (struct MacAddress))
+  if (addrlen != sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress))
   {
     GNUNET_break (0);
     return NULL;
@@ -833,7 +817,7 @@ session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
   struct Sessionqueue *queue = cls;
 
   GNUNET_assert (queue != NULL);
-  GNUNET_assert(queue->content != NULL);
+  GNUNET_assert (queue->content != NULL);
   queue->content->timeout_task = GNUNET_SCHEDULER_NO_TASK;
   if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
   {
@@ -844,9 +828,10 @@ session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
        (queue->content->last_activity, SESSION_TIMEOUT)).rel_value == 0)
   {
 
-    GNUNET_assert(queue->content->mac != NULL);
-    GNUNET_assert(queue->content->mac->plugin != NULL);
-    GNUNET_STATISTICS_update (queue->content->mac->plugin->env->stats, _("# wlan session timeouts"), 1, GNUNET_NO);
+    GNUNET_assert (queue->content->mac != NULL);
+    GNUNET_assert (queue->content->mac->plugin != NULL);
+    GNUNET_STATISTICS_update (queue->content->mac->plugin->env->stats,
+                              _("# wlan session timeouts"), 1, GNUNET_NO);
     free_session (queue->content->mac->plugin, queue, GNUNET_YES);
   }
   else
@@ -864,14 +849,14 @@ session_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  * @param peer peer identity to use for this session
  * @return returns the session
  */
-
 static struct Session *
 create_session (struct Plugin *plugin, struct MacEndpoint *endpoint,
                 const struct GNUNET_PeerIdentity *peer)
 {
   GNUNET_assert (endpoint != NULL);
   GNUNET_assert (plugin != NULL);
-  GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan session created"), 1, GNUNET_NO);
+  GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan session created"), 1,
+                            GNUNET_NO);
   struct Sessionqueue *queue =
       GNUNET_malloc (sizeof (struct Sessionqueue) + sizeof (struct Session));
 
@@ -880,19 +865,16 @@ create_session (struct Plugin *plugin, struct MacEndpoint *endpoint,
 
   queue->content = (struct Session *) &queue[1];
   queue->content->mac = endpoint;
-  memcpy (&(queue->content->target), peer, sizeof (struct GNUNET_PeerIdentity));
+  queue->content->target = *peer;
   queue->content->last_activity = GNUNET_TIME_absolute_get ();
   queue->content->timeout_task =
       GNUNET_SCHEDULER_add_delayed (SESSION_TIMEOUT, &session_timeout, queue);
 
-#if DEBUG_wlan
   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                    "New session %p with endpoint %p: %s\n", queue->content,
                    endpoint, wlan_plugin_address_to_string (NULL,
                                                             endpoint->addr.mac,
                                                             6));
-#endif
-
   return queue->content;
 }
 
@@ -905,7 +887,7 @@ create_session (struct Plugin *plugin, struct MacEndpoint *endpoint,
  * @return returns the session
  */
 static struct Session *
-get_session (struct Plugin *plugin, const struct MacAddress *addr,
+get_session (struct Plugin *plugin, const struct GNUNET_TRANSPORT_WLAN_MacAddress *addr,
              const struct GNUNET_PeerIdentity *peer)
 {
   struct MacEndpoint *mac;
@@ -954,7 +936,8 @@ queue_session (struct Plugin *plugin, struct Session *session)
     GNUNET_CONTAINER_DLL_insert_tail (plugin->pending_Sessions_head,
                                       plugin->pending_Sessions_tail, queue);
     plugin->pendingsessions++;
-    GNUNET_STATISTICS_set(plugin->env->stats, _("# wlan pending sessions"), plugin->pendingsessions, GNUNET_NO);
+    GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"),
+                           plugin->pendingsessions, GNUNET_NO);
   }
 
 }
@@ -988,7 +971,6 @@ delay_fragment_task (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  * Function to calculate the time of the next periodic "hello-beacon"
  * @param plugin pointer to the plugin struct
  */
-
 static void
 set_next_beacon_time (struct Plugin *const plugin)
 {
@@ -1021,16 +1003,22 @@ set_next_beacon_time (struct Plugin *const plugin)
   }
 }
 
+
 /**
  * Function to set the timer for the next timeout of the fragment queue
  * @param plugin the handle to the plugin struct
  */
-
 static void
-set_next_send (struct Plugin *const plugin)
+set_next_send (struct Plugin *plugin)
 {
   struct GNUNET_TIME_Relative next_send;
 
+  //abort if helper is not running
+  if (plugin->helper_is_running == GNUNET_NO)
+  {
+    return;
+  }
+
   //cancel old task
   if (plugin->server_write_delay_task != GNUNET_SCHEDULER_NO_TASK)
   {
@@ -1054,11 +1042,8 @@ set_next_send (struct Plugin *const plugin)
     next_send = GNUNET_TIME_absolute_get_remaining (plugin->beacon_time);
   }
 
-#if DEBUG_wlan
   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                    "Next packet is send in: %u\n", next_send.rel_value);
-#endif
-
   if (next_send.rel_value == GNUNET_TIME_UNIT_ZERO.rel_value)
   {
     if (plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK)
@@ -1103,24 +1088,23 @@ get_next_queue_session (struct Plugin *plugin)
     pm = session->pending_message_head;
 
     if (pm == NULL)
-        {
-#if DEBUG_wlan
-          GNUNET_log_from(GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
-              "pending message is empty, should not happen. session %p\n",
-              session);
-#endif
-          sessionqueue_alt = sessionqueue;
-          sessionqueue = sessionqueue->next;
-          plugin->pendingsessions--;
-          GNUNET_STATISTICS_set(plugin->env->stats, _("# wlan pending sessions"), plugin->pendingsessions, GNUNET_NO);
-          GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head,
-              plugin->pending_Sessions_tail,
-              sessionqueue_alt);
+    {
+      GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
+                       "pending message is empty, should not happen. session %p\n",
+                       session);
+      sessionqueue_alt = sessionqueue;
+      sessionqueue = sessionqueue->next;
+      plugin->pendingsessions--;
+      GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"),
+                             plugin->pendingsessions, GNUNET_NO);
+      GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head,
+                                   plugin->pending_Sessions_tail,
+                                   sessionqueue_alt);
 
-          GNUNET_free (sessionqueue_alt);
-          continue;
+      GNUNET_free (sessionqueue_alt);
+      continue;
 
-        }
+    }
 
     //check for message timeout
     if (GNUNET_TIME_absolute_get_remaining (pm->timeout).rel_value > 0)
@@ -1132,7 +1116,8 @@ get_next_queue_session (struct Plugin *plugin)
            FRAGMENT_QUEUE_MESSAGES_OUT_PER_SESSION))
       {
         plugin->pendingsessions--;
-        GNUNET_STATISTICS_set(plugin->env->stats, _("# wlan pending sessions"), plugin->pendingsessions, GNUNET_NO);
+        GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"),
+                               plugin->pendingsessions, GNUNET_NO);
         GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head,
                                      plugin->pending_Sessions_tail,
                                      sessionqueue);
@@ -1162,7 +1147,8 @@ get_next_queue_session (struct Plugin *plugin)
         sessionqueue_alt = sessionqueue;
         sessionqueue = sessionqueue->next;
         plugin->pendingsessions--;
-        GNUNET_STATISTICS_set(plugin->env->stats, _("# wlan pending sessions"), plugin->pendingsessions, GNUNET_NO);
+        GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"),
+                               plugin->pendingsessions, GNUNET_NO);
         GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head,
                                      plugin->pending_Sessions_tail,
                                      sessionqueue_alt);
@@ -1188,52 +1174,55 @@ free_fragment_message (struct Plugin *plugin, struct FragmentMessage *fm)
   struct FragmentMessage_queue *fmq;
   struct FragmentMessage_queue *fmq_next;
 
-  if (fm != NULL)
+  fmq = plugin->sending_messages_head;
+  while (fmq != NULL)
   {
-    fmq = plugin->sending_messages_head;
-    while (fmq != NULL)
+    fmq_next = fmq->next;
+    if (fmq->content == fm)
     {
-      fmq_next = fmq->next;
-      if (fmq->content == fm)
-      {
-        GNUNET_CONTAINER_DLL_remove (plugin->sending_messages_head,
-                                     plugin->sending_messages_tail, fmq);
-        GNUNET_free (fmq);
-      }
-      fmq = fmq_next;
+      GNUNET_CONTAINER_DLL_remove (plugin->sending_messages_head,
+                                   plugin->sending_messages_tail, fmq);
+      GNUNET_free (fmq);
     }
-
-    (session->mac->fragment_messages_out_count)--;
-    session->fragment_messages_out_count--;
-    plugin->pending_Fragment_Messages--;
-    GNUNET_CONTAINER_DLL_remove (endpoint->sending_messages_head,
-                                 endpoint->sending_messages_tail, fm);
-    GNUNET_FRAGMENT_context_destroy (fm->fragcontext);
-    if (fm->timeout_task != GNUNET_SCHEDULER_NO_TASK)
-      GNUNET_SCHEDULER_cancel (fm->timeout_task);
-    GNUNET_free (fm);
-
-    queue_session (plugin, session);
-#if DEBUG_wlan
-    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
-                     "Free pending fragment messages %p, session %p\n", fm,
-                     session);
-#endif
-  }
+    fmq = fmq_next;
+  }
+  session->mac->fragment_messages_out_count--;
+  session->fragment_messages_out_count--;
+  plugin->pending_Fragment_Messages--;
+  GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending fragments"),
+                         plugin->pending_Fragment_Messages, GNUNET_NO);
+  GNUNET_CONTAINER_DLL_remove (endpoint->sending_messages_head,
+                               endpoint->sending_messages_tail, fm);
+  GNUNET_FRAGMENT_context_destroy (fm->fragcontext);
+  if (fm->timeout_task != GNUNET_SCHEDULER_NO_TASK)
+  {
+    GNUNET_SCHEDULER_cancel (fm->timeout_task);
+    fm->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+  }
+  GNUNET_free (fm);
+  queue_session (plugin, session);
+  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
+                   "Free pending fragment messages %p, session %p\n", fm,
+                   session);
 }
 
+
 /**
  * function to fill the radiotap header
+ *
  * @param plugin pointer to the plugin struct
  * @param endpoint pointer to the endpoint
  * @param header pointer to the radiotap header
+ * @param size total message size
  * @return GNUNET_YES at success
  */
 static int
 getRadiotapHeader (struct Plugin *plugin, struct MacEndpoint *endpoint,
-                   struct Radiotap_Send *header)
+                   struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header,
+                  uint16_t size)
 {
-
+  header->header.type = ntohs (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER);
+  header->header.size = ntohs (size);
   if (endpoint != NULL)
   {
     header->rate = endpoint->rate;
@@ -1250,274 +1239,520 @@ getRadiotapHeader (struct Plugin *plugin, struct MacEndpoint *endpoint,
   return GNUNET_YES;
 }
 
+
 /**
  * function to generate the wlan hardware header for one packet
  * @param Header address to write the header to
  * @param to_mac_addr address of the recipient
  * @param plugin pointer to the plugin struct
  * @param size size of the whole packet, needed to calculate the time to send the packet
+ *        FIXME: 'size' is initialized inconsistently throughout the code (sometimes payload, sometimes everything)
  * @return GNUNET_YES if there was no error
  */
 static int
-getWlanHeader (struct ieee80211_frame *Header,
-               const struct MacAddress *to_mac_addr, struct Plugin *plugin,
+getWlanHeader (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *Header,
+               const struct GNUNET_TRANSPORT_WLAN_MacAddress *to_mac_addr, struct Plugin *plugin,
                unsigned int size)
 {
-  uint16_t *tmp16;
   const int rate = 11000000;
 
-  Header->i_fc[0] = IEEE80211_FC0_TYPE_DATA;
-  Header->i_fc[1] = 0x00;
-  memcpy (&Header->i_addr3, &mac_bssid, sizeof (mac_bssid));
-  memcpy (&Header->i_addr2, plugin->mac_address.mac,
-          sizeof (plugin->mac_address));
-  memcpy (&Header->i_addr1, to_mac_addr, sizeof (struct MacAddress));
-
-  tmp16 = (uint16_t *) Header->i_dur;
-  *tmp16 = (uint16_t) htole16 ((size * 1000000) / rate + 290);
+  Header->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
+  Header->addr1 = *to_mac_addr;
+  Header->addr2 = plugin->mac_address;
+  Header->addr3 = mac_bssid_gnunet;
+  Header->duration = GNUNET_htole16 ((size * 1000000) / rate + 290);
+  Header->sequence_control = 0; // FIXME?
   Header->llc[0] = WLAN_LLC_DSAP_FIELD;
   Header->llc[1] = WLAN_LLC_SSAP_FIELD;
-
-#if DEBUG_wlan_ip_udp_packets_on_air > 1
-  uint crc = 0;
-  uint16_t *x;
-  int count;
-
-  Header->ip.ip_dst.s_addr = *((uint32_t *) & to_mac_addr->mac[2]);
-  Header->ip.ip_src.s_addr = *((uint32_t *) & plugin->mac_address.mac[2]);
-  Header->ip.ip_v = 4;
-  Header->ip.ip_hl = 5;
-  Header->ip.ip_p = 17;
-  Header->ip.ip_ttl = 1;
-  Header->ip.ip_len = htons (size + 8);
-  Header->ip.ip_sum = 0;
-  x = (uint16_t *) & Header->ip;
-  count = sizeof (struct iph);
-  while (count > 1)
-  {
-    /* This is the inner loop */
-    crc += (unsigned short) *x++;
-    count -= 2;
-  }
-  /* Add left-over byte, if any */
-  if (count > 0)
-    crc += *(unsigned char *) x;
-  crc = (crc & 0xffff) + (crc >> 16);
-  Header->ip.ip_sum = htons (~(unsigned short) crc);
-  Header->udp.len = htons (size - sizeof (struct ieee80211_frame));
-
-#endif
-
+  Header->llc[2] = 0;  // FIXME?
+  Header->llc[3] = 0;  // FIXME?
   return GNUNET_YES;
 }
 
-/**
- * 32bit CRC
- *
- * @param msgbuf pointer tor the data
- * @param msgbuf_size size of the data
- *
- * @return 32bit crc value
- */
-
-uint32_t
-getcrc32 (const char *msgbuf, size_t msgbuf_size)
-{
-
-  return GNUNET_CRYPTO_crc32_n (msgbuf, msgbuf_size);;
-}
-
-/**
- * 16bit CRC
- *
- * @param msgbuf pointer tor the data
- * @param msgbuf_size size of the data
- *
- * @return 16bit crc value
- */
-
-uint16_t
-getcrc16 (const char *msgbuf, size_t msgbuf_size)
-{
-  //TODO calc some crc
-  return 0;
-}
 
 /**
  * function to add a fragment of a message to send
  * @param cls FragmentMessage this message belongs to
  * @param hdr pointer to the start of the message
  */
-
-void
+static void
 add_message_for_send (void *cls, const struct GNUNET_MessageHeader *hdr)
 {
-
   struct FragmentMessage *fm = cls;
   struct FragmentMessage_queue *fmqueue;
+  struct MacEndpoint *endpoint;
+  struct Plugin *plugin;
+  uint16_t size;
 
   GNUNET_assert (cls != NULL);
-  GNUNET_assert (fm->frag == NULL);
-  struct MacEndpoint *endpoint = fm->session->mac;
-  struct Plugin *plugin = endpoint->plugin;
-  struct GNUNET_MessageHeader *msgheader;
-  struct GNUNET_MessageHeader *msgheader2;
-  uint16_t size;
+  endpoint = fm->session->mac;
+  plugin = endpoint->plugin;
 
-#if DEBUG_wlan_retransmission > 1
-  GNUNET_loHELLO_BEACON_SCALING_FACTORg_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
+  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                    "Adding fragment of message %p to send, session %p, endpoint %p, type %u\n",
                    fm, fm->session, endpoint, hdr->type);
-#endif
-
-  size =
-      sizeof (struct GNUNET_MessageHeader) + sizeof (struct Radiotap_Send) +
-      sizeof (struct ieee80211_frame) + ntohs (hdr->size);
-  fm->frag = GNUNET_malloc (size);
-  fm->size = size;
-
-  msgheader = (struct GNUNET_MessageHeader *) fm->frag;
-  msgheader->size = htons (size);
-  msgheader->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
-
-  fm->radioHeader = (struct Radiotap_Send *) &msgheader[1];
-  fm->ieeewlanheader = (struct ieee80211_frame *) &fm->radioHeader[1];
-  msgheader2 = (struct GNUNET_MessageHeader *) &fm->ieeewlanheader[1];
-  memcpy (msgheader2, hdr, ntohs (hdr->size));
-
+  size = sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) + ntohs (hdr->size);
+  fm->radioHeader = GNUNET_malloc (size);
+  getRadiotapHeader (plugin, fm->session->mac, fm->radioHeader, size);
+  getWlanHeader (&fm->radioHeader->frame, &(fm->session->mac->addr), plugin,
+                size);
+  memcpy (&fm->radioHeader[1], hdr, ntohs (hdr->size));
+  // FIXME: yucky allocation structure!
   fmqueue = GNUNET_malloc (sizeof (struct FragmentMessage_queue));
   fmqueue->content = fm;
-
   GNUNET_CONTAINER_DLL_insert_tail (plugin->sending_messages_head,
                                     plugin->sending_messages_tail, fmqueue);
   set_next_send (plugin);
 }
 
+
 /**
- * function to send a hello beacon
- * @param plugin pointer to the plugin struct
+ * We have been notified that gnunet-helper-transport-wlan has written something to stdout.
+ * Handle the output, then reschedule this function to be called again once
+ * more is available.
+ *
+ * @param cls the plugin handle
+ * @param tc the scheduling context
  */
 static void
-send_hello_beacon (struct Plugin *plugin)
+wlan_plugin_helper_read (void *cls,
+                         const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
+  struct Plugin *plugin = cls;
 
-#if DEBUG_wlan
-  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
-                   "Sending hello beacon\n");
-#endif
-
-  uint16_t size;
-  ssize_t bytes;
-  uint16_t hello_size;
-  struct GNUNET_MessageHeader *msgheader;
-  struct ieee80211_frame *ieeewlanheader;
-  struct Radiotap_Send *radioHeader;
-  struct GNUNET_MessageHeader *msgheader2;
-  const struct GNUNET_MessageHeader *hello;
-
-  GNUNET_assert (plugin != NULL);
-
-  GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan hello beacons send"), 1, GNUNET_NO);
-
-  hello = plugin->env->get_our_hello ();
-  hello_size = GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) hello);
-  GNUNET_assert (sizeof (struct WlanHeader) + hello_size <= WLAN_MTU);
-  size =
-      sizeof (struct GNUNET_MessageHeader) + sizeof (struct Radiotap_Send) +
-      sizeof (struct ieee80211_frame) + hello_size;
-
-  msgheader = GNUNET_malloc (size);
-  msgheader->size = htons (size);
-  msgheader->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
-
-  radioHeader = (struct Radiotap_Send *) &msgheader[1];
-  getRadiotapHeader (plugin, NULL, radioHeader);
-  ieeewlanheader = (struct ieee80211_frame *) &radioHeader[1];
-  getWlanHeader (ieeewlanheader, &bc_all_mac, plugin, size);
-
-  msgheader2 = (struct GNUNET_MessageHeader *) &ieeewlanheader[1];
-  /*msgheader2->size =
-      htons (GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) hello) +
-             sizeof (struct GNUNET_MessageHeader));
+  plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK;
 
-  msgheader2->type = htons (GNUNET_MESSAGE_TYPE_WLAN_ADVERTISEMENT);*/
-  memcpy (msgheader2, hello, hello_size);
+  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
+    return;
 
-  bytes = GNUNET_DISK_file_write (plugin->server_stdin_handle, msgheader, size);
+  char mybuf[WLAN_MTU + sizeof (struct GNUNET_MessageHeader)];
+  ssize_t bytes;
 
-  if (bytes == GNUNET_SYSERR)
+  bytes =
+      GNUNET_DISK_file_read (plugin->server_stdout_handle, mybuf,
+                             sizeof (mybuf));
+  if (bytes <= 0)
   {
-    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
+    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                      _
-                     ("Error writing to wlan healper. errno == %d, ERROR: %s\n"),
-                     errno, strerror (errno));
-
+                     ("Finished reading from gnunet-helper-transport-wlan stdout with code: %d\n"),
+                     bytes);
+    return;
   }
-  GNUNET_assert (bytes != GNUNET_SYSERR);
-  GNUNET_assert (bytes == size);
-  GNUNET_free (msgheader);
+  GNUNET_SERVER_mst_receive (plugin->suid_tokenizer, NULL, mybuf, bytes,
+                             GNUNET_NO, GNUNET_NO);
 
-  set_next_beacon_time (plugin);
-  set_next_send (plugin);
+  GNUNET_assert (plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK);
+  plugin->server_read_task =
+      GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
+                                      plugin->server_stdout_handle,
+                                      &wlan_plugin_helper_read, plugin);
+}
+
+/**
+ * Start the gnunet-helper-transport-wlan process.
+ *
+ * @param plugin the transport plugin
+ * @return GNUNET_YES if process was started, GNUNET_SYSERR on error
+ */
+static int
+wlan_transport_start_wlan_helper (struct Plugin *plugin)
+{
+  const char *filenamehw = "gnunet-helper-transport-wlan";
+  const char *filenameloopback = "gnunet-helper-transport-wlan-dummy";
+  char *absolute_filename = NULL;
+
+  if (plugin->helper_is_running == GNUNET_YES)
+  {
+    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
+                     "wlan_transport_start_wlan_helper not needed, helper already running!");
+    return GNUNET_YES;
+  }
+
+  plugin->server_stdout = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO, GNUNET_YES);
+  if (plugin->server_stdout == NULL)
+    return GNUNET_SYSERR;
+
+  plugin->server_stdin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_YES, GNUNET_NO);
+  if (plugin->server_stdin == NULL)
+    return GNUNET_SYSERR;
+
+  if ((plugin->testmode == 1) || (plugin->testmode == 2))
+  {
+    if (GNUNET_OS_check_helper_binary (filenameloopback) == GNUNET_YES)
+    {
+      absolute_filename = GNUNET_strdup (filenameloopback);
+    }
+    else
+    {
+      char cwd[FILENAME_MAX];
+
+      GNUNET_assert (getcwd (cwd, sizeof (cwd)) != NULL);
+
+      GNUNET_asprintf (&absolute_filename, "%s%s%s", cwd, DIR_SEPARATOR_STR,
+                       filenameloopback);
+
+      if (GNUNET_DISK_file_test (filenameloopback) != GNUNET_YES)
+      {
+        GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
+                         "Helper `%s' not found! %i\n", absolute_filename);
+        GNUNET_break (0);
+      }
+    }
+  }
+
+  /* Start the server process */
+
+  if (plugin->testmode == 0)
+  {
+
+    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
+                     "Starting gnunet-helper-transport-wlan process cmd: %s %s %i\n",
+                     filenamehw, plugin->interface, plugin->testmode);
+    if (GNUNET_OS_check_helper_binary (filenamehw) == GNUNET_YES)
+    {
+      plugin->server_proc =
+         GNUNET_OS_start_process (GNUNET_NO, plugin->server_stdin, plugin->server_stdout,
+                                   filenamehw, filenamehw, plugin->interface,
+                                   NULL);
+    }
+    else if (GNUNET_OS_check_helper_binary (filenamehw) == GNUNET_NO)
+    {
+      GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
+                       "gnunet-helper-transport-wlan is not suid, please change it or look at the doku\n");
+      GNUNET_break (0);
+    }
+    else
+    {
+      GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
+                       "gnunet-helper-transport-wlan not found, please look if it exists and is the $PATH variable!\n");
+      GNUNET_break (0);
+    }
+
+  }
+  else if (plugin->testmode == 1)
+  {
+
+    GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, PLUGIN_LOG_NAME,
+                     "Starting gnunet-helper-transport-wlan-dummy loopback 1 process cmd: %s %s %i\n",
+                     absolute_filename, plugin->interface, plugin->testmode);
+    plugin->server_proc =
+        GNUNET_OS_start_process (GNUNET_NO, plugin->server_stdin, plugin->server_stdout,
+                                 absolute_filename, absolute_filename, "1",
+                                 NULL);
+    if (plugin->server_proc == NULL)
+    {
+      GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
+                       "`%s' not found, please look if it exists and is in the $PATH variable!\n",
+                       absolute_filename);
+      GNUNET_break (0);
+    }
+  }
+  else if (plugin->testmode == 2)
+  {
+    GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, PLUGIN_LOG_NAME,
+                     "Starting gnunet-helper-transport-wlan-dummy loopback 2 process cmd: %s %s %i\n",
+                     absolute_filename, plugin->interface, plugin->testmode);
+    plugin->server_proc =
+        GNUNET_OS_start_process (GNUNET_NO, plugin->server_stdin, plugin->server_stdout,
+                                 absolute_filename, absolute_filename, "2",
+                                 NULL);
+    if (plugin->server_proc == NULL)
+    {
+      GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
+                       "`%s' not found, please look if it exists and is in the $PATH variable!\n",
+                       absolute_filename);
+      GNUNET_break (0);
+    }
+  }
+  if (absolute_filename != NULL)
+    GNUNET_free (absolute_filename);
+  if (plugin->server_proc == NULL)
+  {
+    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
+                     "Failed to start gnunet-helper-transport-wlan process\n");
+    return GNUNET_SYSERR;
+  }
+
+
+
+  /* Close the write end of the read pipe */
+  GNUNET_DISK_pipe_close_end (plugin->server_stdout,
+                              GNUNET_DISK_PIPE_END_WRITE);
+
+  /* Close the read end of the write pipe */
+  GNUNET_DISK_pipe_close_end (plugin->server_stdin, GNUNET_DISK_PIPE_END_READ);
+
+  plugin->server_stdout_handle =
+      GNUNET_DISK_pipe_handle (plugin->server_stdout,
+                               GNUNET_DISK_PIPE_END_READ);
+  plugin->server_stdin_handle =
+      GNUNET_DISK_pipe_handle (plugin->server_stdin,
+                               GNUNET_DISK_PIPE_END_WRITE);
+
+  GNUNET_assert (plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK);
+
+  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
+                   "Adding server_read_task for the gnunet-helper-transport-wlan\n");
+  plugin->server_read_task =
+      GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
+                                      plugin->server_stdout_handle,
+                                      &wlan_plugin_helper_read, plugin);
+
+  plugin->helper_is_running = GNUNET_YES;
+  return GNUNET_YES;
+}
+
+/**
+ * Stops the gnunet-helper-transport-wlan process.
+ *
+ * @param plugin the transport plugin
+ * @return GNUNET_YES if process was started, GNUNET_SYSERR on error
+ */
+static int
+wlan_transport_stop_wlan_helper (struct Plugin *plugin)
+{
+  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
+                   "Stoping WLAN helper process\n");
+
+  if (plugin->helper_is_running == GNUNET_NO)
+  {
+    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
+                     "wlan_transport_stop_wlan_helper not needed, helper already stopped!");
+    return GNUNET_YES;
+  }
+
+  if (plugin->server_write_delay_task != GNUNET_SCHEDULER_NO_TASK)
+  {
+    GNUNET_SCHEDULER_cancel (plugin->server_write_delay_task);
+    plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK;
+  }
+
+  if (plugin->server_write_task != GNUNET_SCHEDULER_NO_TASK)
+  {
+    GNUNET_SCHEDULER_cancel (plugin->server_write_task);
+    plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
+  }
+
+  if (plugin->server_read_task != GNUNET_SCHEDULER_NO_TASK)
+  {
+    GNUNET_SCHEDULER_cancel (plugin->server_read_task);
+    plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK;
+  }
+
+  GNUNET_DISK_pipe_close (plugin->server_stdout);
+  GNUNET_DISK_pipe_close (plugin->server_stdin);
+  GNUNET_OS_process_kill (plugin->server_proc, SIGKILL);
+  GNUNET_OS_process_wait (plugin->server_proc);
+  GNUNET_OS_process_close (plugin->server_proc);
+
+  plugin->helper_is_running = GNUNET_NO;
+
+  return GNUNET_YES;
+}
+
+/**
+ * function for delayed restart of the helper process
+ * @param cls Finish_send struct if message should be finished
+ * @param tc TaskContext
+ */
+static void
+delay_restart_helper (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct Finish_send *finish = cls;
+  struct Plugin *plugin;
+
+  plugin = finish->plugin;
+
+  plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
+  if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
+  {
+    GNUNET_free_non_null (finish->msgstart);
+    GNUNET_free (finish);
+    return;
+  }
+
+  wlan_transport_start_wlan_helper (plugin);
+
+  if (finish->size != 0)
+  {
+    plugin->server_write_task =
+        GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
+                                         plugin->server_stdin_handle,
+                                         &finish_sending, finish);
+  }
+  else
+  {
+    set_next_send (plugin);
+    GNUNET_free_non_null (finish->msgstart);
+    GNUNET_free (finish);
+  }
+
+}
+
+/**
+ * Function to restart the helper
+ * @param plugin pointer to the global plugin struct
+ * @param finish pointer to the Finish_send struct to finish
+ */
+static void
+restart_helper (struct Plugin *plugin, struct Finish_send *finish)
+{
+  static struct GNUNET_TIME_Relative next_try = { 1000 };
+  GNUNET_assert (finish != NULL);
+
+  wlan_transport_stop_wlan_helper (plugin);
+  plugin->server_write_task =
+      GNUNET_SCHEDULER_add_delayed (next_try, &delay_restart_helper, finish);
+  GNUNET_TIME_relative_multiply (next_try, HELPER_RESTART_SCALING_FACTOR);
+
+}
+
+/**
+ * function to finish a sending if not all could have been writen befor
+ * @param cls pointer to the Finish_send struct
+ * @param tc TaskContext
+ */
+static void
+finish_sending (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
+{
+  struct Finish_send *finish = cls;
+  struct Plugin *plugin;
+  ssize_t bytes;
+
+  plugin = finish->plugin;
+  plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
+
+  if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
+  {
+    GNUNET_free (finish->msgstart);
+    GNUNET_free (finish);
+    return;
+  }
+  bytes =
+      GNUNET_DISK_file_write (plugin->server_stdin_handle,
+                              finish->head_of_next_write, finish->size);
+
+  if (bytes != finish->size)
+  {
+    if (bytes != GNUNET_SYSERR)
+    {
+      finish->head_of_next_write += bytes;
+      finish->size -= bytes;
+      plugin->server_write_task =
+          GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
+                                           plugin->server_stdin_handle,
+                                           &finish_sending, finish);
+    }
+    else
+    {
+      restart_helper (plugin, finish);
+    }
+  }
+  else
+  {
+    GNUNET_free (finish->msgstart);
+    GNUNET_free (finish);
+    set_next_send (plugin);
+  }
 }
 
+
+/**
+ * function to send a hello beacon
+ * @param plugin pointer to the plugin struct
+ */
+static void
+send_hello_beacon (struct Plugin *plugin)
+{
+  uint16_t size;
+  ssize_t bytes;
+  uint16_t hello_size;
+  struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *radioHeader;
+  const struct GNUNET_MessageHeader *hello;
+  struct Finish_send *finish;
+
+  GNUNET_assert (plugin != NULL);
+  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
+                   "Sending hello beacon\n");
+  GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan hello beacons send"),
+                            1, GNUNET_NO);
+  hello = plugin->env->get_our_hello ();
+  hello_size = GNUNET_HELLO_size ((struct GNUNET_HELLO_Message *) hello);
+  GNUNET_assert (sizeof (struct WlanHeader) + hello_size <= WLAN_MTU);
+
+  size = sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) + hello_size;
+  radioHeader = GNUNET_malloc (size);
+  getRadiotapHeader (plugin, NULL, radioHeader, size);
+  getWlanHeader (&radioHeader->frame, &bc_all_mac, plugin, size);
+  memcpy (&radioHeader[1], hello, hello_size);
+  bytes = GNUNET_DISK_file_write (plugin->server_stdin_handle, radioHeader, size);
+  GNUNET_free (radioHeader);
+  if (bytes == GNUNET_SYSERR)
+  {
+    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
+                     _
+                     ("Error writing to wlan helper. errno == %d, ERROR: %s\n"),
+                     errno, strerror (errno));
+    finish = GNUNET_malloc (sizeof (struct Finish_send));
+    finish->plugin = plugin;
+    finish->head_of_next_write = NULL;
+    finish->size = 0;
+    finish->msgstart = NULL;
+    restart_helper (plugin, finish);
+    set_next_beacon_time (plugin);
+  }
+  else
+  {
+    GNUNET_assert (bytes == size);
+    set_next_beacon_time (plugin);
+    set_next_send (plugin);
+  }
+}
+
+
 /**
  * function to add an ack to send it for a received fragment
+ *
  * @param cls MacEndpoint this ack belongs to
  * @param msg_id id of the message
  * @param hdr pointer to the hdr where the ack is stored
- *
  */
-
 static void
 add_ack_for_send (void *cls, uint32_t msg_id,
                   const struct GNUNET_MessageHeader *hdr)
 {
-
-  struct AckSendQueue *ack;
-
-  GNUNET_assert (cls != NULL);
   struct MacEndpoint *endpoint = cls;
   struct Plugin *plugin = endpoint->plugin;
+  struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage* radioHeader;
+  struct AckSendQueue *ack;
   struct GNUNET_MessageHeader *msgheader;
-  struct GNUNET_MessageHeader *msgheader2;
   uint16_t size;
 
-  size =
-      sizeof (struct GNUNET_MessageHeader) + sizeof (struct Radiotap_Send) +
-      sizeof (struct ieee80211_frame) + ntohs (hdr->size) +
-      sizeof (struct AckSendQueue);
-
+  GNUNET_assert (endpoint != NULL);
+  size = sizeof (struct AckSendQueue) + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) + ntohs (hdr->size);
   ack = GNUNET_malloc (size);
   ack->message_id = msg_id;
   ack->endpoint = endpoint;
-
-  size =
-      sizeof (struct GNUNET_MessageHeader) + sizeof (struct Radiotap_Send) +
-      sizeof (struct ieee80211_frame) + ntohs (hdr->size);
-
-  msgheader = (struct GNUNET_MessageHeader *) &ack[1];
-  ack->hdr = (struct GNUNET_MessageHeader *) &ack[1];
-  msgheader->size = htons (size);
-  msgheader->type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA);
-
-  ack->radioHeader = (struct Radiotap_Send *) &msgheader[1];
-  ack->ieeewlanheader = (struct ieee80211_frame *) &(ack->radioHeader)[1];
-  msgheader2 = (struct GNUNET_MessageHeader *) &(ack->ieeewlanheader)[1];
-  memcpy (msgheader2, hdr, ntohs (hdr->size));
-
+  radioHeader = (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage*) &ack[1];
+  ack->radioHeader = radioHeader;
+  getRadiotapHeader (plugin, ack->endpoint, radioHeader, size - sizeof (struct AckSendQueue));
+  size = ntohs (hdr->size);
+  getWlanHeader (&radioHeader->frame, 
+                &ack->endpoint->addr, 
+                plugin,
+                 size);
+  msgheader = (struct GNUNET_MessageHeader *) &radioHeader[1];
+  memcpy (msgheader, hdr, size);
   GNUNET_CONTAINER_DLL_insert_tail (plugin->ack_send_queue_head,
                                     plugin->ack_send_queue_tail, ack);
-
-#if DEBUG_wlan_retransmission > 1
   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                    "Adding ack with message id %u to send, AckSendQueue %p, endpoint %p\n",
                    msg_id, ack, endpoint);
-#endif
-
   set_next_send (plugin);
 }
 
+
 /**
  * Function for the scheduler if a FragmentMessage times out
  * @param cls pointer to the FragmentMessage
@@ -1531,10 +1766,8 @@ fragmentmessage_timeout (void *cls,
 
   GNUNET_assert (fm != NULL);
   fm->timeout_task = GNUNET_SCHEDULER_NO_TASK;
-  if (tc->reason == GNUNET_SCHEDULER_REASON_SHUTDOWN)
-  {
-    return;
-  }
+  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))  
+    return;  
   free_fragment_message (fm->session->mac->plugin, fm);
 }
 
@@ -1565,11 +1798,12 @@ check_fragment_queue (struct Plugin *plugin)
       session->mac->fragment_messages_out_count++;
       session->fragment_messages_out_count++;
       plugin->pending_Fragment_Messages++;
+      GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending fragments"),
+                             plugin->pending_Fragment_Messages, GNUNET_NO);
 
       fm = GNUNET_malloc (sizeof (struct FragmentMessage));
       fm->session = session;
       fm->timeout.abs_value = pm->timeout.abs_value;
-      fm->frag = NULL;
       fm->fragcontext =
           GNUNET_FRAGMENT_context_create (plugin->env->stats, WLAN_MTU,
                                           &plugin->tracker,
@@ -1588,17 +1822,13 @@ check_fragment_queue (struct Plugin *plugin)
       {
         pid = session->target;
         pm->transmit_cont (pm->transmit_cont_cls, &pid, GNUNET_OK);
-#if DEBUG_wlan
         GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                          "called pm->transmit_cont for %p\n", session);
-#endif
       }
       else
       {
-#if DEBUG_wlan
         GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                          "no pm->transmit_cont for %p\n", session);
-#endif
       }
       GNUNET_free (pm);
 
@@ -1615,89 +1845,50 @@ check_fragment_queue (struct Plugin *plugin)
   set_next_send (plugin);
 }
 
+
 /**
  * Function to send an ack, does not free the ack
  * @param plugin pointer to the plugin
- * @param ack pointer to the ack to send
  */
 static void
-send_ack (struct Plugin *plugin, struct AckSendQueue *ack)
+send_ack (struct Plugin *plugin)
 {
-
   ssize_t bytes;
+  struct AckSendQueue *ack;
+  struct Finish_send *finish;
 
-#if DEBUG_wlan
+  GNUNET_assert (plugin != NULL);
+  ack = plugin->ack_send_queue_head;
   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                    "Sending ack for message_id %u for mac endpoint %p, size %u\n",
                    ack->message_id, ack->endpoint,
-                   ntohs (ack->hdr->size) - sizeof (struct Radiotap_Send));
-#endif
-
-  GNUNET_assert (plugin != NULL);
-  GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan acks send"), 1, GNUNET_NO);
-
-  getRadiotapHeader (plugin, ack->endpoint, ack->radioHeader);
-  getWlanHeader (ack->ieeewlanheader, &ack->endpoint->addr, plugin,
-                 ntohs (ack->hdr->size));
-
+                   ntohs (ack->radioHeader->header.size));
+  GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan acks send"), 1,
+                            GNUNET_NO);
   bytes =
-      GNUNET_DISK_file_write (plugin->server_stdin_handle, ack->hdr,
-                              ntohs (ack->hdr->size));
+      GNUNET_DISK_file_write (plugin->server_stdin_handle, ack->radioHeader,
+                              ntohs (ack->radioHeader->header.size));
   if (bytes == GNUNET_SYSERR)
   {
     GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
                      _
-                     ("Error writing to wlan healper. errno == %d, ERROR: %s\n"),
+                     ("Error writing to wlan helper. errno == %d, ERROR: %s\n"),
                      errno, strerror (errno));
-
+    finish = GNUNET_malloc (sizeof (struct Finish_send));
+    finish->plugin = plugin;
+    finish->head_of_next_write = NULL;
+    finish->size = 0;
+    finish->msgstart = NULL;
+    restart_helper (plugin, finish);
+    return;
   }
-  GNUNET_assert (bytes != GNUNET_SYSERR);
-  GNUNET_assert (bytes == ntohs (ack->hdr->size));
+  GNUNET_assert (bytes == ntohs (ack->radioHeader->header.size));
+  GNUNET_CONTAINER_DLL_remove (plugin->ack_send_queue_head,
+                              plugin->ack_send_queue_tail, ack);
+  GNUNET_free (ack);
   set_next_send (plugin);
 }
 
-/**
- * function to finish a sending if not all could have been writen befor
- * @param cls pointer to the Finish_send struct
- * @param tc TaskContext
- */
-static void
-finish_sending (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
-  struct Finish_send *finish = cls;
-  struct Plugin *plugin;
-  ssize_t bytes;
-
-  plugin = finish->plugin;
-  plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
-
-  if (0 != (GNUNET_SCHEDULER_REASON_SHUTDOWN & tc->reason))
-  {
-    GNUNET_free (finish->msgstart);
-    GNUNET_free (finish);
-    return;
-  }
-  bytes =
-      GNUNET_DISK_file_write (plugin->server_stdin_handle, finish->msgheader,
-                              finish->size);
-  GNUNET_assert (bytes != GNUNET_SYSERR);
-
-  if (bytes != finish->size)
-  {
-    finish->msgheader = finish->msgheader + bytes;
-    finish->size = finish->size - bytes;
-    plugin->server_write_task =
-        GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
-                                         plugin->server_stdin_handle,
-                                         &finish_sending, finish);
-  }
-  else
-  {
-    GNUNET_free (finish->msgstart);
-    GNUNET_free (finish);
-    set_next_send (plugin);
-  }
-}
 
 /**
  * Function called when wlan helper is ready to get some data
@@ -1709,107 +1900,87 @@ static void
 do_transmit (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
 {
   struct Plugin *plugin = cls;
-  GNUNET_assert (plugin != NULL);
-
-  plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
-  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
-    return;
-
   struct Session *session;
   struct FragmentMessage *fm;
   struct Finish_send *finish;
   struct FragmentMessage_queue *fmq;
-  struct AckSendQueue *ack;
   ssize_t bytes;
 
+  GNUNET_assert (plugin != NULL);
+  plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
+  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
+    return;
   if (plugin->ack_send_queue_head != NULL)
   {
-    ack = plugin->ack_send_queue_head;
-    GNUNET_CONTAINER_DLL_remove (plugin->ack_send_queue_head,
-                                 plugin->ack_send_queue_tail, ack);
-    send_ack (plugin, ack);
-    GNUNET_free (ack);
+    send_ack (plugin);
     return;
   }
-
   //test if a "hello-beacon" has to be send
   if (GNUNET_TIME_absolute_get_remaining (plugin->beacon_time).rel_value == 0)
   {
     send_hello_beacon (plugin);
     return;
   }
-
-  if (plugin->sending_messages_head != NULL)
+  if (NULL == plugin->sending_messages_head)
   {
-    GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan fragments send"), 1, GNUNET_NO);
-
-    fmq = plugin->sending_messages_head;
-    fm = fmq->content;
-    GNUNET_CONTAINER_DLL_remove (plugin->sending_messages_head,
-                                 plugin->sending_messages_tail, fmq);
-    GNUNET_free (fmq);
-
-    session = fm->session;
-    GNUNET_assert (session != NULL);
-
-#if DEBUG_wlan
-    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
-                     "Sending GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT for fragment message %p, size: %u\n",
-                     fm, fm->size);
-#endif
-
-    getRadiotapHeader (plugin, session->mac, fm->radioHeader);
-    getWlanHeader (fm->ieeewlanheader, &(fm->session->mac->addr), plugin,
-                   fm->size);
-
-    bytes =
-        GNUNET_DISK_file_write (plugin->server_stdin_handle, fm->frag,
-                                fm->size);
+    /* nothing to do right now, check when to go again */  
+    set_next_send (plugin);
+    return;
+  }
+  GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan fragments send"), 1,
+                           GNUNET_NO);
+  
+  fmq = plugin->sending_messages_head;
+  fm = fmq->content;
+  GNUNET_CONTAINER_DLL_remove (plugin->sending_messages_head,
+                              plugin->sending_messages_tail, fmq);
+  GNUNET_free (fmq);
+  
+  session = fm->session;
+  GNUNET_assert (session != NULL);
+  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
+                  "Sending GNUNET_MESSAGE_TYPE_WLAN_FRAGMENT for fragment message %p, size: %u\n",
+                  fm, ntohs (fm->radioHeader->header.size));
+  bytes =
+    GNUNET_DISK_file_write (plugin->server_stdin_handle, 
+                           fm->radioHeader,
+                           ntohs (fm->radioHeader->header.size));
+  if (bytes != ntohs (fm->radioHeader->header.size))
+  {
+    finish = GNUNET_malloc (sizeof (struct Finish_send));
+    finish->plugin = plugin;
+    finish->msgstart = &fm->radioHeader->header;
+    GNUNET_assert (plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK);
     if (bytes == GNUNET_SYSERR)
     {
       GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
-                       _
-                       ("Error writing to wlan healper. errno == %d, ERROR: %s\n"),
-                       errno, strerror (errno));
-      //TODO START NEW WLAN HELPER
-      /*
-       * alle sessions beenden
-       * neu starten (alle 5 sec)
-       * alles bis dahin ablehnen
-       */
-    }
-    //GNUNET_assert (bytes != GNUNET_SYSERR);
-
-    if (bytes != fm->size)
-    {
-      finish = GNUNET_malloc (sizeof (struct Finish_send));
-      finish->plugin = plugin;
-      finish->msgheader = fm->frag + bytes;
-      finish->size = fm->size - bytes;
-      finish->msgstart = (struct GNUNET_MessageHeader *) fm->frag;
-
-      GNUNET_assert (plugin->server_write_task == GNUNET_SCHEDULER_NO_TASK);
-
-      plugin->server_write_task =
-          GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
-                                           plugin->server_stdin_handle,
-                                           &finish_sending, finish);
-      fm->frag = NULL;
+                      _
+                      ("Error writing to wlan helper. errno == %d, ERROR: %s\n"),
+                      errno, strerror (errno));     
+      finish->head_of_next_write = (char*) fm->radioHeader;
+      finish->size = ntohs (fm->radioHeader->header.size);
+      restart_helper (plugin, finish);
     }
     else
     {
-      GNUNET_free (fm->frag);
-      fm->frag = NULL;
-      set_next_send (plugin);
-    }
-    GNUNET_FRAGMENT_context_transmission_done (fm->fragcontext);
-    return;
+      finish->head_of_next_write = ((char*) fm->radioHeader) + bytes;
+      finish->size = ntohs (fm->radioHeader->header.size) - bytes;
+      plugin->server_write_task =
+       GNUNET_SCHEDULER_add_write_file (GNUNET_TIME_UNIT_FOREVER_REL,
+                                        plugin->server_stdin_handle,
+                                        &finish_sending, finish);
+    }    
   }
-
-  GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, PLUGIN_LOG_NAME,
-                   "do_transmit did nothing, should not happen!\n");
+  else
+  {
+    GNUNET_free (fm->radioHeader);
+    fm->radioHeader = NULL;
+    set_next_send (plugin);
+  }
+  GNUNET_FRAGMENT_context_transmission_done (fm->fragcontext);
 }
 
+
 /**
  * Another peer has suggested an address for this
  * peer and transport plugin.  Check that this could be a valid
@@ -1836,76 +2007,96 @@ wlan_plugin_address_suggested (void *cls, const void *addr, size_t addrlen)
   if (addrlen == 6)
   {
     /* TODO check for bad addresses like multicast, broadcast, etc */
-#if DEBUG_wlan
     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
-                         "wlan_plugin_address_suggested got good address, size %u!\n", addrlen);
-#endif
+                     "wlan_plugin_address_suggested got good address, size %u!\n",
+                     addrlen);
     return GNUNET_OK;
   }
-#if DEBUG_wlan
-    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
-                         "wlan_plugin_address_suggested got bad address, size %u!\n", addrlen);
-#endif
+  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
+                   "wlan_plugin_address_suggested got bad address, size %u!\n",
+                   addrlen);
   return GNUNET_SYSERR;
 }
 
+
+/**
+ * Creates a new outbound session the transport service will use to send data to the
+ * peer
+ *
+ * @param cls the plugin
+ * @param address the address
+ * @return the session or NULL of max connections exceeded
+ */
+
+static struct Session *
+wlan_plugin_get_session (void *cls,
+                  const struct GNUNET_HELLO_Address *address)
+{
+  struct Plugin *plugin = cls;
+  struct Session * s = NULL;
+
+  GNUNET_assert (plugin != NULL);
+  GNUNET_assert (address != NULL);
+
+  if (GNUNET_OK == wlan_plugin_address_suggested (plugin,
+            address->address,
+            address->address_length))
+  {
+    s = get_session (plugin, address->address, &address->peer);
+  }
+  else
+  {
+    GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
+                     _("Wlan Address len %d is wrong\n"), address->address_length);
+    return s;
+  }
+
+  return s;
+}
+
 /**
  * Function that can be used by the transport service to transmit
- * a message using the plugin.
+ * a message using the plugin.   Note that in the case of a
+ * peer disconnecting, the continuation MUST be called
+ * prior to the disconnect notification itself.  This function
+ * will be called with this peer's HELLO message to initiate
+ * a fresh connection to another peer.
  *
  * @param cls closure
- * @param target who should receive this message
- * @param priority how important is the message
+ * @param session which session must be used
  * @param msgbuf the message to transmit
  * @param msgbuf_size number of bytes in 'msgbuf'
- * @param timeout when should we time out
- * @param session which session must be used (or NULL for "any")
- * @param addr the address to use (can be NULL if the plugin
- *                is "on its own" (i.e. re-use existing TCP connection))
- * @param addrlen length of the address in bytes
- * @param force_address GNUNET_YES if the plugin MUST use the given address,
- *                otherwise the plugin may use other addresses or
- *                existing connections (if available)
+ * @param priority how important is the message (most plugins will
+ *                 ignore message priority and just FIFO)
+ * @param to how long to wait at most for the transmission (does not
+ *                require plugins to discard the message after the timeout,
+ *                just advisory for the desired delay; most plugins will ignore
+ *                this as well)
  * @param cont continuation to call once the message has
  *        been transmitted (or if the transport is ready
  *        for the next transmission call; or if the
- *        peer disconnected...)
+ *        peer disconnected...); can be NULL
  * @param cont_cls closure for cont
  * @return number of bytes used (on the physical network, with overheads);
  *         -1 on hard errors (i.e. address invalid); 0 is a legal value
  *         and does NOT mean that the message was not transmitted (DV)
  */
 static ssize_t
-wlan_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target,
-                  const char *msgbuf, size_t msgbuf_size, unsigned int priority,
-                  struct GNUNET_TIME_Relative timeout, struct Session *session,
-                  const void *addr, size_t addrlen, int force_address,
+wlan_plugin_send (void *cls,
+                  struct Session *session,
+                  const char *msgbuf, size_t msgbuf_size,
+                  unsigned int priority,
+                  struct GNUNET_TIME_Relative to,
                   GNUNET_TRANSPORT_TransmitContinuation cont, void *cont_cls)
 {
   struct Plugin *plugin = cls;
   struct PendingMessage *newmsg;
   struct WlanHeader *wlanheader;
+
   GNUNET_assert (plugin != NULL);
-  //check if msglen > 0
+  GNUNET_assert (session != NULL);
   GNUNET_assert (msgbuf_size > 0);
 
-  //get session if needed
-  if (session == NULL)
-  {
-    if (wlan_plugin_address_suggested (plugin, addr, addrlen) == GNUNET_OK)
-    {
-      session = get_session (plugin, addr, target);
-    }
-    else
-    {
-      GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
-                       _("Wlan Address len %d is wrong\n"), addrlen);
-      return -1;
-    }
-  }
-
-  GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan messages queued"), 1, GNUNET_NO);
-
   //queue message:
 
   //queue message in session
@@ -1927,20 +2118,18 @@ wlan_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target,
   //copy msg to buffer, not fragmented / segmented yet, but with message header
   wlanheader->header.size = htons (msgbuf_size + sizeof (struct WlanHeader));
   wlanheader->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA);
-  memcpy (&(wlanheader->target), target, sizeof (struct GNUNET_PeerIdentity));
+  memcpy (&(wlanheader->target), &session->target, sizeof (struct GNUNET_PeerIdentity));
   memcpy (&(wlanheader->source), plugin->env->my_identity,
           sizeof (struct GNUNET_PeerIdentity));
   wlanheader->crc = 0;
   memcpy (&wlanheader[1], msgbuf, msgbuf_size);
   wlanheader->crc =
-      htonl (getcrc32
+      htonl (GNUNET_CRYPTO_crc32_n
              ((char *) wlanheader, msgbuf_size + sizeof (struct WlanHeader)));
-  //GNUNET_log_from(GNUNET_ERROR_TYPE_INFO, PLUGIN_LOG_NAME,  "Wlan message Header crc: %u, %u\n",getcrc32((char*) wlanheader, msgbuf_size + sizeof(struct WlanHeader)), wlanheader->crc);
-  //hexdump(newmsg->msg, msgbuf_size + sizeof(struct WlanHeader));
 
   newmsg->transmit_cont = cont;
   newmsg->transmit_cont_cls = cont_cls;
-  newmsg->timeout = GNUNET_TIME_relative_to_absolute (timeout);
+  newmsg->timeout = GNUNET_TIME_relative_to_absolute (to);
 
   newmsg->timeout.abs_value = newmsg->timeout.abs_value - 500;
 
@@ -1949,12 +2138,10 @@ wlan_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target,
   GNUNET_CONTAINER_DLL_insert_tail (session->pending_message_head,
                                     session->pending_message_tail, newmsg);
 
-#if DEBUG_wlan
   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                    "New message for %p with size (incl wlan header) %u added\n",
                    session, newmsg->message_size);
-#endif
-#if DEBUG_wlan_msg_dump > 1
+#if DEBUG_WLAN > 1
   hexdump (msgbuf, GNUNET_MIN (msgbuf_size, 256));
 #endif
   //queue session
@@ -1963,9 +2150,9 @@ wlan_plugin_send (void *cls, const struct GNUNET_PeerIdentity *target,
   check_fragment_queue (plugin);
   //FIXME not the correct size
   return msgbuf_size;
-
 }
 
+
 /**
  * function to free a mac endpoint
  * @param plugin pointer to the plugin struct
@@ -1989,7 +2176,13 @@ free_macendpoint (struct Plugin *plugin, struct MacEndpoint *endpoint)
 
   GNUNET_CONTAINER_DLL_remove (plugin->mac_head, plugin->mac_tail, endpoint);
   if (endpoint->timeout_task != GNUNET_SCHEDULER_NO_TASK)
+  {
     GNUNET_SCHEDULER_cancel (endpoint->timeout_task);
+    endpoint->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+  }
+  plugin->mac_count--;
+  GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan mac endpoints"),
+                         plugin->mac_count, GNUNET_NO);
   GNUNET_free (endpoint);
 
 }
@@ -1998,7 +2191,7 @@ free_macendpoint (struct Plugin *plugin, struct MacEndpoint *endpoint)
  * function to free a session
  * @param plugin pointer to the plugin
  * @param queue pointer to the sessionqueue element to free
- * @param free_macendpoint if GNUNET_YES and mac endpoint would be empty, free mac endpoint
+ * @param do_free_macendpoint if GNUNET_YES and mac endpoint would be empty, free mac endpoint
  */
 static void
 free_session (struct Plugin *plugin, struct Sessionqueue *queue,
@@ -2027,7 +2220,8 @@ free_session (struct Plugin *plugin, struct Sessionqueue *queue,
     if (pendingsession_tmp->content == queue->content)
     {
       plugin->pendingsessions--;
-      GNUNET_STATISTICS_set(plugin->env->stats, _("# wlan pending sessions"), plugin->pendingsessions, GNUNET_NO);
+      GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"),
+                             plugin->pendingsessions, GNUNET_NO);
       GNUNET_CONTAINER_DLL_remove (plugin->pending_Sessions_head,
                                    plugin->pending_Sessions_tail,
                                    pendingsession_tmp);
@@ -2043,10 +2237,8 @@ free_session (struct Plugin *plugin, struct Sessionqueue *queue,
   while (fm != NULL)
   {
     fmnext = fm->next;
-    if (fm->session == queue->content)
-    {
-      free_fragment_message (plugin, fm);
-    }
+    if (fm->session == queue->content)    
+      free_fragment_message (plugin, fm);    
     fm = fmnext;
   }
 
@@ -2064,16 +2256,21 @@ free_session (struct Plugin *plugin, struct Sessionqueue *queue,
   GNUNET_CONTAINER_DLL_remove (endpoint->sessions_head, endpoint->sessions_tail,
                                queue);
   //Check that no ohter session on this endpoint for this session exits
-  GNUNET_assert(search_session(plugin, endpoint, &queue->content->target) == NULL);
+  GNUNET_assert (search_session (plugin, endpoint, &queue->content->target) ==
+                 NULL);
   if (endpoint->sessions_head == NULL && do_free_macendpoint == GNUNET_YES)
   {
     free_macendpoint (plugin, endpoint);
     //check if no endpoint with the same address exists
-    GNUNET_assert(get_macendpoint(plugin, &endpoint->addr, GNUNET_NO) == NULL);
+    GNUNET_assert (get_macendpoint (plugin, &endpoint->addr, GNUNET_NO) ==
+                   NULL);
   }
 
   if (queue->content->timeout_task != GNUNET_SCHEDULER_NO_TASK)
+  {
     GNUNET_SCHEDULER_cancel (queue->content->timeout_task);
+    queue->content->timeout_task = GNUNET_SCHEDULER_NO_TASK;
+  }
   GNUNET_free (queue);
 
   check_fragment_queue (plugin);
@@ -2145,31 +2342,27 @@ wlan_plugin_address_pretty_printer (void *cls, const char *type,
   const unsigned char *input;
 
   //GNUNET_assert(cls !=NULL);
-  if (addrlen != sizeof(struct MacAddress))
+  if (addrlen != sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress))
   {
     /* invalid address (MAC addresses have 6 bytes) */
     //GNUNET_break (0);
-#if DEBUG_wlan
-      GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
-                   "Func wlan_plugin_address_pretty_printer got size: %u, worng size!\n",
-                   addrlen);
-#endif
-    asc(asc_cls, NULL);
+    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
+                     "Func wlan_plugin_address_pretty_printer got size: %u, worng size!\n",
+                     addrlen);
+    asc (asc_cls, NULL);
     return;
   }
   input = (const unsigned char *) addr;
   GNUNET_asprintf (&ret,
-                   "Transport %s: %s Mac-Address %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",type,
-                   PROTOCOL_PREFIX, input[0], input[1], input[2], input[3],
-                   input[4], input[5]);
-#if DEBUG_wlan
+                   "Transport %s: %s Mac-Address %.2X:%.2X:%.2X:%.2X:%.2X:%.2X",
+                   type, PROTOCOL_PREFIX, input[0], input[1], input[2],
+                   input[3], input[4], input[5]);
   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                    "Func wlan_plugin_address_pretty_printer got size: %u, nummeric %u, type %s; made string: %s\n",
                    addrlen, numeric, type, ret);
-#endif
-  asc ( asc_cls, ret);
+  asc (asc_cls, ret);
   //only one mac address per plugin
-  asc ( asc_cls, NULL);
+  asc (asc_cls, NULL);
 }
 
 
@@ -2196,11 +2389,9 @@ wlan_data_message_handler (void *cls, const struct GNUNET_MessageHeader *hdr)
   if (ntohs (hdr->type) == GNUNET_MESSAGE_TYPE_WLAN_DATA)
   {
 
-#if DEBUG_wlan
     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                      "Func wlan_data_message_handler got GNUNET_MESSAGE_TYPE_WLAN_DATA size: %u\n",
                      ntohs (hdr->size));
-#endif
 
     if (ntohs (hdr->size) <
         sizeof (struct WlanHeader) + sizeof (struct GNUNET_MessageHeader))
@@ -2209,7 +2400,9 @@ wlan_data_message_handler (void *cls, const struct GNUNET_MessageHeader *hdr)
       return;
     }
 
-    GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan whole messages received"), 1, GNUNET_NO);
+    GNUNET_STATISTICS_update (plugin->env->stats,
+                              _("# wlan whole messages received"), 1,
+                              GNUNET_NO);
     wlanheader = (struct WlanHeader *) hdr;
 
     session = search_session (plugin, endpoint, &wlanheader->source);
@@ -2217,13 +2410,15 @@ wlan_data_message_handler (void *cls, const struct GNUNET_MessageHeader *hdr)
     temp_hdr = (const struct GNUNET_MessageHeader *) &wlanheader[1];
     crc = ntohl (wlanheader->crc);
     wlanheader->crc = 0;
-    if (getcrc32 ((char *) wlanheader, ntohs (wlanheader->header.size)) != crc)
+    if (GNUNET_CRYPTO_crc32_n
+        ((char *) wlanheader, ntohs (wlanheader->header.size)) != crc)
     {
       //wrong crc, dispose message
       GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, PLUGIN_LOG_NAME,
                        "Wlan message header crc was wrong: %u != %u\n",
-                       getcrc32 ((char *) wlanheader,
-                                 ntohs (wlanheader->header.size)), crc);
+                       GNUNET_CRYPTO_crc32_n ((char *) wlanheader,
+                                              ntohs (wlanheader->header.size)),
+                       crc);
       hexdump ((void *) hdr, ntohs (hdr->size));
       return;
     }
@@ -2231,12 +2426,10 @@ wlan_data_message_handler (void *cls, const struct GNUNET_MessageHeader *hdr)
     //if not in session list
     if (session == NULL)
     {
-#if DEBUG_wlan
       GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                        "WLAN client not in session list: packet size = %u, inner size = %u, header size = %u\n",
                        ntohs (wlanheader->header.size), ntohs (temp_hdr->size),
                        sizeof (struct WlanHeader));
-#endif
       //try if it is a hello message
       if (ntohs (wlanheader->header.size) >=
           ntohs (temp_hdr->size) + sizeof (struct WlanHeader))
@@ -2281,11 +2474,9 @@ wlan_data_message_handler (void *cls, const struct GNUNET_MessageHeader *hdr)
          sizeof (struct GNUNET_PeerIdentity)) != 0)
     {
       //wrong peer id
-#if DEBUG_wlan
       GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                        "WLAN peer source id doesn't match packet peer source id: session %p\n",
                        session);
-#endif
       return;
     }
 
@@ -2294,11 +2485,9 @@ wlan_data_message_handler (void *cls, const struct GNUNET_MessageHeader *hdr)
          sizeof (struct GNUNET_PeerIdentity)) != 0)
     {
       //wrong peer id
-#if DEBUG_wlan
       GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                        "WLAN peer target id doesn't match our peer id: session %p\n",
                        session);
-#endif
       return;
     }
 
@@ -2333,25 +2522,22 @@ process_data (void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
   GNUNET_assert (cls != NULL);
   struct Session *session = (struct Session *) client;
   struct Plugin *plugin = (struct Plugin *) cls;
+  struct GNUNET_ATS_Information ats[2];
 
-  struct GNUNET_ATS_Information distance;
-
-  distance.type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
-  distance.value = htonl (1);
+  ats[0].type = htonl (GNUNET_ATS_QUALITY_NET_DISTANCE);
+  ats[0].value = htonl (1);
+  ats[1].type = htonl (GNUNET_ATS_NETWORK_TYPE);
+  ats[1].value = htonl (GNUNET_ATS_NET_WLAN);
 
-#if DEBUG_wlan
   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                    "Calling plugin->env->receive for session %p; %s; size: %u\n",
                    session, wlan_plugin_address_to_string (NULL,
                                                            session->mac->
                                                            addr.mac, 6),
                    htons (hdr->size));
-#endif
-
   plugin->env->receive (plugin->env->cls, &(session->target), hdr,
-                        (const struct GNUNET_ATS_Information *)
-                        &distance, 1, session,
-                        (const char *) &session->mac->addr,
+                        (const struct GNUNET_ATS_Information *) &ats, 2,
+                        session, (const char *) &session->mac->addr,
                         sizeof (session->mac->addr));
 }
 
@@ -2359,182 +2545,113 @@ process_data (void *cls, void *client, const struct GNUNET_MessageHeader *hdr)
  * Function used for to process the data received from the wlan interface
  *
  * @param cls the plugin handle
- * @param session_light pointer to the struct holding known informations
  * @param hdr hdr of the GNUNET_MessageHeader
- * @param rxinfo pointer to the radiotap informations got with this packet
+ * @param rxinfo pointer to the radiotap informations got with this packet FIXME: give ATS info
  */
 static void
-wlan_data_helper (void *cls, struct Session_light *session_light,
+wlan_data_helper (void *cls, 
                   const struct GNUNET_MessageHeader *hdr,
-                  const struct Radiotap_rx *rxinfo)
+                 const struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rxinfo)
 {
   struct Plugin *plugin = cls;
   struct FragmentMessage *fm;
   struct FragmentMessage *fm2;
   struct GNUNET_PeerIdentity tmpsource;
+  struct MacEndpoint *macendpoint;
+  struct Session *session;
 
-  GNUNET_assert(plugin != NULL);
+  // NOTE: session_light->addr = rxinfo->frame.addr2;
+  macendpoint = get_macendpoint (plugin, &rxinfo->frame.addr2, GNUNET_YES);
 
-  //ADVERTISEMENT
-  if (ntohs (hdr->type) == GNUNET_MESSAGE_TYPE_HELLO)
+  switch (ntohs (hdr->type))
   {
-
+  case GNUNET_MESSAGE_TYPE_HELLO:
+    //ADVERTISEMENT
     //TODO better DOS protection, error handling
-    //TODO test first than create session
-    GNUNET_assert (session_light != NULL);
-
-#if DEBUG_wlan
-    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
-                     "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_HELLO size: %u; %s\n",
-                     ntohs (hdr->size), wlan_plugin_address_to_string (NULL,
-                                                                       session_light->addr.
-                                                                       mac, 6));
-#endif
-
-    if (session_light->macendpoint == NULL)
-    {
-      session_light->macendpoint =
-          get_macendpoint (plugin, &session_light->addr, GNUNET_YES);
-    }
-
-
+    //TODO test first then create session
     if (GNUNET_HELLO_get_id
-        ((const struct GNUNET_HELLO_Message *) hdr,
-         &tmpsource) == GNUNET_OK)
-    {
-        session_light->session = search_session (plugin, session_light->macendpoint, &tmpsource);
-      if (session_light->session == NULL)
-        {
-          session_light->session = create_session (plugin, session_light->macendpoint, &tmpsource);
-        }
-      GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan hello messages received"), 1, GNUNET_NO);
-      plugin->env->receive(plugin->env->cls,&session_light->session->target,hdr, NULL, 0, session_light->session,
-          (const char *) &session_light->session->mac->addr,
-          sizeof (session_light->session->mac->addr));
+        ((const struct GNUNET_HELLO_Message *) hdr, &tmpsource) == GNUNET_OK)
+    {
+      session = search_session (plugin, macendpoint, &tmpsource);
+      if (session == NULL)
+      {
+        session = create_session (plugin, macendpoint, &tmpsource);
+      }
+      GNUNET_STATISTICS_update (plugin->env->stats,
+                                _("# wlan hello messages received"), 1,
+                                GNUNET_NO);
+      plugin->env->receive (plugin->env->cls, &session->target,
+                            hdr, NULL, 0, session,
+                            (const char *) &session->mac->addr,
+                            sizeof (session->mac->addr));
     }
     else
     {
       GNUNET_log_from (GNUNET_ERROR_TYPE_WARNING, PLUGIN_LOG_NAME,
-                       "WLAN client not in session list and hello message is not okay\n");
+                       "WLAN client not in session list and HELLO message is not okay\n");
       return;
     }
-  }
-
-  //FRAGMENT
-
-  else if (ntohs (hdr->type) == GNUNET_MESSAGE_TYPE_FRAGMENT)
-  {
-
-    GNUNET_assert (session_light != NULL);
-    if (session_light->macendpoint == NULL)
-    {
-      session_light->macendpoint =
-          get_macendpoint (plugin, &session_light->addr, GNUNET_YES);
-    }
-
-#if DEBUG_wlan
-    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
-                     "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_FRAGMENT with size: %u; mac endpoint %p: %s\n",
-                     ntohs (hdr->size), session_light->macendpoint,
-                     wlan_plugin_address_to_string (NULL,
-                                                    session_light->addr.mac,
-                                                    6));
-#endif
-
-    GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan fragments received"), 1, GNUNET_NO);
+    break;
+  case GNUNET_MESSAGE_TYPE_FRAGMENT:
+    macendpoint = get_macendpoint (plugin, &rxinfo->frame.addr2, GNUNET_YES);
+    GNUNET_STATISTICS_update (plugin->env->stats,
+                              _("# wlan fragments received"), 1, GNUNET_NO);
     int ret =
-        GNUNET_DEFRAGMENT_process_fragment (session_light->macendpoint->defrag,
+        GNUNET_DEFRAGMENT_process_fragment (macendpoint->defrag,
                                             hdr);
 
     if (ret == GNUNET_NO)
     {
-      session_light->macendpoint->dups++;
+      macendpoint->dups++;
     }
     else if (ret == GNUNET_OK)
     {
-      session_light->macendpoint->fragc++;
+      macendpoint->fragc++;
     }
     set_next_send (plugin);
-
-  }
-
-  //ACK
-
-  else if (ntohs (hdr->type) == GNUNET_MESSAGE_TYPE_FRAGMENT_ACK)
-  {
-    GNUNET_assert (session_light != NULL);
-    if (session_light->macendpoint == NULL)
-    {
-      session_light->macendpoint =
-          get_macendpoint (plugin, &session_light->addr, GNUNET_NO);
-    }
-
-    if (session_light->macendpoint == NULL)
+    break;
+  case GNUNET_MESSAGE_TYPE_FRAGMENT_ACK:
+    if (NULL == macendpoint)
     {
-#if DEBUG_wlan
       GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                        "Macendpoint does not exist for this GNUNET_MESSAGE_TYPE_FRAGMENT_ACK size: %u; %s\n",
                        ntohs (hdr->size), wlan_plugin_address_to_string (NULL,
-                                                                         session_light->addr.mac,
+                                                                         &rxinfo->frame.addr2.mac,
                                                                          6));
-#endif
       return;
     }
-
-#if DEBUG_wlan
-    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
-                     "Func wlan_data_helper got GNUNET_MESSAGE_TYPE_FRAGMENT_ACK size: %u; mac endpoint: %p; %s\n",
-                     ntohs (hdr->size), session_light->macendpoint,
-                     wlan_plugin_address_to_string (NULL,
-                                                    session_light->addr.mac,
-                                                    6));
-#endif
-    fm = session_light->macendpoint->sending_messages_head;
+    fm = macendpoint->sending_messages_head;
     while (fm != NULL)
     {
       fm2 = fm->next;
-      GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan acks received"), 1, GNUNET_NO);
+      GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan acks received"),
+                                1, GNUNET_NO);
       int ret = GNUNET_FRAGMENT_process_ack (fm->fragcontext, hdr);
 
       if (ret == GNUNET_OK)
       {
-#if DEBUG_wlan_retransmission > 1
         GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                          "Got last ack, finished fragment message %p\n", fm);
-#endif
-        session_light->macendpoint->acks++;
+        macendpoint->acks++;
         fm->session->last_activity = GNUNET_TIME_absolute_get ();
-        session_light->macendpoint->last_activity = fm->session->last_activity;
+        macendpoint->last_activity = fm->session->last_activity;
         free_fragment_message (plugin, fm);
         check_fragment_queue (plugin);
         return;
       }
       if (ret == GNUNET_NO)
       {
-#if DEBUG_wlan_retransmission > 1
         GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                          "Got ack for: %p\n", fm);
-#endif
-        session_light->macendpoint->acks++;
+        macendpoint->acks++;
         return;
       }
-      if (ret == GNUNET_SYSERR)
-      {
-
-      }
-
       fm = fm2;
     }
-
-#if DEBUG_wlan_retransmission > 1
     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                      "WLAN fragment not in fragment list\n");
-#endif
     return;
-
-  }
-  else
-  {
+  default:
     // TODO Wrong data?
     GNUNET_log_from (GNUNET_ERROR_TYPE_INFO, PLUGIN_LOG_NAME,
                      "WLAN packet inside the WLAN helper packet has not the right type: %u size: %u\n",
@@ -2542,26 +2659,23 @@ wlan_data_helper (void *cls, struct Session_light *session_light,
     GNUNET_break (0);
     return;
   }
-
-#if 0
   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                    "Helper finished\n");
-#endif
-
 }
 
 /**
- * Function to print mac addresses nice *
- * @param pointer to 6 byte with the mac address
- * @return pointer to the chars which hold the print out
+ * Function to print mac addresses nicely.
+ *
+ * @param mac the mac address
+ * @return string to a static buffer with the human-readable mac, will be overwritten during the next call to this function
  */
-const char *
-macprinter (const u_int8_t * mac)
+static const char *
+macprinter (const struct GNUNET_TRANSPORT_WLAN_MacAddress * mac)
 {
   static char macstr[20];
 
-  GNUNET_snprintf (macstr, sizeof (macstr), "%X:%X:%X:%X:%X:%X", mac[0], mac[1],
-                   mac[2], mac[3], mac[4], mac[5]);
+  GNUNET_snprintf (macstr, sizeof (macstr), "%2X:%2X:%2X:%2X:%2X:%2X", mac->mac[0], mac->mac[1],
+                   mac->mac[2], mac->mac[3], mac->mac[4], mac->mac[5]);
   return macstr;
 }
 
@@ -2585,8 +2699,9 @@ macendpoint_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
       (GNUNET_TIME_absolute_add
        (endpoint->last_activity, MACENDPOINT_TIMEOUT)).rel_value == 0)
   {
-    GNUNET_assert(endpoint->plugin != NULL);
-    GNUNET_STATISTICS_update (endpoint->plugin->env->stats, _("# wlan mac endpoints timeouts"), 1, GNUNET_NO);
+    GNUNET_assert (endpoint->plugin != NULL);
+    GNUNET_STATISTICS_update (endpoint->plugin->env->stats,
+                              _("# wlan mac endpoints timeouts"), 1, GNUNET_NO);
     free_macendpoint (endpoint->plugin, endpoint);
   }
   else
@@ -2604,12 +2719,13 @@ macendpoint_timeout (void *cls, const struct GNUNET_SCHEDULER_TaskContext *tc)
  * @return returns a macendpoint
  */
 static struct MacEndpoint *
-create_macendpoint (struct Plugin *plugin, const struct MacAddress *addr)
+create_macendpoint (struct Plugin *plugin, const struct GNUNET_TRANSPORT_WLAN_MacAddress *addr)
 {
   struct MacEndpoint *newend = GNUNET_malloc (sizeof (struct MacEndpoint));
 
-  GNUNET_assert(plugin != NULL);
-  GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan mac endpoints created"), 1, GNUNET_NO);
+  GNUNET_assert (plugin != NULL);
+  GNUNET_STATISTICS_update (plugin->env->stats,
+                            _("# wlan mac endpoints created"), 1, GNUNET_NO);
   newend->addr = *addr;
   newend->plugin = plugin;
   newend->addr = *addr;
@@ -2625,12 +2741,12 @@ create_macendpoint (struct Plugin *plugin, const struct MacAddress *addr)
                                     newend);
 
   plugin->mac_count++;
+  GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan mac endpoints"),
+                         plugin->mac_count, GNUNET_NO);
   GNUNET_CONTAINER_DLL_insert_tail (plugin->mac_head, plugin->mac_tail, newend);
-#if DEBUG_wlan
   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                    "New Mac Endpoint %p: %s\n", newend,
                    wlan_plugin_address_to_string (NULL, newend->addr.mac, 6));
-#endif
   return newend;
 }
 
@@ -2646,360 +2762,153 @@ wlan_process_helper (void *cls, void *client,
                      const struct GNUNET_MessageHeader *hdr)
 {
   struct Plugin *plugin = cls;
-  struct ieee80211_frame *wlanIeeeHeader = NULL;
-  struct Session_light *session_light = NULL;
-  struct Radiotap_rx *rxinfo;
+  const struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rxinfo;
+  const struct GNUNET_TRANSPORT_WLAN_HelperControlMessage *cm;
   const struct GNUNET_MessageHeader *temp_hdr = NULL;
-
+  const char *end;
   int datasize = 0;
   int pos;
 
-  GNUNET_assert(plugin != NULL);
+  GNUNET_assert (plugin != NULL);
   switch (ntohs (hdr->type))
   {
-  case GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA:
-#if DEBUG_wlan
+  case GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER:
     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
-                     "Func wlan_process_helper got GNUNET_MESSAGE_TYPE_WLAN_HELPER_DATA size: %u\n",
+                     "Got data message from helper with %u bytes\n",
                      ntohs (hdr->size));
-#endif
-
-    GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan WLAN_HELPER_DATA received"), 1, GNUNET_NO);
+    GNUNET_STATISTICS_update (plugin->env->stats,
+                              _("# wlan data messages received"), 1,
+                              GNUNET_NO);
     //call wlan_process_helper with the message inside, later with wlan: analyze signal
-    if (ntohs (hdr->size) <
-        sizeof (struct ieee80211_frame) + 2*sizeof (struct GNUNET_MessageHeader) +
-        sizeof (struct Radiotap_rx))
+    if (ntohs (hdr->size) < sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage))
     {
-#if DEBUG_wlan
       GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
-                       "Size of packet is too small; size: %u min size: %u\n",
-                       ntohs (hdr->size),
-                       sizeof (struct ieee80211_frame) +
-                       sizeof (struct GNUNET_MessageHeader));
-#endif
-      //GNUNET_break (0);
+                       "Size of packet is too small; size: %u\n",
+                       ntohs (hdr->size));
+      GNUNET_break (0);
       /* FIXME: restart SUID process */
       return;
     }
 
-    rxinfo = (struct Radiotap_rx *) &hdr[1];
-    wlanIeeeHeader = (struct ieee80211_frame *) &rxinfo[1];
-
+    rxinfo = (const struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) hdr;
     //process only if it is an broadcast or for this computer both with the gnunet bssid
-
     //check for bssid
     if (memcmp
-        (&(wlanIeeeHeader->i_addr3), &mac_bssid,
-         sizeof (struct MacAddress)) == 0)
+        (&rxinfo->frame.addr3, &mac_bssid_gnunet,
+         sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
     {
       //check for broadcast or mac
       if ((memcmp
-          (&(wlanIeeeHeader->i_addr1), &bc_all_mac,
-           sizeof (struct MacAddress)) == 0) ||
-          (memcmp (&(wlanIeeeHeader->i_addr1), &(plugin->mac_address),
-                  sizeof (struct MacAddress)) == 0))
+           (&rxinfo->frame.addr1, &bc_all_mac,
+            sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0) ||
+          (memcmp
+           (&rxinfo->frame.addr1, &plugin->mac_address,
+            sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0))
       {
-          //if packet is from us return
-          if ((memcmp (&(wlanIeeeHeader->i_addr2), &(plugin->mac_address),
-                  sizeof (struct MacAddress)) == 0)){
-              return;
-          }
-        // process the inner data
-
-
-        datasize =
-            ntohs (hdr->size) - sizeof (struct ieee80211_frame) -
-            sizeof (struct GNUNET_MessageHeader) - sizeof (struct Radiotap_rx);
-
-        session_light = GNUNET_malloc (sizeof (struct Session_light));
-        memcpy (&session_light->addr, &(wlanIeeeHeader->i_addr2),
-                sizeof (struct MacAddress));
-        //session_light->session = search_session(plugin,session_light->addr);
-        GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan messaged for this client received"), 1, GNUNET_NO);
-
+        //if packet is from us return
+        if ((memcmp
+             (&rxinfo->frame.addr2, &plugin->mac_address,
+              sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0))
+        {
+         /* not for us */
+          return;
+        }
+        datasize = ntohs (hdr->size) - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage);
+        GNUNET_STATISTICS_update (plugin->env->stats,
+                                  _("# wlan messages for this client received"),
+                                  1, GNUNET_NO);
+       // FIXME: this is a job for SERVER_mst -- 
+       // what we are doing here is not good for alignment...
         pos = 0;
-        while (pos < datasize)
+       end = (const char*) &rxinfo[1];
+        while (pos < datasize - sizeof (struct GNUNET_MessageHeader))
         {
-          temp_hdr = (struct GNUNET_MessageHeader *) &wlanIeeeHeader[1] + pos;
-          if (ntohs(temp_hdr->size) <= datasize + pos)
-            {
-              GNUNET_STATISTICS_update (plugin->env->stats, _("# wlan messaged inside WLAN_HELPER_DATA received"), 1, GNUNET_NO);
-              wlan_data_helper (plugin, session_light, temp_hdr, rxinfo);
-            }
+          temp_hdr = (struct GNUNET_MessageHeader *) &end[pos];
+          if (ntohs (temp_hdr->size) <= datasize - pos)
+          {
+            GNUNET_STATISTICS_update (plugin->env->stats,
+                                      _
+                                      ("# wlan messages inside WLAN_HELPER_DATA received"),
+                                      1, GNUNET_NO);
+            wlan_data_helper (plugin, temp_hdr, rxinfo);
+          }
           else
-            {
-#if DEBUG_wlan
+          {
             GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
-                       "Size of packet is too small; size: %u > size of packet: %u\n",
-                       ntohs(temp_hdr->size),datasize + pos);
-#endif
-            }
+                             "Size of packet is too small; size: %u > size of packet: %u\n",
+                             ntohs (temp_hdr->size), datasize - pos);
+          }
           pos += ntohs (temp_hdr->size);
-
         }
-
-        //clean up
-        GNUNET_free (session_light);
       }
       else
       {
-#if DEBUG_wlan
         GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                          "Func wlan_process_helper got wrong MAC: %s\n",
-                         macprinter (wlanIeeeHeader->i_addr1));
-#endif
+                         macprinter (&rxinfo->frame.addr1));
       }
     }
     else
     {
-#if DEBUG_wlan
       GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                        "Func wlan_process_helper got wrong BSSID: %s\n",
-                       macprinter (wlanIeeeHeader->i_addr2));
-#endif
+                       macprinter (&rxinfo->frame.addr2));
     }
     break;
   case GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL:
     //TODO more control messages
-    if (ntohs (hdr->size) != sizeof (struct Wlan_Helper_Control_Message))
+    if (ntohs (hdr->size) != sizeof (struct GNUNET_TRANSPORT_WLAN_HelperControlMessage))
     {
       GNUNET_break (0);
       /* FIXME: restart SUID process */
       return;
     }
-    memcpy (&plugin->mac_address, &hdr[1], sizeof (struct MacAddress));
-#if DEBUG_wlan
+    cm = (const struct GNUNET_TRANSPORT_WLAN_HelperControlMessage *) hdr;
+    plugin->mac_address = cm->mac;
     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                      "Received WLAN_HELPER_CONTROL message with transport of address %s\n",
                      wlan_plugin_address_to_string (cls, &plugin->mac_address,
-                                                    sizeof (struct
-                                                            MacAddress)));
-#endif
+                                                    sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)));
     plugin->env->notify_address (plugin->env->cls, GNUNET_YES,
                                  &plugin->mac_address,
-                                 sizeof (struct MacAddress));
+                                 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
     break;
   default:
-#if DEBUG_wlan
     GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                      "Func wlan_process_helper got unknown message with number %u, size %u\n",
                      ntohs (hdr->type), ntohs (hdr->size));
-
-#endif
-#if DEBUG_wlan_msg_dump > 1
-    hexdump (hdr, GNUNET_MIN (ntohs (hdr->size), 256));
-#endif
     GNUNET_break (0);
     return;
   }
 }
 
-/**
- * We have been notified that wlan-helper has written something to stdout.
- * Handle the output, then reschedule this function to be called again once
- * more is available.
- *
- * @param cls the plugin handle
- * @param tc the scheduling context
- */
-static void
-wlan_plugin_helper_read (void *cls,
-                         const struct GNUNET_SCHEDULER_TaskContext *tc)
-{
-  struct Plugin *plugin = cls;
-
-  plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK;
-
-  if (0 != (tc->reason & GNUNET_SCHEDULER_REASON_SHUTDOWN))
-    return;
-
-  char mybuf[WLAN_MTU + sizeof (struct GNUNET_MessageHeader)];
-  ssize_t bytes;
-
-  bytes =
-      GNUNET_DISK_file_read (plugin->server_stdout_handle, mybuf,
-                             sizeof (mybuf));
-  if (bytes <= 0)
-  {
-#if DEBUG_wlan
-    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
-                     _
-                     ("Finished reading from wlan-helper stdout with code: %d\n"),
-                     bytes);
-#endif
-    return;
-  }
-  GNUNET_SERVER_mst_receive (plugin->suid_tokenizer, NULL, mybuf, bytes,
-                             GNUNET_NO, GNUNET_NO);
-
-  GNUNET_assert (plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK);
-  plugin->server_read_task =
-      GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
-                                      plugin->server_stdout_handle,
-                                      &wlan_plugin_helper_read, plugin);
-}
-
-/**
- * Start the gnunet-wlan-helper process.
- *
- * @param plugin the transport plugin
- * @param testmode should we use the dummy driver for testing?
- * @return GNUNET_YES if process was started, GNUNET_SYSERR on error
- */
-static int
-wlan_transport_start_wlan_helper (struct Plugin *plugin, int testmode)
-{
-  const char *filenamehw = "gnunet-transport-wlan-helper";
-  const char *filenameloopback = "gnunet-transport-wlan-helper-dummy";
-
-  plugin->server_stdout = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_NO, GNUNET_YES);
-  if (plugin->server_stdout == NULL)
-    return GNUNET_SYSERR;
-
-  plugin->server_stdin = GNUNET_DISK_pipe (GNUNET_YES, GNUNET_YES, GNUNET_NO);
-  if (plugin->server_stdin == NULL)
-    return GNUNET_SYSERR;
-
-  /* Start the server process */
-
-  if (testmode == 0)
-  {
-
-#if DEBUG_wlan
-    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
-                     "Starting gnunet-wlan-helper process cmd: %s %s %i\n",
-                     filenamehw, plugin->interface, testmode);
-#endif
-
-    if (GNUNET_OS_check_helper_binary (filenamehw) == GNUNET_YES)
-    {
-      plugin->server_proc =
-          GNUNET_OS_start_process (plugin->server_stdin, plugin->server_stdout,
-                                   filenamehw, filenamehw, plugin->interface,
-                                   NULL);
-    }
-    else if (GNUNET_OS_check_helper_binary (filenamehw) == GNUNET_NO)
-    {
-      GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
-                       "gnunet-transport-wlan-helper is not suid, please change it or look at the doku\n");
-      GNUNET_break (0);
-    }
-    else
-    {
-      GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
-                       "gnunet-transport-wlan-helper not found, please look if it exists and is the $PATH variable!\n");
-      GNUNET_break (0);
-    }
-
-  }
-  else if (testmode == 1)
-  {
-
-#if DEBUG_wlan
-    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
-                     "Starting gnunet-wlan-helper loopback 1 process cmd: %s %s %i\n",
-                     filenameloopback, plugin->interface, testmode);
-#endif
-
-    if (GNUNET_OS_check_helper_binary (filenameloopback) != GNUNET_SYSERR)
-    {
-      plugin->server_proc =
-          GNUNET_OS_start_process (plugin->server_stdin, plugin->server_stdout,
-                                   filenameloopback, filenameloopback, "1",
-                                   NULL);
-    }
-    else
-    {
-      GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
-                       "gnunet-transport-wlan-helper-dummy not found, please look if it exists and is the $PATH variable!\n");
-      GNUNET_break (0);
-    }
-  }
-  else if (testmode == 2)
-  {
-#if DEBUG_wlan
-    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
-                     "Starting gnunet-wlan-helper loopback 2 process cmd: %s %s %i\n",
-                     filenameloopback, plugin->interface, testmode);
-#endif
-    if (GNUNET_OS_check_helper_binary (filenameloopback) != GNUNET_SYSERR)
-    {
-      plugin->server_proc =
-          GNUNET_OS_start_process (plugin->server_stdin, plugin->server_stdout,
-                                   filenameloopback, filenameloopback, "2",
-                                   NULL);
-    }
-    else
-    {
-      GNUNET_log_from (GNUNET_ERROR_TYPE_ERROR, PLUGIN_LOG_NAME,
-                       "gnunet-transport-wlan-helper-dummy not found, please look if it exists and is in the $PATH variable!\n");
-      GNUNET_break (0);
-    }
-  }
-  if (plugin->server_proc == NULL)
-  {
-#if DEBUG_wlan
-    GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
-                     "Failed to start gnunet-wlan-helper process\n");
-#endif
-    return GNUNET_SYSERR;
-  }
-
-  /* Close the write end of the read pipe */
-  GNUNET_DISK_pipe_close_end (plugin->server_stdout,
-                              GNUNET_DISK_PIPE_END_WRITE);
-
-  /* Close the read end of the write pipe */
-  GNUNET_DISK_pipe_close_end (plugin->server_stdin, GNUNET_DISK_PIPE_END_READ);
-
-  plugin->server_stdout_handle =
-      GNUNET_DISK_pipe_handle (plugin->server_stdout,
-                               GNUNET_DISK_PIPE_END_READ);
-  plugin->server_stdin_handle =
-      GNUNET_DISK_pipe_handle (plugin->server_stdin,
-                               GNUNET_DISK_PIPE_END_WRITE);
-
-  GNUNET_assert (plugin->server_read_task == GNUNET_SCHEDULER_NO_TASK);
-
-#if DEBUG_wlan
-  GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
-                   "Adding server_read_task for the wlan-helper\n");
-#endif
-
-  plugin->server_read_task =
-      GNUNET_SCHEDULER_add_read_file (GNUNET_TIME_UNIT_FOREVER_REL,
-                                      plugin->server_stdout_handle,
-                                      &wlan_plugin_helper_read, plugin);
 
-  return GNUNET_YES;
-}
 
 /**
  * Exit point from the plugin.
  * @param cls pointer to the api struct
  */
-
 //FIXME cleanup
 void *
 libgnunet_plugin_transport_wlan_done (void *cls)
 {
   struct GNUNET_TRANSPORT_PluginFunctions *api = cls;
   struct Plugin *plugin = api->cls;
-  struct MacEndpoint *endpoint = plugin->mac_head;
+  struct MacEndpoint *endpoint;
   struct MacEndpoint *endpoint_next;
 
-#if DEBUG_wlan
+  if (NULL == plugin)
+  {
+    GNUNET_free (api);
+    return NULL;
+  }
   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                    "libgnunet_plugin_transport_wlan_done started\n");
-#endif
-
-  GNUNET_DISK_pipe_close (plugin->server_stdout);
-  GNUNET_DISK_pipe_close (plugin->server_stdin);
-  GNUNET_OS_process_kill (plugin->server_proc, 9);
-  GNUNET_OS_process_close (plugin->server_proc);
+  wlan_transport_stop_wlan_helper (plugin);
 
   GNUNET_assert (cls != NULL);
   //free sessions
+  endpoint = plugin->mac_head;
   while (endpoint != NULL)
   {
     endpoint_next = endpoint->next;
@@ -3007,22 +2916,6 @@ libgnunet_plugin_transport_wlan_done (void *cls)
     endpoint = endpoint_next;
 
   }
-  if (plugin->server_write_delay_task != GNUNET_SCHEDULER_NO_TASK)
-  {
-    GNUNET_SCHEDULER_cancel (plugin->server_write_delay_task);
-    plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK;
-  }
-  if (plugin->server_write_task != GNUNET_SCHEDULER_NO_TASK)
-  {
-    GNUNET_SCHEDULER_cancel (plugin->server_write_task);
-    plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
-  }
-  if (plugin->server_read_task != GNUNET_SCHEDULER_NO_TASK)
-  {
-    GNUNET_SCHEDULER_cancel (plugin->server_read_task);
-    plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK;
-  }
-
   if (plugin->suid_tokenizer != NULL)
     GNUNET_SERVER_mst_destroy (plugin->suid_tokenizer);
 
@@ -3035,6 +2928,7 @@ libgnunet_plugin_transport_wlan_done (void *cls)
   return NULL;
 }
 
+
 /**
  * Entry point for the plugin.
  *
@@ -3044,19 +2938,30 @@ libgnunet_plugin_transport_wlan_done (void *cls)
 void *
 libgnunet_plugin_transport_wlan_init (void *cls)
 {
-  //struct GNUNET_SERVICE_Context *service;
   struct GNUNET_TRANSPORT_PluginEnvironment *env = cls;
   struct GNUNET_TRANSPORT_PluginFunctions *api;
   struct Plugin *plugin;
-  static unsigned long long testmode = 0;
 
-  GNUNET_assert (cls != NULL);
+  if (NULL == env->receive)
+  {
+    /* run in 'stub' mode (i.e. as part of gnunet-peerinfo), don't fully
+       initialze the plugin or the API */
+    api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
+    api->cls = NULL;
+    api->address_pretty_printer = &wlan_plugin_address_pretty_printer;
+    api->address_to_string = &wlan_plugin_address_to_string;
+    api->string_to_address = NULL; // FIXME!
+    return api;
+  }
 
   plugin = GNUNET_malloc (sizeof (struct Plugin));
   plugin->env = env;
   plugin->pendingsessions = 0;
-  GNUNET_STATISTICS_set(plugin->env->stats, _("# wlan pending sessions"), plugin->pendingsessions, GNUNET_NO);
+  GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan pending sessions"),
+                         plugin->pendingsessions, GNUNET_NO);
   plugin->mac_count = 0;
+  GNUNET_STATISTICS_set (plugin->env->stats, _("# wlan mac endpoints"),
+                         plugin->mac_count, GNUNET_NO);
   plugin->server_write_task = GNUNET_SCHEDULER_NO_TASK;
   plugin->server_read_task = GNUNET_SCHEDULER_NO_TASK;
   plugin->server_write_delay_task = GNUNET_SCHEDULER_NO_TASK;
@@ -3075,6 +2980,7 @@ libgnunet_plugin_transport_wlan_init (void *cls)
   api = GNUNET_malloc (sizeof (struct GNUNET_TRANSPORT_PluginFunctions));
   api->cls = plugin;
   api->send = &wlan_plugin_send;
+  api->get_session = &wlan_plugin_get_session;
   api->disconnect = &wlan_plugin_disconnect;
   api->address_pretty_printer = &wlan_plugin_address_pretty_printer;
   api->check_address = &wlan_plugin_address_suggested;
@@ -3086,8 +2992,8 @@ libgnunet_plugin_transport_wlan_init (void *cls)
   {
     if (GNUNET_SYSERR ==
         GNUNET_CONFIGURATION_get_value_number (env->cfg, "transport-wlan",
-                                               "TESTMODE", &testmode))
-      testmode = 0;             //default value
+                                               "TESTMODE", &(plugin->testmode)))
+      plugin->testmode = 0;     //default value
   }
 
   if (GNUNET_CONFIGURATION_have_value (env->cfg, "transport-wlan", "INTERFACE"))
@@ -3102,15 +3008,15 @@ libgnunet_plugin_transport_wlan_init (void *cls)
   }
 
   //start the plugin
-  wlan_transport_start_wlan_helper (plugin, testmode);
+  wlan_transport_start_wlan_helper (plugin);
   set_next_beacon_time (plugin);
-  set_next_send(plugin);
-#if DEBUG_wlan
+  set_next_send (plugin);
   GNUNET_log_from (GNUNET_ERROR_TYPE_DEBUG, PLUGIN_LOG_NAME,
                    "wlan init finished\n");
-#endif
-
   return api;
 }
 
+
+
+
 /* end of plugin_transport_wlan.c */