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