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