GNUnet  0.10.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 #define SOCKTYPE int
25 #include <bluetooth/bluetooth.h>
26 #include <bluetooth/hci.h>
27 #include <bluetooth/hci_lib.h>
28 #include <bluetooth/rfcomm.h>
29 #include <bluetooth/sdp.h>
30 #include <bluetooth/sdp_lib.h>
31 #include <errno.h>
32 #include <linux/if.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <sys/ioctl.h>
36 #include <sys/param.h>
37 #include <sys/socket.h>
38 #include <sys/stat.h>
39 #include <sys/types.h>
40 #include <unistd.h>
41 
42 #include "plugin_transport_wlan.h"
43 #include "gnunet_protocols.h"
44 
45 
49 #define MAX_PORTS 30
50 
55 #define MAXLINE 4096
56 
57 
61 #define MAX_LOOPS 5
62 
66 #define BLUEZ_DEVNAME_SIZE 8
67 
72 struct HardwareInfos {
76  char iface[IFNAMSIZ];
77 
81  int fd_rfcomm;
82 
87 
91  sdp_session_t *session;
92 };
93 
97 struct SendBuffer {
102  size_t size;
103 
108  size_t pos;
109 
114  char buf[MAXLINE * 2];
115 };
116 
117 #ifdef LINUX
118 
122 struct BroadcastMessages {
123  /* List with the discoverable devices' addresses */
124  bdaddr_t devices[MAX_PORTS];
125 
126  /* List with the open sockets */
127  int fds[MAX_PORTS];
128 
129 
130  /* The number of the devices */
131  int size;
132 
133  /* The current position */
134  int pos;
135 
136  /* The device id */
137  int dev_id;
138 };
139 
143 static struct GNUNET_TRANSPORT_WLAN_MacAddress broadcast_address = { { 255, 255, 255, 255, 255, 255 } };
144 
148 static struct BroadcastMessages neighbours;
149 
150 static int searching_devices_count = 0;
151 #endif
152 
156 static struct SendBuffer write_pout;
157 
161 static struct SendBuffer write_std;
162 
163 
164 /* ****** this are the same functions as the ones used in gnunet-helper-transport-wlan.c ****** */
165 
170 #define ALIGN_FACTOR 8
171 
175 #define MIN_BUFFER_SIZE sizeof(struct GNUNET_MessageHeader)
176 
177 
185 typedef void (*MessageTokenizerCallback) (void *cls,
186  const struct
188  message);
189 
198 
202  void *cb_cls;
203 
207  size_t curr_buf;
208 
212  size_t off;
213 
217  size_t pos;
218 
223 };
224 
225 
233 static struct MessageStreamTokenizer *
235  void *cb_cls)
236 {
237  struct MessageStreamTokenizer *ret;
238 
239  ret = malloc(sizeof(struct MessageStreamTokenizer));
240  if (NULL == ret)
241  {
242  fprintf(stderr, "Failed to allocate buffer for tokenizer\n");
243  exit(1);
244  }
245  ret->hdr = malloc(MIN_BUFFER_SIZE);
246  if (NULL == ret->hdr)
247  {
248  fprintf(stderr, "Failed to allocate buffer for alignment\n");
249  exit(1);
250  }
251  ret->curr_buf = MIN_BUFFER_SIZE;
252  ret->cb = cb;
253  ret->cb_cls = cb_cls;
254  ret->pos = 0;
255 
256  return ret;
257 }
258 
259 
270 static int
272  const char *buf, size_t size)
273 {
274  const struct GNUNET_MessageHeader *hdr;
275  size_t delta;
276  uint16_t want;
277  char *ibuf;
278  int need_align;
279  unsigned long offset;
280  int ret;
281 
282  ret = GNUNET_OK;
283  ibuf = (char *)mst->hdr;
284  while (mst->pos > 0)
285  {
286 do_align:
287  if (mst->pos < mst->off)
288  {
289  //fprintf (stderr, "We processed too many bytes!\n");
290  return GNUNET_SYSERR;
291  }
292  if ((mst->curr_buf - mst->off < sizeof(struct GNUNET_MessageHeader)) ||
293  (0 != (mst->off % ALIGN_FACTOR)))
294  {
295  /* need to align or need more space */
296  mst->pos -= mst->off;
297  memmove(ibuf, &ibuf[mst->off], mst->pos);
298  mst->off = 0;
299  }
300  if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader))
301  {
302  delta =
303  GNUNET_MIN(sizeof(struct GNUNET_MessageHeader) -
304  (mst->pos - mst->off), size);
305  GNUNET_memcpy(&ibuf[mst->pos], buf, delta);
306  mst->pos += delta;
307  buf += delta;
308  size -= delta;
309  }
310  if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader))
311  {
312  //FIXME should I reset ??
313  // mst->off = 0;
314  // mst->pos = 0;
315  return GNUNET_OK;
316  }
317  hdr = (const struct GNUNET_MessageHeader *)&ibuf[mst->off];
318  want = ntohs(hdr->size);
319  if (want < sizeof(struct GNUNET_MessageHeader))
320  {
321  fprintf(stderr,
322  "Received invalid message from stdin\n");
323  return GNUNET_SYSERR;
324  }
325  if ((mst->curr_buf - mst->off < want) &&
326  (mst->off > 0))
327  {
328  /* need more space */
329  mst->pos -= mst->off;
330  memmove(ibuf, &ibuf[mst->off], mst->pos);
331  mst->off = 0;
332  }
333  if (want > mst->curr_buf)
334  {
335  if (mst->off != 0)
336  {
337  fprintf(stderr, "Error! We should proceeded 0 bytes\n");
338  return GNUNET_SYSERR;
339  }
340  mst->hdr = realloc(mst->hdr, want);
341  if (NULL == mst->hdr)
342  {
343  fprintf(stderr, "Failed to allocate buffer for alignment\n");
344  exit(1);
345  }
346  ibuf = (char *)mst->hdr;
347  mst->curr_buf = want;
348  }
349  hdr = (const struct GNUNET_MessageHeader *)&ibuf[mst->off];
350  if (mst->pos - mst->off < want)
351  {
352  delta = GNUNET_MIN(want - (mst->pos - mst->off), size);
353  if (mst->pos + delta > mst->curr_buf)
354  {
355  fprintf(stderr, "The size of the buffer will be exceeded!\n");
356  return GNUNET_SYSERR;
357  }
358  GNUNET_memcpy(&ibuf[mst->pos], buf, delta);
359  mst->pos += delta;
360  buf += delta;
361  size -= delta;
362  }
363  if (mst->pos - mst->off < want)
364  {
365  //FIXME should I use this?
366  // mst->off = 0;
367  // mst->pos = 0;
368  return GNUNET_OK;
369  }
370  mst->cb(mst->cb_cls, hdr);
371  mst->off += want;
372  if (mst->off == mst->pos)
373  {
374  /* reset to beginning of buffer, it's free right now! */
375  mst->off = 0;
376  mst->pos = 0;
377  }
378  }
379  if (0 != mst->pos)
380  {
381  fprintf(stderr, "There should some valid bytes in the buffer on this stage\n");
382  return GNUNET_SYSERR;
383  }
384  while (size > 0)
385  {
386  if (size < sizeof(struct GNUNET_MessageHeader))
387  break;
388  offset = (unsigned long)buf;
389  need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
390  if (GNUNET_NO == need_align)
391  {
392  /* can try to do zero-copy and process directly from original buffer */
393  hdr = (const struct GNUNET_MessageHeader *)buf;
394  want = ntohs(hdr->size);
395  if (want < sizeof(struct GNUNET_MessageHeader))
396  {
397  fprintf(stderr,
398  "Received invalid message from stdin\n");
399  //exit (1);
400  mst->off = 0;
401  return GNUNET_SYSERR;
402  }
403  if (size < want)
404  break; /* or not, buffer incomplete, so copy to private buffer... */
405  mst->cb(mst->cb_cls, hdr);
406  buf += want;
407  size -= want;
408  }
409  else
410  {
411  /* need to copy to private buffer to align;
412  * yes, we go a bit more spagetti than usual here */
413  goto do_align;
414  }
415  }
416  if (size > 0)
417  {
418  if (size + mst->pos > mst->curr_buf)
419  {
420  mst->hdr = realloc(mst->hdr, size + mst->pos);
421  if (NULL == mst->hdr)
422  {
423  fprintf(stderr, "Failed to allocate buffer for alignment\n");
424  exit(1);
425  }
426  ibuf = (char *)mst->hdr;
427  mst->curr_buf = size + mst->pos;
428  }
429  if (mst->pos + size > mst->curr_buf)
430  {
431  fprintf(stderr,
432  "Assertion failed\n");
433  exit(1);
434  }
435  GNUNET_memcpy(&ibuf[mst->pos], buf, size);
436  mst->pos += size;
437  }
438  return ret;
439 }
440 
446 static void
448 {
449  free(mst->hdr);
450  free(mst);
451 }
452 
460 static unsigned long
461 calc_crc_osdep(const unsigned char *buf, size_t len)
462 {
463  static const unsigned long int crc_tbl_osdep[256] = {
464  0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
465  0xE963A535, 0x9E6495A3,
466  0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
467  0xE7B82D07, 0x90BF1D91,
468  0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
469  0xF4D4B551, 0x83D385C7,
470  0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
471  0xFA0F3D63, 0x8D080DF5,
472  0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
473  0xD20D85FD, 0xA50AB56B,
474  0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
475  0xDCD60DCF, 0xABD13D59,
476  0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
477  0xCFBA9599, 0xB8BDA50F,
478  0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
479  0xC1611DAB, 0xB6662D3D,
480  0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
481  0x9FBFE4A5, 0xE8B8D433,
482  0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
483  0x91646C97, 0xE6635C01,
484  0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
485  0x8208F4C1, 0xF50FC457,
486  0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
487  0x8CD37CF3, 0xFBD44C65,
488  0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
489  0xA4D1C46D, 0xD3D6F4FB,
490  0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
491  0xAA0A4C5F, 0xDD0D7CC9,
492  0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
493  0xB966D409, 0xCE61E49F,
494  0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
495  0xB7BD5C3B, 0xC0BA6CAD,
496  0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
497  0x04DB2615, 0x73DC1683,
498  0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
499  0x0A00AE27, 0x7D079EB1,
500  0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
501  0x196C3671, 0x6E6B06E7,
502  0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
503  0x17B7BE43, 0x60B08ED5,
504  0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
505  0x3FB506DD, 0x48B2364B,
506  0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
507  0x316E8EEF, 0x4669BE79,
508  0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
509  0x220216B9, 0x5505262F,
510  0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
511  0x2CD99E8B, 0x5BDEAE1D,
512  0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
513  0x72076785, 0x05005713,
514  0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
515  0x7CDCEFB7, 0x0BDBDF21,
516  0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
517  0x6FB077E1, 0x18B74777,
518  0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
519  0x616BFFD3, 0x166CCF45,
520  0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
521  0x4969474D, 0x3E6E77DB,
522  0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
523  0x47B2CF7F, 0x30B5FFE9,
524  0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
525  0x54DE5729, 0x23D967BF,
526  0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
527  0x5A05DF1B, 0x2D02EF8D
528  };
529 
530  unsigned long crc = 0xFFFFFFFF;
531 
532  for (; len > 0; len--, buf++)
533  crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
534  return(~crc);
535 }
536 
537 
546 static int
547 check_crc_buf_osdep(const unsigned char *buf, size_t len)
548 {
549  unsigned long crc;
550 
551  crc = calc_crc_osdep(buf, len);
552  buf += len;
553  if (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
554  ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3])
555  return 0;
556  return 1;
557 }
558 
559 
560 
561 /* ************** end of clone ***************** */
562 #ifdef LINUX
563 
570 static int
571 bind_socket(int socket, struct sockaddr_rc *addr)
572 {
573  int port, status;
574 
575  /* Bind every possible port (from 0 to 30) and stop when binding doesn't fail */
576  //FIXME : it should start from port 1, but on my computer it doesn't work :)
577  for (port = 3; port <= 30; port++)
578  {
579  addr->rc_channel = port;
580  status = bind(socket, (struct sockaddr *)addr, sizeof(struct sockaddr_rc));
581  if (status == 0)
582  return 0;
583  }
584 
585  return -1;
586 }
587 #endif
588 
596 static int
597 register_service(struct HardwareInfos *dev, int rc_channel)
598 {
608  uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
609  dev->pl_mac.mac[5], dev->pl_mac.mac[4], dev->pl_mac.mac[3],
610  dev->pl_mac.mac[2], dev->pl_mac.mac[1], dev->pl_mac.mac[0] };
611  const char *service_dsc = "Bluetooth plugin services";
612  const char *service_prov = "GNUnet provider";
613  uuid_t root_uuid, rfcomm_uuid, svc_uuid;
614  sdp_list_t *root_list = 0, *rfcomm_list = 0, *proto_list = 0,
615  *access_proto_list = 0, *svc_list = 0;
616  sdp_record_t *record = 0;
617  sdp_data_t *channel = 0;
618 
619  record = sdp_record_alloc();
620 
621  /* Set the general service ID */
622  sdp_uuid128_create(&svc_uuid, &svc_uuid_int);
623  svc_list = sdp_list_append(0, &svc_uuid);
624  sdp_set_service_classes(record, svc_list);
625  sdp_set_service_id(record, svc_uuid);
626 
627  /* Make the service record publicly browsable */
628  sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
629  root_list = sdp_list_append(0, &root_uuid);
630  sdp_set_browse_groups(record, root_list);
631 
632  /* Register the RFCOMM channel */
633  sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
634  channel = sdp_data_alloc(SDP_UINT8, &rc_channel);
635  rfcomm_list = sdp_list_append(0, &rfcomm_uuid);
636  sdp_list_append(rfcomm_list, channel);
637  proto_list = sdp_list_append(0, rfcomm_list);
638 
639  /* Set protocol information */
640  access_proto_list = sdp_list_append(0, proto_list);
641  sdp_set_access_protos(record, access_proto_list);
642 
643  /* Set the name, provider, and description */
644  sdp_set_info_attr(record, dev->iface, service_prov, service_dsc);
645 
646  /* Connect to the local SDP server */
647  dev->session = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
648 
649  if (!dev->session)
650  {
651  fprintf(stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
652  IFNAMSIZ, dev->iface, strerror(errno));
653  //FIXME exit?
654  return 1;
655  }
656 
657  /* Register the service record */
658  if (sdp_record_register(dev->session, record, 0) < 0)
659  {
660  fprintf(stderr, "Failed to register a service record on interface `%.*s': %s\n",
661  IFNAMSIZ, dev->iface, strerror(errno));
662  //FIXME exit?
663  return 1;
664  }
665 
666  /* Cleanup */
667  sdp_data_free(channel);
668  sdp_list_free(root_list, 0);
669  sdp_list_free(rfcomm_list, 0);
670  sdp_list_free(proto_list, 0);
671  sdp_list_free(access_proto_list, 0);
672  sdp_list_free(svc_list, 0);
673  sdp_record_free(record);
674 
675  return 0;
676 }
677 
686 static int
687 get_channel(struct HardwareInfos *dev, bdaddr_t dest)
688 {
697  uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
698  dest.b[5], dest.b[4], dest.b[3],
699  dest.b[2], dest.b[1], dest.b[0] };
700  sdp_session_t *session = 0;
701  sdp_list_t *search_list = 0, *attrid_list = 0, *response_list = 0, *it = 0;
702  uuid_t svc_uuid;
703  uint32_t range = 0x0000ffff;
704  int channel = -1;
705 
706  /* Connect to the local SDP server */
707  session = sdp_connect(BDADDR_ANY, &dest, 0);
708  if (!session)
709  {
710  fprintf(stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
711  IFNAMSIZ, dev->iface, strerror(errno));
712  return -1;
713  }
714 
715  sdp_uuid128_create(&svc_uuid, &svc_uuid_int);
716  search_list = sdp_list_append(0, &svc_uuid);
717  attrid_list = sdp_list_append(0, &range);
718 
719  if (sdp_service_search_attr_req(session, search_list,
720  SDP_ATTR_REQ_RANGE, attrid_list, &response_list) == 0)
721  {
722  for (it = response_list; it; it = it->next)
723  {
724  sdp_record_t *record = (sdp_record_t*)it->data;
725  sdp_list_t *proto_list = 0;
726  if (sdp_get_access_protos(record, &proto_list) == 0)
727  {
728  channel = sdp_get_proto_port(proto_list, RFCOMM_UUID);
729  sdp_list_free(proto_list, 0);
730  }
731  sdp_record_free(record);
732  }
733  }
734 
735  sdp_list_free(search_list, 0);
736  sdp_list_free(attrid_list, 0);
737  sdp_list_free(response_list, 0);
738 
739  sdp_close(session);
740 
741  if (-1 == channel)
742  fprintf(stderr,
743  "Failed to find the listening channel for interface `%.*s': %s\n",
744  IFNAMSIZ,
745  dev->iface,
746  strerror(errno));
747 
748  return channel;
749 }
750 
761 static ssize_t
763  unsigned char *buf, size_t buf_size,
765 {
766  unsigned char tmpbuf[buf_size];
767  ssize_t count;
768  count = read(*((int *)sock), tmpbuf, buf_size);
769 
770  if (0 > count)
771  {
772  if (EAGAIN == errno)
773  return 0;
774 
775  fprintf(stderr, "Failed to read from the HCI socket: %s\n", strerror(errno));
776 
777  return -1;
778  }
779 
780  #ifdef LINUX
781  /* Get the channel used */
782  int len;
783  struct sockaddr_rc rc_addr = { 0 };
784 
785  memset(&rc_addr, 0, sizeof(rc_addr));
786  len = sizeof(rc_addr);
787  if (0 > getsockname(*((int *)sock), (struct sockaddr *)&rc_addr, (socklen_t *)&len))
788  {
789  fprintf(stderr, "getsockname() call failed : %s\n", strerror(errno));
790  return -1;
791  }
792 
793  memset(ri, 0, sizeof(*ri));
794  ri->ri_channel = rc_addr.rc_channel;
795  #endif
796 
797  /* Detect CRC32 at the end */
798  if (0 == check_crc_buf_osdep(tmpbuf, count - sizeof(uint32_t)))
799  {
800  count -= sizeof(uint32_t);
801  }
802 
803  GNUNET_memcpy(buf, tmpbuf, count);
804 
805  return count;
806 }
807 
808 
815 static int
817 {
818  int i, dev_id = -1, fd_hci;
819  struct {
820  struct hci_dev_list_req list;
821  struct hci_dev_req dev[HCI_MAX_DEV];
822  } request; //used for detecting the local devices
823  struct sockaddr_rc rc_addr = { 0 }; //used for binding
824 
825  /* Initialize the neighbour structure */
826  neighbours.dev_id = -1;
827  for (i = 0; i < MAX_PORTS; i++)
828  neighbours.fds[i] = -1;
829 
830  /* Open a HCI socket */
831  fd_hci = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
832 
833  if (fd_hci < 0)
834  {
835  fprintf(stderr,
836  "Failed to create HCI socket: %s\n",
837  strerror(errno));
838  return -1;
839  }
840 
841  memset(&request, 0, sizeof(request));
842  request.list.dev_num = HCI_MAX_DEV;
843 
844  if (ioctl(fd_hci, HCIGETDEVLIST, (void *)&request) < 0)
845  {
846  fprintf(stderr,
847  "ioctl(HCIGETDEVLIST) on interface `%.*s' failed: %s\n",
848  IFNAMSIZ,
849  dev->iface,
850  strerror(errno));
851  (void)close(fd_hci);
852  return 1;
853  }
854 
855  /* Search for a device with dev->iface name */
856  for (i = 0; i < request.list.dev_num; i++)
857  {
858  struct hci_dev_info dev_info;
859 
860  memset(&dev_info, 0, sizeof(struct hci_dev_info));
861  dev_info.dev_id = request.dev[i].dev_id;
862  strncpy(dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE);
863 
864  if (ioctl(fd_hci, HCIGETDEVINFO, (void *)&dev_info))
865  {
866  fprintf(stderr,
867  "ioctl(HCIGETDEVINFO) 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  if (strncmp(dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE) == 0)
876  {
877  dev_id = dev_info.dev_id; //the device was found
881  GNUNET_memcpy(&dev->pl_mac, &dev_info.bdaddr, sizeof(bdaddr_t));
882 
883  /* Check if the interface is up */
884  if (hci_test_bit(HCI_UP, (void *)&dev_info.flags) == 0)
885  {
886  /* Bring the interface up */
887  if (ioctl(fd_hci, HCIDEVUP, dev_info.dev_id))
888  {
889  fprintf(stderr,
890  "ioctl(HCIDEVUP) on interface `%.*s' failed: %s\n",
891  IFNAMSIZ,
892  dev->iface,
893  strerror(errno));
894  (void)close(fd_hci);
895  return 1;
896  }
897  }
898 
899  /* Check if the device is discoverable */
900  if (hci_test_bit(HCI_PSCAN, (void *)&dev_info.flags) == 0 ||
901  hci_test_bit(HCI_ISCAN, (void *)&dev_info.flags) == 0)
902  {
903  /* Set interface Page Scan and Inqury Scan ON */
904  struct hci_dev_req dev_req;
905 
906  memset(&dev_req, 0, sizeof(dev_req));
907  dev_req.dev_id = dev_info.dev_id;
908  dev_req.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
909 
910  if (ioctl(fd_hci, HCISETSCAN, (unsigned long)&dev_req))
911  {
912  fprintf(stderr,
913  "ioctl(HCISETSCAN) on interface `%.*s' failed: %s\n",
914  IFNAMSIZ,
915  dev->iface,
916  strerror(errno));
917  (void)close(fd_hci);
918  return 1;
919  }
920  }
921  break;
922  }
923  }
924 
925  /* Check if the interface was not found */
926  if (-1 == dev_id)
927  {
928  fprintf(stderr,
929  "The interface %s was not found\n",
930  dev->iface);
931  (void)close(fd_hci);
932  return 1;
933  }
934 
935  /* Close the hci socket */
936  (void)close(fd_hci);
937 
938 
939 
940  /* Bind the rfcomm socket to the interface */
941  memset(&rc_addr, 0, sizeof(rc_addr));
942  rc_addr.rc_family = AF_BLUETOOTH;
943  rc_addr.rc_bdaddr = *BDADDR_ANY;
944 
945  if (bind_socket(dev->fd_rfcomm, &rc_addr) != 0)
946  {
947  fprintf(stderr,
948  "Failed to bind interface `%.*s': %s\n",
949  IFNAMSIZ,
950  dev->iface,
951  strerror(errno));
952  return 1;
953  }
954 
955  /* Register a SDP service */
956  if (register_service(dev, rc_addr.rc_channel) != 0)
957  {
958  fprintf(stderr,
959  "Failed to register a service on interface `%.*s': %s\n",
960  IFNAMSIZ,
961  dev->iface, strerror(errno));
962  return 1;
963  }
964 
965  /* Switch socket in listening mode */
966  if (listen(dev->fd_rfcomm, 5) == -1) //FIXME: probably we need a bigger number
967  {
968  fprintf(stderr, "Failed to listen on socket for interface `%.*s': %s\n", IFNAMSIZ,
969  dev->iface, strerror(errno));
970  return 1;
971  }
972 
973  return 0;
974 }
975 
976 
985 static void
987  const struct HardwareInfos *dev)
988 {
989  taIeeeHeader->frame_control = htons(IEEE80211_FC0_TYPE_DATA);
990  taIeeeHeader->addr3 = mac_bssid_gnunet;
991  taIeeeHeader->addr2 = dev->pl_mac;
992 }
993 
994 #ifdef LINUX
995 
1003 static int
1004 test_bluetooth_interface(const char *iface)
1005 {
1006  char strbuf[512];
1007  struct stat sbuf;
1008  int ret;
1009 
1010  ret = snprintf(strbuf, sizeof(strbuf),
1011  "/sys/class/bluetooth/%s/subsystem",
1012  iface);
1013  if ((ret < 0) || (ret >= sizeof(strbuf)) || (0 != stat(strbuf, &sbuf)))
1014  {
1015  fprintf(stderr,
1016  "Did not find 802.15.1 interface `%s'. Exiting.\n",
1017  iface);
1018  exit(1);
1019  }
1020  return 0;
1021 }
1022 #endif
1023 
1033 static int
1035  const struct HardwareInfos *dev)
1036 {
1037  static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
1038 
1039  if ((0 == memcmp(&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
1040  (0 == memcmp(&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)))
1041  return 0; /* some drivers set no Macs, then assume it is all for us! */
1042 
1043  if (0 != memcmp(&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1044  return 1; /* not a GNUnet ad-hoc package */
1045  if ((0 == memcmp(&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
1046  (0 == memcmp(&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)))
1047  return 0; /* for us, or broadcast */
1048  return 1; /* not for us */
1049 }
1050 
1051 
1061 static void
1062 stdin_send_hw(void *cls, const struct GNUNET_MessageHeader *hdr)
1063 {
1064  struct HardwareInfos *dev = cls;
1066  struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *blueheader;
1067  size_t sendsize;
1068 
1069  sendsize = ntohs(hdr->size);
1070  if ((sendsize <
1073  {
1074  fprintf(stderr, "Received malformed message\n");
1075  exit(1);
1076  }
1077  sendsize -= (sizeof(struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) -
1078  sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1079  if (MAXLINE < sendsize)
1080  {
1081  fprintf(stderr, "Packet too big for buffer\n");
1082  exit(1);
1083  }
1084  header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *)hdr;
1085  GNUNET_memcpy(&write_pout.buf, &header->frame, sendsize);
1086  blueheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *)&write_pout.buf;
1087 
1088  /* payload contains MAC address, but we don't trust it, so we'll
1089  * overwrite it with OUR MAC address to prevent mischief */
1090  mac_set(blueheader, dev);
1091  GNUNET_memcpy(&blueheader->addr1, &header->frame.addr1,
1092  sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress));
1093  write_pout.size = sendsize;
1094 }
1095 
1096 #ifdef LINUX
1097 
1104 static int
1105 send_broadcast(struct HardwareInfos *dev, int *sendsocket)
1106 {
1107  int new_device = 0;
1108  int loops = 0;
1109 
1110 search_for_devices:
1111  if ((neighbours.size == neighbours.pos && new_device == 1) || neighbours.size == 0)
1112  {
1113 inquiry_devices: //skip the conditions and force a inquiry for new devices
1114  {
1119  inquiry_info *devices = NULL;
1120  int i, responses, max_responses = MAX_PORTS;
1121 
1122  /* sanity checks */
1123  if (neighbours.size >= MAX_PORTS)
1124  {
1125  fprintf(stderr, "%.*s reached the top limit for the discovarable devices\n", IFNAMSIZ, dev->iface);
1126  return 2;
1127  }
1128 
1129  /* Get the device id */
1130  if (neighbours.dev_id == -1)
1131  {
1132  char addr[19] = { 0 }; //the device MAC address
1133 
1134  ba2str((bdaddr_t *)&dev->pl_mac, addr);
1135  neighbours.dev_id = hci_devid(addr);
1136  if (neighbours.dev_id < 0)
1137  {
1138  fprintf(stderr, "Failed to get the device id for interface %.*s : %s\n", IFNAMSIZ,
1139  dev->iface, strerror(errno));
1140  return 1;
1141  }
1142  }
1143 
1144  devices = malloc(max_responses * sizeof(inquiry_info));
1145  if (devices == NULL)
1146  {
1147  fprintf(stderr, "Failed to allocate memory for inquiry info list on interface %.*s\n", IFNAMSIZ,
1148  dev->iface);
1149  return 1;
1150  }
1151 
1152  responses = hci_inquiry(neighbours.dev_id, 8, max_responses, NULL, &devices, IREQ_CACHE_FLUSH);
1153  if (responses < 0)
1154  {
1155  fprintf(stderr, "Failed to inquiry on interface %.*s\n", IFNAMSIZ, dev->iface);
1156  return 1;
1157  }
1158 
1159  fprintf(stderr, "LOG : Found %d devices\n", responses); //FIXME delete it after debugging stage
1160 
1161  if (responses == 0)
1162  {
1163  fprintf(stderr, "LOG : No devices discoverable\n");
1164  return 1;
1165  }
1166 
1167  for (i = 0; i < responses; i++)
1168  {
1169  int j;
1170  int found = 0;
1171 
1172  /* sanity check */
1173  if (i >= MAX_PORTS)
1174  {
1175  fprintf(stderr, "%.*s reached the top limit for the discoverable devices (after inquiry)\n", IFNAMSIZ,
1176  dev->iface);
1177  return 2;
1178  }
1179 
1180  /* Search if the address already exists on the list */
1181  for (j = 0; j < neighbours.size; j++)
1182  {
1183  if (memcmp(&(devices + i)->bdaddr, &(neighbours.devices[j]), sizeof(bdaddr_t)) == 0)
1184  {
1185  found = 1;
1186  fprintf(stderr, "LOG : the device already exists on the list\n"); //FIXME debugging message
1187  break;
1188  }
1189  }
1190 
1191  if (found == 0)
1192  {
1193  char addr[19] = { 0 };
1194 
1195  ba2str(&(devices + i)->bdaddr, addr);
1196  fprintf(stderr, "LOG : %s was added to the list\n", addr); //FIXME debugging message
1197  GNUNET_memcpy(&(neighbours.devices[neighbours.size++]), &(devices + i)->bdaddr, sizeof(bdaddr_t));
1198  }
1199  }
1200 
1201  free(devices);
1202  }
1203  }
1204 
1205  int connection_successful = 0;
1206  struct sockaddr_rc addr_rc = { 0 };
1207  int errno_copy = 0;
1208  addr_rc.rc_family = AF_BLUETOOTH;
1209 
1210  /* Try to connect to a new device from the list */
1211  while (neighbours.pos < neighbours.size)
1212  {
1213  /* Check if we are already connected to this device */
1214  if (neighbours.fds[neighbours.pos] == -1)
1215  {
1216  memset(&addr_rc.rc_bdaddr, 0, sizeof(addr_rc.rc_bdaddr));
1217  GNUNET_memcpy(&addr_rc.rc_bdaddr, &(neighbours.devices[neighbours.pos]), sizeof(addr_rc.rc_bdaddr));
1218 
1219  addr_rc.rc_channel = get_channel(dev, addr_rc.rc_bdaddr);
1220 
1221  *sendsocket = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1222  if ((-1 < *sendsocket) &&
1223  (0 == connect(*sendsocket,
1224  (struct sockaddr *)&addr_rc,
1225  sizeof(addr_rc))))
1226  {
1227  neighbours.fds[neighbours.pos++] = *sendsocket;
1228  connection_successful = 1;
1229  char addr[19] = { 0 };
1230  ba2str(&(neighbours.devices[neighbours.pos - 1]), addr);
1231  fprintf(stderr, "LOG : Connected to %s\n", addr);
1232  break;
1233  }
1234  else
1235  {
1236  char addr[19] = { 0 };
1237  errno_copy = errno; //Save a copy for later
1238 
1239  if (-1 != *sendsocket)
1240  {
1241  (void)close(*sendsocket);
1242  *sendsocket = -1;
1243  }
1244  ba2str(&(neighbours.devices[neighbours.pos]), addr);
1245  fprintf(stderr,
1246  "LOG : Couldn't connect on device %s, error : %s\n",
1247  addr,
1248  strerror(errno));
1249  if (errno != ECONNREFUSED) //FIXME be sure that this works
1250  {
1251  fprintf(stderr, "LOG : Removes %d device from the list\n", neighbours.pos);
1252  /* Remove the device from the list */
1253  GNUNET_memcpy(&neighbours.devices[neighbours.pos], &neighbours.devices[neighbours.size - 1], sizeof(bdaddr_t));
1254  memset(&neighbours.devices[neighbours.size - 1], 0, sizeof(bdaddr_t));
1255  neighbours.fds[neighbours.pos] = neighbours.fds[neighbours.size - 1];
1256  neighbours.fds[neighbours.size - 1] = -1;
1257  neighbours.size -= 1;
1258  }
1259 
1260  neighbours.pos += 1;
1261 
1262  if (neighbours.pos >= neighbours.size)
1263  neighbours.pos = 0;
1264 
1265  loops += 1;
1266 
1267  if (loops == MAX_LOOPS) //don't get stuck trying to connect to one device
1268  return 1;
1269  }
1270  }
1271  else
1272  {
1273  fprintf(stderr, "LOG : Search for a new device\n"); //FIXME debugging message
1274  neighbours.pos += 1;
1275  }
1276  }
1277 
1278  /* Cycle on the list */
1279  if (neighbours.pos == neighbours.size)
1280  {
1281  neighbours.pos = 0;
1282  searching_devices_count += 1;
1283 
1284  if (searching_devices_count == MAX_LOOPS)
1285  {
1286  fprintf(stderr, "LOG : Force to inquiry for new devices\n");
1287  searching_devices_count = 0;
1288  goto inquiry_devices;
1289  }
1290  }
1291  /* If a new device wasn't found, search an old one */
1292  if (connection_successful == 0)
1293  {
1294  int loop_check = neighbours.pos;
1295  while (neighbours.fds[neighbours.pos] == -1)
1296  {
1297  if (neighbours.pos == neighbours.size)
1298  neighbours.pos = 0;
1299 
1300  if (neighbours.pos == loop_check)
1301  {
1302  if (errno_copy == ECONNREFUSED)
1303  {
1304  fprintf(stderr, "LOG : No device found. Go back and search again\n"); //FIXME debugging message
1305  new_device = 1;
1306  loops += 1;
1307  goto search_for_devices;
1308  }
1309  else
1310  {
1311  return 1; // Skip the broadcast message
1312  }
1313  }
1314 
1315  neighbours.pos += 1;
1316  }
1317 
1318  *sendsocket = neighbours.fds[neighbours.pos++];
1319  }
1320 
1321  return 0;
1322 }
1323 #endif
1324 
1336 int
1337 main(int argc, char *argv[])
1338 {
1339 #ifdef LINUX
1340  struct HardwareInfos dev;
1341  char readbuf[MAXLINE];
1342  int maxfd;
1343  fd_set rfds;
1344  fd_set wfds;
1345  int stdin_open;
1347  int raw_eno, i;
1348  int crt_rfds = 0, rfds_list[MAX_PORTS];
1349  int broadcast, sendsocket;
1350 
1351  /* Assert privs so we can modify the firewall rules! */
1352  {
1353 #ifdef HAVE_SETRESUID
1354  uid_t uid = getuid();
1355 
1356  if (0 != setresuid(uid, 0, 0))
1357  {
1358  fprintf(stderr,
1359  "Failed to setresuid to root: %s\n",
1360  strerror(errno));
1361  return 254;
1362  }
1363 #else
1364  if (0 != seteuid(0))
1365  {
1366  fprintf(stderr,
1367  "Failed to seteuid back to root: %s\n", strerror(errno));
1368  return 254;
1369  }
1370 #endif
1371  }
1372 
1373  /* Make use of SGID capabilities on POSIX */
1374  memset(&dev, 0, sizeof(dev));
1375  dev.fd_rfcomm = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1376  raw_eno = errno; /* remember for later */
1377 
1378  /* Now that we've dropped root rights, we can do error checking */
1379  if (2 != argc)
1380  {
1381  fprintf(stderr, "You must specify the name of the interface as the first \
1382  and only argument to this program.\n");
1383  if (-1 != dev.fd_rfcomm)
1384  (void)close(dev.fd_rfcomm);
1385  return 1;
1386  }
1387 
1388  if (-1 == dev.fd_rfcomm)
1389  {
1390  fprintf(stderr, "Failed to create a RFCOMM socket: %s\n", strerror(raw_eno));
1391  return 1;
1392  }
1393  if (dev.fd_rfcomm >= FD_SETSIZE)
1394  {
1395  fprintf(stderr, "File descriptor too large for select (%d > %d)\n",
1396  dev.fd_rfcomm, FD_SETSIZE);
1397  (void)close(dev.fd_rfcomm);
1398  return 1;
1399  }
1400  if (0 != test_bluetooth_interface(argv[1]))
1401  {
1402  (void)close(dev.fd_rfcomm);
1403  return 1;
1404  }
1405  strncpy(dev.iface, argv[1], IFNAMSIZ);
1406  if (0 != open_device(&dev))
1407  {
1408  (void)close(dev.fd_rfcomm);
1409  return 1;
1410  }
1411 
1412  /* Drop privs */
1413  {
1414  uid_t uid = getuid();
1415  #ifdef HAVE_SETRESUID
1416  if (0 != setresuid(uid, uid, uid))
1417  {
1418  fprintf(stderr, "Failed to setresuid: %s\n", strerror(errno));
1419  if (-1 != dev.fd_rfcomm)
1420  (void)close(dev.fd_rfcomm);
1421  return 1;
1422  }
1423  #else
1424  if (0 != (setuid(uid) | seteuid(uid)))
1425  {
1426  fprintf(stderr, "Failed to setuid: %s\n", strerror(errno));
1427  if (-1 != dev.fd_rfcomm)
1428  (void)close(dev.fd_rfcomm);
1429  return 1;
1430  }
1431  #endif
1432  }
1433 
1434  /* Send MAC address of the bluetooth interface to STDOUT first */
1435  {
1437 
1438  macmsg.hdr.size = htons(sizeof(macmsg));
1440  GNUNET_memcpy(&macmsg.mac, &dev.pl_mac, sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress));
1441  GNUNET_memcpy(write_std.buf, &macmsg, sizeof(macmsg));
1442  write_std.size = sizeof(macmsg);
1443  }
1444 
1445 
1446  stdin_mst = mst_create(&stdin_send_hw, &dev);
1447  stdin_open = 1;
1448 
1453  while (1)
1454  {
1455  maxfd = -1;
1456  broadcast = 0;
1457  sendsocket = -1;
1458 
1459  FD_ZERO(&rfds);
1460  if ((0 == write_pout.size) && (1 == stdin_open))
1461  {
1462  FD_SET(STDIN_FILENO, &rfds);
1463  maxfd = MAX(maxfd, STDIN_FILENO);
1464  }
1465  if (0 == write_std.size)
1466  {
1467  FD_SET(dev.fd_rfcomm, &rfds);
1468  maxfd = MAX(maxfd, dev.fd_rfcomm);
1469  }
1470 
1471  for (i = 0; i < crt_rfds; i++) // it can receive messages from multiple devices
1472  {
1473  FD_SET(rfds_list[i], &rfds);
1474  maxfd = MAX(maxfd, rfds_list[i]);
1475  }
1476  FD_ZERO(&wfds);
1477  if (0 < write_std.size)
1478  {
1479  FD_SET(STDOUT_FILENO, &wfds);
1480  maxfd = MAX(maxfd, STDOUT_FILENO);
1481  }
1482  if (0 < write_pout.size) //it can send messages only to one device per loop
1483  {
1485  /* Get the destination address */
1487 
1488  if (memcmp(&frame->addr1, &dev.pl_mac,
1489  sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1490  {
1491  broadcast = 1;
1492  memset(&write_pout, 0, sizeof(write_pout)); //clear the buffer
1493  }
1494  else if (memcmp(&frame->addr1, &broadcast_address,
1495  sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1496  {
1497  fprintf(stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n", dev.iface, neighbours.pos, neighbours.size); //FIXME: debugging message
1498 
1499  if (send_broadcast(&dev, &sendsocket) != 0) //if the searching wasn't successful don't get stuck on the select stage
1500  {
1501  broadcast = 1;
1502  memset(&write_pout, 0, sizeof(write_pout)); //remove the message
1503  fprintf(stderr, "LOG : Skipping the broadcast message (pos %d, size %d)\n", neighbours.pos, neighbours.size);
1504  }
1505  else
1506  {
1507  FD_SET(sendsocket, &wfds);
1508  maxfd = MAX(maxfd, sendsocket);
1509  }
1510  }
1511  else
1512  {
1513  int found = 0;
1514  int pos = 0;
1515  /* Search if the address already exists on the list */
1516  for (i = 0; i < neighbours.size; i++)
1517  {
1518  if (memcmp(&frame->addr1, &(neighbours.devices[i]), sizeof(bdaddr_t)) == 0)
1519  {
1520  pos = i;
1521  if (neighbours.fds[i] != -1)
1522  {
1523  found = 1; //save the position where it was found
1524  FD_SET(neighbours.fds[i], &wfds);
1525  maxfd = MAX(maxfd, neighbours.fds[i]);
1526  sendsocket = neighbours.fds[i];
1527  fprintf(stderr, "LOG: the address was found in the list\n");
1528  break;
1529  }
1530  }
1531  }
1532  if (found == 0)
1533  {
1534  int status;
1535  struct sockaddr_rc addr = { 0 };
1536 
1537  fprintf(stderr, "LOG : %s has a new message for %.2X:%.2X:%.2X:%.2X:%.2X:%.2X which isn't on the broadcast list\n", dev.iface,
1538  frame->addr1.mac[5], frame->addr1.mac[4], frame->addr1.mac[3],
1539  frame->addr1.mac[2], frame->addr1.mac[1], frame->addr1.mac[0]); //FIXME: debugging message
1540 
1541  sendsocket = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1542 
1543  if (sendsocket < 0)
1544  {
1545  fprintf(stderr, "Failed to create a RFCOMM socket (sending stage): %s\n",
1546  strerror(errno));
1547  return -1;
1548  }
1549 
1550  GNUNET_memcpy(&addr.rc_bdaddr, &frame->addr1, sizeof(bdaddr_t));
1551  addr.rc_family = AF_BLUETOOTH;
1552  addr.rc_channel = get_channel(&dev, addr.rc_bdaddr);
1553 
1554  int tries = 0;
1555 connect_retry:
1556  status = connect(sendsocket, (struct sockaddr *)&addr, sizeof(addr));
1557  if (0 != status && errno != EAGAIN)
1558  {
1559  if (errno == ECONNREFUSED && tries < 2)
1560  {
1561  fprintf(stderr, "LOG : %.*s failed to connect. Trying again!\n", IFNAMSIZ, dev.iface);
1562  tries++;
1563  goto connect_retry;
1564  }
1565  else if (errno == EBADF)
1566  {
1567  fprintf(stderr, "LOG : %s failed to connect : %s. Skip it!\n", dev.iface, strerror(errno));
1568  memset(&write_pout, 0, sizeof(write_pout));
1569  broadcast = 1;
1570  }
1571  else
1572  {
1573  fprintf(stderr, "LOG : %s failed to connect : %s. Try again later!\n", dev.iface, strerror(errno));
1574  memset(&write_pout, 0, sizeof(write_pout));
1575  broadcast = 1;
1576  }
1577  }
1578  else
1579  {
1580  FD_SET(sendsocket, &wfds);
1581  maxfd = MAX(maxfd, sendsocket);
1582  fprintf(stderr, "LOG : Connection successful\n");
1583  if (pos != 0) // save the socket
1584  {
1585  neighbours.fds[pos] = sendsocket;
1586  }
1587  else
1588  {
1589  /* Add the new device to the discovered devices list */
1590  if (neighbours.size < MAX_PORTS)
1591  {
1592  neighbours.fds[neighbours.size] = sendsocket;
1593  GNUNET_memcpy(&(neighbours.devices[neighbours.size++]), &addr.rc_bdaddr, sizeof(bdaddr_t));
1594  }
1595  else
1596  {
1597  fprintf(stderr, "The top limit for the discovarable devices' list was reached\n");
1598  }
1599  }
1600  }
1601  }
1602  }
1603  }
1604 
1605  if (broadcast == 0)
1606  {
1607  /* Select a fd which is ready for action :) */
1608  {
1609  int retval = select(maxfd + 1, &rfds, &wfds, NULL, NULL);
1610  if ((-1 == retval) && (EINTR == errno))
1611  continue;
1612  if (0 > retval && errno != EBADF) // we handle BADF errors later
1613  {
1614  fprintf(stderr, "select failed: %s\n", strerror(errno));
1615  break;
1616  }
1617  }
1618  if (FD_ISSET(STDOUT_FILENO, &wfds))
1619  {
1620  ssize_t ret =
1621  write(STDOUT_FILENO, write_std.buf + write_std.pos,
1623  if (0 > ret)
1624  {
1625  fprintf(stderr, "Failed to write to STDOUT: %s\n", strerror(errno));
1626  break;
1627  }
1628  write_std.pos += ret;
1629  if (write_std.pos == write_std.size)
1630  {
1631  write_std.pos = 0;
1632  write_std.size = 0;
1633  }
1634  fprintf(stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); //FIXME: debugging message
1635  }
1636  if (-1 != sendsocket)
1637  {
1638  if (FD_ISSET(sendsocket, &wfds))
1639  {
1640  ssize_t ret = write(sendsocket,
1643  if (0 > ret) //FIXME should I first check the error type?
1644  {
1645  fprintf(stderr, "Failed to write to bluetooth device: %s. Closing the socket!\n",
1646  strerror(errno));
1647  for (i = 0; i < neighbours.size; i++)
1648  {
1649  if (neighbours.fds[i] == sendsocket)
1650  {
1651  (void)close(sendsocket);
1652  neighbours.fds[i] = -1;
1653  break;
1654  }
1655  }
1656  /* Remove the message */
1657  memset(&write_pout.buf + write_std.pos, 0, (write_pout.size - write_pout.pos));
1658  write_pout.pos = 0;
1659  write_pout.size = 0;
1660  }
1661  else
1662  {
1663  write_pout.pos += ret;
1664  if ((write_pout.pos != write_pout.size) && (0 != ret))
1665  {
1666  /* We should not get partial sends with packet-oriented devices... */
1667  fprintf(stderr, "Write error, partial send: %u/%u\n",
1668  (unsigned int)write_pout.pos,
1669  (unsigned int)write_pout.size);
1670  break;
1671  }
1672 
1673  if (write_pout.pos == write_pout.size)
1674  {
1675  write_pout.pos = 0;
1676  write_pout.size = 0;
1677  }
1678  fprintf(stderr, "LOG : %s sends a message to a DEVICE\n", dev.iface); //FIXME: debugging message
1679  }
1680  }
1681  }
1682  for (i = 0; i <= maxfd; i++)
1683  {
1684  if (FD_ISSET(i, &rfds))
1685  {
1686  if (i == STDIN_FILENO)
1687  {
1688  ssize_t ret =
1689  read(i, readbuf, sizeof(readbuf));
1690  if (0 > ret)
1691  {
1692  fprintf(stderr,
1693  "Read error from STDIN: %s\n",
1694  strerror(errno));
1695  break;
1696  }
1697  if (0 == ret)
1698  {
1699  /* stop reading... */
1700  stdin_open = 0;
1701  }
1702  else
1703  {
1704  mst_receive(stdin_mst, readbuf, ret);
1705  fprintf(stderr, "LOG : %s receives a message from STDIN\n", dev.iface); //FIXME: debugging message
1706  }
1707  }
1708  else if (i == dev.fd_rfcomm)
1709  {
1710  int readsocket;
1711  struct sockaddr_rc addr = { 0 };
1712  unsigned int opt = sizeof(addr);
1713 
1714  readsocket = accept(dev.fd_rfcomm, (struct sockaddr *)&addr, &opt);
1715  fprintf(stderr, "LOG : %s accepts a message\n", dev.iface); //FIXME: debugging message
1716  if (readsocket == -1)
1717  {
1718  fprintf(stderr, "Failed to accept a connection on interface: %.*s\n", IFNAMSIZ,
1719  strerror(errno));
1720  break;
1721  }
1722  else
1723  {
1724  FD_SET(readsocket, &rfds);
1725  maxfd = MAX(maxfd, readsocket);
1726 
1727  if (crt_rfds < MAX_PORTS)
1728  rfds_list[crt_rfds++] = readsocket;
1729  else
1730  {
1731  fprintf(stderr, "The limit for the read file descriptors list was \
1732  reached\n");
1733  break;
1734  }
1735  }
1736  }
1737  else
1738  {
1740  ssize_t ret;
1741  fprintf(stderr, "LOG : %s reads something from the socket\n", dev.iface);//FIXME : debugging message
1743  ret =
1744  read_from_the_socket((void *)&i, (unsigned char *)&rrm->frame,
1745  sizeof(write_std.buf)
1747  + sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
1748  rrm);
1749  if (0 >= ret)
1750  {
1751  int j;
1752  FD_CLR(i, &rfds);
1753  close(i);
1754  /* Remove the socket from the list */
1755  for (j = 0; j < crt_rfds; j++)
1756  {
1757  if (rfds_list[j] == i)
1758  {
1759  rfds_list[j] ^= rfds_list[crt_rfds - 1];
1760  rfds_list[crt_rfds - 1] ^= rfds_list[j];
1761  rfds_list[j] ^= rfds_list[crt_rfds - 1];
1762  crt_rfds -= 1;
1763  break;
1764  }
1765  }
1766 
1767  fprintf(stderr, "Read error from raw socket: %s\n", strerror(errno));
1768  break;
1769  }
1770  if ((0 < ret) && (0 == mac_test(&rrm->frame, &dev)))
1771  {
1772  write_std.size = ret
1774  - sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
1775  rrm->header.size = htons(write_std.size);
1777  }
1778  }
1779  }
1780  }
1781  }
1782  }
1783  /* Error handling, try to clean up a bit at least */
1784  mst_destroy(stdin_mst);
1785  stdin_mst = NULL;
1786  sdp_close(dev.session);
1787  (void)close(dev.fd_rfcomm);
1788  if (-1 != sendsocket)
1789  (void)close(sendsocket);
1790 
1791  for (i = 0; i < crt_rfds; i++)
1792  (void)close(rfds_list[i]);
1793 
1794  for (i = 0; i < neighbours.size; i++)
1795  (void)close(neighbours.fds[i]);
1796  #else
1797  struct HardwareInfos dev;
1798  struct GNUNET_NETWORK_Handle *sendsocket;
1799  struct GNUNET_NETWORK_FDSet *rfds;
1800  struct GNUNET_NETWORK_FDSet *wfds;
1801  struct GNUNET_NETWORK_Handle *rfds_list[MAX_PORTS];
1802  char readbuf[MAXLINE] = { 0 };
1803  SOCKADDR_BTH acc_addr = { 0 };
1804  int addr_len = sizeof(SOCKADDR_BTH);
1805  int broadcast, i, stdin_open, crt_rfds = 0;
1806  HANDLE stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
1807  HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
1809 
1810  /* check the handles */
1811  if (stdin_handle == INVALID_HANDLE_VALUE)
1812  {
1813  fprintf(stderr, "Failed to get the stdin handle\n");
1814  ExitProcess(2);
1815  }
1816 
1817  if (stdout_handle == INVALID_HANDLE_VALUE)
1818  {
1819  fprintf(stderr, "Failed to get the stdout handle\n");
1820  ExitProcess(2);
1821  }
1822 
1823  /* initialize windows sockets */
1824  initialize_windows_sockets();
1825 
1826  // /* test bluetooth socket family support */ --> it return false because the GNUNET_NETWORK_test_pf should also receive the type of socket (BTHPROTO_RFCOMM)
1827  // if (GNUNET_NETWORK_test_pf (AF_BTH) != GNUNET_OK)
1828  // {
1829  // fprintf (stderr, "AF_BTH family is not supported\n");
1830  // ExitProcess (2);
1831  // }
1832 
1833  /* create the socket */
1834  dev.handle = GNUNET_NETWORK_socket_create(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
1835  if (dev.handle == NULL)
1836  {
1837  fprintf(stderr, "Failed to create RFCOMM socket: ");
1838  print_last_error();
1839  ExitProcess(2);
1840  }
1841 
1842 
1843  if (open_device(&dev) == -1)
1844  {
1845  fprintf(stderr, "Failed to open the device\n");
1846  print_last_error();
1847  if (GNUNET_NETWORK_socket_close(dev.handle) != GNUNET_OK)
1848  {
1849  fprintf(stderr, "Failed to close the socket!\n");
1850  print_last_error();
1851  }
1852  ExitProcess(2);
1853  }
1854 
1855  if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking(dev.handle, 1))
1856  {
1857  fprintf(stderr, "Failed to change the socket mode\n");
1858  ExitProcess(2);
1859  }
1860 
1861  memset(&write_std, 0, sizeof(write_std));
1862  memset(&write_pout, 0, sizeof(write_pout));
1863  stdin_open = 1;
1864 
1865  rfds = GNUNET_NETWORK_fdset_create();
1866  wfds = GNUNET_NETWORK_fdset_create();
1867 
1868  /* Send MAC address of the bluetooth interface to STDOUT first */
1869  {
1871 
1872  macmsg.hdr.size = htons(sizeof(macmsg));
1874  GNUNET_memcpy(&macmsg.mac, &dev.pl_mac, sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy));
1875  GNUNET_memcpy(write_std.buf, &macmsg, sizeof(macmsg));
1876  write_std.size = sizeof(macmsg);
1877  }
1878 
1879 
1880  stdin_mst = mst_create(&stdin_send_hw, &dev);
1881  stdin_open = 1;
1882 
1883  int pos = 0;
1884  int stdin_pos = -1;
1885  int stdout_pos = -1;
1886  while (1)
1887  {
1888  broadcast = 0;
1889  pos = 0;
1890  stdin_pos = -1;
1891  stdout_pos = -1;
1892  sendsocket = NULL; //FIXME ???memleaks
1893 
1895  if ((0 == write_pout.size) && (1 == stdin_open))
1896  {
1897  stdin_pos = pos;
1898  pos += 1;
1899  GNUNET_NETWORK_fdset_handle_set(rfds, (struct GNUNET_DISK_FileHandle*)&stdin_handle);
1900  }
1901 
1902  if (0 == write_std.size)
1903  {
1904  pos += 1;
1905  GNUNET_NETWORK_fdset_set(rfds, dev.handle);
1906  }
1907 
1908  for (i = 0; i < crt_rfds; i++)
1909  {
1910  pos += 1;
1911  GNUNET_NETWORK_fdset_set(rfds, rfds_list[i]);
1912  }
1913 
1915  if (0 < write_std.size)
1916  {
1917  stdout_pos = pos;
1918  GNUNET_NETWORK_fdset_handle_set(wfds, (struct GNUNET_DISK_FileHandle*)&stdout_handle);
1919  // printf ("%s\n", write_std.buf);
1920  // memset (write_std.buf, 0, write_std.size);
1921  // write_std.size = 0;
1922  }
1923 
1924  if (0 < write_pout.size)
1925  {
1926  if (strcmp(argv[1], "ff:ff:ff:ff:ff:ff") == 0)
1927  {
1928  fprintf(stderr, "LOG: BROADCAST! Skipping the message\n");
1929  // skip the message
1930  broadcast = 1;
1931  memset(write_pout.buf, 0, write_pout.size);
1932  write_pout.size = 0;
1933  }
1934  else
1935  {
1936  SOCKADDR_BTH addr;
1937  fprintf(stderr, "LOG : has a new message for %s\n", argv[1]);
1938  sendsocket = GNUNET_NETWORK_socket_create(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
1939 
1940  if (sendsocket == NULL)
1941  {
1942  fprintf(stderr, "Failed to create RFCOMM socket: \n");
1943  print_last_error();
1944  ExitProcess(2);
1945  }
1946 
1947  memset(&addr, 0, sizeof(addr));
1948  //addr.addressFamily = AF_BTH;
1949  if (SOCKET_ERROR ==
1950  WSAStringToAddress(argv[1], AF_BTH, NULL, (LPSOCKADDR)&addr, &addr_len))
1951  {
1952  fprintf(stderr, "Failed to translate the address: ");
1953  print_last_error();
1954  ExitProcess(2);
1955  }
1956  addr.port = get_channel(argv[1]);
1957  if (addr.port == -1)
1958  {
1959  fprintf(stderr, "Couldn't find the sdp service for the address: %s\n", argv[1]);
1960  memset(write_pout.buf, 0, write_pout.size);
1961  write_pout.size = 0;
1962  broadcast = 1; //skipping the select part
1963  }
1964  else
1965  {
1966  if (GNUNET_OK != GNUNET_NETWORK_socket_connect(sendsocket, (LPSOCKADDR)&addr, addr_len))
1967  {
1968  fprintf(stderr, "Failed to connect: ");
1969  print_last_error();
1970  ExitProcess(2);
1971  }
1972 
1973  if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking(sendsocket, 1))
1974  {
1975  fprintf(stderr, "Failed to change the socket mode\n");
1976  ExitProcess(2);
1977  }
1978 
1979  GNUNET_NETWORK_fdset_set(wfds, sendsocket);
1980  }
1981  }
1982  }
1983 
1984  if (broadcast == 0)
1985  {
1986  int retval = GNUNET_NETWORK_socket_select(rfds, wfds, NULL, GNUNET_TIME_relative_get_forever_());
1987  if (retval < 0)
1988  {
1989  fprintf(stderr, "Select error\n");
1990  ExitProcess(2);
1991  }
1992  //if (GNUNET_NETWORK_fdset_isset (wfds, (struct GNUNET_NETWORK_Handle*)&stdout_handle))
1993  if (retval == stdout_pos)
1994  {
1995  fprintf(stderr, "LOG : sends a message to STDOUT\n"); //FIXME: debugging message
1996  //ssize_t ret;
1997  //ret = GNUNET_NETWORK_socket_send ((struct GNUNET_NETWORK_Handle *)&stdout_handle, write_std.buf + write_std.pos, write_std.size - write_std.pos);
1998  //ret = write (STDOUT_FILENO, write_std.buf + write_std.pos, write_std.size - write_std.pos);
1999  DWORD ret;
2000  if (FALSE == WriteFile(stdout_handle, write_std.buf + write_std.pos, write_std.size - write_std.pos, &ret, NULL))
2001  {
2002  fprintf(stderr, "Failed to write to STDOUT: ");
2003  print_last_error();
2004  break;
2005  }
2006 
2007  if (ret <= 0)
2008  {
2009  fprintf(stderr, "Failed to write to STDOUT\n");
2010  ExitProcess(2);
2011  }
2012 
2013  write_std.pos += ret;
2014  if (write_std.pos == write_std.size)
2015  {
2016  write_std.pos = 0;
2017  write_std.size = 0;
2018  }
2019  }
2020  if (sendsocket != NULL)
2021  {
2022  if (GNUNET_NETWORK_fdset_isset(wfds, sendsocket))
2023  {
2024  ssize_t ret;
2027 
2028  if (GNUNET_SYSERR == ret)
2029  {
2030  fprintf(stderr, "Failed to send to the socket. Closing the socket. Error: \n");
2031  print_last_error();
2032  if (GNUNET_NETWORK_socket_close(sendsocket) != GNUNET_OK)
2033  {
2034  fprintf(stderr, "Failed to close the sendsocket!\n");
2035  print_last_error();
2036  }
2037  ExitProcess(2);
2038  }
2039  else
2040  {
2041  write_pout.pos += ret;
2042  if ((write_pout.pos != write_pout.size) && (0 != ret))
2043  {
2044  /* we should not get partial sends with packet-oriented devices... */
2045  fprintf(stderr, "Write error, partial send: %u/%u\n",
2046  (unsigned int)write_pout.pos,
2047  (unsigned int)write_pout.size);
2048  break;
2049  }
2050 
2051  if (write_pout.pos == write_pout.size)
2052  {
2053  write_pout.pos = 0;
2054  write_pout.size = 0;
2055  }
2056  fprintf(stderr, "LOG : sends a message to a DEVICE\n"); //FIXME: debugging message
2057  }
2058  }
2059  }
2060 
2061  //if (GNUNET_NETWORK_fdset_isset (rfds, (struct GNUNET_NETWORK_Handle*)&stdin_handle))
2062  if (retval == stdin_pos)
2063  {
2064  //ssize_t ret;
2065  //ret = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)&stdin_handle, readbuf, sizeof (write_pout.buf));
2066  //ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
2067  DWORD ret;
2068  if (FALSE == ReadFile(stdin_handle, readbuf, sizeof(readbuf), &ret, NULL)) /* do nothing asynchronous */
2069  {
2070  fprintf(stderr, "Read error from STDIN: ");
2071  print_last_error();
2072  break;
2073  }
2074  if (0 == ret)
2075  {
2076  /* stop reading... */
2077  stdin_open = 0;
2078  }
2079  else
2080  {
2081  mst_receive(stdin_mst, readbuf, ret);
2082  fprintf(stderr, "LOG : receives a message from STDIN\n"); //FIXME: debugging message
2083  }
2084  }
2085  else
2086  if (GNUNET_NETWORK_fdset_isset(rfds, dev.handle))
2087  {
2088  fprintf(stderr, "LOG: accepting connection\n");
2089  struct GNUNET_NETWORK_Handle *readsocket;
2090  readsocket = GNUNET_NETWORK_socket_accept(dev.handle, (LPSOCKADDR)&acc_addr, &addr_len);
2091  if (readsocket == NULL)
2092  {
2093  fprintf(stderr, "Accept error %d: ", GetLastError());
2094  print_last_error();
2095  ExitProcess(2);
2096  }
2097  else
2098  {
2099  if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking(readsocket, 1))
2100  {
2101  fprintf(stderr, "Failed to change the socket mode\n");
2102  ExitProcess(2);
2103  }
2104  GNUNET_NETWORK_fdset_set(rfds, readsocket);
2105 
2106  if (crt_rfds < MAX_PORTS)
2107  rfds_list[crt_rfds++] = readsocket;
2108  else
2109  {
2110  fprintf(stderr, "The limit for the read file descriptors list was reached\n");
2111  break;
2112  }
2113  }
2114  }
2115  else
2116  for (i = 0; i < crt_rfds; i++)
2117  {
2118  if (GNUNET_NETWORK_fdset_isset(rfds, rfds_list[i]))
2119  {
2121  ssize_t ret;
2122  fprintf(stderr, "LOG: reading something from the socket\n");//FIXME : debugging message
2124  ret = read_from_the_socket(rfds_list[i], (unsigned char *)&rrm->frame,
2125  sizeof(write_std.buf)
2127  + sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2128  rrm);
2129  if (0 >= ret)
2130  {
2131  //TODO remove the socket from the list
2132  if (GNUNET_NETWORK_socket_close(rfds_list[i]) != GNUNET_OK)
2133  {
2134  fprintf(stderr, "Failed to close the sendsocket!\n");
2135  print_last_error();
2136  }
2137 
2138  fprintf(stderr, "Read error from raw socket: ");
2139  print_last_error();
2140  break;
2141  }
2142  if ((0 < ret) && (0 == mac_test(&rrm->frame, &dev)))
2143  {
2144  write_std.size = ret
2146  - sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2147  rrm->header.size = htons(write_std.size);
2148  rrm->header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2149  }
2150  break;
2151  }
2152  }
2153  }
2154  }
2155 
2156  mst_destroy(stdin_mst);
2157  stdin_mst = NULL;
2158 
2159  if (GNUNET_NETWORK_socket_close(dev.handle) != GNUNET_OK)
2160  {
2161  fprintf(stderr, "Failed to close the socket!\n");
2162  print_last_error();
2163  }
2164 
2165  for (i = 0; i < crt_rfds; i++)
2166  {
2167  if (GNUNET_NETWORK_socket_close(rfds_list[i]) != GNUNET_OK)
2168  {
2169  fprintf(stderr, "Failed to close the socket!\n");
2170  print_last_error();
2171  }
2172  }
2173 
2174  WSACleanup();
2175  #endif
2176  return 1; /* we never exit 'normally' */
2177 }
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:247
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:804
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:480
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.
#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 int ret
Final status code.
Definition: gnunet-arm.c:89
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:420
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:1238
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:646
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:1328
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:66
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:985
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:1159
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:999
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:46
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:1017
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:548
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:900