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