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