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