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