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 #ifdef MINGW
25  #include "platform.h"
26  #include "gnunet_util_lib.h"
27  #include <bthdef.h>
28  #include <ws2bth.h>
29 #else
30  #define SOCKTYPE int
31  #include <bluetooth/bluetooth.h>
32  #include <bluetooth/hci.h>
33  #include <bluetooth/hci_lib.h>
34  #include <bluetooth/rfcomm.h>
35  #include <bluetooth/sdp.h>
36  #include <bluetooth/sdp_lib.h>
37  #include <errno.h>
38  #include <linux/if.h>
39  #include <stdio.h>
40  #include <stdlib.h>
41  #include <sys/ioctl.h>
42  #include <sys/param.h>
43  #include <sys/socket.h>
44  #include <sys/stat.h>
45  #include <sys/types.h>
46  #include <unistd.h>
47 #endif
48 
49 #include "plugin_transport_wlan.h"
50 #include "gnunet_protocols.h"
51 
52 
56 #define MAX_PORTS 30
57 
62 #define MAXLINE 4096
63 
64 
68 #define MAX_LOOPS 5
69 
70 #ifdef MINGW
71  /* Maximum size of the interface's name */
72  #define IFNAMSIZ 16
73 
74  #ifndef NS_BTH
75  #define NS_BTH 16
76  #endif
77 
80  struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy
81  {
82  UINT8 mac[MAC_ADDR_SIZE];
83  };
84 
89  #define GNUNET_BLUETOOTH_SDP_UUID \
90  { \
91  0x31, 0x19, 0x1E, 0x56, \
92  0xFA, 0x7E, \
93  0x45, 0x17, \
94  0x87, 0x0E, \
95  0x71, 0xB8, 0x6B, 0xBC, 0xC5, 0x2F \
96  }
97 #endif
98 
102 #define BLUEZ_DEVNAME_SIZE 8
103 
109 {
113  char iface[IFNAMSIZ];
114 
115  #ifdef MINGW
116 
120 
124  struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy pl_mac;
125  #else
126 
130 
135 
139  sdp_session_t *session ;
140  #endif
141 };
142 
147 {
152  size_t size;
153 
158  size_t pos;
159 
164  char buf[MAXLINE * 2];
165 };
166 
167 #ifdef LINUX
168 
172  struct BroadcastMessages
173  {
174  /* List with the discoverable devices' addresses */
175  bdaddr_t devices[MAX_PORTS];
176 
177  /* List with the open sockets */
178  int fds[MAX_PORTS];
179 
180 
181  /* The number of the devices */
182  int size;
183 
184  /* The current position */
185  int pos;
186 
187  /* The device id */
188  int dev_id;
189  };
190 
194  static struct GNUNET_TRANSPORT_WLAN_MacAddress broadcast_address = {{255, 255, 255, 255, 255, 255}};
195 
199  static struct BroadcastMessages neighbours;
200 
201  static int searching_devices_count = 0;
202 #endif
203 
207 static struct SendBuffer write_pout;
208 
212 static struct SendBuffer write_std;
213 
214 
215 /* ****** this are the same functions as the ones used in gnunet-helper-transport-wlan.c ****** */
216 
221 #define ALIGN_FACTOR 8
222 
226 #define MIN_BUFFER_SIZE sizeof (struct GNUNET_MessageHeader)
227 
228 
236 typedef void (*MessageTokenizerCallback) (void *cls,
237  const struct
239  message);
240 
245 {
246 
251 
255  void *cb_cls;
256 
260  size_t curr_buf;
261 
265  size_t off;
266 
270  size_t pos;
271 
276 
277 };
278 
279 
287 static struct MessageStreamTokenizer *
289  void *cb_cls)
290 {
291  struct MessageStreamTokenizer *ret;
292 
293  ret = malloc (sizeof (struct MessageStreamTokenizer));
294  if (NULL == ret)
295  {
296  fprintf (stderr, "Failed to allocate buffer for tokenizer\n");
297  exit (1);
298  }
299  ret->hdr = malloc (MIN_BUFFER_SIZE);
300  if (NULL == ret->hdr)
301  {
302  fprintf (stderr, "Failed to allocate buffer for alignment\n");
303  exit (1);
304  }
305  ret->curr_buf = MIN_BUFFER_SIZE;
306  ret->cb = cb;
307  ret->cb_cls = cb_cls;
308  ret->pos = 0;
309 
310  return ret;
311 }
312 
313 
324 static int
326  const char *buf, size_t size)
327 {
328  const struct GNUNET_MessageHeader *hdr;
329  size_t delta;
330  uint16_t want;
331  char *ibuf;
332  int need_align;
333  unsigned long offset;
334  int ret;
335 
336  ret = GNUNET_OK;
337  ibuf = (char *) mst->hdr;
338  while (mst->pos > 0)
339  {
340 do_align:
341  if (mst->pos < mst->off)
342  {
343  //fprintf (stderr, "We processed too many bytes!\n");
344  return GNUNET_SYSERR;
345  }
346  if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) ||
347  (0 != (mst->off % ALIGN_FACTOR)))
348  {
349  /* need to align or need more space */
350  mst->pos -= mst->off;
351  memmove (ibuf, &ibuf[mst->off], mst->pos);
352  mst->off = 0;
353  }
354  if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
355  {
356  delta =
357  GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) -
358  (mst->pos - mst->off), size);
359  GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
360  mst->pos += delta;
361  buf += delta;
362  size -= delta;
363  }
364  if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
365  {
366  //FIXME should I reset ??
367  // mst->off = 0;
368  // mst->pos = 0;
369  return GNUNET_OK;
370  }
371  hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
372  want = ntohs (hdr->size);
373  if (want < sizeof (struct GNUNET_MessageHeader))
374  {
375  fprintf (stderr,
376  "Received invalid message from stdin\n");
377  return GNUNET_SYSERR;
378  }
379  if ((mst->curr_buf - mst->off < want) &&
380  (mst->off > 0))
381  {
382  /* need more space */
383  mst->pos -= mst->off;
384  memmove (ibuf, &ibuf[mst->off], mst->pos);
385  mst->off = 0;
386  }
387  if (want > mst->curr_buf)
388  {
389  if (mst->off != 0)
390  {
391  fprintf (stderr, "Error! We should proceeded 0 bytes\n");
392  return GNUNET_SYSERR;
393  }
394  mst->hdr = realloc (mst->hdr, want);
395  if (NULL == mst->hdr)
396  {
397  fprintf (stderr, "Failed to allocate buffer for alignment\n");
398  exit (1);
399  }
400  ibuf = (char *) mst->hdr;
401  mst->curr_buf = want;
402  }
403  hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
404  if (mst->pos - mst->off < want)
405  {
406  delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
407  if (mst->pos + delta > mst->curr_buf)
408  {
409  fprintf (stderr, "The size of the buffer will be exceeded!\n");
410  return GNUNET_SYSERR;
411  }
412  GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
413  mst->pos += delta;
414  buf += delta;
415  size -= delta;
416  }
417  if (mst->pos - mst->off < want)
418  {
419  //FIXME should I use this?
420  // mst->off = 0;
421  // mst->pos = 0;
422  return GNUNET_OK;
423  }
424  mst->cb (mst->cb_cls, hdr);
425  mst->off += want;
426  if (mst->off == mst->pos)
427  {
428  /* reset to beginning of buffer, it's free right now! */
429  mst->off = 0;
430  mst->pos = 0;
431  }
432  }
433  if (0 != mst->pos)
434  {
435  fprintf (stderr, "There should some valid bytes in the buffer on this stage\n");
436  return GNUNET_SYSERR;
437  }
438  while (size > 0)
439  {
440  if (size < sizeof (struct GNUNET_MessageHeader))
441  break;
442  offset = (unsigned long) buf;
443  need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
444  if (GNUNET_NO == need_align)
445  {
446  /* can try to do zero-copy and process directly from original buffer */
447  hdr = (const struct GNUNET_MessageHeader *) buf;
448  want = ntohs (hdr->size);
449  if (want < sizeof (struct GNUNET_MessageHeader))
450  {
451  fprintf (stderr,
452  "Received invalid message from stdin\n");
453  //exit (1);
454  mst->off = 0;
455  return GNUNET_SYSERR;
456  }
457  if (size < want)
458  break; /* or not, buffer incomplete, so copy to private buffer... */
459  mst->cb (mst->cb_cls, hdr);
460  buf += want;
461  size -= want;
462  }
463  else
464  {
465  /* need to copy to private buffer to align;
466  * yes, we go a bit more spagetti than usual here */
467  goto do_align;
468  }
469  }
470  if (size > 0)
471  {
472  if (size + mst->pos > mst->curr_buf)
473  {
474  mst->hdr = realloc (mst->hdr, size + mst->pos);
475  if (NULL == mst->hdr)
476  {
477  fprintf (stderr, "Failed to allocate buffer for alignment\n");
478  exit (1);
479  }
480  ibuf = (char *) mst->hdr;
481  mst->curr_buf = size + mst->pos;
482  }
483  if (mst->pos + size > mst->curr_buf)
484  {
485  fprintf (stderr,
486  "Assertion failed\n");
487  exit (1);
488  }
489  GNUNET_memcpy (&ibuf[mst->pos], buf, size);
490  mst->pos += size;
491  }
492  return ret;
493 }
494 
500 static void
502 {
503  free (mst->hdr);
504  free (mst);
505 }
506 
514 static unsigned long
515 calc_crc_osdep (const unsigned char *buf, size_t len)
516 {
517  static const unsigned long int crc_tbl_osdep[256] = {
518  0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
519  0xE963A535, 0x9E6495A3,
520  0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
521  0xE7B82D07, 0x90BF1D91,
522  0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
523  0xF4D4B551, 0x83D385C7,
524  0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
525  0xFA0F3D63, 0x8D080DF5,
526  0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
527  0xD20D85FD, 0xA50AB56B,
528  0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
529  0xDCD60DCF, 0xABD13D59,
530  0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
531  0xCFBA9599, 0xB8BDA50F,
532  0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
533  0xC1611DAB, 0xB6662D3D,
534  0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
535  0x9FBFE4A5, 0xE8B8D433,
536  0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
537  0x91646C97, 0xE6635C01,
538  0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
539  0x8208F4C1, 0xF50FC457,
540  0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
541  0x8CD37CF3, 0xFBD44C65,
542  0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
543  0xA4D1C46D, 0xD3D6F4FB,
544  0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
545  0xAA0A4C5F, 0xDD0D7CC9,
546  0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
547  0xB966D409, 0xCE61E49F,
548  0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
549  0xB7BD5C3B, 0xC0BA6CAD,
550  0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
551  0x04DB2615, 0x73DC1683,
552  0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
553  0x0A00AE27, 0x7D079EB1,
554  0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
555  0x196C3671, 0x6E6B06E7,
556  0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
557  0x17B7BE43, 0x60B08ED5,
558  0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
559  0x3FB506DD, 0x48B2364B,
560  0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
561  0x316E8EEF, 0x4669BE79,
562  0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
563  0x220216B9, 0x5505262F,
564  0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
565  0x2CD99E8B, 0x5BDEAE1D,
566  0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
567  0x72076785, 0x05005713,
568  0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
569  0x7CDCEFB7, 0x0BDBDF21,
570  0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
571  0x6FB077E1, 0x18B74777,
572  0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
573  0x616BFFD3, 0x166CCF45,
574  0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
575  0x4969474D, 0x3E6E77DB,
576  0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
577  0x47B2CF7F, 0x30B5FFE9,
578  0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
579  0x54DE5729, 0x23D967BF,
580  0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
581  0x5A05DF1B, 0x2D02EF8D
582  };
583 
584  unsigned long crc = 0xFFFFFFFF;
585 
586  for (; len > 0; len--, buf++)
587  crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
588  return (~crc);
589 }
590 
591 
600 static int
601 check_crc_buf_osdep (const unsigned char *buf, size_t len)
602 {
603  unsigned long crc;
604 
605  crc = calc_crc_osdep (buf, len);
606  buf += len;
607  if (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
608  ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3])
609  return 0;
610  return 1;
611 }
612 
613 
614 
615 /* ************** end of clone ***************** */
616 
617 #ifdef MINGW
618 
621  static void
622  print_last_error()
623  {
624  LPVOID lpMsgBuf = NULL;
625 
626  if (FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
627  NULL, GetLastError(), 0, (LPTSTR) &lpMsgBuf, 0, NULL))
628  fprintf (stderr, "%s\n", (char *)lpMsgBuf);
629  else
630  fprintf (stderr, "Failed to format the message for the last error! Error number : %d\n", GetLastError());
631  }
632 
636  static void
637  initialize_windows_sockets()
638  {
639  WSADATA wsaData ;
640  WORD wVersionRequested = MAKEWORD (2, 0);
641  if (WSAStartup (wVersionRequested, &wsaData) != NO_ERROR)
642  {
643  fprintf (stderr , "Error initializing window sockets!\n");
644  print_last_error();
645  ExitProcess (2) ;
646  }
647  }
648 
654  static void
655  convert_guid(char *bytes, GUID * uuid)
656  {
657  int i;
658  uuid->Data1 = ((bytes[0] << 24) & 0xff000000) | ((bytes[1] << 16) & 0x00ff0000) | ((bytes[2] << 8) & 0x0000ff00) | (bytes[3] & 0x000000ff);
659  uuid->Data2 = ((bytes[4] << 8) & 0xff00) | (bytes[5] & 0x00ff);
660  uuid->Data3 = ((bytes[6] << 8) & 0xff00) | (bytes[7] & 0x00ff);
661 
662  for (i = 0; i < 8; i++)
663  {
664  uuid->Data4[i] = bytes[i + 8];
665  }
666  }
667 #endif
668 
669 #ifdef LINUX
670 
677  static int
678  bind_socket (int socket, struct sockaddr_rc *addr)
679  {
680  int port, status;
681 
682  /* Bind every possible port (from 0 to 30) and stop when binding doesn't fail */
683  //FIXME : it should start from port 1, but on my computer it doesn't work :)
684  for (port = 3; port <= 30; port++)
685  {
686  addr->rc_channel = port;
687  status = bind (socket, (struct sockaddr *) addr, sizeof (struct sockaddr_rc));
688  if (status == 0)
689  return 0;
690  }
691 
692  return -1;
693  }
694 #endif
695 
696 #ifdef MINGW
697 
703  static int
704  register_service (struct HardwareInfos *dev)
705  {
706  /* advertise the service */
707  CSADDR_INFO addr_info;
708  WSAQUERYSET wqs;
709  GUID guid;
710  unsigned char uuid[] = GNUNET_BLUETOOTH_SDP_UUID;
711  SOCKADDR_BTH addr;
712  int addr_len = sizeof (SOCKADDR_BTH);
713  int fd;
714  /* get the port on which we are listening on */
715  memset (& addr, 0, sizeof (SOCKADDR_BTH));
716  fd = GNUNET_NETWORK_get_fd (dev->handle);
717  if (fd <= 0)
718  {
719  fprintf (stderr, "Failed to get the file descriptor\n");
720  return -1;
721  }
722  if (SOCKET_ERROR == getsockname (fd, (SOCKADDR*)&addr, &addr_len))
723  {
724  fprintf (stderr, "Failed to get the port on which we are listening on: \n");
725  print_last_error();
726  return -1;
727  }
728 
729  /* save the device address */
730  GNUNET_memcpy (&dev->pl_mac, &addr.btAddr, sizeof (BTH_ADDR));
731 
732  /* set the address information */
733  memset (&addr_info, 0, sizeof (CSADDR_INFO));
734  addr_info.iProtocol = BTHPROTO_RFCOMM;
735  addr_info.iSocketType = SOCK_STREAM;
736  addr_info.LocalAddr.lpSockaddr = (LPSOCKADDR)&addr;
737  addr_info.LocalAddr.iSockaddrLength = sizeof (addr);
738  addr_info.RemoteAddr.lpSockaddr = (LPSOCKADDR)&addr;
739  addr_info.RemoteAddr.iSockaddrLength = sizeof (addr);
740 
741  convert_guid((char *) uuid, &guid);
742 
743  /* register the service */
744  memset (&wqs, 0, sizeof (WSAQUERYSET));
745  wqs.dwSize = sizeof (WSAQUERYSET);
746  wqs.dwNameSpace = NS_BTH;
747  wqs.lpszServiceInstanceName = "GNUnet Bluetooth Service";
748  wqs.lpszComment = "This is the service used by the GNUnnet plugin transport";
749  wqs.lpServiceClassId = &guid;
750  wqs.dwNumberOfCsAddrs = 1;
751  wqs.lpcsaBuffer = &addr_info ;
752  wqs.lpBlob = 0;
753 
754  if (SOCKET_ERROR == WSASetService (&wqs , RNRSERVICE_REGISTER, 0))
755  {
756  fprintf (stderr, "Failed to register the SDP service: ");
757  print_last_error();
758  return -1;
759  }
760  else
761  {
762  fprintf (stderr, "The SDP service was registered\n");
763  }
764 
765  return 0;
766  }
767 #else
768 
775  static int
776  register_service (struct HardwareInfos *dev, int rc_channel)
777  {
787  uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
788  dev->pl_mac.mac[5], dev->pl_mac.mac[4], dev->pl_mac.mac[3],
789  dev->pl_mac.mac[2], dev->pl_mac.mac[1], dev->pl_mac.mac[0]};
790  const char *service_dsc = "Bluetooth plugin services";
791  const char *service_prov = "GNUnet provider";
792  uuid_t root_uuid, rfcomm_uuid, svc_uuid;
793  sdp_list_t *root_list = 0, *rfcomm_list = 0, *proto_list = 0,
794  *access_proto_list = 0, *svc_list = 0;
795  sdp_record_t *record = 0;
796  sdp_data_t *channel = 0;
797 
798  record = sdp_record_alloc();
799 
800  /* Set the general service ID */
801  sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
802  svc_list = sdp_list_append (0, &svc_uuid);
803  sdp_set_service_classes (record, svc_list);
804  sdp_set_service_id (record, svc_uuid);
805 
806  /* Make the service record publicly browsable */
807  sdp_uuid16_create (&root_uuid, PUBLIC_BROWSE_GROUP);
808  root_list = sdp_list_append (0, &root_uuid);
809  sdp_set_browse_groups (record, root_list);
810 
811  /* Register the RFCOMM channel */
812  sdp_uuid16_create (&rfcomm_uuid, RFCOMM_UUID);
813  channel = sdp_data_alloc (SDP_UINT8, &rc_channel);
814  rfcomm_list = sdp_list_append (0, &rfcomm_uuid);
815  sdp_list_append (rfcomm_list, channel);
816  proto_list = sdp_list_append (0, rfcomm_list);
817 
818  /* Set protocol information */
819  access_proto_list = sdp_list_append (0, proto_list);
820  sdp_set_access_protos (record, access_proto_list);
821 
822  /* Set the name, provider, and description */
823  sdp_set_info_attr (record, dev->iface, service_prov, service_dsc);
824 
825  /* Connect to the local SDP server */
826  dev->session = sdp_connect (BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
827 
828  if (!dev->session)
829  {
830  fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
831  IFNAMSIZ, dev->iface, strerror (errno));
832  //FIXME exit?
833  return 1;
834  }
835 
836  /* Register the service record */
837  if (sdp_record_register (dev->session, record, 0) < 0)
838  {
839  fprintf (stderr, "Failed to register a service record on interface `%.*s': %s\n",
840  IFNAMSIZ, dev->iface, strerror (errno));
841  //FIXME exit?
842  return 1;
843  }
844 
845  /* Cleanup */
846  sdp_data_free (channel);
847  sdp_list_free (root_list, 0);
848  sdp_list_free (rfcomm_list, 0);
849  sdp_list_free (proto_list, 0);
850  sdp_list_free (access_proto_list, 0);
851  sdp_list_free (svc_list, 0);
852  sdp_record_free (record);
853 
854  return 0;
855  }
856 #endif
857 
858 #ifdef MINGW
859 
866  static int
867  get_channel(const char *dest)
868  {
869  HANDLE h;
870  WSAQUERYSET *wqs;
871  DWORD wqs_len = sizeof (WSAQUERYSET);
872  int done = 0;
873  int channel = -1;
874  GUID guid;
875  unsigned char uuid[] = GNUNET_BLUETOOTH_SDP_UUID;
876  convert_guid ((char *) uuid, &guid);
877 
878  wqs = (WSAQUERYSET*)malloc (wqs_len);
879  ZeroMemory (wqs, wqs_len);
880 
881  wqs->dwSize = sizeof (WSAQUERYSET) ;
882  wqs->lpServiceClassId = &guid;
883  wqs->dwNameSpace = NS_BTH;
884  wqs->dwNumberOfCsAddrs = 0;
885  wqs->lpszContext = (LPSTR)dest;
886 
887  if (SOCKET_ERROR == WSALookupServiceBegin (wqs, LUP_FLUSHCACHE | LUP_RETURN_ALL, &h))
888  {
889  if (GetLastError() == WSASERVICE_NOT_FOUND)
890  {
891  fprintf (stderr, "WARNING! The device with address %s wasn't found. Skipping the message!", dest);
892  return -1;
893  }
894  else
895  {
896  fprintf (stderr, "Failed to find the port number: ");
897  print_last_error();
898  ExitProcess (2);
899  return -1;
900  }
901  }
902 
903  /* search the sdp service */
904  while (!done)
905  {
906  if (SOCKET_ERROR == WSALookupServiceNext (h, LUP_FLUSHCACHE | LUP_RETURN_ALL, &wqs_len, wqs))
907  {
908  int error = WSAGetLastError();
909 
910  switch (error)
911  {
912  case WSAEFAULT:
913  free (wqs);
914  wqs = (WSAQUERYSET*)malloc (wqs_len);
915  break;
916  case WSANO_DATA:
917  fprintf (stderr, "Failed! The address was valid but there was no data record of requested type\n");
918  done = 1;
919  break;
920  case WSA_E_NO_MORE:
921  done = 1;
922  break;
923  default:
924  fprintf (stderr, "Failed to look over the services: ");
925  print_last_error();
926  WSALookupServiceEnd (h);
927  ExitProcess (2);
928  }
929  }
930  else
931  {
932  channel = ((SOCKADDR_BTH*)wqs->lpcsaBuffer->RemoteAddr.lpSockaddr)->port;
933  }
934  }
935 
936  free (wqs) ;
937  WSALookupServiceEnd (h);
938 
939  return channel;
940  }
941 #else
942 
950  static int
951  get_channel(struct HardwareInfos *dev, bdaddr_t dest)
952  {
961  uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
962  dest.b[5], dest.b[4], dest.b[3],
963  dest.b[2], dest.b[1], dest.b[0]};
964  sdp_session_t *session = 0;
965  sdp_list_t *search_list = 0, *attrid_list = 0, *response_list = 0, *it = 0;
966  uuid_t svc_uuid;
967  uint32_t range = 0x0000ffff;
968  int channel = -1;
969 
970  /* Connect to the local SDP server */
971  session = sdp_connect (BDADDR_ANY, &dest, 0);
972  if (!session)
973  {
974  fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
975  IFNAMSIZ, dev->iface, strerror (errno));
976  return -1;
977  }
978 
979  sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
980  search_list = sdp_list_append (0, &svc_uuid);
981  attrid_list = sdp_list_append (0, &range);
982 
983  if (sdp_service_search_attr_req (session, search_list,
984  SDP_ATTR_REQ_RANGE, attrid_list, &response_list) == 0)
985  {
986  for (it = response_list; it; it = it->next)
987  {
988  sdp_record_t *record = (sdp_record_t*) it->data;
989  sdp_list_t *proto_list = 0;
990  if (sdp_get_access_protos (record, &proto_list) == 0)
991  {
992  channel = sdp_get_proto_port (proto_list, RFCOMM_UUID);
993  sdp_list_free (proto_list, 0);
994  }
995  sdp_record_free (record);
996  }
997  }
998 
999  sdp_list_free (search_list, 0);
1000  sdp_list_free (attrid_list, 0);
1001  sdp_list_free (response_list, 0);
1002 
1003  sdp_close (session);
1004 
1005  if (-1 == channel)
1006  fprintf (stderr,
1007  "Failed to find the listening channel for interface `%.*s': %s\n",
1008  IFNAMSIZ,
1009  dev->iface,
1010  strerror (errno));
1011 
1012  return channel;
1013  }
1014 #endif
1015 
1026 static ssize_t
1028  unsigned char *buf, size_t buf_size,
1030 {
1031  unsigned char tmpbuf[buf_size];
1032  ssize_t count;
1033 
1034  #ifdef MINGW
1035  count = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)sock, tmpbuf, buf_size);
1036  #else
1037  count = read (*((int *)sock), tmpbuf, buf_size);
1038  #endif
1039 
1040  if (0 > count)
1041  {
1042  if (EAGAIN == errno)
1043  return 0;
1044  #if MINGW
1045  print_last_error();
1046  #else
1047  fprintf (stderr, "Failed to read from the HCI socket: %s\n", strerror (errno));
1048  #endif
1049 
1050  return -1;
1051  }
1052 
1053  #ifdef LINUX
1054  /* Get the channel used */
1055  int len;
1056  struct sockaddr_rc rc_addr = { 0 };
1057 
1058  memset (&rc_addr, 0, sizeof (rc_addr));
1059  len = sizeof (rc_addr);
1060  if (0 > getsockname (*((int *)sock), (struct sockaddr *) &rc_addr, (socklen_t *) &len))
1061  {
1062  fprintf (stderr, "getsockname() call failed : %s\n", strerror (errno));
1063  return -1;
1064  }
1065 
1066  memset (ri, 0, sizeof (*ri));
1067  ri->ri_channel = rc_addr.rc_channel;
1068  #endif
1069 
1070  /* Detect CRC32 at the end */
1071  if (0 == check_crc_buf_osdep (tmpbuf, count - sizeof (uint32_t)))
1072  {
1073  count -= sizeof(uint32_t);
1074  }
1075 
1076  GNUNET_memcpy (buf, tmpbuf, count);
1077 
1078  return count;
1079 }
1080 
1081 
1088 static int
1090 {
1091  #ifdef MINGW
1092  SOCKADDR_BTH addr;
1093 
1094  /* bind the RFCOMM socket to the interface */
1095  addr.addressFamily = AF_BTH;
1096  addr.btAddr = 0;
1097  addr.port = BT_PORT_ANY;
1098 
1099  if (GNUNET_OK !=
1100  GNUNET_NETWORK_socket_bind (dev->handle, (const SOCKADDR*)&addr, sizeof (SOCKADDR_BTH)))
1101  {
1102  fprintf (stderr, "Failed to bind the socket: ");
1103  if (GetLastError() == WSAENETDOWN)
1104  {
1105  fprintf (stderr, "Please make sure that your Bluetooth device is ON!\n");
1106  ExitProcess (2);
1107  }
1108  print_last_error();
1109  return -1;
1110  }
1111 
1112  /* start listening on the socket */
1113  if (GNUNET_NETWORK_socket_listen (dev->handle, 4) != GNUNET_OK)
1114  {
1115  fprintf (stderr, "Failed to listen on the socket: ");
1116  print_last_error();
1117  return -1;
1118  }
1119 
1120  /* register the sdp service */
1121  if (register_service(dev) != 0)
1122  {
1123  fprintf (stderr, "Failed to register a service: ");
1124  print_last_error();
1125  return 1;
1126  }
1127  #else
1128  int i, dev_id = -1, fd_hci;
1129  struct
1130  {
1131  struct hci_dev_list_req list;
1132  struct hci_dev_req dev[HCI_MAX_DEV];
1133  } request; //used for detecting the local devices
1134  struct sockaddr_rc rc_addr = { 0 }; //used for binding
1135 
1136  /* Initialize the neighbour structure */
1137  neighbours.dev_id = -1;
1138  for (i = 0; i < MAX_PORTS; i++)
1139  neighbours.fds[i] = -1;
1140 
1141  /* Open a HCI socket */
1142  fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
1143 
1144  if (fd_hci < 0)
1145  {
1146  fprintf (stderr,
1147  "Failed to create HCI socket: %s\n",
1148  strerror (errno));
1149  return -1;
1150  }
1151 
1152  memset (&request, 0, sizeof(request));
1153  request.list.dev_num = HCI_MAX_DEV;
1154 
1155  if (ioctl (fd_hci, HCIGETDEVLIST, (void *) &request) < 0)
1156  {
1157  fprintf (stderr,
1158  "ioctl(HCIGETDEVLIST) on interface `%.*s' failed: %s\n",
1159  IFNAMSIZ,
1160  dev->iface,
1161  strerror (errno));
1162  (void) close (fd_hci);
1163  return 1;
1164  }
1165 
1166  /* Search for a device with dev->iface name */
1167  for (i = 0; i < request.list.dev_num; i++)
1168  {
1169  struct hci_dev_info dev_info;
1170 
1171  memset (&dev_info, 0, sizeof(struct hci_dev_info));
1172  dev_info.dev_id = request.dev[i].dev_id;
1173  strncpy (dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE);
1174 
1175  if (ioctl (fd_hci, HCIGETDEVINFO, (void *) &dev_info))
1176  {
1177  fprintf (stderr,
1178  "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n",
1179  IFNAMSIZ,
1180  dev->iface,
1181  strerror (errno));
1182  (void) close (fd_hci);
1183  return 1;
1184  }
1185 
1186  if (strncmp (dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE) == 0)
1187  {
1188 
1189  dev_id = dev_info.dev_id; //the device was found
1193  GNUNET_memcpy (&dev->pl_mac, &dev_info.bdaddr, sizeof (bdaddr_t));
1194 
1195  /* Check if the interface is up */
1196  if (hci_test_bit (HCI_UP, (void *) &dev_info.flags) == 0)
1197  {
1198  /* Bring the interface up */
1199  if (ioctl (fd_hci, HCIDEVUP, dev_info.dev_id))
1200  {
1201  fprintf (stderr,
1202  "ioctl(HCIDEVUP) on interface `%.*s' failed: %s\n",
1203  IFNAMSIZ,
1204  dev->iface,
1205  strerror (errno));
1206  (void) close (fd_hci);
1207  return 1;
1208  }
1209  }
1210 
1211  /* Check if the device is discoverable */
1212  if (hci_test_bit (HCI_PSCAN, (void *) &dev_info.flags) == 0 ||
1213  hci_test_bit (HCI_ISCAN, (void *) &dev_info.flags) == 0)
1214  {
1215  /* Set interface Page Scan and Inqury Scan ON */
1216  struct hci_dev_req dev_req;
1217 
1218  memset (&dev_req, 0, sizeof (dev_req));
1219  dev_req.dev_id = dev_info.dev_id;
1220  dev_req.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
1221 
1222  if (ioctl (fd_hci, HCISETSCAN, (unsigned long) &dev_req))
1223  {
1224  fprintf (stderr,
1225  "ioctl(HCISETSCAN) on interface `%.*s' failed: %s\n",
1226  IFNAMSIZ,
1227  dev->iface,
1228  strerror (errno));
1229  (void) close (fd_hci);
1230  return 1;
1231  }
1232 
1233  }
1234  break;
1235  }
1236 
1237  }
1238 
1239  /* Check if the interface was not found */
1240  if (-1 == dev_id)
1241  {
1242  fprintf (stderr,
1243  "The interface %s was not found\n",
1244  dev->iface);
1245  (void) close (fd_hci);
1246  return 1;
1247  }
1248 
1249  /* Close the hci socket */
1250  (void) close(fd_hci);
1251 
1252 
1253 
1254  /* Bind the rfcomm socket to the interface */
1255  memset (&rc_addr, 0, sizeof (rc_addr));
1256  rc_addr.rc_family = AF_BLUETOOTH;
1257  rc_addr.rc_bdaddr = *BDADDR_ANY;
1258 
1259  if (bind_socket (dev->fd_rfcomm, &rc_addr) != 0)
1260  {
1261  fprintf (stderr,
1262  "Failed to bind interface `%.*s': %s\n",
1263  IFNAMSIZ,
1264  dev->iface,
1265  strerror (errno));
1266  return 1;
1267  }
1268 
1269  /* Register a SDP service */
1270  if (register_service (dev, rc_addr.rc_channel) != 0)
1271  {
1272  fprintf (stderr,
1273  "Failed to register a service on interface `%.*s': %s\n",
1274  IFNAMSIZ,
1275  dev->iface, strerror (errno));
1276  return 1;
1277  }
1278 
1279  /* Switch socket in listening mode */
1280  if (listen (dev->fd_rfcomm, 5) == -1) //FIXME: probably we need a bigger number
1281  {
1282  fprintf (stderr, "Failed to listen on socket for interface `%.*s': %s\n", IFNAMSIZ,
1283  dev->iface, strerror (errno));
1284  return 1;
1285  }
1286 
1287  #endif
1288 
1289  return 0;
1290 }
1291 
1292 
1301 static void
1303  const struct HardwareInfos *dev)
1304 {
1305  taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
1306  taIeeeHeader->addr3 = mac_bssid_gnunet;
1307 
1308  #ifdef MINGW
1309  GNUNET_memcpy (&taIeeeHeader->addr2, &dev->pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1310  #else
1311  taIeeeHeader->addr2 = dev->pl_mac;
1312  #endif
1313 }
1314 
1315 #ifdef LINUX
1316 
1324  static int
1325  test_bluetooth_interface (const char *iface)
1326  {
1327  char strbuf[512];
1328  struct stat sbuf;
1329  int ret;
1330 
1331  ret = snprintf (strbuf, sizeof (strbuf),
1332  "/sys/class/bluetooth/%s/subsystem",
1333  iface);
1334  if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
1335  {
1336  fprintf (stderr,
1337  "Did not find 802.15.1 interface `%s'. Exiting.\n",
1338  iface);
1339  exit (1);
1340  }
1341  return 0;
1342  }
1343 #endif
1344 
1354 static int
1356  const struct HardwareInfos *dev)
1357 {
1358  static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
1359 
1360  if ( (0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
1361  (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)) )
1362  return 0; /* some drivers set no Macs, then assume it is all for us! */
1363 
1364  if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1365  return 1; /* not a GNUnet ad-hoc package */
1366  if ( (0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
1367  (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)) )
1368  return 0; /* for us, or broadcast */
1369  return 1; /* not for us */
1370 }
1371 
1372 
1382 static void
1383 stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1384 {
1385  struct HardwareInfos *dev = cls;
1387  struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *blueheader;
1388  size_t sendsize;
1389 
1390  sendsize = ntohs (hdr->size);
1391  if ( (sendsize <
1392  sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
1393  (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) )
1394  {
1395  fprintf (stderr, "Received malformed message\n");
1396  exit (1);
1397  }
1398  sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) -
1399  sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1400  if (MAXLINE < sendsize)
1401  {
1402  fprintf (stderr, "Packet too big for buffer\n");
1403  exit (1);
1404  }
1405  header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
1406  GNUNET_memcpy (&write_pout.buf, &header->frame, sendsize);
1407  blueheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf;
1408 
1409  /* payload contains MAC address, but we don't trust it, so we'll
1410  * overwrite it with OUR MAC address to prevent mischief */
1411  mac_set (blueheader, dev);
1412  GNUNET_memcpy (&blueheader->addr1, &header->frame.addr1,
1413  sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1414  write_pout.size = sendsize;
1415 }
1416 
1417 #ifdef LINUX
1418 
1425  static int
1426  send_broadcast (struct HardwareInfos *dev, int *sendsocket)
1427  {
1428  int new_device = 0;
1429  int loops = 0;
1430 
1431  search_for_devices:
1432  if ((neighbours.size == neighbours.pos && new_device == 1) || neighbours.size == 0)
1433  {
1434  inquiry_devices: //skip the conditions and force a inquiry for new devices
1435  {
1440  inquiry_info *devices = NULL;
1441  int i, responses, max_responses = MAX_PORTS;
1442 
1443  /* sanity checks */
1444  if (neighbours.size >= MAX_PORTS)
1445  {
1446  fprintf (stderr, "%.*s reached the top limit for the discovarable devices\n", IFNAMSIZ, dev->iface);
1447  return 2;
1448  }
1449 
1450  /* Get the device id */
1451  if (neighbours.dev_id == -1)
1452  {
1453  char addr[19] = { 0 }; //the device MAC address
1454 
1455  ba2str ((bdaddr_t *) &dev->pl_mac, addr);
1456  neighbours.dev_id = hci_devid (addr);
1457  if (neighbours.dev_id < 0)
1458  {
1459  fprintf (stderr, "Failed to get the device id for interface %.*s : %s\n", IFNAMSIZ,
1460  dev->iface, strerror (errno));
1461  return 1;
1462  }
1463  }
1464 
1465  devices = malloc (max_responses * sizeof (inquiry_info));
1466  if (devices == NULL)
1467  {
1468  fprintf (stderr, "Failed to allocate memory for inquiry info list on interface %.*s\n", IFNAMSIZ,
1469  dev->iface);
1470  return 1;
1471  }
1472 
1473  responses = hci_inquiry (neighbours.dev_id, 8, max_responses, NULL, &devices, IREQ_CACHE_FLUSH);
1474  if (responses < 0)
1475  {
1476  fprintf (stderr, "Failed to inquiry on interface %.*s\n", IFNAMSIZ, dev->iface);
1477  return 1;
1478  }
1479 
1480  fprintf (stderr, "LOG : Found %d devices\n", responses); //FIXME delete it after debugging stage
1481 
1482  if (responses == 0)
1483  {
1484  fprintf (stderr, "LOG : No devices discoverable\n");
1485  return 1;
1486  }
1487 
1488  for (i = 0; i < responses; i++)
1489  {
1490  int j;
1491  int found = 0;
1492 
1493  /* sanity check */
1494  if (i >= MAX_PORTS)
1495  {
1496  fprintf (stderr, "%.*s reached the top limit for the discoverable devices (after inquiry)\n", IFNAMSIZ,
1497  dev->iface);
1498  return 2;
1499  }
1500 
1501  /* Search if the address already exists on the list */
1502  for (j = 0; j < neighbours.size; j++)
1503  {
1504  if (memcmp (&(devices + i)->bdaddr, &(neighbours.devices[j]), sizeof (bdaddr_t)) == 0)
1505  {
1506  found = 1;
1507  fprintf (stderr, "LOG : the device already exists on the list\n"); //FIXME debugging message
1508  break;
1509  }
1510  }
1511 
1512  if (found == 0)
1513  {
1514  char addr[19] = { 0 };
1515 
1516  ba2str (&(devices +i)->bdaddr, addr);
1517  fprintf (stderr, "LOG : %s was added to the list\n", addr); //FIXME debugging message
1518  GNUNET_memcpy (&(neighbours.devices[neighbours.size++]), &(devices + i)->bdaddr, sizeof (bdaddr_t));
1519  }
1520  }
1521 
1522  free (devices);
1523  }
1524  }
1525 
1526  int connection_successful = 0;
1527  struct sockaddr_rc addr_rc = { 0 };
1528  int errno_copy = 0;
1529  addr_rc.rc_family = AF_BLUETOOTH;
1530 
1531  /* Try to connect to a new device from the list */
1532  while (neighbours.pos < neighbours.size)
1533  {
1534  /* Check if we are already connected to this device */
1535  if (neighbours.fds[neighbours.pos] == -1)
1536  {
1537 
1538  memset (&addr_rc.rc_bdaddr, 0, sizeof (addr_rc.rc_bdaddr));
1539  GNUNET_memcpy (&addr_rc.rc_bdaddr, &(neighbours.devices[neighbours.pos]), sizeof (addr_rc.rc_bdaddr));
1540 
1541  addr_rc.rc_channel = get_channel (dev, addr_rc.rc_bdaddr);
1542 
1543  *sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1544  if ( (-1 < *sendsocket) &&
1545  (0 == connect (*sendsocket,
1546  (struct sockaddr *) &addr_rc,
1547  sizeof (addr_rc))) )
1548  {
1549  neighbours.fds[neighbours.pos++] = *sendsocket;
1550  connection_successful = 1;
1551  char addr[19] = { 0 };
1552  ba2str (&(neighbours.devices[neighbours.pos - 1]), addr);
1553  fprintf (stderr, "LOG : Connected to %s\n", addr);
1554  break;
1555  }
1556  else
1557  {
1558  char addr[19] = { 0 };
1559  errno_copy = errno; //Save a copy for later
1560 
1561  if (-1 != *sendsocket)
1562  {
1563  (void) close (*sendsocket);
1564  *sendsocket = -1;
1565  }
1566  ba2str (&(neighbours.devices[neighbours.pos]), addr);
1567  fprintf (stderr,
1568  "LOG : Couldn't connect on device %s, error : %s\n",
1569  addr,
1570  strerror (errno));
1571  if (errno != ECONNREFUSED) //FIXME be sure that this works
1572  {
1573  fprintf (stderr, "LOG : Removes %d device from the list\n", neighbours.pos);
1574  /* Remove the device from the list */
1575  GNUNET_memcpy (&neighbours.devices[neighbours.pos], &neighbours.devices[neighbours.size - 1], sizeof (bdaddr_t));
1576  memset (&neighbours.devices[neighbours.size - 1], 0, sizeof (bdaddr_t));
1577  neighbours.fds[neighbours.pos] = neighbours.fds[neighbours.size - 1];
1578  neighbours.fds[neighbours.size - 1] = -1;
1579  neighbours.size -= 1;
1580  }
1581 
1582  neighbours.pos += 1;
1583 
1584  if (neighbours.pos >= neighbours.size)
1585  neighbours.pos = 0;
1586 
1587  loops += 1;
1588 
1589  if (loops == MAX_LOOPS) //don't get stuck trying to connect to one device
1590  return 1;
1591  }
1592  }
1593  else
1594  {
1595  fprintf (stderr, "LOG : Search for a new device\n"); //FIXME debugging message
1596  neighbours.pos += 1;
1597  }
1598  }
1599 
1600  /* Cycle on the list */
1601  if (neighbours.pos == neighbours.size)
1602  {
1603  neighbours.pos = 0;
1604  searching_devices_count += 1;
1605 
1606  if (searching_devices_count == MAX_LOOPS)
1607  {
1608  fprintf (stderr, "LOG : Force to inquiry for new devices\n");
1609  searching_devices_count = 0;
1610  goto inquiry_devices;
1611  }
1612  }
1613  /* If a new device wasn't found, search an old one */
1614  if (connection_successful == 0)
1615  {
1616  int loop_check = neighbours.pos;
1617  while (neighbours.fds[neighbours.pos] == -1)
1618  {
1619  if (neighbours.pos == neighbours.size)
1620  neighbours.pos = 0;
1621 
1622  if (neighbours.pos == loop_check)
1623  {
1624  if (errno_copy == ECONNREFUSED)
1625  {
1626  fprintf (stderr, "LOG : No device found. Go back and search again\n"); //FIXME debugging message
1627  new_device = 1;
1628  loops += 1;
1629  goto search_for_devices;
1630  }
1631  else
1632  {
1633  return 1; // Skip the broadcast message
1634  }
1635  }
1636 
1637  neighbours.pos += 1;
1638  }
1639 
1640  *sendsocket = neighbours.fds[neighbours.pos++];
1641  }
1642 
1643  return 0;
1644  }
1645 #endif
1646 
1658 int
1659 main (int argc, char *argv[])
1660 {
1661 #ifdef LINUX
1662  struct HardwareInfos dev;
1663  char readbuf[MAXLINE];
1664  int maxfd;
1665  fd_set rfds;
1666  fd_set wfds;
1667  int stdin_open;
1669  int raw_eno, i;
1670  int crt_rfds = 0, rfds_list[MAX_PORTS];
1671  int broadcast, sendsocket;
1672 
1673  /* Assert privs so we can modify the firewall rules! */
1674  {
1675 #ifdef HAVE_SETRESUID
1676  uid_t uid = getuid ();
1677 
1678  if (0 != setresuid (uid, 0, 0))
1679  {
1680  fprintf (stderr,
1681  "Failed to setresuid to root: %s\n",
1682  strerror (errno));
1683  return 254;
1684  }
1685 #else
1686  if (0 != seteuid (0))
1687  {
1688  fprintf (stderr,
1689  "Failed to seteuid back to root: %s\n", strerror (errno));
1690  return 254;
1691  }
1692 #endif
1693  }
1694 
1695  /* Make use of SGID capabilities on POSIX */
1696  memset (&dev, 0, sizeof (dev));
1697  dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1698  raw_eno = errno; /* remember for later */
1699 
1700  /* Now that we've dropped root rights, we can do error checking */
1701  if (2 != argc)
1702  {
1703  fprintf (stderr, "You must specify the name of the interface as the first \
1704  and only argument to this program.\n");
1705  if (-1 != dev.fd_rfcomm)
1706  (void) close (dev.fd_rfcomm);
1707  return 1;
1708  }
1709 
1710  if (-1 == dev.fd_rfcomm)
1711  {
1712  fprintf (stderr, "Failed to create a RFCOMM socket: %s\n", strerror (raw_eno));
1713  return 1;
1714  }
1715  if (dev.fd_rfcomm >= FD_SETSIZE)
1716  {
1717  fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1718  dev.fd_rfcomm, FD_SETSIZE);
1719  (void) close (dev.fd_rfcomm);
1720  return 1;
1721  }
1722  if (0 != test_bluetooth_interface (argv[1]))
1723  {
1724  (void) close (dev.fd_rfcomm);
1725  return 1;
1726  }
1727  strncpy (dev.iface, argv[1], IFNAMSIZ);
1728  if (0 != open_device (&dev))
1729  {
1730  (void) close (dev.fd_rfcomm);
1731  return 1;
1732  }
1733 
1734  /* Drop privs */
1735  {
1736  uid_t uid = getuid ();
1737  #ifdef HAVE_SETRESUID
1738  if (0 != setresuid (uid, uid, uid))
1739  {
1740  fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1741  if (-1 != dev.fd_rfcomm)
1742  (void) close (dev.fd_rfcomm);
1743  return 1;
1744  }
1745  #else
1746  if (0 != (setuid (uid) | seteuid (uid)))
1747  {
1748  fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
1749  if (-1 != dev.fd_rfcomm)
1750  (void) close (dev.fd_rfcomm);
1751  return 1;
1752  }
1753  #endif
1754  }
1755 
1756  /* Send MAC address of the bluetooth interface to STDOUT first */
1757  {
1759 
1760  macmsg.hdr.size = htons (sizeof (macmsg));
1762  GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1763  GNUNET_memcpy (write_std.buf, &macmsg, sizeof (macmsg));
1764  write_std.size = sizeof (macmsg);
1765  }
1766 
1767 
1768  stdin_mst = mst_create (&stdin_send_hw, &dev);
1769  stdin_open = 1;
1770 
1775  while (1)
1776  {
1777  maxfd = -1;
1778  broadcast = 0;
1779  sendsocket = -1;
1780 
1781  FD_ZERO (&rfds);
1782  if ((0 == write_pout.size) && (1 == stdin_open))
1783  {
1784  FD_SET (STDIN_FILENO, &rfds);
1785  maxfd = MAX (maxfd, STDIN_FILENO);
1786  }
1787  if (0 == write_std.size)
1788  {
1789  FD_SET (dev.fd_rfcomm, &rfds);
1790  maxfd = MAX (maxfd, dev.fd_rfcomm);
1791  }
1792 
1793  for (i = 0; i < crt_rfds; i++) // it can receive messages from multiple devices
1794  {
1795  FD_SET (rfds_list[i], &rfds);
1796  maxfd = MAX (maxfd, rfds_list[i]);
1797  }
1798  FD_ZERO (&wfds);
1799  if (0 < write_std.size)
1800  {
1801  FD_SET (STDOUT_FILENO, &wfds);
1802  maxfd = MAX (maxfd, STDOUT_FILENO);
1803  }
1804  if (0 < write_pout.size) //it can send messages only to one device per loop
1805  {
1807  /* Get the destination address */
1809 
1810  if (memcmp (&frame->addr1, &dev.pl_mac,
1811  sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1812  {
1813  broadcast = 1;
1814  memset (&write_pout, 0, sizeof (write_pout)); //clear the buffer
1815  }
1816  else if (memcmp (&frame->addr1, &broadcast_address,
1817  sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1818  {
1819  fprintf (stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n", dev.iface, neighbours.pos, neighbours.size); //FIXME: debugging message
1820 
1821  if (send_broadcast(&dev, &sendsocket) != 0) //if the searching wasn't successful don't get stuck on the select stage
1822  {
1823  broadcast = 1;
1824  memset (&write_pout, 0, sizeof (write_pout)); //remove the message
1825  fprintf (stderr, "LOG : Skipping the broadcast message (pos %d, size %d)\n", neighbours.pos, neighbours.size);
1826  }
1827  else
1828  {
1829  FD_SET (sendsocket, &wfds);
1830  maxfd = MAX (maxfd, sendsocket);
1831  }
1832  }
1833  else
1834  {
1835  int found = 0;
1836  int pos = 0;
1837  /* Search if the address already exists on the list */
1838  for (i = 0; i < neighbours.size; i++)
1839  {
1840  if (memcmp (&frame->addr1, &(neighbours.devices[i]), sizeof (bdaddr_t)) == 0)
1841  {
1842  pos = i;
1843  if (neighbours.fds[i] != -1)
1844  {
1845  found = 1; //save the position where it was found
1846  FD_SET (neighbours.fds[i], &wfds);
1847  maxfd = MAX (maxfd, neighbours.fds[i]);
1848  sendsocket = neighbours.fds[i];
1849  fprintf (stderr, "LOG: the address was found in the list\n");
1850  break;
1851  }
1852  }
1853  }
1854  if (found == 0)
1855  {
1856  int status;
1857  struct sockaddr_rc addr = { 0 };
1858 
1859  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,
1860  frame->addr1.mac[5], frame->addr1.mac[4], frame->addr1.mac[3],
1861  frame->addr1.mac[2], frame->addr1.mac[1], frame->addr1.mac[0]); //FIXME: debugging message
1862 
1863  sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1864 
1865  if (sendsocket < 0)
1866  {
1867  fprintf (stderr, "Failed to create a RFCOMM socket (sending stage): %s\n",
1868  strerror (errno));
1869  return -1;
1870  }
1871 
1872  GNUNET_memcpy (&addr.rc_bdaddr, &frame->addr1, sizeof (bdaddr_t));
1873  addr.rc_family = AF_BLUETOOTH;
1874  addr.rc_channel = get_channel (&dev, addr.rc_bdaddr);
1875 
1876  int tries = 0;
1877  connect_retry:
1878  status = connect (sendsocket, (struct sockaddr *) &addr, sizeof (addr));
1879  if (0 != status && errno != EAGAIN)
1880  {
1881  if (errno == ECONNREFUSED && tries < 2)
1882  {
1883  fprintf (stderr, "LOG : %.*s failed to connect. Trying again!\n", IFNAMSIZ, dev.iface);
1884  tries++;
1885  goto connect_retry;
1886  }
1887  else if (errno == EBADF)
1888  {
1889  fprintf (stderr, "LOG : %s failed to connect : %s. Skip it!\n", dev.iface, strerror (errno));
1890  memset (&write_pout, 0, sizeof (write_pout));
1891  broadcast = 1;
1892  }
1893  else
1894  {
1895  fprintf (stderr, "LOG : %s failed to connect : %s. Try again later!\n", dev.iface, strerror (errno));
1896  memset (&write_pout, 0, sizeof (write_pout));
1897  broadcast = 1;
1898  }
1899 
1900  }
1901  else
1902  {
1903  FD_SET (sendsocket, &wfds);
1904  maxfd = MAX (maxfd, sendsocket);
1905  fprintf (stderr, "LOG : Connection successful\n");
1906  if (pos != 0) // save the socket
1907  {
1908  neighbours.fds[pos] = sendsocket;
1909  }
1910  else
1911  {
1912  /* Add the new device to the discovered devices list */
1913  if (neighbours.size < MAX_PORTS)
1914  {
1915  neighbours.fds[neighbours.size] = sendsocket;
1916  GNUNET_memcpy (&(neighbours.devices[neighbours.size++]), &addr.rc_bdaddr, sizeof (bdaddr_t));
1917  }
1918  else
1919  {
1920  fprintf (stderr, "The top limit for the discovarable devices' list was reached\n");
1921  }
1922  }
1923  }
1924  }
1925  }
1926  }
1927 
1928  if (broadcast == 0)
1929  {
1930  /* Select a fd which is ready for action :) */
1931  {
1932  int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
1933  if ((-1 == retval) && (EINTR == errno))
1934  continue;
1935  if (0 > retval && errno != EBADF) // we handle BADF errors later
1936  {
1937  fprintf (stderr, "select failed: %s\n", strerror (errno));
1938  break;
1939  }
1940  }
1941  if (FD_ISSET (STDOUT_FILENO , &wfds))
1942  {
1943  ssize_t ret =
1944  write (STDOUT_FILENO, write_std.buf + write_std.pos,
1946  if (0 > ret)
1947  {
1948  fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1949  break;
1950  }
1951  write_std.pos += ret;
1952  if (write_std.pos == write_std.size)
1953  {
1954  write_std.pos = 0;
1955  write_std.size = 0;
1956  }
1957  fprintf (stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); //FIXME: debugging message
1958 
1959  }
1960  if (-1 != sendsocket)
1961  {
1962  if (FD_ISSET (sendsocket , &wfds))
1963  {
1964  ssize_t ret = write (sendsocket,
1967  if (0 > ret) //FIXME should I first check the error type?
1968  {
1969  fprintf (stderr, "Failed to write to bluetooth device: %s. Closing the socket!\n",
1970  strerror (errno));
1971  for (i = 0; i < neighbours.size; i++)
1972  {
1973  if (neighbours.fds[i] == sendsocket)
1974  {
1975  (void) close(sendsocket);
1976  neighbours.fds[i] = -1;
1977  break;
1978  }
1979  }
1980  /* Remove the message */
1981  memset (&write_pout.buf + write_std.pos, 0, (write_pout.size - write_pout.pos));
1982  write_pout.pos = 0 ;
1983  write_pout.size = 0;
1984  }
1985  else
1986  {
1987  write_pout.pos += ret;
1988  if ((write_pout.pos != write_pout.size) && (0 != ret))
1989  {
1990  /* We should not get partial sends with packet-oriented devices... */
1991  fprintf (stderr, "Write error, partial send: %u/%u\n",
1992  (unsigned int) write_pout.pos,
1993  (unsigned int) write_pout.size);
1994  break;
1995  }
1996 
1997  if (write_pout.pos == write_pout.size)
1998  {
1999  write_pout.pos = 0;
2000  write_pout.size = 0;
2001  }
2002  fprintf (stderr, "LOG : %s sends a message to a DEVICE\n", dev.iface); //FIXME: debugging message
2003  }
2004  }
2005  }
2006  for (i = 0; i <= maxfd; i++)
2007  {
2008  if (FD_ISSET (i, &rfds))
2009  {
2010  if (i == STDIN_FILENO)
2011  {
2012  ssize_t ret =
2013  read (i, readbuf, sizeof (readbuf));
2014  if (0 > ret)
2015  {
2016  fprintf (stderr,
2017  "Read error from STDIN: %s\n",
2018  strerror (errno));
2019  break;
2020  }
2021  if (0 == ret)
2022  {
2023  /* stop reading... */
2024  stdin_open = 0;
2025  }
2026  else
2027  {
2028  mst_receive (stdin_mst, readbuf, ret);
2029  fprintf (stderr, "LOG : %s receives a message from STDIN\n", dev.iface); //FIXME: debugging message
2030  }
2031  }
2032  else if (i == dev.fd_rfcomm)
2033  {
2034  int readsocket;
2035  struct sockaddr_rc addr = { 0 };
2036  unsigned int opt = sizeof (addr);
2037 
2038  readsocket = accept (dev.fd_rfcomm, (struct sockaddr *) &addr, &opt);
2039  fprintf(stderr, "LOG : %s accepts a message\n", dev.iface); //FIXME: debugging message
2040  if (readsocket == -1)
2041  {
2042  fprintf (stderr, "Failed to accept a connection on interface: %.*s\n", IFNAMSIZ,
2043  strerror (errno));
2044  break;
2045  }
2046  else
2047  {
2048  FD_SET (readsocket, &rfds);
2049  maxfd = MAX (maxfd, readsocket);
2050 
2051  if (crt_rfds < MAX_PORTS)
2052  rfds_list[crt_rfds++] = readsocket;
2053  else
2054  {
2055  fprintf (stderr, "The limit for the read file descriptors list was \
2056  reached\n");
2057  break;
2058  }
2059  }
2060 
2061  }
2062  else
2063  {
2065  ssize_t ret;
2066  fprintf (stderr, "LOG : %s reads something from the socket\n", dev.iface);//FIXME : debugging message
2068  ret =
2069  read_from_the_socket ((void *)&i, (unsigned char *) &rrm->frame,
2070  sizeof (write_std.buf)
2072  + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2073  rrm);
2074  if (0 >= ret)
2075  {
2076  int j;
2077  FD_CLR (i, &rfds);
2078  close (i);
2079  /* Remove the socket from the list */
2080  for (j = 0; j < crt_rfds; j++)
2081  {
2082  if (rfds_list[j] == i)
2083  {
2084  rfds_list[j] ^= rfds_list[crt_rfds - 1];
2085  rfds_list[crt_rfds - 1] ^= rfds_list[j];
2086  rfds_list[j] ^= rfds_list[crt_rfds - 1];
2087  crt_rfds -= 1;
2088  break;
2089  }
2090  }
2091 
2092  fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
2093  break;
2094  }
2095  if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2096  {
2097  write_std.size = ret
2099  - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2100  rrm->header.size = htons (write_std.size);
2102  }
2103  }
2104  }
2105  }
2106  }
2107  }
2108  /* Error handling, try to clean up a bit at least */
2109  mst_destroy (stdin_mst);
2110  stdin_mst = NULL;
2111  sdp_close (dev.session);
2112  (void) close (dev.fd_rfcomm);
2113  if (-1 != sendsocket)
2114  (void) close (sendsocket);
2115 
2116  for (i = 0; i < crt_rfds; i++)
2117  (void) close (rfds_list[i]);
2118 
2119  for (i = 0; i < neighbours.size; i++)
2120  (void) close (neighbours.fds[i]);
2121  #else
2122  struct HardwareInfos dev;
2123  struct GNUNET_NETWORK_Handle *sendsocket;
2124  struct GNUNET_NETWORK_FDSet *rfds;
2125  struct GNUNET_NETWORK_FDSet *wfds;
2126  struct GNUNET_NETWORK_Handle *rfds_list[MAX_PORTS];
2127  char readbuf[MAXLINE] = { 0 };
2128  SOCKADDR_BTH acc_addr = { 0 };
2129  int addr_len = sizeof (SOCKADDR_BTH);
2130  int broadcast, i, stdin_open, crt_rfds = 0;
2131  HANDLE stdin_handle = GetStdHandle (STD_INPUT_HANDLE);
2132  HANDLE stdout_handle = GetStdHandle (STD_OUTPUT_HANDLE);
2134 
2135  /* check the handles */
2136  if (stdin_handle == INVALID_HANDLE_VALUE)
2137  {
2138  fprintf (stderr, "Failed to get the stdin handle\n");
2139  ExitProcess (2);
2140  }
2141 
2142  if (stdout_handle == INVALID_HANDLE_VALUE)
2143  {
2144  fprintf (stderr, "Failed to get the stdout handle\n");
2145  ExitProcess (2);
2146  }
2147 
2148  /* initialize windows sockets */
2149  initialize_windows_sockets();
2150 
2151  // /* test bluetooth socket family support */ --> it return false because the GNUNET_NETWORK_test_pf should also receive the type of socket (BTHPROTO_RFCOMM)
2152  // if (GNUNET_NETWORK_test_pf (AF_BTH) != GNUNET_OK)
2153  // {
2154  // fprintf (stderr, "AF_BTH family is not supported\n");
2155  // ExitProcess (2);
2156  // }
2157 
2158  /* create the socket */
2159  dev.handle = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
2160  if (dev.handle == NULL)
2161  {
2162  fprintf (stderr, "Failed to create RFCOMM socket: ");
2163  print_last_error();
2164  ExitProcess (2);
2165  }
2166 
2167 
2168  if (open_device (&dev) == -1)
2169  {
2170  fprintf (stderr, "Failed to open the device\n");
2171  print_last_error();
2172  if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
2173  {
2174  fprintf (stderr, "Failed to close the socket!\n");
2175  print_last_error();
2176  }
2177  ExitProcess (2);
2178  }
2179 
2180  if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (dev.handle, 1) )
2181  {
2182  fprintf (stderr, "Failed to change the socket mode\n");
2183  ExitProcess (2);
2184  }
2185 
2186  memset (&write_std, 0, sizeof (write_std));
2187  memset (&write_pout, 0, sizeof (write_pout));
2188  stdin_open = 1;
2189 
2190  rfds = GNUNET_NETWORK_fdset_create ();
2191  wfds = GNUNET_NETWORK_fdset_create ();
2192 
2193  /* Send MAC address of the bluetooth interface to STDOUT first */
2194  {
2196 
2197  macmsg.hdr.size = htons (sizeof (macmsg));
2199  GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy));
2200  GNUNET_memcpy (write_std.buf, &macmsg, sizeof (macmsg));
2201  write_std.size = sizeof (macmsg);
2202  }
2203 
2204 
2205  stdin_mst = mst_create (&stdin_send_hw, &dev);
2206  stdin_open = 1;
2207 
2208  int pos = 0;
2209  int stdin_pos = -1;
2210  int stdout_pos = -1;
2211  while (1)
2212  {
2213  broadcast = 0;
2214  pos = 0;
2215  stdin_pos = -1;
2216  stdout_pos = -1;
2217  sendsocket = NULL; //FIXME ???memleaks
2218 
2220  if ((0 == write_pout.size) && (1 == stdin_open))
2221  {
2222  stdin_pos = pos;
2223  pos +=1;
2224  GNUNET_NETWORK_fdset_handle_set (rfds, (struct GNUNET_DISK_FileHandle*) &stdin_handle);
2225  }
2226 
2227  if (0 == write_std.size)
2228  {
2229  pos += 1;
2230  GNUNET_NETWORK_fdset_set (rfds, dev.handle);
2231  }
2232 
2233  for (i = 0; i < crt_rfds; i++)
2234  {
2235  pos += 1;
2236  GNUNET_NETWORK_fdset_set (rfds, rfds_list[i]);
2237  }
2238 
2240  if (0 < write_std.size)
2241  {
2242  stdout_pos = pos;
2243  GNUNET_NETWORK_fdset_handle_set (wfds, (struct GNUNET_DISK_FileHandle*) &stdout_handle);
2244  // printf ("%s\n", write_std.buf);
2245  // memset (write_std.buf, 0, write_std.size);
2246  // write_std.size = 0;
2247  }
2248 
2249  if (0 < write_pout.size)
2250  {
2251  if (strcmp (argv[1], "ff:ff:ff:ff:ff:ff") == 0) {
2252  fprintf(stderr, "LOG: BROADCAST! Skipping the message\n");
2253  // skip the message
2254  broadcast = 1;
2255  memset (write_pout.buf, 0, write_pout.size);
2256  write_pout.size = 0;
2257  }
2258  else
2259  {
2260  SOCKADDR_BTH addr;
2261  fprintf (stderr, "LOG : has a new message for %s\n", argv[1]);
2262  sendsocket = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
2263 
2264  if (sendsocket == NULL)
2265  {
2266  fprintf (stderr, "Failed to create RFCOMM socket: \n");
2267  print_last_error();
2268  ExitProcess (2);
2269  }
2270 
2271  memset (&addr, 0, sizeof (addr));
2272  //addr.addressFamily = AF_BTH;
2273  if (SOCKET_ERROR ==
2274  WSAStringToAddress (argv[1], AF_BTH, NULL, (LPSOCKADDR) &addr, &addr_len))
2275  {
2276  fprintf (stderr, "Failed to translate the address: ");
2277  print_last_error();
2278  ExitProcess ( 2 ) ;
2279  }
2280  addr.port = get_channel (argv[1]);
2281  if (addr.port == -1)
2282  {
2283  fprintf (stderr, "Couldn't find the sdp service for the address: %s\n", argv[1]);
2284  memset (write_pout.buf, 0, write_pout.size);
2285  write_pout.size = 0;
2286  broadcast = 1; //skipping the select part
2287  }
2288  else
2289  {
2290  if (GNUNET_OK != GNUNET_NETWORK_socket_connect (sendsocket, (LPSOCKADDR)&addr, addr_len))
2291  {
2292  fprintf (stderr, "Failed to connect: ");
2293  print_last_error();
2294  ExitProcess (2);
2295  }
2296 
2297  if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (sendsocket, 1) )
2298  {
2299  fprintf (stderr, "Failed to change the socket mode\n");
2300  ExitProcess (2);
2301  }
2302 
2303  GNUNET_NETWORK_fdset_set (wfds, sendsocket);
2304  }
2305  }
2306  }
2307 
2308  if (broadcast == 0)
2309  {
2310  int retval = GNUNET_NETWORK_socket_select (rfds, wfds, NULL, GNUNET_TIME_relative_get_forever_());
2311  if (retval < 0)
2312  {
2313  fprintf (stderr, "Select error\n");
2314  ExitProcess (2);
2315  }
2316  //if (GNUNET_NETWORK_fdset_isset (wfds, (struct GNUNET_NETWORK_Handle*)&stdout_handle))
2317  if (retval == stdout_pos)
2318  {
2319  fprintf(stderr, "LOG : sends a message to STDOUT\n"); //FIXME: debugging message
2320  //ssize_t ret;
2321  //ret = GNUNET_NETWORK_socket_send ((struct GNUNET_NETWORK_Handle *)&stdout_handle, write_std.buf + write_std.pos, write_std.size - write_std.pos);
2322  //ret = write (STDOUT_FILENO, write_std.buf + write_std.pos, write_std.size - write_std.pos);
2323  DWORD ret;
2324  if (FALSE == WriteFile (stdout_handle, write_std.buf + write_std.pos, write_std.size - write_std.pos, &ret, NULL))
2325  {
2326  fprintf (stderr, "Failed to write to STDOUT: ");
2327  print_last_error();
2328  break;
2329  }
2330 
2331  if (ret <= 0)
2332  {
2333  fprintf (stderr, "Failed to write to STDOUT\n");
2334  ExitProcess (2);
2335  }
2336 
2337  write_std.pos += ret;
2338  if (write_std.pos == write_std.size)
2339  {
2340  write_std.pos = 0;
2341  write_std.size = 0;
2342  }
2343  }
2344  if (sendsocket != NULL)
2345  {
2346  if (GNUNET_NETWORK_fdset_isset (wfds, sendsocket))
2347  {
2348  ssize_t ret;
2351 
2352  if (GNUNET_SYSERR == ret)
2353  {
2354  fprintf (stderr, "Failed to send to the socket. Closing the socket. Error: \n");
2355  print_last_error();
2356  if (GNUNET_NETWORK_socket_close (sendsocket) != GNUNET_OK)
2357  {
2358  fprintf (stderr, "Failed to close the sendsocket!\n");
2359  print_last_error();
2360  }
2361  ExitProcess (2);
2362  }
2363  else
2364  {
2365  write_pout.pos += ret;
2366  if ((write_pout.pos != write_pout.size) && (0 != ret))
2367  {
2368  /* we should not get partial sends with packet-oriented devices... */
2369  fprintf (stderr, "Write error, partial send: %u/%u\n",
2370  (unsigned int) write_pout.pos,
2371  (unsigned int) write_pout.size);
2372  break;
2373  }
2374 
2375  if (write_pout.pos == write_pout.size)
2376  {
2377  write_pout.pos = 0;
2378  write_pout.size = 0;
2379 
2380  }
2381  fprintf(stderr, "LOG : sends a message to a DEVICE\n"); //FIXME: debugging message
2382  }
2383  }
2384  }
2385 
2386  //if (GNUNET_NETWORK_fdset_isset (rfds, (struct GNUNET_NETWORK_Handle*)&stdin_handle))
2387  if (retval == stdin_pos)
2388  {
2389  //ssize_t ret;
2390  //ret = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)&stdin_handle, readbuf, sizeof (write_pout.buf));
2391  //ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
2392  DWORD ret;
2393  if (FALSE == ReadFile (stdin_handle, readbuf, sizeof (readbuf), &ret, NULL)) /* do nothing asynchronous */
2394  {
2395  fprintf (stderr, "Read error from STDIN: ");
2396  print_last_error();
2397  break;
2398  }
2399  if (0 == ret)
2400  {
2401  /* stop reading... */
2402  stdin_open = 0;
2403  } else {
2404  mst_receive (stdin_mst, readbuf, ret);
2405  fprintf (stderr, "LOG : receives a message from STDIN\n"); //FIXME: debugging message
2406  }
2407  }
2408  else
2409  if (GNUNET_NETWORK_fdset_isset (rfds, dev.handle))
2410  {
2411  fprintf (stderr, "LOG: accepting connection\n");
2412  struct GNUNET_NETWORK_Handle *readsocket;
2413  readsocket = GNUNET_NETWORK_socket_accept (dev.handle, (LPSOCKADDR)&acc_addr, &addr_len);
2414  if (readsocket == NULL)
2415  {
2416  fprintf (stderr, "Accept error %d: ", GetLastError());
2417  print_last_error();
2418  ExitProcess (2);
2419  }
2420  else
2421  {
2422  if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (readsocket, 1) )
2423  {
2424  fprintf (stderr, "Failed to change the socket mode\n");
2425  ExitProcess (2);
2426  }
2427  GNUNET_NETWORK_fdset_set (rfds, readsocket);
2428 
2429  if (crt_rfds < MAX_PORTS)
2430  rfds_list[crt_rfds++] = readsocket;
2431  else
2432  {
2433  fprintf (stderr, "The limit for the read file descriptors list was reached\n");
2434  break;
2435  }
2436  }
2437  }
2438  else
2439  for (i = 0; i < crt_rfds; i++)
2440  {
2441  if (GNUNET_NETWORK_fdset_isset (rfds, rfds_list[i]))
2442  {
2444  ssize_t ret;
2445  fprintf (stderr, "LOG: reading something from the socket\n");//FIXME : debugging message
2447  ret = read_from_the_socket (rfds_list[i], (unsigned char *) &rrm->frame,
2448  sizeof (write_std.buf)
2450  + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2451  rrm);
2452  if (0 >= ret)
2453  {
2454 
2455  //TODO remove the socket from the list
2456  if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2457  {
2458  fprintf (stderr, "Failed to close the sendsocket!\n");
2459  print_last_error();
2460  }
2461 
2462  fprintf (stderr, "Read error from raw socket: ");
2463  print_last_error();
2464  break;
2465 
2466  }
2467  if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2468  {
2469  write_std.size = ret
2471  - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2472  rrm->header.size = htons (write_std.size);
2473  rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2474  }
2475  break;
2476  }
2477  }
2478  }
2479  }
2480 
2481  mst_destroy (stdin_mst);
2482  stdin_mst = NULL;
2483 
2484  if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
2485  {
2486  fprintf (stderr, "Failed to close the socket!\n");
2487  print_last_error();
2488  }
2489 
2490  for (i = 0; i < crt_rfds; i++)
2491  {
2492  if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2493  {
2494  fprintf (stderr, "Failed to close the socket!\n");
2495  print_last_error();
2496  }
2497  }
2498 
2499  WSACleanup();
2500  #endif
2501  return 1; /* we never exit 'normally' */
2502 }
int GNUNET_NETWORK_socket_listen(const struct GNUNET_NETWORK_Handle *desc, int backlog)
Listen on a socket.
Definition: network.c:796
int GNUNET_NETWORK_get_fd(const struct GNUNET_NETWORK_Handle *desc)
Return file descriptor for this network handle.
Definition: network.c:1268
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:256
IO buffer used for buffering data in transit (to wireless or to stdout).
static void done()
#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:927
struct GNUNET_MessageHeader hdr
Message header.
struct for storing the information of the hardware.
Definition: w32nsp.c:83
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:484
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
ssize_t GNUNET_NETWORK_socket_recv(const struct GNUNET_NETWORK_Handle *desc, void *buffer, size_t length)
Read data from a connected socket (always non-blocking).
Definition: network.c:894
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.
int GNUNET_NETWORK_socket_bind(struct GNUNET_NETWORK_Handle *desc, const struct sockaddr *address, socklen_t address_len)
Bind a socket to a particular address.
Definition: network.c:522
struct GNUNET_MessageHeader header
Type is &#39;GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER&#39;.
struct GNUNET_MessageStreamTokenizer * stdin_mst
Tokenizer for the data we get from stdin.
#define GNUNET_NO
Definition: gnunet_common.h:81
#define GNUNET_OK
Named constants for return values.
Definition: gnunet_common.h:78
#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.
static struct GNUNET_ARM_Handle * h
Connection with ARM.
Definition: gnunet-arm.c:94
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:468
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.
#define FD_SETSIZE
Definition: winproc.h:39
struct GNUNET_NETWORK_FDSet * GNUNET_NETWORK_fdset_create(void)
Creates an fd set.
Definition: network.c:1538
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:731
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
#define GNUNET_memcpy(dst, src, n)
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:83
collection of IO descriptors
uint16_t status
See PRISM_STATUS_*-constants.
static char buf[2048]
struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame frame
IEEE Frame.
static struct GNUNET_DNS_Handle * handle
Handle to transport service.
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:1812
uint16_t frame_control
802.11 Frame Control field.
#define GNUNET_SYSERR
Definition: gnunet_common.h:79
static unsigned int size
Size of the "table".
Definition: peer.c:67
static unsigned long calc_crc_osdep(const unsigned char *buf, size_t len)
Calculate crc32, the start of the calculation.
MessageTokenizerCallback cb
Function to call on completed messages.
struct GNUNET_MessageHeader header
Type is &#39;GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER&#39;.
void GNUNET_NETWORK_fdset_zero(struct GNUNET_NETWORK_FDSet *fds)
Reset FD set (clears all file descriptors).
Definition: network.c:1146
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:1359
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:1163
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:79
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.
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:80
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:1181
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:604
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:1037