GNUnet  0.19.4
gnunet-helper-transport-bluetooth.c File Reference
#include "platform.h"
#include "gnunet_private_config.h"
#include <bluetooth/bluetooth.h>
#include <bluetooth/hci.h>
#include <bluetooth/hci_lib.h>
#include <bluetooth/rfcomm.h>
#include <bluetooth/sdp.h>
#include <bluetooth/sdp_lib.h>
#include <errno.h>
#include <linux/if.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/param.h>
#include <sys/socket.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "plugin_transport_wlan.h"
#include "gnunet_protocols.h"
Include dependency graph for gnunet-helper-transport-bluetooth.c:

Go to the source code of this file.

Data Structures

struct  HardwareInfos
 struct for storing the information of the hardware. More...
 
struct  SendBuffer
 IO buffer used for buffering data in transit (to wireless or to stdout). More...
 
struct  MessageStreamTokenizer
 Handle to a message stream tokenizer. More...
 

Macros

#define MAX_PORTS   30
 Maximum number of ports assignable for RFCOMMM protocol. More...
 
#define MAXLINE   4096
 Maximum size of a message allowed in either direction (used for our receive and sent buffers). More...
 
#define MAX_LOOPS   5
 Maximum number of loops without inquiring for new devices. More...
 
#define BLUEZ_DEVNAME_SIZE   8
 In bluez library, the maximum name length of a device is 8. More...
 
#define ALIGN_FACTOR   8
 To what multiple do we align messages? 8 byte should suffice for everyone for now. More...
 
#define MIN_BUFFER_SIZE   sizeof(struct GNUNET_MessageHeader)
 Smallest supported message. More...
 

Typedefs

typedef void(* MessageTokenizerCallback) (void *cls, const struct GNUNET_MessageHeader *message)
 Functions with this signature are called whenever a complete message is received by the tokenizer. More...
 

Functions

static struct MessageStreamTokenizermst_create (MessageTokenizerCallback cb, void *cb_cls)
 Create a message stream tokenizer. More...
 
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. More...
 
static void mst_destroy (struct MessageStreamTokenizer *mst)
 Destroys a tokenizer. More...
 
static unsigned long calc_crc_osdep (const unsigned char *buf, size_t len)
 Calculate crc32, the start of the calculation. More...
 
static int check_crc_buf_osdep (const unsigned char *buf, size_t len)
 Calculate and check crc of the bluetooth packet. More...
 
static int register_service (struct HardwareInfos *dev, int rc_channel)
 Function used for creating the service record and registering it. More...
 
static int get_channel (struct HardwareInfos *dev, bdaddr_t dest)
 Function used for searching and browsing for a service. More...
 
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'. More...
 
static int open_device (struct HardwareInfos *dev)
 Open the bluetooth interface for reading/writing. More...
 
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. More...
 
static int mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader, const struct HardwareInfos *dev)
 Test incoming packets mac for being our own. More...
 
static void stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
 Process data from the stdin. More...
 
int main (int argc, char *argv[])
 Main function of the helper. More...
 

Variables

static struct SendBuffer write_pout
 Buffer for data read from stdin to be transmitted to the bluetooth device. More...
 
static struct SendBuffer write_std
 Buffer for data read from the bluetooth device to be transmitted to stdout. More...
 

Macro Definition Documentation

◆ MAX_PORTS

#define MAX_PORTS   30

Maximum number of ports assignable for RFCOMMM protocol.

Definition at line 49 of file gnunet-helper-transport-bluetooth.c.

◆ MAXLINE

#define MAXLINE   4096

Maximum size of a message allowed in either direction (used for our receive and sent buffers).

Definition at line 55 of file gnunet-helper-transport-bluetooth.c.

◆ MAX_LOOPS

#define MAX_LOOPS   5

Maximum number of loops without inquiring for new devices.

Definition at line 61 of file gnunet-helper-transport-bluetooth.c.

◆ BLUEZ_DEVNAME_SIZE

#define BLUEZ_DEVNAME_SIZE   8

In bluez library, the maximum name length of a device is 8.

Definition at line 66 of file gnunet-helper-transport-bluetooth.c.

◆ ALIGN_FACTOR

#define ALIGN_FACTOR   8

To what multiple do we align messages? 8 byte should suffice for everyone for now.

Definition at line 176 of file gnunet-helper-transport-bluetooth.c.

◆ MIN_BUFFER_SIZE

#define MIN_BUFFER_SIZE   sizeof(struct GNUNET_MessageHeader)

Smallest supported message.

Definition at line 181 of file gnunet-helper-transport-bluetooth.c.

Typedef Documentation

◆ MessageTokenizerCallback

typedef void(* MessageTokenizerCallback) (void *cls, const struct GNUNET_MessageHeader *message)

Functions with this signature are called whenever a complete message is received by the tokenizer.

Parameters
clsclosure
messagethe actual message

Definition at line 191 of file gnunet-helper-transport-bluetooth.c.

Function Documentation

◆ mst_create()

static struct MessageStreamTokenizer* mst_create ( MessageTokenizerCallback  cb,
void *  cb_cls 
)
static

Create a message stream tokenizer.

Parameters
cbfunction to call on completed messages
cb_clsclosure for cb
Returns
handle to tokenizer

Definition at line 241 of file gnunet-helper-transport-bluetooth.c.

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 }
static int ret
Return value of the commandline.
Definition: gnunet-abd.c:81
#define MIN_BUFFER_SIZE
Smallest supported message.
Handle to a message stream tokenizer.
MessageTokenizerCallback cb
Function to call on completed messages.

References MessageStreamTokenizer::cb, MessageStreamTokenizer::cb_cls, MIN_BUFFER_SIZE, and ret.

Referenced by main().

Here is the caller graph for this function:

◆ mst_receive()

static int mst_receive ( struct MessageStreamTokenizer mst,
const char *  buf,
size_t  size 
)
static

Add incoming data to the receive buffer and call the callback for all complete messages.

Parameters
msttokenizer to use
bufinput data to add
sizenumber of bytes in buf
Returns
GNUNET_OK if we are done processing (need more data) GNUNET_SYSERR if the data stream is corrupt

Definition at line 278 of file gnunet-helper-transport-bluetooth.c.

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 }
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
#define ALIGN_FACTOR
To what multiple do we align messages? 8 byte should suffice for everyone for now.
static char buf[2048]
#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
static unsigned int size
Size of the "table".
Definition: peer.c:68
static struct GNUNET_TIME_Relative delta
Definition: speedup.c:36
Header for all communications.
uint16_t size
The length of the struct (in bytes, including the length field itself), in big-endian format.
struct GNUNET_MessageHeader * hdr
Beginning of the buffer.
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?

References ALIGN_FACTOR, buf, MessageStreamTokenizer::cb, MessageStreamTokenizer::cb_cls, MessageStreamTokenizer::curr_buf, delta, do_align(), GNUNET_memcpy, GNUNET_MIN, GNUNET_NO, GNUNET_OK, GNUNET_SYSERR, GNUNET_YES, MessageStreamTokenizer::hdr, MessageStreamTokenizer::off, MessageStreamTokenizer::pos, ret, GNUNET_MessageHeader::size, and size.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mst_destroy()

static void mst_destroy ( struct MessageStreamTokenizer mst)
static

Destroys a tokenizer.

Parameters
msttokenizer to destroy

Definition at line 456 of file gnunet-helper-transport-bluetooth.c.

457 {
458  free (mst->hdr);
459  free (mst);
460 }

References MessageStreamTokenizer::hdr.

Referenced by main().

Here is the caller graph for this function:

◆ calc_crc_osdep()

static unsigned long calc_crc_osdep ( const unsigned char *  buf,
size_t  len 
)
static

Calculate crc32, the start of the calculation.

Parameters
bufbuffer to calc the crc
lenlen of the buffer
Returns
crc sum

Definition at line 471 of file gnunet-helper-transport-bluetooth.c.

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 }
uint16_t len
length of data (which is always a uint32_t, but presumably this can be used to specify that fewer byt...

References buf, and len.

Referenced by check_crc_buf_osdep().

Here is the caller graph for this function:

◆ check_crc_buf_osdep()

static int check_crc_buf_osdep ( const unsigned char *  buf,
size_t  len 
)
static

Calculate and check crc of the bluetooth packet.

Parameters
bufbuffer of the packet, with len + 4 bytes of data, the last 4 bytes being the checksum
lenlength of the payload in data
Returns
0 on success (checksum matches), 1 on error

Definition at line 557 of file gnunet-helper-transport-bluetooth.c.

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 }
static unsigned long calc_crc_osdep(const unsigned char *buf, size_t len)
Calculate crc32, the start of the calculation.

References buf, calc_crc_osdep(), and len.

Referenced by read_from_the_socket().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ register_service()

static int register_service ( struct HardwareInfos dev,
int  rc_channel 
)
static

Function used for creating the service record and registering it.

Parameters
devpointer to the device struct
rc_channelthe rfcomm channel
Returns
0 on success
  1. initializations
  2. set the service ID, class, profile information
  3. make the service record publicly browsable
  4. register the RFCOMM channel
  5. set the name, provider and description
  6. register the service record to the local SDP server
  7. cleanup

Definition at line 609 of file gnunet-helper-transport-bluetooth.c.

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 }
static void record(void *cls, size_t data_size, const void *data)
Process recorded audio data.
char iface[IFNAMSIZ]
Name of the interface, not necessarily 0-terminated (!).
sdp_session_t * session
SDP session.
struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac
MAC address of our own bluetooth interface.

References HardwareInfos::iface, GNUNET_TRANSPORT_WLAN_MacAddress::mac, HardwareInfos::pl_mac, record(), and HardwareInfos::session.

Referenced by open_device().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ get_channel()

static int get_channel ( struct HardwareInfos dev,
bdaddr_t  dest 
)
static

Function used for searching and browsing for a service.

This will return the port number on which the service is running.

Parameters
devpointer to the device struct
desttarget address
Returns
channel
  1. detect all nearby devices
  2. for each device: 2.1. connect to the SDP server running 2.2. get a list of service records with the specific UUID 2.3. for each service record get a list of the protocol sequences and get the port number

Definition at line 703 of file gnunet-helper-transport-bluetooth.c.

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 }

References warningfilter::dest, HardwareInfos::iface, and record().

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ read_from_the_socket()

static ssize_t read_from_the_socket ( void *  sock,
unsigned char *  buf,
size_t  buf_size,
struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage ri 
)
static

Read from the socket and put the result into the buffer for transmission to 'stdout'.

Parameters
sockfile descriptor for reading
bufbuffer to read to; first bytes will be the 'struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame', followed by the actual payload
buf_sizesize of the buffer
riwhere to write radiotap_rx info
Returns
number of bytes written to 'buf'

Definition at line 780 of file gnunet-helper-transport-bluetooth.c.

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 }
static int check_crc_buf_osdep(const unsigned char *buf, size_t len)
Calculate and check crc of the bluetooth packet.
uint32_t ri_channel
IEEE80211_RADIOTAP_CHANNEL, 0 if unknown.

References buf, check_crc_buf_osdep(), GNUNET_memcpy, len, and GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage::ri_channel.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ open_device()

static int open_device ( struct HardwareInfos dev)
static

Open the bluetooth interface for reading/writing.

Parameters
devpointer to the device struct
Returns
0 on success, non-zero on error

Copy the MAC address to the device structure

Definition at line 836 of file gnunet-helper-transport-bluetooth.c.

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 }
static int list
Set if we should print a list of currently running services.
Definition: gnunet-arm.c:69
#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 register_service(struct HardwareInfos *dev, int rc_channel)
Function used for creating the service record and registering it.
static struct GNUNET_CONTAINER_MultiPeerMap * neighbours
Map from PIDs to struct Neighbour entries.
static struct GNUNET_VPN_RedirectionRequest * request
Opaque redirection request handle.
Definition: gnunet-vpn.c:40
int fd_rfcomm
file descriptor for the rfcomm socket

References BLUEZ_DEVNAME_SIZE, HardwareInfos::fd_rfcomm, GNUNET_memcpy, HardwareInfos::iface, list, MAX_PORTS, neighbours, HardwareInfos::pl_mac, register_service(), and request.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ mac_set()

static void mac_set ( struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame taIeeeHeader,
const struct HardwareInfos dev 
)
static

Set the header to sane values to make attacks more difficult.

Parameters
taIeeeHeaderpointer to the header of the packet
devpointer to the Hardware_Infos struct

copy from gnunet-helper-transport-wlan.c ****

Definition at line 1007 of file gnunet-helper-transport-bluetooth.c.

1009 {
1010  taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
1011  taIeeeHeader->addr3 = mac_bssid_gnunet;
1012  taIeeeHeader->addr2 = dev->pl_mac;
1013 }
#define IEEE80211_FC0_TYPE_DATA
static GNUNET_NETWORK_STRUCT_END const struct GNUNET_TRANSPORT_WLAN_MacAddress mac_bssid_gnunet
GNUnet bssid.
uint16_t frame_control
802.11 Frame Control field.
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.

References GNUNET_TRANSPORT_WLAN_Ieee80211Frame::addr2, GNUNET_TRANSPORT_WLAN_Ieee80211Frame::addr3, GNUNET_TRANSPORT_WLAN_Ieee80211Frame::frame_control, IEEE80211_FC0_TYPE_DATA, mac_bssid_gnunet, and HardwareInfos::pl_mac.

Referenced by stdin_send_hw().

Here is the caller graph for this function:

◆ mac_test()

static int mac_test ( const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame taIeeeHeader,
const struct HardwareInfos dev 
)
static

Test incoming packets mac for being our own.

Parameters
taIeeeHeaderbuffer of the packet
devthe Hardware_Infos struct
Returns
0 if mac belongs to us, 1 if mac is for another target

same as the one from gnunet-helper-transport-wlan.c ****

Definition at line 1058 of file gnunet-helper-transport-bluetooth.c.

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 }
static struct GNUNET_PeerIdentity all_zeros
Peer identity that is all zeros, used as a way to indicate "all peers".
static const struct GNUNET_TRANSPORT_WLAN_MacAddress bc_all_mac
Broadcast MAC.
#define MAC_ADDR_SIZE
Number fo bytes in a mac address.
struct GNUNET_TRANSPORT_WLAN_MacAddress addr1
Address 1: destination address in ad-hoc mode or AP, BSSID if station,.

References GNUNET_TRANSPORT_WLAN_Ieee80211Frame::addr1, GNUNET_TRANSPORT_WLAN_Ieee80211Frame::addr3, all_zeros, bc_all_mac, MAC_ADDR_SIZE, mac_bssid_gnunet, and HardwareInfos::pl_mac.

Referenced by main().

Here is the caller graph for this function:

◆ stdin_send_hw()

static void stdin_send_hw ( void *  cls,
const struct GNUNET_MessageHeader hdr 
)
static

Process data from the stdin.

Takes the message, forces the sender MAC to be correct and puts it into our buffer for transmission to the receiver.

Parameters
clspointer to the device struct ('struct HardwareInfos*')
hdrpointer to the start of the packet

same as the one from gnunet-helper-transport-wlan.c ****

Definition at line 1086 of file gnunet-helper-transport-bluetooth.c.

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 }
static struct SendBuffer write_pout
Buffer for data read from stdin to be transmitted to the bluetooth device.
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.
#define MAXLINE
Maximum size of a message allowed in either direction (used for our receive and sent buffers).
#define GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER
Type of data messages from the plugin to the gnunet-wlan-helper.
uint16_t type
The type of the message (GNUNET_MESSAGE_TYPE_XXXX), in big-endian format.
generic definitions for IEEE 802.11 frames
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.
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.

References GNUNET_TRANSPORT_WLAN_Ieee80211Frame::addr1, SendBuffer::buf, GNUNET_TRANSPORT_WLAN_RadiotapSendMessage::frame, GNUNET_memcpy, GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER, GNUNET_TRANSPORT_WLAN_RadiotapSendMessage::header, mac_set(), MAXLINE, GNUNET_MessageHeader::size, SendBuffer::size, GNUNET_MessageHeader::type, and write_pout.

Referenced by main().

Here is the call graph for this function:
Here is the caller graph for this function:

◆ main()

int main ( int  argc,
char *  argv[] 
)

Main function of the helper.

This code accesses a bluetooth interface forwards traffic in both directions between the bluetooth interface and stdin/stdout of this process. Error messages are written to stderr.

Parameters
argcnumber of arguments, must be 2
argvarguments only argument is the name of the interface (e.g. 'hci0')
Returns
0 on success (never happens, as we don't return unless aborted), 1 on error

similar to gnunet-helper-transport-wlan.c ****

Definition at line 1384 of file gnunet-helper-transport-bluetooth.c.

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));
1488  macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
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));
1957  macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
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 }
struct GNUNET_MessageStreamTokenizer * stdin_mst
Tokenizer for the data we get from stdin.
static struct SendBuffer write_std
Buffer for data read from the bluetooth device to be transmitted to stdout.
static int mac_test(const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader, const struct HardwareInfos *dev)
Test incoming packets mac for being our own.
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.
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 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.
uint16_t status
See PRISM_STATUS_*-constants.
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_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
unsigned int size
Number of entries in the map.
Handle used to access files (and pipes).
collection of IO descriptors
handle to a socket
Definition: network.c:53
struct GNUNET_MessageHeader hdr
Message header.
Message from the WLAN helper to the plugin: we have received the given message with the given perform...
struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame frame
IEEE Frame.
struct GNUNET_MessageHeader header
Type is 'GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER'.
size_t pos
How many bytes that were stored in 'buf' did we already write to the destination? Always smaller than...

References GNUNET_TRANSPORT_WLAN_Ieee80211Frame::addr1, SendBuffer::buf, HardwareInfos::fd_rfcomm, GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage::frame, get_channel(), GNUNET_memcpy, GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER, GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL, GNUNET_NETWORK_fdset_create(), GNUNET_NETWORK_fdset_handle_set(), GNUNET_NETWORK_fdset_isset(), GNUNET_NETWORK_fdset_set(), GNUNET_NETWORK_fdset_zero(), GNUNET_NETWORK_socket_accept(), GNUNET_NETWORK_socket_close(), GNUNET_NETWORK_socket_connect(), GNUNET_NETWORK_socket_create(), GNUNET_NETWORK_socket_select(), GNUNET_NETWORK_socket_send(), GNUNET_NETWORK_socket_set_blocking(), GNUNET_OK, GNUNET_SYSERR, GNUNET_TIME_relative_get_forever_(), GNUNET_TRANSPORT_WLAN_HelperControlMessage::hdr, GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage::header, HardwareInfos::iface, GNUNET_TRANSPORT_WLAN_MacAddress::mac, GNUNET_TRANSPORT_WLAN_HelperControlMessage::mac, mac_test(), MAX_PORTS, MAXLINE, mst_create(), mst_destroy(), mst_receive(), neighbours, open_device(), HardwareInfos::pl_mac, SendBuffer::pos, read_from_the_socket(), ret, HardwareInfos::session, GNUNET_MessageHeader::size, SendBuffer::size, GNUNET_CONTAINER_MultiPeerMap::size, status, stdin_mst, stdin_send_hw(), GNUNET_MessageHeader::type, write_pout, and write_std.

Here is the call graph for this function:

Variable Documentation

◆ write_pout

struct SendBuffer write_pout
static

Buffer for data read from stdin to be transmitted to the bluetooth device.

Definition at line 1 of file gnunet-helper-transport-bluetooth.c.

Referenced by main(), stdin_send(), and stdin_send_hw().

◆ write_std

struct SendBuffer write_std
static

Buffer for data read from the bluetooth device to be transmitted to stdout.

Definition at line 1 of file gnunet-helper-transport-bluetooth.c.

Referenced by file_in_send(), and main().