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