- fix compilation
[oweals/gnunet.git] / src / transport / gnunet-helper-transport-bluetooth.c
1 /*
2    This file is part of GNUnet.
3    (C) 2010, 2011, 2012 Christian Grothoff (and other contributing authors)
4    Copyright (c) 2007, 2008, Andy Green <andy@warmcat.com>
5    Copyright (C) 2009 Thomas d'Otreppe
6
7    GNUnet is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published
9    by the Free Software Foundation; either version 3, or (at your
10    option) any later version.
11
12    GNUnet is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GNUnet; see the file COPYING.  If not, write to the
19    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.
21 */
22 #include "gnunet_config.h"
23
24 #ifdef MINGW
25   #include "platform.h"
26   #include "gnunet_util_lib.h"
27   #include <bthdef.h>
28   #include <ws2bth.h>
29 #else
30   #define SOCKTYPE int
31   #include <bluetooth/bluetooth.h>
32   #include <bluetooth/hci.h>
33   #include <bluetooth/hci_lib.h>
34   #include <bluetooth/rfcomm.h>
35   #include <bluetooth/sdp.h>
36   #include <bluetooth/sdp_lib.h>
37   #include <errno.h>
38   #include <linux/if.h>  
39   #include <stdio.h>
40   #include <stdlib.h>
41   #include <sys/ioctl.h>
42   #include <sys/param.h>
43   #include <sys/socket.h>
44   #include <sys/stat.h>
45   #include <sys/types.h>
46   #include <unistd.h>
47 #endif
48
49 #include "plugin_transport_wlan.h"
50 #include "gnunet_protocols.h"
51
52
53 /**
54  * Maximum number of ports assignable for RFCOMMM protocol.
55  */
56 #define MAX_PORTS 30
57
58 /**
59  * Maximum size of a message allowed in either direction
60  * (used for our receive and sent buffers).
61  */
62 #define MAXLINE 4096
63
64
65 /**
66  * Maximum number of loops without inquiring for new devices.
67  */
68 #define MAX_LOOPS 5
69
70 #ifdef MINGW
71   /* Maximum size of the interface's name */
72   #define IFNAMSIZ 16
73
74   #ifndef NS_BTH
75     #define NS_BTH 16
76   #endif
77   /**
78    * A copy of the MAC Address.
79    */
80   struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy
81   {
82     UINT8 mac[MAC_ADDR_SIZE];
83   };
84
85   /** 
86    * The UUID used for the SDP service.
87    * {31191E56-FA7E-4517-870E-71B86BBCC52F}
88    */
89   #define GNUNET_BLUETOOTH_SDP_UUID \
90     { \
91       0x31, 0x19, 0x1E, 0x56, \
92       0xFA, 0x7E, \
93       0x45, 0x17, \
94       0x87, 0x0E, \
95       0x71, 0xB8, 0x6B, 0xBC, 0xC5, 0x2F \
96     }
97 #endif
98
99 /**
100  * struct for storing the information of the hardware.  There is only
101  * one of these.
102  */
103 struct HardwareInfos
104 {
105   /**
106    * Name of the interface, not necessarily 0-terminated (!).
107    */
108   char iface[IFNAMSIZ];
109
110  #ifdef MINGW
111   /**
112    * socket handle
113    */ 
114   struct GNUNET_NETWORK_Handle *handle;
115
116   /**
117    * MAC address of our own bluetooth interface.
118    */
119   struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy pl_mac;
120  #else
121   /**
122    * file descriptor for the rfcomm socket
123    */
124   int fd_rfcomm;
125
126   /**
127    * MAC address of our own bluetooth interface.
128    */
129   struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac;
130   
131   /**
132    * SDP session
133    */
134    sdp_session_t *session ;
135  #endif
136 };
137
138 /**
139  * IO buffer used for buffering data in transit (to wireless or to stdout).
140  */
141 struct SendBuffer
142 {
143   /**
144    * How many bytes of data are stored in 'buf' for transmission right now?
145    * Data always starts at offset 0 and extends to 'size'.
146    */
147   size_t size;
148
149   /**
150    * How many bytes that were stored in 'buf' did we already write to the
151    * destination?  Always smaller than 'size'.
152    */
153   size_t pos;
154   
155   /**
156    * Buffered data; twice the maximum allowed message size as we add some
157    * headers.
158    */
159   char buf[MAXLINE * 2];
160 };
161
162 #ifdef LINUX
163  /**
164   * Devices buffer used to keep a list with all the discoverable devices in 
165   * order to send them HELLO messages one by one when it receive a broadcast message.
166   */ 
167  struct BroadcastMessages
168  {
169    /* List with the discoverable devices' addresses */
170    bdaddr_t devices[MAX_PORTS]; 
171
172    /* List with the open sockets */
173    int fds[MAX_PORTS];
174
175
176    /* The number of the devices */
177    int size;
178     
179    /* The current position */
180    int pos;
181
182    /* The device id */
183    int dev_id;
184  };
185
186  /**
187   * Address used to identify the broadcast messages.
188   */
189  static struct GNUNET_TRANSPORT_WLAN_MacAddress broadcast_address = {{255, 255, 255, 255, 255, 255}};
190
191  /**
192   * Buffer with the discoverable devices.
193   */
194  static struct BroadcastMessages neighbours;
195
196  static int searching_devices_count = 0;
197 #endif
198
199 /**
200  * Buffer for data read from stdin to be transmitted to the bluetooth device
201  */
202 static struct SendBuffer write_pout;
203
204 /**
205  * Buffer for data read from the bluetooth device to be transmitted to stdout.
206  */
207 static struct SendBuffer write_std;
208
209
210 /* ****** this are the same functions as the ones used in gnunet-helper-transport-wlan.c ****** */ 
211
212 /**
213  * To what multiple do we align messages?  8 byte should suffice for everyone
214  * for now.
215  */
216 #define ALIGN_FACTOR 8
217
218 /**
219  * Smallest supported message.
220  */
221 #define MIN_BUFFER_SIZE sizeof (struct GNUNET_MessageHeader)
222
223
224 /**
225  * Functions with this signature are called whenever a
226  * complete message is received by the tokenizer.
227  *
228  * @param cls closure
229  * @param message the actual message
230  */
231 typedef void (*MessageTokenizerCallback) (void *cls, 
232             const struct
233             GNUNET_MessageHeader *
234             message);
235
236 /**
237  * Handle to a message stream tokenizer.
238  */
239 struct MessageStreamTokenizer
240 {
241
242   /**
243    * Function to call on completed messages.
244    */
245   MessageTokenizerCallback cb;
246
247   /**
248    * Closure for cb.
249    */
250   void *cb_cls;
251
252   /**
253    * Size of the buffer (starting at 'hdr').
254    */
255   size_t curr_buf;
256
257   /**
258    * How many bytes in buffer have we already processed?
259    */
260   size_t off;
261
262   /**
263    * How many bytes in buffer are valid right now?
264    */
265   size_t pos;
266
267   /**
268    * Beginning of the buffer.  Typed like this to force alignment.
269    */
270   struct GNUNET_MessageHeader *hdr;
271
272 };
273
274
275 /**
276  * Create a message stream tokenizer.
277  *
278  * @param cb function to call on completed messages
279  * @param cb_cls closure for cb
280  * @return handle to tokenizer
281  */
282 static struct MessageStreamTokenizer *
283 mst_create (MessageTokenizerCallback cb,
284       void *cb_cls)
285 {
286   struct MessageStreamTokenizer *ret;
287
288   ret = malloc (sizeof (struct MessageStreamTokenizer));
289   if (NULL == ret)
290   {
291     fprintf (stderr, "Failed to allocate buffer for tokenizer\n");
292     exit (1);
293   }
294   ret->hdr = malloc (MIN_BUFFER_SIZE);
295   if (NULL == ret->hdr)
296   {
297     fprintf (stderr, "Failed to allocate buffer for alignment\n");
298     exit (1);
299   }
300   ret->curr_buf = MIN_BUFFER_SIZE;
301   ret->cb = cb;
302   ret->cb_cls = cb_cls;
303   ret->pos = 0;
304   
305   return ret;
306 }
307
308
309 /**
310  * Add incoming data to the receive buffer and call the
311  * callback for all complete messages.
312  *
313  * @param mst tokenizer to use
314  * @param buf input data to add
315  * @param size number of bytes in buf
316  * @return GNUNET_OK if we are done processing (need more data)
317  *         GNUNET_SYSERR if the data stream is corrupt
318  */
319 static int
320 mst_receive (struct MessageStreamTokenizer *mst,
321        const char *buf, size_t size)
322 {
323   const struct GNUNET_MessageHeader *hdr;
324   size_t delta;
325   uint16_t want;
326   char *ibuf;
327   int need_align;
328   unsigned long offset;
329   int ret;
330
331   ret = GNUNET_OK;
332   ibuf = (char *) mst->hdr;
333   while (mst->pos > 0)
334   {
335 do_align:
336     if (mst->pos < mst->off)
337     {
338       //fprintf (stderr, "We processed too many bytes!\n");
339       return GNUNET_SYSERR;
340     }
341     if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) ||
342         (0 != (mst->off % ALIGN_FACTOR)))
343     {
344       /* need to align or need more space */
345       mst->pos -= mst->off;
346       memmove (ibuf, &ibuf[mst->off], mst->pos);
347       mst->off = 0;
348     }
349     if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
350     {
351       delta =
352           GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) -
353                       (mst->pos - mst->off), size);
354       memcpy (&ibuf[mst->pos], buf, delta);
355       mst->pos += delta;
356       buf += delta;
357       size -= delta;
358     }
359     if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
360     {
361       //FIXME should I reset ??
362       // mst->off = 0;
363       // mst->pos = 0;
364       return GNUNET_OK;
365     }
366     hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
367     want = ntohs (hdr->size);
368     if (want < sizeof (struct GNUNET_MessageHeader))
369     {
370       fprintf (stderr,
371          "Received invalid message from stdin\n");
372       return GNUNET_SYSERR;
373     }
374     if ((mst->curr_buf - mst->off < want) &&
375        (mst->off > 0))
376     {
377       /* need more space */
378       mst->pos -= mst->off;
379       memmove (ibuf, &ibuf[mst->off], mst->pos);
380       mst->off = 0;
381     }
382     if (want > mst->curr_buf)
383     {
384       if (mst->off != 0)
385       {
386         fprintf (stderr, "Error! We should proceeded 0 bytes\n");
387         return GNUNET_SYSERR;
388       }
389       mst->hdr = realloc (mst->hdr, want);
390       if (NULL == mst->hdr)
391       {
392   fprintf (stderr, "Failed to allocate buffer for alignment\n");
393   exit (1);
394       }
395       ibuf = (char *) mst->hdr;
396       mst->curr_buf = want;
397     }
398     hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
399     if (mst->pos - mst->off < want)
400     {
401       delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
402       if (mst->pos + delta > mst->curr_buf)
403       {
404         fprintf (stderr, "The size of the buffer will be exceeded!\n");
405         return GNUNET_SYSERR;
406       }
407       memcpy (&ibuf[mst->pos], buf, delta);
408       mst->pos += delta;
409       buf += delta;
410       size -= delta;
411     }
412     if (mst->pos - mst->off < want)
413     {
414       //FIXME should I use this?
415       // mst->off = 0;
416       // mst->pos = 0;
417       return GNUNET_OK;
418     }
419     mst->cb (mst->cb_cls, hdr);
420     mst->off += want;
421     if (mst->off == mst->pos)
422     {
423       /* reset to beginning of buffer, it's free right now! */
424       mst->off = 0;
425       mst->pos = 0;
426     }
427   }
428   if (0 != mst->pos)
429   {
430     fprintf (stderr, "There should some valid bytes in the buffer on this stage\n");
431     return GNUNET_SYSERR;
432   }
433   while (size > 0)
434   {
435     if (size < sizeof (struct GNUNET_MessageHeader))
436       break;
437     offset = (unsigned long) buf;
438     need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
439     if (GNUNET_NO == need_align)
440     {
441       /* can try to do zero-copy and process directly from original buffer */
442       hdr = (const struct GNUNET_MessageHeader *) buf;
443       want = ntohs (hdr->size);
444       if (want < sizeof (struct GNUNET_MessageHeader))
445       {
446   fprintf (stderr,
447      "Received invalid message from stdin\n");
448   //exit (1);
449         mst->off = 0;
450         return GNUNET_SYSERR;
451       }
452       if (size < want)
453         break;                  /* or not, buffer incomplete, so copy to private buffer... */
454       mst->cb (mst->cb_cls, hdr);
455       buf += want;
456       size -= want;
457     }
458     else
459     {
460       /* need to copy to private buffer to align;
461        * yes, we go a bit more spagetti than usual here */
462       goto do_align;
463     }
464   }
465   if (size > 0)
466   {
467     if (size + mst->pos > mst->curr_buf)
468     {
469       mst->hdr = realloc (mst->hdr, size + mst->pos);
470       if (NULL == mst->hdr)
471       {
472   fprintf (stderr, "Failed to allocate buffer for alignment\n");
473   exit (1);
474       }
475       ibuf = (char *) mst->hdr;
476       mst->curr_buf = size + mst->pos;
477     }
478     if (mst->pos + size > mst->curr_buf)
479     {
480       fprintf (stderr,
481          "Assertion failed\n");
482       exit (1);
483     }
484     memcpy (&ibuf[mst->pos], buf, size);
485     mst->pos += size;
486   }
487   return ret;
488 }
489
490 /**
491  * Destroys a tokenizer.
492  *
493  * @param mst tokenizer to destroy
494  */
495 static void
496 mst_destroy (struct MessageStreamTokenizer *mst)
497 {
498   free (mst->hdr);
499   free (mst);
500 }
501
502 /**
503  * Calculate crc32, the start of the calculation
504  *
505  * @param buf buffer to calc the crc
506  * @param len len of the buffer
507  * @return crc sum
508  */
509 static unsigned long
510 calc_crc_osdep (const unsigned char *buf, size_t len)
511 {
512   static const unsigned long int crc_tbl_osdep[256] = {
513     0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
514     0xE963A535, 0x9E6495A3,
515     0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
516     0xE7B82D07, 0x90BF1D91,
517     0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
518     0xF4D4B551, 0x83D385C7,
519     0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
520     0xFA0F3D63, 0x8D080DF5,
521     0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
522     0xD20D85FD, 0xA50AB56B,
523     0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
524     0xDCD60DCF, 0xABD13D59,
525     0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
526     0xCFBA9599, 0xB8BDA50F,
527     0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
528     0xC1611DAB, 0xB6662D3D,
529     0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
530     0x9FBFE4A5, 0xE8B8D433,
531     0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
532     0x91646C97, 0xE6635C01,
533     0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
534     0x8208F4C1, 0xF50FC457,
535     0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
536     0x8CD37CF3, 0xFBD44C65,
537     0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
538     0xA4D1C46D, 0xD3D6F4FB,
539     0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
540     0xAA0A4C5F, 0xDD0D7CC9,
541     0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
542     0xB966D409, 0xCE61E49F,
543     0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
544     0xB7BD5C3B, 0xC0BA6CAD,
545     0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
546     0x04DB2615, 0x73DC1683,
547     0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
548     0x0A00AE27, 0x7D079EB1,
549     0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
550     0x196C3671, 0x6E6B06E7,
551     0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
552     0x17B7BE43, 0x60B08ED5,
553     0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
554     0x3FB506DD, 0x48B2364B,
555     0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
556     0x316E8EEF, 0x4669BE79,
557     0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
558     0x220216B9, 0x5505262F,
559     0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
560     0x2CD99E8B, 0x5BDEAE1D,
561     0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
562     0x72076785, 0x05005713,
563     0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
564     0x7CDCEFB7, 0x0BDBDF21,
565     0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
566     0x6FB077E1, 0x18B74777,
567     0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
568     0x616BFFD3, 0x166CCF45,
569     0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
570     0x4969474D, 0x3E6E77DB,
571     0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
572     0x47B2CF7F, 0x30B5FFE9,
573     0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
574     0x54DE5729, 0x23D967BF,
575     0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
576     0x5A05DF1B, 0x2D02EF8D
577   };
578
579   unsigned long crc = 0xFFFFFFFF;
580
581   for (; len > 0; len--, buf++)
582     crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
583   return (~crc);
584 }
585
586
587 /**
588  * Calculate and check crc of the bluetooth packet
589  *
590  * @param buf buffer of the packet, with len + 4 bytes of data,
591  *            the last 4 bytes being the checksum
592  * @param len length of the payload in data
593  * @return 0 on success (checksum matches), 1 on error
594  */
595 static int
596 check_crc_buf_osdep (const unsigned char *buf, size_t len)
597 {
598   unsigned long crc;
599
600   crc = calc_crc_osdep (buf, len);
601   buf += len;
602   if (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
603       ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3])
604     return 0;
605   return 1;     
606 }
607
608
609
610 /* ************** end of clone  ***************** */
611
612 #ifdef MINGW
613   /**
614    * Function used to get the code of last error and to print the type of error.
615    */
616   static void 
617   print_last_error()
618   {
619     LPVOID lpMsgBuf = NULL;
620
621     if (FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
622                     NULL, GetLastError(), 0, (LPTSTR) &lpMsgBuf, 0, NULL))
623       fprintf (stderr, "%s\n", (char *)lpMsgBuf);
624     else
625       fprintf (stderr, "Failed to format the message for the last error! Error number : %d\n", GetLastError());
626   }
627
628   /**
629    * Function used to initialize the Windows Sockets
630    */
631   static void
632   initialize_windows_sockets()
633   {
634     WSADATA wsaData ;
635     WORD wVersionRequested = MAKEWORD (2, 0);
636     if (WSAStartup (wVersionRequested, &wsaData) != NO_ERROR)
637     {
638       fprintf (stderr , "Error initializing window sockets!\n");
639       print_last_error();
640       ExitProcess (2) ;
641     }
642   }
643
644   /**
645    * Function used to convert the GUID.
646    * @param bytes the GUID represented as a char array
647    * @param uuid pointer to the GUID 
648    */
649   static void 
650   convert_guid(char *bytes, GUID * uuid)
651   {
652     int i;
653     uuid->Data1 = ((bytes[0] << 24) & 0xff000000) | ((bytes[1] << 16) & 0x00ff0000) | ((bytes[2] << 8) & 0x0000ff00) | (bytes[3] & 0x000000ff);
654     uuid->Data2 = ((bytes[4] << 8) & 0xff00) | (bytes[5] & 0x00ff);
655     uuid->Data3 = ((bytes[6] << 8) & 0xff00) | (bytes[7] & 0x00ff);
656
657     for (i = 0; i < 8; i++)
658     {
659       uuid->Data4[i] = bytes[i + 8];
660     }
661   }
662 #endif
663
664 #ifdef LINUX
665   /**
666    * Function for assigning a port number
667    * 
668    * @param socket the socket used to bind
669    * @param addr pointer to the rfcomm address
670    * @return 0 on success 
671    */ 
672   static int
673   bind_socket (int socket, struct sockaddr_rc *addr)
674   {
675     int port, status;
676     
677     /* Bind every possible port (from 0 to 30) and stop when binding doesn't fail */
678     //FIXME : it should start from port 1, but on my computer it doesn't work :)
679     for (port = 3; port <= 30; port++)
680     {
681       addr->rc_channel = port;
682       status = bind (socket, (struct sockaddr *) addr, sizeof (struct sockaddr_rc));
683       if (status == 0)
684         return 0;
685     }
686     
687     return -1; 
688   }
689 #endif
690
691 #ifdef MINGW
692   /**
693    * Function used for creating the service record and registering it.
694    *
695    * @param dev pointer to the device struct
696    * @return 0 on success
697    */
698   static int
699   register_service (struct HardwareInfos *dev) 
700   {
701     /* advertise the service */
702     CSADDR_INFO addr_info;
703     WSAQUERYSET wqs;
704     GUID guid;
705     unsigned char uuid[] = GNUNET_BLUETOOTH_SDP_UUID;
706     SOCKADDR_BTH addr;
707     int addr_len = sizeof (SOCKADDR_BTH);
708     int fd;
709     /* get the port on which we are listening on */
710     memset (& addr, 0, sizeof (SOCKADDR_BTH));
711     fd = GNUNET_NETWORK_get_fd (dev->handle);
712     if (fd <= 0)
713     {
714       fprintf (stderr, "Failed to get the file descriptor\n");
715       return -1;
716     }
717     if (SOCKET_ERROR == getsockname (fd, (SOCKADDR*)&addr, &addr_len))
718     {
719       fprintf (stderr, "Failed to get the port on which we are listening on: \n");
720       print_last_error();
721       return -1;
722     }
723
724     /* save the device address */
725     memcpy (&dev->pl_mac, &addr.btAddr, sizeof (BTH_ADDR));
726
727     /* set the address information */
728     memset (&addr_info, 0, sizeof (CSADDR_INFO));
729     addr_info.iProtocol = BTHPROTO_RFCOMM;
730     addr_info.iSocketType = SOCK_STREAM;
731     addr_info.LocalAddr.lpSockaddr = (LPSOCKADDR)&addr;
732     addr_info.LocalAddr.iSockaddrLength = sizeof (addr);
733     addr_info.RemoteAddr.lpSockaddr = (LPSOCKADDR)&addr;
734     addr_info.RemoteAddr.iSockaddrLength = sizeof (addr);
735
736     convert_guid((char *) uuid, &guid);
737
738     /* register the service */
739     memset (&wqs, 0, sizeof (WSAQUERYSET));
740     wqs.dwSize = sizeof (WSAQUERYSET);
741     wqs.dwNameSpace = NS_BTH;
742     wqs.lpszServiceInstanceName = "GNUnet Bluetooth Service";
743     wqs.lpszComment = "This is the service used by the GNUnnet plugin transport";
744     wqs.lpServiceClassId = &guid;
745     wqs.dwNumberOfCsAddrs = 1;
746     wqs.lpcsaBuffer = &addr_info ;
747     wqs.lpBlob = 0;
748
749     if (SOCKET_ERROR == WSASetService (&wqs , RNRSERVICE_REGISTER, 0)) 
750     {
751       fprintf (stderr, "Failed to register the SDP service: ");
752       print_last_error();
753       return -1;
754     }
755     else
756     {
757       fprintf (stderr, "The SDP service was registered\n");
758     }
759
760     return 0;
761   }
762 #else
763   /**
764    * Function used for creating the service record and registering it.
765    *
766    * @param dev pointer to the device struct
767    * @param rc_channel the rfcomm channel
768    * @return 0 on success
769    */
770   static int
771   register_service (struct HardwareInfos *dev, int rc_channel) 
772   {
773     /**
774      * 1. initializations
775      * 2. set the service ID, class, profile information
776      * 3. make the service record publicly browsable
777      * 4. register the RFCOMM channel
778      * 5. set the name, provider and description
779      * 6. register the service record to the local SDP server
780      * 7. cleanup
781      */
782     uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
783                               dev->pl_mac.mac[5], dev->pl_mac.mac[4], dev->pl_mac.mac[3],
784                               dev->pl_mac.mac[2], dev->pl_mac.mac[1], dev->pl_mac.mac[0]};
785     const char *service_dsc = "Bluetooth plugin services";
786     const char *service_prov = "GNUnet provider";                       
787     uuid_t root_uuid, rfcomm_uuid, svc_uuid;  
788     sdp_list_t *root_list = 0, *rfcomm_list = 0, *proto_list = 0,
789        *access_proto_list = 0, *svc_list = 0;
790     sdp_record_t *record = 0;
791     sdp_data_t *channel = 0;
792     
793     record = sdp_record_alloc();
794
795     /* Set the general service ID */
796     sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
797     svc_list = sdp_list_append (0, &svc_uuid);
798     sdp_set_service_classes (record, svc_list);
799     sdp_set_service_id (record, svc_uuid);
800
801     /* Make the service record publicly browsable */
802     sdp_uuid16_create (&root_uuid, PUBLIC_BROWSE_GROUP); 
803     root_list = sdp_list_append (0, &root_uuid); 
804     sdp_set_browse_groups (record, root_list);
805
806     /* Register the RFCOMM channel */
807     sdp_uuid16_create (&rfcomm_uuid, RFCOMM_UUID);
808     channel = sdp_data_alloc (SDP_UINT8, &rc_channel);
809     rfcomm_list = sdp_list_append (0, &rfcomm_uuid);
810     sdp_list_append (rfcomm_list, channel);
811     proto_list = sdp_list_append (0, rfcomm_list);
812
813     /* Set protocol information */
814     access_proto_list = sdp_list_append (0, proto_list);
815     sdp_set_access_protos (record, access_proto_list);
816
817     /* Set the name, provider, and description */
818     sdp_set_info_attr (record, dev->iface, service_prov, service_dsc);
819     
820     /* Connect to the local SDP server */
821     dev->session = sdp_connect (BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
822     
823     if (!dev->session)
824     {
825       fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
826                IFNAMSIZ, dev->iface, strerror (errno));
827       //FIXME exit?
828       return 1;
829     }
830     
831     /* Register the service record */
832     if (sdp_record_register (dev->session, record, 0) < 0)
833     {
834       fprintf (stderr, "Failed to register a service record on interface `%.*s': %s\n",
835                IFNAMSIZ, dev->iface, strerror (errno));
836       //FIXME exit?
837       return 1;
838     }
839     
840     /* Cleanup */
841     sdp_data_free (channel);  
842     sdp_list_free (root_list, 0);
843     sdp_list_free (rfcomm_list, 0);
844     sdp_list_free (proto_list, 0);
845     sdp_list_free (access_proto_list, 0);
846     sdp_list_free (svc_list, 0);
847     sdp_record_free (record);
848     
849     return 0;
850   }
851 #endif
852
853 #ifdef MINGW
854   /**
855    * Function for searching and browsing for a service. This will return the 
856    * port number on which the service is running.
857    *
858    * @param dest target address
859    * @return channel
860    */
861   static int
862   get_channel(const char *dest)
863   {
864     HANDLE h;
865     WSAQUERYSET *wqs;
866     DWORD wqs_len = sizeof (WSAQUERYSET);
867     int done = 0;
868     int channel = -1;
869     GUID guid;
870     unsigned char uuid[] = GNUNET_BLUETOOTH_SDP_UUID;
871     convert_guid ((char *) uuid, &guid);
872    
873     wqs = (WSAQUERYSET*)malloc (wqs_len);
874     ZeroMemory (wqs, wqs_len);
875    
876     wqs->dwSize = sizeof (WSAQUERYSET) ;
877     wqs->lpServiceClassId = &guid;
878     wqs->dwNameSpace = NS_BTH;
879     wqs->dwNumberOfCsAddrs = 0;
880     wqs->lpszContext = (LPSTR)dest;
881    
882     if (SOCKET_ERROR == WSALookupServiceBegin (wqs,  LUP_FLUSHCACHE | LUP_RETURN_ALL, &h))
883     {
884       if (GetLastError() == WSASERVICE_NOT_FOUND)
885       {
886         fprintf (stderr, "WARNING! The device with address %s wasn't found. Skipping the message!", dest);
887         return -1;
888       }
889       else
890       {
891         fprintf (stderr, "Failed to find the port number: ");
892         print_last_error();
893         ExitProcess (2);
894         return -1;
895       }
896     }
897    
898     /* search the sdp service */
899     while (!done)
900     {
901       if (SOCKET_ERROR == WSALookupServiceNext (h, LUP_FLUSHCACHE | LUP_RETURN_ALL, &wqs_len, wqs))
902       {
903         int error = WSAGetLastError();
904    
905         switch (error)
906         {
907         case WSAEFAULT:
908           free (wqs);
909           wqs = (WSAQUERYSET*)malloc (wqs_len);
910           break;
911         case WSANO_DATA:
912           fprintf (stderr, "Failed! The address was valid but there was no data record of requested type\n");
913           done = 1;
914           break;
915         case WSA_E_NO_MORE:
916           done = 1;
917           break;
918         default:
919           fprintf (stderr, "Failed to look over the services: ");
920           print_last_error();
921           WSALookupServiceEnd (h);
922           ExitProcess (2);
923         }
924       }
925       else
926       {
927         channel = ((SOCKADDR_BTH*)wqs->lpcsaBuffer->RemoteAddr.lpSockaddr)->port;
928       }
929     }
930    
931     free (wqs) ;
932     WSALookupServiceEnd (h);
933    
934     return channel;
935   }
936 #else
937   /**
938    * Function used for searching and browsing for a service. This will return the 
939    * port number on which the service is running.
940    *
941    * @param dev pointer to the device struct
942    * @param dest target address
943    * @return channel
944    */
945   static int
946   get_channel(struct HardwareInfos *dev, bdaddr_t dest) 
947   {
948     /**
949      * 1. detect all nearby devices
950      * 2. for each device:
951      * 2.1. connect to the SDP server running
952      * 2.2. get a list of service records with the specific UUID
953      * 2.3. for each service record get a list of the protocol sequences and get 
954      *       the port number
955      */
956     uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
957                              dest.b[5], dest.b[4], dest.b[3],
958                              dest.b[2], dest.b[1], dest.b[0]};
959     sdp_session_t *session = 0;
960     sdp_list_t *search_list = 0, *attrid_list = 0, *response_list = 0, *it = 0;
961     uuid_t svc_uuid;
962     uint32_t range = 0x0000ffff;
963     uint8_t channel = -1;
964      
965     /* Connect to the local SDP server */
966     session = sdp_connect (BDADDR_ANY, &dest, 0); 
967     if (!session)
968     {
969      fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
970               IFNAMSIZ, dev->iface, strerror (errno));
971      return -1;
972     }
973     
974     sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
975     search_list = sdp_list_append (0, &svc_uuid);
976     attrid_list = sdp_list_append (0, &range);
977     
978     if (sdp_service_search_attr_req (session, search_list, 
979                     SDP_ATTR_REQ_RANGE, attrid_list, &response_list) == 0)
980     {
981       for (it = response_list; it; it = it->next)
982       {
983         sdp_record_t *record = (sdp_record_t*) it->data;
984         sdp_list_t *proto_list = 0;
985         if (sdp_get_access_protos (record, &proto_list) == 0)
986         {
987           channel = sdp_get_proto_port (proto_list, RFCOMM_UUID);
988           sdp_list_free (proto_list, 0);
989         }
990         sdp_record_free (record);
991       }
992     }
993     
994     sdp_list_free (search_list, 0);
995     sdp_list_free (attrid_list, 0);
996     sdp_list_free (response_list, 0);
997     
998     sdp_close (session);
999     
1000     if (channel == -1)
1001       fprintf (stderr, "Failed to find the listening channel for interface `%.*s': %s\n",
1002               IFNAMSIZ, dev->iface, strerror (errno));
1003     
1004     return channel;
1005   }
1006 #endif
1007
1008 /**
1009  * Read from the socket and put the result into the buffer for transmission to 'stdout'.
1010  * 
1011  * @param sock file descriptor for reading
1012  * @param buf buffer to read to; first bytes will be the 'struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame',
1013  *            followed by the actual payload
1014  * @param buf_size size of the buffer
1015  * @param ri where to write radiotap_rx info
1016  * @return number of bytes written to 'buf'
1017  */
1018 static ssize_t 
1019 read_from_the_socket (void *sock, 
1020       unsigned char *buf, size_t buf_size,
1021             struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri)
1022 {
1023   unsigned char tmpbuf[buf_size];
1024   ssize_t count;
1025   
1026   #ifdef MINGW
1027    count = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)sock, tmpbuf, buf_size);
1028   #else
1029    count = read (*((int *)sock), tmpbuf, buf_size); 
1030   #endif
1031
1032   if (0 > count)
1033   {
1034     if (EAGAIN == errno)
1035       return 0;
1036     #if MINGW
1037      print_last_error();
1038     #else
1039      fprintf (stderr, "Failed to read from the HCI socket: %s\n", strerror (errno));
1040     #endif
1041
1042     return -1;
1043   }
1044   
1045   #ifdef LINUX
1046    /* Get the channel used */
1047    int len;
1048    struct sockaddr_rc  rc_addr = { 0 }; 
1049
1050    memset (&rc_addr, 0, sizeof (rc_addr));
1051    len = sizeof (rc_addr);
1052    if (0 > getsockname (*((int *)sock), (struct sockaddr *) &rc_addr, (socklen_t *) &len))
1053    {
1054      fprintf (stderr, "getsockname() call failed : %s\n", strerror (errno));
1055      return -1;
1056    }
1057
1058    memset (ri, 0, sizeof (*ri));
1059    ri->ri_channel = rc_addr.rc_channel;
1060   #endif
1061
1062   /* Detect CRC32 at the end */
1063   if (0 == check_crc_buf_osdep (tmpbuf, count - sizeof (uint32_t)))
1064   {
1065     count -= sizeof(uint32_t);
1066   }
1067   
1068   memcpy (buf, tmpbuf, count);
1069   
1070   return count;
1071 }
1072
1073 /**
1074  * Open the bluetooth interface for reading/writing
1075  *
1076  * @param dev pointer to the device struct
1077  * @return 0 on success
1078  */
1079 static int
1080 open_device (struct HardwareInfos *dev)
1081
1082   #ifdef MINGW
1083     SOCKADDR_BTH addr;
1084
1085     /* bind the RFCOMM socket to the interface */
1086     addr.addressFamily = AF_BTH;
1087     addr.btAddr = 0;
1088     addr.port = BT_PORT_ANY;
1089
1090     if (GNUNET_NETWORK_socket_bind (dev->handle, (const SOCKADDR*)&addr, sizeof (SOCKADDR_BTH), 0) != GNUNET_OK)
1091     {
1092       fprintf (stderr, "Failed to bind the socket: ");
1093       if (GetLastError() == WSAENETDOWN)
1094       {
1095         fprintf (stderr, "Please make sure that your Bluetooth device is ON!\n");
1096         ExitProcess (2);
1097       }
1098       print_last_error();
1099       return -1;
1100     }
1101
1102     /* start listening on the socket */
1103     if (GNUNET_NETWORK_socket_listen (dev->handle, 4) != GNUNET_OK)
1104     {
1105       fprintf (stderr, "Failed to listen on the socket: ");
1106       print_last_error();
1107       return -1;
1108     }
1109
1110     /* register the sdp service */
1111     if (register_service(dev) != 0)
1112     {
1113       fprintf (stderr, "Failed to register a service: ");
1114       print_last_error();
1115       return 1;
1116     } 
1117   #else
1118     int i, dev_id = -1, fd_hci;
1119     struct 
1120     {
1121       struct hci_dev_list_req list;
1122       struct hci_dev_req dev[HCI_MAX_DEV];
1123     } request;                              //used for detecting the local devices
1124     struct sockaddr_rc rc_addr = { 0 };    //used for binding
1125     
1126     /* Initialize the neighbour structure */
1127     neighbours.dev_id = -1;
1128     for (i = 0; i < MAX_PORTS; i++)
1129       neighbours.fds[i] = -1;
1130     
1131     /* Open a HCI socket */
1132     fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
1133
1134     if (fd_hci < 0) 
1135     {
1136       fprintf (stderr, "Failed to create HCI socket: %s\n", strerror (errno));
1137       return -1;
1138     }
1139       
1140     memset (&request, 0, sizeof(request));
1141     request.list.dev_num = HCI_MAX_DEV;
1142
1143     if (ioctl (fd_hci, HCIGETDEVLIST, (void *) &request) < 0)
1144     {
1145       fprintf (stderr, "ioctl(HCIGETDEVLIST) on interface `%.*s' failed: %s\n",
1146               IFNAMSIZ, dev->iface, strerror (errno));
1147       return 1;
1148     }
1149     
1150     /* Search for a device with dev->iface name */
1151     for (i = 0; i < request.list.dev_num; i++)
1152     {
1153       struct hci_dev_info dev_info;
1154
1155       memset (&dev_info, 0, sizeof(struct hci_dev_info));
1156       dev_info.dev_id = request.dev[i].dev_id;
1157       strncpy (dev_info.name, dev->iface, IFNAMSIZ);
1158       
1159       if (ioctl (fd_hci, HCIGETDEVINFO, (void *) &dev_info))
1160       {
1161         fprintf (stderr, "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n",
1162                IFNAMSIZ, dev->iface, strerror (errno));
1163         return 1;
1164       }
1165       
1166       if (strcmp (dev_info.name, dev->iface) == 0)
1167       {
1168         
1169         dev_id = dev_info.dev_id; //the device was found
1170         /**
1171          * Copy the MAC address to the device structure
1172          */
1173         memcpy (&dev->pl_mac, &dev_info.bdaddr, sizeof (bdaddr_t));
1174         
1175         /* Check if the interface is up */
1176         if (hci_test_bit (HCI_UP, (void *) &dev_info.flags) == 0)
1177         {
1178           /* Bring the interface up */
1179           if (ioctl (fd_hci, HCIDEVUP, dev_info.dev_id))
1180           {
1181             fprintf (stderr, "ioctl(HCIDEVUP) on interface `%.*s' failed: %s\n",
1182                IFNAMSIZ, dev->iface, strerror (errno));
1183             return 1;
1184           }
1185         }
1186         
1187         /* Check if the device is discoverable */
1188         if (hci_test_bit (HCI_PSCAN, (void *) &dev_info.flags) == 0 ||
1189             hci_test_bit (HCI_ISCAN, (void *) &dev_info.flags) == 0)
1190         {
1191           /* Set interface Page Scan and Inqury Scan ON */
1192           struct hci_dev_req dev_req;
1193             
1194           memset (&dev_req, 0, sizeof (dev_req));
1195           dev_req.dev_id = dev_info.dev_id;
1196           dev_req.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
1197           
1198           if (ioctl (fd_hci, HCISETSCAN, (unsigned long) &dev_req))
1199           {  
1200             fprintf (stderr, "ioctl(HCISETSCAN) on interface `%.*s' failed: %s\n",
1201                IFNAMSIZ, dev->iface, strerror (errno));
1202             return 1;
1203           }
1204           
1205         }
1206         break;
1207       }
1208       
1209     }
1210     
1211     /* Check if the interface was not found */
1212     if (dev_id == -1)
1213     {
1214       fprintf (stderr, "The interface %s was not found\n", dev->iface);
1215       return 1;
1216     }
1217     
1218     /* Close the hci socket */
1219     (void) close(fd_hci);
1220     
1221     
1222     
1223     /* Bind the rfcomm socket to the interface */
1224     memset (&rc_addr, 0, sizeof (rc_addr)); 
1225     rc_addr.rc_family = AF_BLUETOOTH;
1226     rc_addr.rc_bdaddr = *BDADDR_ANY;
1227    
1228     if (bind_socket (dev->fd_rfcomm, &rc_addr) != 0)
1229     {
1230       fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
1231                dev->iface, strerror (errno));
1232       return 1;
1233     }
1234     
1235     /* Register a SDP service */
1236     if (register_service (dev, rc_addr.rc_channel) != 0)
1237     {
1238       fprintf (stderr, "Failed to register a service on interface `%.*s': %s\n", IFNAMSIZ,
1239                dev->iface, strerror (errno));
1240       return 1;
1241     }
1242     
1243     /* Switch socket in listening mode */
1244     if (listen (dev->fd_rfcomm, 5) == -1) //FIXME: probably we need a bigger number
1245     {
1246       fprintf (stderr, "Failed to listen on socket for interface `%.*s': %s\n", IFNAMSIZ,
1247                dev->iface, strerror (errno));
1248       return 1;
1249     }
1250   
1251   #endif
1252
1253   return 0;
1254 }
1255
1256
1257 /**
1258  * Set the header to sane values to make attacks more difficult
1259  *
1260  * @param taIeeeHeader pointer to the header of the packet
1261  * @param dev pointer to the Hardware_Infos struct
1262  *
1263  **** copy from gnunet-helper-transport-wlan.c ****
1264  */
1265 static void
1266 mac_set (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1267          const struct HardwareInfos *dev)
1268 {
1269   taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA); 
1270   taIeeeHeader->addr3 = mac_bssid_gnunet;
1271
1272   #ifdef MINGW
1273     memcpy (&taIeeeHeader->addr2, &dev->pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1274   #else
1275     taIeeeHeader->addr2 = dev->pl_mac;
1276   #endif
1277 }
1278
1279 #ifdef LINUX
1280   /**
1281    * Test if the given interface name really corresponds to a bluetooth
1282    * device.
1283    *
1284    * @param iface name of the interface
1285    * @return 0 on success, 1 on error
1286    **** similar with the one from gnunet-helper-transport-wlan.c ****
1287    */
1288   static int
1289   test_bluetooth_interface (const char *iface)
1290   {
1291     char strbuf[512];
1292     struct stat sbuf;
1293     int ret;
1294
1295     ret = snprintf (strbuf, sizeof (strbuf), 
1296         "/sys/class/bluetooth/%s/subsystem",
1297         iface);
1298     if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
1299     {
1300       fprintf (stderr, 
1301          "Did not find 802.15.1 interface `%s'. Exiting.\n", 
1302          iface);
1303       exit (1);
1304     }
1305     return 0;
1306   }
1307 #endif
1308
1309 /**
1310  * Test incoming packets mac for being our own.
1311  *
1312  * @param taIeeeHeader buffer of the packet
1313  * @param dev the Hardware_Infos struct
1314  * @return 0 if mac belongs to us, 1 if mac is for another target
1315  *
1316  **** same as the one from gnunet-helper-transport-wlan.c ****
1317  */
1318 static int
1319 mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1320           const struct HardwareInfos *dev)
1321 {
1322   static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
1323
1324   if ( (0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
1325        (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)) )
1326     return 0; /* some drivers set no Macs, then assume it is all for us! */
1327
1328   if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1329     return 1; /* not a GNUnet ad-hoc package */
1330   if ( (0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
1331        (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)) )
1332     return 0; /* for us, or broadcast */
1333   return 1; /* not for us */
1334 }
1335
1336
1337 /**
1338  * Process data from the stdin. Takes the message, forces the sender MAC to be correct
1339  * and puts it into our buffer for transmission to the receiver.
1340  *
1341  * @param cls pointer to the device struct ('struct HardwareInfos*')
1342  * @param hdr pointer to the start of the packet
1343  *
1344  **** same as the one from gnunet-helper-transport-wlan.c ****
1345  */
1346 static void
1347 stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1348 {
1349   struct HardwareInfos *dev = cls;
1350   const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header;
1351   struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *blueheader;
1352   size_t sendsize;
1353
1354   sendsize = ntohs (hdr->size);
1355   if ( (sendsize <
1356   sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
1357        (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) ) 
1358   {
1359     fprintf (stderr, "Received malformed message\n");
1360     exit (1);
1361   }
1362   sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) - 
1363                sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1364   if (MAXLINE < sendsize)
1365   {
1366     fprintf (stderr, "Packet too big for buffer\n");
1367     exit (1);
1368   }
1369   header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
1370   memcpy (&write_pout.buf, &header->frame, sendsize);
1371   blueheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf;
1372
1373   /* payload contains MAC address, but we don't trust it, so we'll
1374   * overwrite it with OUR MAC address to prevent mischief */
1375   mac_set (blueheader, dev);
1376   memcpy (&blueheader->addr1, &header->frame.addr1, 
1377           sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1378   write_pout.size = sendsize;
1379 }
1380
1381 #ifdef LINUX
1382   /**
1383    * Broadcast a HELLO message for peer discovery
1384    *
1385    * @param dev pointer to the device struct
1386    * @param dev pointer to the socket which was added to the set
1387    * @return 0 on success
1388    */
1389   static int 
1390   send_broadcast (struct HardwareInfos *dev, int *sendsocket) 
1391   {
1392     int new_device = 0;
1393     int loops = 0;
1394
1395    search_for_devices:
1396     if ((neighbours.size == neighbours.pos && new_device == 1) || neighbours.size == 0) 
1397     { 
1398    inquiry_devices:   //skip the conditions and force a inquiry for new devices
1399       {
1400       /** 
1401        * It means that I sent HELLO messages to all the devices from the list and I should search 
1402        * for new ones or that this is the first time when I do a search.
1403        */
1404       inquiry_info *devices = NULL;
1405       int i, responses, max_responses = MAX_PORTS;
1406
1407       /* sanity checks */
1408       if (neighbours.size >= MAX_PORTS)
1409       {
1410         fprintf (stderr, "%.*s reached the top limit for the discovarable devices\n", IFNAMSIZ, dev->iface);
1411         return 2;
1412       }
1413
1414       /* Get the device id */
1415       if (neighbours.dev_id == -1)
1416       {
1417         char addr[19] = { 0 }; //the device MAC address
1418         
1419         ba2str ((bdaddr_t *) &dev->pl_mac, addr); 
1420         neighbours.dev_id = hci_devid (addr);
1421         if (neighbours.dev_id < 0)
1422         { 
1423           fprintf (stderr, "Failed to get the device id for interface %.*s : %s\n", IFNAMSIZ,
1424                   dev->iface, strerror (errno));
1425           return 1;
1426         }
1427       }
1428     
1429       devices = malloc (max_responses * sizeof (inquiry_info));
1430       if (devices == NULL)
1431       {
1432         fprintf (stderr, "Failed to allocate memory for inquiry info list on interface %.*s\n", IFNAMSIZ,
1433                 dev->iface);
1434         return 1;
1435       }
1436              
1437       responses = hci_inquiry (neighbours.dev_id, 8, max_responses, NULL, &devices, IREQ_CACHE_FLUSH);
1438       if (responses < 0)
1439       {
1440         fprintf (stderr, "Failed to inquiry on interface %.*s\n", IFNAMSIZ, dev->iface);
1441         return 1;
1442       }
1443      
1444       fprintf (stderr, "LOG : Found %d devices\n", responses); //FIXME delete it after debugging stage
1445       
1446       if (responses == 0)
1447       {
1448         fprintf (stderr, "LOG : No devices discoverable\n");
1449         return 1;
1450       }
1451       
1452       for (i = 0; i < responses; i++) 
1453       {
1454         int j;
1455         int found = 0;
1456
1457         /* sanity check */
1458         if (i >= MAX_PORTS)
1459         {
1460           fprintf (stderr, "%.*s reached the top limit for the discoverable devices (after inquiry)\n", IFNAMSIZ,
1461                   dev->iface);
1462           return 2;
1463         }
1464         
1465         /* Search if the address already exists on the list */
1466         for (j = 0; j < neighbours.size; j++)
1467         {
1468           if (memcmp (&(devices + i)->bdaddr, &(neighbours.devices[j]), sizeof (bdaddr_t)) == 0) 
1469           {
1470             found = 1;
1471             fprintf (stderr, "LOG : the device already exists on the list\n"); //FIXME debugging message
1472             break;
1473           }
1474         }
1475
1476         if (found == 0)
1477         {
1478           char addr[19] = { 0 };
1479
1480           ba2str (&(devices +i)->bdaddr, addr);
1481           fprintf (stderr, "LOG : %s was added to the list\n", addr); //FIXME debugging message
1482           memcpy (&(neighbours.devices[neighbours.size++]), &(devices + i)->bdaddr, sizeof (bdaddr_t));
1483         }
1484       }   
1485          
1486       free (devices);
1487       }
1488     }
1489     
1490     int connection_successful = 0;
1491     struct sockaddr_rc addr_rc = { 0 };
1492     int errno_copy = 0;
1493     addr_rc.rc_family = AF_BLUETOOTH;
1494
1495     /* Try to connect to a new device from the list */
1496     while (neighbours.pos < neighbours.size)
1497     {
1498       /* Check if we are already connected to this device */
1499       if (neighbours.fds[neighbours.pos] == -1)
1500       {
1501
1502         memset (&addr_rc.rc_bdaddr, 0, sizeof (addr_rc.rc_bdaddr));
1503         memcpy (&addr_rc.rc_bdaddr, &(neighbours.devices[neighbours.pos]), sizeof (addr_rc.rc_bdaddr));
1504       
1505         addr_rc.rc_channel = get_channel (dev, addr_rc.rc_bdaddr);
1506       
1507         *sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1508         if (connect (*sendsocket, (struct sockaddr *)&addr_rc, sizeof (addr_rc)) == 0)
1509         {
1510           neighbours.fds[neighbours.pos++] = *sendsocket;
1511           connection_successful = 1;
1512           char addr[19] = { 0 };
1513           ba2str (&(neighbours.devices[neighbours.pos - 1]), addr);
1514           fprintf (stderr, "LOG : Connected to %s\n", addr);
1515
1516           break;
1517         }
1518         else
1519         {
1520           char addr[19] = { 0 };
1521           errno_copy = errno;  //Save a copy for later
1522           ba2str (&(neighbours.devices[neighbours.pos]), addr);
1523           fprintf (stderr, "LOG : Couldn't connect on device %s, error : %s\n", addr, strerror(errno));
1524           if (errno != ECONNREFUSED) //FIXME be sure that this works
1525           {
1526             fprintf (stderr, "LOG : Removes %d device from the list\n", neighbours.pos);
1527             /* Remove the device from the list */
1528             memcpy (&neighbours.devices[neighbours.pos], &neighbours.devices[neighbours.size - 1], sizeof (bdaddr_t));
1529             memset (&neighbours.devices[neighbours.size - 1], 0, sizeof (bdaddr_t));
1530             neighbours.fds[neighbours.pos] = neighbours.fds[neighbours.size - 1];
1531             neighbours.fds[neighbours.size - 1] = -1;
1532             neighbours.size -= 1;
1533           }
1534
1535           neighbours.pos += 1;
1536
1537           if (neighbours.pos >= neighbours.size)
1538               neighbours.pos = 0;
1539
1540           loops += 1;
1541
1542           if (loops == MAX_LOOPS) //don't get stuck trying to connect to one device
1543             return 1;
1544         }
1545       }
1546       else
1547       {
1548         fprintf (stderr, "LOG : Search for a new device\n"); //FIXME debugging message
1549         neighbours.pos += 1;
1550       }
1551     }
1552     
1553     /* Cycle on the list */
1554     if (neighbours.pos == neighbours.size)
1555     {
1556       neighbours.pos = 0;
1557       searching_devices_count += 1;
1558
1559       if (searching_devices_count == MAX_LOOPS)
1560       {
1561         fprintf (stderr, "LOG : Force to inquiry for new devices\n");
1562         searching_devices_count = 0;
1563         goto inquiry_devices;
1564       }
1565     }
1566    /* If a new device wasn't found, search an old one */
1567     if (connection_successful == 0) 
1568     {
1569       int loop_check = neighbours.pos;
1570       while (neighbours.fds[neighbours.pos] == -1)
1571       {
1572         if (neighbours.pos == neighbours.size)
1573           neighbours.pos = 0;
1574         
1575         if (neighbours.pos == loop_check)
1576         {
1577           if (errno_copy == ECONNREFUSED)
1578           {
1579             fprintf (stderr, "LOG : No device found. Go back and search again\n"); //FIXME debugging message
1580             new_device = 1;
1581             loops += 1;
1582             goto search_for_devices;
1583           }
1584           else
1585           {
1586             return 1; // Skip the broadcast message
1587           }
1588         }
1589
1590         neighbours.pos += 1;
1591       }
1592
1593       *sendsocket = neighbours.fds[neighbours.pos++];
1594     }
1595
1596     return 0;
1597   }
1598 #endif
1599
1600 /**
1601  * Main function of the helper.  This code accesses a bluetooth interface
1602  * forwards traffic in both directions between the bluetooth interface and 
1603  * stdin/stdout of this process.  Error messages are written to stderr.
1604  *
1605  * @param argc number of arguments, must be 2
1606  * @param argv arguments only argument is the name of the interface (i.e. 'hci0')
1607  * @return 0 on success (never happens, as we don't return unless aborted), 1 on error
1608  *
1609  **** similar to gnunet-helper-transport-wlan.c ****
1610  */
1611 int
1612 main (int argc, char *argv[])
1613 {
1614 #ifdef LINUX   
1615     struct HardwareInfos dev;
1616     char readbuf[MAXLINE];
1617     int maxfd;
1618     fd_set rfds;
1619     fd_set wfds;
1620     int stdin_open;
1621     struct MessageStreamTokenizer *stdin_mst;
1622     int raw_eno, i;
1623     uid_t uid;
1624     int crt_rfds = 0, rfds_list[MAX_PORTS];
1625     int broadcast, sendsocket;
1626     /* Assert privs so we can modify the firewall rules! */
1627     uid = getuid ();
1628   #ifdef HAVE_SETRESUID
1629     if (0 != setresuid (uid, 0, 0))
1630     {
1631       fprintf (stderr, "Failed to setresuid to root: %s\n", strerror (errno));
1632       return 254;
1633     }
1634   #else
1635     if (0 != seteuid (0)) 
1636     {
1637       fprintf (stderr, "Failed to seteuid back to root: %s\n", strerror (errno));
1638       return 254;
1639     }
1640   #endif
1641
1642     /* Make use of SGID capabilities on POSIX */
1643     memset (&dev, 0, sizeof (dev));
1644     dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1645     raw_eno = errno; /* remember for later */
1646
1647     /* Now that we've dropped root rights, we can do error checking */
1648     if (2 != argc)
1649     {
1650       fprintf (stderr, "You must specify the name of the interface as the first \
1651                         and only argument to this program.\n");
1652       if (-1 != dev.fd_rfcomm)
1653         (void) close (dev.fd_rfcomm);
1654       return 1;
1655     }
1656
1657     if (-1 == dev.fd_rfcomm)
1658     {
1659       fprintf (stderr, "Failed to create a RFCOMM socket: %s\n", strerror (raw_eno));
1660       return 1;
1661     }
1662     if (dev.fd_rfcomm >= FD_SETSIZE)
1663     {
1664       fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1665                dev.fd_rfcomm, FD_SETSIZE);
1666       (void) close (dev.fd_rfcomm);
1667       return 1;
1668     }
1669     if (0 != test_bluetooth_interface (argv[1]))
1670     {
1671       (void) close (dev.fd_rfcomm);
1672       return 1;
1673     }
1674     strncpy (dev.iface, argv[1], IFNAMSIZ);
1675     if (0 != open_device (&dev))
1676     {
1677       (void) close (dev.fd_rfcomm);
1678       return 1;
1679     }
1680
1681     /* Drop privs */
1682     {
1683       uid_t uid = getuid ();
1684   #ifdef HAVE_SETRESUID
1685       if (0 != setresuid (uid, uid, uid))
1686       {
1687         fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1688         if (-1 != dev.fd_rfcomm)
1689     (void) close (dev.fd_rfcomm);
1690         return 1;
1691       }
1692   #else
1693       if (0 != (setuid (uid) | seteuid (uid)))
1694       {
1695         fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
1696         if (-1 != dev.fd_rfcomm)
1697     (void) close (dev.fd_rfcomm);
1698         return 1;
1699       }
1700   #endif
1701     }
1702
1703    /* Send MAC address of the bluetooth interface to STDOUT first */
1704     {
1705       struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
1706
1707       macmsg.hdr.size = htons (sizeof (macmsg));
1708       macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
1709       memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1710       memcpy (write_std.buf, &macmsg, sizeof (macmsg));
1711       write_std.size = sizeof (macmsg);
1712     }
1713       
1714    
1715     stdin_mst = mst_create (&stdin_send_hw, &dev);  
1716     stdin_open = 1;
1717     
1718    /**
1719     * TODO : I should make the time out of a mac endpoint smaller and check if the rate 
1720     * from get_wlan_header (plugin_transport_bluetooth.c) is correct.
1721     */ 
1722    while (1)
1723     {
1724       maxfd = -1;
1725       broadcast = 0;
1726       sendsocket = -1;
1727
1728       FD_ZERO (&rfds);
1729       if ((0 == write_pout.size) && (1 == stdin_open))
1730       {
1731         FD_SET (STDIN_FILENO, &rfds);
1732         maxfd = MAX (maxfd, STDIN_FILENO);
1733       }
1734       if (0 == write_std.size)
1735       {
1736         FD_SET (dev.fd_rfcomm, &rfds);
1737         maxfd = MAX (maxfd, dev.fd_rfcomm);
1738       }
1739
1740       for (i = 0; i < crt_rfds; i++)  // it can receive messages from multiple devices 
1741       {
1742         FD_SET (rfds_list[i], &rfds);
1743         maxfd = MAX (maxfd, rfds_list[i]);
1744       }
1745       FD_ZERO (&wfds);
1746       if (0 < write_std.size)
1747       {
1748         FD_SET (STDOUT_FILENO, &wfds);
1749         maxfd = MAX (maxfd, STDOUT_FILENO);
1750       }
1751       if (0 < write_pout.size) //it can send messages only to one device per loop
1752       {    
1753         struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *frame;
1754         /* Get the destination address */
1755         frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) write_pout.buf;
1756         
1757         if (memcmp (&frame->addr1, &dev.pl_mac, 
1758                     sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1759         {
1760           broadcast = 1;
1761           memset (&write_pout, 0, sizeof (write_pout)); //clear the buffer 
1762         } 
1763         else if (memcmp (&frame->addr1, &broadcast_address, 
1764                   sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1765         {
1766           fprintf (stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n", dev.iface, neighbours.pos, neighbours.size); //FIXME: debugging message
1767          
1768           if (send_broadcast(&dev, &sendsocket) != 0) //if the searching wasn't successful don't get stuck on the select stage
1769           {
1770             broadcast = 1;
1771             memset (&write_pout, 0, sizeof (write_pout)); //remove the message
1772             fprintf (stderr, "LOG : Skipping the broadcast message (pos %d, size %d)\n", neighbours.pos, neighbours.size);
1773           }
1774           else
1775           {
1776             FD_SET (sendsocket, &wfds);
1777             maxfd = MAX (maxfd, sendsocket);
1778           }
1779         } 
1780         else 
1781         {
1782           int found = 0;
1783           int pos = 0;
1784           /* Search if the address already exists on the list */
1785           for (i = 0; i < neighbours.size; i++)
1786           {
1787             if (memcmp (&frame->addr1, &(neighbours.devices[i]), sizeof (bdaddr_t)) == 0) 
1788             {
1789               pos = i;
1790               if (neighbours.fds[i] != -1)
1791               {
1792                 found = 1;  //save the position where it was found
1793                 FD_SET (neighbours.fds[i], &wfds);
1794                 maxfd = MAX (maxfd, neighbours.fds[i]);
1795                 sendsocket = neighbours.fds[i];
1796                 fprintf (stderr, "LOG: the address was found in the list\n");
1797                 break;
1798               }
1799             }
1800           }
1801           if (found == 0)
1802           {
1803             int status;
1804             struct sockaddr_rc addr = { 0 };
1805           
1806             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, 
1807                     frame->addr1.mac[5], frame->addr1.mac[4], frame->addr1.mac[3],
1808                     frame->addr1.mac[2], frame->addr1.mac[1], frame->addr1.mac[0]); //FIXME: debugging message      
1809             
1810             sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1811             
1812             if (sendsocket < 0) 
1813             {
1814               fprintf (stderr, "Failed to create a RFCOMM socket (sending stage): %s\n", 
1815                       strerror (errno));
1816               return -1;
1817             }
1818                                     
1819             memcpy (&addr.rc_bdaddr, &frame->addr1, sizeof (bdaddr_t));
1820             addr.rc_family = AF_BLUETOOTH;
1821             addr.rc_channel = get_channel (&dev, addr.rc_bdaddr);
1822             
1823             int tries = 0;
1824             connect_retry:
1825             status = connect (sendsocket, (struct sockaddr *) &addr, sizeof (addr));
1826             if (0 != status && errno != EAGAIN)
1827             {
1828               if (errno == ECONNREFUSED && tries < 2)
1829               {
1830                 fprintf (stderr, "LOG : %.*s failed to connect. Trying again!\n", IFNAMSIZ, dev.iface);
1831                 tries++;
1832                 goto connect_retry;
1833               }
1834               else if (errno == EBADF)
1835               {
1836                 fprintf (stderr, "LOG : %s failed to connect : %s. Skip it!\n", dev.iface, strerror (errno));
1837                 memset (&write_pout, 0, sizeof (write_pout));
1838                 broadcast = 1;
1839               }
1840               else
1841               {
1842                 fprintf (stderr, "LOG : %s failed to connect : %s. Try again later!\n", dev.iface, strerror (errno));
1843                 memset (&write_pout, 0, sizeof (write_pout));
1844                 broadcast = 1;
1845               }
1846               
1847             }
1848             else
1849             {
1850               FD_SET (sendsocket, &wfds);
1851               maxfd = MAX (maxfd, sendsocket);
1852               fprintf (stderr, "LOG : Connection successful\n");
1853               if (pos != 0) // save the socket
1854               {
1855                 neighbours.fds[pos] = sendsocket;
1856               }
1857               else
1858               {
1859                 /* Add the new device to the discovered devices list */
1860                 if (neighbours.size < MAX_PORTS)
1861                 {
1862                   neighbours.fds[neighbours.size] = sendsocket;
1863                   memcpy (&(neighbours.devices[neighbours.size++]), &addr.rc_bdaddr, sizeof (bdaddr_t));
1864                 }
1865                 else
1866                 {
1867                   fprintf (stderr, "The top limit for the discovarable devices' list was reached\n");
1868                 }
1869               }
1870             }
1871           }
1872         }
1873       }
1874
1875       if (broadcast == 0)
1876       {
1877         /* Select a fd which is ready for action :) */
1878         {
1879           int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
1880           if ((-1 == retval) && (EINTR == errno))
1881       continue;
1882           if (0 > retval && errno != EBADF)   // we handle BADF errors later
1883           {
1884       fprintf (stderr, "select failed: %s\n", strerror (errno));
1885       break;
1886           }
1887         }
1888         if (FD_ISSET (STDOUT_FILENO , &wfds))
1889         {
1890           ssize_t ret =
1891               write (STDOUT_FILENO, write_std.buf + write_std.pos,
1892                      write_std.size - write_std.pos);
1893           if (0 > ret)
1894           {
1895             fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1896             break;
1897           }
1898           write_std.pos += ret;
1899           if (write_std.pos == write_std.size)
1900           {
1901             write_std.pos = 0;
1902             write_std.size = 0;
1903           }
1904           fprintf (stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); //FIXME: debugging message
1905           
1906         } 
1907         if (sendsocket != -1)
1908         {
1909           if (FD_ISSET (sendsocket , &wfds))
1910           {
1911             ssize_t ret =
1912         write (sendsocket, write_pout.buf + write_std.pos, 
1913                write_pout.size - write_pout.pos);
1914             if (0 > ret) //FIXME should I first check the error type?
1915             {
1916               fprintf (stderr, "Failed to write to bluetooth device: %s. Closing the socket!\n",
1917                        strerror (errno));         
1918               for (i = 0; i < neighbours.size; i++)
1919               {
1920                 if (neighbours.fds[i] == sendsocket)
1921                 {
1922                   (void) close(sendsocket);
1923                   neighbours.fds[i] = -1;
1924                   break;
1925                 }
1926               }
1927               /* Remove the message */
1928               memset (&write_pout.buf + write_std.pos, 0, (write_pout.size - write_pout.pos)); 
1929               write_pout.pos = 0 ;
1930               write_pout.size = 0;
1931             }
1932             else
1933             {
1934               write_pout.pos += ret;
1935               if ((write_pout.pos != write_pout.size) && (0 != ret))
1936               {
1937                 /* We should not get partial sends with packet-oriented devices... */
1938                 fprintf (stderr, "Write error, partial send: %u/%u\n",
1939                         (unsigned int) write_pout.pos,
1940                         (unsigned int) write_pout.size);
1941                 break;
1942               }
1943               
1944               if (write_pout.pos == write_pout.size)
1945               {
1946                 write_pout.pos = 0;
1947                 write_pout.size = 0;
1948               }
1949               fprintf (stderr, "LOG : %s sends a message to a DEVICE\n", dev.iface); //FIXME: debugging message
1950             }
1951           }
1952         }
1953         for (i = 0; i <= maxfd; i++)
1954         {
1955           if (FD_ISSET (i, &rfds))
1956           {
1957             if (i == STDIN_FILENO)
1958             {
1959               ssize_t ret = 
1960           read (i, readbuf, sizeof (readbuf));
1961               if (0 > ret)
1962               {
1963                 fprintf (stderr,
1964                          "Read error from STDIN: %s\n",
1965                          strerror (errno));
1966                 break; 
1967               }
1968               if (0 == ret)
1969               {
1970                 /* stop reading... */
1971                 stdin_open = 0;
1972               }
1973               else
1974               {
1975                 mst_receive (stdin_mst, readbuf, ret);
1976                 fprintf (stderr, "LOG : %s receives a message from STDIN\n", dev.iface); //FIXME: debugging message
1977               }
1978             } 
1979             else if (i == dev.fd_rfcomm) 
1980             {
1981               int readsocket;
1982               struct sockaddr_rc addr = { 0 };
1983               unsigned int opt = sizeof (addr);
1984               
1985               readsocket = accept (dev.fd_rfcomm, (struct sockaddr *) &addr, &opt);
1986               fprintf(stderr, "LOG : %s accepts a message\n", dev.iface); //FIXME: debugging message
1987               if (readsocket == -1)
1988               {
1989                 fprintf (stderr, "Failed to accept a connection on interface: %.*s\n", IFNAMSIZ, 
1990                     strerror (errno));
1991                 break;
1992               }
1993               else
1994               {
1995                 FD_SET (readsocket, &rfds);
1996                 maxfd = MAX (maxfd, readsocket);
1997                 
1998                 if (crt_rfds < MAX_PORTS)
1999                   rfds_list[crt_rfds++] = readsocket;
2000                 else
2001                 {
2002                   fprintf (stderr, "The limit for the read file descriptors list was \
2003                                   reached\n");
2004                   break;
2005                 }
2006               }
2007               
2008             } 
2009             else 
2010             {
2011               struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
2012               ssize_t ret;
2013               fprintf (stderr, "LOG : %s reads something from the socket\n", dev.iface);//FIXME : debugging message 
2014               rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
2015               ret =
2016                   read_from_the_socket ((void *)&i, (unsigned char *) &rrm->frame,
2017                               sizeof (write_std.buf) 
2018                   - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage) 
2019                   + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame), 
2020                   rrm);
2021               if (0 >= ret)
2022               {
2023                 int j;
2024                 FD_CLR (i, &rfds);
2025                 close (i);
2026                  /* Remove the socket from the list */
2027                 for (j = 0; j < crt_rfds; j++)
2028                 {
2029                   if (rfds_list[j] == i)
2030                   {
2031                     rfds_list[j] ^= rfds_list[crt_rfds - 1];
2032                     rfds_list[crt_rfds - 1] ^= rfds_list[j];
2033                     rfds_list[j] ^= rfds_list[crt_rfds - 1];
2034                     crt_rfds -= 1;
2035                     break;
2036                   }
2037                 }
2038
2039                 fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
2040                 break;
2041               }
2042               if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2043               {
2044                 write_std.size = ret 
2045             + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage) 
2046             - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2047                 rrm->header.size = htons (write_std.size);
2048                 rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2049               }
2050             }
2051           }
2052         }
2053       }
2054     }
2055     /* Error handling, try to clean up a bit at least */
2056     mst_destroy (stdin_mst);
2057     stdin_mst = NULL;
2058     sdp_close (dev.session);
2059     (void) close (dev.fd_rfcomm);
2060     (void) close (sendsocket);
2061     
2062     for (i = 0; i < crt_rfds; i++)
2063       (void) close (rfds_list[i]);
2064
2065     for (i = 0; i < neighbours.size; i++)
2066       (void) close (neighbours.fds[i]);
2067   #else
2068     struct HardwareInfos dev;
2069     struct GNUNET_NETWORK_Handle *sendsocket;
2070     struct GNUNET_NETWORK_FDSet *rfds;
2071     struct GNUNET_NETWORK_FDSet *wfds;
2072     struct GNUNET_NETWORK_Handle *rfds_list[MAX_PORTS];
2073     char readbuf[MAXLINE] = { 0 };
2074     SOCKADDR_BTH acc_addr = { 0 };
2075     int addr_len = sizeof (SOCKADDR_BTH);
2076     int broadcast, i, stdin_open, crt_rfds = 0;
2077     HANDLE stdin_handle = GetStdHandle (STD_INPUT_HANDLE);
2078     HANDLE stdout_handle = GetStdHandle (STD_OUTPUT_HANDLE);
2079     struct MessageStreamTokenizer *stdin_mst;
2080
2081     /* check the handles */
2082     if (stdin_handle == INVALID_HANDLE_VALUE) 
2083     {
2084       fprintf (stderr, "Failed to get the stdin handle\n");
2085       ExitProcess (2);
2086     }
2087
2088     if (stdout_handle == INVALID_HANDLE_VALUE) 
2089     {
2090       fprintf (stderr, "Failed to get the stdout handle\n");
2091       ExitProcess (2);
2092     }
2093
2094     /* initialize windows sockets */
2095     initialize_windows_sockets();
2096
2097     // /* test bluetooth socket family support */ --> it return false because the GNUNET_NETWORK_test_pf should also receive the type of socket (BTHPROTO_RFCOMM)
2098     // if (GNUNET_NETWORK_test_pf (AF_BTH) != GNUNET_OK)
2099     // {
2100     //   fprintf (stderr, "AF_BTH family is not supported\n");
2101     //   ExitProcess (2);
2102     // }
2103
2104      /* create the socket */
2105     dev.handle = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
2106     if (dev.handle == NULL)
2107     {
2108       fprintf (stderr, "Failed to create RFCOMM socket: ");
2109       print_last_error();
2110       ExitProcess (2);
2111     }
2112
2113
2114     if (open_device (&dev) == -1) 
2115     {
2116       fprintf (stderr, "Failed to open the device\n");
2117       print_last_error();
2118       if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
2119       {
2120         fprintf (stderr, "Failed to close the socket!\n");
2121         print_last_error();
2122       }
2123       ExitProcess (2);
2124     } 
2125
2126     if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (dev.handle, 1) )
2127     {
2128       fprintf (stderr, "Failed to change the socket mode\n");
2129       ExitProcess (2);
2130     }
2131    
2132     memset (&write_std, 0, sizeof (write_std));
2133     memset (&write_pout, 0, sizeof (write_pout)); 
2134     stdin_open = 1;
2135
2136     rfds = GNUNET_NETWORK_fdset_create ();
2137     wfds = GNUNET_NETWORK_fdset_create ();
2138     
2139   /* Send MAC address of the bluetooth interface to STDOUT first */
2140     {
2141       struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
2142
2143       macmsg.hdr.size = htons (sizeof (macmsg));
2144       macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
2145       memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy));
2146       memcpy (write_std.buf, &macmsg, sizeof (macmsg));
2147       write_std.size = sizeof (macmsg);
2148     }
2149       
2150    
2151     stdin_mst = mst_create (&stdin_send_hw, &dev);  
2152     stdin_open = 1;
2153
2154     int pos = 0;
2155     int stdin_pos = -1;
2156     int stdout_pos = -1;
2157     while (1)
2158     {
2159       broadcast = 0;
2160       pos = 0;
2161       stdin_pos = -1;
2162       stdout_pos = -1;
2163       sendsocket = NULL; //FIXME ???memleaks
2164       
2165       GNUNET_NETWORK_fdset_zero (rfds);    
2166       if ((0 == write_pout.size) && (1 == stdin_open))
2167       {
2168         stdin_pos = pos;
2169         pos +=1;
2170         GNUNET_NETWORK_fdset_handle_set (rfds, (struct GNUNET_DISK_FileHandle*) &stdin_handle); 
2171       }
2172
2173       if (0 == write_std.size)
2174       {
2175         pos += 1;
2176         GNUNET_NETWORK_fdset_set (rfds, dev.handle);
2177       }
2178       
2179       for (i = 0; i < crt_rfds; i++)
2180       {
2181         pos += 1;
2182         GNUNET_NETWORK_fdset_set (rfds, rfds_list[i]);
2183       }
2184
2185       GNUNET_NETWORK_fdset_zero (wfds);
2186       if (0 < write_std.size)
2187       {
2188         stdout_pos = pos;
2189         GNUNET_NETWORK_fdset_handle_set (wfds, (struct GNUNET_DISK_FileHandle*) &stdout_handle);
2190         // printf ("%s\n", write_std.buf);
2191         // memset (write_std.buf, 0, write_std.size);
2192         // write_std.size = 0; 
2193       }
2194
2195       if (0 < write_pout.size)
2196       {   
2197         if (strcmp (argv[1], "ff:ff:ff:ff:ff:ff") == 0) {
2198           fprintf(stderr, "LOG: BROADCAST! Skipping the message\n");
2199           // skip the message
2200           broadcast = 1;
2201           memset (write_pout.buf, 0, write_pout.size);
2202           write_pout.size = 0;
2203         } 
2204         else 
2205         {
2206           SOCKADDR_BTH addr;
2207           fprintf (stderr, "LOG : has a new message for %s\n", argv[1]);
2208           sendsocket = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
2209           
2210           if (sendsocket == NULL) 
2211           {
2212             fprintf (stderr, "Failed to create RFCOMM socket: \n");
2213             print_last_error();
2214             ExitProcess (2);
2215           }
2216           
2217           memset (&addr, 0, sizeof (addr));
2218           //addr.addressFamily = AF_BTH;
2219           if (SOCKET_ERROR == 
2220              WSAStringToAddress (argv[1], AF_BTH, NULL, (LPSOCKADDR) &addr, &addr_len))
2221           {
2222             fprintf (stderr, "Failed to translate the address: ");
2223             print_last_error();
2224             ExitProcess ( 2 ) ;
2225           }
2226           addr.port = get_channel (argv[1]);
2227           if (addr.port == -1)
2228           {
2229             fprintf (stderr, "Couldn't find the sdp service for the address: %s\n", argv[1]);
2230             memset (write_pout.buf, 0, write_pout.size);
2231             write_pout.size = 0;
2232             broadcast = 1; //skipping the select part
2233           }
2234           else
2235           {
2236             if (GNUNET_OK != GNUNET_NETWORK_socket_connect (sendsocket, (LPSOCKADDR)&addr, addr_len))
2237             {
2238               fprintf (stderr, "Failed to connect: ");
2239               print_last_error();
2240               ExitProcess (2);
2241             }
2242
2243             if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (sendsocket, 1) )
2244             {
2245               fprintf (stderr, "Failed to change the socket mode\n");
2246               ExitProcess (2);
2247             }
2248
2249             GNUNET_NETWORK_fdset_set (wfds, sendsocket);
2250           }
2251         }
2252       }
2253      
2254       if (broadcast == 0)
2255       {
2256         int retval = GNUNET_NETWORK_socket_select (rfds, wfds, NULL, GNUNET_TIME_relative_get_forever_());
2257         if (retval < 0)
2258         {
2259           fprintf (stderr, "Select error\n");
2260           ExitProcess (2);
2261         }
2262         //if (GNUNET_NETWORK_fdset_isset (wfds, (struct GNUNET_NETWORK_Handle*)&stdout_handle))
2263         if (retval == stdout_pos)
2264         {
2265           fprintf(stderr, "LOG : sends a message to STDOUT\n"); //FIXME: debugging message
2266           //ssize_t ret;
2267           //ret = GNUNET_NETWORK_socket_send ((struct GNUNET_NETWORK_Handle *)&stdout_handle,  write_std.buf + write_std.pos, write_std.size - write_std.pos);
2268           //ret = write (STDOUT_FILENO, write_std.buf + write_std.pos,  write_std.size - write_std.pos);
2269           DWORD ret;
2270           if (FALSE == WriteFile (stdout_handle,  write_std.buf + write_std.pos, write_std.size - write_std.pos, &ret, NULL))
2271           {
2272             fprintf (stderr, "Failed to write to STDOUT: ");
2273             print_last_error();
2274             break;
2275           }
2276
2277           if (ret <= 0)
2278           {
2279             fprintf (stderr, "Failed to write to STDOUT\n");
2280             ExitProcess (2);
2281           }
2282           
2283           write_std.pos += ret;
2284           if (write_std.pos == write_std.size)
2285           {
2286             write_std.pos = 0;
2287             write_std.size = 0;
2288           }
2289         }
2290         if (sendsocket != NULL)
2291         {
2292           if (GNUNET_NETWORK_fdset_isset (wfds, sendsocket))
2293           {
2294             ssize_t ret;
2295             ret = GNUNET_NETWORK_socket_send (sendsocket, write_pout.buf + write_pout.pos, 
2296                  write_pout.size - write_pout.pos);
2297             
2298             if (GNUNET_SYSERR == ret)
2299             {
2300               fprintf (stderr, "Failed to send to the socket. Closing the socket. Error: \n");
2301               print_last_error();
2302               if (GNUNET_NETWORK_socket_close (sendsocket) != GNUNET_OK)
2303               {
2304                 fprintf (stderr, "Failed to close the sendsocket!\n");
2305                 print_last_error();
2306               }
2307               ExitProcess (2);
2308             }
2309             else
2310             {
2311               write_pout.pos += ret;
2312               if ((write_pout.pos != write_pout.size) && (0 != ret))
2313               {
2314                 /* we should not get partial sends with packet-oriented devices... */
2315                 fprintf (stderr, "Write error, partial send: %u/%u\n",
2316                         (unsigned int) write_pout.pos,
2317                        (unsigned int) write_pout.size);
2318                 break;
2319               }
2320                 
2321               if (write_pout.pos == write_pout.size)
2322               {
2323                 write_pout.pos = 0;
2324                 write_pout.size = 0;
2325                   
2326               }
2327               fprintf(stderr, "LOG : sends a message to a DEVICE\n"); //FIXME: debugging message
2328             }
2329           }
2330         }
2331         
2332         //if (GNUNET_NETWORK_fdset_isset (rfds, (struct GNUNET_NETWORK_Handle*)&stdin_handle))
2333         if (retval == stdin_pos)
2334         {
2335           //ssize_t ret; 
2336           //ret = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)&stdin_handle, readbuf, sizeof (write_pout.buf));
2337           //ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
2338           DWORD ret;
2339           if (FALSE == ReadFile (stdin_handle, readbuf, sizeof (readbuf), &ret, NULL))  /* do nothing asynchronous */
2340           {
2341             fprintf (stderr, "Read error from STDIN: ");
2342             print_last_error();
2343             break;
2344           }
2345           if (0 == ret)
2346           {
2347             /* stop reading... */
2348             stdin_open = 0;
2349           } else {
2350             mst_receive (stdin_mst, readbuf, ret);
2351             fprintf (stderr, "LOG : receives a message from STDIN\n"); //FIXME: debugging message
2352           }
2353         }
2354         else
2355         if (GNUNET_NETWORK_fdset_isset (rfds, dev.handle))
2356         {
2357           fprintf (stderr, "LOG: accepting connection\n");
2358           struct GNUNET_NETWORK_Handle *readsocket;
2359           readsocket = GNUNET_NETWORK_socket_accept (dev.handle, (LPSOCKADDR)&acc_addr, &addr_len);  
2360           if (readsocket == NULL)
2361           {
2362             fprintf (stderr, "Accept error %d: ", GetLastError());
2363             print_last_error();
2364             ExitProcess (2);
2365           }
2366           else
2367           {
2368             if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (readsocket, 1) )
2369             {
2370               fprintf (stderr, "Failed to change the socket mode\n");
2371               ExitProcess (2);
2372             }
2373             GNUNET_NETWORK_fdset_set (rfds, readsocket);
2374
2375             if (crt_rfds < MAX_PORTS)
2376               rfds_list[crt_rfds++] = readsocket;
2377             else
2378             {
2379               fprintf (stderr, "The limit for the read file descriptors list was reached\n");
2380               break;
2381             }
2382           }
2383         }
2384         else
2385         for (i = 0; i < crt_rfds; i++)
2386         {
2387           if (GNUNET_NETWORK_fdset_isset (rfds, rfds_list[i]))
2388           {
2389             struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;  
2390             ssize_t ret;
2391             fprintf (stderr, "LOG: reading something from the socket\n");//FIXME : debugging message
2392             rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
2393             ret = read_from_the_socket (rfds_list[i], (unsigned char *) &rrm->frame,
2394                               sizeof (write_std.buf) 
2395                   - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage) 
2396                   + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame), 
2397                   rrm);
2398             if (0 >= ret)
2399             {
2400
2401               //TODO remove the socket from the list
2402               if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2403               {
2404                 fprintf (stderr, "Failed to close the sendsocket!\n");
2405                 print_last_error();
2406               }
2407
2408               fprintf (stderr, "Read error from raw socket: ");
2409               print_last_error();
2410               break;
2411           
2412             }
2413             if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2414             {
2415               write_std.size = ret 
2416           + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage) 
2417           - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2418               rrm->header.size = htons (write_std.size);
2419               rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2420             }
2421             break;
2422           }
2423         } 
2424       }
2425     }
2426     
2427     mst_destroy (stdin_mst);
2428     stdin_mst = NULL;
2429
2430     if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
2431     {
2432       fprintf (stderr, "Failed to close the socket!\n");
2433       print_last_error();
2434     }
2435
2436     for (i = 0; i < crt_rfds; i++)
2437     {
2438       if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2439       {
2440         fprintf (stderr, "Failed to close the socket!\n");
2441         print_last_error();
2442       }
2443     }
2444
2445     WSACleanup();
2446   #endif
2447   return 1;                     /* we never exit 'normally' */
2448 }