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