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