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