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