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