note about assertion actually failing
[oweals/gnunet.git] / src / transport / gnunet-helper-transport-bluetooth.c
index 1f5add92da988961a4c8fb013f9b13e15dec1cb9..2170221907192f37780006c8b99698cd2daa5a2c 100644 (file)
@@ -1,45 +1,54 @@
 /*
    This file is part of GNUnet.
-   (C) 2010, 2011, 2012 Christian Grothoff (and other contributing authors)
+   Copyright (C) 2010, 2011, 2012 GNUnet e.V.
    Copyright (c) 2007, 2008, Andy Green <andy@warmcat.com>
-   Copyright (C) 2009 Thomas d'Otreppe
+   Copyright Copyright (C) 2009 Thomas d'Otreppe
 
-   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 Affero General Public License as published
+   by the Free Software Foundation, either version 3 of the License,
+   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.
+   Affero General Public License for more details.
+  
+   You should have received a copy of the GNU Affero General Public License
+   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
-   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.
+     SPDX-License-Identifier: AGPL3.0-or-later
 */
 #include "gnunet_config.h"
 
-#include <bluetooth/bluetooth.h>
-#include <bluetooth/hci.h>
-#include <bluetooth/hci_lib.h>
-#include <bluetooth/rfcomm.h>
-#include <bluetooth/sdp.h>
-#include <bluetooth/sdp_lib.h>
-#include <errno.h>
-#include <linux/if.h>  
-#include <stdio.h>
-#include <stdlib.h>
-#include <sys/ioctl.h>
-#include <sys/param.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/types.h>
-#include <unistd.h>
+#ifdef MINGW
+  #include "platform.h"
+  #include "gnunet_util_lib.h"
+  #include <bthdef.h>
+  #include <ws2bth.h>
+#else
+  #define SOCKTYPE int
+  #include <bluetooth/bluetooth.h>
+  #include <bluetooth/hci.h>
+  #include <bluetooth/hci_lib.h>
+  #include <bluetooth/rfcomm.h>
+  #include <bluetooth/sdp.h>
+  #include <bluetooth/sdp_lib.h>
+  #include <errno.h>
+  #include <linux/if.h>
+  #include <stdio.h>
+  #include <stdlib.h>
+  #include <sys/ioctl.h>
+  #include <sys/param.h>
+  #include <sys/socket.h>
+  #include <sys/stat.h>
+  #include <sys/types.h>
+  #include <unistd.h>
+#endif
 
-#include "gnunet_protocols.h"
 #include "plugin_transport_wlan.h"
+#include "gnunet_protocols.h"
+
 
 /**
  * Maximum number of ports assignable for RFCOMMM protocol.
  */
 #define MAX_LOOPS 5
 
+#ifdef MINGW
+  /* Maximum size of the interface's name */
+  #define IFNAMSIZ 16
+
+  #ifndef NS_BTH
+    #define NS_BTH 16
+  #endif
+  /**
+   * A copy of the MAC Address.
+   */
+  struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy
+  {
+    UINT8 mac[MAC_ADDR_SIZE];
+  };
+
+  /**
+   * The UUID used for the SDP service.
+   * {31191E56-FA7E-4517-870E-71B86BBCC52F}
+   */
+  #define GNUNET_BLUETOOTH_SDP_UUID \
+    { \
+      0x31, 0x19, 0x1E, 0x56, \
+      0xFA, 0x7E, \
+      0x45, 0x17, \
+      0x87, 0x0E, \
+      0x71, 0xB8, 0x6B, 0xBC, 0xC5, 0x2F \
+    }
+#endif
+
+/**
+ * In bluez library, the maximum name length of a device is 8
+ */
+#define BLUEZ_DEVNAME_SIZE  8
+
 /**
  * struct for storing the information of the hardware.  There is only
  * one of these.
  */
 struct HardwareInfos
 {
+  /**
+   * Name of the interface, not necessarily 0-terminated (!).
+   */
+  char iface[IFNAMSIZ];
 
+ #ifdef MINGW
   /**
-   * file descriptor for the rfcomm socket
+   * socket handle
    */
-  int fd_rfcomm;
+  struct GNUNET_NETWORK_Handle *handle;
 
   /**
-   * Name of the interface, not necessarily 0-terminated (!).
+   * MAC address of our own bluetooth interface.
    */
-  char iface[IFNAMSIZ];
+  struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy pl_mac;
+ #else
+  /**
+   * file descriptor for the rfcomm socket
+   */
+  int fd_rfcomm;
 
   /**
    * MAC address of our own bluetooth interface.
    */
   struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac;
-  
+
   /**
    * SDP session
    */
    sdp_session_t *session ;
+ #endif
 };
 
 /**
@@ -102,7 +156,7 @@ struct SendBuffer
    * destination?  Always smaller than 'size'.
    */
   size_t pos;
-  
+
   /**
    * Buffered data; twice the maximum allowed message size as we add some
    * headers.
@@ -110,29 +164,42 @@ struct SendBuffer
   char buf[MAXLINE * 2];
 };
 
-/**
- * Devices buffer used to keep a list with all the discoverable devices in 
- * order to send them HELLO messages one by one when it receive a broadcast message.
- */ 
-struct BroadcastMessages
-{
-  /* List with the discoverable devices' addresses */
-  bdaddr_t devices[MAX_PORTS]; //FIXME I should use a linked list but 30 isn't such a big number
-  
-  /* List with the open sockets */
-  int fds[MAX_PORTS];
+#ifdef LINUX
+ /**
+  * Devices buffer used to keep a list with all the discoverable devices in
+  * order to send them HELLO messages one by one when it receive a broadcast message.
+  */
+ struct BroadcastMessages
+ {
+   /* List with the discoverable devices' addresses */
+   bdaddr_t devices[MAX_PORTS];
 
+   /* List with the open sockets */
+   int fds[MAX_PORTS];
 
-  /* The number of the devices */
-  int size;
-  
-  /* The current position */
-  int pos;
 
-  /* The device id */
-  int dev_id;
-};
+   /* The number of the devices */
+   int size;
+
+   /* The current position */
+   int pos;
+
+   /* The device id */
+   int dev_id;
+ };
+
+ /**
+  * Address used to identify the broadcast messages.
+  */
+ static struct GNUNET_TRANSPORT_WLAN_MacAddress broadcast_address = {{255, 255, 255, 255, 255, 255}};
+
+ /**
+  * Buffer with the discoverable devices.
+  */
+ static struct BroadcastMessages neighbours;
 
+ static int searching_devices_count = 0;
+#endif
 
 /**
  * Buffer for data read from stdin to be transmitted to the bluetooth device
@@ -144,20 +211,8 @@ static struct SendBuffer write_pout;
  */
 static struct SendBuffer write_std;
 
-/**
- * Address used to identify the broadcast messages.
- */
-static struct GNUNET_TRANSPORT_WLAN_MacAddress broadcast_address = {{255, 255, 255, 255, 255, 255}};
-
-/**
- * Buffer with the discoverable devices.
- */
-static struct BroadcastMessages neighbours;
 
-static int searching_devices_count = 0;
-
-/* *********** specialized version of server_mst.c begins here ********** */
-/* ****** this is the same version as the one used in gnunet-helper-transport-wlan.c ****** */ 
+/* ****** this are the same functions as the ones used in gnunet-helper-transport-wlan.c ****** */
 
 /**
  * To what multiple do we align messages?  8 byte should suffice for everyone
@@ -178,10 +233,10 @@ static int searching_devices_count = 0;
  * @param cls closure
  * @param message the actual message
  */
-typedef void (*MessageTokenizerCallback) (void *cls, 
-                                         const struct
-                                         GNUNET_MessageHeader *
-                                         message);
+typedef void (*MessageTokenizerCallback) (void *cls,
+            const struct
+            GNUNET_MessageHeader *
+            message);
 
 /**
  * Handle to a message stream tokenizer.
@@ -231,7 +286,7 @@ struct MessageStreamTokenizer
  */
 static struct MessageStreamTokenizer *
 mst_create (MessageTokenizerCallback cb,
-           void *cb_cls)
+      void *cb_cls)
 {
   struct MessageStreamTokenizer *ret;
 
@@ -251,7 +306,7 @@ mst_create (MessageTokenizerCallback cb,
   ret->cb = cb;
   ret->cb_cls = cb_cls;
   ret->pos = 0;
-  
+
   return ret;
 }
 
@@ -301,7 +356,7 @@ do_align:
       delta =
           GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) -
                       (mst->pos - mst->off), size);
-      memcpy (&ibuf[mst->pos], buf, delta);
+      GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
       mst->pos += delta;
       buf += delta;
       size -= delta;
@@ -354,7 +409,7 @@ do_align:
         fprintf (stderr, "The size of the buffer will be exceeded!\n");
         return GNUNET_SYSERR;
       }
-      memcpy (&ibuf[mst->pos], buf, delta);
+      GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
       mst->pos += delta;
       buf += delta;
       size -= delta;
@@ -431,14 +486,12 @@ do_align:
          "Assertion failed\n");
       exit (1);
     }
-    memcpy (&ibuf[mst->pos], buf, size);
+    GNUNET_memcpy (&ibuf[mst->pos], buf, size);
     mst->pos += size;
   }
   return ret;
 }
 
-
-
 /**
  * Destroys a tokenizer.
  *
@@ -451,11 +504,6 @@ mst_destroy (struct MessageStreamTokenizer *mst)
   free (mst);
 }
 
-/* *****************  end of server_mst.c clone ***************** **/
-
-
-/* ****** same crc version as the one used in gnunet-helper-transport-wlan.c ****** */ 
-
 /**
  * Calculate crc32, the start of the calculation
  *
@@ -559,205 +607,415 @@ check_crc_buf_osdep (const unsigned char *buf, size_t len)
   if (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
       ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3])
     return 0;
-  return 1;     
+  return 1;
 }
 
 
 
-/* ************** end of crc version  ***************** */
-
+/* ************** end of clone  ***************** */
 
+#ifdef MINGW
+  /**
+   * Function used to get the code of last error and to print the type of error.
+   */
+  static void
+  print_last_error()
+  {
+    LPVOID lpMsgBuf = NULL;
 
+    if (FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
+                    NULL, GetLastError(), 0, (LPTSTR) &lpMsgBuf, 0, NULL))
+      fprintf (stderr, "%s\n", (char *)lpMsgBuf);
+    else
+      fprintf (stderr, "Failed to format the message for the last error! Error number : %d\n", GetLastError());
+  }
 
-/**
- * Function for assigning a port number
- * @param socket the socket used to bind
- * @param addr pointer to the rfcomm address
- * @return 0 on success 
- */ 
-static int
-bind_socket (int socket, struct sockaddr_rc *addr)
-{
-  int port, status;
-  
-  /* Bind every possible port (from 0 to 30) and stop when bind doesn't fail */
-  //FIXME : it should start from port 1, but on my computer it doesn't work :)
-  for (port = 3; port <= 30; port++)
+  /**
+   * Function used to initialize the Windows Sockets
+   */
+  static void
+  initialize_windows_sockets()
   {
-    addr->rc_channel = port;
-    status = bind (socket, (struct sockaddr *) addr, sizeof (struct sockaddr_rc));
-    if (status == 0)
-      return 0;
+    WSADATA wsaData ;
+    WORD wVersionRequested = MAKEWORD (2, 0);
+    if (WSAStartup (wVersionRequested, &wsaData) != NO_ERROR)
+    {
+      fprintf (stderr , "Error initializing window sockets!\n");
+      print_last_error();
+      ExitProcess (2) ;
+    }
   }
-  
-  return -1; 
-}
 
+  /**
+   * Function used to convert the GUID.
+   * @param bytes the GUID represented as a char array
+   * @param uuid pointer to the GUID
+   */
+  static void
+  convert_guid(char *bytes, GUID * uuid)
+  {
+    int i;
+    uuid->Data1 = ((bytes[0] << 24) & 0xff000000) | ((bytes[1] << 16) & 0x00ff0000) | ((bytes[2] << 8) & 0x0000ff00) | (bytes[3] & 0x000000ff);
+    uuid->Data2 = ((bytes[4] << 8) & 0xff00) | (bytes[5] & 0x00ff);
+    uuid->Data3 = ((bytes[6] << 8) & 0xff00) | (bytes[7] & 0x00ff);
 
-/**
- * Function used for creating the service record and registering it.
- * @param dev pointer to the device struct
- * @param rc_channel the rfcomm channel
- * @return 0 on success
- */
-static int
-register_service (struct HardwareInfos *dev, int rc_channel) 
-{
+    for (i = 0; i < 8; i++)
+    {
+      uuid->Data4[i] = bytes[i + 8];
+    }
+  }
+#endif
+
+#ifdef LINUX
   /**
-   * 1. initializations
-   * 2. set the service ID, class, profile information
-   * 3. make the service record publicly browsable
-   * 4. register the RFCOMM channel
-   * 5. set the name, provider and description
-   * 6. register the service record to the local SDP server
-   * 7. cleanup
+   * Function for assigning a port number
+   *
+   * @param socket the socket used to bind
+   * @param addr pointer to the rfcomm address
+   * @return 0 on success
    */
+  static int
+  bind_socket (int socket, struct sockaddr_rc *addr)
+  {
+    int port, status;
 
-  //FIXME: probably this is not the best idea. I should find a different uuid
-  uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-                            dev->pl_mac.mac[5], dev->pl_mac.mac[4], dev->pl_mac.mac[3],
-                            dev->pl_mac.mac[2], dev->pl_mac.mac[1], dev->pl_mac.mac[0]};
-//  const char *service_name = "GNUnet";
-  const char *service_dsc = "Bluetooth plugin services";
-  const char *service_prov = "GNUnet provider";                       
-  uuid_t root_uuid, rfcomm_uuid, svc_uuid;  
-  sdp_list_t *root_list = 0, *rfcomm_list = 0, *proto_list = 0,
-     *access_proto_list = 0, *svc_list = 0;
-  sdp_record_t *record = 0;
-  sdp_data_t *channel = 0;
-       
-       record = sdp_record_alloc();
-
-  /* Set the general service ID */
-  sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
-  svc_list = sdp_list_append (0, &svc_uuid);
-  sdp_set_service_classes (record, svc_list);
-  sdp_set_service_id (record, svc_uuid);
-
-       /* Make the service record publicly browsable */
-  sdp_uuid16_create (&root_uuid, PUBLIC_BROWSE_GROUP); 
-  root_list = sdp_list_append (0, &root_uuid); 
-  sdp_set_browse_groups (record, root_list);
-
-       /* Register the RFCOMM channel */
-  sdp_uuid16_create (&rfcomm_uuid, RFCOMM_UUID);
-  channel = sdp_data_alloc (SDP_UINT8, &rc_channel);
-  rfcomm_list = sdp_list_append (0, &rfcomm_uuid);
-  sdp_list_append (rfcomm_list, channel);
-  proto_list = sdp_list_append (0, rfcomm_list);
-
-  /* Set protocol information */
-  access_proto_list = sdp_list_append (0, proto_list);
-  sdp_set_access_protos (record, access_proto_list);
-
-  /* Set the name, provider, and description */
-       sdp_set_info_attr (record, dev->iface, service_prov, service_dsc);
-  
-  /* Connect to the local SDP server */
-  dev->session = sdp_connect (BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
-  
-  if (!dev->session)
+    /* Bind every possible port (from 0 to 30) and stop when binding doesn't fail */
+    //FIXME : it should start from port 1, but on my computer it doesn't work :)
+    for (port = 3; port <= 30; port++)
+    {
+      addr->rc_channel = port;
+      status = bind (socket, (struct sockaddr *) addr, sizeof (struct sockaddr_rc));
+      if (status == 0)
+        return 0;
+    }
+
+    return -1;
+  }
+#endif
+
+#ifdef MINGW
+  /**
+   * Function used for creating the service record and registering it.
+   *
+   * @param dev pointer to the device struct
+   * @return 0 on success
+   */
+  static int
+  register_service (struct HardwareInfos *dev)
   {
-    fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
-             IFNAMSIZ, dev->iface, strerror (errno));
-    //FIXME exit?
-    return 1;
+    /* advertise the service */
+    CSADDR_INFO addr_info;
+    WSAQUERYSET wqs;
+    GUID guid;
+    unsigned char uuid[] = GNUNET_BLUETOOTH_SDP_UUID;
+    SOCKADDR_BTH addr;
+    int addr_len = sizeof (SOCKADDR_BTH);
+    int fd;
+    /* get the port on which we are listening on */
+    memset (& addr, 0, sizeof (SOCKADDR_BTH));
+    fd = GNUNET_NETWORK_get_fd (dev->handle);
+    if (fd <= 0)
+    {
+      fprintf (stderr, "Failed to get the file descriptor\n");
+      return -1;
+    }
+    if (SOCKET_ERROR == getsockname (fd, (SOCKADDR*)&addr, &addr_len))
+    {
+      fprintf (stderr, "Failed to get the port on which we are listening on: \n");
+      print_last_error();
+      return -1;
+    }
+
+    /* save the device address */
+    GNUNET_memcpy (&dev->pl_mac, &addr.btAddr, sizeof (BTH_ADDR));
+
+    /* set the address information */
+    memset (&addr_info, 0, sizeof (CSADDR_INFO));
+    addr_info.iProtocol = BTHPROTO_RFCOMM;
+    addr_info.iSocketType = SOCK_STREAM;
+    addr_info.LocalAddr.lpSockaddr = (LPSOCKADDR)&addr;
+    addr_info.LocalAddr.iSockaddrLength = sizeof (addr);
+    addr_info.RemoteAddr.lpSockaddr = (LPSOCKADDR)&addr;
+    addr_info.RemoteAddr.iSockaddrLength = sizeof (addr);
+
+    convert_guid((char *) uuid, &guid);
+
+    /* register the service */
+    memset (&wqs, 0, sizeof (WSAQUERYSET));
+    wqs.dwSize = sizeof (WSAQUERYSET);
+    wqs.dwNameSpace = NS_BTH;
+    wqs.lpszServiceInstanceName = "GNUnet Bluetooth Service";
+    wqs.lpszComment = "This is the service used by the GNUnnet plugin transport";
+    wqs.lpServiceClassId = &guid;
+    wqs.dwNumberOfCsAddrs = 1;
+    wqs.lpcsaBuffer = &addr_info ;
+    wqs.lpBlob = 0;
+
+    if (SOCKET_ERROR == WSASetService (&wqs , RNRSERVICE_REGISTER, 0))
+    {
+      fprintf (stderr, "Failed to register the SDP service: ");
+      print_last_error();
+      return -1;
+    }
+    else
+    {
+      fprintf (stderr, "The SDP service was registered\n");
+    }
+
+    return 0;
   }
-  
-  /* Register the service record */
-  if (sdp_record_register (dev->session, record, 0) < 0)
+#else
+  /**
+   * Function used for creating the service record and registering it.
+   *
+   * @param dev pointer to the device struct
+   * @param rc_channel the rfcomm channel
+   * @return 0 on success
+   */
+  static int
+  register_service (struct HardwareInfos *dev, int rc_channel)
   {
-    fprintf (stderr, "Failed to register a service record on interface `%.*s': %s\n",
-             IFNAMSIZ, dev->iface, strerror (errno));
-    //FIXME exit?
-    return 1;
+    /**
+     * 1. initializations
+     * 2. set the service ID, class, profile information
+     * 3. make the service record publicly browsable
+     * 4. register the RFCOMM channel
+     * 5. set the name, provider and description
+     * 6. register the service record to the local SDP server
+     * 7. cleanup
+     */
+    uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                              dev->pl_mac.mac[5], dev->pl_mac.mac[4], dev->pl_mac.mac[3],
+                              dev->pl_mac.mac[2], dev->pl_mac.mac[1], dev->pl_mac.mac[0]};
+    const char *service_dsc = "Bluetooth plugin services";
+    const char *service_prov = "GNUnet provider";
+    uuid_t root_uuid, rfcomm_uuid, svc_uuid;
+    sdp_list_t *root_list = 0, *rfcomm_list = 0, *proto_list = 0,
+       *access_proto_list = 0, *svc_list = 0;
+    sdp_record_t *record = 0;
+    sdp_data_t *channel = 0;
+
+    record = sdp_record_alloc();
+
+    /* Set the general service ID */
+    sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
+    svc_list = sdp_list_append (0, &svc_uuid);
+    sdp_set_service_classes (record, svc_list);
+    sdp_set_service_id (record, svc_uuid);
+
+    /* Make the service record publicly browsable */
+    sdp_uuid16_create (&root_uuid, PUBLIC_BROWSE_GROUP);
+    root_list = sdp_list_append (0, &root_uuid);
+    sdp_set_browse_groups (record, root_list);
+
+    /* Register the RFCOMM channel */
+    sdp_uuid16_create (&rfcomm_uuid, RFCOMM_UUID);
+    channel = sdp_data_alloc (SDP_UINT8, &rc_channel);
+    rfcomm_list = sdp_list_append (0, &rfcomm_uuid);
+    sdp_list_append (rfcomm_list, channel);
+    proto_list = sdp_list_append (0, rfcomm_list);
+
+    /* Set protocol information */
+    access_proto_list = sdp_list_append (0, proto_list);
+    sdp_set_access_protos (record, access_proto_list);
+
+    /* Set the name, provider, and description */
+    sdp_set_info_attr (record, dev->iface, service_prov, service_dsc);
+
+    /* Connect to the local SDP server */
+    dev->session = sdp_connect (BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
+
+    if (!dev->session)
+    {
+      fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
+               IFNAMSIZ, dev->iface, strerror (errno));
+      //FIXME exit?
+      return 1;
+    }
+
+    /* Register the service record */
+    if (sdp_record_register (dev->session, record, 0) < 0)
+    {
+      fprintf (stderr, "Failed to register a service record on interface `%.*s': %s\n",
+               IFNAMSIZ, dev->iface, strerror (errno));
+      //FIXME exit?
+      return 1;
+    }
+
+    /* Cleanup */
+    sdp_data_free (channel);
+    sdp_list_free (root_list, 0);
+    sdp_list_free (rfcomm_list, 0);
+    sdp_list_free (proto_list, 0);
+    sdp_list_free (access_proto_list, 0);
+    sdp_list_free (svc_list, 0);
+    sdp_record_free (record);
+
+    return 0;
   }
-  
-  /* Cleanup */
-  sdp_data_free (channel);     
-  sdp_list_free (root_list, 0);
-  sdp_list_free (rfcomm_list, 0);
-  sdp_list_free (proto_list, 0);
-  sdp_list_free (access_proto_list, 0);
-  sdp_list_free (svc_list, 0);
-  sdp_record_free (record);
-  
-  return 0;
-}
+#endif
 
-/**
- * Function for searching and browsing for a service. This will return the 
- * port number on which the service is running.
- * @param dev pointer to the device struct
- * @param dest target address
- * @return channel
- */
-static int
-get_channel(struct HardwareInfos *dev, bdaddr_t dest) 
-{
+#ifdef MINGW
   /**
-   * 1. detect all nearby devices
-   * 2. for each device:
-   * 2.1. connect to the SDP server running
-   * 2.2. get a list of service records with the specific UUID
-   * 2.3. for each service record get a list of the protocol sequences and get 
-   *       the port number
+   * Function for searching and browsing for a service. This will return the
+   * port number on which the service is running.
+   *
+   * @param dest target address
+   * @return channel
    */
-  uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
-                           dest.b[5], dest.b[4], dest.b[3],
-                           dest.b[2], dest.b[1], dest.b[0]};
-  sdp_session_t *session = 0;
-  sdp_list_t *search_list = 0, *attrid_list = 0, *response_list = 0, *it = 0;
-  uuid_t svc_uuid;
-  uint32_t range = 0x0000ffff;
-  uint8_t channel = -1;
-   
-  /* Connect to the local SDP server */
-  session = sdp_connect (BDADDR_ANY, &dest, 0); 
-  if (!session)
+  static int
+  get_channel(const char *dest)
   {
-   fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
-            IFNAMSIZ, dev->iface, strerror (errno));
-   //FIXME exit?
-   return -1;
+    HANDLE h;
+    WSAQUERYSET *wqs;
+    DWORD wqs_len = sizeof (WSAQUERYSET);
+    int done = 0;
+    int channel = -1;
+    GUID guid;
+    unsigned char uuid[] = GNUNET_BLUETOOTH_SDP_UUID;
+    convert_guid ((char *) uuid, &guid);
+
+    wqs = (WSAQUERYSET*)malloc (wqs_len);
+    ZeroMemory (wqs, wqs_len);
+
+    wqs->dwSize = sizeof (WSAQUERYSET) ;
+    wqs->lpServiceClassId = &guid;
+    wqs->dwNameSpace = NS_BTH;
+    wqs->dwNumberOfCsAddrs = 0;
+    wqs->lpszContext = (LPSTR)dest;
+
+    if (SOCKET_ERROR == WSALookupServiceBegin (wqs,  LUP_FLUSHCACHE | LUP_RETURN_ALL, &h))
+    {
+      if (GetLastError() == WSASERVICE_NOT_FOUND)
+      {
+        fprintf (stderr, "WARNING! The device with address %s wasn't found. Skipping the message!", dest);
+        return -1;
+      }
+      else
+      {
+        fprintf (stderr, "Failed to find the port number: ");
+        print_last_error();
+        ExitProcess (2);
+        return -1;
+      }
+    }
+
+    /* search the sdp service */
+    while (!done)
+    {
+      if (SOCKET_ERROR == WSALookupServiceNext (h, LUP_FLUSHCACHE | LUP_RETURN_ALL, &wqs_len, wqs))
+      {
+        int error = WSAGetLastError();
+
+        switch (error)
+        {
+        case WSAEFAULT:
+          free (wqs);
+          wqs = (WSAQUERYSET*)malloc (wqs_len);
+          break;
+        case WSANO_DATA:
+          fprintf (stderr, "Failed! The address was valid but there was no data record of requested type\n");
+          done = 1;
+          break;
+        case WSA_E_NO_MORE:
+          done = 1;
+          break;
+        default:
+          fprintf (stderr, "Failed to look over the services: ");
+          print_last_error();
+          WSALookupServiceEnd (h);
+          ExitProcess (2);
+        }
+      }
+      else
+      {
+        channel = ((SOCKADDR_BTH*)wqs->lpcsaBuffer->RemoteAddr.lpSockaddr)->port;
+      }
+    }
+
+    free (wqs) ;
+    WSALookupServiceEnd (h);
+
+    return channel;
   }
-  
-  sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
-  search_list = sdp_list_append (0, &svc_uuid);
-  attrid_list = sdp_list_append (0, &range);
-  
-  if (sdp_service_search_attr_req (session, search_list, 
-                  SDP_ATTR_REQ_RANGE, attrid_list, &response_list) == 0)
+#else
+  /**
+   * Function used for searching and browsing for a service. This will return the
+   * port number on which the service is running.
+   *
+   * @param dev pointer to the device struct
+   * @param dest target address
+   * @return channel
+   */
+  static int
+  get_channel(struct HardwareInfos *dev, bdaddr_t dest)
   {
-    for (it = response_list; it; it = it->next)
+    /**
+     * 1. detect all nearby devices
+     * 2. for each device:
+     * 2.1. connect to the SDP server running
+     * 2.2. get a list of service records with the specific UUID
+     * 2.3. for each service record get a list of the protocol sequences and get
+     *       the port number
+     */
+    uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+                             dest.b[5], dest.b[4], dest.b[3],
+                             dest.b[2], dest.b[1], dest.b[0]};
+    sdp_session_t *session = 0;
+    sdp_list_t *search_list = 0, *attrid_list = 0, *response_list = 0, *it = 0;
+    uuid_t svc_uuid;
+    uint32_t range = 0x0000ffff;
+    int channel = -1;
+
+    /* Connect to the local SDP server */
+    session = sdp_connect (BDADDR_ANY, &dest, 0);
+    if (!session)
+    {
+     fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
+              IFNAMSIZ, dev->iface, strerror (errno));
+     return -1;
+    }
+
+    sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
+    search_list = sdp_list_append (0, &svc_uuid);
+    attrid_list = sdp_list_append (0, &range);
+
+    if (sdp_service_search_attr_req (session, search_list,
+                    SDP_ATTR_REQ_RANGE, attrid_list, &response_list) == 0)
     {
-      sdp_record_t *record = (sdp_record_t*) it->data;
-      //TODO print some record informations to be sure everything is good
-      sdp_list_t *proto_list = 0;
-      if (sdp_get_access_protos (record, &proto_list) == 0)
+      for (it = response_list; it; it = it->next)
       {
-        channel = sdp_get_proto_port (proto_list, RFCOMM_UUID);
-        sdp_list_free (proto_list, 0);
+        sdp_record_t *record = (sdp_record_t*) it->data;
+        sdp_list_t *proto_list = 0;
+        if (sdp_get_access_protos (record, &proto_list) == 0)
+        {
+          channel = sdp_get_proto_port (proto_list, RFCOMM_UUID);
+          sdp_list_free (proto_list, 0);
+        }
+        sdp_record_free (record);
       }
-      sdp_record_free (record);
     }
+
+    sdp_list_free (search_list, 0);
+    sdp_list_free (attrid_list, 0);
+    sdp_list_free (response_list, 0);
+
+    sdp_close (session);
+
+    if (-1 == channel)
+      fprintf (stderr,
+               "Failed to find the listening channel for interface `%.*s': %s\n",
+               IFNAMSIZ,
+               dev->iface,
+               strerror (errno));
+
+    return channel;
   }
-  
-  sdp_list_free (search_list, 0);
-  sdp_list_free (attrid_list, 0);
-  sdp_list_free (response_list, 0);
-  
-  sdp_close (session);
-  
-  if (channel == -1)
-    fprintf (stderr, "Failed to find the listening channel for interface `%.*s': %s\n",
-            IFNAMSIZ, dev->iface, strerror (errno));
-  
-  return channel;
-}
+#endif
 
 /**
  * Read from the socket and put the result into the buffer for transmission to 'stdout'.
+ *
  * @param sock file descriptor for reading
  * @param buf buffer to read to; first bytes will be the 'struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame',
  *            followed by the actual payload
@@ -765,198 +1023,269 @@ get_channel(struct HardwareInfos *dev, bdaddr_t dest)
  * @param ri where to write radiotap_rx info
  * @return number of bytes written to 'buf'
  */
-static ssize_t 
-read_from_the_socket (int sock, 
-           unsigned char *buf, size_t buf_size,
+static ssize_t
+read_from_the_socket (void *sock,
+      unsigned char *buf, size_t buf_size,
             struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri)
 {
- /**
-  * 1. Read from the socket in a temporary buffer (check for errors)
-  * 2. Detect if the crc exists
-  * 3. Write the result to the buffer
-  */
   unsigned char tmpbuf[buf_size];
   ssize_t count;
-  int len;
-  struct sockaddr_rc  rc_addr = { 0 }; 
-  
-  count = read (sock, tmpbuf, buf_size); 
-  
+
+  #ifdef MINGW
+   count = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)sock, tmpbuf, buf_size);
+  #else
+   count = read (*((int *)sock), tmpbuf, buf_size);
+  #endif
+
   if (0 > count)
   {
     if (EAGAIN == errno)
       return 0;
-     
-    fprintf (stderr, "Failed to read from the HCI socket: %s\n", strerror (errno));
-    return -1;
-  }
-  
-  /* Get the channel used */
-  memset (&rc_addr, 0, sizeof (rc_addr));
-  len = sizeof (rc_addr);
-  if (0 > getsockname (sock, (struct sockaddr *) &rc_addr, (socklen_t *) &len))
-  {
-    fprintf (stderr, "getsockname() call failed : %s\n", strerror (errno));
+    #if MINGW
+     print_last_error();
+    #else
+     fprintf (stderr, "Failed to read from the HCI socket: %s\n", strerror (errno));
+    #endif
+
     return -1;
   }
-  
-  memset (ri, 0, sizeof (*ri));
-  ri->ri_channel = rc_addr.rc_channel;
-  
+
+  #ifdef LINUX
+   /* Get the channel used */
+   int len;
+   struct sockaddr_rc  rc_addr = { 0 };
+
+   memset (&rc_addr, 0, sizeof (rc_addr));
+   len = sizeof (rc_addr);
+   if (0 > getsockname (*((int *)sock), (struct sockaddr *) &rc_addr, (socklen_t *) &len))
+   {
+     fprintf (stderr, "getsockname() call failed : %s\n", strerror (errno));
+     return -1;
+   }
+
+   memset (ri, 0, sizeof (*ri));
+   ri->ri_channel = rc_addr.rc_channel;
+  #endif
+
   /* Detect CRC32 at the end */
   if (0 == check_crc_buf_osdep (tmpbuf, count - sizeof (uint32_t)))
   {
     count -= sizeof(uint32_t);
   }
-  
-  memcpy (buf, tmpbuf, count);
-  
+
+  GNUNET_memcpy (buf, tmpbuf, count);
+
   return count;
 }
 
+
 /**
  * Open the bluetooth interface for reading/writing
  *
  * @param dev pointer to the device struct
- * @return 0 on success
+ * @return 0 on success, non-zero on error
  */
 static int
 open_device (struct HardwareInfos *dev)
-{   
-  int i, dev_id = -1, fd_hci;
-  struct 
-  {
-    struct hci_dev_list_req list;
-    struct hci_dev_req dev[HCI_MAX_DEV];
-  } request;                        //used for detecting the local devices
-  struct sockaddr_rc rc_addr = { 0 };    //used for binding
-  
-  /* Initialize the neighbour structure */
-  neighbours.dev_id = -1;
-  for (i = 0; i < MAX_PORTS; i++)
-    neighbours.fds[i] = -1;
-  
-  /* Open a HCI socket */
-  fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
+{
+  #ifdef MINGW
+    SOCKADDR_BTH addr;
 
-  if (fd_hci < 0) 
-  {
-    fprintf (stderr, "Failed to create HCI socket: %s\n", strerror (errno));
-    return -1;
-  }
-       
-  memset (&request, 0, sizeof(request));
-  request.list.dev_num = HCI_MAX_DEV;
+    /* bind the RFCOMM socket to the interface */
+    addr.addressFamily = AF_BTH;
+    addr.btAddr = 0;
+    addr.port = BT_PORT_ANY;
 
-  if (ioctl (fd_hci, HCIGETDEVLIST, (void *) &request) < 0)
-  {
-    fprintf (stderr, "ioctl(HCIGETDEVLIST) on interface `%.*s' failed: %s\n",
-            IFNAMSIZ, dev->iface, strerror (errno));
-    return 1;
-  }
-       
-       /* Search for a device with dev->iface name */
-  for (i = 0; i < request.list.dev_num; i++)
-  {
-    struct hci_dev_info dev_info;
+    if (GNUNET_OK !=
+       GNUNET_NETWORK_socket_bind (dev->handle, (const SOCKADDR*)&addr, sizeof (SOCKADDR_BTH)))
+    {
+      fprintf (stderr, "Failed to bind the socket: ");
+      if (GetLastError() == WSAENETDOWN)
+      {
+        fprintf (stderr, "Please make sure that your Bluetooth device is ON!\n");
+        ExitProcess (2);
+      }
+      print_last_error();
+      return -1;
+    }
 
-    memset (&dev_info, 0, sizeof(struct hci_dev_info));
-    dev_info.dev_id = request.dev[i].dev_id;
-    strncpy (dev_info.name, dev->iface, IFNAMSIZ);
-    
-    if (ioctl (fd_hci, HCIGETDEVINFO, (void *) &dev_info))
+    /* start listening on the socket */
+    if (GNUNET_NETWORK_socket_listen (dev->handle, 4) != GNUNET_OK)
     {
-      fprintf (stderr, "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n",
-             IFNAMSIZ, dev->iface, strerror (errno));
+      fprintf (stderr, "Failed to listen on the socket: ");
+      print_last_error();
+      return -1;
+    }
+
+    /* register the sdp service */
+    if (register_service(dev) != 0)
+    {
+      fprintf (stderr, "Failed to register a service: ");
+      print_last_error();
       return 1;
     }
-    
-    if (strcmp (dev_info.name, dev->iface) == 0)
+  #else
+    int i, dev_id = -1, fd_hci;
+    struct
     {
-      
-      dev_id = dev_info.dev_id; //the device was found
-      /**
-       * Copy the MAC address to the device structure
-       */
-      memcpy (&dev->pl_mac, &dev_info.bdaddr, sizeof (bdaddr_t));
-      
-      /* Check if the interface is UP */
-      if (hci_test_bit (HCI_UP, (void *) &dev_info.flags) == 0)
+      struct hci_dev_list_req list;
+      struct hci_dev_req dev[HCI_MAX_DEV];
+    } request;                              //used for detecting the local devices
+    struct sockaddr_rc rc_addr = { 0 };    //used for binding
+
+    /* Initialize the neighbour structure */
+    neighbours.dev_id = -1;
+    for (i = 0; i < MAX_PORTS; i++)
+      neighbours.fds[i] = -1;
+
+    /* Open a HCI socket */
+    fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
+
+    if (fd_hci < 0)
+    {
+      fprintf (stderr,
+               "Failed to create HCI socket: %s\n",
+               strerror (errno));
+      return -1;
+    }
+
+    memset (&request, 0, sizeof(request));
+    request.list.dev_num = HCI_MAX_DEV;
+
+    if (ioctl (fd_hci, HCIGETDEVLIST, (void *) &request) < 0)
+    {
+      fprintf (stderr,
+               "ioctl(HCIGETDEVLIST) on interface `%.*s' failed: %s\n",
+               IFNAMSIZ,
+               dev->iface,
+               strerror (errno));
+      (void) close (fd_hci);
+      return 1;
+    }
+
+    /* Search for a device with dev->iface name */
+    for (i = 0; i < request.list.dev_num; i++)
+    {
+      struct hci_dev_info dev_info;
+
+      memset (&dev_info, 0, sizeof(struct hci_dev_info));
+      dev_info.dev_id = request.dev[i].dev_id;
+      strncpy (dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE);
+
+      if (ioctl (fd_hci, HCIGETDEVINFO, (void *) &dev_info))
       {
-        /* Bring interface up */
-        if (ioctl (fd_hci, HCIDEVUP, dev_info.dev_id))
-        {
-          fprintf (stderr, "ioctl(HCIDEVUP) on interface `%.*s' failed: %s\n",
-             IFNAMSIZ, dev->iface, strerror (errno));
-          return 1;
-        }
+        fprintf (stderr,
+                 "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n",
+                 IFNAMSIZ,
+                 dev->iface,
+                 strerror (errno));
+        (void) close (fd_hci);
+        return 1;
       }
-      
-      /* Check if the device is discoverable */
-      if (hci_test_bit (HCI_PSCAN, (void *) &dev_info.flags) == 0 ||
-          hci_test_bit (HCI_ISCAN, (void *) &dev_info.flags) == 0)
+
+      if (strncmp (dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE) == 0)
       {
-        /* Set interface Page Scan and Inqury Scan ON */
-        struct hci_dev_req dev_req;
-          
-        memset (&dev_req, 0, sizeof (dev_req));
-        dev_req.dev_id = dev_info.dev_id;
-        dev_req.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
-        
-        if (ioctl (fd_hci, HCISETSCAN, (unsigned long) &dev_req))
-        {  
-          fprintf (stderr, "ioctl(HCISETSCAN) on interface `%.*s' failed: %s\n",
-             IFNAMSIZ, dev->iface, strerror (errno));
-          return 1;
-        }
-        
+
+        dev_id = dev_info.dev_id; //the device was found
+        /**
+         * Copy the MAC address to the device structure
+         */
+        GNUNET_memcpy (&dev->pl_mac, &dev_info.bdaddr, sizeof (bdaddr_t));
+
+        /* Check if the interface is up */
+        if (hci_test_bit (HCI_UP, (void *) &dev_info.flags) == 0)
+        {
+          /* Bring the interface up */
+          if (ioctl (fd_hci, HCIDEVUP, dev_info.dev_id))
+          {
+            fprintf (stderr,
+                     "ioctl(HCIDEVUP) on interface `%.*s' failed: %s\n",
+                     IFNAMSIZ,
+                     dev->iface,
+                     strerror (errno));
+            (void) close (fd_hci);
+            return 1;
+          }
+        }
+
+        /* Check if the device is discoverable */
+        if (hci_test_bit (HCI_PSCAN, (void *) &dev_info.flags) == 0 ||
+            hci_test_bit (HCI_ISCAN, (void *) &dev_info.flags) == 0)
+        {
+          /* Set interface Page Scan and Inqury Scan ON */
+          struct hci_dev_req dev_req;
+
+          memset (&dev_req, 0, sizeof (dev_req));
+          dev_req.dev_id = dev_info.dev_id;
+          dev_req.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
+
+          if (ioctl (fd_hci, HCISETSCAN, (unsigned long) &dev_req))
+          {
+            fprintf (stderr,
+                     "ioctl(HCISETSCAN) on interface `%.*s' failed: %s\n",
+                     IFNAMSIZ,
+                     dev->iface,
+                     strerror (errno));
+            (void) close (fd_hci);
+            return 1;
+          }
+
+        }
+        break;
       }
-      break;
+
     }
-    
-  }
-  
-  /* Check if the interface was not found */
-  if (dev_id == -1)
-  {
-    fprintf (stderr, "The interface %s was not found\n", dev->iface);
-    return 1;
-  }
-  
-  /* Close the hci socket */
-  (void) close(fd_hci);
-  
-  
-  
-  /* Bind the rfcomm socket to the interface */
-  memset (&rc_addr, 0, sizeof (rc_addr)); 
-  rc_addr.rc_family = AF_BLUETOOTH;
-  rc_addr.rc_bdaddr = *BDADDR_ANY;
-  if (bind_socket (dev->fd_rfcomm, &rc_addr) != 0)
-  {
-    fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
-             dev->iface, strerror (errno));
-    return 1;
-  }
-  
-  /* Register a SDP service */
-  if (register_service (dev, rc_addr.rc_channel) != 0)
-  {
-    fprintf (stderr, "Failed to register a service on interface `%.*s': %s\n", IFNAMSIZ,
-             dev->iface, strerror (errno));
-    return 1;
-  }
-  
-  /* Switch socket in listening mode */
-  if (listen (dev->fd_rfcomm, 5) == -1) //FIXME: probably we need a bigger number
-  {
-    fprintf (stderr, "Failed to listen on socket for interface `%.*s': %s\n", IFNAMSIZ,
-             dev->iface, strerror (errno));
-    return 1;
-  }
-  
-  
+
+    /* Check if the interface was not found */
+    if (-1 == dev_id)
+    {
+      fprintf (stderr,
+               "The interface %s was not found\n",
+               dev->iface);
+      (void) close (fd_hci);
+      return 1;
+    }
+
+    /* Close the hci socket */
+    (void) close(fd_hci);
+
+
+
+    /* Bind the rfcomm socket to the interface */
+    memset (&rc_addr, 0, sizeof (rc_addr));
+    rc_addr.rc_family = AF_BLUETOOTH;
+    rc_addr.rc_bdaddr = *BDADDR_ANY;
+
+    if (bind_socket (dev->fd_rfcomm, &rc_addr) != 0)
+    {
+      fprintf (stderr,
+               "Failed to bind interface `%.*s': %s\n",
+               IFNAMSIZ,
+               dev->iface,
+               strerror (errno));
+      return 1;
+    }
+
+    /* Register a SDP service */
+    if (register_service (dev, rc_addr.rc_channel) != 0)
+    {
+      fprintf (stderr,
+               "Failed to register a service on interface `%.*s': %s\n",
+               IFNAMSIZ,
+               dev->iface, strerror (errno));
+      return 1;
+    }
+
+    /* Switch socket in listening mode */
+    if (listen (dev->fd_rfcomm, 5) == -1) //FIXME: probably we need a bigger number
+    {
+      fprintf (stderr, "Failed to listen on socket for interface `%.*s': %s\n", IFNAMSIZ,
+               dev->iface, strerror (errno));
+      return 1;
+    }
+
+  #endif
+
   return 0;
 }
 
@@ -974,37 +1303,44 @@ mac_set (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
          const struct HardwareInfos *dev)
 {
   taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
-  taIeeeHeader->addr2 = dev->pl_mac;
   taIeeeHeader->addr3 = mac_bssid_gnunet;
-}
 
-/**
- * Test if the given interface name really corresponds to a bluetooth
- * device.
- *
- * @param iface name of the interface
- * @return 0 on success, 1 on error
- **** similar with the one from gnunet-helper-transport-wlan.c ****
- */
-static int
-test_bluetooth_interface (const char *iface)
-{
-  char strbuf[512];
-  struct stat sbuf;
-  int ret;
+  #ifdef MINGW
+    GNUNET_memcpy (&taIeeeHeader->addr2, &dev->pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
+  #else
+    taIeeeHeader->addr2 = dev->pl_mac;
+  #endif
+}
 
-  ret = snprintf (strbuf, sizeof (strbuf), 
-                 "/sys/class/bluetooth/%s/subsystem",
-                 iface);
-  if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
+#ifdef LINUX
+  /**
+   * Test if the given interface name really corresponds to a bluetooth
+   * device.
+   *
+   * @param iface name of the interface
+   * @return 0 on success, 1 on error
+   **** similar with the one from gnunet-helper-transport-wlan.c ****
+   */
+  static int
+  test_bluetooth_interface (const char *iface)
   {
-    fprintf (stderr, 
-            "Did not find 802.15.1 interface `%s'. Exiting.\n", 
-            iface);
-    exit (1);
+    char strbuf[512];
+    struct stat sbuf;
+    int ret;
+
+    ret = snprintf (strbuf, sizeof (strbuf),
+        "/sys/class/bluetooth/%s/subsystem",
+        iface);
+    if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
+    {
+      fprintf (stderr,
+         "Did not find 802.15.1 interface `%s'. Exiting.\n",
+         iface);
+      exit (1);
+    }
+    return 0;
   }
-  return 0;
-}
+#endif
 
 /**
  * Test incoming packets mac for being our own.
@@ -1035,8 +1371,8 @@ mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
 
 
 /**
- * Process data from the stdin.  Takes the message forces the sender MAC to be correct
- * and puts it into our buffer for transmission to the kernel. (the other device).
+ * Process data from the stdin. Takes the message, forces the sender MAC to be correct
+ * and puts it into our buffer for transmission to the receiver.
  *
  * @param cls pointer to the device struct ('struct HardwareInfos*')
  * @param hdr pointer to the start of the packet
@@ -1053,13 +1389,13 @@ stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
 
   sendsize = ntohs (hdr->size);
   if ( (sendsize <
-       sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
-       (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) ) 
+  sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
+       (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) )
   {
     fprintf (stderr, "Received malformed message\n");
     exit (1);
   }
-  sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) - 
+  sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) -
                sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
   if (MAXLINE < sendsize)
   {
@@ -1067,706 +1403,1100 @@ stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
     exit (1);
   }
   header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
-  memcpy (&write_pout.buf, &header->frame, sendsize);
+  GNUNET_memcpy (&write_pout.buf, &header->frame, sendsize);
   blueheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf;
 
   /* payload contains MAC address, but we don't trust it, so we'll
   * overwrite it with OUR MAC address to prevent mischief */
   mac_set (blueheader, dev);
-  memcpy (&blueheader->addr1, &header->frame.addr1, 
-          sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)); //FIXME is this correct?
+  GNUNET_memcpy (&blueheader->addr1, &header->frame.addr1,
+          sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
   write_pout.size = sendsize;
 }
 
-/**
- * Broadcast a HELLO message for peer discovery
- * @param dev pointer to the device struct
- * @param dev pointer to the socket which was added to the set
- * @return 0 on success
- */
-static int 
-send_broadcast (struct HardwareInfos *dev, int *sendsocket) 
-{
-  int new_device = 0;
-  int loops = 0;
-
- search_for_devices:
-  if ((neighbours.size == neighbours.pos && new_device == 1) || neighbours.size == 0) 
-  { 
- inquiry_devices:   //skip the conditions and force a inquiry for new devices
-    {
-    /** 
-     * It means that I sent HELLO messages to all the devices from the list and I should search 
-     * for another ones or that this is the first time when I do a search.
-     */
-    inquiry_info *devices = NULL;
-    int i, responses, max_responses = MAX_PORTS;
-
-    /* sanity checks */
-    if (neighbours.size >= MAX_PORTS)
-    {
-      fprintf (stderr, "%.*s reached the top limit for the discovarable devices\n", IFNAMSIZ, dev->iface);
-      return 2;
-    }
+#ifdef LINUX
+  /**
+   * Broadcast a HELLO message for peer discovery
+   *
+   * @param dev pointer to the device struct
+   * @param dev pointer to the socket which was added to the set
+   * @return 0 on success
+   */
+  static int
+  send_broadcast (struct HardwareInfos *dev, int *sendsocket)
+  {
+    int new_device = 0;
+    int loops = 0;
 
-    /* Get the device id */
-    if (neighbours.dev_id == -1)
-    {
-      char addr[19] = { 0 }; //the device MAC address
-      
-      ba2str ((bdaddr_t *) &dev->pl_mac, addr); 
-      neighbours.dev_id = hci_devid (addr);
-      if (neighbours.dev_id < 0)
-      { 
-        fprintf (stderr, "Failed to get the device id for interface %.*s : %s\n", IFNAMSIZ,
-                dev->iface, strerror (errno));
-        return 1;
-      }
-    }
-  
-    devices = malloc (max_responses * sizeof (inquiry_info));
-    if (devices == NULL)
-    {
-      fprintf (stderr, "Failed to allocate memory for inquiry info list on interface %.*s\n", IFNAMSIZ,
-              dev->iface);
-      return 1;
-    }
-           
-    responses = hci_inquiry (neighbours.dev_id, 8, max_responses, NULL, &devices, IREQ_CACHE_FLUSH);
-    if (responses < 0)
-    {
-      fprintf (stderr, "Failed to inquiry on interface %.*s\n", IFNAMSIZ, dev->iface);
-      return 1;
-    }
-   
-    fprintf (stderr, "LOG : Found %d devices\n", responses); //FIXME delete it after debugging stage
-    
-    if (responses == 0)
-    {
-      fprintf (stderr, "LOG : No devices discoverable\n");
-      return 1;
-    }
-    
-    for (i = 0; i < responses; i++) 
+   search_for_devices:
+    if ((neighbours.size == neighbours.pos && new_device == 1) || neighbours.size == 0)
     {
-      int j;
-      int found = 0;
+   inquiry_devices:   //skip the conditions and force a inquiry for new devices
+      {
+      /**
+       * It means that I sent HELLO messages to all the devices from the list and I should search
+       * for new ones or that this is the first time when I do a search.
+       */
+      inquiry_info *devices = NULL;
+      int i, responses, max_responses = MAX_PORTS;
 
-      /* sanity check */
-      if (i >= MAX_PORTS)
+      /* sanity checks */
+      if (neighbours.size >= MAX_PORTS)
       {
-        fprintf (stderr, "%.*s reached the top limit for the discoverable devices (after inquiry)\n", IFNAMSIZ,
-                dev->iface);
+        fprintf (stderr, "%.*s reached the top limit for the discovarable devices\n", IFNAMSIZ, dev->iface);
         return 2;
       }
-      
-      /* Search if the address already exists on the list */
-      for (j = 0; j < neighbours.size; j++)
+
+      /* Get the device id */
+      if (neighbours.dev_id == -1)
       {
-        if (memcmp (&(devices + i)->bdaddr, &(neighbours.devices[j]), sizeof (bdaddr_t)) == 0) 
+        char addr[19] = { 0 }; //the device MAC address
+
+        ba2str ((bdaddr_t *) &dev->pl_mac, addr);
+        neighbours.dev_id = hci_devid (addr);
+        if (neighbours.dev_id < 0)
         {
-          found = 1;
-          fprintf (stderr, "LOG : the device already exists on the list\n"); //FIXME debugging message
-          break;
+          fprintf (stderr, "Failed to get the device id for interface %.*s : %s\n", IFNAMSIZ,
+                  dev->iface, strerror (errno));
+          return 1;
         }
       }
 
-      if (found == 0)
+      devices = malloc (max_responses * sizeof (inquiry_info));
+      if (devices == NULL)
       {
-        char addr[19] = { 0 };
+        fprintf (stderr, "Failed to allocate memory for inquiry info list on interface %.*s\n", IFNAMSIZ,
+                dev->iface);
+        return 1;
+      }
 
-        ba2str (&(devices +i)->bdaddr, addr);
-        fprintf (stderr, "LOG : %s was added to the list\n", addr); //FIXME debugging message
-        memcpy (&(neighbours.devices[neighbours.size++]), &(devices + i)->bdaddr, sizeof (bdaddr_t));
+      responses = hci_inquiry (neighbours.dev_id, 8, max_responses, NULL, &devices, IREQ_CACHE_FLUSH);
+      if (responses < 0)
+      {
+        fprintf (stderr, "Failed to inquiry on interface %.*s\n", IFNAMSIZ, dev->iface);
+        return 1;
       }
-    }   
-       
-    free (devices);
-    }
-  }
-  
-  int connection_successful = 0;
-  struct sockaddr_rc addr_rc = { 0 };
-  int errno_copy = 0;
-  addr_rc.rc_family = AF_BLUETOOTH;
 
-  /* Try to connect to a new device from the list */
-  while (neighbours.pos < neighbours.size)
-  {
-    /* Check if we are connected to this device */
-    if (neighbours.fds[neighbours.pos] == -1)
-    {
+      fprintf (stderr, "LOG : Found %d devices\n", responses); //FIXME delete it after debugging stage
 
-      memset (&addr_rc.rc_bdaddr, 0, sizeof (addr_rc.rc_bdaddr));
-      memcpy (&addr_rc.rc_bdaddr, &(neighbours.devices[neighbours.pos]), sizeof (addr_rc.rc_bdaddr));
-    
-      addr_rc.rc_channel = get_channel (dev, addr_rc.rc_bdaddr);
-    
-      *sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
-      //TODO adauga un label aici si intoarcete de cateva ori daca nu reuseste
-      if (connect (*sendsocket, (struct sockaddr *)&addr_rc, sizeof (addr_rc)) == 0)
+      if (responses == 0)
       {
-        neighbours.fds[neighbours.pos++] = *sendsocket;
-        connection_successful = 1;
-        char addr[19] = { 0 };
-        ba2str (&(neighbours.devices[neighbours.pos - 1]), addr);
-        fprintf (stderr, "LOG : Connected to %s\n", addr);
-
-        break;
+        fprintf (stderr, "LOG : No devices discoverable\n");
+        return 1;
       }
-      else
+
+      for (i = 0; i < responses; i++)
       {
-        char addr[19] = { 0 };
-        errno_copy = errno;  //Save a copy for later
-        ba2str (&(neighbours.devices[neighbours.pos]), addr);
-        fprintf (stderr, "LOG : Couldn't connect on device %s, error : %s\n", addr, strerror(errno));
-        if (errno != ECONNREFUSED) //FIXME nu merge!
+        int j;
+        int found = 0;
+
+        /* sanity check */
+        if (i >= MAX_PORTS)
         {
-          fprintf (stderr, "LOG : Removes %d device from the list\n", neighbours.pos);
-          /* Remove the device from the list */
-          memcpy (&neighbours.devices[neighbours.pos], &neighbours.devices[neighbours.size - 1], sizeof (bdaddr_t));
-          memset (&neighbours.devices[neighbours.size - 1], 0, sizeof (bdaddr_t));
-          neighbours.fds[neighbours.pos] = neighbours.fds[neighbours.size - 1];
-          neighbours.fds[neighbours.size - 1] = -1;
-          neighbours.size -= 1;
+          fprintf (stderr, "%.*s reached the top limit for the discoverable devices (after inquiry)\n", IFNAMSIZ,
+                  dev->iface);
+          return 2;
         }
 
-        neighbours.pos += 1;
+        /* Search if the address already exists on the list */
+        for (j = 0; j < neighbours.size; j++)
+        {
+          if (memcmp (&(devices + i)->bdaddr, &(neighbours.devices[j]), sizeof (bdaddr_t)) == 0)
+          {
+            found = 1;
+            fprintf (stderr, "LOG : the device already exists on the list\n"); //FIXME debugging message
+            break;
+          }
+        }
 
-        if (neighbours.pos >= neighbours.size)
-            neighbours.pos = 0;
+        if (found == 0)
+        {
+          char addr[19] = { 0 };
 
-        loops += 1;
+          ba2str (&(devices +i)->bdaddr, addr);
+          fprintf (stderr, "LOG : %s was added to the list\n", addr); //FIXME debugging message
+          GNUNET_memcpy (&(neighbours.devices[neighbours.size++]), &(devices + i)->bdaddr, sizeof (bdaddr_t));
+        }
+      }
 
-        if (loops == MAX_LOOPS) //don't get stuck trying to connect to one device
-          return 1;
+      free (devices);
       }
     }
-    else
+
+    int connection_successful = 0;
+    struct sockaddr_rc addr_rc = { 0 };
+    int errno_copy = 0;
+    addr_rc.rc_family = AF_BLUETOOTH;
+
+    /* Try to connect to a new device from the list */
+    while (neighbours.pos < neighbours.size)
     {
-      fprintf (stderr, "LOG : Search for a new device\n"); //FIXME debugging message
-      neighbours.pos += 1;
+      /* Check if we are already connected to this device */
+      if (neighbours.fds[neighbours.pos] == -1)
+      {
+
+        memset (&addr_rc.rc_bdaddr, 0, sizeof (addr_rc.rc_bdaddr));
+        GNUNET_memcpy (&addr_rc.rc_bdaddr, &(neighbours.devices[neighbours.pos]), sizeof (addr_rc.rc_bdaddr));
+
+        addr_rc.rc_channel = get_channel (dev, addr_rc.rc_bdaddr);
+
+        *sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
+        if ( (-1 < *sendsocket) &&
+             (0 == connect (*sendsocket,
+                            (struct sockaddr *) &addr_rc,
+                            sizeof (addr_rc))) )
+        {
+          neighbours.fds[neighbours.pos++] = *sendsocket;
+          connection_successful = 1;
+          char addr[19] = { 0 };
+          ba2str (&(neighbours.devices[neighbours.pos - 1]), addr);
+          fprintf (stderr, "LOG : Connected to %s\n", addr);
+          break;
+        }
+        else
+        {
+          char addr[19] = { 0 };
+          errno_copy = errno;  //Save a copy for later
+
+          if (-1 != *sendsocket)
+          {
+            (void) close (*sendsocket);
+            *sendsocket = -1;
+          }
+          ba2str (&(neighbours.devices[neighbours.pos]), addr);
+          fprintf (stderr,
+                   "LOG : Couldn't connect on device %s, error : %s\n",
+                   addr,
+                   strerror (errno));
+          if (errno != ECONNREFUSED) //FIXME be sure that this works
+          {
+            fprintf (stderr, "LOG : Removes %d device from the list\n", neighbours.pos);
+            /* Remove the device from the list */
+            GNUNET_memcpy (&neighbours.devices[neighbours.pos], &neighbours.devices[neighbours.size - 1], sizeof (bdaddr_t));
+            memset (&neighbours.devices[neighbours.size - 1], 0, sizeof (bdaddr_t));
+            neighbours.fds[neighbours.pos] = neighbours.fds[neighbours.size - 1];
+            neighbours.fds[neighbours.size - 1] = -1;
+            neighbours.size -= 1;
+          }
+
+          neighbours.pos += 1;
+
+          if (neighbours.pos >= neighbours.size)
+              neighbours.pos = 0;
+
+          loops += 1;
+
+          if (loops == MAX_LOOPS) //don't get stuck trying to connect to one device
+            return 1;
+        }
+      }
+      else
+      {
+        fprintf (stderr, "LOG : Search for a new device\n"); //FIXME debugging message
+        neighbours.pos += 1;
+      }
     }
-  }
-  
-  /* Cycle on the list */
-  if (neighbours.pos == neighbours.size)
-  {
-    neighbours.pos = 0;
-    searching_devices_count += 1;
 
-    if (searching_devices_count == MAX_LOOPS)
+    /* Cycle on the list */
+    if (neighbours.pos == neighbours.size)
     {
-      fprintf (stderr, "LOG : Force to inquiry for new devices\n");
-      searching_devices_count = 0;
-      goto inquiry_devices;
+      neighbours.pos = 0;
+      searching_devices_count += 1;
+
+      if (searching_devices_count == MAX_LOOPS)
+      {
+        fprintf (stderr, "LOG : Force to inquiry for new devices\n");
+        searching_devices_count = 0;
+        goto inquiry_devices;
+      }
     }
-  }
- /* If a new device wasn't found, search an old one */
-  if (connection_successful == 0) 
-  {
-    int loop_check = neighbours.pos;
-    while (neighbours.fds[neighbours.pos] == -1)
+   /* If a new device wasn't found, search an old one */
+    if (connection_successful == 0)
     {
-      if (neighbours.pos == neighbours.size)
-        neighbours.pos = 0;
-      
-      if (neighbours.pos == loop_check)
+      int loop_check = neighbours.pos;
+      while (neighbours.fds[neighbours.pos] == -1)
       {
-        if (errno_copy == ECONNREFUSED)
-        {
-          fprintf (stderr, "LOG : No device found. Go back and search again\n"); //FIXME debugging message
-          new_device = 1;
-          loops += 1;
-          goto search_for_devices;
-        }
-        else
+        if (neighbours.pos == neighbours.size)
+          neighbours.pos = 0;
+
+        if (neighbours.pos == loop_check)
         {
-          return 1; // Skip the broadcast message
+          if (errno_copy == ECONNREFUSED)
+          {
+            fprintf (stderr, "LOG : No device found. Go back and search again\n"); //FIXME debugging message
+            new_device = 1;
+            loops += 1;
+            goto search_for_devices;
+          }
+          else
+          {
+            return 1; // Skip the broadcast message
+          }
         }
+
+        neighbours.pos += 1;
       }
 
-      neighbours.pos += 1;
+      *sendsocket = neighbours.fds[neighbours.pos++];
     }
 
-    *sendsocket = neighbours.fds[neighbours.pos++];
+    return 0;
   }
-
-  return 0;
-}
+#endif
 
 /**
  * Main function of the helper.  This code accesses a bluetooth interface
- * forwards traffic in both directions between the bluetooth interface and 
- * stdin/stdout of this process.  Error messages are written to stdout.
+ * forwards traffic in both directions between the bluetooth interface and
+ * stdin/stdout of this process.  Error messages are written to stderr.
  *
  * @param argc number of arguments, must be 2
  * @param argv arguments only argument is the name of the interface (i.e. 'hci0')
  * @return 0 on success (never happens, as we don't return unless aborted), 1 on error
  *
- **** same as the one from gnunet-helper-transport-wlan.c ****
+ **** similar to gnunet-helper-transport-wlan.c ****
  */
 int
 main (int argc, char *argv[])
-{   
-  struct HardwareInfos dev;
-  char readbuf[MAXLINE];
-  int maxfd;
-  fd_set rfds;
-  fd_set wfds;
-  int stdin_open;
-  struct MessageStreamTokenizer *stdin_mst;
-  int raw_eno, i;
-  uid_t uid;
-  int crt_rfds = 0, rfds_list[MAX_PORTS];
-  int broadcast, sendsocket;
-  /* Assert privs so we can modify the firewall rules! */
-  uid = getuid ();
+{
+#ifdef LINUX
+    struct HardwareInfos dev;
+    char readbuf[MAXLINE];
+    int maxfd;
+    fd_set rfds;
+    fd_set wfds;
+    int stdin_open;
+    struct MessageStreamTokenizer *stdin_mst;
+    int raw_eno, i;
+    int crt_rfds = 0, rfds_list[MAX_PORTS];
+    int broadcast, sendsocket;
+
+    /* Assert privs so we can modify the firewall rules! */
+    {
 #ifdef HAVE_SETRESUID
-  if (0 != setresuid (uid, 0, 0))
-  {
-    fprintf (stderr, "Failed to setresuid to root: %s\n", strerror (errno));
-    return 254;
-  }
+      uid_t uid = getuid ();
+
+      if (0 != setresuid (uid, 0, 0))
+      {
+       fprintf (stderr, 
+                "Failed to setresuid to root: %s\n",
+                strerror (errno));
+       return 254;
+      }
 #else
-  if (0 != seteuid (0)) 
-  {
-    fprintf (stderr, "Failed to seteuid back to root: %s\n", strerror (errno));
-    return 254;
-  }
+      if (0 != seteuid (0))
+      {
+       fprintf (stderr, 
+                "Failed to seteuid back to root: %s\n", strerror (errno));
+       return 254;
+      }
 #endif
+    }
 
-  /* Make use of SGID capabilities on POSIX */
-  memset (&dev, 0, sizeof (dev));
-  dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
-  raw_eno = errno; /* remember for later */
-
-  /* Now that we've dropped root rights, we can do error checking */
-  if (2 != argc)
-  {
-    fprintf (stderr, "You must specify the name of the interface as the first \
-                      and only argument to this program.\n");
-    if (-1 != dev.fd_rfcomm)
-      (void) close (dev.fd_rfcomm);
-    return 1;
-  }
-
-  if (-1 == dev.fd_rfcomm)
-  {
-    fprintf (stderr, "Failed to create a HCI socket: %s\n", strerror (raw_eno));
-    return 1;
-  }
-  if (dev.fd_rfcomm >= FD_SETSIZE)
-  {
-    fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
-             dev.fd_rfcomm, FD_SETSIZE);
-    (void) close (dev.fd_rfcomm);
-    return 1;
-  }
-  if (0 != test_bluetooth_interface (argv[1]))
-  {
-    (void) close (dev.fd_rfcomm);
-    return 1;
-  }
-  strncpy (dev.iface, argv[1], IFNAMSIZ);
-  if (0 != open_device (&dev))
-  {
-    (void) close (dev.fd_rfcomm);
-    return 1;
-  }
+    /* Make use of SGID capabilities on POSIX */
+    memset (&dev, 0, sizeof (dev));
+    dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
+    raw_eno = errno; /* remember for later */
 
-  /* Drop privs */
-  {
-    uid_t uid = getuid ();
-#ifdef HAVE_SETRESUID
-    if (0 != setresuid (uid, uid, uid))
+    /* Now that we've dropped root rights, we can do error checking */
+    if (2 != argc)
     {
-      fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
+      fprintf (stderr, "You must specify the name of the interface as the first \
+                        and only argument to this program.\n");
       if (-1 != dev.fd_rfcomm)
-       (void) close (dev.fd_rfcomm);
+        (void) close (dev.fd_rfcomm);
       return 1;
     }
-#else
-    if (0 != (setuid (uid) | seteuid (uid)))
+
+    if (-1 == dev.fd_rfcomm)
     {
-      fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
-      if (-1 != dev.fd_rfcomm)
-       (void) close (dev.fd_rfcomm);
+      fprintf (stderr, "Failed to create a RFCOMM socket: %s\n", strerror (raw_eno));
       return 1;
     }
-#endif
-  }
-
- /* Send MAC address of the bluetooth interface to STDOUT first */
-  {
-    struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
-
-    macmsg.hdr.size = htons (sizeof (macmsg));
-    macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
-    memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
-    memcpy (write_std.buf, &macmsg, sizeof (macmsg));
-    write_std.size = sizeof (macmsg);
-  }
-    
-  stdin_mst = mst_create (&stdin_send_hw, &dev);  
-  stdin_open = 1;
-  
-  fprintf (stderr, "\n-----------------------------------------------\n      Check if the program exits\n-----------------------------------------------\n");
- /**
-  * TODO : When a connection fails I should ignore only the CONTROL messages. 
-  * For DATA messages I should retry to send the message until it doesn't fail
-  * Also I should make the time out of a mac endpoint smaller and check if the rate 
-  * from get_wlan_header (plugin_transport_bluetooth.c) is correct.
-  */ 
- while (1)
-  {
-    maxfd = -1;
-    broadcast = 0;
-    sendsocket = -1;
-
-    FD_ZERO (&rfds);
-    if ((0 == write_pout.size) && (1 == stdin_open))
+    if (dev.fd_rfcomm >= FD_SETSIZE)
     {
-      FD_SET (STDIN_FILENO, &rfds);
-      maxfd = MAX (maxfd, STDIN_FILENO);
+      fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
+               dev.fd_rfcomm, FD_SETSIZE);
+      (void) close (dev.fd_rfcomm);
+      return 1;
     }
-    if (0 == write_std.size)
+    if (0 != test_bluetooth_interface (argv[1]))
     {
-      FD_SET (dev.fd_rfcomm, &rfds);
-      maxfd = MAX (maxfd, dev.fd_rfcomm);
+      (void) close (dev.fd_rfcomm);
+      return 1;
     }
-
-    for (i = 0; i < crt_rfds; i++)  // it can receive messages from multiple devices 
+    strncpy (dev.iface, argv[1], IFNAMSIZ);
+    if (0 != open_device (&dev))
     {
-      FD_SET (rfds_list[i], &rfds);
-      maxfd = MAX (maxfd, rfds_list[i]);
+      (void) close (dev.fd_rfcomm);
+      return 1;
     }
-    FD_ZERO (&wfds);
-    if (0 < write_std.size)
+
+    /* Drop privs */
     {
-      FD_SET (STDOUT_FILENO, &wfds);
-      maxfd = MAX (maxfd, STDOUT_FILENO);
-    }
-    if (0 < write_pout.size) //it can send messages only to one device per loop
-    {    
-      struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *frame;
-      /* Get the destination address */
-      frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) write_pout.buf;
-      
-      if (memcmp (&frame->addr1, &dev.pl_mac, 
-                  sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
+      uid_t uid = getuid ();
+  #ifdef HAVE_SETRESUID
+      if (0 != setresuid (uid, uid, uid))
       {
-        broadcast = 1;
-        memset (&write_pout, 0, sizeof (write_pout)); //clear the buffer 
-      } 
-      else if (memcmp (&frame->addr1, &broadcast_address, 
-                sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
+        fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
+        if (-1 != dev.fd_rfcomm)
+    (void) close (dev.fd_rfcomm);
+        return 1;
+      }
+  #else
+      if (0 != (setuid (uid) | seteuid (uid)))
       {
-        fprintf (stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n", dev.iface, neighbours.pos, neighbours.size); //FIXME: debugging message
-        // broadcast = 1; // IF I HAVE A BROADCAST MESSAGE I skip.
-        // memset (&write_pout, 0, sizeof (write_pout));
-       
-        if (send_broadcast(&dev, &sendsocket) != 0) //if the searching wasn't successful don't get stuck on the select stage
-        {
-          broadcast = 1;
-          memset (&write_pout, 0, sizeof (write_pout)); //remove the message
-          fprintf (stderr, "LOG : Skip the broadcast message (pos %d, size %d)\n", neighbours.pos, neighbours.size);
-        }
-        else
+        fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
+        if (-1 != dev.fd_rfcomm)
+    (void) close (dev.fd_rfcomm);
+        return 1;
+      }
+  #endif
+    }
+
+   /* Send MAC address of the bluetooth interface to STDOUT first */
+    {
+      struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
+
+      macmsg.hdr.size = htons (sizeof (macmsg));
+      macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
+      GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
+      GNUNET_memcpy (write_std.buf, &macmsg, sizeof (macmsg));
+      write_std.size = sizeof (macmsg);
+    }
+
+
+    stdin_mst = mst_create (&stdin_send_hw, &dev);
+    stdin_open = 1;
+
+   /**
+    * TODO : I should make the time out of a mac endpoint smaller and check if the rate
+    * from get_wlan_header (plugin_transport_bluetooth.c) is correct.
+    */
+   while (1)
+    {
+      maxfd = -1;
+      broadcast = 0;
+      sendsocket = -1;
+
+      FD_ZERO (&rfds);
+      if ((0 == write_pout.size) && (1 == stdin_open))
+      {
+        FD_SET (STDIN_FILENO, &rfds);
+        maxfd = MAX (maxfd, STDIN_FILENO);
+      }
+      if (0 == write_std.size)
+      {
+        FD_SET (dev.fd_rfcomm, &rfds);
+        maxfd = MAX (maxfd, dev.fd_rfcomm);
+      }
+
+      for (i = 0; i < crt_rfds; i++)  // it can receive messages from multiple devices
+      {
+        FD_SET (rfds_list[i], &rfds);
+        maxfd = MAX (maxfd, rfds_list[i]);
+      }
+      FD_ZERO (&wfds);
+      if (0 < write_std.size)
+      {
+        FD_SET (STDOUT_FILENO, &wfds);
+        maxfd = MAX (maxfd, STDOUT_FILENO);
+      }
+      if (0 < write_pout.size) //it can send messages only to one device per loop
+      {
+        struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *frame;
+        /* Get the destination address */
+        frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) write_pout.buf;
+
+        if (memcmp (&frame->addr1, &dev.pl_mac,
+                    sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
         {
-          FD_SET (sendsocket, &wfds);
-          maxfd = MAX (maxfd, sendsocket);
+          broadcast = 1;
+          memset (&write_pout, 0, sizeof (write_pout)); //clear the buffer
         }
-      } 
-      else 
-      {
-        int found = 0;
-        int pos = 0;
-        /* Search if the address already exists on the list */
-        for (i = 0; i < neighbours.size; i++)
+        else if (memcmp (&frame->addr1, &broadcast_address,
+                  sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
         {
-          if (memcmp (&frame->addr1, &(neighbours.devices[i]), sizeof (bdaddr_t)) == 0) 
+          fprintf (stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n", dev.iface, neighbours.pos, neighbours.size); //FIXME: debugging message
+
+          if (send_broadcast(&dev, &sendsocket) != 0) //if the searching wasn't successful don't get stuck on the select stage
           {
-            pos = i;
-            if (neighbours.fds[i] != -1)
-            {
-              found = 1;  //save the position where it was found
-              FD_SET (neighbours.fds[i], &wfds);
-              maxfd = MAX (maxfd, neighbours.fds[i]);
-              sendsocket = neighbours.fds[i];
-              fprintf (stderr, "LOG: the address was found in the list\n");
-              break;
-            }
+            broadcast = 1;
+            memset (&write_pout, 0, sizeof (write_pout)); //remove the message
+            fprintf (stderr, "LOG : Skipping the broadcast message (pos %d, size %d)\n", neighbours.pos, neighbours.size);
+          }
+          else
+          {
+            FD_SET (sendsocket, &wfds);
+            maxfd = MAX (maxfd, sendsocket);
           }
         }
-        if (found == 0)
+        else
         {
-          int status;
-          struct sockaddr_rc addr = { 0 };
-        
-          fprintf (stderr, "LOG : %s has a new message for %.2X:%.2X:%.2X:%.2X:%.2X:%.2X which isn't on the broadcast list\n", dev.iface, 
-                  frame->addr1.mac[5], frame->addr1.mac[4], frame->addr1.mac[3],
-                  frame->addr1.mac[2], frame->addr1.mac[1], frame->addr1.mac[0]); //FIXME: debugging message      
-          
-          sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
-          
-          if (sendsocket < 0) 
+          int found = 0;
+          int pos = 0;
+          /* Search if the address already exists on the list */
+          for (i = 0; i < neighbours.size; i++)
           {
-            fprintf (stderr, "Failed to create a RFCOMM socket (sending stage): %s\n", 
-                    strerror (errno));
-            return -1;
-          }
-                                  
-          memcpy (&addr.rc_bdaddr, &frame->addr1, sizeof (bdaddr_t));
-          addr.rc_family = AF_BLUETOOTH;
-          addr.rc_channel = get_channel (&dev, addr.rc_bdaddr);
-          
-          int tries = 0;
-          connect_retry:
-          status = connect (sendsocket, (struct sockaddr *) &addr, sizeof (addr));
-               if (0 != status && errno != EAGAIN)
-               {
-            if (errno == ECONNREFUSED && tries < 2)
+            if (memcmp (&frame->addr1, &(neighbours.devices[i]), sizeof (bdaddr_t)) == 0)
             {
-              fprintf (stderr, "LOG : %.*s failed to connect. Trying again!\n", IFNAMSIZ, dev.iface);
-              tries++;
-              goto connect_retry;
-            }
-            else if (errno == EBADF)
-            {
-              fprintf (stderr, "LOG : %s failed to connect : %s. Skip it!\n", dev.iface, strerror (errno));
-              memset (&write_pout, 0, sizeof (write_pout));
-              broadcast = 1;
+              pos = i;
+              if (neighbours.fds[i] != -1)
+              {
+                found = 1;  //save the position where it was found
+                FD_SET (neighbours.fds[i], &wfds);
+                maxfd = MAX (maxfd, neighbours.fds[i]);
+                sendsocket = neighbours.fds[i];
+                fprintf (stderr, "LOG: the address was found in the list\n");
+                break;
+              }
             }
-            else
+          }
+          if (found == 0)
+          {
+            int status;
+            struct sockaddr_rc addr = { 0 };
+
+            fprintf (stderr, "LOG : %s has a new message for %.2X:%.2X:%.2X:%.2X:%.2X:%.2X which isn't on the broadcast list\n", dev.iface,
+                    frame->addr1.mac[5], frame->addr1.mac[4], frame->addr1.mac[3],
+                    frame->addr1.mac[2], frame->addr1.mac[1], frame->addr1.mac[0]); //FIXME: debugging message
+
+            sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
+
+            if (sendsocket < 0)
             {
-                 fprintf (stderr, "LOG : %s failed to connect : %s. Try again later!\n", dev.iface, strerror (errno));
-                   memset (&write_pout, 0, sizeof (write_pout));
-              broadcast = 1;
+              fprintf (stderr, "Failed to create a RFCOMM socket (sending stage): %s\n",
+                      strerror (errno));
+              return -1;
             }
-                 
-               }
-          else
-          {
-            FD_SET (sendsocket, &wfds);
-            maxfd = MAX (maxfd, sendsocket);
-            fprintf (stderr, "LOG : Connection successful\n");
-            if (pos != 0) // save the socket
+
+            GNUNET_memcpy (&addr.rc_bdaddr, &frame->addr1, sizeof (bdaddr_t));
+            addr.rc_family = AF_BLUETOOTH;
+            addr.rc_channel = get_channel (&dev, addr.rc_bdaddr);
+
+            int tries = 0;
+            connect_retry:
+            status = connect (sendsocket, (struct sockaddr *) &addr, sizeof (addr));
+            if (0 != status && errno != EAGAIN)
             {
-              neighbours.fds[pos] = sendsocket;
+              if (errno == ECONNREFUSED && tries < 2)
+              {
+                fprintf (stderr, "LOG : %.*s failed to connect. Trying again!\n", IFNAMSIZ, dev.iface);
+                tries++;
+                goto connect_retry;
+              }
+              else if (errno == EBADF)
+              {
+                fprintf (stderr, "LOG : %s failed to connect : %s. Skip it!\n", dev.iface, strerror (errno));
+                memset (&write_pout, 0, sizeof (write_pout));
+                broadcast = 1;
+              }
+              else
+              {
+                fprintf (stderr, "LOG : %s failed to connect : %s. Try again later!\n", dev.iface, strerror (errno));
+                memset (&write_pout, 0, sizeof (write_pout));
+                broadcast = 1;
+              }
+
             }
             else
             {
-              /* Add the new device to the discovered devices list */
-              if (neighbours.size < MAX_PORTS)
+              FD_SET (sendsocket, &wfds);
+              maxfd = MAX (maxfd, sendsocket);
+              fprintf (stderr, "LOG : Connection successful\n");
+              if (pos != 0) // save the socket
               {
-                neighbours.fds[neighbours.size] = sendsocket;
-                memcpy (&(neighbours.devices[neighbours.size++]), &addr.rc_bdaddr, sizeof (bdaddr_t));
+                neighbours.fds[pos] = sendsocket;
               }
               else
               {
-                fprintf (stderr, "The top limit for the discovarable devices' list was reached\n");
+                /* Add the new device to the discovered devices list */
+                if (neighbours.size < MAX_PORTS)
+                {
+                  neighbours.fds[neighbours.size] = sendsocket;
+                  GNUNET_memcpy (&(neighbours.devices[neighbours.size++]), &addr.rc_bdaddr, sizeof (bdaddr_t));
+                }
+                else
+                {
+                  fprintf (stderr, "The top limit for the discovarable devices' list was reached\n");
+                }
               }
             }
           }
         }
       }
-    }
 
-    if (broadcast == 0)
-    {
-      /* Select a fd which is ready for action :) */
+      if (broadcast == 0)
       {
-        int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
-        if ((-1 == retval) && (EINTR == errno))
-         continue;
-        if (0 > retval && errno != EBADF)   // we handle BADF errors later
+        /* Select a fd which is ready for action :) */
         {
-         fprintf (stderr, "select failed: %s\n", strerror (errno));
-         break;
+          int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
+          if ((-1 == retval) && (EINTR == errno))
+      continue;
+          if (0 > retval && errno != EBADF)   // we handle BADF errors later
+          {
+      fprintf (stderr, "select failed: %s\n", strerror (errno));
+      break;
+          }
         }
-      }
-      if (FD_ISSET (STDOUT_FILENO , &wfds))
-      {
-        ssize_t ret =
-            write (STDOUT_FILENO, write_std.buf + write_std.pos,
-                   write_std.size - write_std.pos);
-        if (0 > ret)
+        if (FD_ISSET (STDOUT_FILENO , &wfds))
         {
-          fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
-          break;
+          ssize_t ret =
+              write (STDOUT_FILENO, write_std.buf + write_std.pos,
+                     write_std.size - write_std.pos);
+          if (0 > ret)
+          {
+            fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
+            break;
+          }
+          write_std.pos += ret;
+          if (write_std.pos == write_std.size)
+          {
+            write_std.pos = 0;
+            write_std.size = 0;
+          }
+          fprintf (stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); //FIXME: debugging message
+
         }
-        write_std.pos += ret;
-        if (write_std.pos == write_std.size)
+        if (-1 != sendsocket)
         {
-          write_std.pos = 0;
-          write_std.size = 0;
+          if (FD_ISSET (sendsocket , &wfds))
+          {
+            ssize_t ret = write (sendsocket,
+                                 write_pout.buf + write_std.pos,
+                                 write_pout.size - write_pout.pos);
+            if (0 > ret) //FIXME should I first check the error type?
+            {
+              fprintf (stderr, "Failed to write to bluetooth device: %s. Closing the socket!\n",
+                       strerror (errno));
+              for (i = 0; i < neighbours.size; i++)
+              {
+                if (neighbours.fds[i] == sendsocket)
+                {
+                  (void) close(sendsocket);
+                  neighbours.fds[i] = -1;
+                  break;
+                }
+              }
+              /* Remove the message */
+              memset (&write_pout.buf + write_std.pos, 0, (write_pout.size - write_pout.pos));
+              write_pout.pos = 0 ;
+              write_pout.size = 0;
+            }
+            else
+            {
+              write_pout.pos += ret;
+              if ((write_pout.pos != write_pout.size) && (0 != ret))
+              {
+                /* We should not get partial sends with packet-oriented devices... */
+                fprintf (stderr, "Write error, partial send: %u/%u\n",
+                        (unsigned int) write_pout.pos,
+                        (unsigned int) write_pout.size);
+                break;
+              }
+
+              if (write_pout.pos == write_pout.size)
+              {
+                write_pout.pos = 0;
+                write_pout.size = 0;
+              }
+              fprintf (stderr, "LOG : %s sends a message to a DEVICE\n", dev.iface); //FIXME: debugging message
+            }
+          }
         }
-        fprintf (stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); //FIXME: debugging message
-        
-      } 
-      if (sendsocket != -1)
-      {
-        if (FD_ISSET (sendsocket , &wfds))
+        for (i = 0; i <= maxfd; i++)
         {
-          ssize_t ret =
-      write (sendsocket, write_pout.buf + write_std.pos, 
-             write_pout.size - write_pout.pos);
-          if (0 > ret) //FIXME should I check first the error type?
+          if (FD_ISSET (i, &rfds))
           {
-            fprintf (stderr, "Failed to write to bluetooth device: %s. Closing the socket!\n",
-                     strerror (errno));         
-            for (i = 0; i < neighbours.size; i++)
+            if (i == STDIN_FILENO)
             {
-              if (neighbours.fds[i] == sendsocket)
+              ssize_t ret =
+          read (i, readbuf, sizeof (readbuf));
+              if (0 > ret)
               {
-                (void) close(sendsocket);
-                neighbours.fds[i] = -1;
+                fprintf (stderr,
+                        "Read error from STDIN: %s\n",
+                        strerror (errno));
+                break;
+              }
+              if (0 == ret)
+              {
+                /* stop reading... */
+                stdin_open = 0;
+              }
+              else
+              {
+                mst_receive (stdin_mst, readbuf, ret);
+                fprintf (stderr, "LOG : %s receives a message from STDIN\n", dev.iface); //FIXME: debugging message
+              }
+            }
+            else if (i == dev.fd_rfcomm)
+            {
+              int readsocket;
+              struct sockaddr_rc addr = { 0 };
+              unsigned int opt = sizeof (addr);
+
+              readsocket = accept (dev.fd_rfcomm, (struct sockaddr *) &addr, &opt);
+              fprintf(stderr, "LOG : %s accepts a message\n", dev.iface); //FIXME: debugging message
+              if (readsocket == -1)
+              {
+                fprintf (stderr, "Failed to accept a connection on interface: %.*s\n", IFNAMSIZ,
+                    strerror (errno));
+                break;
+              }
+              else
+              {
+                FD_SET (readsocket, &rfds);
+                maxfd = MAX (maxfd, readsocket);
+
+                if (crt_rfds < MAX_PORTS)
+                  rfds_list[crt_rfds++] = readsocket;
+                else
+                {
+                  fprintf (stderr, "The limit for the read file descriptors list was \
+                                  reached\n");
+                  break;
+                }
+              }
+
+            }
+            else
+            {
+              struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
+              ssize_t ret;
+              fprintf (stderr, "LOG : %s reads something from the socket\n", dev.iface);//FIXME : debugging message
+              rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
+              ret =
+                  read_from_the_socket ((void *)&i, (unsigned char *) &rrm->frame,
+                              sizeof (write_std.buf)
+                  - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
+                  + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
+                  rrm);
+              if (0 >= ret)
+              {
+                int j;
+                FD_CLR (i, &rfds);
+                close (i);
+                 /* Remove the socket from the list */
+                for (j = 0; j < crt_rfds; j++)
+                {
+                  if (rfds_list[j] == i)
+                  {
+                    rfds_list[j] ^= rfds_list[crt_rfds - 1];
+                    rfds_list[crt_rfds - 1] ^= rfds_list[j];
+                    rfds_list[j] ^= rfds_list[crt_rfds - 1];
+                    crt_rfds -= 1;
+                    break;
+                  }
+                }
+
+                fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
                 break;
               }
+              if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
+              {
+                write_std.size = ret
+            + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
+            - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
+                rrm->header.size = htons (write_std.size);
+                rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
+              }
             }
-            /* Remove the message */
-            memset (&write_pout.buf + write_std.pos, 0, (write_pout.size - write_pout.pos)); 
-            write_pout.pos = 0 ;
+          }
+        }
+      }
+    }
+    /* Error handling, try to clean up a bit at least */
+    mst_destroy (stdin_mst);
+    stdin_mst = NULL;
+    sdp_close (dev.session);
+    (void) close (dev.fd_rfcomm);
+    if (-1 != sendsocket)
+      (void) close (sendsocket);
+
+    for (i = 0; i < crt_rfds; i++)
+      (void) close (rfds_list[i]);
+
+    for (i = 0; i < neighbours.size; i++)
+      (void) close (neighbours.fds[i]);
+  #else
+    struct HardwareInfos dev;
+    struct GNUNET_NETWORK_Handle *sendsocket;
+    struct GNUNET_NETWORK_FDSet *rfds;
+    struct GNUNET_NETWORK_FDSet *wfds;
+    struct GNUNET_NETWORK_Handle *rfds_list[MAX_PORTS];
+    char readbuf[MAXLINE] = { 0 };
+    SOCKADDR_BTH acc_addr = { 0 };
+    int addr_len = sizeof (SOCKADDR_BTH);
+    int broadcast, i, stdin_open, crt_rfds = 0;
+    HANDLE stdin_handle = GetStdHandle (STD_INPUT_HANDLE);
+    HANDLE stdout_handle = GetStdHandle (STD_OUTPUT_HANDLE);
+    struct MessageStreamTokenizer *stdin_mst;
+
+    /* check the handles */
+    if (stdin_handle == INVALID_HANDLE_VALUE)
+    {
+      fprintf (stderr, "Failed to get the stdin handle\n");
+      ExitProcess (2);
+    }
+
+    if (stdout_handle == INVALID_HANDLE_VALUE)
+    {
+      fprintf (stderr, "Failed to get the stdout handle\n");
+      ExitProcess (2);
+    }
+
+    /* initialize windows sockets */
+    initialize_windows_sockets();
+
+    // /* test bluetooth socket family support */ --> it return false because the GNUNET_NETWORK_test_pf should also receive the type of socket (BTHPROTO_RFCOMM)
+    // if (GNUNET_NETWORK_test_pf (AF_BTH) != GNUNET_OK)
+    // {
+    //   fprintf (stderr, "AF_BTH family is not supported\n");
+    //   ExitProcess (2);
+    // }
+
+     /* create the socket */
+    dev.handle = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
+    if (dev.handle == NULL)
+    {
+      fprintf (stderr, "Failed to create RFCOMM socket: ");
+      print_last_error();
+      ExitProcess (2);
+    }
+
+
+    if (open_device (&dev) == -1)
+    {
+      fprintf (stderr, "Failed to open the device\n");
+      print_last_error();
+      if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
+      {
+        fprintf (stderr, "Failed to close the socket!\n");
+        print_last_error();
+      }
+      ExitProcess (2);
+    }
+
+    if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (dev.handle, 1) )
+    {
+      fprintf (stderr, "Failed to change the socket mode\n");
+      ExitProcess (2);
+    }
+
+    memset (&write_std, 0, sizeof (write_std));
+    memset (&write_pout, 0, sizeof (write_pout));
+    stdin_open = 1;
+
+    rfds = GNUNET_NETWORK_fdset_create ();
+    wfds = GNUNET_NETWORK_fdset_create ();
+
+  /* Send MAC address of the bluetooth interface to STDOUT first */
+    {
+      struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
+
+      macmsg.hdr.size = htons (sizeof (macmsg));
+      macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
+      GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy));
+      GNUNET_memcpy (write_std.buf, &macmsg, sizeof (macmsg));
+      write_std.size = sizeof (macmsg);
+    }
+
+
+    stdin_mst = mst_create (&stdin_send_hw, &dev);
+    stdin_open = 1;
+
+    int pos = 0;
+    int stdin_pos = -1;
+    int stdout_pos = -1;
+    while (1)
+    {
+      broadcast = 0;
+      pos = 0;
+      stdin_pos = -1;
+      stdout_pos = -1;
+      sendsocket = NULL; //FIXME ???memleaks
+
+      GNUNET_NETWORK_fdset_zero (rfds);
+      if ((0 == write_pout.size) && (1 == stdin_open))
+      {
+        stdin_pos = pos;
+        pos +=1;
+        GNUNET_NETWORK_fdset_handle_set (rfds, (struct GNUNET_DISK_FileHandle*) &stdin_handle);
+      }
+
+      if (0 == write_std.size)
+      {
+        pos += 1;
+        GNUNET_NETWORK_fdset_set (rfds, dev.handle);
+      }
+
+      for (i = 0; i < crt_rfds; i++)
+      {
+        pos += 1;
+        GNUNET_NETWORK_fdset_set (rfds, rfds_list[i]);
+      }
+
+      GNUNET_NETWORK_fdset_zero (wfds);
+      if (0 < write_std.size)
+      {
+        stdout_pos = pos;
+        GNUNET_NETWORK_fdset_handle_set (wfds, (struct GNUNET_DISK_FileHandle*) &stdout_handle);
+        // printf ("%s\n", write_std.buf);
+        // memset (write_std.buf, 0, write_std.size);
+        // write_std.size = 0;
+      }
+
+      if (0 < write_pout.size)
+      {
+        if (strcmp (argv[1], "ff:ff:ff:ff:ff:ff") == 0) {
+          fprintf(stderr, "LOG: BROADCAST! Skipping the message\n");
+          // skip the message
+          broadcast = 1;
+          memset (write_pout.buf, 0, write_pout.size);
+          write_pout.size = 0;
+        }
+        else
+        {
+          SOCKADDR_BTH addr;
+          fprintf (stderr, "LOG : has a new message for %s\n", argv[1]);
+          sendsocket = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
+
+          if (sendsocket == NULL)
+          {
+            fprintf (stderr, "Failed to create RFCOMM socket: \n");
+            print_last_error();
+            ExitProcess (2);
+          }
+
+          memset (&addr, 0, sizeof (addr));
+          //addr.addressFamily = AF_BTH;
+          if (SOCKET_ERROR ==
+             WSAStringToAddress (argv[1], AF_BTH, NULL, (LPSOCKADDR) &addr, &addr_len))
+          {
+            fprintf (stderr, "Failed to translate the address: ");
+            print_last_error();
+            ExitProcess ( 2 ) ;
+          }
+          addr.port = get_channel (argv[1]);
+          if (addr.port == -1)
+          {
+            fprintf (stderr, "Couldn't find the sdp service for the address: %s\n", argv[1]);
+            memset (write_pout.buf, 0, write_pout.size);
             write_pout.size = 0;
+            broadcast = 1; //skipping the select part
           }
           else
           {
-            write_pout.pos += ret;
-            if ((write_pout.pos != write_pout.size) && (0 != ret))
+            if (GNUNET_OK != GNUNET_NETWORK_socket_connect (sendsocket, (LPSOCKADDR)&addr, addr_len))
             {
-              /* We should not get partial sends with packet-oriented devices... */
-              fprintf (stderr, "Write error, partial send: %u/%u\n",
-                      (unsigned int) write_pout.pos,
-                      (unsigned int) write_pout.size);
-              break;
+              fprintf (stderr, "Failed to connect: ");
+              print_last_error();
+              ExitProcess (2);
             }
-            
-            if (write_pout.pos == write_pout.size)
+
+            if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (sendsocket, 1) )
             {
-              write_pout.pos = 0;
-              write_pout.size = 0;
+              fprintf (stderr, "Failed to change the socket mode\n");
+              ExitProcess (2);
             }
-            fprintf (stderr, "LOG : %s sends a message to a DEVICE\n", dev.iface); //FIXME: debugging message
+
+            GNUNET_NETWORK_fdset_set (wfds, sendsocket);
           }
         }
       }
-      for (i = 0; i <= maxfd; i++)
+
+      if (broadcast == 0)
       {
-        if (FD_ISSET (i, &rfds))
+        int retval = GNUNET_NETWORK_socket_select (rfds, wfds, NULL, GNUNET_TIME_relative_get_forever_());
+        if (retval < 0)
+        {
+          fprintf (stderr, "Select error\n");
+          ExitProcess (2);
+        }
+        //if (GNUNET_NETWORK_fdset_isset (wfds, (struct GNUNET_NETWORK_Handle*)&stdout_handle))
+        if (retval == stdout_pos)
         {
-          if (i == STDIN_FILENO)
+          fprintf(stderr, "LOG : sends a message to STDOUT\n"); //FIXME: debugging message
+          //ssize_t ret;
+          //ret = GNUNET_NETWORK_socket_send ((struct GNUNET_NETWORK_Handle *)&stdout_handle,  write_std.buf + write_std.pos, write_std.size - write_std.pos);
+          //ret = write (STDOUT_FILENO, write_std.buf + write_std.pos,  write_std.size - write_std.pos);
+          DWORD ret;
+          if (FALSE == WriteFile (stdout_handle,  write_std.buf + write_std.pos, write_std.size - write_std.pos, &ret, NULL))
           {
-            ssize_t ret = 
-             read (i, readbuf, sizeof (readbuf));
-            if (0 > ret)
-            {
-              fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno));
-              break; break;
-            }
-            if (0 == ret)
+            fprintf (stderr, "Failed to write to STDOUT: ");
+            print_last_error();
+            break;
+          }
+
+          if (ret <= 0)
+          {
+            fprintf (stderr, "Failed to write to STDOUT\n");
+            ExitProcess (2);
+          }
+
+          write_std.pos += ret;
+          if (write_std.pos == write_std.size)
+          {
+            write_std.pos = 0;
+            write_std.size = 0;
+          }
+        }
+        if (sendsocket != NULL)
+        {
+          if (GNUNET_NETWORK_fdset_isset (wfds, sendsocket))
+          {
+            ssize_t ret;
+            ret = GNUNET_NETWORK_socket_send (sendsocket, write_pout.buf + write_pout.pos,
+                 write_pout.size - write_pout.pos);
+
+            if (GNUNET_SYSERR == ret)
             {
-              /* stop reading... */
-              stdin_open = 0;
+              fprintf (stderr, "Failed to send to the socket. Closing the socket. Error: \n");
+              print_last_error();
+              if (GNUNET_NETWORK_socket_close (sendsocket) != GNUNET_OK)
+              {
+                fprintf (stderr, "Failed to close the sendsocket!\n");
+                print_last_error();
+              }
+              ExitProcess (2);
             }
             else
             {
-              mst_receive (stdin_mst, readbuf, ret);
-              fprintf (stderr, "LOG : %s receives a message from STDIN\n", dev.iface); //FIXME: debugging message
+              write_pout.pos += ret;
+              if ((write_pout.pos != write_pout.size) && (0 != ret))
+              {
+                /* we should not get partial sends with packet-oriented devices... */
+                fprintf (stderr, "Write error, partial send: %u/%u\n",
+                        (unsigned int) write_pout.pos,
+                       (unsigned int) write_pout.size);
+                break;
+              }
+
+              if (write_pout.pos == write_pout.size)
+              {
+                write_pout.pos = 0;
+                write_pout.size = 0;
+
+              }
+              fprintf(stderr, "LOG : sends a message to a DEVICE\n"); //FIXME: debugging message
             }
-          } 
-          else if (i == dev.fd_rfcomm) 
+          }
+        }
+
+        //if (GNUNET_NETWORK_fdset_isset (rfds, (struct GNUNET_NETWORK_Handle*)&stdin_handle))
+        if (retval == stdin_pos)
+        {
+          //ssize_t ret;
+          //ret = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)&stdin_handle, readbuf, sizeof (write_pout.buf));
+          //ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
+          DWORD ret;
+          if (FALSE == ReadFile (stdin_handle, readbuf, sizeof (readbuf), &ret, NULL))  /* do nothing asynchronous */
           {
-            int readsocket;
-            struct sockaddr_rc addr = { 0 };
-            unsigned int opt = sizeof (addr);
-            
-            readsocket = accept (dev.fd_rfcomm, (struct sockaddr *) &addr, &opt);
-            fprintf(stderr, "LOG : %s accepts a message\n", dev.iface); //FIXME: debugging message
-            if (readsocket == -1)
+            fprintf (stderr, "Read error from STDIN: ");
+            print_last_error();
+            break;
+          }
+          if (0 == ret)
+          {
+            /* stop reading... */
+            stdin_open = 0;
+          } else {
+            mst_receive (stdin_mst, readbuf, ret);
+            fprintf (stderr, "LOG : receives a message from STDIN\n"); //FIXME: debugging message
+          }
+        }
+        else
+        if (GNUNET_NETWORK_fdset_isset (rfds, dev.handle))
+        {
+          fprintf (stderr, "LOG: accepting connection\n");
+          struct GNUNET_NETWORK_Handle *readsocket;
+          readsocket = GNUNET_NETWORK_socket_accept (dev.handle, (LPSOCKADDR)&acc_addr, &addr_len);
+          if (readsocket == NULL)
+          {
+            fprintf (stderr, "Accept error %d: ", GetLastError());
+            print_last_error();
+            ExitProcess (2);
+          }
+          else
+          {
+            if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (readsocket, 1) )
             {
-              fprintf (stderr, "Failed to accept a connection on interface: %.*s\n", IFNAMSIZ, 
-                  strerror (errno));
-              break;
+              fprintf (stderr, "Failed to change the socket mode\n");
+              ExitProcess (2);
             }
+            GNUNET_NETWORK_fdset_set (rfds, readsocket);
+
+            if (crt_rfds < MAX_PORTS)
+              rfds_list[crt_rfds++] = readsocket;
             else
             {
-              FD_SET (readsocket, &rfds);
-              maxfd = MAX (maxfd, readsocket);
-              
-              if (crt_rfds < MAX_PORTS)
-                rfds_list[crt_rfds++] = readsocket;
-              else
-              {
-                fprintf (stderr, "The limit for the read file descriptors list was \
-                                reached\n");
-                break;
-              }
+              fprintf (stderr, "The limit for the read file descriptors list was reached\n");
+              break;
             }
-            
-          } 
-          else 
+          }
+        }
+        else
+        for (i = 0; i < crt_rfds; i++)
+        {
+          if (GNUNET_NETWORK_fdset_isset (rfds, rfds_list[i]))
           {
             struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
             ssize_t ret;
-            fprintf (stderr, "LOG : %s reads something from the socket\n", dev.iface);//FIXME : debugging message 
+            fprintf (stderr, "LOG: reading something from the socket\n");//FIXME : debugging message
             rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
-            ret =
-                read_from_the_socket (i, (unsigned char *) &rrm->frame,
-                            sizeof (write_std.buf) 
-                           - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage) 
-                           + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame), 
-                           rrm);
+            ret = read_from_the_socket (rfds_list[i], (unsigned char *) &rrm->frame,
+                              sizeof (write_std.buf)
+                  - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
+                  + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
+                  rrm);
             if (0 >= ret)
             {
-              int j;
-              FD_CLR (i, &rfds);
-              close (i);
-               /* Remove the socket from the list */
-              for (j = 0; j < crt_rfds; j++)
+
+              //TODO remove the socket from the list
+              if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
               {
-                if (rfds_list[j] == i)
-                {
-                  rfds_list[j] ^= rfds_list[crt_rfds - 1];
-                  rfds_list[crt_rfds - 1] ^= rfds_list[j];
-                  rfds_list[j] ^= rfds_list[crt_rfds - 1];
-                  crt_rfds -= 1;
-                  break;
-                }
+                fprintf (stderr, "Failed to close the sendsocket!\n");
+                print_last_error();
               }
 
-              fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
+              fprintf (stderr, "Read error from raw socket: ");
+              print_last_error();
               break;
+
             }
             if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
             {
-              write_std.size = ret 
-               + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage) 
-               - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
+              write_std.size = ret
+          + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
+          - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
               rrm->header.size = htons (write_std.size);
               rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
             }
+            break;
           }
         }
       }
     }
-  }
-  /* Error handling, try to clean up a bit at least */
-  mst_destroy (stdin_mst);
-  stdin_mst = NULL;
-  sdp_close (dev.session);
-  (void) close (dev.fd_rfcomm);
-  (void) close (sendsocket);
-  
-  for (i = 0; i < crt_rfds; i++)
-    (void) close (rfds_list[i]);
-
-  for (i = 0; i < neighbours.size; i++)
-    (void) close (neighbours.fds[i]);
 
-  return 1;                     /* we never exit 'normally' */
-}
+    mst_destroy (stdin_mst);
+    stdin_mst = NULL;
 
+    if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
+    {
+      fprintf (stderr, "Failed to close the socket!\n");
+      print_last_error();
+    }
 
+    for (i = 0; i < crt_rfds; i++)
+    {
+      if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
+      {
+        fprintf (stderr, "Failed to close the socket!\n");
+        print_last_error();
+      }
+    }
 
+    WSACleanup();
+  #endif
+  return 1;                     /* we never exit 'normally' */
+}