Adding a helper file for bluetooth plugin : gnunet-helper-transport-bluetooth.c
[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 #define HARD_CODED_PORT_NUMBER 10
45 #define HARD_CODED_PORT_NUMBER2 10
46
47 /**
48  * Maximum size of a message allowed in either direction
49  * (used for our receive and sent buffers).
50  */
51 #define MAXLINE 4096
52
53
54 /**
55  * struct for storing the information of the hardware.  There is only
56  * one of these.
57  */
58 struct HardwareInfos
59 {
60
61   /**
62    * file descriptor for the rfcomm socket
63    */
64   int fd_rfcomm;
65
66   /**
67    * Name of the interface, not necessarily 0-terminated (!).
68    */
69   char iface[IFNAMSIZ];
70
71   /**
72    * MAC address of our own bluetooth interface.
73    */
74   struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac;
75 };
76
77 /**
78  * IO buffer used for buffering data in transit (to wireless or to stdout).
79  */
80 struct SendBuffer
81 {
82   /**
83    * How many bytes of data are stored in 'buf' for transmission right now?
84    * Data always starts at offset 0 and extends to 'size'.
85    */
86   size_t size;
87
88   /**
89    * How many bytes that were stored in 'buf' did we already write to the
90    * destination?  Always smaller than 'size'.
91    */
92   size_t pos;
93   
94   /**
95    * Buffered data; twice the maximum allowed message size as we add some
96    * headers.
97    */
98   char buf[MAXLINE * 2];
99 };
100
101
102 /**
103  * Buffer for data read from stdin to be transmitted to the bluetooth device
104  */
105 static struct SendBuffer write_pout;
106
107 /**
108  * Buffer for data read from the bluetooth device to be transmitted to stdout.
109  */
110 static struct SendBuffer write_std;
111
112
113 /* *********** specialized version of server_mst.c begins here ********** */
114 /* ****** this is the same version as the one used in gnunet-helper-transport-wlan.c ****** */ 
115
116 /**
117  * To what multiple do we align messages?  8 byte should suffice for everyone
118  * for now.
119  */
120 #define ALIGN_FACTOR 8
121
122 /**
123  * Smallest supported message.
124  */
125 #define MIN_BUFFER_SIZE sizeof (struct GNUNET_MessageHeader)
126
127
128 /**
129  * Functions with this signature are called whenever a
130  * complete message is received by the tokenizer.
131  *
132  * @param cls closure
133  * @param message the actual message
134  */
135 typedef void (*MessageTokenizerCallback) (void *cls, 
136                                           const struct
137                                           GNUNET_MessageHeader *
138                                           message);
139
140 /**
141  * Handle to a message stream tokenizer.
142  */
143 struct MessageStreamTokenizer
144 {
145
146   /**
147    * Function to call on completed messages.
148    */
149   MessageTokenizerCallback cb;
150
151   /**
152    * Closure for cb.
153    */
154   void *cb_cls;
155
156   /**
157    * Size of the buffer (starting at 'hdr').
158    */
159   size_t curr_buf;
160
161   /**
162    * How many bytes in buffer have we already processed?
163    */
164   size_t off;
165
166   /**
167    * How many bytes in buffer are valid right now?
168    */
169   size_t pos;
170
171   /**
172    * Beginning of the buffer.  Typed like this to force alignment.
173    */
174   struct GNUNET_MessageHeader *hdr;
175
176 };
177
178
179 /**
180  * Create a message stream tokenizer.
181  *
182  * @param cb function to call on completed messages
183  * @param cb_cls closure for cb
184  * @return handle to tokenizer
185  */
186 static struct MessageStreamTokenizer *
187 mst_create (MessageTokenizerCallback cb,
188             void *cb_cls)
189 {
190   struct MessageStreamTokenizer *ret;
191
192   ret = malloc (sizeof (struct MessageStreamTokenizer));
193   if (NULL == ret)
194   {
195     fprintf (stderr, "Failed to allocate buffer for tokenizer\n");
196     exit (1);
197   }
198   ret->hdr = malloc (MIN_BUFFER_SIZE);
199   if (NULL == ret->hdr)
200   {
201     fprintf (stderr, "Failed to allocate buffer for alignment\n");
202     exit (1);
203   }
204   ret->curr_buf = MIN_BUFFER_SIZE;
205   ret->cb = cb;
206   ret->cb_cls = cb_cls;
207   return ret;
208 }
209
210
211 /**
212  * Add incoming data to the receive buffer and call the
213  * callback for all complete messages.
214  *
215  * @param mst tokenizer to use
216  * @param buf input data to add
217  * @param size number of bytes in buf
218  * @return GNUNET_OK if we are done processing (need more data)
219  *         GNUNET_SYSERR if the data stream is corrupt
220  */
221 static int
222 mst_receive (struct MessageStreamTokenizer *mst,
223              const char *buf, size_t size)
224 {
225   const struct GNUNET_MessageHeader *hdr;
226   size_t delta;
227   uint16_t want;
228   char *ibuf;
229   int need_align;
230   unsigned long offset;
231   int ret;
232
233   ret = GNUNET_OK;
234   ibuf = (char *) mst->hdr;
235   while (mst->pos > 0)
236   {
237 do_align:
238     if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) ||
239         (0 != (mst->off % ALIGN_FACTOR)))
240     {
241       /* need to align or need more space */
242       mst->pos -= mst->off;
243       memmove (ibuf, &ibuf[mst->off], mst->pos);
244       mst->off = 0;
245     }
246     if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
247     {
248       delta =
249           GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) -
250                       (mst->pos - mst->off), size);
251       memcpy (&ibuf[mst->pos], buf, delta);
252       mst->pos += delta;
253       buf += delta;
254       size -= delta;
255     }
256     if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
257     {
258       return GNUNET_OK;
259     }
260     hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
261     want = ntohs (hdr->size);
262     if (want < sizeof (struct GNUNET_MessageHeader))
263     {
264       fprintf (stderr,
265                "Received invalid message from stdin\n");
266       exit (1);
267     }
268     if (mst->curr_buf - mst->off < want)
269     {
270       /* need more space */
271       mst->pos -= mst->off;
272       memmove (ibuf, &ibuf[mst->off], mst->pos);
273       mst->off = 0;
274     }
275     if (want > mst->curr_buf)
276     {
277       mst->hdr = realloc (mst->hdr, want);
278       if (NULL == mst->hdr)
279       {
280         fprintf (stderr, "Failed to allocate buffer for alignment\n");
281         exit (1);
282       }
283       ibuf = (char *) mst->hdr;
284       mst->curr_buf = want;
285     }
286     hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
287     if (mst->pos - mst->off < want)
288     {
289       delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
290       memcpy (&ibuf[mst->pos], buf, delta);
291       mst->pos += delta;
292       buf += delta;
293       size -= delta;
294     }
295     if (mst->pos - mst->off < want)
296     {
297       return GNUNET_OK;
298     }
299     mst->cb (mst->cb_cls, hdr);
300     mst->off += want;
301     if (mst->off == mst->pos)
302     {
303       /* reset to beginning of buffer, it's free right now! */
304       mst->off = 0;
305       mst->pos = 0;
306     }
307   }
308   while (size > 0)
309   {
310     if (size < sizeof (struct GNUNET_MessageHeader))
311       break;
312     offset = (unsigned long) buf;
313     need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
314     if (GNUNET_NO == need_align)
315     {
316       /* can try to do zero-copy and process directly from original buffer */
317       hdr = (const struct GNUNET_MessageHeader *) buf;
318       want = ntohs (hdr->size);
319       if (want < sizeof (struct GNUNET_MessageHeader))
320       {
321         fprintf (stderr,
322                  "Received invalid message from stdin\n");
323         exit (1);
324       }
325       if (size < want)
326         break;                  /* or not, buffer incomplete, so copy to private buffer... */
327       mst->cb (mst->cb_cls, hdr);
328       buf += want;
329       size -= want;
330     }
331     else
332     {
333       /* need to copy to private buffer to align;
334        * yes, we go a bit more spagetti than usual here */
335       goto do_align;
336     }
337   }
338   if (size > 0)
339   {
340     if (size + mst->pos > mst->curr_buf)
341     {
342       mst->hdr = realloc (mst->hdr, size + mst->pos);
343       if (NULL == mst->hdr)
344       {
345         fprintf (stderr, "Failed to allocate buffer for alignment\n");
346         exit (1);
347       }
348       ibuf = (char *) mst->hdr;
349       mst->curr_buf = size + mst->pos;
350     }
351     if (mst->pos + size > mst->curr_buf)
352     {
353       fprintf (stderr,
354                "Assertion failed\n");
355       exit (1);
356     }
357     memcpy (&ibuf[mst->pos], buf, size);
358     mst->pos += size;
359   }
360   return ret;
361 }
362
363
364 /**
365  * Destroys a tokenizer.
366  *
367  * @param mst tokenizer to destroy
368  */
369 static void
370 mst_destroy (struct MessageStreamTokenizer *mst)
371 {
372   free (mst->hdr);
373   free (mst);
374 }
375
376 /* *****************  end of server_mst.c clone ***************** **/
377
378
379 /* ****** same crc version as the one used in gnunet-helper-transport-wlan.c ****** */ 
380
381 /**
382  * Calculate crc32, the start of the calculation
383  *
384  * @param buf buffer to calc the crc
385  * @param len len of the buffer
386  * @return crc sum
387  */
388 static unsigned long
389 calc_crc_osdep (const unsigned char *buf, size_t len)
390 {
391   static const unsigned long int crc_tbl_osdep[256] = {
392     0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
393     0xE963A535, 0x9E6495A3,
394     0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
395     0xE7B82D07, 0x90BF1D91,
396     0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
397     0xF4D4B551, 0x83D385C7,
398     0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
399     0xFA0F3D63, 0x8D080DF5,
400     0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
401     0xD20D85FD, 0xA50AB56B,
402     0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
403     0xDCD60DCF, 0xABD13D59,
404     0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
405     0xCFBA9599, 0xB8BDA50F,
406     0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
407     0xC1611DAB, 0xB6662D3D,
408     0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
409     0x9FBFE4A5, 0xE8B8D433,
410     0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
411     0x91646C97, 0xE6635C01,
412     0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
413     0x8208F4C1, 0xF50FC457,
414     0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
415     0x8CD37CF3, 0xFBD44C65,
416     0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
417     0xA4D1C46D, 0xD3D6F4FB,
418     0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
419     0xAA0A4C5F, 0xDD0D7CC9,
420     0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
421     0xB966D409, 0xCE61E49F,
422     0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
423     0xB7BD5C3B, 0xC0BA6CAD,
424     0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
425     0x04DB2615, 0x73DC1683,
426     0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
427     0x0A00AE27, 0x7D079EB1,
428     0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
429     0x196C3671, 0x6E6B06E7,
430     0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
431     0x17B7BE43, 0x60B08ED5,
432     0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
433     0x3FB506DD, 0x48B2364B,
434     0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
435     0x316E8EEF, 0x4669BE79,
436     0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
437     0x220216B9, 0x5505262F,
438     0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
439     0x2CD99E8B, 0x5BDEAE1D,
440     0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
441     0x72076785, 0x05005713,
442     0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
443     0x7CDCEFB7, 0x0BDBDF21,
444     0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
445     0x6FB077E1, 0x18B74777,
446     0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
447     0x616BFFD3, 0x166CCF45,
448     0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
449     0x4969474D, 0x3E6E77DB,
450     0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
451     0x47B2CF7F, 0x30B5FFE9,
452     0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
453     0x54DE5729, 0x23D967BF,
454     0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
455     0x5A05DF1B, 0x2D02EF8D
456   };
457
458   unsigned long crc = 0xFFFFFFFF;
459
460   for (; len > 0; len--, buf++)
461     crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
462   return (~crc);
463 }
464
465
466 /**
467  * Calculate and check crc of the bluetooth packet
468  *
469  * @param buf buffer of the packet, with len + 4 bytes of data,
470  *            the last 4 bytes being the checksum
471  * @param len length of the payload in data
472  * @return 0 on success (checksum matches), 1 on error
473  */
474 static int
475 check_crc_buf_osdep (const unsigned char *buf, size_t len)
476 {
477   unsigned long crc;
478
479   crc = calc_crc_osdep (buf, len);
480   buf += len;
481   if (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
482       ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3])
483     return 0;
484   return 1;     
485 }
486
487
488
489 /* ************** end of crc version  ***************** */
490
491
492
493
494 /**
495  * Function for assigning a port number
496  * @return 0 on success 
497  */ 
498 static int
499 bind_socket (int *socket)
500 {
501   int port, status;
502   struct sockaddr_rc src = { 0 };
503   
504   src.rc_family = AF_BLUETOOTH;
505   src.rc_bdaddr = *BDADDR_ANY;
506   
507   /* Bind every possible port (from 0 to 30) and stop when bind doesn't fail */
508   for (port = 1; port <= 30; port++)
509   {
510     src.rc_channel = port;
511     status = bind(*socket, (struct sockaddr *)&src, sizeof(src));
512     if (status == 0)
513       return 0;
514   }
515   
516   return -1; 
517 }
518
519
520 //TODO
521 /**
522  * Function used for creating the service record and registering it.
523  */
524 static sdp_session_t*
525 register_service (void) 
526 {
527   /**
528    * 1. initializations
529    * 2. set the service ID, class, profile information
530    * 3. make the service record publicly nrowsable
531    * 4. register the RFCOMM channel
532    * 5. set the name, provider and description
533    * 6. register the service record to the local SDP server
534    * 7. cleanup
535    */
536   
537   //TODO: For now I will use a hard coded port number but in the end I will implement the SDP protocol 
538     
539    return NULL;
540 }
541
542 //TODO
543 /**
544  * Function for searching and browsing for a service. This will return the 
545  * port number on which the service is running.
546  */
547  
548 static int
549 searching_service (void) 
550 {
551   /**
552    * 1. detect all nearby devices
553    * 2. for each device:
554    * 2.1. connect to the SDP server running
555    * 2.2. get a list of service records with the specific UUID
556    * 2.3. for each service record get a list of the protocol sequences and get 
557    *       the port number
558    */
559    
560    return 0;
561 }
562
563 /**
564  * Read from the socket and put the result into the buffer for transmission to 'stdout'.
565  * @param sock file descriptor for reading
566  * @param buf buffer to read to; first bytes will be the 'struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame',
567  *            followed by the actual payload
568  * @param buf_size size of the buffer
569  * @param ri where to write radiotap_rx info
570  * @return number of bytes written to 'buf'
571  */
572 static ssize_t 
573 read_from_the_socket (int sock, 
574             unsigned char *buf, size_t buf_size,
575             struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri)
576 {
577  /**
578   * 1. Read from the socket in a temporary buffer (check for errors)
579   * 2. Detect if the crc exists
580   * 3. Write the result to the buffer
581   */
582   unsigned char tmpbuf[buf_size];
583   ssize_t count;
584   int len;
585   struct sockaddr_rc  rc_addr = { 0 }; 
586    
587   //count = recv (dev->fd_rfcomm, tmpbuf, buf_size, 0);   //FIXME if I use RFCOMM
588   
589   count = read (sock, tmpbuf, buf_size); 
590   
591   if (0 > count)
592   {
593     if (EAGAIN == errno)
594       return 0;
595      
596     fprintf (stderr, "Failed to read from the HCI socket: %s\n", strerror (errno));
597     return -1;
598   }
599   
600   /* Get the channel used */
601   memset (&rc_addr, 0, sizeof (rc_addr));
602   len = sizeof (rc_addr);
603   if (0 > getsockname (sock, (struct sockaddr *) &rc_addr, (socklen_t *) &len))
604   {
605     fprintf (stderr, "getsockname() call failed : %s\n", strerror (errno));
606     return -1;
607   }
608   
609   memset (ri, 0, sizeof (*ri));
610   ri->ri_channel = rc_addr.rc_channel;
611   
612   /* detect CRC32 at the end */
613   if (0 == check_crc_buf_osdep (tmpbuf, count - sizeof (uint32_t)))
614   {
615     count -= sizeof(uint32_t);
616   }
617   
618   memcpy (buf, tmpbuf, count);
619   
620   return count;
621 }
622
623 /**
624  * Open the bluetooth interface for reading/writing
625  *
626  * @param dev pointer to the device struct
627  * @return 0 on success
628  */
629 static int
630 open_device (struct HardwareInfos *dev)
631 {
632   /**
633    * 1. Open a HCI socket (if RFCOMM protocol is used. If not, the HCI socket is 
634    * saved in dev->fd_hci.
635    * 2. Find the device id (request a list with all the devices and find the one
636    * with the dev->iface name)
637    * 3. If the interface is down try to get it up
638    * 4. TODO: Bind the RFCOMM socket to the interface using the bind_socket() method and register
639    * a SDP service
640    * 5. For now use a hard coded port number(channel) value
641    * FIXME : if I use HCI sockets , should I enable RAW_SOCKET MODE?!?!?!
642    */
643    
644   int i, dev_id = -1, fd_hci;
645   struct 
646   {
647     struct hci_dev_list_req list;
648     struct hci_dev_req dev[HCI_MAX_DEV];
649   } request;                      //used for detecting the local devices
650   struct sockaddr_rc rc_addr = { 0 };    //used for binding
651   
652   fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
653
654   if (fd_hci < 0) 
655   {
656     fprintf (stderr, "Failed to create HCI socket: %s\n", strerror (errno));
657     return -1;
658   }
659         
660   memset (&request, 0, sizeof(request));
661   request.list.dev_num = HCI_MAX_DEV;
662
663   if (ioctl (fd_hci, HCIGETDEVLIST, (void *) &request) < 0)
664   {
665     fprintf (stderr, "ioctl(HCIGETDEVLIST) on interface `%.*s' failed: %s\n",
666             IFNAMSIZ, dev->iface, strerror (errno));
667     return 1;
668   }
669         
670         /* Search for a device with dev->iface name */
671   for (i = 0; i < request.list.dev_num; i++)
672   {
673     struct hci_dev_info dev_info;
674
675     memset (&dev_info, 0, sizeof(struct hci_dev_info));
676     dev_info.dev_id = request.dev[i].dev_id;
677     strncpy (dev_info.name, dev->iface, IFNAMSIZ);
678     
679     if (ioctl (fd_hci, HCIGETDEVINFO, (void *) &dev_info))
680     {
681       fprintf (stderr, "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n",
682              IFNAMSIZ, dev->iface, strerror (errno));
683       return 1;
684     }
685     
686     if (strcmp (dev_info.name, dev->iface) == 0)
687     {
688       char addr[19] = { 0 };  //the device MAC address
689       
690       dev_id = dev_info.dev_id; //the device was found
691       
692       ba2str (&dev_info.bdaddr, addr); //get the device's MAC address
693       //TODO : copy the MAC address to the device structure
694       memcpy (&dev->pl_mac, &dev_info.bdaddr, sizeof (bdaddr_t));
695       
696       /* Check if the interface is UP */
697       if (hci_test_bit (HCI_UP, (void *) &dev_info.flags) == 0)
698       {
699         /* Bring interface up */ //FIXME should I check if is HCI_RUNNING ?!?!??!
700         if (ioctl (fd_hci, HCIDEVUP, dev_info.dev_id))
701         {
702           fprintf (stderr, "ioctl(HCIDEVUP) on interface `%.*s' failed: %s\n",
703              IFNAMSIZ, dev->iface, strerror (errno));
704           return 1;
705         }
706       }
707       
708       /* Check if the device is discoverable */
709       if (hci_test_bit (HCI_PSCAN, (void *) &dev_info.flags) == 0 ||
710           hci_test_bit (HCI_ISCAN, (void *) &dev_info.flags) == 0)
711       {
712         /* Set interface Page Scan and Inqury Scan ON */
713         struct hci_dev_req dev_req;
714           
715         memset (&dev_req, 0, sizeof (dev_req));
716         dev_req.dev_id = dev_info.dev_id;
717         dev_req.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
718         
719         if (ioctl (fd_hci, HCISETSCAN, (unsigned long) &dev_req))
720         {  
721           fprintf (stderr, "ioctl(HCISETSCAN) on interface `%.*s' failed: %s\n",
722              IFNAMSIZ, dev->iface, strerror (errno));
723           return 1;
724         }
725         
726       }
727       
728       //FIXME : Sniff mode!?!
729       //FIXME : RAW MODE?!?
730       
731       break;
732     }
733     
734   }
735   
736   /* Check if the interface was not found */
737   if (dev_id == -1)
738   {
739     fprintf (stderr, "The interface %s was not found\n", dev->iface);
740     return 1;
741   }
742   
743   /* Close the hci socket */
744   (void) close(fd_hci);
745   
746   
747   
748   /* Bind the rfcomm socket to the interface */
749   memset (&rc_addr, 0, sizeof (rc_addr)); 
750   rc_addr.rc_family = AF_BLUETOOTH;
751   rc_addr.rc_bdaddr = *BDADDR_ANY;
752   rc_addr.rc_channel = (uint8_t) HARD_CODED_PORT_NUMBER;
753  
754   if (bind (dev->fd_rfcomm, (struct sockaddr *) &rc_addr, sizeof (rc_addr) != 0))
755   {
756     fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
757              dev->iface, strerror (errno));
758     return 1;
759   }
760   
761   /*
762   memset (&hci_addr, 0, sizeof (hci_addr));
763         hci_addr.hci_family = AF_BLUETOOTH;
764         hci_addr.hci_dev = dev_id;
765         */
766         /**
767          * FIXME      hci_addr.hci_channel = HARD_CODED_PORT_NUMBER 
768          * For linux kernel >= 2.6.7 the kernel automatically chooses an available port
769          * number. (getsockname() function can be used for finding out what port the kernel 
770          * chose).
771          */
772         /*
773   if (-1 == bind (dev->fd_hci, (struct sockaddr *) &hci_addr, sizeof (hci_addr)))
774   {
775     fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
776              dev->iface, strerror (errno));
777     return 1;
778   }
779   */
780   
781   if (listen (dev->fd_rfcomm, 5) == -1)
782   {
783     fprintf (stderr, "Failed to listen on socket for interface `%.*s': %s\n", IFNAMSIZ,
784              dev->iface, strerror (errno));
785     return 3;
786   }
787   
788   
789   return 0;
790 }
791
792
793 /**
794  * Set the header to sane values to make attacks more difficult
795  *
796  * @param taIeeeHeader pointer to the header of the packet
797  * @param dev pointer to the Hardware_Infos struct
798  *
799  **** copy from gnunet-helper-transport-wlan.c ****
800  */
801 static void
802 mac_set (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
803          const struct HardwareInfos *dev)
804 {
805   taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
806   taIeeeHeader->addr2 = dev->pl_mac;
807   taIeeeHeader->addr3 = mac_bssid_gnunet;
808 }
809
810 /**
811  * Test if the given interface name really corresponds to a bluetooth
812  * device.
813  *
814  * @param iface name of the interface
815  * @return 0 on success, 1 on error
816  **** similar with the one from gnunet-helper-transport-wlan.c ****
817  */
818 static int
819 test_bluetooth_interface (const char *iface)
820 {
821   char strbuf[512];
822   struct stat sbuf;
823   int ret;
824
825   ret = snprintf (strbuf, sizeof (strbuf), 
826                   "/sys/class/bluetooth/%s/subsystem",
827                   iface);
828   if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
829   {
830     fprintf (stderr, 
831              "Did not find 802.15.1 interface `%s'. Exiting.\n", 
832              iface);
833     exit (1);
834   }
835   return 0;
836 }
837
838 /**
839  * Test incoming packets mac for being our own.
840  *
841  * @param taIeeeHeader buffer of the packet
842  * @param dev the Hardware_Infos struct
843  * @return 0 if mac belongs to us, 1 if mac is for another target
844  *
845  **** same as the one from gnunet-helper-transport-wlan.c ****
846  */
847 static int
848 mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
849           const struct HardwareInfos *dev)
850 {
851   static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
852
853   if ( (0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
854        (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)) )
855     return 0; /* some drivers set no Macs, then assume it is all for us! */
856
857   if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
858     return 1; /* not a GNUnet ad-hoc package */
859   if ( (0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
860        (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)) )
861     return 0; /* for us, or broadcast */
862   return 1; /* not for us */
863 }
864
865
866 /**
867  * Process data from the stdin.  Takes the message forces the sender MAC to be correct
868  * and puts it into our buffer for transmission to the kernel. (the other device).
869  *
870  * @param cls pointer to the device struct ('struct HardwareInfos*')
871  * @param hdr pointer to the start of the packet
872  *
873  **** same as the one from gnunet-helper-transport-wlan.c ****
874  */
875 static void
876 stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
877 {
878   struct HardwareInfos *dev = cls;
879   const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header;
880   struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *blueheader;
881   size_t sendsize;
882
883   sendsize = ntohs (hdr->size);
884   if ( (sendsize <
885         sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
886        (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) ) 
887   {
888     fprintf (stderr, "Received malformed message\n");
889     exit (1);
890   }
891   sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
892   if (MAXLINE < sendsize)
893   {
894     fprintf (stderr, "Packet too big for buffer\n");
895     exit (1);
896   }
897   header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
898   memcpy (&write_pout.buf, &header->frame, sendsize);
899   blueheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf;
900
901   /* payload contains MAC address, but we don't trust it, so we'll
902   * overwrite it with OUR MAC address to prevent mischief */
903   mac_set (blueheader, dev);
904   write_pout.size = sendsize;
905 }
906
907
908 /**
909  * Main function of the helper.  This code accesses a bluetooth interface
910  * forwards traffic in both directions between the bluetooth interface and 
911  * stdin/stdout of this
912  * process.  Error messages are written to stdout.
913  *
914  * @param argc number of arguments, must be 2
915  * @param argv arguments only argument is the name of the interface (i.e. 'mon0')
916  * @return 0 on success (never happens, as we don't return unless aborted), 1 on error
917  *
918  **** same as the one from gnunet-helper-transport-wlan.c ****
919  */
920 int
921 main (int argc, char *argv[])
922 {   
923   struct HardwareInfos dev;
924   char readbuf[MAXLINE];
925   char dest[18];
926   int maxfd;
927   fd_set rfds;
928   fd_set wfds;
929   int stdin_open;
930   struct MessageStreamTokenizer *stdin_mst;
931   int raw_eno, i;
932   uid_t uid;
933
934   /* assert privs so we can modify the firewall rules! */
935   uid = getuid ();
936 #ifdef HAVE_SETRESUID
937   if (0 != setresuid (uid, 0, 0))
938   {
939     fprintf (stderr, "Failed to setresuid to root: %s\n", strerror (errno));
940     return 254;
941   }
942 #else
943   if (0 != seteuid (0)) 
944   {
945     fprintf (stderr, "Failed to seteuid back to root: %s\n", strerror (errno));
946     return 254;
947   }
948 #endif
949
950   /* make use of SGID capabilities on POSIX */
951   memset (&dev, 0, sizeof (dev));
952   dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
953   //FIXME : using RFCOMM protocol : dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
954   raw_eno = errno; /* remember for later */
955
956   /* now that we've dropped root rights, we can do error checking */
957   if (2 != argc)
958   {
959     fprintf (stderr,
960              "You must specify the name of the interface as the first and only argument to this program.\n");
961     if (-1 != dev.fd_rfcomm)
962       (void) close (dev.fd_rfcomm);
963     return 1;
964   }
965
966   if (-1 == dev.fd_rfcomm)
967   {
968     fprintf (stderr, "Failed to create a HCI socket: %s\n", strerror (raw_eno));
969     return 1;
970   }
971   if (dev.fd_rfcomm >= FD_SETSIZE)
972   {
973     fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
974              dev.fd_rfcomm, FD_SETSIZE);
975     (void) close (dev.fd_rfcomm);
976     return 1;
977   }
978   if (0 != test_bluetooth_interface (argv[1]))
979   {
980     (void) close (dev.fd_rfcomm);
981     return 1;
982   }
983   strncpy (dev.iface, argv[1], IFNAMSIZ);
984   if (0 != open_device (&dev))
985   {
986     (void) close (dev.fd_rfcomm);
987     return 1;
988   }
989
990   /* drop privs */
991   {
992     uid_t uid = getuid ();
993 #ifdef HAVE_SETRESUID
994     if (0 != setresuid (uid, uid, uid))
995     {
996       fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
997       if (-1 != dev.fd_rfcomm)
998         (void) close (dev.fd_rfcomm);
999       return 1;
1000     }
1001 #else
1002     if (0 != (setuid (uid) | seteuid (uid)))
1003     {
1004       fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
1005       if (-1 != dev.fd_rfcomm)
1006         (void) close (dev.fd_rfcomm);
1007       return 1;
1008     }
1009 #endif
1010   }
1011
1012
1013   /* send MAC address of the bluetooth interface to STDOUT first */
1014   {
1015     struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
1016
1017     macmsg.hdr.size = htons (sizeof (macmsg));
1018     macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
1019     memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1020     memcpy (write_std.buf, &macmsg, sizeof (macmsg));
1021     write_std.size = sizeof (macmsg);
1022   }  
1023
1024   stdin_mst = mst_create (&stdin_send_hw, &dev);  
1025   stdin_open = 1;
1026   while (1)
1027   {
1028     maxfd = -1;
1029     FD_ZERO (&rfds);
1030     if ((0 == write_pout.size) && (1 == stdin_open))
1031     {
1032       FD_SET (STDIN_FILENO, &rfds);
1033       maxfd = MAX (maxfd, STDIN_FILENO);
1034     }
1035     if (0 == write_std.size)
1036     {
1037       FD_SET (dev.fd_rfcomm, &rfds);
1038       maxfd = MAX (maxfd, dev.fd_rfcomm);
1039     }
1040     FD_ZERO (&wfds);
1041     if (0 < write_std.size)
1042     {
1043       FD_SET (STDOUT_FILENO, &wfds);
1044       maxfd = MAX (maxfd, STDOUT_FILENO);
1045     }
1046     if (0 < write_pout.size)
1047     {
1048       int sendsocket, status;
1049       struct sockaddr_rc addr = { 0 };
1050       
1051       memset (dest, 0, sizeof (dest));
1052       
1053       sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1054       
1055       if (sendsocket < 0) 
1056       {
1057         fprintf (stderr, "Failed to create a RFCOMM socket (sending stage): %s\n", 
1058                 strerror (errno));
1059         return -1;
1060       }
1061       
1062       addr.rc_family = AF_BLUETOOTH;
1063       addr.rc_channel = HARD_CODED_PORT_NUMBER2; //TODO: dinamically binding
1064       str2ba(dest, &addr.rc_bdaddr);  //TODO: get the destination address from the message
1065       
1066       /*TODO: use a NON-BLOCKING socket
1067        *      sock_flags = fcntl (sendsocket, F_GETFL, 0);
1068        *      fcntl( sendsocket, F_SETFL, sock_flags | O_NONBLOCK);
1069       */
1070       status = connect (sendsocket, (struct sockaddr *) &addr, sizeof (addr));
1071             if (0 != status && errno != EAGAIN)
1072             {
1073                 //fprintf (stderr, "connect error on %s\n", argv[1]);
1074               perror("Connect error");
1075               return -1;
1076             }
1077       
1078       FD_SET (sendsocket, &wfds);
1079       maxfd = MAX (maxfd, sendsocket);
1080     }
1081     {
1082       int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
1083       if ((-1 == retval) && (EINTR == errno))
1084         continue;
1085       if (0 > retval)
1086       {
1087         fprintf (stderr, "select failed: %s\n", strerror (errno));
1088         break;
1089       }
1090     }
1091     
1092     for (i = 0; i <= maxfd; i++)
1093     {
1094       if (FD_ISSET (i , &wfds))
1095       {
1096         if (i == STDOUT_FILENO)
1097         {
1098           ssize_t ret =
1099               write (STDOUT_FILENO, write_std.buf + write_std.pos,
1100                      write_std.size - write_std.pos);
1101           if (0 > ret)
1102           {
1103             fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1104             break;
1105           }
1106           write_std.pos += ret;
1107           if (write_std.pos == write_std.size)
1108           {
1109             write_std.pos = 0;
1110             write_std.size = 0;
1111           }
1112         } 
1113         else 
1114         {
1115           ssize_t ret =
1116             write (i, write_pout.buf + write_std.pos, 
1117                    write_pout.size - write_pout.pos);
1118           if (0 > ret)
1119           {
1120             fprintf (stderr, "Failed to write to bluetooth device: %s\n",
1121                      strerror (errno));
1122             break;
1123           }
1124           write_pout.pos += ret;
1125           if ((write_pout.pos != write_pout.size) && (0 != ret))
1126           {
1127             /* we should not get partial sends with packet-oriented devices... */
1128             fprintf (stderr, "Write error, partial send: %u/%u\n",
1129                      (unsigned int) write_pout.pos,
1130                      (unsigned int) write_pout.size);
1131             break;
1132           }
1133           if (write_pout.pos == write_pout.size)
1134           {
1135             write_pout.pos = 0;
1136             write_pout.size = 0;
1137             (void) close (i);
1138           }
1139         }
1140       }
1141
1142       if (FD_ISSET (i, &rfds))
1143       {
1144         if (i == STDIN_FILENO)
1145         {
1146           ssize_t ret = 
1147             read (i, readbuf, sizeof (readbuf));
1148           if (0 > ret)
1149           {
1150             fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno));
1151             break;
1152           }
1153           if (0 == ret)
1154           {
1155             /* stop reading... */
1156             stdin_open = 0;
1157           }
1158           mst_receive (stdin_mst, readbuf, ret);
1159         } 
1160         else if (i == dev.fd_rfcomm) 
1161         {
1162           int newfd;
1163           struct sockaddr_rc addr = { 0 };
1164           unsigned int opt = sizeof (addr);
1165           
1166           newfd = accept (dev.fd_rfcomm, (struct sockaddr *) &addr, &opt);
1167           
1168           if (newfd == -1)
1169           {
1170             fprintf (stderr, "Failed to accept a connection on interface: %s\n", 
1171                 strerror (errno));
1172             return -1;
1173           } else {
1174             FD_SET (newfd, &rfds);
1175             maxfd = MAX (maxfd, newfd);
1176           }
1177           
1178         } 
1179         else 
1180         {
1181           struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
1182           ssize_t ret;
1183
1184           rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
1185           ret =
1186               read_from_the_socket (i, (unsigned char *) &rrm->frame,
1187                           sizeof (write_std.buf) 
1188                           - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage) 
1189                           + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame), 
1190                           rrm);
1191           if (0 > ret)
1192           {
1193             fprintf (stderr, "Read error from rfcomm socket: %s\n", strerror (errno));
1194             break;
1195           }
1196           if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
1197           {
1198             write_std.size = ret 
1199               + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage) 
1200               - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
1201             rrm->header.size = htons (write_std.size);
1202             rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
1203           }
1204         }
1205       }
1206     }
1207   }
1208   /* Error handling, try to clean up a bit at least */
1209   mst_destroy (stdin_mst);
1210   (void) close (dev.fd_rfcomm);
1211   
1212   return 1;                     /* we never exit 'normally' */
1213   
1214 }
1215
1216
1217