glitch in the license text detected by hyazinthe, thank you!
[oweals/gnunet.git] / src / transport / gnunet-helper-transport-bluetooth.c
1 /*
2    This file is part of GNUnet.
3    Copyright (C) 2010, 2011, 2012 GNUnet e.V.
4    Copyright (c) 2007, 2008, Andy Green <andy@warmcat.com>
5    Copyright Copyright (C) 2009 Thomas d'Otreppe
6
7    GNUnet is free software: you can redistribute it and/or modify it
8    under the terms of the GNU Affero General Public License as published
9    by the Free Software Foundation, either version 3 of the License,
10    or (at your 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    Affero General Public License for more details.
16 */
17 #include "gnunet_config.h"
18
19 #ifdef MINGW
20   #include "platform.h"
21   #include "gnunet_util_lib.h"
22   #include <bthdef.h>
23   #include <ws2bth.h>
24 #else
25   #define SOCKTYPE int
26   #include <bluetooth/bluetooth.h>
27   #include <bluetooth/hci.h>
28   #include <bluetooth/hci_lib.h>
29   #include <bluetooth/rfcomm.h>
30   #include <bluetooth/sdp.h>
31   #include <bluetooth/sdp_lib.h>
32   #include <errno.h>
33   #include <linux/if.h>
34   #include <stdio.h>
35   #include <stdlib.h>
36   #include <sys/ioctl.h>
37   #include <sys/param.h>
38   #include <sys/socket.h>
39   #include <sys/stat.h>
40   #include <sys/types.h>
41   #include <unistd.h>
42 #endif
43
44 #include "plugin_transport_wlan.h"
45 #include "gnunet_protocols.h"
46
47
48 /**
49  * Maximum number of ports assignable for RFCOMMM protocol.
50  */
51 #define MAX_PORTS 30
52
53 /**
54  * Maximum size of a message allowed in either direction
55  * (used for our receive and sent buffers).
56  */
57 #define MAXLINE 4096
58
59
60 /**
61  * Maximum number of loops without inquiring for new devices.
62  */
63 #define MAX_LOOPS 5
64
65 #ifdef MINGW
66   /* Maximum size of the interface's name */
67   #define IFNAMSIZ 16
68
69   #ifndef NS_BTH
70     #define NS_BTH 16
71   #endif
72   /**
73    * A copy of the MAC Address.
74    */
75   struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy
76   {
77     UINT8 mac[MAC_ADDR_SIZE];
78   };
79
80   /**
81    * The UUID used for the SDP service.
82    * {31191E56-FA7E-4517-870E-71B86BBCC52F}
83    */
84   #define GNUNET_BLUETOOTH_SDP_UUID \
85     { \
86       0x31, 0x19, 0x1E, 0x56, \
87       0xFA, 0x7E, \
88       0x45, 0x17, \
89       0x87, 0x0E, \
90       0x71, 0xB8, 0x6B, 0xBC, 0xC5, 0x2F \
91     }
92 #endif
93
94 /**
95  * In bluez library, the maximum name length of a device is 8
96  */
97 #define BLUEZ_DEVNAME_SIZE  8
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       GNUNET_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       GNUNET_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     GNUNET_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     GNUNET_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     int 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 (-1 == channel)
1001       fprintf (stderr,
1002                "Failed to find the listening channel for interface `%.*s': %s\n",
1003                IFNAMSIZ,
1004                dev->iface,
1005                strerror (errno));
1006
1007     return channel;
1008   }
1009 #endif
1010
1011 /**
1012  * Read from the socket and put the result into the buffer for transmission to 'stdout'.
1013  *
1014  * @param sock file descriptor for reading
1015  * @param buf buffer to read to; first bytes will be the 'struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame',
1016  *            followed by the actual payload
1017  * @param buf_size size of the buffer
1018  * @param ri where to write radiotap_rx info
1019  * @return number of bytes written to 'buf'
1020  */
1021 static ssize_t
1022 read_from_the_socket (void *sock,
1023       unsigned char *buf, size_t buf_size,
1024             struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri)
1025 {
1026   unsigned char tmpbuf[buf_size];
1027   ssize_t count;
1028
1029   #ifdef MINGW
1030    count = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)sock, tmpbuf, buf_size);
1031   #else
1032    count = read (*((int *)sock), tmpbuf, buf_size);
1033   #endif
1034
1035   if (0 > count)
1036   {
1037     if (EAGAIN == errno)
1038       return 0;
1039     #if MINGW
1040      print_last_error();
1041     #else
1042      fprintf (stderr, "Failed to read from the HCI socket: %s\n", strerror (errno));
1043     #endif
1044
1045     return -1;
1046   }
1047
1048   #ifdef LINUX
1049    /* Get the channel used */
1050    int len;
1051    struct sockaddr_rc  rc_addr = { 0 };
1052
1053    memset (&rc_addr, 0, sizeof (rc_addr));
1054    len = sizeof (rc_addr);
1055    if (0 > getsockname (*((int *)sock), (struct sockaddr *) &rc_addr, (socklen_t *) &len))
1056    {
1057      fprintf (stderr, "getsockname() call failed : %s\n", strerror (errno));
1058      return -1;
1059    }
1060
1061    memset (ri, 0, sizeof (*ri));
1062    ri->ri_channel = rc_addr.rc_channel;
1063   #endif
1064
1065   /* Detect CRC32 at the end */
1066   if (0 == check_crc_buf_osdep (tmpbuf, count - sizeof (uint32_t)))
1067   {
1068     count -= sizeof(uint32_t);
1069   }
1070
1071   GNUNET_memcpy (buf, tmpbuf, count);
1072
1073   return count;
1074 }
1075
1076
1077 /**
1078  * Open the bluetooth interface for reading/writing
1079  *
1080  * @param dev pointer to the device struct
1081  * @return 0 on success, non-zero on error
1082  */
1083 static int
1084 open_device (struct HardwareInfos *dev)
1085 {
1086   #ifdef MINGW
1087     SOCKADDR_BTH addr;
1088
1089     /* bind the RFCOMM socket to the interface */
1090     addr.addressFamily = AF_BTH;
1091     addr.btAddr = 0;
1092     addr.port = BT_PORT_ANY;
1093
1094     if (GNUNET_OK !=
1095         GNUNET_NETWORK_socket_bind (dev->handle, (const SOCKADDR*)&addr, sizeof (SOCKADDR_BTH)))
1096     {
1097       fprintf (stderr, "Failed to bind the socket: ");
1098       if (GetLastError() == WSAENETDOWN)
1099       {
1100         fprintf (stderr, "Please make sure that your Bluetooth device is ON!\n");
1101         ExitProcess (2);
1102       }
1103       print_last_error();
1104       return -1;
1105     }
1106
1107     /* start listening on the socket */
1108     if (GNUNET_NETWORK_socket_listen (dev->handle, 4) != GNUNET_OK)
1109     {
1110       fprintf (stderr, "Failed to listen on the socket: ");
1111       print_last_error();
1112       return -1;
1113     }
1114
1115     /* register the sdp service */
1116     if (register_service(dev) != 0)
1117     {
1118       fprintf (stderr, "Failed to register a service: ");
1119       print_last_error();
1120       return 1;
1121     }
1122   #else
1123     int i, dev_id = -1, fd_hci;
1124     struct
1125     {
1126       struct hci_dev_list_req list;
1127       struct hci_dev_req dev[HCI_MAX_DEV];
1128     } request;                              //used for detecting the local devices
1129     struct sockaddr_rc rc_addr = { 0 };    //used for binding
1130
1131     /* Initialize the neighbour structure */
1132     neighbours.dev_id = -1;
1133     for (i = 0; i < MAX_PORTS; i++)
1134       neighbours.fds[i] = -1;
1135
1136     /* Open a HCI socket */
1137     fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
1138
1139     if (fd_hci < 0)
1140     {
1141       fprintf (stderr,
1142                "Failed to create HCI socket: %s\n",
1143                strerror (errno));
1144       return -1;
1145     }
1146
1147     memset (&request, 0, sizeof(request));
1148     request.list.dev_num = HCI_MAX_DEV;
1149
1150     if (ioctl (fd_hci, HCIGETDEVLIST, (void *) &request) < 0)
1151     {
1152       fprintf (stderr,
1153                "ioctl(HCIGETDEVLIST) on interface `%.*s' failed: %s\n",
1154                IFNAMSIZ,
1155                dev->iface,
1156                strerror (errno));
1157       (void) close (fd_hci);
1158       return 1;
1159     }
1160
1161     /* Search for a device with dev->iface name */
1162     for (i = 0; i < request.list.dev_num; i++)
1163     {
1164       struct hci_dev_info dev_info;
1165
1166       memset (&dev_info, 0, sizeof(struct hci_dev_info));
1167       dev_info.dev_id = request.dev[i].dev_id;
1168       strncpy (dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE);
1169
1170       if (ioctl (fd_hci, HCIGETDEVINFO, (void *) &dev_info))
1171       {
1172         fprintf (stderr,
1173                  "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n",
1174                  IFNAMSIZ,
1175                  dev->iface,
1176                  strerror (errno));
1177         (void) close (fd_hci);
1178         return 1;
1179       }
1180
1181       if (strncmp (dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE) == 0)
1182       {
1183
1184         dev_id = dev_info.dev_id; //the device was found
1185         /**
1186          * Copy the MAC address to the device structure
1187          */
1188         GNUNET_memcpy (&dev->pl_mac, &dev_info.bdaddr, sizeof (bdaddr_t));
1189
1190         /* Check if the interface is up */
1191         if (hci_test_bit (HCI_UP, (void *) &dev_info.flags) == 0)
1192         {
1193           /* Bring the interface up */
1194           if (ioctl (fd_hci, HCIDEVUP, dev_info.dev_id))
1195           {
1196             fprintf (stderr,
1197                      "ioctl(HCIDEVUP) on interface `%.*s' failed: %s\n",
1198                      IFNAMSIZ,
1199                      dev->iface,
1200                      strerror (errno));
1201             (void) close (fd_hci);
1202             return 1;
1203           }
1204         }
1205
1206         /* Check if the device is discoverable */
1207         if (hci_test_bit (HCI_PSCAN, (void *) &dev_info.flags) == 0 ||
1208             hci_test_bit (HCI_ISCAN, (void *) &dev_info.flags) == 0)
1209         {
1210           /* Set interface Page Scan and Inqury Scan ON */
1211           struct hci_dev_req dev_req;
1212
1213           memset (&dev_req, 0, sizeof (dev_req));
1214           dev_req.dev_id = dev_info.dev_id;
1215           dev_req.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
1216
1217           if (ioctl (fd_hci, HCISETSCAN, (unsigned long) &dev_req))
1218           {
1219             fprintf (stderr,
1220                      "ioctl(HCISETSCAN) on interface `%.*s' failed: %s\n",
1221                      IFNAMSIZ,
1222                      dev->iface,
1223                      strerror (errno));
1224             (void) close (fd_hci);
1225             return 1;
1226           }
1227
1228         }
1229         break;
1230       }
1231
1232     }
1233
1234     /* Check if the interface was not found */
1235     if (-1 == dev_id)
1236     {
1237       fprintf (stderr,
1238                "The interface %s was not found\n",
1239                dev->iface);
1240       (void) close (fd_hci);
1241       return 1;
1242     }
1243
1244     /* Close the hci socket */
1245     (void) close(fd_hci);
1246
1247
1248
1249     /* Bind the rfcomm socket to the interface */
1250     memset (&rc_addr, 0, sizeof (rc_addr));
1251     rc_addr.rc_family = AF_BLUETOOTH;
1252     rc_addr.rc_bdaddr = *BDADDR_ANY;
1253
1254     if (bind_socket (dev->fd_rfcomm, &rc_addr) != 0)
1255     {
1256       fprintf (stderr,
1257                "Failed to bind interface `%.*s': %s\n",
1258                IFNAMSIZ,
1259                dev->iface,
1260                strerror (errno));
1261       return 1;
1262     }
1263
1264     /* Register a SDP service */
1265     if (register_service (dev, rc_addr.rc_channel) != 0)
1266     {
1267       fprintf (stderr,
1268                "Failed to register a service on interface `%.*s': %s\n",
1269                IFNAMSIZ,
1270                dev->iface, strerror (errno));
1271       return 1;
1272     }
1273
1274     /* Switch socket in listening mode */
1275     if (listen (dev->fd_rfcomm, 5) == -1) //FIXME: probably we need a bigger number
1276     {
1277       fprintf (stderr, "Failed to listen on socket for interface `%.*s': %s\n", IFNAMSIZ,
1278                dev->iface, strerror (errno));
1279       return 1;
1280     }
1281
1282   #endif
1283
1284   return 0;
1285 }
1286
1287
1288 /**
1289  * Set the header to sane values to make attacks more difficult
1290  *
1291  * @param taIeeeHeader pointer to the header of the packet
1292  * @param dev pointer to the Hardware_Infos struct
1293  *
1294  **** copy from gnunet-helper-transport-wlan.c ****
1295  */
1296 static void
1297 mac_set (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1298          const struct HardwareInfos *dev)
1299 {
1300   taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
1301   taIeeeHeader->addr3 = mac_bssid_gnunet;
1302
1303   #ifdef MINGW
1304     GNUNET_memcpy (&taIeeeHeader->addr2, &dev->pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1305   #else
1306     taIeeeHeader->addr2 = dev->pl_mac;
1307   #endif
1308 }
1309
1310 #ifdef LINUX
1311   /**
1312    * Test if the given interface name really corresponds to a bluetooth
1313    * device.
1314    *
1315    * @param iface name of the interface
1316    * @return 0 on success, 1 on error
1317    **** similar with the one from gnunet-helper-transport-wlan.c ****
1318    */
1319   static int
1320   test_bluetooth_interface (const char *iface)
1321   {
1322     char strbuf[512];
1323     struct stat sbuf;
1324     int ret;
1325
1326     ret = snprintf (strbuf, sizeof (strbuf),
1327         "/sys/class/bluetooth/%s/subsystem",
1328         iface);
1329     if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
1330     {
1331       fprintf (stderr,
1332          "Did not find 802.15.1 interface `%s'. Exiting.\n",
1333          iface);
1334       exit (1);
1335     }
1336     return 0;
1337   }
1338 #endif
1339
1340 /**
1341  * Test incoming packets mac for being our own.
1342  *
1343  * @param taIeeeHeader buffer of the packet
1344  * @param dev the Hardware_Infos struct
1345  * @return 0 if mac belongs to us, 1 if mac is for another target
1346  *
1347  **** same as the one from gnunet-helper-transport-wlan.c ****
1348  */
1349 static int
1350 mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1351           const struct HardwareInfos *dev)
1352 {
1353   static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
1354
1355   if ( (0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
1356        (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)) )
1357     return 0; /* some drivers set no Macs, then assume it is all for us! */
1358
1359   if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1360     return 1; /* not a GNUnet ad-hoc package */
1361   if ( (0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
1362        (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)) )
1363     return 0; /* for us, or broadcast */
1364   return 1; /* not for us */
1365 }
1366
1367
1368 /**
1369  * Process data from the stdin. Takes the message, forces the sender MAC to be correct
1370  * and puts it into our buffer for transmission to the receiver.
1371  *
1372  * @param cls pointer to the device struct ('struct HardwareInfos*')
1373  * @param hdr pointer to the start of the packet
1374  *
1375  **** same as the one from gnunet-helper-transport-wlan.c ****
1376  */
1377 static void
1378 stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1379 {
1380   struct HardwareInfos *dev = cls;
1381   const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header;
1382   struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *blueheader;
1383   size_t sendsize;
1384
1385   sendsize = ntohs (hdr->size);
1386   if ( (sendsize <
1387   sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
1388        (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) )
1389   {
1390     fprintf (stderr, "Received malformed message\n");
1391     exit (1);
1392   }
1393   sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) -
1394                sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1395   if (MAXLINE < sendsize)
1396   {
1397     fprintf (stderr, "Packet too big for buffer\n");
1398     exit (1);
1399   }
1400   header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
1401   GNUNET_memcpy (&write_pout.buf, &header->frame, sendsize);
1402   blueheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf;
1403
1404   /* payload contains MAC address, but we don't trust it, so we'll
1405   * overwrite it with OUR MAC address to prevent mischief */
1406   mac_set (blueheader, dev);
1407   GNUNET_memcpy (&blueheader->addr1, &header->frame.addr1,
1408           sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1409   write_pout.size = sendsize;
1410 }
1411
1412 #ifdef LINUX
1413   /**
1414    * Broadcast a HELLO message for peer discovery
1415    *
1416    * @param dev pointer to the device struct
1417    * @param dev pointer to the socket which was added to the set
1418    * @return 0 on success
1419    */
1420   static int
1421   send_broadcast (struct HardwareInfos *dev, int *sendsocket)
1422   {
1423     int new_device = 0;
1424     int loops = 0;
1425
1426    search_for_devices:
1427     if ((neighbours.size == neighbours.pos && new_device == 1) || neighbours.size == 0)
1428     {
1429    inquiry_devices:   //skip the conditions and force a inquiry for new devices
1430       {
1431       /**
1432        * It means that I sent HELLO messages to all the devices from the list and I should search
1433        * for new ones or that this is the first time when I do a search.
1434        */
1435       inquiry_info *devices = NULL;
1436       int i, responses, max_responses = MAX_PORTS;
1437
1438       /* sanity checks */
1439       if (neighbours.size >= MAX_PORTS)
1440       {
1441         fprintf (stderr, "%.*s reached the top limit for the discovarable devices\n", IFNAMSIZ, dev->iface);
1442         return 2;
1443       }
1444
1445       /* Get the device id */
1446       if (neighbours.dev_id == -1)
1447       {
1448         char addr[19] = { 0 }; //the device MAC address
1449
1450         ba2str ((bdaddr_t *) &dev->pl_mac, addr);
1451         neighbours.dev_id = hci_devid (addr);
1452         if (neighbours.dev_id < 0)
1453         {
1454           fprintf (stderr, "Failed to get the device id for interface %.*s : %s\n", IFNAMSIZ,
1455                   dev->iface, strerror (errno));
1456           return 1;
1457         }
1458       }
1459
1460       devices = malloc (max_responses * sizeof (inquiry_info));
1461       if (devices == NULL)
1462       {
1463         fprintf (stderr, "Failed to allocate memory for inquiry info list on interface %.*s\n", IFNAMSIZ,
1464                 dev->iface);
1465         return 1;
1466       }
1467
1468       responses = hci_inquiry (neighbours.dev_id, 8, max_responses, NULL, &devices, IREQ_CACHE_FLUSH);
1469       if (responses < 0)
1470       {
1471         fprintf (stderr, "Failed to inquiry on interface %.*s\n", IFNAMSIZ, dev->iface);
1472         return 1;
1473       }
1474
1475       fprintf (stderr, "LOG : Found %d devices\n", responses); //FIXME delete it after debugging stage
1476
1477       if (responses == 0)
1478       {
1479         fprintf (stderr, "LOG : No devices discoverable\n");
1480         return 1;
1481       }
1482
1483       for (i = 0; i < responses; i++)
1484       {
1485         int j;
1486         int found = 0;
1487
1488         /* sanity check */
1489         if (i >= MAX_PORTS)
1490         {
1491           fprintf (stderr, "%.*s reached the top limit for the discoverable devices (after inquiry)\n", IFNAMSIZ,
1492                   dev->iface);
1493           return 2;
1494         }
1495
1496         /* Search if the address already exists on the list */
1497         for (j = 0; j < neighbours.size; j++)
1498         {
1499           if (memcmp (&(devices + i)->bdaddr, &(neighbours.devices[j]), sizeof (bdaddr_t)) == 0)
1500           {
1501             found = 1;
1502             fprintf (stderr, "LOG : the device already exists on the list\n"); //FIXME debugging message
1503             break;
1504           }
1505         }
1506
1507         if (found == 0)
1508         {
1509           char addr[19] = { 0 };
1510
1511           ba2str (&(devices +i)->bdaddr, addr);
1512           fprintf (stderr, "LOG : %s was added to the list\n", addr); //FIXME debugging message
1513           GNUNET_memcpy (&(neighbours.devices[neighbours.size++]), &(devices + i)->bdaddr, sizeof (bdaddr_t));
1514         }
1515       }
1516
1517       free (devices);
1518       }
1519     }
1520
1521     int connection_successful = 0;
1522     struct sockaddr_rc addr_rc = { 0 };
1523     int errno_copy = 0;
1524     addr_rc.rc_family = AF_BLUETOOTH;
1525
1526     /* Try to connect to a new device from the list */
1527     while (neighbours.pos < neighbours.size)
1528     {
1529       /* Check if we are already connected to this device */
1530       if (neighbours.fds[neighbours.pos] == -1)
1531       {
1532
1533         memset (&addr_rc.rc_bdaddr, 0, sizeof (addr_rc.rc_bdaddr));
1534         GNUNET_memcpy (&addr_rc.rc_bdaddr, &(neighbours.devices[neighbours.pos]), sizeof (addr_rc.rc_bdaddr));
1535
1536         addr_rc.rc_channel = get_channel (dev, addr_rc.rc_bdaddr);
1537
1538         *sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1539         if ( (-1 < *sendsocket) &&
1540              (0 == connect (*sendsocket,
1541                             (struct sockaddr *) &addr_rc,
1542                             sizeof (addr_rc))) )
1543         {
1544           neighbours.fds[neighbours.pos++] = *sendsocket;
1545           connection_successful = 1;
1546           char addr[19] = { 0 };
1547           ba2str (&(neighbours.devices[neighbours.pos - 1]), addr);
1548           fprintf (stderr, "LOG : Connected to %s\n", addr);
1549           break;
1550         }
1551         else
1552         {
1553           char addr[19] = { 0 };
1554           errno_copy = errno;  //Save a copy for later
1555
1556           if (-1 != *sendsocket)
1557           {
1558             (void) close (*sendsocket);
1559             *sendsocket = -1;
1560           }
1561           ba2str (&(neighbours.devices[neighbours.pos]), addr);
1562           fprintf (stderr,
1563                    "LOG : Couldn't connect on device %s, error : %s\n",
1564                    addr,
1565                    strerror (errno));
1566           if (errno != ECONNREFUSED) //FIXME be sure that this works
1567           {
1568             fprintf (stderr, "LOG : Removes %d device from the list\n", neighbours.pos);
1569             /* Remove the device from the list */
1570             GNUNET_memcpy (&neighbours.devices[neighbours.pos], &neighbours.devices[neighbours.size - 1], sizeof (bdaddr_t));
1571             memset (&neighbours.devices[neighbours.size - 1], 0, sizeof (bdaddr_t));
1572             neighbours.fds[neighbours.pos] = neighbours.fds[neighbours.size - 1];
1573             neighbours.fds[neighbours.size - 1] = -1;
1574             neighbours.size -= 1;
1575           }
1576
1577           neighbours.pos += 1;
1578
1579           if (neighbours.pos >= neighbours.size)
1580               neighbours.pos = 0;
1581
1582           loops += 1;
1583
1584           if (loops == MAX_LOOPS) //don't get stuck trying to connect to one device
1585             return 1;
1586         }
1587       }
1588       else
1589       {
1590         fprintf (stderr, "LOG : Search for a new device\n"); //FIXME debugging message
1591         neighbours.pos += 1;
1592       }
1593     }
1594
1595     /* Cycle on the list */
1596     if (neighbours.pos == neighbours.size)
1597     {
1598       neighbours.pos = 0;
1599       searching_devices_count += 1;
1600
1601       if (searching_devices_count == MAX_LOOPS)
1602       {
1603         fprintf (stderr, "LOG : Force to inquiry for new devices\n");
1604         searching_devices_count = 0;
1605         goto inquiry_devices;
1606       }
1607     }
1608    /* If a new device wasn't found, search an old one */
1609     if (connection_successful == 0)
1610     {
1611       int loop_check = neighbours.pos;
1612       while (neighbours.fds[neighbours.pos] == -1)
1613       {
1614         if (neighbours.pos == neighbours.size)
1615           neighbours.pos = 0;
1616
1617         if (neighbours.pos == loop_check)
1618         {
1619           if (errno_copy == ECONNREFUSED)
1620           {
1621             fprintf (stderr, "LOG : No device found. Go back and search again\n"); //FIXME debugging message
1622             new_device = 1;
1623             loops += 1;
1624             goto search_for_devices;
1625           }
1626           else
1627           {
1628             return 1; // Skip the broadcast message
1629           }
1630         }
1631
1632         neighbours.pos += 1;
1633       }
1634
1635       *sendsocket = neighbours.fds[neighbours.pos++];
1636     }
1637
1638     return 0;
1639   }
1640 #endif
1641
1642 /**
1643  * Main function of the helper.  This code accesses a bluetooth interface
1644  * forwards traffic in both directions between the bluetooth interface and
1645  * stdin/stdout of this process.  Error messages are written to stderr.
1646  *
1647  * @param argc number of arguments, must be 2
1648  * @param argv arguments only argument is the name of the interface (i.e. 'hci0')
1649  * @return 0 on success (never happens, as we don't return unless aborted), 1 on error
1650  *
1651  **** similar to gnunet-helper-transport-wlan.c ****
1652  */
1653 int
1654 main (int argc, char *argv[])
1655 {
1656 #ifdef LINUX
1657     struct HardwareInfos dev;
1658     char readbuf[MAXLINE];
1659     int maxfd;
1660     fd_set rfds;
1661     fd_set wfds;
1662     int stdin_open;
1663     struct MessageStreamTokenizer *stdin_mst;
1664     int raw_eno, i;
1665     int crt_rfds = 0, rfds_list[MAX_PORTS];
1666     int broadcast, sendsocket;
1667
1668     /* Assert privs so we can modify the firewall rules! */
1669     {
1670 #ifdef HAVE_SETRESUID
1671       uid_t uid = getuid ();
1672
1673       if (0 != setresuid (uid, 0, 0))
1674       {
1675         fprintf (stderr, 
1676                  "Failed to setresuid to root: %s\n",
1677                  strerror (errno));
1678         return 254;
1679       }
1680 #else
1681       if (0 != seteuid (0))
1682       {
1683         fprintf (stderr, 
1684                  "Failed to seteuid back to root: %s\n", strerror (errno));
1685         return 254;
1686       }
1687 #endif
1688     }
1689
1690     /* Make use of SGID capabilities on POSIX */
1691     memset (&dev, 0, sizeof (dev));
1692     dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1693     raw_eno = errno; /* remember for later */
1694
1695     /* Now that we've dropped root rights, we can do error checking */
1696     if (2 != argc)
1697     {
1698       fprintf (stderr, "You must specify the name of the interface as the first \
1699                         and only argument to this program.\n");
1700       if (-1 != dev.fd_rfcomm)
1701         (void) close (dev.fd_rfcomm);
1702       return 1;
1703     }
1704
1705     if (-1 == dev.fd_rfcomm)
1706     {
1707       fprintf (stderr, "Failed to create a RFCOMM socket: %s\n", strerror (raw_eno));
1708       return 1;
1709     }
1710     if (dev.fd_rfcomm >= FD_SETSIZE)
1711     {
1712       fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1713                dev.fd_rfcomm, FD_SETSIZE);
1714       (void) close (dev.fd_rfcomm);
1715       return 1;
1716     }
1717     if (0 != test_bluetooth_interface (argv[1]))
1718     {
1719       (void) close (dev.fd_rfcomm);
1720       return 1;
1721     }
1722     strncpy (dev.iface, argv[1], IFNAMSIZ);
1723     if (0 != open_device (&dev))
1724     {
1725       (void) close (dev.fd_rfcomm);
1726       return 1;
1727     }
1728
1729     /* Drop privs */
1730     {
1731       uid_t uid = getuid ();
1732   #ifdef HAVE_SETRESUID
1733       if (0 != setresuid (uid, uid, uid))
1734       {
1735         fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1736         if (-1 != dev.fd_rfcomm)
1737     (void) close (dev.fd_rfcomm);
1738         return 1;
1739       }
1740   #else
1741       if (0 != (setuid (uid) | seteuid (uid)))
1742       {
1743         fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
1744         if (-1 != dev.fd_rfcomm)
1745     (void) close (dev.fd_rfcomm);
1746         return 1;
1747       }
1748   #endif
1749     }
1750
1751    /* Send MAC address of the bluetooth interface to STDOUT first */
1752     {
1753       struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
1754
1755       macmsg.hdr.size = htons (sizeof (macmsg));
1756       macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
1757       GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1758       GNUNET_memcpy (write_std.buf, &macmsg, sizeof (macmsg));
1759       write_std.size = sizeof (macmsg);
1760     }
1761
1762
1763     stdin_mst = mst_create (&stdin_send_hw, &dev);
1764     stdin_open = 1;
1765
1766    /**
1767     * TODO : I should make the time out of a mac endpoint smaller and check if the rate
1768     * from get_wlan_header (plugin_transport_bluetooth.c) is correct.
1769     */
1770    while (1)
1771     {
1772       maxfd = -1;
1773       broadcast = 0;
1774       sendsocket = -1;
1775
1776       FD_ZERO (&rfds);
1777       if ((0 == write_pout.size) && (1 == stdin_open))
1778       {
1779         FD_SET (STDIN_FILENO, &rfds);
1780         maxfd = MAX (maxfd, STDIN_FILENO);
1781       }
1782       if (0 == write_std.size)
1783       {
1784         FD_SET (dev.fd_rfcomm, &rfds);
1785         maxfd = MAX (maxfd, dev.fd_rfcomm);
1786       }
1787
1788       for (i = 0; i < crt_rfds; i++)  // it can receive messages from multiple devices
1789       {
1790         FD_SET (rfds_list[i], &rfds);
1791         maxfd = MAX (maxfd, rfds_list[i]);
1792       }
1793       FD_ZERO (&wfds);
1794       if (0 < write_std.size)
1795       {
1796         FD_SET (STDOUT_FILENO, &wfds);
1797         maxfd = MAX (maxfd, STDOUT_FILENO);
1798       }
1799       if (0 < write_pout.size) //it can send messages only to one device per loop
1800       {
1801         struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *frame;
1802         /* Get the destination address */
1803         frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) write_pout.buf;
1804
1805         if (memcmp (&frame->addr1, &dev.pl_mac,
1806                     sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1807         {
1808           broadcast = 1;
1809           memset (&write_pout, 0, sizeof (write_pout)); //clear the buffer
1810         }
1811         else if (memcmp (&frame->addr1, &broadcast_address,
1812                   sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1813         {
1814           fprintf (stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n", dev.iface, neighbours.pos, neighbours.size); //FIXME: debugging message
1815
1816           if (send_broadcast(&dev, &sendsocket) != 0) //if the searching wasn't successful don't get stuck on the select stage
1817           {
1818             broadcast = 1;
1819             memset (&write_pout, 0, sizeof (write_pout)); //remove the message
1820             fprintf (stderr, "LOG : Skipping the broadcast message (pos %d, size %d)\n", neighbours.pos, neighbours.size);
1821           }
1822           else
1823           {
1824             FD_SET (sendsocket, &wfds);
1825             maxfd = MAX (maxfd, sendsocket);
1826           }
1827         }
1828         else
1829         {
1830           int found = 0;
1831           int pos = 0;
1832           /* Search if the address already exists on the list */
1833           for (i = 0; i < neighbours.size; i++)
1834           {
1835             if (memcmp (&frame->addr1, &(neighbours.devices[i]), sizeof (bdaddr_t)) == 0)
1836             {
1837               pos = i;
1838               if (neighbours.fds[i] != -1)
1839               {
1840                 found = 1;  //save the position where it was found
1841                 FD_SET (neighbours.fds[i], &wfds);
1842                 maxfd = MAX (maxfd, neighbours.fds[i]);
1843                 sendsocket = neighbours.fds[i];
1844                 fprintf (stderr, "LOG: the address was found in the list\n");
1845                 break;
1846               }
1847             }
1848           }
1849           if (found == 0)
1850           {
1851             int status;
1852             struct sockaddr_rc addr = { 0 };
1853
1854             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,
1855                     frame->addr1.mac[5], frame->addr1.mac[4], frame->addr1.mac[3],
1856                     frame->addr1.mac[2], frame->addr1.mac[1], frame->addr1.mac[0]); //FIXME: debugging message
1857
1858             sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1859
1860             if (sendsocket < 0)
1861             {
1862               fprintf (stderr, "Failed to create a RFCOMM socket (sending stage): %s\n",
1863                       strerror (errno));
1864               return -1;
1865             }
1866
1867             GNUNET_memcpy (&addr.rc_bdaddr, &frame->addr1, sizeof (bdaddr_t));
1868             addr.rc_family = AF_BLUETOOTH;
1869             addr.rc_channel = get_channel (&dev, addr.rc_bdaddr);
1870
1871             int tries = 0;
1872             connect_retry:
1873             status = connect (sendsocket, (struct sockaddr *) &addr, sizeof (addr));
1874             if (0 != status && errno != EAGAIN)
1875             {
1876               if (errno == ECONNREFUSED && tries < 2)
1877               {
1878                 fprintf (stderr, "LOG : %.*s failed to connect. Trying again!\n", IFNAMSIZ, dev.iface);
1879                 tries++;
1880                 goto connect_retry;
1881               }
1882               else if (errno == EBADF)
1883               {
1884                 fprintf (stderr, "LOG : %s failed to connect : %s. Skip it!\n", dev.iface, strerror (errno));
1885                 memset (&write_pout, 0, sizeof (write_pout));
1886                 broadcast = 1;
1887               }
1888               else
1889               {
1890                 fprintf (stderr, "LOG : %s failed to connect : %s. Try again later!\n", dev.iface, strerror (errno));
1891                 memset (&write_pout, 0, sizeof (write_pout));
1892                 broadcast = 1;
1893               }
1894
1895             }
1896             else
1897             {
1898               FD_SET (sendsocket, &wfds);
1899               maxfd = MAX (maxfd, sendsocket);
1900               fprintf (stderr, "LOG : Connection successful\n");
1901               if (pos != 0) // save the socket
1902               {
1903                 neighbours.fds[pos] = sendsocket;
1904               }
1905               else
1906               {
1907                 /* Add the new device to the discovered devices list */
1908                 if (neighbours.size < MAX_PORTS)
1909                 {
1910                   neighbours.fds[neighbours.size] = sendsocket;
1911                   GNUNET_memcpy (&(neighbours.devices[neighbours.size++]), &addr.rc_bdaddr, sizeof (bdaddr_t));
1912                 }
1913                 else
1914                 {
1915                   fprintf (stderr, "The top limit for the discovarable devices' list was reached\n");
1916                 }
1917               }
1918             }
1919           }
1920         }
1921       }
1922
1923       if (broadcast == 0)
1924       {
1925         /* Select a fd which is ready for action :) */
1926         {
1927           int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
1928           if ((-1 == retval) && (EINTR == errno))
1929       continue;
1930           if (0 > retval && errno != EBADF)   // we handle BADF errors later
1931           {
1932       fprintf (stderr, "select failed: %s\n", strerror (errno));
1933       break;
1934           }
1935         }
1936         if (FD_ISSET (STDOUT_FILENO , &wfds))
1937         {
1938           ssize_t ret =
1939               write (STDOUT_FILENO, write_std.buf + write_std.pos,
1940                      write_std.size - write_std.pos);
1941           if (0 > ret)
1942           {
1943             fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1944             break;
1945           }
1946           write_std.pos += ret;
1947           if (write_std.pos == write_std.size)
1948           {
1949             write_std.pos = 0;
1950             write_std.size = 0;
1951           }
1952           fprintf (stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); //FIXME: debugging message
1953
1954         }
1955         if (-1 != sendsocket)
1956         {
1957           if (FD_ISSET (sendsocket , &wfds))
1958           {
1959             ssize_t ret = write (sendsocket,
1960                                  write_pout.buf + write_std.pos,
1961                                  write_pout.size - write_pout.pos);
1962             if (0 > ret) //FIXME should I first check the error type?
1963             {
1964               fprintf (stderr, "Failed to write to bluetooth device: %s. Closing the socket!\n",
1965                        strerror (errno));
1966               for (i = 0; i < neighbours.size; i++)
1967               {
1968                 if (neighbours.fds[i] == sendsocket)
1969                 {
1970                   (void) close(sendsocket);
1971                   neighbours.fds[i] = -1;
1972                   break;
1973                 }
1974               }
1975               /* Remove the message */
1976               memset (&write_pout.buf + write_std.pos, 0, (write_pout.size - write_pout.pos));
1977               write_pout.pos = 0 ;
1978               write_pout.size = 0;
1979             }
1980             else
1981             {
1982               write_pout.pos += ret;
1983               if ((write_pout.pos != write_pout.size) && (0 != ret))
1984               {
1985                 /* We should not get partial sends with packet-oriented devices... */
1986                 fprintf (stderr, "Write error, partial send: %u/%u\n",
1987                         (unsigned int) write_pout.pos,
1988                         (unsigned int) write_pout.size);
1989                 break;
1990               }
1991
1992               if (write_pout.pos == write_pout.size)
1993               {
1994                 write_pout.pos = 0;
1995                 write_pout.size = 0;
1996               }
1997               fprintf (stderr, "LOG : %s sends a message to a DEVICE\n", dev.iface); //FIXME: debugging message
1998             }
1999           }
2000         }
2001         for (i = 0; i <= maxfd; i++)
2002         {
2003           if (FD_ISSET (i, &rfds))
2004           {
2005             if (i == STDIN_FILENO)
2006             {
2007               ssize_t ret =
2008           read (i, readbuf, sizeof (readbuf));
2009               if (0 > ret)
2010               {
2011                 fprintf (stderr,
2012                          "Read error from STDIN: %s\n",
2013                          strerror (errno));
2014                 break;
2015               }
2016               if (0 == ret)
2017               {
2018                 /* stop reading... */
2019                 stdin_open = 0;
2020               }
2021               else
2022               {
2023                 mst_receive (stdin_mst, readbuf, ret);
2024                 fprintf (stderr, "LOG : %s receives a message from STDIN\n", dev.iface); //FIXME: debugging message
2025               }
2026             }
2027             else if (i == dev.fd_rfcomm)
2028             {
2029               int readsocket;
2030               struct sockaddr_rc addr = { 0 };
2031               unsigned int opt = sizeof (addr);
2032
2033               readsocket = accept (dev.fd_rfcomm, (struct sockaddr *) &addr, &opt);
2034               fprintf(stderr, "LOG : %s accepts a message\n", dev.iface); //FIXME: debugging message
2035               if (readsocket == -1)
2036               {
2037                 fprintf (stderr, "Failed to accept a connection on interface: %.*s\n", IFNAMSIZ,
2038                     strerror (errno));
2039                 break;
2040               }
2041               else
2042               {
2043                 FD_SET (readsocket, &rfds);
2044                 maxfd = MAX (maxfd, readsocket);
2045
2046                 if (crt_rfds < MAX_PORTS)
2047                   rfds_list[crt_rfds++] = readsocket;
2048                 else
2049                 {
2050                   fprintf (stderr, "The limit for the read file descriptors list was \
2051                                   reached\n");
2052                   break;
2053                 }
2054               }
2055
2056             }
2057             else
2058             {
2059               struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
2060               ssize_t ret;
2061               fprintf (stderr, "LOG : %s reads something from the socket\n", dev.iface);//FIXME : debugging message
2062               rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
2063               ret =
2064                   read_from_the_socket ((void *)&i, (unsigned char *) &rrm->frame,
2065                               sizeof (write_std.buf)
2066                   - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2067                   + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2068                   rrm);
2069               if (0 >= ret)
2070               {
2071                 int j;
2072                 FD_CLR (i, &rfds);
2073                 close (i);
2074                  /* Remove the socket from the list */
2075                 for (j = 0; j < crt_rfds; j++)
2076                 {
2077                   if (rfds_list[j] == i)
2078                   {
2079                     rfds_list[j] ^= rfds_list[crt_rfds - 1];
2080                     rfds_list[crt_rfds - 1] ^= rfds_list[j];
2081                     rfds_list[j] ^= rfds_list[crt_rfds - 1];
2082                     crt_rfds -= 1;
2083                     break;
2084                   }
2085                 }
2086
2087                 fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
2088                 break;
2089               }
2090               if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2091               {
2092                 write_std.size = ret
2093             + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2094             - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2095                 rrm->header.size = htons (write_std.size);
2096                 rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2097               }
2098             }
2099           }
2100         }
2101       }
2102     }
2103     /* Error handling, try to clean up a bit at least */
2104     mst_destroy (stdin_mst);
2105     stdin_mst = NULL;
2106     sdp_close (dev.session);
2107     (void) close (dev.fd_rfcomm);
2108     if (-1 != sendsocket)
2109       (void) close (sendsocket);
2110
2111     for (i = 0; i < crt_rfds; i++)
2112       (void) close (rfds_list[i]);
2113
2114     for (i = 0; i < neighbours.size; i++)
2115       (void) close (neighbours.fds[i]);
2116   #else
2117     struct HardwareInfos dev;
2118     struct GNUNET_NETWORK_Handle *sendsocket;
2119     struct GNUNET_NETWORK_FDSet *rfds;
2120     struct GNUNET_NETWORK_FDSet *wfds;
2121     struct GNUNET_NETWORK_Handle *rfds_list[MAX_PORTS];
2122     char readbuf[MAXLINE] = { 0 };
2123     SOCKADDR_BTH acc_addr = { 0 };
2124     int addr_len = sizeof (SOCKADDR_BTH);
2125     int broadcast, i, stdin_open, crt_rfds = 0;
2126     HANDLE stdin_handle = GetStdHandle (STD_INPUT_HANDLE);
2127     HANDLE stdout_handle = GetStdHandle (STD_OUTPUT_HANDLE);
2128     struct MessageStreamTokenizer *stdin_mst;
2129
2130     /* check the handles */
2131     if (stdin_handle == INVALID_HANDLE_VALUE)
2132     {
2133       fprintf (stderr, "Failed to get the stdin handle\n");
2134       ExitProcess (2);
2135     }
2136
2137     if (stdout_handle == INVALID_HANDLE_VALUE)
2138     {
2139       fprintf (stderr, "Failed to get the stdout handle\n");
2140       ExitProcess (2);
2141     }
2142
2143     /* initialize windows sockets */
2144     initialize_windows_sockets();
2145
2146     // /* test bluetooth socket family support */ --> it return false because the GNUNET_NETWORK_test_pf should also receive the type of socket (BTHPROTO_RFCOMM)
2147     // if (GNUNET_NETWORK_test_pf (AF_BTH) != GNUNET_OK)
2148     // {
2149     //   fprintf (stderr, "AF_BTH family is not supported\n");
2150     //   ExitProcess (2);
2151     // }
2152
2153      /* create the socket */
2154     dev.handle = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
2155     if (dev.handle == NULL)
2156     {
2157       fprintf (stderr, "Failed to create RFCOMM socket: ");
2158       print_last_error();
2159       ExitProcess (2);
2160     }
2161
2162
2163     if (open_device (&dev) == -1)
2164     {
2165       fprintf (stderr, "Failed to open the device\n");
2166       print_last_error();
2167       if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
2168       {
2169         fprintf (stderr, "Failed to close the socket!\n");
2170         print_last_error();
2171       }
2172       ExitProcess (2);
2173     }
2174
2175     if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (dev.handle, 1) )
2176     {
2177       fprintf (stderr, "Failed to change the socket mode\n");
2178       ExitProcess (2);
2179     }
2180
2181     memset (&write_std, 0, sizeof (write_std));
2182     memset (&write_pout, 0, sizeof (write_pout));
2183     stdin_open = 1;
2184
2185     rfds = GNUNET_NETWORK_fdset_create ();
2186     wfds = GNUNET_NETWORK_fdset_create ();
2187
2188   /* Send MAC address of the bluetooth interface to STDOUT first */
2189     {
2190       struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
2191
2192       macmsg.hdr.size = htons (sizeof (macmsg));
2193       macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
2194       GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy));
2195       GNUNET_memcpy (write_std.buf, &macmsg, sizeof (macmsg));
2196       write_std.size = sizeof (macmsg);
2197     }
2198
2199
2200     stdin_mst = mst_create (&stdin_send_hw, &dev);
2201     stdin_open = 1;
2202
2203     int pos = 0;
2204     int stdin_pos = -1;
2205     int stdout_pos = -1;
2206     while (1)
2207     {
2208       broadcast = 0;
2209       pos = 0;
2210       stdin_pos = -1;
2211       stdout_pos = -1;
2212       sendsocket = NULL; //FIXME ???memleaks
2213
2214       GNUNET_NETWORK_fdset_zero (rfds);
2215       if ((0 == write_pout.size) && (1 == stdin_open))
2216       {
2217         stdin_pos = pos;
2218         pos +=1;
2219         GNUNET_NETWORK_fdset_handle_set (rfds, (struct GNUNET_DISK_FileHandle*) &stdin_handle);
2220       }
2221
2222       if (0 == write_std.size)
2223       {
2224         pos += 1;
2225         GNUNET_NETWORK_fdset_set (rfds, dev.handle);
2226       }
2227
2228       for (i = 0; i < crt_rfds; i++)
2229       {
2230         pos += 1;
2231         GNUNET_NETWORK_fdset_set (rfds, rfds_list[i]);
2232       }
2233
2234       GNUNET_NETWORK_fdset_zero (wfds);
2235       if (0 < write_std.size)
2236       {
2237         stdout_pos = pos;
2238         GNUNET_NETWORK_fdset_handle_set (wfds, (struct GNUNET_DISK_FileHandle*) &stdout_handle);
2239         // printf ("%s\n", write_std.buf);
2240         // memset (write_std.buf, 0, write_std.size);
2241         // write_std.size = 0;
2242       }
2243
2244       if (0 < write_pout.size)
2245       {
2246         if (strcmp (argv[1], "ff:ff:ff:ff:ff:ff") == 0) {
2247           fprintf(stderr, "LOG: BROADCAST! Skipping the message\n");
2248           // skip the message
2249           broadcast = 1;
2250           memset (write_pout.buf, 0, write_pout.size);
2251           write_pout.size = 0;
2252         }
2253         else
2254         {
2255           SOCKADDR_BTH addr;
2256           fprintf (stderr, "LOG : has a new message for %s\n", argv[1]);
2257           sendsocket = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
2258
2259           if (sendsocket == NULL)
2260           {
2261             fprintf (stderr, "Failed to create RFCOMM socket: \n");
2262             print_last_error();
2263             ExitProcess (2);
2264           }
2265
2266           memset (&addr, 0, sizeof (addr));
2267           //addr.addressFamily = AF_BTH;
2268           if (SOCKET_ERROR ==
2269              WSAStringToAddress (argv[1], AF_BTH, NULL, (LPSOCKADDR) &addr, &addr_len))
2270           {
2271             fprintf (stderr, "Failed to translate the address: ");
2272             print_last_error();
2273             ExitProcess ( 2 ) ;
2274           }
2275           addr.port = get_channel (argv[1]);
2276           if (addr.port == -1)
2277           {
2278             fprintf (stderr, "Couldn't find the sdp service for the address: %s\n", argv[1]);
2279             memset (write_pout.buf, 0, write_pout.size);
2280             write_pout.size = 0;
2281             broadcast = 1; //skipping the select part
2282           }
2283           else
2284           {
2285             if (GNUNET_OK != GNUNET_NETWORK_socket_connect (sendsocket, (LPSOCKADDR)&addr, addr_len))
2286             {
2287               fprintf (stderr, "Failed to connect: ");
2288               print_last_error();
2289               ExitProcess (2);
2290             }
2291
2292             if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (sendsocket, 1) )
2293             {
2294               fprintf (stderr, "Failed to change the socket mode\n");
2295               ExitProcess (2);
2296             }
2297
2298             GNUNET_NETWORK_fdset_set (wfds, sendsocket);
2299           }
2300         }
2301       }
2302
2303       if (broadcast == 0)
2304       {
2305         int retval = GNUNET_NETWORK_socket_select (rfds, wfds, NULL, GNUNET_TIME_relative_get_forever_());
2306         if (retval < 0)
2307         {
2308           fprintf (stderr, "Select error\n");
2309           ExitProcess (2);
2310         }
2311         //if (GNUNET_NETWORK_fdset_isset (wfds, (struct GNUNET_NETWORK_Handle*)&stdout_handle))
2312         if (retval == stdout_pos)
2313         {
2314           fprintf(stderr, "LOG : sends a message to STDOUT\n"); //FIXME: debugging message
2315           //ssize_t ret;
2316           //ret = GNUNET_NETWORK_socket_send ((struct GNUNET_NETWORK_Handle *)&stdout_handle,  write_std.buf + write_std.pos, write_std.size - write_std.pos);
2317           //ret = write (STDOUT_FILENO, write_std.buf + write_std.pos,  write_std.size - write_std.pos);
2318           DWORD ret;
2319           if (FALSE == WriteFile (stdout_handle,  write_std.buf + write_std.pos, write_std.size - write_std.pos, &ret, NULL))
2320           {
2321             fprintf (stderr, "Failed to write to STDOUT: ");
2322             print_last_error();
2323             break;
2324           }
2325
2326           if (ret <= 0)
2327           {
2328             fprintf (stderr, "Failed to write to STDOUT\n");
2329             ExitProcess (2);
2330           }
2331
2332           write_std.pos += ret;
2333           if (write_std.pos == write_std.size)
2334           {
2335             write_std.pos = 0;
2336             write_std.size = 0;
2337           }
2338         }
2339         if (sendsocket != NULL)
2340         {
2341           if (GNUNET_NETWORK_fdset_isset (wfds, sendsocket))
2342           {
2343             ssize_t ret;
2344             ret = GNUNET_NETWORK_socket_send (sendsocket, write_pout.buf + write_pout.pos,
2345                  write_pout.size - write_pout.pos);
2346
2347             if (GNUNET_SYSERR == ret)
2348             {
2349               fprintf (stderr, "Failed to send to the socket. Closing the socket. Error: \n");
2350               print_last_error();
2351               if (GNUNET_NETWORK_socket_close (sendsocket) != GNUNET_OK)
2352               {
2353                 fprintf (stderr, "Failed to close the sendsocket!\n");
2354                 print_last_error();
2355               }
2356               ExitProcess (2);
2357             }
2358             else
2359             {
2360               write_pout.pos += ret;
2361               if ((write_pout.pos != write_pout.size) && (0 != ret))
2362               {
2363                 /* we should not get partial sends with packet-oriented devices... */
2364                 fprintf (stderr, "Write error, partial send: %u/%u\n",
2365                         (unsigned int) write_pout.pos,
2366                        (unsigned int) write_pout.size);
2367                 break;
2368               }
2369
2370               if (write_pout.pos == write_pout.size)
2371               {
2372                 write_pout.pos = 0;
2373                 write_pout.size = 0;
2374
2375               }
2376               fprintf(stderr, "LOG : sends a message to a DEVICE\n"); //FIXME: debugging message
2377             }
2378           }
2379         }
2380
2381         //if (GNUNET_NETWORK_fdset_isset (rfds, (struct GNUNET_NETWORK_Handle*)&stdin_handle))
2382         if (retval == stdin_pos)
2383         {
2384           //ssize_t ret;
2385           //ret = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)&stdin_handle, readbuf, sizeof (write_pout.buf));
2386           //ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
2387           DWORD ret;
2388           if (FALSE == ReadFile (stdin_handle, readbuf, sizeof (readbuf), &ret, NULL))  /* do nothing asynchronous */
2389           {
2390             fprintf (stderr, "Read error from STDIN: ");
2391             print_last_error();
2392             break;
2393           }
2394           if (0 == ret)
2395           {
2396             /* stop reading... */
2397             stdin_open = 0;
2398           } else {
2399             mst_receive (stdin_mst, readbuf, ret);
2400             fprintf (stderr, "LOG : receives a message from STDIN\n"); //FIXME: debugging message
2401           }
2402         }
2403         else
2404         if (GNUNET_NETWORK_fdset_isset (rfds, dev.handle))
2405         {
2406           fprintf (stderr, "LOG: accepting connection\n");
2407           struct GNUNET_NETWORK_Handle *readsocket;
2408           readsocket = GNUNET_NETWORK_socket_accept (dev.handle, (LPSOCKADDR)&acc_addr, &addr_len);
2409           if (readsocket == NULL)
2410           {
2411             fprintf (stderr, "Accept error %d: ", GetLastError());
2412             print_last_error();
2413             ExitProcess (2);
2414           }
2415           else
2416           {
2417             if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (readsocket, 1) )
2418             {
2419               fprintf (stderr, "Failed to change the socket mode\n");
2420               ExitProcess (2);
2421             }
2422             GNUNET_NETWORK_fdset_set (rfds, readsocket);
2423
2424             if (crt_rfds < MAX_PORTS)
2425               rfds_list[crt_rfds++] = readsocket;
2426             else
2427             {
2428               fprintf (stderr, "The limit for the read file descriptors list was reached\n");
2429               break;
2430             }
2431           }
2432         }
2433         else
2434         for (i = 0; i < crt_rfds; i++)
2435         {
2436           if (GNUNET_NETWORK_fdset_isset (rfds, rfds_list[i]))
2437           {
2438             struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
2439             ssize_t ret;
2440             fprintf (stderr, "LOG: reading something from the socket\n");//FIXME : debugging message
2441             rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
2442             ret = read_from_the_socket (rfds_list[i], (unsigned char *) &rrm->frame,
2443                               sizeof (write_std.buf)
2444                   - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2445                   + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2446                   rrm);
2447             if (0 >= ret)
2448             {
2449
2450               //TODO remove the socket from the list
2451               if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2452               {
2453                 fprintf (stderr, "Failed to close the sendsocket!\n");
2454                 print_last_error();
2455               }
2456
2457               fprintf (stderr, "Read error from raw socket: ");
2458               print_last_error();
2459               break;
2460
2461             }
2462             if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2463             {
2464               write_std.size = ret
2465           + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2466           - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2467               rrm->header.size = htons (write_std.size);
2468               rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2469             }
2470             break;
2471           }
2472         }
2473       }
2474     }
2475
2476     mst_destroy (stdin_mst);
2477     stdin_mst = NULL;
2478
2479     if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
2480     {
2481       fprintf (stderr, "Failed to close the socket!\n");
2482       print_last_error();
2483     }
2484
2485     for (i = 0; i < crt_rfds; i++)
2486     {
2487       if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2488       {
2489         fprintf (stderr, "Failed to close the socket!\n");
2490         print_last_error();
2491       }
2492     }
2493
2494     WSACleanup();
2495   #endif
2496   return 1;                     /* we never exit 'normally' */
2497 }