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