Implementing broadcast functionality; Resolving the 'security block' errors; Handling...
[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 a new devices.
58  */
59 #define MAX_LOOPS 3
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  * @param socket the socket used to bind
575  * @param addr pointer to the rfcomm address
576  * @return 0 on success 
577  */ 
578 static int
579 bind_socket (int socket, struct sockaddr_rc *addr)
580 {
581   int port, status;
582   
583   /* Bind every possible port (from 0 to 30) and stop when bind doesn't fail */
584   //FIXME : it should start from port 1, but on my computer it doesn't work :)
585   for (port = 3; port <= 30; port++)
586   {
587     addr->rc_channel = port;
588     status = bind (socket, (struct sockaddr *) addr, sizeof (struct sockaddr_rc));
589     if (status == 0)
590       return 0;
591   }
592   
593   return -1; 
594 }
595
596
597 /**
598  * Function used for creating the service record and registering it.
599  * @param dev pointer to the device struct
600  * @param rc_channel the rfcomm channel
601  * @return 0 on success
602  */
603 static int
604 register_service (struct HardwareInfos *dev, int rc_channel) 
605 {
606   /**
607    * 1. initializations
608    * 2. set the service ID, class, profile information
609    * 3. make the service record publicly browsable
610    * 4. register the RFCOMM channel
611    * 5. set the name, provider and description
612    * 6. register the service record to the local SDP server
613    * 7. cleanup
614    */
615
616   //FIXME: probably this is not the best idea. I should find a different uuid
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_name = "GNUnet";
621   const char *service_dsc = "Bluetooth plugin services";
622   const char *service_prov = "GNUnet provider";                       
623   uuid_t root_uuid, rfcomm_uuid, svc_uuid;  
624   sdp_list_t *root_list = 0, *rfcomm_list = 0, *proto_list = 0,
625      *access_proto_list = 0, *svc_list = 0;
626   sdp_record_t *record = 0;
627   sdp_data_t *channel = 0;
628         
629         record = sdp_record_alloc();
630
631   /* Set the general service ID */
632   sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
633   svc_list = sdp_list_append (0, &svc_uuid);
634   sdp_set_service_classes (record, svc_list);
635   sdp_set_service_id (record, svc_uuid);
636
637         /* Make the service record publicly browsable */
638   sdp_uuid16_create (&root_uuid, PUBLIC_BROWSE_GROUP); 
639   root_list = sdp_list_append (0, &root_uuid); 
640   sdp_set_browse_groups (record, root_list);
641
642         /* Register the RFCOMM channel */
643   sdp_uuid16_create (&rfcomm_uuid, RFCOMM_UUID);
644   channel = sdp_data_alloc (SDP_UINT8, &rc_channel);
645   rfcomm_list = sdp_list_append (0, &rfcomm_uuid);
646   sdp_list_append (rfcomm_list, channel);
647   proto_list = sdp_list_append (0, rfcomm_list);
648
649   /* Set protocol information */
650   access_proto_list = sdp_list_append (0, proto_list);
651   sdp_set_access_protos (record, access_proto_list);
652
653   /* Set the name, provider, and description */
654         sdp_set_info_attr (record, dev->iface, service_prov, service_dsc);
655   
656   /* Connect to the local SDP server */
657   dev->session = sdp_connect (BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
658   
659   if (!dev->session)
660   {
661     fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
662              IFNAMSIZ, dev->iface, strerror (errno));
663     //FIXME exit?
664     return 1;
665   }
666   
667   /* Register the service record */
668   if (sdp_record_register (dev->session, record, 0) < 0)
669   {
670     fprintf (stderr, "Failed to register a service record on interface `%.*s': %s\n",
671              IFNAMSIZ, dev->iface, strerror (errno));
672     //FIXME exit?
673     return 1;
674   }
675   
676   /* Cleanup */
677   sdp_data_free (channel);      
678   sdp_list_free (root_list, 0);
679   sdp_list_free (rfcomm_list, 0);
680   sdp_list_free (proto_list, 0);
681   sdp_list_free (access_proto_list, 0);
682   sdp_list_free (svc_list, 0);
683   sdp_record_free (record);
684   
685   return 0;
686 }
687
688 /**
689  * Function for searching and browsing for a service. This will return the 
690  * port number on which the service is running.
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 //FIXME : Connect directly to the device with the service
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  * @param sock file descriptor for reading
762  * @param buf buffer to read to; first bytes will be the 'struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame',
763  *            followed by the actual payload
764  * @param buf_size size of the buffer
765  * @param ri where to write radiotap_rx info
766  * @return number of bytes written to 'buf'
767  */
768 static ssize_t 
769 read_from_the_socket (int sock, 
770             unsigned char *buf, size_t buf_size,
771             struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri)
772 {
773  /**
774   * 1. Read from the socket in a temporary buffer (check for errors)
775   * 2. Detect if the crc exists
776   * 3. Write the result to the buffer
777   */
778   unsigned char tmpbuf[buf_size];
779   ssize_t count;
780   int len;
781   struct sockaddr_rc  rc_addr = { 0 }; 
782   
783   count = read (sock, tmpbuf, buf_size); 
784   
785   if (0 > count)
786   {
787     if (EAGAIN == errno)
788       return 0;
789      
790     fprintf (stderr, "Failed to read from the HCI socket: %s\n", strerror (errno));
791     return -1;
792   }
793   
794   /* Get the channel used */
795   memset (&rc_addr, 0, sizeof (rc_addr));
796   len = sizeof (rc_addr);
797   if (0 > getsockname (sock, (struct sockaddr *) &rc_addr, (socklen_t *) &len))
798   {
799     fprintf (stderr, "getsockname() call failed : %s\n", strerror (errno));
800     return -1;
801   }
802   
803   memset (ri, 0, sizeof (*ri));
804   ri->ri_channel = rc_addr.rc_channel;
805   
806   /* detect CRC32 at the end */
807   if (0 == check_crc_buf_osdep (tmpbuf, count - sizeof (uint32_t)))
808   {
809     count -= sizeof(uint32_t);
810   }
811   
812   memcpy (buf, tmpbuf, count);
813   
814   return count;
815 }
816
817 /**
818  * Open the bluetooth interface for reading/writing
819  *
820  * @param dev pointer to the device struct
821  * @return 0 on success
822  */
823 static int
824 open_device (struct HardwareInfos *dev)
825 {
826   /**
827    * 1. Open a HCI socket (if RFCOMM protocol is used. If not, the HCI socket is 
828    * saved in dev->rfcomm).
829    * 2. Find the device id (request a list with all the devices and find the one
830    * with the dev->iface name)
831    * 3. If the interface is down try to get it up
832    * 4. Bind the RFCOMM socket to the interface using the bind_socket() method and register
833    * a SDP service
834    * 5. For now use a hard coded port number(channel) value
835    * FIXME : if I use HCI sockets , should I enable RAW_SOCKET MODE?!?!?!
836    */
837    
838   int i, dev_id = -1, fd_hci;
839   struct 
840   {
841     struct hci_dev_list_req list;
842     struct hci_dev_req dev[HCI_MAX_DEV];
843   } request;                      //used for detecting the local devices
844   struct sockaddr_rc rc_addr = { 0 };    //used for binding
845   
846   /* Initialize the neighbour structure */
847   neighbours.dev_id = -1;
848   for (i = 0; i < MAX_PORTS; i++)
849     neighbours.fds[i] = -1;
850   
851   fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
852
853   if (fd_hci < 0) 
854   {
855     fprintf (stderr, "Failed to create HCI socket: %s\n", strerror (errno));
856     return -1;
857   }
858         
859   memset (&request, 0, sizeof(request));
860   request.list.dev_num = HCI_MAX_DEV;
861
862   if (ioctl (fd_hci, HCIGETDEVLIST, (void *) &request) < 0)
863   {
864     fprintf (stderr, "ioctl(HCIGETDEVLIST) on interface `%.*s' failed: %s\n",
865             IFNAMSIZ, dev->iface, strerror (errno));
866     return 1;
867   }
868         
869         /* Search for a device with dev->iface name */
870   for (i = 0; i < request.list.dev_num; i++)
871   {
872     struct hci_dev_info dev_info;
873
874     memset (&dev_info, 0, sizeof(struct hci_dev_info));
875     dev_info.dev_id = request.dev[i].dev_id;
876     strncpy (dev_info.name, dev->iface, IFNAMSIZ);
877     
878     if (ioctl (fd_hci, HCIGETDEVINFO, (void *) &dev_info))
879     {
880       fprintf (stderr, "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n",
881              IFNAMSIZ, dev->iface, strerror (errno));
882       return 1;
883     }
884     
885     if (strcmp (dev_info.name, dev->iface) == 0)
886     {
887       
888       dev_id = dev_info.dev_id; //the device was found
889       /**
890        * Copy the MAC address to the device structure
891        * FIXME: probably this is not the best solution
892        */
893       memcpy (&dev->pl_mac, &dev_info.bdaddr, sizeof (bdaddr_t));
894       
895       /* Check if the interface is UP */
896       if (hci_test_bit (HCI_UP, (void *) &dev_info.flags) == 0)
897       {
898         /* Bring interface up */ //FIXME should I check if is HCI_RUNNING ?!?!??!
899         if (ioctl (fd_hci, HCIDEVUP, dev_info.dev_id))
900         {
901           fprintf (stderr, "ioctl(HCIDEVUP) on interface `%.*s' failed: %s\n",
902              IFNAMSIZ, dev->iface, strerror (errno));
903           return 1;
904         }
905       }
906       
907       /* Check if the device is discoverable */
908       if (hci_test_bit (HCI_PSCAN, (void *) &dev_info.flags) == 0 ||
909           hci_test_bit (HCI_ISCAN, (void *) &dev_info.flags) == 0)
910       {
911         /* Set interface Page Scan and Inqury Scan ON */
912         struct hci_dev_req dev_req;
913           
914         memset (&dev_req, 0, sizeof (dev_req));
915         dev_req.dev_id = dev_info.dev_id;
916         dev_req.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
917         
918         if (ioctl (fd_hci, HCISETSCAN, (unsigned long) &dev_req))
919         {  
920           fprintf (stderr, "ioctl(HCISETSCAN) on interface `%.*s' failed: %s\n",
921              IFNAMSIZ, dev->iface, strerror (errno));
922           return 1;
923         }
924         
925       }
926       
927       //FIXME : Sniff mode!?!
928       //FIXME : RAW MODE?!?
929       
930       break;
931     }
932     
933   }
934   
935   /* Check if the interface was not found */
936   if (dev_id == -1)
937   {
938     fprintf (stderr, "The interface %s was not found\n", dev->iface);
939     return 1;
940   }
941   
942   /* Close the hci socket */
943   (void) close(fd_hci);
944   
945   
946   
947   /* Bind the rfcomm socket to the interface */
948   memset (&rc_addr, 0, sizeof (rc_addr)); 
949   rc_addr.rc_family = AF_BLUETOOTH;
950   rc_addr.rc_bdaddr = *BDADDR_ANY;
951  
952   if (bind_socket (dev->fd_rfcomm, &rc_addr) != 0)
953   {
954     fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
955              dev->iface, strerror (errno));
956     return 1;
957   }
958   
959   /* Register a SDP service */
960   if (register_service (dev, rc_addr.rc_channel) != 0)
961   {
962     fprintf (stderr, "Failed to register a service on interface `%.*s': %s\n", IFNAMSIZ,
963              dev->iface, strerror (errno));
964     return 1;
965   }
966   
967   /* Switch socket in listening mode */
968   if (listen (dev->fd_rfcomm, 5) == -1) //FIXME: probably we need a bigger number
969   {
970     fprintf (stderr, "Failed to listen on socket for interface `%.*s': %s\n", IFNAMSIZ,
971              dev->iface, strerror (errno));
972     return 3;
973   }
974   
975   
976   return 0;
977 }
978
979
980 /**
981  * Set the header to sane values to make attacks more difficult
982  *
983  * @param taIeeeHeader pointer to the header of the packet
984  * @param dev pointer to the Hardware_Infos struct
985  *
986  **** copy from gnunet-helper-transport-wlan.c ****
987  */
988 static void
989 mac_set (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
990          const struct HardwareInfos *dev)
991 {
992   taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
993   taIeeeHeader->addr2 = dev->pl_mac;
994   taIeeeHeader->addr3 = mac_bssid_gnunet;
995 }
996
997 /**
998  * Test if the given interface name really corresponds to a bluetooth
999  * device.
1000  *
1001  * @param iface name of the interface
1002  * @return 0 on success, 1 on error
1003  **** similar with the one from gnunet-helper-transport-wlan.c ****
1004  */
1005 static int
1006 test_bluetooth_interface (const char *iface)
1007 {
1008   char strbuf[512];
1009   struct stat sbuf;
1010   int ret;
1011
1012   ret = snprintf (strbuf, sizeof (strbuf), 
1013                   "/sys/class/bluetooth/%s/subsystem",
1014                   iface);
1015   if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
1016   {
1017     fprintf (stderr, 
1018              "Did not find 802.15.1 interface `%s'. Exiting.\n", 
1019              iface);
1020     exit (1);
1021   }
1022   return 0;
1023 }
1024
1025 /**
1026  * Test incoming packets mac for being our own.
1027  *
1028  * @param taIeeeHeader buffer of the packet
1029  * @param dev the Hardware_Infos struct
1030  * @return 0 if mac belongs to us, 1 if mac is for another target
1031  *
1032  **** same as the one from gnunet-helper-transport-wlan.c ****
1033  */
1034 static int
1035 mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1036           const struct HardwareInfos *dev)
1037 {
1038   static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
1039
1040   if ( (0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
1041        (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)) )
1042     return 0; /* some drivers set no Macs, then assume it is all for us! */
1043
1044   if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1045     return 1; /* not a GNUnet ad-hoc package */
1046   if ( (0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
1047        (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)) )
1048     return 0; /* for us, or broadcast */
1049   return 1; /* not for us */
1050 }
1051
1052
1053 /**
1054  * Process data from the stdin.  Takes the message forces the sender MAC to be correct
1055  * and puts it into our buffer for transmission to the kernel. (the other device).
1056  *
1057  * @param cls pointer to the device struct ('struct HardwareInfos*')
1058  * @param hdr pointer to the start of the packet
1059  *
1060  **** same as the one from gnunet-helper-transport-wlan.c ****
1061  */
1062 static void
1063 stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1064 {
1065   struct HardwareInfos *dev = cls;
1066   const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header;
1067   struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *blueheader;
1068   size_t sendsize;
1069
1070   sendsize = ntohs (hdr->size);
1071   if ( (sendsize <
1072         sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
1073        (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) ) 
1074   {
1075     fprintf (stderr, "Received malformed message\n");
1076     exit (1);
1077   }
1078   sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) - 
1079                sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1080   if (MAXLINE < sendsize)
1081   {
1082     fprintf (stderr, "Packet too big for buffer\n");
1083     exit (1);
1084   }
1085   header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
1086   memcpy (&write_pout.buf, &header->frame, sendsize);
1087   blueheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf;
1088
1089   /* payload contains MAC address, but we don't trust it, so we'll
1090   * overwrite it with OUR MAC address to prevent mischief */
1091   mac_set (blueheader, dev);
1092   memcpy (&blueheader->addr1, &header->frame.addr1, 
1093           sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)); //FIXME is this correct?
1094   write_pout.size = sendsize;
1095 }
1096
1097 /**
1098  * Broadcast a HELLO message for peer discovery
1099  * @param dev pointer to the device struct
1100  * @param dev pointer to the socket which was added to the set
1101  * @return 0 on success
1102  */
1103 static int 
1104 send_broadcast (struct HardwareInfos *dev, int *sendsocket) 
1105 {
1106   int new_device = 0;
1107   int loops = 0;
1108
1109  search_for_devices:
1110   if ((neighbours.size == neighbours.pos && new_device == 1) || neighbours.size == 0) 
1111   { 
1112  inquiry_devices:   //skip the conditions and force a inquiry for new devices
1113     {
1114     /** 
1115      * It means that I sent HELLO message to all the devices from the list so I should search 
1116      * for another devices or that this is the first time when I do a search for devices.
1117      */
1118     inquiry_info *devices = NULL;
1119     int i, responses, max_responses = MAX_PORTS;
1120
1121     /* sanity checks */
1122     if (neighbours.size >= MAX_PORTS)
1123     {
1124       fprintf (stderr, "%s reached the top limit for the discovarable devices\n", dev->iface);
1125       return 2;
1126     }
1127
1128     /* Get the device id */
1129     if (neighbours.dev_id == -1)
1130     {
1131       char addr[19] = { 0 }; //the device MAC address
1132       
1133       ba2str ((bdaddr_t *) &dev->pl_mac, addr); 
1134       neighbours.dev_id = hci_devid (addr);
1135       if (neighbours.dev_id < 0)
1136       { 
1137         fprintf (stderr, "Failed to get the device id for interface %s : %s\n",
1138                 dev->iface, strerror (errno));
1139         return 1;
1140       }
1141     }
1142   
1143     devices = malloc (max_responses * sizeof (inquiry_info));
1144     if (devices == NULL)
1145     {
1146       fprintf (stderr, "Failed to allocate memory for inquiry info list on interface %s\n",
1147               dev->iface);
1148       return 1;
1149     }
1150            
1151     responses = hci_inquiry (neighbours.dev_id, 8, max_responses, NULL, &devices, IREQ_CACHE_FLUSH);
1152     if (responses < 0)
1153     {
1154       fprintf (stderr, "Failed to inquiry on interface %s\n", dev->iface);
1155       return 1;
1156     }
1157    
1158     fprintf (stderr, "Found %d devices\n", responses); //FIXME delete it after debugging stage
1159     
1160     if (responses == 0)
1161     {
1162       fprintf (stderr, "No devices discoverable\n");
1163       return 1;
1164     }
1165     
1166     for (i = 0; i < responses; i++) 
1167     {
1168       int j;
1169       int found = 0;
1170
1171       /* sanity check */
1172       if (i >= MAX_PORTS)
1173       {
1174         fprintf (stderr, "%s reached the top limit for the discoverable devices (after inquiry)\n", dev->iface);
1175         return 2;
1176       }
1177       
1178       /* Search if the address already exists on the list */
1179       for (j = 0; j < neighbours.size; j++)
1180       {
1181         if (memcmp (&(devices + i)->bdaddr, &(neighbours.devices[j]), sizeof (bdaddr_t)) == 0) 
1182         {
1183           found = 1;
1184           fprintf (stderr, "the device already exists on the list\n"); //FIXME debugging message
1185           break;
1186         }
1187       }
1188
1189       if (found == 0)
1190       {
1191         char addr[19] = { 0 };
1192
1193         ba2str (&(devices +i)->bdaddr, addr);
1194         fprintf (stderr, "%s was added to the list\n", addr); //FIXME debugging message
1195         memcpy (&(neighbours.devices[neighbours.size++]), &(devices + i)->bdaddr, sizeof (bdaddr_t));
1196       }
1197     }   
1198        
1199     free (devices);
1200     }
1201   }
1202   
1203   int connection_successful = 0;
1204   struct sockaddr_rc addr_rc = { 0 };
1205   int errno_copy = 0;
1206   addr_rc.rc_family = AF_BLUETOOTH;
1207
1208   /* Try to connect to a new device from the list */
1209   while (neighbours.pos < neighbours.size)
1210   {
1211     /* Check if we are connected to this device */
1212     if (neighbours.fds[neighbours.pos] == -1)
1213     {
1214
1215       memset (&addr_rc.rc_bdaddr, 0, sizeof (addr_rc.rc_bdaddr));
1216       memcpy (&addr_rc.rc_bdaddr, &(neighbours.devices[neighbours.pos]), sizeof (addr_rc.rc_bdaddr));
1217     
1218       addr_rc.rc_channel = get_channel (dev, addr_rc.rc_bdaddr);
1219     
1220       *sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1221     
1222       if (connect (*sendsocket, (struct sockaddr *)&addr_rc, sizeof (addr_rc)) == 0)
1223       {
1224         neighbours.fds[neighbours.pos++] = *sendsocket;
1225         connection_successful = 1;
1226         char addr[19] = { 0 };
1227         ba2str (&(neighbours.devices[neighbours.pos - 1]), addr);
1228         fprintf (stderr, "Connected to %s\n", addr);
1229
1230         break;
1231       }
1232       else
1233       {
1234         char addr[19] = { 0 };
1235         errno_copy = errno;  //Save a copy for later
1236         ba2str (&(neighbours.devices[neighbours.pos]), addr);
1237         fprintf (stderr, "Couldn't connect on device %s, error : %s\n", addr, strerror(errno));
1238         if (errno != ECONNREFUSED) //FIXME nu merge!
1239         {
1240           fprintf (stderr, "Removes %d device from the list\n", neighbours.pos);
1241           /* Remove the device from the list */
1242           memcpy (&neighbours.devices[neighbours.pos], &neighbours.devices[neighbours.size - 1], sizeof (bdaddr_t));
1243           memset (&neighbours.devices[neighbours.size - 1], 0, sizeof (bdaddr_t));
1244           neighbours.fds[neighbours.pos] = neighbours.fds[neighbours.size - 1];
1245           neighbours.fds[neighbours.size - 1] = -1;
1246           neighbours.size -= 1;
1247         }
1248
1249         neighbours.pos += 1;
1250
1251         if (neighbours.pos >= neighbours.size)
1252             neighbours.pos = 0;
1253
1254         loops += 1;
1255
1256         if (loops == MAX_LOOPS) //don't get stuck trying to connect to one device
1257           return 1;
1258       }
1259     }
1260     else
1261     {
1262       fprintf (stderr, "Search for a new device\n"); //FIXME debugging message
1263       neighbours.pos += 1;
1264     }
1265   }
1266   
1267   /* Cycle on the list */
1268   if (neighbours.pos == neighbours.size)
1269   {
1270     neighbours.pos = 0;
1271     searching_devices_count += 1;
1272
1273     if (searching_devices_count == MAX_LOOPS)
1274     {
1275       fprintf (stderr, "Force to inquiry for new devices\n");
1276       searching_devices_count = 0;
1277       goto inquiry_devices;
1278     }
1279   }
1280  /* If a new device wasn't found, search an old one */
1281   if (connection_successful == 0) 
1282   {
1283     int loop_check = neighbours.pos;
1284     while (neighbours.fds[neighbours.pos] == -1)
1285     {
1286       if (neighbours.pos == neighbours.size)
1287         neighbours.pos = 0;
1288       
1289       if (neighbours.pos == loop_check)
1290       {
1291         if (errno_copy == ECONNREFUSED)
1292         {
1293           fprintf (stderr, "No device found. Go back and search again\n"); //FIXME debugging message
1294           new_device = 1;
1295           loops += 1;
1296           goto search_for_devices;
1297         }
1298         else
1299         {
1300           return 1; // Skip the broadcast message
1301         }
1302       }
1303
1304       neighbours.pos += 1;
1305     }
1306
1307     *sendsocket = neighbours.fds[neighbours.pos++];
1308   }
1309
1310   return 0;
1311 }
1312
1313 /**
1314  * Main function of the helper.  This code accesses a bluetooth interface
1315  * forwards traffic in both directions between the bluetooth interface and 
1316  * stdin/stdout of this process.  Error messages are written to stdout.
1317  *
1318  * @param argc number of arguments, must be 2
1319  * @param argv arguments only argument is the name of the interface (i.e. 'hci0')
1320  * @return 0 on success (never happens, as we don't return unless aborted), 1 on error
1321  *
1322  **** same as the one from gnunet-helper-transport-wlan.c ****
1323  */
1324 int
1325 main (int argc, char *argv[])
1326 {   
1327   struct HardwareInfos dev;
1328   char readbuf[MAXLINE];
1329   int maxfd;
1330   fd_set rfds;
1331   fd_set wfds;
1332   int stdin_open;
1333   struct MessageStreamTokenizer *stdin_mst;
1334   int raw_eno, i;
1335   uid_t uid;
1336   int crt_rfds = 0, rfds_list[MAX_PORTS];
1337   int broadcast, sendsocket;
1338   /* Assert privs so we can modify the firewall rules! */
1339   uid = getuid ();
1340 #ifdef HAVE_SETRESUID
1341   if (0 != setresuid (uid, 0, 0))
1342   {
1343     fprintf (stderr, "Failed to setresuid to root: %s\n", strerror (errno));
1344     return 254;
1345   }
1346 #else
1347   if (0 != seteuid (0)) 
1348   {
1349     fprintf (stderr, "Failed to seteuid back to root: %s\n", strerror (errno));
1350     return 254;
1351   }
1352 #endif
1353
1354   /* Make use of SGID capabilities on POSIX */
1355   memset (&dev, 0, sizeof (dev));
1356   dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1357   raw_eno = errno; /* remember for later */
1358
1359   /* Now that we've dropped root rights, we can do error checking */
1360   if (2 != argc)
1361   {
1362     fprintf (stderr, "You must specify the name of the interface as the first \
1363                       and only argument to this program.\n");
1364     if (-1 != dev.fd_rfcomm)
1365       (void) close (dev.fd_rfcomm);
1366     return 1;
1367   }
1368
1369   if (-1 == dev.fd_rfcomm)
1370   {
1371     fprintf (stderr, "Failed to create a HCI socket: %s\n", strerror (raw_eno));
1372     return 1;
1373   }
1374   if (dev.fd_rfcomm >= FD_SETSIZE)
1375   {
1376     fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1377              dev.fd_rfcomm, FD_SETSIZE);
1378     (void) close (dev.fd_rfcomm);
1379     return 1;
1380   }
1381   if (0 != test_bluetooth_interface (argv[1]))
1382   {
1383     (void) close (dev.fd_rfcomm);
1384     return 1;
1385   }
1386   strncpy (dev.iface, argv[1], IFNAMSIZ);
1387   if (0 != open_device (&dev))
1388   {
1389     (void) close (dev.fd_rfcomm);
1390     return 1;
1391   }
1392
1393   /* Drop privs */
1394   {
1395     uid_t uid = getuid ();
1396 #ifdef HAVE_SETRESUID
1397     if (0 != setresuid (uid, uid, uid))
1398     {
1399       fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1400       if (-1 != dev.fd_rfcomm)
1401         (void) close (dev.fd_rfcomm);
1402       return 1;
1403     }
1404 #else
1405     if (0 != (setuid (uid) | seteuid (uid)))
1406     {
1407       fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
1408       if (-1 != dev.fd_rfcomm)
1409         (void) close (dev.fd_rfcomm);
1410       return 1;
1411     }
1412 #endif
1413   }
1414
1415  /* Send MAC address of the bluetooth interface to STDOUT first */
1416   {
1417     struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
1418
1419     macmsg.hdr.size = htons (sizeof (macmsg));
1420     macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
1421     memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1422     memcpy (write_std.buf, &macmsg, sizeof (macmsg));
1423     write_std.size = sizeof (macmsg);
1424   }
1425     
1426  
1427   stdin_mst = mst_create (&stdin_send_hw, &dev);  
1428   stdin_open = 1;
1429   
1430   fprintf (stderr, "\n-----------------------------------------------\n      Check if the program exits\n-----------------------------------------------\n");
1431  /**
1432   * TODO : When a connection fails I should ignore only the CONTROL messages. 
1433   * For DATA messages I should retry to send the message until it doesn't fail
1434   * Also I should make the time out of a mac endpoint smaller and check if the rate 
1435   * from get_wlan_header (plugin_transport_bluetooth.c) is correct.
1436   */ 
1437  while (1)
1438   {
1439     maxfd = -1;
1440     broadcast = 0;
1441     sendsocket = -1;
1442
1443     FD_ZERO (&rfds);
1444     if ((0 == write_pout.size) && (1 == stdin_open))
1445     {
1446     //  fprintf (stderr, "LOG : %s adds STDIN to rfds\n", dev.iface); //FIXME: debugging message
1447       FD_SET (STDIN_FILENO, &rfds);
1448       maxfd = MAX (maxfd, STDIN_FILENO);
1449     }
1450     if (0 == write_std.size)
1451     {
1452     //  fprintf (stderr, "LOG : %s adds fd_rfcomm to rfds\n", dev.iface); //FIXME: debugging message
1453       FD_SET (dev.fd_rfcomm, &rfds);
1454       maxfd = MAX (maxfd, dev.fd_rfcomm);
1455     }
1456
1457     for (i = 0; i < crt_rfds; i++)  // it can receive messages from multiple devices 
1458     {
1459     //  fprintf (stderr, "LOG : %s adds extra fds to rfds\n", dev.iface); //FIXME: debugging message
1460       FD_SET (rfds_list[i], &rfds);
1461       maxfd = MAX (maxfd, rfds_list[i]);
1462     }
1463     FD_ZERO (&wfds);
1464     if (0 < write_std.size)
1465     {
1466     //  fprintf (stderr, "LOG : %s adds STDOUT to wfds\n", dev.iface); //FIXME: debugging message
1467       FD_SET (STDOUT_FILENO, &wfds);
1468       maxfd = MAX (maxfd, STDOUT_FILENO);
1469     }
1470     if (0 < write_pout.size) //it can send messages only to one device per loop
1471     {    
1472       struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *frame;
1473       /* Get the destination address */
1474       //FIXME : not sure if this is correct
1475       frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) write_pout.buf;
1476       
1477       if (memcmp (&frame->addr1, &dev.pl_mac, 
1478                   sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1479       {
1480         fprintf (stderr, "LOG : %s has a message for him:)\n", dev.iface); //FIXME: debugging message
1481         memset (&write_pout, 0, sizeof (write_pout)); // clear the buffer
1482       } 
1483       else if (memcmp (&frame->addr1, &broadcast_address, 
1484                 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1485       {
1486         fprintf (stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n", dev.iface, neighbours.pos, neighbours.size); //FIXME: debugging message
1487         // broadcast = 1; // IF I HAVE A BROADCAST MESSAGE I skip.
1488         // memset (&write_pout, 0, sizeof (write_pout));
1489        
1490         if (send_broadcast(&dev, &sendsocket) != 0) //if the searching wasn't successful don't get stuck on the select stage
1491         {
1492           broadcast = 1;
1493           memset (&write_pout, 0, sizeof (write_pout)); //remove the message
1494           fprintf (stderr, "Skip the broadcast message (pos %d, size %d)\n", neighbours.pos, neighbours.size);
1495         }
1496         else
1497         {
1498           FD_SET (sendsocket, &wfds);
1499           maxfd = MAX (maxfd, sendsocket);
1500         }
1501       } 
1502       else 
1503       {
1504         int found = 0;
1505         /* Search if the address already exists on the list */
1506         for (i = 0; i < neighbours.size; i++)
1507         {
1508           if (memcmp (&frame->addr1, &(neighbours.devices[i]), sizeof (bdaddr_t)) == 0 && neighbours.fds[i] != -1) 
1509           {
1510             found = 1;
1511             FD_SET (neighbours.fds[i], &wfds);
1512             maxfd = MAX (maxfd, neighbours.fds[i]);
1513             sendsocket = neighbours.fds[i];
1514             fprintf (stderr, "LOG: the address was found in the list\n");
1515             break;
1516           }
1517         }
1518         if (found == 0)
1519         {
1520           int status;
1521           struct sockaddr_rc addr = { 0 };
1522         
1523           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, 
1524                   frame->addr1.mac[5], frame->addr1.mac[4], frame->addr1.mac[3],
1525                   frame->addr1.mac[2], frame->addr1.mac[1], frame->addr1.mac[0]); //FIXME: debugging message      
1526           
1527           sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1528           
1529           if (sendsocket < 0) 
1530           {
1531             fprintf (stderr, "Failed to create a RFCOMM socket (sending stage): %s\n", 
1532                     strerror (errno));
1533             return -1;
1534           }
1535                                   
1536           memcpy (&addr.rc_bdaddr, &frame->addr1, sizeof (bdaddr_t));
1537           addr.rc_family = AF_BLUETOOTH;
1538           addr.rc_channel = get_channel (&dev, addr.rc_bdaddr);
1539           
1540           /***
1541            *TODO: use a NON-BLOCKING socket
1542            *    sock_flags = fcntl (sendsocket, F_GETFL, 0);
1543            *    fcntl( sendsocket, F_SETFL, sock_flags | O_NONBLOCK);
1544            */
1545           int tries = 0;
1546           connect_retry:
1547           status = connect (sendsocket, (struct sockaddr *) &addr, sizeof (addr));
1548                 if (0 != status && errno != EAGAIN)
1549                 {
1550             if (errno == ECONNREFUSED && tries < 2)
1551             {
1552               fprintf (stderr, "%s failed to connect. Trying again!\n", dev.iface);
1553               tries++;
1554               goto connect_retry;
1555             }
1556             else if (errno == EBADF)
1557             {
1558               fprintf (stderr, "%s failed to connect : %s. Skip it!\n", dev.iface, strerror (errno));
1559               memset (&write_pout, 0, sizeof (write_pout));
1560               broadcast = 1;
1561             }
1562             else
1563             {
1564                   fprintf (stderr, "%s failed to connect : %s. Try again later!\n", dev.iface, strerror (errno));
1565                     memset (&write_pout, 0, sizeof (write_pout));
1566               broadcast = 1;
1567             }
1568                   
1569                 }
1570           else
1571           {
1572             FD_SET (sendsocket, &wfds);
1573             maxfd = MAX (maxfd, sendsocket);
1574             fprintf (stderr, "Connection successful\n");
1575             /* Add the new device to the discovered devices list */
1576             if (neighbours.size < MAX_PORTS)
1577             {
1578               neighbours.fds[neighbours.size] = sendsocket;
1579               memcpy (&(neighbours.devices[neighbours.size++]), &addr.rc_bdaddr, sizeof (bdaddr_t));
1580             }
1581             else
1582             {
1583               fprintf (stderr, "The top limit for the discovarable devices' list was reached\n");
1584             }
1585           }
1586         }
1587       }
1588     }
1589
1590     if (broadcast == 0)
1591     {
1592       /* Select a fd which is ready for action :) */
1593       {
1594         int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);  //FIXME : when a device close the connection remove the socket from the list
1595         if ((-1 == retval) && (EINTR == errno))
1596           continue;
1597         if (0 > retval && errno != EBADF)   // we handle BADF errors later
1598         {
1599           fprintf (stderr, "select failed: %s\n", strerror (errno));
1600           break;
1601         }
1602       }
1603       if (FD_ISSET (STDOUT_FILENO , &wfds))
1604       {
1605         ssize_t ret =
1606             write (STDOUT_FILENO, write_std.buf + write_std.pos,
1607                    write_std.size - write_std.pos);
1608         if (0 > ret)
1609         {
1610           fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1611           break;
1612         }
1613         write_std.pos += ret;
1614         if (write_std.pos == write_std.size)
1615         {
1616           write_std.pos = 0;
1617           write_std.size = 0;
1618         }
1619         fprintf (stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); //FIXME: debugging message
1620         
1621       } 
1622       if (sendsocket != -1)
1623       {
1624         if (FD_ISSET (sendsocket , &wfds))
1625         {
1626           ssize_t ret =
1627       write (sendsocket, write_pout.buf + write_std.pos, 
1628              write_pout.size - write_pout.pos);
1629           if (0 > ret) //FIXME should I check first the error type?
1630           {
1631             fprintf (stderr, "Failed to write to bluetooth device: %s. Closing the socket!\n",
1632                      strerror (errno));
1633             
1634             for (i = 0; i < neighbours.size; i++)
1635             {
1636               if (neighbours.fds[i] == sendsocket)
1637               {
1638                 (void) close(sendsocket);
1639                 neighbours.fds[i] = -1;
1640                 break;
1641               }
1642             }
1643             //memset (&(write_pout.buf + write_std.pos), 0, (write_pout.size - write_pout.pos)) // FIXME should I remove the message? or try to resend it 
1644             //write_pour.pos = 0 ; write_pout.size = 0;
1645           }
1646           else
1647           {
1648             write_pout.pos += ret;
1649             if ((write_pout.pos != write_pout.size) && (0 != ret))
1650             {
1651               /* we should not get partial sends with packet-oriented devices... */
1652               fprintf (stderr, "Write error, partial send: %u/%u\n",
1653                       (unsigned int) write_pout.pos,
1654                       (unsigned int) write_pout.size);
1655               break;
1656             }
1657             
1658             if (write_pout.pos == write_pout.size)
1659             {
1660               write_pout.pos = 0;
1661               write_pout.size = 0;
1662             }
1663             fprintf (stderr, "LOG : %s sends a message to a DEVICE\n", dev.iface); //FIXME: debugging message
1664           }
1665         }
1666       }
1667       for (i = 0; i <= maxfd; i++) //FIXME it should be incremented
1668       {
1669         if (FD_ISSET (i, &rfds))
1670         {
1671           if (i == STDIN_FILENO)
1672           {
1673             ssize_t ret = 
1674               read (i, readbuf, sizeof (readbuf));
1675             if (0 > ret)
1676             {
1677               fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno));
1678               break;
1679             }
1680             if (0 == ret)
1681             {
1682               /* stop reading... */
1683               stdin_open = 0;
1684             }
1685             else
1686             {
1687               mst_receive (stdin_mst, readbuf, ret);
1688               fprintf (stderr, "LOG : %s receives a message from STDIN\n", dev.iface); //FIXME: debugging message
1689             }
1690           } 
1691           else if (i == dev.fd_rfcomm) 
1692           {
1693             int readsocket;
1694             struct sockaddr_rc addr = { 0 };
1695             unsigned int opt = sizeof (addr);
1696             
1697             readsocket = accept (dev.fd_rfcomm, (struct sockaddr *) &addr, &opt);
1698             fprintf(stderr, "LOG : %s accepts a message\n", dev.iface); //FIXME: debugging message
1699             if (readsocket == -1)
1700             {
1701               fprintf (stderr, "Failed to accept a connection on interface: %s\n", 
1702                   strerror (errno));
1703               return -1;    //FIXME probably I should ignore the error and keep the process alive
1704             }
1705             else
1706             {
1707               FD_SET (readsocket, &rfds);
1708               maxfd = MAX (maxfd, readsocket);
1709               
1710               if (crt_rfds < MAX_PORTS)
1711                 rfds_list[crt_rfds++] = readsocket;
1712               else
1713               {
1714                 fprintf (stderr, "The limit for the read file descriptors list was \
1715                                 reached\n");
1716                 break;
1717               }
1718             }
1719             
1720           } 
1721           else 
1722           {
1723             struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
1724             ssize_t ret;
1725             fprintf (stderr, "LOG : %s reads something from the socket\n", dev.iface);//FIXME : debugging message 
1726             rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
1727             ret =
1728                 read_from_the_socket (i, (unsigned char *) &rrm->frame,
1729                             sizeof (write_std.buf) 
1730                             - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage) 
1731                             + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame), 
1732                             rrm);
1733             if (0 >= ret)
1734             {
1735               int j;
1736               FD_CLR (i, &rfds);
1737               close (i);
1738                /* Remove the socket from the list */
1739               for (j = 0; j < crt_rfds; j++)
1740               {
1741                 if (rfds_list[j] == i)
1742                 {
1743                   rfds_list[j] ^= rfds_list[crt_rfds - 1];
1744                   rfds_list[crt_rfds - 1] ^= rfds_list[j];
1745                   rfds_list[j] ^= rfds_list[crt_rfds - 1];
1746                   crt_rfds -= 1;
1747                   break;
1748                 }
1749               }
1750
1751               fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
1752               break;
1753             }
1754             if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
1755             {
1756               write_std.size = ret 
1757                 + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage) 
1758                 - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
1759               rrm->header.size = htons (write_std.size);
1760               rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
1761               
1762               /* Remove the socket from the list */
1763               int j;
1764               for (j = 0; j < crt_rfds; j++)
1765               {
1766                 if (i == rfds_list[crt_rfds])
1767                 {
1768                   rfds_list[j] ^= rfds_list[crt_rfds];
1769                   rfds_list[crt_rfds] ^= rfds_list[j];
1770                   rfds_list[j] ^= rfds_list[crt_rfds];
1771                   crt_rfds -= 1;
1772                   break;
1773                 }
1774               }
1775             }
1776           }
1777         }
1778       }
1779     }
1780   }
1781   /* Error handling, try to clean up a bit at least */
1782   mst_destroy (stdin_mst);
1783   stdin_mst = NULL;
1784   sdp_close (dev.session);
1785   (void) close (dev.fd_rfcomm);
1786   (void) close (sendsocket);
1787   
1788   for (i = 0; i < crt_rfds; i++)
1789     (void) close (rfds_list[i]);
1790
1791   for (i = 0; i < neighbours.size; i++)
1792     (void) close (neighbours.fds[i]);
1793
1794   return 1;                     /* we never exit 'normally' */
1795 }
1796
1797
1798