splitting 'struct GNUNET_CRYPTO_EccPublicKey' into one struct for signing and another...
[oweals/gnunet.git] / src / transport / gnunet-helper-transport-bluetooth.c
1 /*
2    This file is part of GNUnet.
3    (C) 2010, 2011, 2012 Christian Grothoff (and other contributing authors)
4    Copyright (c) 2007, 2008, Andy Green <andy@warmcat.com>
5    Copyright (C) 2009 Thomas d'Otreppe
6
7    GNUnet is free software; you can redistribute it and/or modify
8    it under the terms of the GNU General Public License as published
9    by the Free Software Foundation; either version 3, or (at your
10    option) any later version.
11
12    GNUnet is distributed in the hope that it will be useful, but
13    WITHOUT ANY WARRANTY; without even the implied warranty of
14    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15    General Public License for more details.
16
17    You should have received a copy of the GNU General Public License
18    along with GNUnet; see the file COPYING.  If not, write to the
19    Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20    Boston, MA 02111-1307, USA.
21 */
22 #include "gnunet_config.h"
23
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 "gnunet_protocols.h"
42 #include "plugin_transport_wlan.h"
43
44 /**
45  * Maximum number of ports assignable for RFCOMMM protocol.
46  */
47 #define MAX_PORTS 30
48
49 /**
50  * Maximum size of a message allowed in either direction
51  * (used for our receive and sent buffers).
52  */
53 #define MAXLINE 4096
54
55
56 /**
57  * Maximum number of loops without inquiring for new devices.
58  */
59 #define MAX_LOOPS 5
60
61 /**
62  * struct for storing the information of the hardware.  There is only
63  * one of these.
64  */
65 struct HardwareInfos
66 {
67
68   /**
69    * file descriptor for the rfcomm socket
70    */
71   int fd_rfcomm;
72
73   /**
74    * Name of the interface, not necessarily 0-terminated (!).
75    */
76   char iface[IFNAMSIZ];
77
78   /**
79    * MAC address of our own bluetooth interface.
80    */
81   struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac;
82   
83   /**
84    * SDP session
85    */
86    sdp_session_t *session ;
87 };
88
89 /**
90  * IO buffer used for buffering data in transit (to wireless or to stdout).
91  */
92 struct SendBuffer
93 {
94   /**
95    * How many bytes of data are stored in 'buf' for transmission right now?
96    * Data always starts at offset 0 and extends to 'size'.
97    */
98   size_t size;
99
100   /**
101    * How many bytes that were stored in 'buf' did we already write to the
102    * destination?  Always smaller than 'size'.
103    */
104   size_t pos;
105   
106   /**
107    * Buffered data; twice the maximum allowed message size as we add some
108    * headers.
109    */
110   char buf[MAXLINE * 2];
111 };
112
113 /**
114  * Devices buffer used to keep a list with all the discoverable devices in 
115  * order to send them HELLO messages one by one when it receive a broadcast message.
116  */ 
117 struct BroadcastMessages
118 {
119   /* List with the discoverable devices' addresses */
120   bdaddr_t devices[MAX_PORTS]; //FIXME I should use a linked list but 30 isn't such a big number
121   
122   /* List with the open sockets */
123   int fds[MAX_PORTS];
124
125
126   /* The number of the devices */
127   int size;
128   
129   /* The current position */
130   int pos;
131
132   /* The device id */
133   int dev_id;
134 };
135
136
137 /**
138  * Buffer for data read from stdin to be transmitted to the bluetooth device
139  */
140 static struct SendBuffer write_pout;
141
142 /**
143  * Buffer for data read from the bluetooth device to be transmitted to stdout.
144  */
145 static struct SendBuffer write_std;
146
147 /**
148  * Address used to identify the broadcast messages.
149  */
150 static struct GNUNET_TRANSPORT_WLAN_MacAddress broadcast_address = {{255, 255, 255, 255, 255, 255}};
151
152 /**
153  * Buffer with the discoverable devices.
154  */
155 static struct BroadcastMessages neighbours;
156
157 static int searching_devices_count = 0;
158
159 /* *********** specialized version of server_mst.c begins here ********** */
160 /* ****** this is the same version as the one used in gnunet-helper-transport-wlan.c ****** */ 
161
162 /**
163  * To what multiple do we align messages?  8 byte should suffice for everyone
164  * for now.
165  */
166 #define ALIGN_FACTOR 8
167
168 /**
169  * Smallest supported message.
170  */
171 #define MIN_BUFFER_SIZE sizeof (struct GNUNET_MessageHeader)
172
173
174 /**
175  * Functions with this signature are called whenever a
176  * complete message is received by the tokenizer.
177  *
178  * @param cls closure
179  * @param message the actual message
180  */
181 typedef void (*MessageTokenizerCallback) (void *cls, 
182                                           const struct
183                                           GNUNET_MessageHeader *
184                                           message);
185
186 /**
187  * Handle to a message stream tokenizer.
188  */
189 struct MessageStreamTokenizer
190 {
191
192   /**
193    * Function to call on completed messages.
194    */
195   MessageTokenizerCallback cb;
196
197   /**
198    * Closure for cb.
199    */
200   void *cb_cls;
201
202   /**
203    * Size of the buffer (starting at 'hdr').
204    */
205   size_t curr_buf;
206
207   /**
208    * How many bytes in buffer have we already processed?
209    */
210   size_t off;
211
212   /**
213    * How many bytes in buffer are valid right now?
214    */
215   size_t pos;
216
217   /**
218    * Beginning of the buffer.  Typed like this to force alignment.
219    */
220   struct GNUNET_MessageHeader *hdr;
221
222 };
223
224
225 /**
226  * Create a message stream tokenizer.
227  *
228  * @param cb function to call on completed messages
229  * @param cb_cls closure for cb
230  * @return handle to tokenizer
231  */
232 static struct MessageStreamTokenizer *
233 mst_create (MessageTokenizerCallback cb,
234             void *cb_cls)
235 {
236   struct MessageStreamTokenizer *ret;
237
238   ret = malloc (sizeof (struct MessageStreamTokenizer));
239   if (NULL == ret)
240   {
241     fprintf (stderr, "Failed to allocate buffer for tokenizer\n");
242     exit (1);
243   }
244   ret->hdr = malloc (MIN_BUFFER_SIZE);
245   if (NULL == ret->hdr)
246   {
247     fprintf (stderr, "Failed to allocate buffer for alignment\n");
248     exit (1);
249   }
250   ret->curr_buf = MIN_BUFFER_SIZE;
251   ret->cb = cb;
252   ret->cb_cls = cb_cls;
253   ret->pos = 0;
254   
255   return ret;
256 }
257
258
259 /**
260  * Add incoming data to the receive buffer and call the
261  * callback for all complete messages.
262  *
263  * @param mst tokenizer to use
264  * @param buf input data to add
265  * @param size number of bytes in buf
266  * @return GNUNET_OK if we are done processing (need more data)
267  *         GNUNET_SYSERR if the data stream is corrupt
268  */
269 static int
270 mst_receive (struct MessageStreamTokenizer *mst,
271        const char *buf, size_t size)
272 {
273   const struct GNUNET_MessageHeader *hdr;
274   size_t delta;
275   uint16_t want;
276   char *ibuf;
277   int need_align;
278   unsigned long offset;
279   int ret;
280
281   ret = GNUNET_OK;
282   ibuf = (char *) mst->hdr;
283   while (mst->pos > 0)
284   {
285 do_align:
286     if (mst->pos < mst->off)
287     {
288       //fprintf (stderr, "We processed too many bytes!\n");
289       return GNUNET_SYSERR;
290     }
291     if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) ||
292         (0 != (mst->off % ALIGN_FACTOR)))
293     {
294       /* need to align or need more space */
295       mst->pos -= mst->off;
296       memmove (ibuf, &ibuf[mst->off], mst->pos);
297       mst->off = 0;
298     }
299     if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
300     {
301       delta =
302           GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) -
303                       (mst->pos - mst->off), size);
304       memcpy (&ibuf[mst->pos], buf, delta);
305       mst->pos += delta;
306       buf += delta;
307       size -= delta;
308     }
309     if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
310     {
311       //FIXME should I reset ??
312       // mst->off = 0;
313       // mst->pos = 0;
314       return GNUNET_OK;
315     }
316     hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
317     want = ntohs (hdr->size);
318     if (want < sizeof (struct GNUNET_MessageHeader))
319     {
320       fprintf (stderr,
321          "Received invalid message from stdin\n");
322       return GNUNET_SYSERR;
323     }
324     if ((mst->curr_buf - mst->off < want) &&
325        (mst->off > 0))
326     {
327       /* need more space */
328       mst->pos -= mst->off;
329       memmove (ibuf, &ibuf[mst->off], mst->pos);
330       mst->off = 0;
331     }
332     if (want > mst->curr_buf)
333     {
334       if (mst->off != 0)
335       {
336         fprintf (stderr, "Error! We should proceeded 0 bytes\n");
337         return GNUNET_SYSERR;
338       }
339       mst->hdr = realloc (mst->hdr, want);
340       if (NULL == mst->hdr)
341       {
342   fprintf (stderr, "Failed to allocate buffer for alignment\n");
343   exit (1);
344       }
345       ibuf = (char *) mst->hdr;
346       mst->curr_buf = want;
347     }
348     hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
349     if (mst->pos - mst->off < want)
350     {
351       delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
352       if (mst->pos + delta > mst->curr_buf)
353       {
354         fprintf (stderr, "The size of the buffer will be exceeded!\n");
355         return GNUNET_SYSERR;
356       }
357       memcpy (&ibuf[mst->pos], buf, delta);
358       mst->pos += delta;
359       buf += delta;
360       size -= delta;
361     }
362     if (mst->pos - mst->off < want)
363     {
364       //FIXME should I use this?
365       // mst->off = 0;
366       // mst->pos = 0;
367       return GNUNET_OK;
368     }
369     mst->cb (mst->cb_cls, hdr);
370     mst->off += want;
371     if (mst->off == mst->pos)
372     {
373       /* reset to beginning of buffer, it's free right now! */
374       mst->off = 0;
375       mst->pos = 0;
376     }
377   }
378   if (0 != mst->pos)
379   {
380     fprintf (stderr, "There should some valid bytes in the buffer on this stage\n");
381     return GNUNET_SYSERR;
382   }
383   while (size > 0)
384   {
385     if (size < sizeof (struct GNUNET_MessageHeader))
386       break;
387     offset = (unsigned long) buf;
388     need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
389     if (GNUNET_NO == need_align)
390     {
391       /* can try to do zero-copy and process directly from original buffer */
392       hdr = (const struct GNUNET_MessageHeader *) buf;
393       want = ntohs (hdr->size);
394       if (want < sizeof (struct GNUNET_MessageHeader))
395       {
396   fprintf (stderr,
397      "Received invalid message from stdin\n");
398   //exit (1);
399         mst->off = 0;
400         return GNUNET_SYSERR;
401       }
402       if (size < want)
403         break;                  /* or not, buffer incomplete, so copy to private buffer... */
404       mst->cb (mst->cb_cls, hdr);
405       buf += want;
406       size -= want;
407     }
408     else
409     {
410       /* need to copy to private buffer to align;
411        * yes, we go a bit more spagetti than usual here */
412       goto do_align;
413     }
414   }
415   if (size > 0)
416   {
417     if (size + mst->pos > mst->curr_buf)
418     {
419       mst->hdr = realloc (mst->hdr, size + mst->pos);
420       if (NULL == mst->hdr)
421       {
422   fprintf (stderr, "Failed to allocate buffer for alignment\n");
423   exit (1);
424       }
425       ibuf = (char *) mst->hdr;
426       mst->curr_buf = size + mst->pos;
427     }
428     if (mst->pos + size > mst->curr_buf)
429     {
430       fprintf (stderr,
431          "Assertion failed\n");
432       exit (1);
433     }
434     memcpy (&ibuf[mst->pos], buf, size);
435     mst->pos += size;
436   }
437   return ret;
438 }
439
440
441
442 /**
443  * Destroys a tokenizer.
444  *
445  * @param mst tokenizer to destroy
446  */
447 static void
448 mst_destroy (struct MessageStreamTokenizer *mst)
449 {
450   free (mst->hdr);
451   free (mst);
452 }
453
454 /* *****************  end of server_mst.c clone ***************** **/
455
456
457 /* ****** same crc version as the one used in gnunet-helper-transport-wlan.c ****** */ 
458
459 /**
460  * Calculate crc32, the start of the calculation
461  *
462  * @param buf buffer to calc the crc
463  * @param len len of the buffer
464  * @return crc sum
465  */
466 static unsigned long
467 calc_crc_osdep (const unsigned char *buf, size_t len)
468 {
469   static const unsigned long int crc_tbl_osdep[256] = {
470     0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
471     0xE963A535, 0x9E6495A3,
472     0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
473     0xE7B82D07, 0x90BF1D91,
474     0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
475     0xF4D4B551, 0x83D385C7,
476     0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
477     0xFA0F3D63, 0x8D080DF5,
478     0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
479     0xD20D85FD, 0xA50AB56B,
480     0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
481     0xDCD60DCF, 0xABD13D59,
482     0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
483     0xCFBA9599, 0xB8BDA50F,
484     0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
485     0xC1611DAB, 0xB6662D3D,
486     0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
487     0x9FBFE4A5, 0xE8B8D433,
488     0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
489     0x91646C97, 0xE6635C01,
490     0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
491     0x8208F4C1, 0xF50FC457,
492     0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
493     0x8CD37CF3, 0xFBD44C65,
494     0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
495     0xA4D1C46D, 0xD3D6F4FB,
496     0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
497     0xAA0A4C5F, 0xDD0D7CC9,
498     0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
499     0xB966D409, 0xCE61E49F,
500     0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
501     0xB7BD5C3B, 0xC0BA6CAD,
502     0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
503     0x04DB2615, 0x73DC1683,
504     0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
505     0x0A00AE27, 0x7D079EB1,
506     0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
507     0x196C3671, 0x6E6B06E7,
508     0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
509     0x17B7BE43, 0x60B08ED5,
510     0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
511     0x3FB506DD, 0x48B2364B,
512     0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
513     0x316E8EEF, 0x4669BE79,
514     0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
515     0x220216B9, 0x5505262F,
516     0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
517     0x2CD99E8B, 0x5BDEAE1D,
518     0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
519     0x72076785, 0x05005713,
520     0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
521     0x7CDCEFB7, 0x0BDBDF21,
522     0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
523     0x6FB077E1, 0x18B74777,
524     0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
525     0x616BFFD3, 0x166CCF45,
526     0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
527     0x4969474D, 0x3E6E77DB,
528     0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
529     0x47B2CF7F, 0x30B5FFE9,
530     0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
531     0x54DE5729, 0x23D967BF,
532     0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
533     0x5A05DF1B, 0x2D02EF8D
534   };
535
536   unsigned long crc = 0xFFFFFFFF;
537
538   for (; len > 0; len--, buf++)
539     crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
540   return (~crc);
541 }
542
543
544 /**
545  * Calculate and check crc of the bluetooth packet
546  *
547  * @param buf buffer of the packet, with len + 4 bytes of data,
548  *            the last 4 bytes being the checksum
549  * @param len length of the payload in data
550  * @return 0 on success (checksum matches), 1 on error
551  */
552 static int
553 check_crc_buf_osdep (const unsigned char *buf, size_t len)
554 {
555   unsigned long crc;
556
557   crc = calc_crc_osdep (buf, len);
558   buf += len;
559   if (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
560       ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3])
561     return 0;
562   return 1;     
563 }
564
565
566
567 /* ************** end of crc version  ***************** */
568
569
570
571
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 sockaddr_rc));
590     if (status == 0)
591       return 0;
592   }
593   
594   return -1; 
595 }
596
597
598 /**
599  * Function used for creating the service record and registering it.
600  *
601  * @param dev pointer to the device struct
602  * @param rc_channel the rfcomm channel
603  * @return 0 on success
604  */
605 static int
606 register_service (struct HardwareInfos *dev, int rc_channel) 
607 {
608   /**
609    * 1. initializations
610    * 2. set the service ID, class, profile information
611    * 3. make the service record publicly browsable
612    * 4. register the RFCOMM channel
613    * 5. set the name, provider and description
614    * 6. register the service record to the local SDP server
615    * 7. cleanup
616    */
617   uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
618                             dev->pl_mac.mac[5], dev->pl_mac.mac[4], dev->pl_mac.mac[3],
619                             dev->pl_mac.mac[2], dev->pl_mac.mac[1], dev->pl_mac.mac[0]};
620   const char *service_dsc = "Bluetooth plugin services";
621   const char *service_prov = "GNUnet provider";                       
622   uuid_t root_uuid, rfcomm_uuid, svc_uuid;  
623   sdp_list_t *root_list = 0, *rfcomm_list = 0, *proto_list = 0,
624      *access_proto_list = 0, *svc_list = 0;
625   sdp_record_t *record = 0;
626   sdp_data_t *channel = 0;
627         
628         record = sdp_record_alloc();
629
630   /* Set the general service ID */
631   sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
632   svc_list = sdp_list_append (0, &svc_uuid);
633   sdp_set_service_classes (record, svc_list);
634   sdp_set_service_id (record, svc_uuid);
635
636         /* Make the service record publicly browsable */
637   sdp_uuid16_create (&root_uuid, PUBLIC_BROWSE_GROUP); 
638   root_list = sdp_list_append (0, &root_uuid); 
639   sdp_set_browse_groups (record, root_list);
640
641         /* Register the RFCOMM channel */
642   sdp_uuid16_create (&rfcomm_uuid, RFCOMM_UUID);
643   channel = sdp_data_alloc (SDP_UINT8, &rc_channel);
644   rfcomm_list = sdp_list_append (0, &rfcomm_uuid);
645   sdp_list_append (rfcomm_list, channel);
646   proto_list = sdp_list_append (0, rfcomm_list);
647
648   /* Set protocol information */
649   access_proto_list = sdp_list_append (0, proto_list);
650   sdp_set_access_protos (record, access_proto_list);
651
652   /* Set the name, provider, and description */
653         sdp_set_info_attr (record, dev->iface, service_prov, service_dsc);
654   
655   /* Connect to the local SDP server */
656   dev->session = sdp_connect (BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
657   
658   if (!dev->session)
659   {
660     fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
661              IFNAMSIZ, dev->iface, strerror (errno));
662     //FIXME exit?
663     return 1;
664   }
665   
666   /* Register the service record */
667   if (sdp_record_register (dev->session, record, 0) < 0)
668   {
669     fprintf (stderr, "Failed to register a service record on interface `%.*s': %s\n",
670              IFNAMSIZ, dev->iface, strerror (errno));
671     //FIXME exit?
672     return 1;
673   }
674   
675   /* Cleanup */
676   sdp_data_free (channel);      
677   sdp_list_free (root_list, 0);
678   sdp_list_free (rfcomm_list, 0);
679   sdp_list_free (proto_list, 0);
680   sdp_list_free (access_proto_list, 0);
681   sdp_list_free (svc_list, 0);
682   sdp_record_free (record);
683   
684   return 0;
685 }
686
687 /**
688  * Function for searching and browsing for a service. This will return the 
689  * port number on which the service is running.
690  *
691  * @param dev pointer to the device struct
692  * @param dest target address
693  * @return channel
694  */
695 static int
696 get_channel(struct HardwareInfos *dev, bdaddr_t dest) 
697 {
698   /**
699    * 1. detect all nearby devices
700    * 2. for each device:
701    * 2.1. connect to the SDP server running
702    * 2.2. get a list of service records with the specific UUID
703    * 2.3. for each service record get a list of the protocol sequences and get 
704    *       the port number
705    */
706   uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
707                            dest.b[5], dest.b[4], dest.b[3],
708                            dest.b[2], dest.b[1], dest.b[0]};
709   sdp_session_t *session = 0;
710   sdp_list_t *search_list = 0, *attrid_list = 0, *response_list = 0, *it = 0;
711   uuid_t svc_uuid;
712   uint32_t range = 0x0000ffff;
713   uint8_t channel = -1;
714    
715   /* Connect to the local SDP server */
716   session = sdp_connect (BDADDR_ANY, &dest, 0); 
717   if (!session)
718   {
719    fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
720             IFNAMSIZ, dev->iface, strerror (errno));
721    //FIXME exit?
722    return -1;
723   }
724   
725   sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
726   search_list = sdp_list_append (0, &svc_uuid);
727   attrid_list = sdp_list_append (0, &range);
728   
729   if (sdp_service_search_attr_req (session, search_list, 
730                   SDP_ATTR_REQ_RANGE, attrid_list, &response_list) == 0)
731   {
732     for (it = response_list; it; it = it->next)
733     {
734       sdp_record_t *record = (sdp_record_t*) it->data;
735       //TODO print some record informations to be sure everything is good
736       sdp_list_t *proto_list = 0;
737       if (sdp_get_access_protos (record, &proto_list) == 0)
738       {
739         channel = sdp_get_proto_port (proto_list, RFCOMM_UUID);
740         sdp_list_free (proto_list, 0);
741       }
742       sdp_record_free (record);
743     }
744   }
745   
746   sdp_list_free (search_list, 0);
747   sdp_list_free (attrid_list, 0);
748   sdp_list_free (response_list, 0);
749   
750   sdp_close (session);
751   
752   if (channel == -1)
753     fprintf (stderr, "Failed to find the listening channel for interface `%.*s': %s\n",
754             IFNAMSIZ, dev->iface, strerror (errno));
755   
756   return channel;
757 }
758
759 /**
760  * Read from the socket and put the result into the buffer for transmission to 'stdout'.
761  * 
762  * @param sock file descriptor for reading
763  * @param buf buffer to read to; first bytes will be the 'struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame',
764  *            followed by the actual payload
765  * @param buf_size size of the buffer
766  * @param ri where to write radiotap_rx info
767  * @return number of bytes written to 'buf'
768  */
769 static ssize_t 
770 read_from_the_socket (int sock, 
771             unsigned char *buf, size_t buf_size,
772             struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri)
773 {
774   unsigned char tmpbuf[buf_size];
775   ssize_t count;
776   int len;
777   struct sockaddr_rc  rc_addr = { 0 }; 
778   
779   count = read (sock, tmpbuf, buf_size); 
780   
781   if (0 > count)
782   {
783     if (EAGAIN == errno)
784       return 0;
785      
786     fprintf (stderr, "Failed to read from the HCI socket: %s\n", strerror (errno));
787     return -1;
788   }
789   
790   /* Get the channel used */ //FIXME probably not needed anymore
791   memset (&rc_addr, 0, sizeof (rc_addr));
792   len = sizeof (rc_addr);
793   if (0 > getsockname (sock, (struct sockaddr *) &rc_addr, (socklen_t *) &len))
794   {
795     fprintf (stderr, "getsockname() call failed : %s\n", strerror (errno));
796     return -1;
797   }
798   
799   memset (ri, 0, sizeof (*ri));
800   ri->ri_channel = rc_addr.rc_channel;
801   
802   /* Detect CRC32 at the end */
803   if (0 == check_crc_buf_osdep (tmpbuf, count - sizeof (uint32_t)))
804   {
805     count -= sizeof(uint32_t);
806   }
807   
808   memcpy (buf, tmpbuf, count);
809   
810   return count;
811 }
812
813 /**
814  * Open the bluetooth interface for reading/writing
815  *
816  * @param dev pointer to the device struct
817  * @return 0 on success
818  */
819 static int
820 open_device (struct HardwareInfos *dev)
821 {   
822   int i, dev_id = -1, fd_hci;
823   struct 
824   {
825     struct hci_dev_list_req list;
826     struct hci_dev_req dev[HCI_MAX_DEV];
827   } request;                              //used for detecting the local devices
828   struct sockaddr_rc rc_addr = { 0 };    //used for binding
829   
830   /* Initialize the neighbour structure */
831   neighbours.dev_id = -1;
832   for (i = 0; i < MAX_PORTS; i++)
833     neighbours.fds[i] = -1;
834   
835   /* Open a HCI socket */
836   fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
837
838   if (fd_hci < 0) 
839   {
840     fprintf (stderr, "Failed to create HCI socket: %s\n", strerror (errno));
841     return -1;
842   }
843         
844   memset (&request, 0, sizeof(request));
845   request.list.dev_num = HCI_MAX_DEV;
846
847   if (ioctl (fd_hci, HCIGETDEVLIST, (void *) &request) < 0)
848   {
849     fprintf (stderr, "ioctl(HCIGETDEVLIST) on interface `%.*s' failed: %s\n",
850             IFNAMSIZ, dev->iface, strerror (errno));
851     return 1;
852   }
853         
854         /* Search for a device with dev->iface name */
855   for (i = 0; i < request.list.dev_num; i++)
856   {
857     struct hci_dev_info dev_info;
858
859     memset (&dev_info, 0, sizeof(struct hci_dev_info));
860     dev_info.dev_id = request.dev[i].dev_id;
861     strncpy (dev_info.name, dev->iface, IFNAMSIZ);
862     
863     if (ioctl (fd_hci, HCIGETDEVINFO, (void *) &dev_info))
864     {
865       fprintf (stderr, "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n",
866              IFNAMSIZ, dev->iface, strerror (errno));
867       return 1;
868     }
869     
870     if (strcmp (dev_info.name, dev->iface) == 0)
871     {
872       
873       dev_id = dev_info.dev_id; //the device was found
874       /**
875        * Copy the MAC address to the device structure
876        */
877       memcpy (&dev->pl_mac, &dev_info.bdaddr, sizeof (bdaddr_t));
878       
879       /* Check if the interface is up */
880       if (hci_test_bit (HCI_UP, (void *) &dev_info.flags) == 0)
881       {
882         /* Bring the interface up */
883         if (ioctl (fd_hci, HCIDEVUP, dev_info.dev_id))
884         {
885           fprintf (stderr, "ioctl(HCIDEVUP) on interface `%.*s' failed: %s\n",
886              IFNAMSIZ, dev->iface, strerror (errno));
887           return 1;
888         }
889       }
890       
891       /* Check if the device is discoverable */
892       if (hci_test_bit (HCI_PSCAN, (void *) &dev_info.flags) == 0 ||
893           hci_test_bit (HCI_ISCAN, (void *) &dev_info.flags) == 0)
894       {
895         /* Set interface Page Scan and Inqury Scan ON */
896         struct hci_dev_req dev_req;
897           
898         memset (&dev_req, 0, sizeof (dev_req));
899         dev_req.dev_id = dev_info.dev_id;
900         dev_req.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
901         
902         if (ioctl (fd_hci, HCISETSCAN, (unsigned long) &dev_req))
903         {  
904           fprintf (stderr, "ioctl(HCISETSCAN) on interface `%.*s' failed: %s\n",
905              IFNAMSIZ, dev->iface, strerror (errno));
906           return 1;
907         }
908         
909       }
910       break;
911     }
912     
913   }
914   
915   /* Check if the interface was not found */
916   if (dev_id == -1)
917   {
918     fprintf (stderr, "The interface %s was not found\n", dev->iface);
919     return 1;
920   }
921   
922   /* Close the hci socket */
923   (void) close(fd_hci);
924   
925   
926   
927   /* Bind the rfcomm socket to the interface */
928   memset (&rc_addr, 0, sizeof (rc_addr)); 
929   rc_addr.rc_family = AF_BLUETOOTH;
930   rc_addr.rc_bdaddr = *BDADDR_ANY;
931  
932   if (bind_socket (dev->fd_rfcomm, &rc_addr) != 0)
933   {
934     fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
935              dev->iface, strerror (errno));
936     return 1;
937   }
938   
939   /* Register a SDP service */
940   if (register_service (dev, rc_addr.rc_channel) != 0)
941   {
942     fprintf (stderr, "Failed to register a service on interface `%.*s': %s\n", IFNAMSIZ,
943              dev->iface, strerror (errno));
944     return 1;
945   }
946   
947   /* Switch socket in listening mode */
948   if (listen (dev->fd_rfcomm, 5) == -1) //FIXME: probably we need a bigger number
949   {
950     fprintf (stderr, "Failed to listen on socket for interface `%.*s': %s\n", IFNAMSIZ,
951              dev->iface, strerror (errno));
952     return 1;
953   }
954   
955   
956   return 0;
957 }
958
959
960 /**
961  * Set the header to sane values to make attacks more difficult
962  *
963  * @param taIeeeHeader pointer to the header of the packet
964  * @param dev pointer to the Hardware_Infos struct
965  *
966  **** copy from gnunet-helper-transport-wlan.c ****
967  */
968 static void
969 mac_set (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
970          const struct HardwareInfos *dev)
971 {
972   taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
973   taIeeeHeader->addr2 = dev->pl_mac;
974   taIeeeHeader->addr3 = mac_bssid_gnunet;
975 }
976
977 /**
978  * Test if the given interface name really corresponds to a bluetooth
979  * device.
980  *
981  * @param iface name of the interface
982  * @return 0 on success, 1 on error
983  **** similar with the one from gnunet-helper-transport-wlan.c ****
984  */
985 static int
986 test_bluetooth_interface (const char *iface)
987 {
988   char strbuf[512];
989   struct stat sbuf;
990   int ret;
991
992   ret = snprintf (strbuf, sizeof (strbuf), 
993                   "/sys/class/bluetooth/%s/subsystem",
994                   iface);
995   if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
996   {
997     fprintf (stderr, 
998              "Did not find 802.15.1 interface `%s'. Exiting.\n", 
999              iface);
1000     exit (1);
1001   }
1002   return 0;
1003 }
1004
1005 /**
1006  * Test incoming packets mac for being our own.
1007  *
1008  * @param taIeeeHeader buffer of the packet
1009  * @param dev the Hardware_Infos struct
1010  * @return 0 if mac belongs to us, 1 if mac is for another target
1011  *
1012  **** same as the one from gnunet-helper-transport-wlan.c ****
1013  */
1014 static int
1015 mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1016           const struct HardwareInfos *dev)
1017 {
1018   static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
1019
1020   if ( (0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
1021        (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)) )
1022     return 0; /* some drivers set no Macs, then assume it is all for us! */
1023
1024   if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1025     return 1; /* not a GNUnet ad-hoc package */
1026   if ( (0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
1027        (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)) )
1028     return 0; /* for us, or broadcast */
1029   return 1; /* not for us */
1030 }
1031
1032
1033 /**
1034  * Process data from the stdin. Takes the message, forces the sender MAC to be correct
1035  * and puts it into our buffer for transmission to the receiver.
1036  *
1037  * @param cls pointer to the device struct ('struct HardwareInfos*')
1038  * @param hdr pointer to the start of the packet
1039  *
1040  **** same as the one from gnunet-helper-transport-wlan.c ****
1041  */
1042 static void
1043 stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1044 {
1045   struct HardwareInfos *dev = cls;
1046   const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header;
1047   struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *blueheader;
1048   size_t sendsize;
1049
1050   sendsize = ntohs (hdr->size);
1051   if ( (sendsize <
1052         sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
1053        (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) ) 
1054   {
1055     fprintf (stderr, "Received malformed message\n");
1056     exit (1);
1057   }
1058   sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) - 
1059                sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1060   if (MAXLINE < sendsize)
1061   {
1062     fprintf (stderr, "Packet too big for buffer\n");
1063     exit (1);
1064   }
1065   header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
1066   memcpy (&write_pout.buf, &header->frame, sendsize);
1067   blueheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf;
1068
1069   /* payload contains MAC address, but we don't trust it, so we'll
1070   * overwrite it with OUR MAC address to prevent mischief */
1071   mac_set (blueheader, dev);
1072   memcpy (&blueheader->addr1, &header->frame.addr1, 
1073           sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1074   write_pout.size = sendsize;
1075 }
1076
1077 /**
1078  * Broadcast a HELLO message for peer discovery
1079  *
1080  * @param dev pointer to the device struct
1081  * @param dev pointer to the socket which was added to the set
1082  * @return 0 on success
1083  */
1084 static int 
1085 send_broadcast (struct HardwareInfos *dev, int *sendsocket) 
1086 {
1087   int new_device = 0;
1088   int loops = 0;
1089
1090  search_for_devices:
1091   if ((neighbours.size == neighbours.pos && new_device == 1) || neighbours.size == 0) 
1092   { 
1093  inquiry_devices:   //skip the conditions and force a inquiry for new devices
1094     {
1095     /** 
1096      * It means that I sent HELLO messages to all the devices from the list and I should search 
1097      * for new ones or that this is the first time when I do a search.
1098      */
1099     inquiry_info *devices = NULL;
1100     int i, responses, max_responses = MAX_PORTS;
1101
1102     /* sanity checks */
1103     if (neighbours.size >= MAX_PORTS)
1104     {
1105       fprintf (stderr, "%.*s reached the top limit for the discovarable devices\n", IFNAMSIZ, dev->iface);
1106       return 2;
1107     }
1108
1109     /* Get the device id */
1110     if (neighbours.dev_id == -1)
1111     {
1112       char addr[19] = { 0 }; //the device MAC address
1113       
1114       ba2str ((bdaddr_t *) &dev->pl_mac, addr); 
1115       neighbours.dev_id = hci_devid (addr);
1116       if (neighbours.dev_id < 0)
1117       { 
1118         fprintf (stderr, "Failed to get the device id for interface %.*s : %s\n", IFNAMSIZ,
1119                 dev->iface, strerror (errno));
1120         return 1;
1121       }
1122     }
1123   
1124     devices = malloc (max_responses * sizeof (inquiry_info));
1125     if (devices == NULL)
1126     {
1127       fprintf (stderr, "Failed to allocate memory for inquiry info list on interface %.*s\n", IFNAMSIZ,
1128               dev->iface);
1129       return 1;
1130     }
1131            
1132     responses = hci_inquiry (neighbours.dev_id, 8, max_responses, NULL, &devices, IREQ_CACHE_FLUSH);
1133     if (responses < 0)
1134     {
1135       fprintf (stderr, "Failed to inquiry on interface %.*s\n", IFNAMSIZ, dev->iface);
1136       return 1;
1137     }
1138    
1139     fprintf (stderr, "LOG : Found %d devices\n", responses); //FIXME delete it after debugging stage
1140     
1141     if (responses == 0)
1142     {
1143       fprintf (stderr, "LOG : No devices discoverable\n");
1144       return 1;
1145     }
1146     
1147     for (i = 0; i < responses; i++) 
1148     {
1149       int j;
1150       int found = 0;
1151
1152       /* sanity check */
1153       if (i >= MAX_PORTS)
1154       {
1155         fprintf (stderr, "%.*s reached the top limit for the discoverable devices (after inquiry)\n", IFNAMSIZ,
1156                 dev->iface);
1157         return 2;
1158       }
1159       
1160       /* Search if the address already exists on the list */
1161       for (j = 0; j < neighbours.size; j++)
1162       {
1163         if (memcmp (&(devices + i)->bdaddr, &(neighbours.devices[j]), sizeof (bdaddr_t)) == 0) 
1164         {
1165           found = 1;
1166           fprintf (stderr, "LOG : the device already exists on the list\n"); //FIXME debugging message
1167           break;
1168         }
1169       }
1170
1171       if (found == 0)
1172       {
1173         char addr[19] = { 0 };
1174
1175         ba2str (&(devices +i)->bdaddr, addr);
1176         fprintf (stderr, "LOG : %s was added to the list\n", addr); //FIXME debugging message
1177         memcpy (&(neighbours.devices[neighbours.size++]), &(devices + i)->bdaddr, sizeof (bdaddr_t));
1178       }
1179     }   
1180        
1181     free (devices);
1182     }
1183   }
1184   
1185   int connection_successful = 0;
1186   struct sockaddr_rc addr_rc = { 0 };
1187   int errno_copy = 0;
1188   addr_rc.rc_family = AF_BLUETOOTH;
1189
1190   /* Try to connect to a new device from the list */
1191   while (neighbours.pos < neighbours.size)
1192   {
1193     /* Check if we are already connected to this device */
1194     if (neighbours.fds[neighbours.pos] == -1)
1195     {
1196
1197       memset (&addr_rc.rc_bdaddr, 0, sizeof (addr_rc.rc_bdaddr));
1198       memcpy (&addr_rc.rc_bdaddr, &(neighbours.devices[neighbours.pos]), sizeof (addr_rc.rc_bdaddr));
1199     
1200       addr_rc.rc_channel = get_channel (dev, addr_rc.rc_bdaddr);
1201     
1202       *sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1203       if (connect (*sendsocket, (struct sockaddr *)&addr_rc, sizeof (addr_rc)) == 0)
1204       {
1205         neighbours.fds[neighbours.pos++] = *sendsocket;
1206         connection_successful = 1;
1207         char addr[19] = { 0 };
1208         ba2str (&(neighbours.devices[neighbours.pos - 1]), addr);
1209         fprintf (stderr, "LOG : Connected to %s\n", addr);
1210
1211         break;
1212       }
1213       else
1214       {
1215         char addr[19] = { 0 };
1216         errno_copy = errno;  //Save a copy for later
1217         ba2str (&(neighbours.devices[neighbours.pos]), addr);
1218         fprintf (stderr, "LOG : Couldn't connect on device %s, error : %s\n", addr, strerror(errno));
1219         if (errno != ECONNREFUSED) //FIXME be sure that this works
1220         {
1221           fprintf (stderr, "LOG : Removes %d device from the list\n", neighbours.pos);
1222           /* Remove the device from the list */
1223           memcpy (&neighbours.devices[neighbours.pos], &neighbours.devices[neighbours.size - 1], sizeof (bdaddr_t));
1224           memset (&neighbours.devices[neighbours.size - 1], 0, sizeof (bdaddr_t));
1225           neighbours.fds[neighbours.pos] = neighbours.fds[neighbours.size - 1];
1226           neighbours.fds[neighbours.size - 1] = -1;
1227           neighbours.size -= 1;
1228         }
1229
1230         neighbours.pos += 1;
1231
1232         if (neighbours.pos >= neighbours.size)
1233             neighbours.pos = 0;
1234
1235         loops += 1;
1236
1237         if (loops == MAX_LOOPS) //don't get stuck trying to connect to one device
1238           return 1;
1239       }
1240     }
1241     else
1242     {
1243       fprintf (stderr, "LOG : Search for a new device\n"); //FIXME debugging message
1244       neighbours.pos += 1;
1245     }
1246   }
1247   
1248   /* Cycle on the list */
1249   if (neighbours.pos == neighbours.size)
1250   {
1251     neighbours.pos = 0;
1252     searching_devices_count += 1;
1253
1254     if (searching_devices_count == MAX_LOOPS)
1255     {
1256       fprintf (stderr, "LOG : Force to inquiry for new devices\n");
1257       searching_devices_count = 0;
1258       goto inquiry_devices;
1259     }
1260   }
1261  /* If a new device wasn't found, search an old one */
1262   if (connection_successful == 0) 
1263   {
1264     int loop_check = neighbours.pos;
1265     while (neighbours.fds[neighbours.pos] == -1)
1266     {
1267       if (neighbours.pos == neighbours.size)
1268         neighbours.pos = 0;
1269       
1270       if (neighbours.pos == loop_check)
1271       {
1272         if (errno_copy == ECONNREFUSED)
1273         {
1274           fprintf (stderr, "LOG : No device found. Go back and search again\n"); //FIXME debugging message
1275           new_device = 1;
1276           loops += 1;
1277           goto search_for_devices;
1278         }
1279         else
1280         {
1281           return 1; // Skip the broadcast message
1282         }
1283       }
1284
1285       neighbours.pos += 1;
1286     }
1287
1288     *sendsocket = neighbours.fds[neighbours.pos++];
1289   }
1290
1291   return 0;
1292 }
1293
1294 /**
1295  * Main function of the helper.  This code accesses a bluetooth interface
1296  * forwards traffic in both directions between the bluetooth interface and 
1297  * stdin/stdout of this process.  Error messages are written to stderr.
1298  *
1299  * @param argc number of arguments, must be 2
1300  * @param argv arguments only argument is the name of the interface (i.e. 'hci0')
1301  * @return 0 on success (never happens, as we don't return unless aborted), 1 on error
1302  *
1303  **** similar to gnunet-helper-transport-wlan.c ****
1304  */
1305 int
1306 main (int argc, char *argv[])
1307 {   
1308   struct HardwareInfos dev;
1309   char readbuf[MAXLINE];
1310   int maxfd;
1311   fd_set rfds;
1312   fd_set wfds;
1313   int stdin_open;
1314   struct MessageStreamTokenizer *stdin_mst;
1315   int raw_eno, i;
1316   uid_t uid;
1317   int crt_rfds = 0, rfds_list[MAX_PORTS];
1318   int broadcast, sendsocket;
1319   /* Assert privs so we can modify the firewall rules! */
1320   uid = getuid ();
1321 #ifdef HAVE_SETRESUID
1322   if (0 != setresuid (uid, 0, 0))
1323   {
1324     fprintf (stderr, "Failed to setresuid to root: %s\n", strerror (errno));
1325     return 254;
1326   }
1327 #else
1328   if (0 != seteuid (0)) 
1329   {
1330     fprintf (stderr, "Failed to seteuid back to root: %s\n", strerror (errno));
1331     return 254;
1332   }
1333 #endif
1334
1335   /* Make use of SGID capabilities on POSIX */
1336   memset (&dev, 0, sizeof (dev));
1337   dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1338   raw_eno = errno; /* remember for later */
1339
1340   /* Now that we've dropped root rights, we can do error checking */
1341   if (2 != argc)
1342   {
1343     fprintf (stderr, "You must specify the name of the interface as the first \
1344                       and only argument to this program.\n");
1345     if (-1 != dev.fd_rfcomm)
1346       (void) close (dev.fd_rfcomm);
1347     return 1;
1348   }
1349
1350   if (-1 == dev.fd_rfcomm)
1351   {
1352     fprintf (stderr, "Failed to create a HCI socket: %s\n", strerror (raw_eno));
1353     return 1;
1354   }
1355   if (dev.fd_rfcomm >= FD_SETSIZE)
1356   {
1357     fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1358              dev.fd_rfcomm, FD_SETSIZE);
1359     (void) close (dev.fd_rfcomm);
1360     return 1;
1361   }
1362   if (0 != test_bluetooth_interface (argv[1]))
1363   {
1364     (void) close (dev.fd_rfcomm);
1365     return 1;
1366   }
1367   strncpy (dev.iface, argv[1], IFNAMSIZ);
1368   if (0 != open_device (&dev))
1369   {
1370     (void) close (dev.fd_rfcomm);
1371     return 1;
1372   }
1373
1374   /* Drop privs */
1375   {
1376     uid_t uid = getuid ();
1377 #ifdef HAVE_SETRESUID
1378     if (0 != setresuid (uid, uid, uid))
1379     {
1380       fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1381       if (-1 != dev.fd_rfcomm)
1382         (void) close (dev.fd_rfcomm);
1383       return 1;
1384     }
1385 #else
1386     if (0 != (setuid (uid) | seteuid (uid)))
1387     {
1388       fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
1389       if (-1 != dev.fd_rfcomm)
1390         (void) close (dev.fd_rfcomm);
1391       return 1;
1392     }
1393 #endif
1394   }
1395
1396  /* Send MAC address of the bluetooth interface to STDOUT first */
1397   {
1398     struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
1399
1400     macmsg.hdr.size = htons (sizeof (macmsg));
1401     macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
1402     memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1403     memcpy (write_std.buf, &macmsg, sizeof (macmsg));
1404     write_std.size = sizeof (macmsg);
1405   }
1406     
1407  
1408   stdin_mst = mst_create (&stdin_send_hw, &dev);  
1409   stdin_open = 1;
1410   
1411   fprintf (stderr, "\n-----------------------------------------------\n      Check if the program exits\n-----------------------------------------------\n");
1412  /**
1413   * TODO : When a connection fails I should ignore only the CONTROL messages. 
1414   * For DATA messages I should retry to send the message until it doesn't fail
1415   * Also I should make the time out of a mac endpoint smaller and check if the rate 
1416   * from get_wlan_header (plugin_transport_bluetooth.c) is correct.
1417   */ 
1418  while (1)
1419   {
1420     maxfd = -1;
1421     broadcast = 0;
1422     sendsocket = -1;
1423
1424     FD_ZERO (&rfds);
1425     if ((0 == write_pout.size) && (1 == stdin_open))
1426     {
1427       FD_SET (STDIN_FILENO, &rfds);
1428       maxfd = MAX (maxfd, STDIN_FILENO);
1429     }
1430     if (0 == write_std.size)
1431     {
1432       FD_SET (dev.fd_rfcomm, &rfds);
1433       maxfd = MAX (maxfd, dev.fd_rfcomm);
1434     }
1435
1436     for (i = 0; i < crt_rfds; i++)  // it can receive messages from multiple devices 
1437     {
1438       FD_SET (rfds_list[i], &rfds);
1439       maxfd = MAX (maxfd, rfds_list[i]);
1440     }
1441     FD_ZERO (&wfds);
1442     if (0 < write_std.size)
1443     {
1444       FD_SET (STDOUT_FILENO, &wfds);
1445       maxfd = MAX (maxfd, STDOUT_FILENO);
1446     }
1447     if (0 < write_pout.size) //it can send messages only to one device per loop
1448     {    
1449       struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *frame;
1450       /* Get the destination address */
1451       frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) write_pout.buf;
1452       
1453       if (memcmp (&frame->addr1, &dev.pl_mac, 
1454                   sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1455       {
1456         broadcast = 1;
1457         memset (&write_pout, 0, sizeof (write_pout)); //clear the buffer 
1458       } 
1459       else if (memcmp (&frame->addr1, &broadcast_address, 
1460                 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1461       {
1462         fprintf (stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n", dev.iface, neighbours.pos, neighbours.size); //FIXME: debugging message
1463         // broadcast = 1; // IF I HAVE A BROADCAST MESSAGE I skip.
1464         // memset (&write_pout, 0, sizeof (write_pout));
1465        
1466         if (send_broadcast(&dev, &sendsocket) != 0) //if the searching wasn't successful don't get stuck on the select stage
1467         {
1468           broadcast = 1;
1469           memset (&write_pout, 0, sizeof (write_pout)); //remove the message
1470           fprintf (stderr, "LOG : Skip the broadcast message (pos %d, size %d)\n", neighbours.pos, neighbours.size);
1471         }
1472         else
1473         {
1474           FD_SET (sendsocket, &wfds);
1475           maxfd = MAX (maxfd, sendsocket);
1476         }
1477       } 
1478       else 
1479       {
1480         int found = 0;
1481         int pos = 0;
1482         /* Search if the address already exists on the list */
1483         for (i = 0; i < neighbours.size; i++)
1484         {
1485           if (memcmp (&frame->addr1, &(neighbours.devices[i]), sizeof (bdaddr_t)) == 0) 
1486           {
1487             pos = i;
1488             if (neighbours.fds[i] != -1)
1489             {
1490               found = 1;  //save the position where it was found
1491               FD_SET (neighbours.fds[i], &wfds);
1492               maxfd = MAX (maxfd, neighbours.fds[i]);
1493               sendsocket = neighbours.fds[i];
1494               fprintf (stderr, "LOG: the address was found in the list\n");
1495               break;
1496             }
1497           }
1498         }
1499         if (found == 0)
1500         {
1501           int status;
1502           struct sockaddr_rc addr = { 0 };
1503         
1504           fprintf (stderr, "LOG : %s has a new message for %.2X:%.2X:%.2X:%.2X:%.2X:%.2X which isn't on the broadcast list\n", dev.iface, 
1505                   frame->addr1.mac[5], frame->addr1.mac[4], frame->addr1.mac[3],
1506                   frame->addr1.mac[2], frame->addr1.mac[1], frame->addr1.mac[0]); //FIXME: debugging message      
1507           
1508           sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1509           
1510           if (sendsocket < 0) 
1511           {
1512             fprintf (stderr, "Failed to create a RFCOMM socket (sending stage): %s\n", 
1513                     strerror (errno));
1514             return -1;
1515           }
1516                                   
1517           memcpy (&addr.rc_bdaddr, &frame->addr1, sizeof (bdaddr_t));
1518           addr.rc_family = AF_BLUETOOTH;
1519           addr.rc_channel = get_channel (&dev, addr.rc_bdaddr);
1520           
1521           int tries = 0;
1522           connect_retry:
1523           status = connect (sendsocket, (struct sockaddr *) &addr, sizeof (addr));
1524                 if (0 != status && errno != EAGAIN)
1525                 {
1526             if (errno == ECONNREFUSED && tries < 2)
1527             {
1528               fprintf (stderr, "LOG : %.*s failed to connect. Trying again!\n", IFNAMSIZ, dev.iface);
1529               tries++;
1530               goto connect_retry;
1531             }
1532             else if (errno == EBADF)
1533             {
1534               fprintf (stderr, "LOG : %s failed to connect : %s. Skip it!\n", dev.iface, strerror (errno));
1535               memset (&write_pout, 0, sizeof (write_pout));
1536               broadcast = 1;
1537             }
1538             else
1539             {
1540                   fprintf (stderr, "LOG : %s failed to connect : %s. Try again later!\n", dev.iface, strerror (errno));
1541                     memset (&write_pout, 0, sizeof (write_pout));
1542               broadcast = 1;
1543             }
1544                   
1545                 }
1546           else
1547           {
1548             FD_SET (sendsocket, &wfds);
1549             maxfd = MAX (maxfd, sendsocket);
1550             fprintf (stderr, "LOG : Connection successful\n");
1551             if (pos != 0) // save the socket
1552             {
1553               neighbours.fds[pos] = sendsocket;
1554             }
1555             else
1556             {
1557               /* Add the new device to the discovered devices list */
1558               if (neighbours.size < MAX_PORTS)
1559               {
1560                 neighbours.fds[neighbours.size] = sendsocket;
1561                 memcpy (&(neighbours.devices[neighbours.size++]), &addr.rc_bdaddr, sizeof (bdaddr_t));
1562               }
1563               else
1564               {
1565                 fprintf (stderr, "The top limit for the discovarable devices' list was reached\n");
1566               }
1567             }
1568           }
1569         }
1570       }
1571     }
1572
1573     if (broadcast == 0)
1574     {
1575       /* Select a fd which is ready for action :) */
1576       {
1577         int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
1578         if ((-1 == retval) && (EINTR == errno))
1579           continue;
1580         if (0 > retval && errno != EBADF)   // we handle BADF errors later
1581         {
1582           fprintf (stderr, "select failed: %s\n", strerror (errno));
1583           break;
1584         }
1585       }
1586       if (FD_ISSET (STDOUT_FILENO , &wfds))
1587       {
1588         ssize_t ret =
1589             write (STDOUT_FILENO, write_std.buf + write_std.pos,
1590                    write_std.size - write_std.pos);
1591         if (0 > ret)
1592         {
1593           fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1594           break;
1595         }
1596         write_std.pos += ret;
1597         if (write_std.pos == write_std.size)
1598         {
1599           write_std.pos = 0;
1600           write_std.size = 0;
1601         }
1602         fprintf (stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); //FIXME: debugging message
1603         
1604       } 
1605       if (sendsocket != -1)
1606       {
1607         if (FD_ISSET (sendsocket , &wfds))
1608         {
1609           ssize_t ret =
1610       write (sendsocket, write_pout.buf + write_std.pos, 
1611              write_pout.size - write_pout.pos);
1612           if (0 > ret) //FIXME should I first check the error type?
1613           {
1614             fprintf (stderr, "Failed to write to bluetooth device: %s. Closing the socket!\n",
1615                      strerror (errno));         
1616             for (i = 0; i < neighbours.size; i++)
1617             {
1618               if (neighbours.fds[i] == sendsocket)
1619               {
1620                 (void) close(sendsocket);
1621                 neighbours.fds[i] = -1;
1622                 break;
1623               }
1624             }
1625             /* Remove the message */
1626             memset (&write_pout.buf + write_std.pos, 0, (write_pout.size - write_pout.pos)); 
1627             write_pout.pos = 0 ;
1628             write_pout.size = 0;
1629           }
1630           else
1631           {
1632             write_pout.pos += ret;
1633             if ((write_pout.pos != write_pout.size) && (0 != ret))
1634             {
1635               /* We should not get partial sends with packet-oriented devices... */
1636               fprintf (stderr, "Write error, partial send: %u/%u\n",
1637                       (unsigned int) write_pout.pos,
1638                       (unsigned int) write_pout.size);
1639               break;
1640             }
1641             
1642             if (write_pout.pos == write_pout.size)
1643             {
1644               write_pout.pos = 0;
1645               write_pout.size = 0;
1646             }
1647             fprintf (stderr, "LOG : %s sends a message to a DEVICE\n", dev.iface); //FIXME: debugging message
1648           }
1649         }
1650       }
1651       for (i = 0; i <= maxfd; i++)
1652       {
1653         if (FD_ISSET (i, &rfds))
1654         {
1655           if (i == STDIN_FILENO)
1656           {
1657             ssize_t ret = 
1658               read (i, readbuf, sizeof (readbuf));
1659             if (0 > ret)
1660             {
1661               fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno));
1662               break; break;
1663             }
1664             if (0 == ret)
1665             {
1666               /* stop reading... */
1667               stdin_open = 0;
1668             }
1669             else
1670             {
1671               mst_receive (stdin_mst, readbuf, ret);
1672               fprintf (stderr, "LOG : %s receives a message from STDIN\n", dev.iface); //FIXME: debugging message
1673             }
1674           } 
1675           else if (i == dev.fd_rfcomm) 
1676           {
1677             int readsocket;
1678             struct sockaddr_rc addr = { 0 };
1679             unsigned int opt = sizeof (addr);
1680             
1681             readsocket = accept (dev.fd_rfcomm, (struct sockaddr *) &addr, &opt);
1682             fprintf(stderr, "LOG : %s accepts a message\n", dev.iface); //FIXME: debugging message
1683             if (readsocket == -1)
1684             {
1685               fprintf (stderr, "Failed to accept a connection on interface: %.*s\n", IFNAMSIZ, 
1686                   strerror (errno));
1687               break;
1688             }
1689             else
1690             {
1691               FD_SET (readsocket, &rfds);
1692               maxfd = MAX (maxfd, readsocket);
1693               
1694               if (crt_rfds < MAX_PORTS)
1695                 rfds_list[crt_rfds++] = readsocket;
1696               else
1697               {
1698                 fprintf (stderr, "The limit for the read file descriptors list was \
1699                                 reached\n");
1700                 break;
1701               }
1702             }
1703             
1704           } 
1705           else 
1706           {
1707             struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
1708             ssize_t ret;
1709             fprintf (stderr, "LOG : %s reads something from the socket\n", dev.iface);//FIXME : debugging message 
1710             rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
1711             ret =
1712                 read_from_the_socket (i, (unsigned char *) &rrm->frame,
1713                             sizeof (write_std.buf) 
1714                             - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage) 
1715                             + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame), 
1716                             rrm);
1717             if (0 >= ret)
1718             {
1719               int j;
1720               FD_CLR (i, &rfds);
1721               close (i);
1722                /* Remove the socket from the list */
1723               for (j = 0; j < crt_rfds; j++)
1724               {
1725                 if (rfds_list[j] == i)
1726                 {
1727                   rfds_list[j] ^= rfds_list[crt_rfds - 1];
1728                   rfds_list[crt_rfds - 1] ^= rfds_list[j];
1729                   rfds_list[j] ^= rfds_list[crt_rfds - 1];
1730                   crt_rfds -= 1;
1731                   break;
1732                 }
1733               }
1734
1735               fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
1736               break;
1737             }
1738             if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
1739             {
1740               write_std.size = ret 
1741                 + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage) 
1742                 - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
1743               rrm->header.size = htons (write_std.size);
1744               rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
1745             }
1746           }
1747         }
1748       }
1749     }
1750   }
1751   /* Error handling, try to clean up a bit at least */
1752   mst_destroy (stdin_mst);
1753   stdin_mst = NULL;
1754   sdp_close (dev.session);
1755   (void) close (dev.fd_rfcomm);
1756   (void) close (sendsocket);
1757   
1758   for (i = 0; i < crt_rfds; i++)
1759     (void) close (rfds_list[i]);
1760
1761   for (i = 0; i < neighbours.size; i++)
1762     (void) close (neighbours.fds[i]);
1763
1764   return 1;                     /* we never exit 'normally' */
1765 }
1766
1767
1768