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