Check that you are not present in trail twice
[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     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     uid_t uid;
1671     int crt_rfds = 0, rfds_list[MAX_PORTS];
1672     int broadcast, sendsocket;
1673     /* Assert privs so we can modify the firewall rules! */
1674     uid = getuid ();
1675   #ifdef HAVE_SETRESUID
1676     if (0 != setresuid (uid, 0, 0))
1677     {
1678       fprintf (stderr, "Failed to setresuid to root: %s\n", strerror (errno));
1679       return 254;
1680     }
1681   #else
1682     if (0 != seteuid (0))
1683     {
1684       fprintf (stderr, "Failed to seteuid back to root: %s\n", strerror (errno));
1685       return 254;
1686     }
1687   #endif
1688
1689     /* Make use of SGID capabilities on POSIX */
1690     memset (&dev, 0, sizeof (dev));
1691     dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1692     raw_eno = errno; /* remember for later */
1693
1694     /* Now that we've dropped root rights, we can do error checking */
1695     if (2 != argc)
1696     {
1697       fprintf (stderr, "You must specify the name of the interface as the first \
1698                         and only argument to this program.\n");
1699       if (-1 != dev.fd_rfcomm)
1700         (void) close (dev.fd_rfcomm);
1701       return 1;
1702     }
1703
1704     if (-1 == dev.fd_rfcomm)
1705     {
1706       fprintf (stderr, "Failed to create a RFCOMM socket: %s\n", strerror (raw_eno));
1707       return 1;
1708     }
1709     if (dev.fd_rfcomm >= FD_SETSIZE)
1710     {
1711       fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1712                dev.fd_rfcomm, FD_SETSIZE);
1713       (void) close (dev.fd_rfcomm);
1714       return 1;
1715     }
1716     if (0 != test_bluetooth_interface (argv[1]))
1717     {
1718       (void) close (dev.fd_rfcomm);
1719       return 1;
1720     }
1721     strncpy (dev.iface, argv[1], IFNAMSIZ);
1722     if (0 != open_device (&dev))
1723     {
1724       (void) close (dev.fd_rfcomm);
1725       return 1;
1726     }
1727
1728     /* Drop privs */
1729     {
1730       uid_t uid = getuid ();
1731   #ifdef HAVE_SETRESUID
1732       if (0 != setresuid (uid, uid, uid))
1733       {
1734         fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1735         if (-1 != dev.fd_rfcomm)
1736     (void) close (dev.fd_rfcomm);
1737         return 1;
1738       }
1739   #else
1740       if (0 != (setuid (uid) | seteuid (uid)))
1741       {
1742         fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
1743         if (-1 != dev.fd_rfcomm)
1744     (void) close (dev.fd_rfcomm);
1745         return 1;
1746       }
1747   #endif
1748     }
1749
1750    /* Send MAC address of the bluetooth interface to STDOUT first */
1751     {
1752       struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
1753
1754       macmsg.hdr.size = htons (sizeof (macmsg));
1755       macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
1756       memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1757       memcpy (write_std.buf, &macmsg, sizeof (macmsg));
1758       write_std.size = sizeof (macmsg);
1759     }
1760
1761
1762     stdin_mst = mst_create (&stdin_send_hw, &dev);
1763     stdin_open = 1;
1764
1765    /**
1766     * TODO : I should make the time out of a mac endpoint smaller and check if the rate
1767     * from get_wlan_header (plugin_transport_bluetooth.c) is correct.
1768     */
1769    while (1)
1770     {
1771       maxfd = -1;
1772       broadcast = 0;
1773       sendsocket = -1;
1774
1775       FD_ZERO (&rfds);
1776       if ((0 == write_pout.size) && (1 == stdin_open))
1777       {
1778         FD_SET (STDIN_FILENO, &rfds);
1779         maxfd = MAX (maxfd, STDIN_FILENO);
1780       }
1781       if (0 == write_std.size)
1782       {
1783         FD_SET (dev.fd_rfcomm, &rfds);
1784         maxfd = MAX (maxfd, dev.fd_rfcomm);
1785       }
1786
1787       for (i = 0; i < crt_rfds; i++)  // it can receive messages from multiple devices
1788       {
1789         FD_SET (rfds_list[i], &rfds);
1790         maxfd = MAX (maxfd, rfds_list[i]);
1791       }
1792       FD_ZERO (&wfds);
1793       if (0 < write_std.size)
1794       {
1795         FD_SET (STDOUT_FILENO, &wfds);
1796         maxfd = MAX (maxfd, STDOUT_FILENO);
1797       }
1798       if (0 < write_pout.size) //it can send messages only to one device per loop
1799       {
1800         struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *frame;
1801         /* Get the destination address */
1802         frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) write_pout.buf;
1803
1804         if (memcmp (&frame->addr1, &dev.pl_mac,
1805                     sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1806         {
1807           broadcast = 1;
1808           memset (&write_pout, 0, sizeof (write_pout)); //clear the buffer
1809         }
1810         else if (memcmp (&frame->addr1, &broadcast_address,
1811                   sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1812         {
1813           fprintf (stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n", dev.iface, neighbours.pos, neighbours.size); //FIXME: debugging message
1814
1815           if (send_broadcast(&dev, &sendsocket) != 0) //if the searching wasn't successful don't get stuck on the select stage
1816           {
1817             broadcast = 1;
1818             memset (&write_pout, 0, sizeof (write_pout)); //remove the message
1819             fprintf (stderr, "LOG : Skipping the broadcast message (pos %d, size %d)\n", neighbours.pos, neighbours.size);
1820           }
1821           else
1822           {
1823             FD_SET (sendsocket, &wfds);
1824             maxfd = MAX (maxfd, sendsocket);
1825           }
1826         }
1827         else
1828         {
1829           int found = 0;
1830           int pos = 0;
1831           /* Search if the address already exists on the list */
1832           for (i = 0; i < neighbours.size; i++)
1833           {
1834             if (memcmp (&frame->addr1, &(neighbours.devices[i]), sizeof (bdaddr_t)) == 0)
1835             {
1836               pos = i;
1837               if (neighbours.fds[i] != -1)
1838               {
1839                 found = 1;  //save the position where it was found
1840                 FD_SET (neighbours.fds[i], &wfds);
1841                 maxfd = MAX (maxfd, neighbours.fds[i]);
1842                 sendsocket = neighbours.fds[i];
1843                 fprintf (stderr, "LOG: the address was found in the list\n");
1844                 break;
1845               }
1846             }
1847           }
1848           if (found == 0)
1849           {
1850             int status;
1851             struct sockaddr_rc addr = { 0 };
1852
1853             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,
1854                     frame->addr1.mac[5], frame->addr1.mac[4], frame->addr1.mac[3],
1855                     frame->addr1.mac[2], frame->addr1.mac[1], frame->addr1.mac[0]); //FIXME: debugging message
1856
1857             sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1858
1859             if (sendsocket < 0)
1860             {
1861               fprintf (stderr, "Failed to create a RFCOMM socket (sending stage): %s\n",
1862                       strerror (errno));
1863               return -1;
1864             }
1865
1866             memcpy (&addr.rc_bdaddr, &frame->addr1, sizeof (bdaddr_t));
1867             addr.rc_family = AF_BLUETOOTH;
1868             addr.rc_channel = get_channel (&dev, addr.rc_bdaddr);
1869
1870             int tries = 0;
1871             connect_retry:
1872             status = connect (sendsocket, (struct sockaddr *) &addr, sizeof (addr));
1873             if (0 != status && errno != EAGAIN)
1874             {
1875               if (errno == ECONNREFUSED && tries < 2)
1876               {
1877                 fprintf (stderr, "LOG : %.*s failed to connect. Trying again!\n", IFNAMSIZ, dev.iface);
1878                 tries++;
1879                 goto connect_retry;
1880               }
1881               else if (errno == EBADF)
1882               {
1883                 fprintf (stderr, "LOG : %s failed to connect : %s. Skip it!\n", dev.iface, strerror (errno));
1884                 memset (&write_pout, 0, sizeof (write_pout));
1885                 broadcast = 1;
1886               }
1887               else
1888               {
1889                 fprintf (stderr, "LOG : %s failed to connect : %s. Try again later!\n", dev.iface, strerror (errno));
1890                 memset (&write_pout, 0, sizeof (write_pout));
1891                 broadcast = 1;
1892               }
1893
1894             }
1895             else
1896             {
1897               FD_SET (sendsocket, &wfds);
1898               maxfd = MAX (maxfd, sendsocket);
1899               fprintf (stderr, "LOG : Connection successful\n");
1900               if (pos != 0) // save the socket
1901               {
1902                 neighbours.fds[pos] = sendsocket;
1903               }
1904               else
1905               {
1906                 /* Add the new device to the discovered devices list */
1907                 if (neighbours.size < MAX_PORTS)
1908                 {
1909                   neighbours.fds[neighbours.size] = sendsocket;
1910                   memcpy (&(neighbours.devices[neighbours.size++]), &addr.rc_bdaddr, sizeof (bdaddr_t));
1911                 }
1912                 else
1913                 {
1914                   fprintf (stderr, "The top limit for the discovarable devices' list was reached\n");
1915                 }
1916               }
1917             }
1918           }
1919         }
1920       }
1921
1922       if (broadcast == 0)
1923       {
1924         /* Select a fd which is ready for action :) */
1925         {
1926           int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
1927           if ((-1 == retval) && (EINTR == errno))
1928       continue;
1929           if (0 > retval && errno != EBADF)   // we handle BADF errors later
1930           {
1931       fprintf (stderr, "select failed: %s\n", strerror (errno));
1932       break;
1933           }
1934         }
1935         if (FD_ISSET (STDOUT_FILENO , &wfds))
1936         {
1937           ssize_t ret =
1938               write (STDOUT_FILENO, write_std.buf + write_std.pos,
1939                      write_std.size - write_std.pos);
1940           if (0 > ret)
1941           {
1942             fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1943             break;
1944           }
1945           write_std.pos += ret;
1946           if (write_std.pos == write_std.size)
1947           {
1948             write_std.pos = 0;
1949             write_std.size = 0;
1950           }
1951           fprintf (stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); //FIXME: debugging message
1952
1953         }
1954         if (-1 != sendsocket)
1955         {
1956           if (FD_ISSET (sendsocket , &wfds))
1957           {
1958             ssize_t ret = write (sendsocket,
1959                                  write_pout.buf + write_std.pos,
1960                                  write_pout.size - write_pout.pos);
1961             if (0 > ret) //FIXME should I first check the error type?
1962             {
1963               fprintf (stderr, "Failed to write to bluetooth device: %s. Closing the socket!\n",
1964                        strerror (errno));
1965               for (i = 0; i < neighbours.size; i++)
1966               {
1967                 if (neighbours.fds[i] == sendsocket)
1968                 {
1969                   (void) close(sendsocket);
1970                   neighbours.fds[i] = -1;
1971                   break;
1972                 }
1973               }
1974               /* Remove the message */
1975               memset (&write_pout.buf + write_std.pos, 0, (write_pout.size - write_pout.pos));
1976               write_pout.pos = 0 ;
1977               write_pout.size = 0;
1978             }
1979             else
1980             {
1981               write_pout.pos += ret;
1982               if ((write_pout.pos != write_pout.size) && (0 != ret))
1983               {
1984                 /* We should not get partial sends with packet-oriented devices... */
1985                 fprintf (stderr, "Write error, partial send: %u/%u\n",
1986                         (unsigned int) write_pout.pos,
1987                         (unsigned int) write_pout.size);
1988                 break;
1989               }
1990
1991               if (write_pout.pos == write_pout.size)
1992               {
1993                 write_pout.pos = 0;
1994                 write_pout.size = 0;
1995               }
1996               fprintf (stderr, "LOG : %s sends a message to a DEVICE\n", dev.iface); //FIXME: debugging message
1997             }
1998           }
1999         }
2000         for (i = 0; i <= maxfd; i++)
2001         {
2002           if (FD_ISSET (i, &rfds))
2003           {
2004             if (i == STDIN_FILENO)
2005             {
2006               ssize_t ret =
2007           read (i, readbuf, sizeof (readbuf));
2008               if (0 > ret)
2009               {
2010                 fprintf (stderr,
2011                          "Read error from STDIN: %s\n",
2012                          strerror (errno));
2013                 break;
2014               }
2015               if (0 == ret)
2016               {
2017                 /* stop reading... */
2018                 stdin_open = 0;
2019               }
2020               else
2021               {
2022                 mst_receive (stdin_mst, readbuf, ret);
2023                 fprintf (stderr, "LOG : %s receives a message from STDIN\n", dev.iface); //FIXME: debugging message
2024               }
2025             }
2026             else if (i == dev.fd_rfcomm)
2027             {
2028               int readsocket;
2029               struct sockaddr_rc addr = { 0 };
2030               unsigned int opt = sizeof (addr);
2031
2032               readsocket = accept (dev.fd_rfcomm, (struct sockaddr *) &addr, &opt);
2033               fprintf(stderr, "LOG : %s accepts a message\n", dev.iface); //FIXME: debugging message
2034               if (readsocket == -1)
2035               {
2036                 fprintf (stderr, "Failed to accept a connection on interface: %.*s\n", IFNAMSIZ,
2037                     strerror (errno));
2038                 break;
2039               }
2040               else
2041               {
2042                 FD_SET (readsocket, &rfds);
2043                 maxfd = MAX (maxfd, readsocket);
2044
2045                 if (crt_rfds < MAX_PORTS)
2046                   rfds_list[crt_rfds++] = readsocket;
2047                 else
2048                 {
2049                   fprintf (stderr, "The limit for the read file descriptors list was \
2050                                   reached\n");
2051                   break;
2052                 }
2053               }
2054
2055             }
2056             else
2057             {
2058               struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
2059               ssize_t ret;
2060               fprintf (stderr, "LOG : %s reads something from the socket\n", dev.iface);//FIXME : debugging message
2061               rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
2062               ret =
2063                   read_from_the_socket ((void *)&i, (unsigned char *) &rrm->frame,
2064                               sizeof (write_std.buf)
2065                   - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2066                   + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2067                   rrm);
2068               if (0 >= ret)
2069               {
2070                 int j;
2071                 FD_CLR (i, &rfds);
2072                 close (i);
2073                  /* Remove the socket from the list */
2074                 for (j = 0; j < crt_rfds; j++)
2075                 {
2076                   if (rfds_list[j] == i)
2077                   {
2078                     rfds_list[j] ^= rfds_list[crt_rfds - 1];
2079                     rfds_list[crt_rfds - 1] ^= rfds_list[j];
2080                     rfds_list[j] ^= rfds_list[crt_rfds - 1];
2081                     crt_rfds -= 1;
2082                     break;
2083                   }
2084                 }
2085
2086                 fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
2087                 break;
2088               }
2089               if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2090               {
2091                 write_std.size = ret
2092             + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2093             - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2094                 rrm->header.size = htons (write_std.size);
2095                 rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2096               }
2097             }
2098           }
2099         }
2100       }
2101     }
2102     /* Error handling, try to clean up a bit at least */
2103     mst_destroy (stdin_mst);
2104     stdin_mst = NULL;
2105     sdp_close (dev.session);
2106     (void) close (dev.fd_rfcomm);
2107     if (-1 != sendsocket)
2108       (void) close (sendsocket);
2109
2110     for (i = 0; i < crt_rfds; i++)
2111       (void) close (rfds_list[i]);
2112
2113     for (i = 0; i < neighbours.size; i++)
2114       (void) close (neighbours.fds[i]);
2115   #else
2116     struct HardwareInfos dev;
2117     struct GNUNET_NETWORK_Handle *sendsocket;
2118     struct GNUNET_NETWORK_FDSet *rfds;
2119     struct GNUNET_NETWORK_FDSet *wfds;
2120     struct GNUNET_NETWORK_Handle *rfds_list[MAX_PORTS];
2121     char readbuf[MAXLINE] = { 0 };
2122     SOCKADDR_BTH acc_addr = { 0 };
2123     int addr_len = sizeof (SOCKADDR_BTH);
2124     int broadcast, i, stdin_open, crt_rfds = 0;
2125     HANDLE stdin_handle = GetStdHandle (STD_INPUT_HANDLE);
2126     HANDLE stdout_handle = GetStdHandle (STD_OUTPUT_HANDLE);
2127     struct MessageStreamTokenizer *stdin_mst;
2128
2129     /* check the handles */
2130     if (stdin_handle == INVALID_HANDLE_VALUE)
2131     {
2132       fprintf (stderr, "Failed to get the stdin handle\n");
2133       ExitProcess (2);
2134     }
2135
2136     if (stdout_handle == INVALID_HANDLE_VALUE)
2137     {
2138       fprintf (stderr, "Failed to get the stdout handle\n");
2139       ExitProcess (2);
2140     }
2141
2142     /* initialize windows sockets */
2143     initialize_windows_sockets();
2144
2145     // /* test bluetooth socket family support */ --> it return false because the GNUNET_NETWORK_test_pf should also receive the type of socket (BTHPROTO_RFCOMM)
2146     // if (GNUNET_NETWORK_test_pf (AF_BTH) != GNUNET_OK)
2147     // {
2148     //   fprintf (stderr, "AF_BTH family is not supported\n");
2149     //   ExitProcess (2);
2150     // }
2151
2152      /* create the socket */
2153     dev.handle = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
2154     if (dev.handle == NULL)
2155     {
2156       fprintf (stderr, "Failed to create RFCOMM socket: ");
2157       print_last_error();
2158       ExitProcess (2);
2159     }
2160
2161
2162     if (open_device (&dev) == -1)
2163     {
2164       fprintf (stderr, "Failed to open the device\n");
2165       print_last_error();
2166       if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
2167       {
2168         fprintf (stderr, "Failed to close the socket!\n");
2169         print_last_error();
2170       }
2171       ExitProcess (2);
2172     }
2173
2174     if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (dev.handle, 1) )
2175     {
2176       fprintf (stderr, "Failed to change the socket mode\n");
2177       ExitProcess (2);
2178     }
2179
2180     memset (&write_std, 0, sizeof (write_std));
2181     memset (&write_pout, 0, sizeof (write_pout));
2182     stdin_open = 1;
2183
2184     rfds = GNUNET_NETWORK_fdset_create ();
2185     wfds = GNUNET_NETWORK_fdset_create ();
2186
2187   /* Send MAC address of the bluetooth interface to STDOUT first */
2188     {
2189       struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
2190
2191       macmsg.hdr.size = htons (sizeof (macmsg));
2192       macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
2193       memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy));
2194       memcpy (write_std.buf, &macmsg, sizeof (macmsg));
2195       write_std.size = sizeof (macmsg);
2196     }
2197
2198
2199     stdin_mst = mst_create (&stdin_send_hw, &dev);
2200     stdin_open = 1;
2201
2202     int pos = 0;
2203     int stdin_pos = -1;
2204     int stdout_pos = -1;
2205     while (1)
2206     {
2207       broadcast = 0;
2208       pos = 0;
2209       stdin_pos = -1;
2210       stdout_pos = -1;
2211       sendsocket = NULL; //FIXME ???memleaks
2212
2213       GNUNET_NETWORK_fdset_zero (rfds);
2214       if ((0 == write_pout.size) && (1 == stdin_open))
2215       {
2216         stdin_pos = pos;
2217         pos +=1;
2218         GNUNET_NETWORK_fdset_handle_set (rfds, (struct GNUNET_DISK_FileHandle*) &stdin_handle);
2219       }
2220
2221       if (0 == write_std.size)
2222       {
2223         pos += 1;
2224         GNUNET_NETWORK_fdset_set (rfds, dev.handle);
2225       }
2226
2227       for (i = 0; i < crt_rfds; i++)
2228       {
2229         pos += 1;
2230         GNUNET_NETWORK_fdset_set (rfds, rfds_list[i]);
2231       }
2232
2233       GNUNET_NETWORK_fdset_zero (wfds);
2234       if (0 < write_std.size)
2235       {
2236         stdout_pos = pos;
2237         GNUNET_NETWORK_fdset_handle_set (wfds, (struct GNUNET_DISK_FileHandle*) &stdout_handle);
2238         // printf ("%s\n", write_std.buf);
2239         // memset (write_std.buf, 0, write_std.size);
2240         // write_std.size = 0;
2241       }
2242
2243       if (0 < write_pout.size)
2244       {
2245         if (strcmp (argv[1], "ff:ff:ff:ff:ff:ff") == 0) {
2246           fprintf(stderr, "LOG: BROADCAST! Skipping the message\n");
2247           // skip the message
2248           broadcast = 1;
2249           memset (write_pout.buf, 0, write_pout.size);
2250           write_pout.size = 0;
2251         }
2252         else
2253         {
2254           SOCKADDR_BTH addr;
2255           fprintf (stderr, "LOG : has a new message for %s\n", argv[1]);
2256           sendsocket = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
2257
2258           if (sendsocket == NULL)
2259           {
2260             fprintf (stderr, "Failed to create RFCOMM socket: \n");
2261             print_last_error();
2262             ExitProcess (2);
2263           }
2264
2265           memset (&addr, 0, sizeof (addr));
2266           //addr.addressFamily = AF_BTH;
2267           if (SOCKET_ERROR ==
2268              WSAStringToAddress (argv[1], AF_BTH, NULL, (LPSOCKADDR) &addr, &addr_len))
2269           {
2270             fprintf (stderr, "Failed to translate the address: ");
2271             print_last_error();
2272             ExitProcess ( 2 ) ;
2273           }
2274           addr.port = get_channel (argv[1]);
2275           if (addr.port == -1)
2276           {
2277             fprintf (stderr, "Couldn't find the sdp service for the address: %s\n", argv[1]);
2278             memset (write_pout.buf, 0, write_pout.size);
2279             write_pout.size = 0;
2280             broadcast = 1; //skipping the select part
2281           }
2282           else
2283           {
2284             if (GNUNET_OK != GNUNET_NETWORK_socket_connect (sendsocket, (LPSOCKADDR)&addr, addr_len))
2285             {
2286               fprintf (stderr, "Failed to connect: ");
2287               print_last_error();
2288               ExitProcess (2);
2289             }
2290
2291             if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (sendsocket, 1) )
2292             {
2293               fprintf (stderr, "Failed to change the socket mode\n");
2294               ExitProcess (2);
2295             }
2296
2297             GNUNET_NETWORK_fdset_set (wfds, sendsocket);
2298           }
2299         }
2300       }
2301
2302       if (broadcast == 0)
2303       {
2304         int retval = GNUNET_NETWORK_socket_select (rfds, wfds, NULL, GNUNET_TIME_relative_get_forever_());
2305         if (retval < 0)
2306         {
2307           fprintf (stderr, "Select error\n");
2308           ExitProcess (2);
2309         }
2310         //if (GNUNET_NETWORK_fdset_isset (wfds, (struct GNUNET_NETWORK_Handle*)&stdout_handle))
2311         if (retval == stdout_pos)
2312         {
2313           fprintf(stderr, "LOG : sends a message to STDOUT\n"); //FIXME: debugging message
2314           //ssize_t ret;
2315           //ret = GNUNET_NETWORK_socket_send ((struct GNUNET_NETWORK_Handle *)&stdout_handle,  write_std.buf + write_std.pos, write_std.size - write_std.pos);
2316           //ret = write (STDOUT_FILENO, write_std.buf + write_std.pos,  write_std.size - write_std.pos);
2317           DWORD ret;
2318           if (FALSE == WriteFile (stdout_handle,  write_std.buf + write_std.pos, write_std.size - write_std.pos, &ret, NULL))
2319           {
2320             fprintf (stderr, "Failed to write to STDOUT: ");
2321             print_last_error();
2322             break;
2323           }
2324
2325           if (ret <= 0)
2326           {
2327             fprintf (stderr, "Failed to write to STDOUT\n");
2328             ExitProcess (2);
2329           }
2330
2331           write_std.pos += ret;
2332           if (write_std.pos == write_std.size)
2333           {
2334             write_std.pos = 0;
2335             write_std.size = 0;
2336           }
2337         }
2338         if (sendsocket != NULL)
2339         {
2340           if (GNUNET_NETWORK_fdset_isset (wfds, sendsocket))
2341           {
2342             ssize_t ret;
2343             ret = GNUNET_NETWORK_socket_send (sendsocket, write_pout.buf + write_pout.pos,
2344                  write_pout.size - write_pout.pos);
2345
2346             if (GNUNET_SYSERR == ret)
2347             {
2348               fprintf (stderr, "Failed to send to the socket. Closing the socket. Error: \n");
2349               print_last_error();
2350               if (GNUNET_NETWORK_socket_close (sendsocket) != GNUNET_OK)
2351               {
2352                 fprintf (stderr, "Failed to close the sendsocket!\n");
2353                 print_last_error();
2354               }
2355               ExitProcess (2);
2356             }
2357             else
2358             {
2359               write_pout.pos += ret;
2360               if ((write_pout.pos != write_pout.size) && (0 != ret))
2361               {
2362                 /* we should not get partial sends with packet-oriented devices... */
2363                 fprintf (stderr, "Write error, partial send: %u/%u\n",
2364                         (unsigned int) write_pout.pos,
2365                        (unsigned int) write_pout.size);
2366                 break;
2367               }
2368
2369               if (write_pout.pos == write_pout.size)
2370               {
2371                 write_pout.pos = 0;
2372                 write_pout.size = 0;
2373
2374               }
2375               fprintf(stderr, "LOG : sends a message to a DEVICE\n"); //FIXME: debugging message
2376             }
2377           }
2378         }
2379
2380         //if (GNUNET_NETWORK_fdset_isset (rfds, (struct GNUNET_NETWORK_Handle*)&stdin_handle))
2381         if (retval == stdin_pos)
2382         {
2383           //ssize_t ret;
2384           //ret = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)&stdin_handle, readbuf, sizeof (write_pout.buf));
2385           //ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
2386           DWORD ret;
2387           if (FALSE == ReadFile (stdin_handle, readbuf, sizeof (readbuf), &ret, NULL))  /* do nothing asynchronous */
2388           {
2389             fprintf (stderr, "Read error from STDIN: ");
2390             print_last_error();
2391             break;
2392           }
2393           if (0 == ret)
2394           {
2395             /* stop reading... */
2396             stdin_open = 0;
2397           } else {
2398             mst_receive (stdin_mst, readbuf, ret);
2399             fprintf (stderr, "LOG : receives a message from STDIN\n"); //FIXME: debugging message
2400           }
2401         }
2402         else
2403         if (GNUNET_NETWORK_fdset_isset (rfds, dev.handle))
2404         {
2405           fprintf (stderr, "LOG: accepting connection\n");
2406           struct GNUNET_NETWORK_Handle *readsocket;
2407           readsocket = GNUNET_NETWORK_socket_accept (dev.handle, (LPSOCKADDR)&acc_addr, &addr_len);
2408           if (readsocket == NULL)
2409           {
2410             fprintf (stderr, "Accept error %d: ", GetLastError());
2411             print_last_error();
2412             ExitProcess (2);
2413           }
2414           else
2415           {
2416             if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (readsocket, 1) )
2417             {
2418               fprintf (stderr, "Failed to change the socket mode\n");
2419               ExitProcess (2);
2420             }
2421             GNUNET_NETWORK_fdset_set (rfds, readsocket);
2422
2423             if (crt_rfds < MAX_PORTS)
2424               rfds_list[crt_rfds++] = readsocket;
2425             else
2426             {
2427               fprintf (stderr, "The limit for the read file descriptors list was reached\n");
2428               break;
2429             }
2430           }
2431         }
2432         else
2433         for (i = 0; i < crt_rfds; i++)
2434         {
2435           if (GNUNET_NETWORK_fdset_isset (rfds, rfds_list[i]))
2436           {
2437             struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
2438             ssize_t ret;
2439             fprintf (stderr, "LOG: reading something from the socket\n");//FIXME : debugging message
2440             rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
2441             ret = read_from_the_socket (rfds_list[i], (unsigned char *) &rrm->frame,
2442                               sizeof (write_std.buf)
2443                   - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2444                   + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2445                   rrm);
2446             if (0 >= ret)
2447             {
2448
2449               //TODO remove the socket from the list
2450               if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2451               {
2452                 fprintf (stderr, "Failed to close the sendsocket!\n");
2453                 print_last_error();
2454               }
2455
2456               fprintf (stderr, "Read error from raw socket: ");
2457               print_last_error();
2458               break;
2459
2460             }
2461             if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2462             {
2463               write_std.size = ret
2464           + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2465           - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2466               rrm->header.size = htons (write_std.size);
2467               rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2468             }
2469             break;
2470           }
2471         }
2472       }
2473     }
2474
2475     mst_destroy (stdin_mst);
2476     stdin_mst = NULL;
2477
2478     if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
2479     {
2480       fprintf (stderr, "Failed to close the socket!\n");
2481       print_last_error();
2482     }
2483
2484     for (i = 0; i < crt_rfds; i++)
2485     {
2486       if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2487       {
2488         fprintf (stderr, "Failed to close the socket!\n");
2489         print_last_error();
2490       }
2491     }
2492
2493     WSACleanup();
2494   #endif
2495   return 1;                     /* we never exit 'normally' */
2496 }