GNUnet  0.11.x
gnunet-helper-transport-bluetooth.c
Go to the documentation of this file.
1 /*
2  This file is part of GNUnet.
3  Copyright (C) 2010, 2011, 2012 GNUnet e.V.
4  Copyright (c) 2007, 2008, Andy Green <andy@warmcat.com>
5  Copyright Copyright (C) 2009 Thomas d'Otreppe
6 
7  GNUnet is free software: you can redistribute it and/or modify it
8  under the terms of the GNU Affero General Public License as published
9  by the Free Software Foundation, either version 3 of the License,
10  or (at your 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  Affero General Public License for more details.
16 
17  You should have received a copy of the GNU Affero General Public License
18  along with this program. If not, see <http://www.gnu.org/licenses/>.
19 
20  SPDX-License-Identifier: AGPL3.0-or-later
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 "plugin_transport_wlan.h"
42 #include "gnunet_protocols.h"
43 
44 
48 #define MAX_PORTS 30
49 
54 #define MAXLINE 4096
55 
56 
60 #define MAX_LOOPS 5
61 
65 #define BLUEZ_DEVNAME_SIZE 8
66 
72 {
76  char iface[IFNAMSIZ];
77 
81  int fd_rfcomm;
82 
87 
91  sdp_session_t *session;
92 };
93 
97 struct SendBuffer
98 {
103  size_t size;
104 
109  size_t pos;
110 
115  char buf[MAXLINE * 2];
116 };
117 
118 #ifdef LINUX
119 
123 struct BroadcastMessages
124 {
125  /* List with the discoverable devices' addresses */
126  bdaddr_t devices[MAX_PORTS];
127 
128  /* List with the open sockets */
129  int fds[MAX_PORTS];
130 
131 
132  /* The number of the devices */
133  int size;
134 
135  /* The current position */
136  int pos;
137 
138  /* The device id */
139  int dev_id;
140 };
141 
145 static struct GNUNET_TRANSPORT_WLAN_MacAddress broadcast_address = { { 255, 255,
146  255, 255,
147  255,
148  255 } };
149 
153 static struct BroadcastMessages neighbours;
154 
155 static int searching_devices_count = 0;
156 #endif
157 
161 static struct SendBuffer write_pout;
162 
166 static struct SendBuffer write_std;
167 
168 
169 /* ****** this are the same functions as the ones used in gnunet-helper-transport-wlan.c ****** */
170 
175 #define ALIGN_FACTOR 8
176 
180 #define MIN_BUFFER_SIZE sizeof(struct GNUNET_MessageHeader)
181 
182 
190 typedef void (*MessageTokenizerCallback) (void *cls,
191  const struct
193  message);
194 
199 {
204 
208  void *cb_cls;
209 
213  size_t curr_buf;
214 
218  size_t off;
219 
223  size_t pos;
224 
229 };
230 
231 
239 static struct MessageStreamTokenizer *
241  void *cb_cls)
242 {
243  struct MessageStreamTokenizer *ret;
244 
245  ret = malloc (sizeof(struct MessageStreamTokenizer));
246  if (NULL == ret)
247  {
248  fprintf (stderr, "Failed to allocate buffer for tokenizer\n");
249  exit (1);
250  }
251  ret->hdr = malloc (MIN_BUFFER_SIZE);
252  if (NULL == ret->hdr)
253  {
254  fprintf (stderr, "Failed to allocate buffer for alignment\n");
255  exit (1);
256  }
257  ret->curr_buf = MIN_BUFFER_SIZE;
258  ret->cb = cb;
259  ret->cb_cls = cb_cls;
260  ret->pos = 0;
261 
262  return ret;
263 }
264 
265 
276 static int
278  const char *buf, size_t size)
279 {
280  const struct GNUNET_MessageHeader *hdr;
281  size_t delta;
282  uint16_t want;
283  char *ibuf;
284  int need_align;
285  unsigned long offset;
286  int ret;
287 
288  ret = GNUNET_OK;
289  ibuf = (char *) mst->hdr;
290  while (mst->pos > 0)
291  {
292 do_align:
293  if (mst->pos < mst->off)
294  {
295  // fprintf (stderr, "We processed too many bytes!\n");
296  return GNUNET_SYSERR;
297  }
298  if ((mst->curr_buf - mst->off < sizeof(struct GNUNET_MessageHeader)) ||
299  (0 != (mst->off % ALIGN_FACTOR)))
300  {
301  /* need to align or need more space */
302  mst->pos -= mst->off;
303  memmove (ibuf, &ibuf[mst->off], mst->pos);
304  mst->off = 0;
305  }
306  if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader))
307  {
308  delta =
309  GNUNET_MIN (sizeof(struct GNUNET_MessageHeader)
310  - (mst->pos - mst->off), size);
311  GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
312  mst->pos += delta;
313  buf += delta;
314  size -= delta;
315  }
316  if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader))
317  {
318  // FIXME should I reset ??
319  // mst->off = 0;
320  // mst->pos = 0;
321  return GNUNET_OK;
322  }
323  hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
324  want = ntohs (hdr->size);
325  if (want < sizeof(struct GNUNET_MessageHeader))
326  {
327  fprintf (stderr,
328  "Received invalid message from stdin\n");
329  return GNUNET_SYSERR;
330  }
331  if ((mst->curr_buf - mst->off < want) &&
332  (mst->off > 0))
333  {
334  /* need more space */
335  mst->pos -= mst->off;
336  memmove (ibuf, &ibuf[mst->off], mst->pos);
337  mst->off = 0;
338  }
339  if (want > mst->curr_buf)
340  {
341  if (mst->off != 0)
342  {
343  fprintf (stderr, "Error! We should proceeded 0 bytes\n");
344  return GNUNET_SYSERR;
345  }
346  mst->hdr = realloc (mst->hdr, want);
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 = want;
354  }
355  hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
356  if (mst->pos - mst->off < want)
357  {
358  delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
359  if (mst->pos + delta > mst->curr_buf)
360  {
361  fprintf (stderr, "The size of the buffer will be exceeded!\n");
362  return GNUNET_SYSERR;
363  }
364  GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
365  mst->pos += delta;
366  buf += delta;
367  size -= delta;
368  }
369  if (mst->pos - mst->off < want)
370  {
371  // FIXME should I use this?
372  // mst->off = 0;
373  // mst->pos = 0;
374  return GNUNET_OK;
375  }
376  mst->cb (mst->cb_cls, hdr);
377  mst->off += want;
378  if (mst->off == mst->pos)
379  {
380  /* reset to beginning of buffer, it's free right now! */
381  mst->off = 0;
382  mst->pos = 0;
383  }
384  }
385  if (0 != mst->pos)
386  {
387  fprintf (stderr,
388  "There should some valid bytes in the buffer on this stage\n");
389  return GNUNET_SYSERR;
390  }
391  while (size > 0)
392  {
393  if (size < sizeof(struct GNUNET_MessageHeader))
394  break;
395  offset = (unsigned long) buf;
396  need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
397  if (GNUNET_NO == need_align)
398  {
399  /* can try to do zero-copy and process directly from original buffer */
400  hdr = (const struct GNUNET_MessageHeader *) buf;
401  want = ntohs (hdr->size);
402  if (want < sizeof(struct GNUNET_MessageHeader))
403  {
404  fprintf (stderr,
405  "Received invalid message from stdin\n");
406  // exit (1);
407  mst->off = 0;
408  return GNUNET_SYSERR;
409  }
410  if (size < want)
411  break; /* or not, buffer incomplete, so copy to private buffer... */
412  mst->cb (mst->cb_cls, hdr);
413  buf += want;
414  size -= want;
415  }
416  else
417  {
418  /* need to copy to private buffer to align;
419  * yes, we go a bit more spagetti than usual here */
420  goto do_align;
421  }
422  }
423  if (size > 0)
424  {
425  if (size + mst->pos > mst->curr_buf)
426  {
427  mst->hdr = realloc (mst->hdr, size + mst->pos);
428  if (NULL == mst->hdr)
429  {
430  fprintf (stderr, "Failed to allocate buffer for alignment\n");
431  exit (1);
432  }
433  ibuf = (char *) mst->hdr;
434  mst->curr_buf = size + mst->pos;
435  }
436  if (mst->pos + size > mst->curr_buf)
437  {
438  fprintf (stderr,
439  "Assertion failed\n");
440  exit (1);
441  }
442  GNUNET_memcpy (&ibuf[mst->pos], buf, size);
443  mst->pos += size;
444  }
445  return ret;
446 }
447 
448 
454 static void
456 {
457  free (mst->hdr);
458  free (mst);
459 }
460 
461 
469 static unsigned long
470 calc_crc_osdep (const unsigned char *buf, size_t len)
471 {
472  static const unsigned long int crc_tbl_osdep[256] = {
473  0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
474  0xE963A535, 0x9E6495A3,
475  0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
476  0xE7B82D07, 0x90BF1D91,
477  0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
478  0xF4D4B551, 0x83D385C7,
479  0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
480  0xFA0F3D63, 0x8D080DF5,
481  0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
482  0xD20D85FD, 0xA50AB56B,
483  0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
484  0xDCD60DCF, 0xABD13D59,
485  0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
486  0xCFBA9599, 0xB8BDA50F,
487  0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
488  0xC1611DAB, 0xB6662D3D,
489  0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
490  0x9FBFE4A5, 0xE8B8D433,
491  0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
492  0x91646C97, 0xE6635C01,
493  0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
494  0x8208F4C1, 0xF50FC457,
495  0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
496  0x8CD37CF3, 0xFBD44C65,
497  0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
498  0xA4D1C46D, 0xD3D6F4FB,
499  0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
500  0xAA0A4C5F, 0xDD0D7CC9,
501  0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
502  0xB966D409, 0xCE61E49F,
503  0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
504  0xB7BD5C3B, 0xC0BA6CAD,
505  0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
506  0x04DB2615, 0x73DC1683,
507  0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
508  0x0A00AE27, 0x7D079EB1,
509  0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
510  0x196C3671, 0x6E6B06E7,
511  0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
512  0x17B7BE43, 0x60B08ED5,
513  0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
514  0x3FB506DD, 0x48B2364B,
515  0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
516  0x316E8EEF, 0x4669BE79,
517  0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
518  0x220216B9, 0x5505262F,
519  0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
520  0x2CD99E8B, 0x5BDEAE1D,
521  0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
522  0x72076785, 0x05005713,
523  0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
524  0x7CDCEFB7, 0x0BDBDF21,
525  0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
526  0x6FB077E1, 0x18B74777,
527  0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
528  0x616BFFD3, 0x166CCF45,
529  0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
530  0x4969474D, 0x3E6E77DB,
531  0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
532  0x47B2CF7F, 0x30B5FFE9,
533  0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
534  0x54DE5729, 0x23D967BF,
535  0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
536  0x5A05DF1B, 0x2D02EF8D
537  };
538 
539  unsigned long crc = 0xFFFFFFFF;
540 
541  for (; len > 0; len--, buf++)
542  crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
543  return(~crc);
544 }
545 
546 
555 static int
556 check_crc_buf_osdep (const unsigned char *buf, size_t len)
557 {
558  unsigned long crc;
559 
560  crc = calc_crc_osdep (buf, len);
561  buf += len;
562  if ((((crc) & 0xFF) == buf[0]) && (((crc >> 8) & 0xFF) == buf[1]) &&
563  ( ((crc >> 16) & 0xFF) == buf[2]) && ( ((crc >> 24) & 0xFF) == buf[3]) )
564  return 0;
565  return 1;
566 }
567 
568 
569 /* ************** end of clone ***************** */
570 #ifdef LINUX
571 
578 static int
579 bind_socket (int socket, struct sockaddr_rc *addr)
580 {
581  int port, status;
582 
583  /* Bind every possible port (from 0 to 30) and stop when binding doesn't fail */
584  // FIXME : it should start from port 1, but on my computer it doesn't work :)
585  for (port = 3; port <= 30; port++)
586  {
587  addr->rc_channel = port;
588  status = bind (socket, (struct sockaddr *) addr, sizeof(struct
589  sockaddr_rc));
590  if (status == 0)
591  return 0;
592  }
593 
594  return -1;
595 }
596 
597 
598 #endif
599 
607 static int
608 register_service (struct HardwareInfos *dev, int rc_channel)
609 {uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
619  dev->pl_mac.mac[5], dev->pl_mac.mac[4],
620  dev->pl_mac.mac[3],
621  dev->pl_mac.mac[2], dev->pl_mac.mac[1],
622  dev->pl_mac.mac[0] };
623  const char *service_dsc = "Bluetooth plugin services";
624  const char *service_prov = "GNUnet provider";
625  uuid_t root_uuid, rfcomm_uuid, svc_uuid;
626  sdp_list_t *root_list = 0, *rfcomm_list = 0, *proto_list = 0,
627  *access_proto_list = 0, *svc_list = 0;
628  sdp_record_t *record = 0;
629  sdp_data_t *channel = 0;
630 
631  record = sdp_record_alloc ();
632 
633  /* Set the general service ID */
634  sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
635  svc_list = sdp_list_append (0, &svc_uuid);
636  sdp_set_service_classes (record, svc_list);
637  sdp_set_service_id (record, svc_uuid);
638 
639  /* Make the service record publicly browsable */
640  sdp_uuid16_create (&root_uuid, PUBLIC_BROWSE_GROUP);
641  root_list = sdp_list_append (0, &root_uuid);
642  sdp_set_browse_groups (record, root_list);
643 
644  /* Register the RFCOMM channel */
645  sdp_uuid16_create (&rfcomm_uuid, RFCOMM_UUID);
646  channel = sdp_data_alloc (SDP_UINT8, &rc_channel);
647  rfcomm_list = sdp_list_append (0, &rfcomm_uuid);
648  sdp_list_append (rfcomm_list, channel);
649  proto_list = sdp_list_append (0, rfcomm_list);
650 
651  /* Set protocol information */
652  access_proto_list = sdp_list_append (0, proto_list);
653  sdp_set_access_protos (record, access_proto_list);
654 
655  /* Set the name, provider, and description */
656  sdp_set_info_attr (record, dev->iface, service_prov, service_dsc);
657 
658  /* Connect to the local SDP server */
659  dev->session = sdp_connect (BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
660 
661  if (! dev->session)
662  {
663  fprintf (stderr,
664  "Failed to connect to the SDP server on interface `%.*s': %s\n",
665  IFNAMSIZ, dev->iface, strerror (errno));
666  // FIXME exit?
667  return 1;
668  }
669 
670  /* Register the service record */
671  if (sdp_record_register (dev->session, record, 0) < 0)
672  {
673  fprintf (stderr,
674  "Failed to register a service record on interface `%.*s': %s\n",
675  IFNAMSIZ, dev->iface, strerror (errno));
676  // FIXME exit?
677  return 1;
678  }
679 
680  /* Cleanup */
681  sdp_data_free (channel);
682  sdp_list_free (root_list, 0);
683  sdp_list_free (rfcomm_list, 0);
684  sdp_list_free (proto_list, 0);
685  sdp_list_free (access_proto_list, 0);
686  sdp_list_free (svc_list, 0);
687  sdp_record_free (record);
688 
689  return 0;
690 }
691 
692 
701 static int
702 get_channel (struct HardwareInfos *dev, bdaddr_t dest)
703 {uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
712  dest.b[5], dest.b[4], dest.b[3],
713  dest.b[2], dest.b[1], dest.b[0] };
714  sdp_session_t *session = 0;
715  sdp_list_t *search_list = 0, *attrid_list = 0, *response_list = 0, *it = 0;
716  uuid_t svc_uuid;
717  uint32_t range = 0x0000ffff;
718  int channel = -1;
719 
720  /* Connect to the local SDP server */
721  session = sdp_connect (BDADDR_ANY, &dest, 0);
722  if (! session)
723  {
724  fprintf (stderr,
725  "Failed to connect to the SDP server on interface `%.*s': %s\n",
726  IFNAMSIZ, dev->iface, strerror (errno));
727  return -1;
728  }
729 
730  sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
731  search_list = sdp_list_append (0, &svc_uuid);
732  attrid_list = sdp_list_append (0, &range);
733 
734  if (sdp_service_search_attr_req (session, search_list,
735  SDP_ATTR_REQ_RANGE, attrid_list,
736  &response_list) == 0)
737  {
738  for (it = response_list; it; it = it->next)
739  {
740  sdp_record_t *record = (sdp_record_t*) it->data;
741  sdp_list_t *proto_list = 0;
742  if (sdp_get_access_protos (record, &proto_list) == 0)
743  {
744  channel = sdp_get_proto_port (proto_list, RFCOMM_UUID);
745  sdp_list_free (proto_list, 0);
746  }
747  sdp_record_free (record);
748  }
749  }
750 
751  sdp_list_free (search_list, 0);
752  sdp_list_free (attrid_list, 0);
753  sdp_list_free (response_list, 0);
754 
755  sdp_close (session);
756 
757  if (-1 == channel)
758  fprintf (stderr,
759  "Failed to find the listening channel for interface `%.*s': %s\n",
760  IFNAMSIZ,
761  dev->iface,
762  strerror (errno));
763 
764  return channel;
765 }
766 
767 
778 static ssize_t
780  unsigned char *buf, size_t buf_size,
782 {
783  unsigned char tmpbuf[buf_size];
784  ssize_t count;
785  count = read (*((int *) sock), tmpbuf, buf_size);
786 
787  if (0 > count)
788  {
789  if (EAGAIN == errno)
790  return 0;
791 
792  fprintf (stderr, "Failed to read from the HCI socket: %s\n", strerror (
793  errno));
794 
795  return -1;
796  }
797 
798  #ifdef LINUX
799  /* Get the channel used */
800  int len;
801  struct sockaddr_rc rc_addr = { 0 };
802 
803  memset (&rc_addr, 0, sizeof(rc_addr));
804  len = sizeof(rc_addr);
805  if (0 > getsockname (*((int *) sock), (struct sockaddr *) &rc_addr,
806  (socklen_t *) &len))
807  {
808  fprintf (stderr, "getsockname() call failed : %s\n", strerror (errno));
809  return -1;
810  }
811 
812  memset (ri, 0, sizeof(*ri));
813  ri->ri_channel = rc_addr.rc_channel;
814  #endif
815 
816  /* Detect CRC32 at the end */
817  if (0 == check_crc_buf_osdep (tmpbuf, count - sizeof(uint32_t)))
818  {
819  count -= sizeof(uint32_t);
820  }
821 
822  GNUNET_memcpy (buf, tmpbuf, count);
823 
824  return count;
825 }
826 
827 
834 static int
836 {
837  int i, dev_id = -1, fd_hci;
838  struct
839  {
840  struct hci_dev_list_req list;
841  struct hci_dev_req dev[HCI_MAX_DEV];
842  } request; // used for detecting the local devices
843  struct sockaddr_rc rc_addr = { 0 }; // used for binding
844 
845  /* Initialize the neighbour structure */
846  neighbours.dev_id = -1;
847  for (i = 0; i < MAX_PORTS; i++)
848  neighbours.fds[i] = -1;
849 
850  /* Open a HCI socket */
851  fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
852 
853  if (fd_hci < 0)
854  {
855  fprintf (stderr,
856  "Failed to create HCI socket: %s\n",
857  strerror (errno));
858  return -1;
859  }
860 
861  memset (&request, 0, sizeof(request));
862  request.list.dev_num = HCI_MAX_DEV;
863 
864  if (ioctl (fd_hci, HCIGETDEVLIST, (void *) &request) < 0)
865  {
866  fprintf (stderr,
867  "ioctl(HCIGETDEVLIST) on interface `%.*s' failed: %s\n",
868  IFNAMSIZ,
869  dev->iface,
870  strerror (errno));
871  (void) close (fd_hci);
872  return 1;
873  }
874 
875  /* Search for a device with dev->iface name */
876  for (i = 0; i < request.list.dev_num; i++)
877  {
878  struct hci_dev_info dev_info;
879 
880  memset (&dev_info, 0, sizeof(struct hci_dev_info));
881  dev_info.dev_id = request.dev[i].dev_id;
882  strncpy (dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE);
883 
884  if (ioctl (fd_hci, HCIGETDEVINFO, (void *) &dev_info))
885  {
886  fprintf (stderr,
887  "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n",
888  IFNAMSIZ,
889  dev->iface,
890  strerror (errno));
891  (void) close (fd_hci);
892  return 1;
893  }
894 
895  if (strncmp (dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE) == 0)
896  {
897  dev_id = dev_info.dev_id; // the device was found
901  GNUNET_memcpy (&dev->pl_mac, &dev_info.bdaddr, sizeof(bdaddr_t));
902 
903  /* Check if the interface is up */
904  if (hci_test_bit (HCI_UP, (void *) &dev_info.flags) == 0)
905  {
906  /* Bring the interface up */
907  if (ioctl (fd_hci, HCIDEVUP, dev_info.dev_id))
908  {
909  fprintf (stderr,
910  "ioctl(HCIDEVUP) on interface `%.*s' failed: %s\n",
911  IFNAMSIZ,
912  dev->iface,
913  strerror (errno));
914  (void) close (fd_hci);
915  return 1;
916  }
917  }
918 
919  /* Check if the device is discoverable */
920  if ((hci_test_bit (HCI_PSCAN, (void *) &dev_info.flags) == 0) ||
921  (hci_test_bit (HCI_ISCAN, (void *) &dev_info.flags) == 0) )
922  {
923  /* Set interface Page Scan and Inqury Scan ON */
924  struct hci_dev_req dev_req;
925 
926  memset (&dev_req, 0, sizeof(dev_req));
927  dev_req.dev_id = dev_info.dev_id;
928  dev_req.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
929 
930  if (ioctl (fd_hci, HCISETSCAN, (unsigned long) &dev_req))
931  {
932  fprintf (stderr,
933  "ioctl(HCISETSCAN) on interface `%.*s' failed: %s\n",
934  IFNAMSIZ,
935  dev->iface,
936  strerror (errno));
937  (void) close (fd_hci);
938  return 1;
939  }
940  }
941  break;
942  }
943  }
944 
945  /* Check if the interface was not found */
946  if (-1 == dev_id)
947  {
948  fprintf (stderr,
949  "The interface %s was not found\n",
950  dev->iface);
951  (void) close (fd_hci);
952  return 1;
953  }
954 
955  /* Close the hci socket */
956  (void) close (fd_hci);
957 
958 
959  /* Bind the rfcomm socket to the interface */
960  memset (&rc_addr, 0, sizeof(rc_addr));
961  rc_addr.rc_family = AF_BLUETOOTH;
962  rc_addr.rc_bdaddr = *BDADDR_ANY;
963 
964  if (bind_socket (dev->fd_rfcomm, &rc_addr) != 0)
965  {
966  fprintf (stderr,
967  "Failed to bind interface `%.*s': %s\n",
968  IFNAMSIZ,
969  dev->iface,
970  strerror (errno));
971  return 1;
972  }
973 
974  /* Register a SDP service */
975  if (register_service (dev, rc_addr.rc_channel) != 0)
976  {
977  fprintf (stderr,
978  "Failed to register a service on interface `%.*s': %s\n",
979  IFNAMSIZ,
980  dev->iface, strerror (errno));
981  return 1;
982  }
983 
984  /* Switch socket in listening mode */
985  if (listen (dev->fd_rfcomm, 5) == -1) // FIXME: probably we need a bigger number
986  {
987  fprintf (stderr, "Failed to listen on socket for interface `%.*s': %s\n",
988  IFNAMSIZ,
989  dev->iface, strerror (errno));
990  return 1;
991  }
992 
993  return 0;
994 }
995 
996 
1005 static void
1007  const struct HardwareInfos *dev)
1008 {
1009  taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
1010  taIeeeHeader->addr3 = mac_bssid_gnunet;
1011  taIeeeHeader->addr2 = dev->pl_mac;
1012 }
1013 
1014 
1015 #ifdef LINUX
1016 
1024 static int
1025 test_bluetooth_interface (const char *iface)
1026 {
1027  char strbuf[512];
1028  struct stat sbuf;
1029  int ret;
1030 
1031  ret = snprintf (strbuf, sizeof(strbuf),
1032  "/sys/class/bluetooth/%s/subsystem",
1033  iface);
1034  if ((ret < 0) || (ret >= sizeof(strbuf)) || (0 != stat (strbuf, &sbuf)))
1035  {
1036  fprintf (stderr,
1037  "Did not find 802.15.1 interface `%s'. Exiting.\n",
1038  iface);
1039  exit (1);
1040  }
1041  return 0;
1042 }
1043 
1044 
1045 #endif
1046 
1056 static int
1058  const struct HardwareInfos *dev)
1059 {
1060  static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
1061 
1062  if ((0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
1063  (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)))
1064  return 0; /* some drivers set no Macs, then assume it is all for us! */
1065 
1066  if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1067  return 1; /* not a GNUnet ad-hoc package */
1068  if ((0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
1069  (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)))
1070  return 0; /* for us, or broadcast */
1071  return 1; /* not for us */
1072 }
1073 
1074 
1084 static void
1085 stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1086 {
1087  struct HardwareInfos *dev = cls;
1089  struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *blueheader;
1090  size_t sendsize;
1091 
1092  sendsize = ntohs (hdr->size);
1093  if ((sendsize <
1096  {
1097  fprintf (stderr, "Received malformed message\n");
1098  exit (1);
1099  }
1100  sendsize -= (sizeof(struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)
1101  - sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1102  if (MAXLINE < sendsize)
1103  {
1104  fprintf (stderr, "Packet too big for buffer\n");
1105  exit (1);
1106  }
1107  header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
1108  GNUNET_memcpy (&write_pout.buf, &header->frame, sendsize);
1109  blueheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf;
1110 
1111  /* payload contains MAC address, but we don't trust it, so we'll
1112  * overwrite it with OUR MAC address to prevent mischief */
1113  mac_set (blueheader, dev);
1114  GNUNET_memcpy (&blueheader->addr1, &header->frame.addr1,
1115  sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress));
1116  write_pout.size = sendsize;
1117 }
1118 
1119 
1120 #ifdef LINUX
1121 
1128 static int
1129 send_broadcast (struct HardwareInfos *dev, int *sendsocket)
1130 {
1131  int new_device = 0;
1132  int loops = 0;
1133 
1134 search_for_devices:
1135  if (((neighbours.size == neighbours.pos) && (new_device == 1)) ||
1136  (neighbours.size == 0) )
1137  {
1138 inquiry_devices: // skip the conditions and force a inquiry for new devices
1139  {
1144  inquiry_info *devices = NULL;
1145  int i, responses, max_responses = MAX_PORTS;
1146 
1147  /* sanity checks */
1148  if (neighbours.size >= MAX_PORTS)
1149  {
1150  fprintf (stderr,
1151  "%.*s reached the top limit for the discovarable devices\n",
1152  IFNAMSIZ,
1153  dev->iface);
1154  return 2;
1155  }
1156 
1157  /* Get the device id */
1158  if (neighbours.dev_id == -1)
1159  {
1160  char addr[19] = { 0 }; // the device MAC address
1161 
1162  ba2str ((bdaddr_t *) &dev->pl_mac, addr);
1163  neighbours.dev_id = hci_devid (addr);
1164  if (neighbours.dev_id < 0)
1165  {
1166  fprintf (stderr,
1167  "Failed to get the device id for interface %.*s : %s\n",
1168  IFNAMSIZ,
1169  dev->iface, strerror (errno));
1170  return 1;
1171  }
1172  }
1173 
1174  devices = malloc (max_responses * sizeof(inquiry_info));
1175  if (devices == NULL)
1176  {
1177  fprintf (stderr,
1178  "Failed to allocate memory for inquiry info list on interface %.*s\n",
1179  IFNAMSIZ,
1180  dev->iface);
1181  return 1;
1182  }
1183 
1184  responses = hci_inquiry (neighbours.dev_id, 8, max_responses, NULL,
1185  &devices, IREQ_CACHE_FLUSH);
1186  if (responses < 0)
1187  {
1188  fprintf (stderr, "Failed to inquiry on interface %.*s\n", IFNAMSIZ,
1189  dev->iface);
1190  return 1;
1191  }
1192 
1193  fprintf (stderr, "LOG : Found %d devices\n", responses); // FIXME delete it after debugging stage
1194 
1195  if (responses == 0)
1196  {
1197  fprintf (stderr, "LOG : No devices discoverable\n");
1198  return 1;
1199  }
1200 
1201  for (i = 0; i < responses; i++)
1202  {
1203  int j;
1204  int found = 0;
1205 
1206  /* sanity check */
1207  if (i >= MAX_PORTS)
1208  {
1209  fprintf (stderr,
1210  "%.*s reached the top limit for the discoverable devices (after inquiry)\n",
1211  IFNAMSIZ,
1212  dev->iface);
1213  return 2;
1214  }
1215 
1216  /* Search if the address already exists on the list */
1217  for (j = 0; j < neighbours.size; j++)
1218  {
1219  if (memcmp (&(devices + i)->bdaddr, &(neighbours.devices[j]),
1220  sizeof(bdaddr_t)) == 0)
1221  {
1222  found = 1;
1223  fprintf (stderr, "LOG : the device already exists on the list\n"); // FIXME debugging message
1224  break;
1225  }
1226  }
1227 
1228  if (found == 0)
1229  {
1230  char addr[19] = { 0 };
1231 
1232  ba2str (&(devices + i)->bdaddr, addr);
1233  fprintf (stderr, "LOG : %s was added to the list\n", addr); // FIXME debugging message
1234  GNUNET_memcpy (&(neighbours.devices[neighbours.size++]), &(devices
1235  + i)->
1236  bdaddr, sizeof(bdaddr_t));
1237  }
1238  }
1239 
1240  free (devices);
1241  }
1242  }
1243 
1244  int connection_successful = 0;
1245  struct sockaddr_rc addr_rc = { 0 };
1246  int errno_copy = 0;
1247  addr_rc.rc_family = AF_BLUETOOTH;
1248 
1249  /* Try to connect to a new device from the list */
1250  while (neighbours.pos < neighbours.size)
1251  {
1252  /* Check if we are already connected to this device */
1253  if (neighbours.fds[neighbours.pos] == -1)
1254  {
1255  memset (&addr_rc.rc_bdaddr, 0, sizeof(addr_rc.rc_bdaddr));
1256  GNUNET_memcpy (&addr_rc.rc_bdaddr, &(neighbours.devices[neighbours.pos]),
1257  sizeof(addr_rc.rc_bdaddr));
1258 
1259  addr_rc.rc_channel = get_channel (dev, addr_rc.rc_bdaddr);
1260 
1261  *sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1262  if ((-1 < *sendsocket) &&
1263  (0 == connect (*sendsocket,
1264  (struct sockaddr *) &addr_rc,
1265  sizeof(addr_rc))))
1266  {
1267  neighbours.fds[neighbours.pos++] = *sendsocket;
1268  connection_successful = 1;
1269  char addr[19] = { 0 };
1270  ba2str (&(neighbours.devices[neighbours.pos - 1]), addr);
1271  fprintf (stderr, "LOG : Connected to %s\n", addr);
1272  break;
1273  }
1274  else
1275  {
1276  char addr[19] = { 0 };
1277  errno_copy = errno; // Save a copy for later
1278 
1279  if (-1 != *sendsocket)
1280  {
1281  (void) close (*sendsocket);
1282  *sendsocket = -1;
1283  }
1284  ba2str (&(neighbours.devices[neighbours.pos]), addr);
1285  fprintf (stderr,
1286  "LOG : Couldn't connect on device %s, error : %s\n",
1287  addr,
1288  strerror (errno));
1289  if (errno != ECONNREFUSED) // FIXME be sure that this works
1290  {
1291  fprintf (stderr, "LOG : Removes %d device from the list\n",
1292  neighbours.pos);
1293  /* Remove the device from the list */
1294  GNUNET_memcpy (&neighbours.devices[neighbours.pos],
1295  &neighbours.devices[neighbours.size - 1],
1296  sizeof(bdaddr_t));
1297  memset (&neighbours.devices[neighbours.size - 1], 0,
1298  sizeof(bdaddr_t));
1299  neighbours.fds[neighbours.pos] = neighbours.fds[neighbours.size - 1];
1300  neighbours.fds[neighbours.size - 1] = -1;
1301  neighbours.size -= 1;
1302  }
1303 
1304  neighbours.pos += 1;
1305 
1306  if (neighbours.pos >= neighbours.size)
1307  neighbours.pos = 0;
1308 
1309  loops += 1;
1310 
1311  if (loops == MAX_LOOPS) // don't get stuck trying to connect to one device
1312  return 1;
1313  }
1314  }
1315  else
1316  {
1317  fprintf (stderr, "LOG : Search for a new device\n"); // FIXME debugging message
1318  neighbours.pos += 1;
1319  }
1320  }
1321 
1322  /* Cycle on the list */
1323  if (neighbours.pos == neighbours.size)
1324  {
1325  neighbours.pos = 0;
1326  searching_devices_count += 1;
1327 
1328  if (searching_devices_count == MAX_LOOPS)
1329  {
1330  fprintf (stderr, "LOG : Force to inquiry for new devices\n");
1331  searching_devices_count = 0;
1332  goto inquiry_devices;
1333  }
1334  }
1335  /* If a new device wasn't found, search an old one */
1336  if (connection_successful == 0)
1337  {
1338  int loop_check = neighbours.pos;
1339  while (neighbours.fds[neighbours.pos] == -1)
1340  {
1341  if (neighbours.pos == neighbours.size)
1342  neighbours.pos = 0;
1343 
1344  if (neighbours.pos == loop_check)
1345  {
1346  if (errno_copy == ECONNREFUSED)
1347  {
1348  fprintf (stderr, "LOG : No device found. Go back and search again\n"); // FIXME debugging message
1349  new_device = 1;
1350  loops += 1;
1351  goto search_for_devices;
1352  }
1353  else
1354  {
1355  return 1; // Skip the broadcast message
1356  }
1357  }
1358 
1359  neighbours.pos += 1;
1360  }
1361 
1362  *sendsocket = neighbours.fds[neighbours.pos++];
1363  }
1364 
1365  return 0;
1366 }
1367 
1368 
1369 #endif
1370 
1382 int
1383 main (int argc, char *argv[])
1384 {
1385 #ifdef LINUX
1386  struct HardwareInfos dev;
1387  char readbuf[MAXLINE];
1388  int maxfd;
1389  fd_set rfds;
1390  fd_set wfds;
1391  int stdin_open;
1393  int raw_eno, i;
1394  int crt_rfds = 0, rfds_list[MAX_PORTS];
1395  int broadcast, sendsocket;
1396 
1397  /* Assert privs so we can modify the firewall rules! */
1398  {
1399 #ifdef HAVE_SETRESUID
1400  uid_t uid = getuid ();
1401 
1402  if (0 != setresuid (uid, 0, 0))
1403  {
1404  fprintf (stderr,
1405  "Failed to setresuid to root: %s\n",
1406  strerror (errno));
1407  return 254;
1408  }
1409 #else
1410  if (0 != seteuid (0))
1411  {
1412  fprintf (stderr,
1413  "Failed to seteuid back to root: %s\n", strerror (errno));
1414  return 254;
1415  }
1416 #endif
1417  }
1418 
1419  /* Make use of SGID capabilities on POSIX */
1420  memset (&dev, 0, sizeof(dev));
1421  dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1422  raw_eno = errno; /* remember for later */
1423 
1424  /* Now that we've dropped root rights, we can do error checking */
1425  if (2 != argc)
1426  {
1427  fprintf (stderr,
1428  "You must specify the name of the interface as the first \
1429  and only argument to this program.\n");
1430  if (-1 != dev.fd_rfcomm)
1431  (void) close (dev.fd_rfcomm);
1432  return 1;
1433  }
1434 
1435  if (-1 == dev.fd_rfcomm)
1436  {
1437  fprintf (stderr, "Failed to create a RFCOMM socket: %s\n", strerror (
1438  raw_eno));
1439  return 1;
1440  }
1441  if (dev.fd_rfcomm >= FD_SETSIZE)
1442  {
1443  fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1444  dev.fd_rfcomm, FD_SETSIZE);
1445  (void) close (dev.fd_rfcomm);
1446  return 1;
1447  }
1448  if (0 != test_bluetooth_interface (argv[1]))
1449  {
1450  (void) close (dev.fd_rfcomm);
1451  return 1;
1452  }
1453  strncpy (dev.iface, argv[1], IFNAMSIZ);
1454  if (0 != open_device (&dev))
1455  {
1456  (void) close (dev.fd_rfcomm);
1457  return 1;
1458  }
1459 
1460  /* Drop privs */
1461  {
1462  uid_t uid = getuid ();
1463  #ifdef HAVE_SETRESUID
1464  if (0 != setresuid (uid, uid, uid))
1465  {
1466  fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1467  if (-1 != dev.fd_rfcomm)
1468  (void) close (dev.fd_rfcomm);
1469  return 1;
1470  }
1471  #else
1472  if (0 != (setuid (uid) | seteuid (uid)))
1473  {
1474  fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
1475  if (-1 != dev.fd_rfcomm)
1476  (void) close (dev.fd_rfcomm);
1477  return 1;
1478  }
1479  #endif
1480  }
1481 
1482  /* Send MAC address of the bluetooth interface to STDOUT first */
1483  {
1485 
1486  macmsg.hdr.size = htons (sizeof(macmsg));
1488  GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof(struct
1490  GNUNET_memcpy (write_std.buf, &macmsg, sizeof(macmsg));
1491  write_std.size = sizeof(macmsg);
1492  }
1493 
1494 
1495  stdin_mst = mst_create (&stdin_send_hw, &dev);
1496  stdin_open = 1;
1497 
1502  while (1)
1503  {
1504  maxfd = -1;
1505  broadcast = 0;
1506  sendsocket = -1;
1507 
1508  FD_ZERO (&rfds);
1509  if ((0 == write_pout.size) && (1 == stdin_open))
1510  {
1511  FD_SET (STDIN_FILENO, &rfds);
1512  maxfd = MAX (maxfd, STDIN_FILENO);
1513  }
1514  if (0 == write_std.size)
1515  {
1516  FD_SET (dev.fd_rfcomm, &rfds);
1517  maxfd = MAX (maxfd, dev.fd_rfcomm);
1518  }
1519 
1520  for (i = 0; i < crt_rfds; i++) // it can receive messages from multiple devices
1521  {
1522  FD_SET (rfds_list[i], &rfds);
1523  maxfd = MAX (maxfd, rfds_list[i]);
1524  }
1525  FD_ZERO (&wfds);
1526  if (0 < write_std.size)
1527  {
1528  FD_SET (STDOUT_FILENO, &wfds);
1529  maxfd = MAX (maxfd, STDOUT_FILENO);
1530  }
1531  if (0 < write_pout.size) // it can send messages only to one device per loop
1532  {
1534  /* Get the destination address */
1536 
1537  if (memcmp (&frame->addr1, &dev.pl_mac,
1538  sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1539  {
1540  broadcast = 1;
1541  memset (&write_pout, 0, sizeof(write_pout)); // clear the buffer
1542  }
1543  else if (memcmp (&frame->addr1, &broadcast_address,
1544  sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1545  {
1546  fprintf (stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n",
1547  dev.iface, neighbours.pos, neighbours.size); // FIXME: debugging message
1548 
1549  if (send_broadcast (&dev, &sendsocket) != 0) // if the searching wasn't successful don't get stuck on the select stage
1550  {
1551  broadcast = 1;
1552  memset (&write_pout, 0, sizeof(write_pout)); // remove the message
1553  fprintf (stderr,
1554  "LOG : Skipping the broadcast message (pos %d, size %d)\n",
1555  neighbours.pos, neighbours.size);
1556  }
1557  else
1558  {
1559  FD_SET (sendsocket, &wfds);
1560  maxfd = MAX (maxfd, sendsocket);
1561  }
1562  }
1563  else
1564  {
1565  int found = 0;
1566  int pos = 0;
1567  /* Search if the address already exists on the list */
1568  for (i = 0; i < neighbours.size; i++)
1569  {
1570  if (memcmp (&frame->addr1, &(neighbours.devices[i]),
1571  sizeof(bdaddr_t)) == 0)
1572  {
1573  pos = i;
1574  if (neighbours.fds[i] != -1)
1575  {
1576  found = 1; // save the position where it was found
1577  FD_SET (neighbours.fds[i], &wfds);
1578  maxfd = MAX (maxfd, neighbours.fds[i]);
1579  sendsocket = neighbours.fds[i];
1580  fprintf (stderr, "LOG: the address was found in the list\n");
1581  break;
1582  }
1583  }
1584  }
1585  if (found == 0)
1586  {
1587  int status;
1588  struct sockaddr_rc addr = { 0 };
1589 
1590  fprintf (stderr,
1591  "LOG : %s has a new message for %.2X:%.2X:%.2X:%.2X:%.2X:%.2X which isn't on the broadcast list\n",
1592  dev.iface,
1593  frame->addr1.mac[5], frame->addr1.mac[4],
1594  frame->addr1.mac[3],
1595  frame->addr1.mac[2], frame->addr1.mac[1],
1596  frame->addr1.mac[0]); // FIXME: debugging message
1597 
1598  sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1599 
1600  if (sendsocket < 0)
1601  {
1602  fprintf (stderr,
1603  "Failed to create a RFCOMM socket (sending stage): %s\n",
1604  strerror (errno));
1605  return -1;
1606  }
1607 
1608  GNUNET_memcpy (&addr.rc_bdaddr, &frame->addr1, sizeof(bdaddr_t));
1609  addr.rc_family = AF_BLUETOOTH;
1610  addr.rc_channel = get_channel (&dev, addr.rc_bdaddr);
1611 
1612  int tries = 0;
1613 connect_retry:
1614  status = connect (sendsocket, (struct sockaddr *) &addr,
1615  sizeof(addr));
1616  if ((0 != status) && (errno != EAGAIN) )
1617  {
1618  if ((errno == ECONNREFUSED) && (tries < 2) )
1619  {
1620  fprintf (stderr, "LOG : %.*s failed to connect. Trying again!\n",
1621  IFNAMSIZ, dev.iface);
1622  tries++;
1623  goto connect_retry;
1624  }
1625  else if (errno == EBADF)
1626  {
1627  fprintf (stderr, "LOG : %s failed to connect : %s. Skip it!\n",
1628  dev.iface, strerror (errno));
1629  memset (&write_pout, 0, sizeof(write_pout));
1630  broadcast = 1;
1631  }
1632  else
1633  {
1634  fprintf (stderr,
1635  "LOG : %s failed to connect : %s. Try again later!\n",
1636  dev.iface,
1637  strerror (errno));
1638  memset (&write_pout, 0, sizeof(write_pout));
1639  broadcast = 1;
1640  }
1641  }
1642  else
1643  {
1644  FD_SET (sendsocket, &wfds);
1645  maxfd = MAX (maxfd, sendsocket);
1646  fprintf (stderr, "LOG : Connection successful\n");
1647  if (pos != 0) // save the socket
1648  {
1649  neighbours.fds[pos] = sendsocket;
1650  }
1651  else
1652  {
1653  /* Add the new device to the discovered devices list */
1654  if (neighbours.size < MAX_PORTS)
1655  {
1656  neighbours.fds[neighbours.size] = sendsocket;
1657  GNUNET_memcpy (&(neighbours.devices[neighbours.size++]),
1658  &addr.rc_bdaddr, sizeof(bdaddr_t));
1659  }
1660  else
1661  {
1662  fprintf (stderr,
1663  "The top limit for the discovarable devices' list was reached\n");
1664  }
1665  }
1666  }
1667  }
1668  }
1669  }
1670 
1671  if (broadcast == 0)
1672  {
1673  /* Select a fd which is ready for action :) */
1674  {
1675  int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
1676  if ((-1 == retval) && (EINTR == errno))
1677  continue;
1678  if ((0 > retval) && (errno != EBADF) ) // we handle BADF errors later
1679  {
1680  fprintf (stderr, "select failed: %s\n", strerror (errno));
1681  break;
1682  }
1683  }
1684  if (FD_ISSET (STDOUT_FILENO, &wfds))
1685  {
1686  ssize_t ret =
1687  write (STDOUT_FILENO, write_std.buf + write_std.pos,
1689  if (0 > ret)
1690  {
1691  fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1692  break;
1693  }
1694  write_std.pos += ret;
1695  if (write_std.pos == write_std.size)
1696  {
1697  write_std.pos = 0;
1698  write_std.size = 0;
1699  }
1700  fprintf (stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); // FIXME: debugging message
1701  }
1702  if (-1 != sendsocket)
1703  {
1704  if (FD_ISSET (sendsocket, &wfds))
1705  {
1706  ssize_t ret = write (sendsocket,
1709  if (0 > ret) // FIXME should I first check the error type?
1710  {
1711  fprintf (stderr,
1712  "Failed to write to bluetooth device: %s. Closing the socket!\n",
1713  strerror (errno));
1714  for (i = 0; i < neighbours.size; i++)
1715  {
1716  if (neighbours.fds[i] == sendsocket)
1717  {
1718  (void) close (sendsocket);
1719  neighbours.fds[i] = -1;
1720  break;
1721  }
1722  }
1723  /* Remove the message */
1724  memset (&write_pout.buf + write_std.pos, 0, (write_pout.size
1725  - write_pout.pos));
1726  write_pout.pos = 0;
1727  write_pout.size = 0;
1728  }
1729  else
1730  {
1731  write_pout.pos += ret;
1732  if ((write_pout.pos != write_pout.size) && (0 != ret))
1733  {
1734  /* We should not get partial sends with packet-oriented devices... */
1735  fprintf (stderr, "Write error, partial send: %u/%u\n",
1736  (unsigned int) write_pout.pos,
1737  (unsigned int) write_pout.size);
1738  break;
1739  }
1740 
1741  if (write_pout.pos == write_pout.size)
1742  {
1743  write_pout.pos = 0;
1744  write_pout.size = 0;
1745  }
1746  fprintf (stderr, "LOG : %s sends a message to a DEVICE\n",
1747  dev.iface); // FIXME: debugging message
1748  }
1749  }
1750  }
1751  for (i = 0; i <= maxfd; i++)
1752  {
1753  if (FD_ISSET (i, &rfds))
1754  {
1755  if (i == STDIN_FILENO)
1756  {
1757  ssize_t ret =
1758  read (i, readbuf, sizeof(readbuf));
1759  if (0 > ret)
1760  {
1761  fprintf (stderr,
1762  "Read error from STDIN: %s\n",
1763  strerror (errno));
1764  break;
1765  }
1766  if (0 == ret)
1767  {
1768  /* stop reading... */
1769  stdin_open = 0;
1770  }
1771  else
1772  {
1773  mst_receive (stdin_mst, readbuf, ret);
1774  fprintf (stderr, "LOG : %s receives a message from STDIN\n",
1775  dev.iface); // FIXME: debugging message
1776  }
1777  }
1778  else if (i == dev.fd_rfcomm)
1779  {
1780  int readsocket;
1781  struct sockaddr_rc addr = { 0 };
1782  unsigned int opt = sizeof(addr);
1783 
1784  readsocket = accept (dev.fd_rfcomm, (struct sockaddr *) &addr,
1785  &opt);
1786  fprintf (stderr, "LOG : %s accepts a message\n", dev.iface); // FIXME: debugging message
1787  if (readsocket == -1)
1788  {
1789  fprintf (stderr,
1790  "Failed to accept a connection on interface: %.*s\n",
1791  IFNAMSIZ,
1792  strerror (errno));
1793  break;
1794  }
1795  else
1796  {
1797  FD_SET (readsocket, &rfds);
1798  maxfd = MAX (maxfd, readsocket);
1799 
1800  if (crt_rfds < MAX_PORTS)
1801  rfds_list[crt_rfds++] = readsocket;
1802  else
1803  {
1804  fprintf (stderr,
1805  "The limit for the read file descriptors list was \
1806  reached\n");
1807  break;
1808  }
1809  }
1810  }
1811  else
1812  {
1814  ssize_t ret;
1815  fprintf (stderr, "LOG : %s reads something from the socket\n",
1816  dev.iface); // FIXME : debugging message
1817  rrm = (struct
1819  ret =
1820  read_from_the_socket ((void *) &i, (unsigned char *) &rrm->frame,
1821  sizeof(write_std.buf)
1822  - sizeof(struct
1824  + sizeof(struct
1826  rrm);
1827  if (0 >= ret)
1828  {
1829  int j;
1830  FD_CLR (i, &rfds);
1831  close (i);
1832  /* Remove the socket from the list */
1833  for (j = 0; j < crt_rfds; j++)
1834  {
1835  if (rfds_list[j] == i)
1836  {
1837  rfds_list[j] ^= rfds_list[crt_rfds - 1];
1838  rfds_list[crt_rfds - 1] ^= rfds_list[j];
1839  rfds_list[j] ^= rfds_list[crt_rfds - 1];
1840  crt_rfds -= 1;
1841  break;
1842  }
1843  }
1844 
1845  fprintf (stderr, "Read error from raw socket: %s\n", strerror (
1846  errno));
1847  break;
1848  }
1849  if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
1850  {
1851  write_std.size = ret
1852  + sizeof(struct
1854  - sizeof(struct
1856  rrm->header.size = htons (write_std.size);
1857  rrm->header.type = htons (
1859  }
1860  }
1861  }
1862  }
1863  }
1864  }
1865  /* Error handling, try to clean up a bit at least */
1866  mst_destroy (stdin_mst);
1867  stdin_mst = NULL;
1868  sdp_close (dev.session);
1869  (void) close (dev.fd_rfcomm);
1870  if (-1 != sendsocket)
1871  (void) close (sendsocket);
1872 
1873  for (i = 0; i < crt_rfds; i++)
1874  (void) close (rfds_list[i]);
1875 
1876  for (i = 0; i < neighbours.size; i++)
1877  (void) close (neighbours.fds[i]);
1878  #else
1879  struct HardwareInfos dev;
1880  struct GNUNET_NETWORK_Handle *sendsocket;
1881  struct GNUNET_NETWORK_FDSet *rfds;
1882  struct GNUNET_NETWORK_FDSet *wfds;
1883  struct GNUNET_NETWORK_Handle *rfds_list[MAX_PORTS];
1884  char readbuf[MAXLINE] = { 0 };
1885  SOCKADDR_BTH acc_addr = { 0 };
1886  int addr_len = sizeof(SOCKADDR_BTH);
1887  int broadcast, i, stdin_open, crt_rfds = 0;
1888  HANDLE stdin_handle = GetStdHandle (STD_INPUT_HANDLE);
1889  HANDLE stdout_handle = GetStdHandle (STD_OUTPUT_HANDLE);
1891 
1892  /* check the handles */
1893  if (stdin_handle == INVALID_HANDLE_VALUE)
1894  {
1895  fprintf (stderr, "Failed to get the stdin handle\n");
1896  ExitProcess (2);
1897  }
1898 
1899  if (stdout_handle == INVALID_HANDLE_VALUE)
1900  {
1901  fprintf (stderr, "Failed to get the stdout handle\n");
1902  ExitProcess (2);
1903  }
1904 
1905  /* initialize windows sockets */
1906  initialize_windows_sockets ();
1907 
1908  // /* test bluetooth socket family support */ --> it return false because the GNUNET_NETWORK_test_pf should also receive the type of socket (BTHPROTO_RFCOMM)
1909  // if (GNUNET_NETWORK_test_pf (AF_BTH) != GNUNET_OK)
1910  // {
1911  // fprintf (stderr, "AF_BTH family is not supported\n");
1912  // ExitProcess (2);
1913  // }
1914 
1915  /* create the socket */
1916  dev.handle = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM,
1917  BTHPROTO_RFCOMM);
1918  if (dev.handle == NULL)
1919  {
1920  fprintf (stderr, "Failed to create RFCOMM socket: ");
1921  print_last_error ();
1922  ExitProcess (2);
1923  }
1924 
1925 
1926  if (open_device (&dev) == -1)
1927  {
1928  fprintf (stderr, "Failed to open the device\n");
1929  print_last_error ();
1930  if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
1931  {
1932  fprintf (stderr, "Failed to close the socket!\n");
1933  print_last_error ();
1934  }
1935  ExitProcess (2);
1936  }
1937 
1938  if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (dev.handle, 1))
1939  {
1940  fprintf (stderr, "Failed to change the socket mode\n");
1941  ExitProcess (2);
1942  }
1943 
1944  memset (&write_std, 0, sizeof(write_std));
1945  memset (&write_pout, 0, sizeof(write_pout));
1946  stdin_open = 1;
1947 
1948  rfds = GNUNET_NETWORK_fdset_create ();
1949  wfds = GNUNET_NETWORK_fdset_create ();
1950 
1951  /* Send MAC address of the bluetooth interface to STDOUT first */
1952  {
1954 
1955  macmsg.hdr.size = htons (sizeof(macmsg));
1957  GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof(struct
1958  GNUNET_TRANSPORT_WLAN_MacAddress_Copy));
1959  GNUNET_memcpy (write_std.buf, &macmsg, sizeof(macmsg));
1960  write_std.size = sizeof(macmsg);
1961  }
1962 
1963 
1964  stdin_mst = mst_create (&stdin_send_hw, &dev);
1965  stdin_open = 1;
1966 
1967  int pos = 0;
1968  int stdin_pos = -1;
1969  int stdout_pos = -1;
1970  while (1)
1971  {
1972  broadcast = 0;
1973  pos = 0;
1974  stdin_pos = -1;
1975  stdout_pos = -1;
1976  sendsocket = NULL; // FIXME ???memleaks
1977 
1979  if ((0 == write_pout.size) && (1 == stdin_open))
1980  {
1981  stdin_pos = pos;
1982  pos += 1;
1983  GNUNET_NETWORK_fdset_handle_set (rfds, (struct
1985  stdin_handle);
1986  }
1987 
1988  if (0 == write_std.size)
1989  {
1990  pos += 1;
1991  GNUNET_NETWORK_fdset_set (rfds, dev.handle);
1992  }
1993 
1994  for (i = 0; i < crt_rfds; i++)
1995  {
1996  pos += 1;
1997  GNUNET_NETWORK_fdset_set (rfds, rfds_list[i]);
1998  }
1999 
2001  if (0 < write_std.size)
2002  {
2003  stdout_pos = pos;
2004  GNUNET_NETWORK_fdset_handle_set (wfds, (struct
2006  stdout_handle);
2007  // printf ("%s\n", write_std.buf);
2008  // memset (write_std.buf, 0, write_std.size);
2009  // write_std.size = 0;
2010  }
2011 
2012  if (0 < write_pout.size)
2013  {
2014  if (strcmp (argv[1], "ff:ff:ff:ff:ff:ff") == 0)
2015  {
2016  fprintf (stderr, "LOG: BROADCAST! Skipping the message\n");
2017  // skip the message
2018  broadcast = 1;
2019  memset (write_pout.buf, 0, write_pout.size);
2020  write_pout.size = 0;
2021  }
2022  else
2023  {
2024  SOCKADDR_BTH addr;
2025  fprintf (stderr, "LOG : has a new message for %s\n", argv[1]);
2026  sendsocket = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM,
2027  BTHPROTO_RFCOMM);
2028 
2029  if (sendsocket == NULL)
2030  {
2031  fprintf (stderr, "Failed to create RFCOMM socket: \n");
2032  print_last_error ();
2033  ExitProcess (2);
2034  }
2035 
2036  memset (&addr, 0, sizeof(addr));
2037  // addr.addressFamily = AF_BTH;
2038  if (SOCKET_ERROR ==
2039  WSAStringToAddress (argv[1], AF_BTH, NULL, (LPSOCKADDR) &addr,
2040  &addr_len))
2041  {
2042  fprintf (stderr, "Failed to translate the address: ");
2043  print_last_error ();
2044  ExitProcess (2);
2045  }
2046  addr.port = get_channel (argv[1]);
2047  if (addr.port == -1)
2048  {
2049  fprintf (stderr,
2050  "Couldn't find the sdp service for the address: %s\n",
2051  argv[1]);
2052  memset (write_pout.buf, 0, write_pout.size);
2053  write_pout.size = 0;
2054  broadcast = 1; // skipping the select part
2055  }
2056  else
2057  {
2058  if (GNUNET_OK != GNUNET_NETWORK_socket_connect (sendsocket,
2059  (LPSOCKADDR) &addr,
2060  addr_len))
2061  {
2062  fprintf (stderr, "Failed to connect: ");
2063  print_last_error ();
2064  ExitProcess (2);
2065  }
2066 
2067  if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (sendsocket, 1))
2068  {
2069  fprintf (stderr, "Failed to change the socket mode\n");
2070  ExitProcess (2);
2071  }
2072 
2073  GNUNET_NETWORK_fdset_set (wfds, sendsocket);
2074  }
2075  }
2076  }
2077 
2078  if (broadcast == 0)
2079  {
2080  int retval = GNUNET_NETWORK_socket_select (rfds, wfds, NULL,
2082  if (retval < 0)
2083  {
2084  fprintf (stderr, "Select error\n");
2085  ExitProcess (2);
2086  }
2087  // if (GNUNET_NETWORK_fdset_isset (wfds, (struct GNUNET_NETWORK_Handle*)&stdout_handle))
2088  if (retval == stdout_pos)
2089  {
2090  fprintf (stderr, "LOG : sends a message to STDOUT\n"); // FIXME: debugging message
2091  // ssize_t ret;
2092  // ret = GNUNET_NETWORK_socket_send ((struct GNUNET_NETWORK_Handle *)&stdout_handle, write_std.buf + write_std.pos, write_std.size - write_std.pos);
2093  // ret = write (STDOUT_FILENO, write_std.buf + write_std.pos, write_std.size - write_std.pos);
2094  DWORD ret;
2095  if (FALSE == WriteFile (stdout_handle, write_std.buf + write_std.pos,
2096  write_std.size - write_std.pos, &ret, NULL))
2097  {
2098  fprintf (stderr, "Failed to write to STDOUT: ");
2099  print_last_error ();
2100  break;
2101  }
2102 
2103  if (ret <= 0)
2104  {
2105  fprintf (stderr, "Failed to write to STDOUT\n");
2106  ExitProcess (2);
2107  }
2108 
2109  write_std.pos += ret;
2110  if (write_std.pos == write_std.size)
2111  {
2112  write_std.pos = 0;
2113  write_std.size = 0;
2114  }
2115  }
2116  if (sendsocket != NULL)
2117  {
2118  if (GNUNET_NETWORK_fdset_isset (wfds, sendsocket))
2119  {
2120  ssize_t ret;
2121  ret = GNUNET_NETWORK_socket_send (sendsocket, write_pout.buf
2122  + write_pout.pos,
2124 
2125  if (GNUNET_SYSERR == ret)
2126  {
2127  fprintf (stderr,
2128  "Failed to send to the socket. Closing the socket. Error: \n");
2129  print_last_error ();
2130  if (GNUNET_NETWORK_socket_close (sendsocket) != GNUNET_OK)
2131  {
2132  fprintf (stderr, "Failed to close the sendsocket!\n");
2133  print_last_error ();
2134  }
2135  ExitProcess (2);
2136  }
2137  else
2138  {
2139  write_pout.pos += ret;
2140  if ((write_pout.pos != write_pout.size) && (0 != ret))
2141  {
2142  /* we should not get partial sends with packet-oriented devices... */
2143  fprintf (stderr, "Write error, partial send: %u/%u\n",
2144  (unsigned int) write_pout.pos,
2145  (unsigned int) write_pout.size);
2146  break;
2147  }
2148 
2149  if (write_pout.pos == write_pout.size)
2150  {
2151  write_pout.pos = 0;
2152  write_pout.size = 0;
2153  }
2154  fprintf (stderr, "LOG : sends a message to a DEVICE\n"); // FIXME: debugging message
2155  }
2156  }
2157  }
2158 
2159  // if (GNUNET_NETWORK_fdset_isset (rfds, (struct GNUNET_NETWORK_Handle*)&stdin_handle))
2160  if (retval == stdin_pos)
2161  {
2162  // ssize_t ret;
2163  // ret = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)&stdin_handle, readbuf, sizeof (write_pout.buf));
2164  // ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
2165  DWORD ret;
2166  if (FALSE == ReadFile (stdin_handle, readbuf, sizeof(readbuf), &ret,
2167  NULL)) /* do nothing asynchronous */
2168  {
2169  fprintf (stderr, "Read error from STDIN: ");
2170  print_last_error ();
2171  break;
2172  }
2173  if (0 == ret)
2174  {
2175  /* stop reading... */
2176  stdin_open = 0;
2177  }
2178  else
2179  {
2180  mst_receive (stdin_mst, readbuf, ret);
2181  fprintf (stderr, "LOG : receives a message from STDIN\n"); // FIXME: debugging message
2182  }
2183  }
2184  else if (GNUNET_NETWORK_fdset_isset (rfds, dev.handle))
2185  {
2186  fprintf (stderr, "LOG: accepting connection\n");
2187  struct GNUNET_NETWORK_Handle *readsocket;
2188  readsocket = GNUNET_NETWORK_socket_accept (dev.handle,
2189  (LPSOCKADDR) &acc_addr,
2190  &addr_len);
2191  if (readsocket == NULL)
2192  {
2193  fprintf (stderr, "Accept error %d: ", GetLastError ());
2194  print_last_error ();
2195  ExitProcess (2);
2196  }
2197  else
2198  {
2199  if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (readsocket, 1))
2200  {
2201  fprintf (stderr, "Failed to change the socket mode\n");
2202  ExitProcess (2);
2203  }
2204  GNUNET_NETWORK_fdset_set (rfds, readsocket);
2205 
2206  if (crt_rfds < MAX_PORTS)
2207  rfds_list[crt_rfds++] = readsocket;
2208  else
2209  {
2210  fprintf (stderr,
2211  "The limit for the read file descriptors list was reached\n");
2212  break;
2213  }
2214  }
2215  }
2216  else
2217  for (i = 0; i < crt_rfds; i++)
2218  {
2219  if (GNUNET_NETWORK_fdset_isset (rfds, rfds_list[i]))
2220  {
2222  ssize_t ret;
2223  fprintf (stderr, "LOG: reading something from the socket\n"); // FIXME : debugging message
2224  rrm = (struct
2226  ret = read_from_the_socket (rfds_list[i], (unsigned
2227  char *) &rrm->frame,
2228  sizeof(write_std.buf)
2229  - sizeof(struct
2231  + sizeof(struct
2233  rrm);
2234  if (0 >= ret)
2235  {
2236  // TODO remove the socket from the list
2237  if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2238  {
2239  fprintf (stderr, "Failed to close the sendsocket!\n");
2240  print_last_error ();
2241  }
2242 
2243  fprintf (stderr, "Read error from raw socket: ");
2244  print_last_error ();
2245  break;
2246  }
2247  if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2248  {
2249  write_std.size = ret
2250  + sizeof(struct
2252  - sizeof(struct
2254  rrm->header.size = htons (write_std.size);
2255  rrm->header.type = htons (
2257  }
2258  break;
2259  }
2260  }
2261  }
2262  }
2263 
2264  mst_destroy (stdin_mst);
2265  stdin_mst = NULL;
2266 
2267  if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
2268  {
2269  fprintf (stderr, "Failed to close the socket!\n");
2270  print_last_error ();
2271  }
2272 
2273  for (i = 0; i < crt_rfds; i++)
2274  {
2275  if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2276  {
2277  fprintf (stderr, "Failed to close the socket!\n");
2278  print_last_error ();
2279  }
2280  }
2281 
2282  WSACleanup ();
2283  #endif
2284  return 1; /* we never exit 'normally' */
2285 }
static int check_crc_buf_osdep(const unsigned char *buf, size_t len)
Calculate and check crc of the bluetooth packet.
#define GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL
Control message between the gnunet-wlan-helper and the daemon (with the MAC).
int GNUNET_NETWORK_socket_set_blocking(struct GNUNET_NETWORK_Handle *fd, int doBlock)
Set if a socket should use blocking or non-blocking IO.
Definition: network.c:255
IO buffer used for buffering data in transit (to wireless or to stdout).
#define MAC_ADDR_SIZE
Number fo bytes in a mac address.
size_t off
How many bytes in buffer have we already processed?
static struct GNUNET_VPN_RedirectionRequest * request
Opaque redirection request handle.
Definition: gnunet-vpn.c:41
static struct SendBuffer write_pout
Buffer for data read from stdin to be transmitted to the bluetooth device.
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:35
ssize_t GNUNET_NETWORK_socket_send(const struct GNUNET_NETWORK_Handle *desc, const void *buffer, size_t length)
Send data (always non-blocking).
Definition: network.c:816
struct GNUNET_MessageHeader hdr
Message header.
struct for storing the information of the hardware.
static size_t do_align(size_t start_position, size_t end_position)
Given the start and end position of a block of data, return the end position of that data after align...
Definition: fs_directory.c:487
static struct SendBuffer write_std
Buffer for data read from the bluetooth device to be transmitted to stdout.
int fd_rfcomm
file descriptor for the rfcomm socket
struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac
MAC address of our own bluetooth interface.
#define MAX_LOOPS
Maximum number of loops without inquiring for new devices.
struct GNUNET_MessageHeader header
Type is &#39;GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER&#39;.
#define GNUNET_memcpy(dst, src, n)
Call memcpy() but check for n being 0 first.
struct GNUNET_MessageStreamTokenizer * stdin_mst
Tokenizer for the data we get from stdin.
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
#define GNUNET_NO
Definition: gnunet_common.h:78
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:75
#define MAXLINE
Maximum size of a message allowed in either direction (used for our receive and sent buffers)...
#define MIN_BUFFER_SIZE
Smallest supported message.
static int open_device(struct HardwareInfos *dev)
Open the bluetooth interface for reading/writing.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format...
static struct MessageStreamTokenizer * mst_create(MessageTokenizerCallback cb, void *cb_cls)
Create a message stream tokenizer.
#define IEEE80211_FC0_TYPE_DATA
sdp_session_t * session
SDP session.
size_t pos
How many bytes in buffer are valid right now?
int main(int argc, char *argv[])
Main function of the helper.
static void mac_set(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader, const struct HardwareInfos *dev)
Set the header to sane values to make attacks more difficult.
Format of a WLAN Control Message.
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_accept(const struct GNUNET_NETWORK_Handle *desc, struct sockaddr *address, socklen_t *address_len)
Accept a new connection on a socket.
Definition: network.c:430
Message from the WLAN helper to the plugin: we have received the given message with the given perform...
struct GNUNET_TRANSPORT_WLAN_MacAddress mac
MAC Address of the local WLAN interface.
struct GNUNET_NETWORK_FDSet * GNUNET_NETWORK_fdset_create(void)
Creates an fd set.
Definition: network.c:1250
int GNUNET_NETWORK_socket_connect(const struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Connect a socket to some remote address.
Definition: network.c:658
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
size_t size
How many bytes of data are stored in &#39;buf&#39; for transmission right now? Data always starts at offset 0...
static ssize_t read_from_the_socket(void *sock, unsigned char *buf, size_t buf_size, struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri)
Read from the socket and put the result into the buffer for transmission to &#39;stdout&#39;.
struct GNUNET_TIME_Relative GNUNET_TIME_relative_get_forever_(void)
Return "forever".
Definition: time.c:219
#define BLUEZ_DEVNAME_SIZE
In bluez library, the maximum name length of a device is 8.
#define GNUNET_MIN(a, b)
Definition: gnunet_common.h:80
collection of IO descriptors
uint16_t status
See PRISM_STATUS_*-constants.
static char buf[2048]
struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame frame
IEEE Frame.
static GNUNET_NETWORK_STRUCT_END const struct GNUNET_TRANSPORT_WLAN_MacAddress mac_bssid_gnunet
GNUnet bssid.
struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame frame
IEEE Frame to transmit (the sender MAC address will be overwritten by the helper as it does not trust...
#define GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER
Type of data messages from the plugin to the gnunet-wlan-helper.
int GNUNET_NETWORK_socket_select(struct GNUNET_NETWORK_FDSet *rfds, struct GNUNET_NETWORK_FDSet *wfds, struct GNUNET_NETWORK_FDSet *efds, struct GNUNET_TIME_Relative timeout)
Check if sockets meet certain conditions.
Definition: network.c:1340
uint16_t frame_control
802.11 Frame Control field.
#define GNUNET_SYSERR
Definition: gnunet_common.h:76
static unsigned int size
Size of the "table".
Definition: peer.c:67
static unsigned long calc_crc_osdep(const unsigned char *buf, size_t len)
Calculate crc32, the start of the calculation.
MessageTokenizerCallback cb
Function to call on completed messages.
struct GNUNET_MessageHeader header
Type is &#39;GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER&#39;.
void GNUNET_NETWORK_fdset_zero(struct GNUNET_NETWORK_FDSet *fds)
Reset FD set (clears all file descriptors).
Definition: network.c:997
void GNUNET_NETWORK_fdset_handle_set(struct GNUNET_NETWORK_FDSet *fds, const struct GNUNET_DISK_FileHandle *h)
Add a file handle to the fd set.
Definition: network.c:1171
void GNUNET_NETWORK_fdset_set(struct GNUNET_NETWORK_FDSet *fds, const struct GNUNET_NETWORK_Handle *desc)
Add a socket to the FD set.
Definition: network.c:1011
char buf[4096 *2]
Buffered data; twice the maximum allowed message size as we add some headers.
void(* MessageTokenizerCallback)(void *cls, const struct GNUNET_MessageHeader *message)
Functions with this signature are called whenever a complete message is received by the tokenizer...
Handle to a message stream tokenizer.
static int mst_receive(struct MessageStreamTokenizer *mst, const char *buf, size_t size)
Add incoming data to the receive buffer and call the callback for all complete messages.
uint32_t ri_channel
IEEE80211_RADIOTAP_CHANNEL, 0 if unknown.
static uint16_t port
Port number.
Definition: gnunet-bcd.c:81
generic definitions for IEEE 802.11 frames
size_t curr_buf
Size of the buffer (starting at &#39;hdr&#39;).
struct GNUNET_MessageHeader * hdr
Beginning of the buffer.
header for transport plugin and the helper for wlan
static int register_service(struct HardwareInfos *dev, int rc_channel)
Function used for creating the service record and registering it.
static void stdin_send_hw(void *cls, const struct GNUNET_MessageHeader *hdr)
Process data from the stdin.
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
handle to a socket
Definition: network.c:52
char iface[IFNAMSIZ]
Name of the interface, not necessarily 0-terminated (!).
Header for all communications.
#define GNUNET_YES
Definition: gnunet_common.h:77
struct GNUNET_TRANSPORT_WLAN_MacAddress addr3
Address 3: BSSID in ad-hoc mode, Destination if station, source if AP.
#define GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER
Type of data messages from the gnunet-wlan-helper to the plugin.
static const struct GNUNET_TRANSPORT_WLAN_MacAddress bc_all_mac
Broadcast MAC.
static int get_channel(struct HardwareInfos *dev, bdaddr_t dest)
Function used for searching and browsing for a service.
#define MAX_PORTS
Maximum number of ports assignable for RFCOMMM protocol.
int GNUNET_NETWORK_fdset_isset(const struct GNUNET_NETWORK_FDSet *fds, const struct GNUNET_NETWORK_Handle *desc)
Check whether a socket is part of the fd set.
Definition: network.c:1029
static int mac_test(const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader, const struct HardwareInfos *dev)
Test incoming packets mac for being our own.
Message from the plugin to the WLAN helper: send the given message with the given connection paramete...
Handle used to access files (and pipes).
size_t pos
How many bytes that were stored in &#39;buf&#39; did we already write to the destination? Always smaller than...
struct GNUNET_TRANSPORT_WLAN_MacAddress addr2
Address 2: source address if in ad-hoc-mode or station, BSSID if AP.
#define ALIGN_FACTOR
To what multiple do we align messages? 8 byte should suffice for everyone for now.
int GNUNET_NETWORK_socket_close(struct GNUNET_NETWORK_Handle *desc)
Close a socket.
Definition: network.c:560
struct GNUNET_TRANSPORT_WLAN_MacAddress addr1
Address 1: destination address in ad-hoc mode or AP, BSSID if station,.
static void mst_destroy(struct MessageStreamTokenizer *mst)
Destroys a tokenizer.
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...
struct GNUNET_NETWORK_Handle * GNUNET_NETWORK_socket_create(int domain, int type, int protocol)
Create a new socket.
Definition: network.c:912