splitting 'struct GNUNET_CRYPTO_EccPublicKey' into one struct for signing and another...
[oweals/gnunet.git] / src / transport / gnunet-helper-transport-bluetooth.c
index 418cc9dec0ba24cd4b63e1da4ebf24cd5a9e63e6..3eb17de42cc0d0bbd5361aa09c34d8b65b6db05c 100644 (file)
 #include "gnunet_protocols.h"
 #include "plugin_transport_wlan.h"
 
-#define HARD_CODED_PORT_NUMBER 10
-#define HARD_CODED_PORT_NUMBER2 10
+/**
+ * Maximum number of ports assignable for RFCOMMM protocol.
+ */
+#define MAX_PORTS 30
 
 /**
  * Maximum size of a message allowed in either direction
 #define MAXLINE 4096
 
 
+/**
+ * Maximum number of loops without inquiring for new devices.
+ */
+#define MAX_LOOPS 5
+
 /**
  * struct for storing the information of the hardware.  There is only
  * one of these.
@@ -72,6 +79,11 @@ struct HardwareInfos
    * MAC address of our own bluetooth interface.
    */
   struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac;
+  
+  /**
+   * SDP session
+   */
+   sdp_session_t *session ;
 };
 
 /**
@@ -98,6 +110,29 @@ 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];
+
+
+  /* The number of the devices */
+  int size;
+  
+  /* The current position */
+  int pos;
+
+  /* The device id */
+  int dev_id;
+};
+
 
 /**
  * Buffer for data read from stdin to be transmitted to the bluetooth device
@@ -109,6 +144,17 @@ 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 ****** */ 
@@ -204,6 +250,8 @@ mst_create (MessageTokenizerCallback cb,
   ret->curr_buf = MIN_BUFFER_SIZE;
   ret->cb = cb;
   ret->cb_cls = cb_cls;
+  ret->pos = 0;
+  
   return ret;
 }
 
@@ -220,7 +268,7 @@ mst_create (MessageTokenizerCallback cb,
  */
 static int
 mst_receive (struct MessageStreamTokenizer *mst,
-            const char *buf, size_t size)
+       const char *buf, size_t size)
 {
   const struct GNUNET_MessageHeader *hdr;
   size_t delta;
@@ -235,6 +283,11 @@ mst_receive (struct MessageStreamTokenizer *mst,
   while (mst->pos > 0)
   {
 do_align:
+    if (mst->pos < mst->off)
+    {
+      //fprintf (stderr, "We processed too many bytes!\n");
+      return GNUNET_SYSERR;
+    }
     if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) ||
         (0 != (mst->off % ALIGN_FACTOR)))
     {
@@ -255,6 +308,9 @@ do_align:
     }
     if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
     {
+      //FIXME should I reset ??
+      // mst->off = 0;
+      // mst->pos = 0;
       return GNUNET_OK;
     }
     hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
@@ -262,10 +318,11 @@ do_align:
     if (want < sizeof (struct GNUNET_MessageHeader))
     {
       fprintf (stderr,
-              "Received invalid message from stdin\n");
-      exit (1);
+         "Received invalid message from stdin\n");
+      return GNUNET_SYSERR;
     }
-    if (mst->curr_buf - mst->off < want)
+    if ((mst->curr_buf - mst->off < want) &&
+       (mst->off > 0))
     {
       /* need more space */
       mst->pos -= mst->off;
@@ -274,11 +331,16 @@ do_align:
     }
     if (want > mst->curr_buf)
     {
+      if (mst->off != 0)
+      {
+        fprintf (stderr, "Error! We should proceeded 0 bytes\n");
+        return GNUNET_SYSERR;
+      }
       mst->hdr = realloc (mst->hdr, want);
       if (NULL == mst->hdr)
       {
-       fprintf (stderr, "Failed to allocate buffer for alignment\n");
-       exit (1);
+  fprintf (stderr, "Failed to allocate buffer for alignment\n");
+  exit (1);
       }
       ibuf = (char *) mst->hdr;
       mst->curr_buf = want;
@@ -287,6 +349,11 @@ do_align:
     if (mst->pos - mst->off < want)
     {
       delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
+      if (mst->pos + delta > mst->curr_buf)
+      {
+        fprintf (stderr, "The size of the buffer will be exceeded!\n");
+        return GNUNET_SYSERR;
+      }
       memcpy (&ibuf[mst->pos], buf, delta);
       mst->pos += delta;
       buf += delta;
@@ -294,6 +361,9 @@ do_align:
     }
     if (mst->pos - mst->off < want)
     {
+      //FIXME should I use this?
+      // mst->off = 0;
+      // mst->pos = 0;
       return GNUNET_OK;
     }
     mst->cb (mst->cb_cls, hdr);
@@ -305,6 +375,11 @@ do_align:
       mst->pos = 0;
     }
   }
+  if (0 != mst->pos)
+  {
+    fprintf (stderr, "There should some valid bytes in the buffer on this stage\n");
+    return GNUNET_SYSERR;
+  }
   while (size > 0)
   {
     if (size < sizeof (struct GNUNET_MessageHeader))
@@ -318,9 +393,11 @@ do_align:
       want = ntohs (hdr->size);
       if (want < sizeof (struct GNUNET_MessageHeader))
       {
-       fprintf (stderr,
-                "Received invalid message from stdin\n");
-       exit (1);
+  fprintf (stderr,
+     "Received invalid message from stdin\n");
+  //exit (1);
+        mst->off = 0;
+        return GNUNET_SYSERR;
       }
       if (size < want)
         break;                  /* or not, buffer incomplete, so copy to private buffer... */
@@ -342,8 +419,8 @@ do_align:
       mst->hdr = realloc (mst->hdr, size + mst->pos);
       if (NULL == mst->hdr)
       {
-       fprintf (stderr, "Failed to allocate buffer for alignment\n");
-       exit (1);
+  fprintf (stderr, "Failed to allocate buffer for alignment\n");
+  exit (1);
       }
       ibuf = (char *) mst->hdr;
       mst->curr_buf = size + mst->pos;
@@ -351,7 +428,7 @@ do_align:
     if (mst->pos + size > mst->curr_buf)
     {
       fprintf (stderr,
-              "Assertion failed\n");
+         "Assertion failed\n");
       exit (1);
     }
     memcpy (&ibuf[mst->pos], buf, size);
@@ -361,6 +438,7 @@ do_align:
 }
 
 
+
 /**
  * Destroys a tokenizer.
  *
@@ -493,22 +571,22 @@ check_crc_buf_osdep (const unsigned char *buf, size_t len)
 
 /**
  * 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)
+bind_socket (int socket, struct sockaddr_rc *addr)
 {
   int port, status;
-  struct sockaddr_rc src = { 0 };
   
-  src.rc_family = AF_BLUETOOTH;
-  src.rc_bdaddr = *BDADDR_ANY;
-  
-  /* Bind every possible port (from 0 to 30) and stop when bind doesn't fail */
-  for (port = 1; port <= 30; port++)
+  /* 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++)
   {
-    src.rc_channel = port;
-    status = bind(*socket, (struct sockaddr *)&src, sizeof(src));
+    addr->rc_channel = port;
+    status = bind (socket, (struct sockaddr *) addr, sizeof (struct sockaddr_rc));
     if (status == 0)
       return 0;
   }
@@ -517,36 +595,105 @@ bind_socket (int *socket)
 }
 
 
-//TODO
 /**
  * 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 sdp_session_t*
-register_service (void
+static int
+register_service (struct HardwareInfos *dev, int rc_channel
 {
   /**
    * 1. initializations
    * 2. set the service ID, class, profile information
-   * 3. make the service record publicly nrowsable
+   * 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);
   
-  //TODO: For now I will use a hard coded port number but in the end I will implement the SDP protocol 
-    
-   return NULL;
+  /* 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;
 }
 
-//TODO
 /**
  * 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
-searching_service (void
+get_channel(struct HardwareInfos *dev, bdaddr_t dest
 {
   /**
    * 1. detect all nearby devices
@@ -556,12 +703,62 @@ searching_service (void)
    * 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;
+  uint8_t channel = -1;
    
-   return 0;
+  /* 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));
+   //FIXME exit?
+   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)
+  {
+    for (it = response_list; it; it = it->next)
+    {
+      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)
+      {
+        channel = sdp_get_proto_port (proto_list, RFCOMM_UUID);
+        sdp_list_free (proto_list, 0);
+      }
+      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 (channel == -1)
+    fprintf (stderr, "Failed to find the listening channel for interface `%.*s': %s\n",
+            IFNAMSIZ, dev->iface, strerror (errno));
+  
+  return channel;
 }
 
 /**
  * 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
@@ -574,17 +771,10 @@ read_from_the_socket (int 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 = recv (dev->fd_rfcomm, tmpbuf, buf_size, 0);   //FIXME if I use RFCOMM
   
   count = read (sock, tmpbuf, buf_size); 
   
@@ -597,7 +787,7 @@ read_from_the_socket (int sock,
     return -1;
   }
   
-  /* Get the channel used */
+  /* Get the channel used */ //FIXME probably not needed anymore
   memset (&rc_addr, 0, sizeof (rc_addr));
   len = sizeof (rc_addr);
   if (0 > getsockname (sock, (struct sockaddr *) &rc_addr, (socklen_t *) &len))
@@ -609,7 +799,7 @@ read_from_the_socket (int sock,
   memset (ri, 0, sizeof (*ri));
   ri->ri_channel = rc_addr.rc_channel;
   
-  /* detect CRC32 at the end */
+  /* Detect CRC32 at the end */
   if (0 == check_crc_buf_osdep (tmpbuf, count - sizeof (uint32_t)))
   {
     count -= sizeof(uint32_t);
@@ -628,27 +818,21 @@ read_from_the_socket (int sock,
  */
 static int
 open_device (struct HardwareInfos *dev)
-{
-  /**
-   * 1. Open a HCI socket (if RFCOMM protocol is used. If not, the HCI socket is 
-   * saved in dev->fd_hci.
-   * 2. Find the device id (request a list with all the devices and find the one
-   * with the dev->iface name)
-   * 3. If the interface is down try to get it up
-   * 4. TODO: Bind the RFCOMM socket to the interface using the bind_socket() method and register
-   * a SDP service
-   * 5. For now use a hard coded port number(channel) value
-   * FIXME : if I use HCI sockets , should I enable RAW_SOCKET MODE?!?!?!
-   */
-   
+{   
   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
+  } 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) 
@@ -685,18 +869,17 @@ open_device (struct HardwareInfos *dev)
     
     if (strcmp (dev_info.name, dev->iface) == 0)
     {
-      char addr[19] = { 0 };  //the device MAC address
       
       dev_id = dev_info.dev_id; //the device was found
-      
-      ba2str (&dev_info.bdaddr, addr); //get the device's MAC address
-      //TODO : copy the MAC address to the device structure
+      /**
+       * Copy the MAC address to the device structure
+       */
       memcpy (&dev->pl_mac, &dev_info.bdaddr, sizeof (bdaddr_t));
       
-      /* Check if the interface is UP */
+      /* Check if the interface is up */
       if (hci_test_bit (HCI_UP, (void *) &dev_info.flags) == 0)
       {
-        /* Bring interface up */ //FIXME should I check if is HCI_RUNNING ?!?!??!
+        /* Bring the interface up */
         if (ioctl (fd_hci, HCIDEVUP, dev_info.dev_id))
         {
           fprintf (stderr, "ioctl(HCIDEVUP) on interface `%.*s' failed: %s\n",
@@ -724,10 +907,6 @@ open_device (struct HardwareInfos *dev)
         }
         
       }
-      
-      //FIXME : Sniff mode!?!
-      //FIXME : RAW MODE?!?
-      
       break;
     }
     
@@ -749,40 +928,28 @@ open_device (struct HardwareInfos *dev)
   memset (&rc_addr, 0, sizeof (rc_addr)); 
   rc_addr.rc_family = AF_BLUETOOTH;
   rc_addr.rc_bdaddr = *BDADDR_ANY;
-  rc_addr.rc_channel = (uint8_t) HARD_CODED_PORT_NUMBER;
  
-  if (bind (dev->fd_rfcomm, (struct sockaddr *) &rc_addr, sizeof (rc_addr) != 0))
+  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;
   }
   
-  /*
-  memset (&hci_addr, 0, sizeof (hci_addr));
-       hci_addr.hci_family = AF_BLUETOOTH;
-       hci_addr.hci_dev = dev_id;
-       */
-       /**
-        * FIXME      hci_addr.hci_channel = HARD_CODED_PORT_NUMBER 
-        * For linux kernel >= 2.6.7 the kernel automatically chooses an available port
-        * number. (getsockname() function can be used for finding out what port the kernel 
-        * chose).
-        */
-       /*
-  if (-1 == bind (dev->fd_hci, (struct sockaddr *) &hci_addr, sizeof (hci_addr)))
+  /* Register a SDP service */
+  if (register_service (dev, rc_addr.rc_channel) != 0)
   {
-    fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
+    fprintf (stderr, "Failed to register a service on interface `%.*s': %s\n", IFNAMSIZ,
              dev->iface, strerror (errno));
     return 1;
   }
-  */
   
-  if (listen (dev->fd_rfcomm, 5) == -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 3;
+    return 1;
   }
   
   
@@ -864,8 +1031,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
@@ -888,7 +1055,8 @@ stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
     fprintf (stderr, "Received malformed message\n");
     exit (1);
   }
-  sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
+  sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) - 
+               sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
   if (MAXLINE < sendsize)
   {
     fprintf (stderr, "Packet too big for buffer\n");
@@ -901,28 +1069,244 @@ stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
   /* 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));
   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 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 checks */
+    if (neighbours.size >= MAX_PORTS)
+    {
+      fprintf (stderr, "%.*s reached the top limit for the discovarable devices\n", IFNAMSIZ, dev->iface);
+      return 2;
+    }
+
+    /* 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++) 
+    {
+      int j;
+      int found = 0;
+
+      /* sanity check */
+      if (i >= MAX_PORTS)
+      {
+        fprintf (stderr, "%.*s reached the top limit for the discoverable devices (after inquiry)\n", IFNAMSIZ,
+                dev->iface);
+        return 2;
+      }
+      
+      /* 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 (found == 0)
+      {
+        char addr[19] = { 0 };
+
+        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));
+      }
+    }   
+       
+    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 already connected to this device */
+    if (neighbours.fds[neighbours.pos] == -1)
+    {
+
+      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);
+      if (connect (*sendsocket, (struct sockaddr *)&addr_rc, sizeof (addr_rc)) == 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;
+      }
+      else
+      {
+        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 be sure that this works
+        {
+          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;
+        }
+
+        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)
+    {
+      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 (neighbours.pos == neighbours.size)
+        neighbours.pos = 0;
+      
+      if (neighbours.pos == loop_check)
+      {
+        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;
+    }
+
+    *sendsocket = neighbours.fds[neighbours.pos++];
+  }
+
+  return 0;
+}
 
 /**
  * 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.
+ * 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. 'mon0')
+ * @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];
-  char dest[18];
   int maxfd;
   fd_set rfds;
   fd_set wfds;
@@ -930,8 +1314,9 @@ main (int argc, char *argv[])
   struct MessageStreamTokenizer *stdin_mst;
   int raw_eno, i;
   uid_t uid;
-
-  /* assert privs so we can modify the firewall rules! */
+  int crt_rfds = 0, rfds_list[MAX_PORTS];
+  int broadcast, sendsocket;
+  /* Assert privs so we can modify the firewall rules! */
   uid = getuid ();
 #ifdef HAVE_SETRESUID
   if (0 != setresuid (uid, 0, 0))
@@ -947,17 +1332,16 @@ main (int argc, char *argv[])
   }
 #endif
 
-  /* make use of SGID capabilities on POSIX */
+  /* Make use of SGID capabilities on POSIX */
   memset (&dev, 0, sizeof (dev));
   dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
-  //FIXME : using RFCOMM protocol : 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 */
+  /* 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");
+    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;
@@ -987,7 +1371,7 @@ main (int argc, char *argv[])
     return 1;
   }
 
-  /* drop privs */
+  /* Drop privs */
   {
     uid_t uid = getuid ();
 #ifdef HAVE_SETRESUID
@@ -1009,8 +1393,7 @@ main (int argc, char *argv[])
 #endif
   }
 
-
-  /* send MAC address of the bluetooth interface to STDOUT first */
+ /* Send MAC address of the bluetooth interface to STDOUT first */
   {
     struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
 
@@ -1019,13 +1402,25 @@ main (int argc, char *argv[])
     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;
-  while (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))
     {
@@ -1037,169 +1432,317 @@ main (int argc, char *argv[])
       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)
-    {
-      int sendsocket, status;
-      struct sockaddr_rc addr = { 0 };
+    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;
       
-      memset (dest, 0, sizeof (dest));
-      
-      sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
-      
-      if (sendsocket < 0) 
+      if (memcmp (&frame->addr1, &dev.pl_mac, 
+                  sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
       {
-        fprintf (stderr, "Failed to create a RFCOMM socket (sending stage): %s\n", 
-                strerror (errno));
-        return -1;
-      }
-      
-      addr.rc_family = AF_BLUETOOTH;
-      addr.rc_channel = HARD_CODED_PORT_NUMBER2; //TODO: dinamically binding
-      str2ba(dest, &addr.rc_bdaddr);  //TODO: get the destination address from the message
-      
-      /*TODO: use a NON-BLOCKING socket
-       *      sock_flags = fcntl (sendsocket, F_GETFL, 0);
-       *      fcntl( sendsocket, F_SETFL, sock_flags | O_NONBLOCK);
-      */
-      status = connect (sendsocket, (struct sockaddr *) &addr, sizeof (addr));
-           if (0 != status && errno != EAGAIN)
-           {
-               //fprintf (stderr, "connect error on %s\n", argv[1]);
-             perror("Connect error");
-             return -1;
-           }
-      
-      FD_SET (sendsocket, &wfds);
-      maxfd = MAX (maxfd, sendsocket);
-    }
-    {
-      int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
-      if ((-1 == retval) && (EINTR == errno))
-       continue;
-      if (0 > retval)
+        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, "select failed: %s\n", strerror (errno));
-       break;
-      }
-    }
-    
-    for (i = 0; i <= maxfd; i++)
-    {
-      if (FD_ISSET (i , &wfds))
+        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
+        {
+          FD_SET (sendsocket, &wfds);
+          maxfd = MAX (maxfd, sendsocket);
+        }
+      } 
+      else 
       {
-        if (i == STDOUT_FILENO)
+        int found = 0;
+        int pos = 0;
+        /* Search if the address already exists on the list */
+        for (i = 0; i < neighbours.size; i++)
         {
-          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)
+          if (memcmp (&frame->addr1, &(neighbours.devices[i]), sizeof (bdaddr_t)) == 0) 
           {
-            write_std.pos = 0;
-            write_std.size = 0;
+            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)
         {
-          ssize_t ret =
-           write (i, write_pout.buf + write_std.pos, 
-                  write_pout.size - write_pout.pos);
-          if (0 > ret)
-          {
-            fprintf (stderr, "Failed to write to bluetooth device: %s\n",
-                     strerror (errno));
-            break;
-          }
-          write_pout.pos += ret;
-          if ((write_pout.pos != write_pout.size) && (0 != ret))
+          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) 
           {
-            /* 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 create a RFCOMM socket (sending stage): %s\n", 
+                    strerror (errno));
+            return -1;
           }
-          if (write_pout.pos == write_pout.size)
+                                  
+          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)
+            {
+              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
           {
-            write_pout.pos = 0;
-            write_pout.size = 0;
-            (void) close (i);
+            FD_SET (sendsocket, &wfds);
+            maxfd = MAX (maxfd, sendsocket);
+            fprintf (stderr, "LOG : Connection successful\n");
+            if (pos != 0) // save the socket
+            {
+              neighbours.fds[pos] = sendsocket;
+            }
+            else
+            {
+              /* Add the new device to the discovered devices list */
+              if (neighbours.size < MAX_PORTS)
+              {
+                neighbours.fds[neighbours.size] = sendsocket;
+                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 (FD_ISSET (i, &rfds))
+    if (broadcast == 0)
+    {
+      /* Select a fd which is ready for action :) */
+      {
+        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)
+        {
+          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
+        
+      } 
+      if (sendsocket != -1)
       {
-        if (i == STDIN_FILENO)
+        if (FD_ISSET (sendsocket , &wfds))
         {
-          ssize_t ret = 
-           read (i, readbuf, sizeof (readbuf));
-          if (0 > ret)
+          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, "Read error from STDIN: %s\n", strerror (errno));
-            break;
+            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;
           }
-          if (0 == ret)
+          else
           {
-            /* stop reading... */
-            stdin_open = 0;
+            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
           }
-          mst_receive (stdin_mst, readbuf, ret);
-        } 
-        else if (i == dev.fd_rfcomm) 
+        }
+      }
+      for (i = 0; i <= maxfd; i++)
+      {
+        if (FD_ISSET (i, &rfds))
         {
-          int newfd;
-          struct sockaddr_rc addr = { 0 };
-          unsigned int opt = sizeof (addr);
-          
-          newfd = accept (dev.fd_rfcomm, (struct sockaddr *) &addr, &opt);
-          
-          if (newfd == -1)
+          if (i == STDIN_FILENO)
           {
-            fprintf (stderr, "Failed to accept a connection on interface: %s\n", 
-                strerror (errno));
-            return -1;
-          } else {
-            FD_SET (newfd, &rfds);
-            maxfd = MAX (maxfd, newfd);
-          }
-          
-        } 
-        else 
-        {
-          struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
-          ssize_t ret;
-
-          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);
-          if (0 > ret)
+            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)
+            {
+              /* 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) 
           {
-            fprintf (stderr, "Read error from rfcomm socket: %s\n", strerror (errno));
-            break;
-          }
-          if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
+            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 
           {
-            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);
+            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 (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);
+            }
           }
         }
       }
@@ -1207,10 +1750,18 @@ main (int argc, char *argv[])
   }
   /* 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' */
-  
 }