2 This file is part of GNUnet.
3 (C) 2010, 2011, 2012 Christian Grothoff (and other contributing authors)
4 Copyright (c) 2007, 2008, Andy Green <andy@warmcat.com>
5 Copyright (C) 2009 Thomas d'Otreppe
7 GNUnet is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published
9 by the Free Software Foundation; either version 3, or (at your
10 option) any later version.
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 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNUnet; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
22 #include "gnunet_config.h"
24 #include <bluetooth/bluetooth.h>
25 #include <bluetooth/hci.h>
26 #include <bluetooth/hci_lib.h>
27 #include <bluetooth/rfcomm.h>
28 #include <bluetooth/sdp.h>
29 #include <bluetooth/sdp_lib.h>
34 #include <sys/ioctl.h>
35 #include <sys/param.h>
36 #include <sys/socket.h>
38 #include <sys/types.h>
41 #include "gnunet_protocols.h"
42 #include "plugin_transport_wlan.h"
45 * Maximum number of ports assignable for RFCOMMM protocol.
50 * Maximum size of a message allowed in either direction
51 * (used for our receive and sent buffers).
57 * Maximum number of loops without inquiring for new devices.
62 * struct for storing the information of the hardware. There is only
69 * file descriptor for the rfcomm socket
74 * Name of the interface, not necessarily 0-terminated (!).
79 * MAC address of our own bluetooth interface.
81 struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac;
86 sdp_session_t *session ;
90 * IO buffer used for buffering data in transit (to wireless or to stdout).
95 * How many bytes of data are stored in 'buf' for transmission right now?
96 * Data always starts at offset 0 and extends to 'size'.
101 * How many bytes that were stored in 'buf' did we already write to the
102 * destination? Always smaller than 'size'.
107 * Buffered data; twice the maximum allowed message size as we add some
110 char buf[MAXLINE * 2];
114 * Devices buffer used to keep a list with all the discoverable devices in
115 * order to send them HELLO messages one by one when it receive a broadcast message.
117 struct BroadcastMessages
119 /* List with the discoverable devices' addresses */
120 bdaddr_t devices[MAX_PORTS]; //FIXME I should use a linked list but 30 isn't such a big number
122 /* List with the open sockets */
126 /* The number of the devices */
129 /* The current position */
138 * Buffer for data read from stdin to be transmitted to the bluetooth device
140 static struct SendBuffer write_pout;
143 * Buffer for data read from the bluetooth device to be transmitted to stdout.
145 static struct SendBuffer write_std;
148 * Address used to identify the broadcast messages.
150 static struct GNUNET_TRANSPORT_WLAN_MacAddress broadcast_address = {{255, 255, 255, 255, 255, 255}};
153 * Buffer with the discoverable devices.
155 static struct BroadcastMessages neighbours;
157 static int searching_devices_count = 0;
159 /* *********** specialized version of server_mst.c begins here ********** */
160 /* ****** this is the same version as the one used in gnunet-helper-transport-wlan.c ****** */
163 * To what multiple do we align messages? 8 byte should suffice for everyone
166 #define ALIGN_FACTOR 8
169 * Smallest supported message.
171 #define MIN_BUFFER_SIZE sizeof (struct GNUNET_MessageHeader)
175 * Functions with this signature are called whenever a
176 * complete message is received by the tokenizer.
179 * @param message the actual message
181 typedef void (*MessageTokenizerCallback) (void *cls,
183 GNUNET_MessageHeader *
187 * Handle to a message stream tokenizer.
189 struct MessageStreamTokenizer
193 * Function to call on completed messages.
195 MessageTokenizerCallback cb;
203 * Size of the buffer (starting at 'hdr').
208 * How many bytes in buffer have we already processed?
213 * How many bytes in buffer are valid right now?
218 * Beginning of the buffer. Typed like this to force alignment.
220 struct GNUNET_MessageHeader *hdr;
226 * Create a message stream tokenizer.
228 * @param cb function to call on completed messages
229 * @param cb_cls closure for cb
230 * @return handle to tokenizer
232 static struct MessageStreamTokenizer *
233 mst_create (MessageTokenizerCallback cb,
236 struct MessageStreamTokenizer *ret;
238 ret = malloc (sizeof (struct MessageStreamTokenizer));
241 fprintf (stderr, "Failed to allocate buffer for tokenizer\n");
244 ret->hdr = malloc (MIN_BUFFER_SIZE);
245 if (NULL == ret->hdr)
247 fprintf (stderr, "Failed to allocate buffer for alignment\n");
250 ret->curr_buf = MIN_BUFFER_SIZE;
252 ret->cb_cls = cb_cls;
260 * Add incoming data to the receive buffer and call the
261 * callback for all complete messages.
263 * @param mst tokenizer to use
264 * @param buf input data to add
265 * @param size number of bytes in buf
266 * @return GNUNET_OK if we are done processing (need more data)
267 * GNUNET_SYSERR if the data stream is corrupt
270 mst_receive (struct MessageStreamTokenizer *mst,
271 const char *buf, size_t size)
273 const struct GNUNET_MessageHeader *hdr;
278 unsigned long offset;
282 ibuf = (char *) mst->hdr;
286 if (mst->pos < mst->off)
288 //fprintf (stderr, "We processed too many bytes!\n");
289 return GNUNET_SYSERR;
291 if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) ||
292 (0 != (mst->off % ALIGN_FACTOR)))
294 /* need to align or need more space */
295 mst->pos -= mst->off;
296 memmove (ibuf, &ibuf[mst->off], mst->pos);
299 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
302 GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) -
303 (mst->pos - mst->off), size);
304 memcpy (&ibuf[mst->pos], buf, delta);
309 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
311 //FIXME should I reset ??
316 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
317 want = ntohs (hdr->size);
318 if (want < sizeof (struct GNUNET_MessageHeader))
321 "Received invalid message from stdin\n");
322 return GNUNET_SYSERR;
324 if ((mst->curr_buf - mst->off < want) &&
327 /* need more space */
328 mst->pos -= mst->off;
329 memmove (ibuf, &ibuf[mst->off], mst->pos);
332 if (want > mst->curr_buf)
336 fprintf (stderr, "Error! We should proceeded 0 bytes\n");
337 return GNUNET_SYSERR;
339 mst->hdr = realloc (mst->hdr, want);
340 if (NULL == mst->hdr)
342 fprintf (stderr, "Failed to allocate buffer for alignment\n");
345 ibuf = (char *) mst->hdr;
346 mst->curr_buf = want;
348 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
349 if (mst->pos - mst->off < want)
351 delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
352 if (mst->pos + delta > mst->curr_buf)
354 fprintf (stderr, "The size of the buffer will be exceeded!\n");
355 return GNUNET_SYSERR;
357 memcpy (&ibuf[mst->pos], buf, delta);
362 if (mst->pos - mst->off < want)
364 //FIXME should I use this?
369 mst->cb (mst->cb_cls, hdr);
371 if (mst->off == mst->pos)
373 /* reset to beginning of buffer, it's free right now! */
380 fprintf (stderr, "There should some valid bytes in the buffer on this stage\n");
381 return GNUNET_SYSERR;
385 if (size < sizeof (struct GNUNET_MessageHeader))
387 offset = (unsigned long) buf;
388 need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
389 if (GNUNET_NO == need_align)
391 /* can try to do zero-copy and process directly from original buffer */
392 hdr = (const struct GNUNET_MessageHeader *) buf;
393 want = ntohs (hdr->size);
394 if (want < sizeof (struct GNUNET_MessageHeader))
397 "Received invalid message from stdin\n");
400 return GNUNET_SYSERR;
403 break; /* or not, buffer incomplete, so copy to private buffer... */
404 mst->cb (mst->cb_cls, hdr);
410 /* need to copy to private buffer to align;
411 * yes, we go a bit more spagetti than usual here */
417 if (size + mst->pos > mst->curr_buf)
419 mst->hdr = realloc (mst->hdr, size + mst->pos);
420 if (NULL == mst->hdr)
422 fprintf (stderr, "Failed to allocate buffer for alignment\n");
425 ibuf = (char *) mst->hdr;
426 mst->curr_buf = size + mst->pos;
428 if (mst->pos + size > mst->curr_buf)
431 "Assertion failed\n");
434 memcpy (&ibuf[mst->pos], buf, size);
443 * Destroys a tokenizer.
445 * @param mst tokenizer to destroy
448 mst_destroy (struct MessageStreamTokenizer *mst)
454 /* ***************** end of server_mst.c clone ***************** **/
457 /* ****** same crc version as the one used in gnunet-helper-transport-wlan.c ****** */
460 * Calculate crc32, the start of the calculation
462 * @param buf buffer to calc the crc
463 * @param len len of the buffer
467 calc_crc_osdep (const unsigned char *buf, size_t len)
469 static const unsigned long int crc_tbl_osdep[256] = {
470 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
471 0xE963A535, 0x9E6495A3,
472 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
473 0xE7B82D07, 0x90BF1D91,
474 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
475 0xF4D4B551, 0x83D385C7,
476 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
477 0xFA0F3D63, 0x8D080DF5,
478 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
479 0xD20D85FD, 0xA50AB56B,
480 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
481 0xDCD60DCF, 0xABD13D59,
482 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
483 0xCFBA9599, 0xB8BDA50F,
484 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
485 0xC1611DAB, 0xB6662D3D,
486 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
487 0x9FBFE4A5, 0xE8B8D433,
488 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
489 0x91646C97, 0xE6635C01,
490 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
491 0x8208F4C1, 0xF50FC457,
492 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
493 0x8CD37CF3, 0xFBD44C65,
494 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
495 0xA4D1C46D, 0xD3D6F4FB,
496 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
497 0xAA0A4C5F, 0xDD0D7CC9,
498 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
499 0xB966D409, 0xCE61E49F,
500 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
501 0xB7BD5C3B, 0xC0BA6CAD,
502 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
503 0x04DB2615, 0x73DC1683,
504 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
505 0x0A00AE27, 0x7D079EB1,
506 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
507 0x196C3671, 0x6E6B06E7,
508 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
509 0x17B7BE43, 0x60B08ED5,
510 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
511 0x3FB506DD, 0x48B2364B,
512 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
513 0x316E8EEF, 0x4669BE79,
514 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
515 0x220216B9, 0x5505262F,
516 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
517 0x2CD99E8B, 0x5BDEAE1D,
518 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
519 0x72076785, 0x05005713,
520 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
521 0x7CDCEFB7, 0x0BDBDF21,
522 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
523 0x6FB077E1, 0x18B74777,
524 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
525 0x616BFFD3, 0x166CCF45,
526 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
527 0x4969474D, 0x3E6E77DB,
528 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
529 0x47B2CF7F, 0x30B5FFE9,
530 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
531 0x54DE5729, 0x23D967BF,
532 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
533 0x5A05DF1B, 0x2D02EF8D
536 unsigned long crc = 0xFFFFFFFF;
538 for (; len > 0; len--, buf++)
539 crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
545 * Calculate and check crc of the bluetooth packet
547 * @param buf buffer of the packet, with len + 4 bytes of data,
548 * the last 4 bytes being the checksum
549 * @param len length of the payload in data
550 * @return 0 on success (checksum matches), 1 on error
553 check_crc_buf_osdep (const unsigned char *buf, size_t len)
557 crc = calc_crc_osdep (buf, len);
559 if (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
560 ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3])
567 /* ************** end of crc version ***************** */
573 * Function for assigning a port number
575 * @param socket the socket used to bind
576 * @param addr pointer to the rfcomm address
577 * @return 0 on success
580 bind_socket (int socket, struct sockaddr_rc *addr)
584 /* Bind every possible port (from 0 to 30) and stop when binding doesn't fail */
585 //FIXME : it should start from port 1, but on my computer it doesn't work :)
586 for (port = 3; port <= 30; port++)
588 addr->rc_channel = port;
589 status = bind (socket, (struct sockaddr *) addr, sizeof (struct sockaddr_rc));
599 * Function used for creating the service record and registering it.
601 * @param dev pointer to the device struct
602 * @param rc_channel the rfcomm channel
603 * @return 0 on success
606 register_service (struct HardwareInfos *dev, int rc_channel)
610 * 2. set the service ID, class, profile information
611 * 3. make the service record publicly browsable
612 * 4. register the RFCOMM channel
613 * 5. set the name, provider and description
614 * 6. register the service record to the local SDP server
617 uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
618 dev->pl_mac.mac[5], dev->pl_mac.mac[4], dev->pl_mac.mac[3],
619 dev->pl_mac.mac[2], dev->pl_mac.mac[1], dev->pl_mac.mac[0]};
620 const char *service_dsc = "Bluetooth plugin services";
621 const char *service_prov = "GNUnet provider";
622 uuid_t root_uuid, rfcomm_uuid, svc_uuid;
623 sdp_list_t *root_list = 0, *rfcomm_list = 0, *proto_list = 0,
624 *access_proto_list = 0, *svc_list = 0;
625 sdp_record_t *record = 0;
626 sdp_data_t *channel = 0;
628 record = sdp_record_alloc();
630 /* Set the general service ID */
631 sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
632 svc_list = sdp_list_append (0, &svc_uuid);
633 sdp_set_service_classes (record, svc_list);
634 sdp_set_service_id (record, svc_uuid);
636 /* Make the service record publicly browsable */
637 sdp_uuid16_create (&root_uuid, PUBLIC_BROWSE_GROUP);
638 root_list = sdp_list_append (0, &root_uuid);
639 sdp_set_browse_groups (record, root_list);
641 /* Register the RFCOMM channel */
642 sdp_uuid16_create (&rfcomm_uuid, RFCOMM_UUID);
643 channel = sdp_data_alloc (SDP_UINT8, &rc_channel);
644 rfcomm_list = sdp_list_append (0, &rfcomm_uuid);
645 sdp_list_append (rfcomm_list, channel);
646 proto_list = sdp_list_append (0, rfcomm_list);
648 /* Set protocol information */
649 access_proto_list = sdp_list_append (0, proto_list);
650 sdp_set_access_protos (record, access_proto_list);
652 /* Set the name, provider, and description */
653 sdp_set_info_attr (record, dev->iface, service_prov, service_dsc);
655 /* Connect to the local SDP server */
656 dev->session = sdp_connect (BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
660 fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
661 IFNAMSIZ, dev->iface, strerror (errno));
666 /* Register the service record */
667 if (sdp_record_register (dev->session, record, 0) < 0)
669 fprintf (stderr, "Failed to register a service record on interface `%.*s': %s\n",
670 IFNAMSIZ, dev->iface, strerror (errno));
676 sdp_data_free (channel);
677 sdp_list_free (root_list, 0);
678 sdp_list_free (rfcomm_list, 0);
679 sdp_list_free (proto_list, 0);
680 sdp_list_free (access_proto_list, 0);
681 sdp_list_free (svc_list, 0);
682 sdp_record_free (record);
688 * Function for searching and browsing for a service. This will return the
689 * port number on which the service is running.
691 * @param dev pointer to the device struct
692 * @param dest target address
696 get_channel(struct HardwareInfos *dev, bdaddr_t dest)
699 * 1. detect all nearby devices
700 * 2. for each device:
701 * 2.1. connect to the SDP server running
702 * 2.2. get a list of service records with the specific UUID
703 * 2.3. for each service record get a list of the protocol sequences and get
706 uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
707 dest.b[5], dest.b[4], dest.b[3],
708 dest.b[2], dest.b[1], dest.b[0]};
709 sdp_session_t *session = 0;
710 sdp_list_t *search_list = 0, *attrid_list = 0, *response_list = 0, *it = 0;
712 uint32_t range = 0x0000ffff;
713 uint8_t channel = -1;
715 /* Connect to the local SDP server */
716 session = sdp_connect (BDADDR_ANY, &dest, 0);
719 fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
720 IFNAMSIZ, dev->iface, strerror (errno));
725 sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
726 search_list = sdp_list_append (0, &svc_uuid);
727 attrid_list = sdp_list_append (0, &range);
729 if (sdp_service_search_attr_req (session, search_list,
730 SDP_ATTR_REQ_RANGE, attrid_list, &response_list) == 0)
732 for (it = response_list; it; it = it->next)
734 sdp_record_t *record = (sdp_record_t*) it->data;
735 //TODO print some record informations to be sure everything is good
736 sdp_list_t *proto_list = 0;
737 if (sdp_get_access_protos (record, &proto_list) == 0)
739 channel = sdp_get_proto_port (proto_list, RFCOMM_UUID);
740 sdp_list_free (proto_list, 0);
742 sdp_record_free (record);
746 sdp_list_free (search_list, 0);
747 sdp_list_free (attrid_list, 0);
748 sdp_list_free (response_list, 0);
753 fprintf (stderr, "Failed to find the listening channel for interface `%.*s': %s\n",
754 IFNAMSIZ, dev->iface, strerror (errno));
760 * Read from the socket and put the result into the buffer for transmission to 'stdout'.
762 * @param sock file descriptor for reading
763 * @param buf buffer to read to; first bytes will be the 'struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame',
764 * followed by the actual payload
765 * @param buf_size size of the buffer
766 * @param ri where to write radiotap_rx info
767 * @return number of bytes written to 'buf'
770 read_from_the_socket (int sock,
771 unsigned char *buf, size_t buf_size,
772 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri)
774 unsigned char tmpbuf[buf_size];
777 struct sockaddr_rc rc_addr = { 0 };
779 count = read (sock, tmpbuf, buf_size);
786 fprintf (stderr, "Failed to read from the HCI socket: %s\n", strerror (errno));
790 /* Get the channel used */ //FIXME probably not needed anymore
791 memset (&rc_addr, 0, sizeof (rc_addr));
792 len = sizeof (rc_addr);
793 if (0 > getsockname (sock, (struct sockaddr *) &rc_addr, (socklen_t *) &len))
795 fprintf (stderr, "getsockname() call failed : %s\n", strerror (errno));
799 memset (ri, 0, sizeof (*ri));
800 ri->ri_channel = rc_addr.rc_channel;
802 /* Detect CRC32 at the end */
803 if (0 == check_crc_buf_osdep (tmpbuf, count - sizeof (uint32_t)))
805 count -= sizeof(uint32_t);
808 memcpy (buf, tmpbuf, count);
814 * Open the bluetooth interface for reading/writing
816 * @param dev pointer to the device struct
817 * @return 0 on success
820 open_device (struct HardwareInfos *dev)
822 int i, dev_id = -1, fd_hci;
825 struct hci_dev_list_req list;
826 struct hci_dev_req dev[HCI_MAX_DEV];
827 } request; //used for detecting the local devices
828 struct sockaddr_rc rc_addr = { 0 }; //used for binding
830 /* Initialize the neighbour structure */
831 neighbours.dev_id = -1;
832 for (i = 0; i < MAX_PORTS; i++)
833 neighbours.fds[i] = -1;
835 /* Open a HCI socket */
836 fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
840 fprintf (stderr, "Failed to create HCI socket: %s\n", strerror (errno));
844 memset (&request, 0, sizeof(request));
845 request.list.dev_num = HCI_MAX_DEV;
847 if (ioctl (fd_hci, HCIGETDEVLIST, (void *) &request) < 0)
849 fprintf (stderr, "ioctl(HCIGETDEVLIST) on interface `%.*s' failed: %s\n",
850 IFNAMSIZ, dev->iface, strerror (errno));
854 /* Search for a device with dev->iface name */
855 for (i = 0; i < request.list.dev_num; i++)
857 struct hci_dev_info dev_info;
859 memset (&dev_info, 0, sizeof(struct hci_dev_info));
860 dev_info.dev_id = request.dev[i].dev_id;
861 strncpy (dev_info.name, dev->iface, IFNAMSIZ);
863 if (ioctl (fd_hci, HCIGETDEVINFO, (void *) &dev_info))
865 fprintf (stderr, "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n",
866 IFNAMSIZ, dev->iface, strerror (errno));
870 if (strcmp (dev_info.name, dev->iface) == 0)
873 dev_id = dev_info.dev_id; //the device was found
875 * Copy the MAC address to the device structure
877 memcpy (&dev->pl_mac, &dev_info.bdaddr, sizeof (bdaddr_t));
879 /* Check if the interface is up */
880 if (hci_test_bit (HCI_UP, (void *) &dev_info.flags) == 0)
882 /* Bring the interface up */
883 if (ioctl (fd_hci, HCIDEVUP, dev_info.dev_id))
885 fprintf (stderr, "ioctl(HCIDEVUP) on interface `%.*s' failed: %s\n",
886 IFNAMSIZ, dev->iface, strerror (errno));
891 /* Check if the device is discoverable */
892 if (hci_test_bit (HCI_PSCAN, (void *) &dev_info.flags) == 0 ||
893 hci_test_bit (HCI_ISCAN, (void *) &dev_info.flags) == 0)
895 /* Set interface Page Scan and Inqury Scan ON */
896 struct hci_dev_req dev_req;
898 memset (&dev_req, 0, sizeof (dev_req));
899 dev_req.dev_id = dev_info.dev_id;
900 dev_req.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
902 if (ioctl (fd_hci, HCISETSCAN, (unsigned long) &dev_req))
904 fprintf (stderr, "ioctl(HCISETSCAN) on interface `%.*s' failed: %s\n",
905 IFNAMSIZ, dev->iface, strerror (errno));
915 /* Check if the interface was not found */
918 fprintf (stderr, "The interface %s was not found\n", dev->iface);
922 /* Close the hci socket */
923 (void) close(fd_hci);
927 /* Bind the rfcomm socket to the interface */
928 memset (&rc_addr, 0, sizeof (rc_addr));
929 rc_addr.rc_family = AF_BLUETOOTH;
930 rc_addr.rc_bdaddr = *BDADDR_ANY;
932 if (bind_socket (dev->fd_rfcomm, &rc_addr) != 0)
934 fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
935 dev->iface, strerror (errno));
939 /* Register a SDP service */
940 if (register_service (dev, rc_addr.rc_channel) != 0)
942 fprintf (stderr, "Failed to register a service on interface `%.*s': %s\n", IFNAMSIZ,
943 dev->iface, strerror (errno));
947 /* Switch socket in listening mode */
948 if (listen (dev->fd_rfcomm, 5) == -1) //FIXME: probably we need a bigger number
950 fprintf (stderr, "Failed to listen on socket for interface `%.*s': %s\n", IFNAMSIZ,
951 dev->iface, strerror (errno));
961 * Set the header to sane values to make attacks more difficult
963 * @param taIeeeHeader pointer to the header of the packet
964 * @param dev pointer to the Hardware_Infos struct
966 **** copy from gnunet-helper-transport-wlan.c ****
969 mac_set (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
970 const struct HardwareInfos *dev)
972 taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
973 taIeeeHeader->addr2 = dev->pl_mac;
974 taIeeeHeader->addr3 = mac_bssid_gnunet;
978 * Test if the given interface name really corresponds to a bluetooth
981 * @param iface name of the interface
982 * @return 0 on success, 1 on error
983 **** similar with the one from gnunet-helper-transport-wlan.c ****
986 test_bluetooth_interface (const char *iface)
992 ret = snprintf (strbuf, sizeof (strbuf),
993 "/sys/class/bluetooth/%s/subsystem",
995 if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
998 "Did not find 802.15.1 interface `%s'. Exiting.\n",
1006 * Test incoming packets mac for being our own.
1008 * @param taIeeeHeader buffer of the packet
1009 * @param dev the Hardware_Infos struct
1010 * @return 0 if mac belongs to us, 1 if mac is for another target
1012 **** same as the one from gnunet-helper-transport-wlan.c ****
1015 mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1016 const struct HardwareInfos *dev)
1018 static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
1020 if ( (0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
1021 (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)) )
1022 return 0; /* some drivers set no Macs, then assume it is all for us! */
1024 if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1025 return 1; /* not a GNUnet ad-hoc package */
1026 if ( (0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
1027 (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)) )
1028 return 0; /* for us, or broadcast */
1029 return 1; /* not for us */
1034 * Process data from the stdin. Takes the message, forces the sender MAC to be correct
1035 * and puts it into our buffer for transmission to the receiver.
1037 * @param cls pointer to the device struct ('struct HardwareInfos*')
1038 * @param hdr pointer to the start of the packet
1040 **** same as the one from gnunet-helper-transport-wlan.c ****
1043 stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1045 struct HardwareInfos *dev = cls;
1046 const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header;
1047 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *blueheader;
1050 sendsize = ntohs (hdr->size);
1052 sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
1053 (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) )
1055 fprintf (stderr, "Received malformed message\n");
1058 sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) -
1059 sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1060 if (MAXLINE < sendsize)
1062 fprintf (stderr, "Packet too big for buffer\n");
1065 header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
1066 memcpy (&write_pout.buf, &header->frame, sendsize);
1067 blueheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf;
1069 /* payload contains MAC address, but we don't trust it, so we'll
1070 * overwrite it with OUR MAC address to prevent mischief */
1071 mac_set (blueheader, dev);
1072 memcpy (&blueheader->addr1, &header->frame.addr1,
1073 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1074 write_pout.size = sendsize;
1078 * Broadcast a HELLO message for peer discovery
1080 * @param dev pointer to the device struct
1081 * @param dev pointer to the socket which was added to the set
1082 * @return 0 on success
1085 send_broadcast (struct HardwareInfos *dev, int *sendsocket)
1091 if ((neighbours.size == neighbours.pos && new_device == 1) || neighbours.size == 0)
1093 inquiry_devices: //skip the conditions and force a inquiry for new devices
1096 * It means that I sent HELLO messages to all the devices from the list and I should search
1097 * for new ones or that this is the first time when I do a search.
1099 inquiry_info *devices = NULL;
1100 int i, responses, max_responses = MAX_PORTS;
1103 if (neighbours.size >= MAX_PORTS)
1105 fprintf (stderr, "%.*s reached the top limit for the discovarable devices\n", IFNAMSIZ, dev->iface);
1109 /* Get the device id */
1110 if (neighbours.dev_id == -1)
1112 char addr[19] = { 0 }; //the device MAC address
1114 ba2str ((bdaddr_t *) &dev->pl_mac, addr);
1115 neighbours.dev_id = hci_devid (addr);
1116 if (neighbours.dev_id < 0)
1118 fprintf (stderr, "Failed to get the device id for interface %.*s : %s\n", IFNAMSIZ,
1119 dev->iface, strerror (errno));
1124 devices = malloc (max_responses * sizeof (inquiry_info));
1125 if (devices == NULL)
1127 fprintf (stderr, "Failed to allocate memory for inquiry info list on interface %.*s\n", IFNAMSIZ,
1132 responses = hci_inquiry (neighbours.dev_id, 8, max_responses, NULL, &devices, IREQ_CACHE_FLUSH);
1135 fprintf (stderr, "Failed to inquiry on interface %.*s\n", IFNAMSIZ, dev->iface);
1139 fprintf (stderr, "LOG : Found %d devices\n", responses); //FIXME delete it after debugging stage
1143 fprintf (stderr, "LOG : No devices discoverable\n");
1147 for (i = 0; i < responses; i++)
1155 fprintf (stderr, "%.*s reached the top limit for the discoverable devices (after inquiry)\n", IFNAMSIZ,
1160 /* Search if the address already exists on the list */
1161 for (j = 0; j < neighbours.size; j++)
1163 if (memcmp (&(devices + i)->bdaddr, &(neighbours.devices[j]), sizeof (bdaddr_t)) == 0)
1166 fprintf (stderr, "LOG : the device already exists on the list\n"); //FIXME debugging message
1173 char addr[19] = { 0 };
1175 ba2str (&(devices +i)->bdaddr, addr);
1176 fprintf (stderr, "LOG : %s was added to the list\n", addr); //FIXME debugging message
1177 memcpy (&(neighbours.devices[neighbours.size++]), &(devices + i)->bdaddr, sizeof (bdaddr_t));
1185 int connection_successful = 0;
1186 struct sockaddr_rc addr_rc = { 0 };
1188 addr_rc.rc_family = AF_BLUETOOTH;
1190 /* Try to connect to a new device from the list */
1191 while (neighbours.pos < neighbours.size)
1193 /* Check if we are already connected to this device */
1194 if (neighbours.fds[neighbours.pos] == -1)
1197 memset (&addr_rc.rc_bdaddr, 0, sizeof (addr_rc.rc_bdaddr));
1198 memcpy (&addr_rc.rc_bdaddr, &(neighbours.devices[neighbours.pos]), sizeof (addr_rc.rc_bdaddr));
1200 addr_rc.rc_channel = get_channel (dev, addr_rc.rc_bdaddr);
1202 *sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1203 if (connect (*sendsocket, (struct sockaddr *)&addr_rc, sizeof (addr_rc)) == 0)
1205 neighbours.fds[neighbours.pos++] = *sendsocket;
1206 connection_successful = 1;
1207 char addr[19] = { 0 };
1208 ba2str (&(neighbours.devices[neighbours.pos - 1]), addr);
1209 fprintf (stderr, "LOG : Connected to %s\n", addr);
1215 char addr[19] = { 0 };
1216 errno_copy = errno; //Save a copy for later
1217 ba2str (&(neighbours.devices[neighbours.pos]), addr);
1218 fprintf (stderr, "LOG : Couldn't connect on device %s, error : %s\n", addr, strerror(errno));
1219 if (errno != ECONNREFUSED) //FIXME be sure that this works
1221 fprintf (stderr, "LOG : Removes %d device from the list\n", neighbours.pos);
1222 /* Remove the device from the list */
1223 memcpy (&neighbours.devices[neighbours.pos], &neighbours.devices[neighbours.size - 1], sizeof (bdaddr_t));
1224 memset (&neighbours.devices[neighbours.size - 1], 0, sizeof (bdaddr_t));
1225 neighbours.fds[neighbours.pos] = neighbours.fds[neighbours.size - 1];
1226 neighbours.fds[neighbours.size - 1] = -1;
1227 neighbours.size -= 1;
1230 neighbours.pos += 1;
1232 if (neighbours.pos >= neighbours.size)
1237 if (loops == MAX_LOOPS) //don't get stuck trying to connect to one device
1243 fprintf (stderr, "LOG : Search for a new device\n"); //FIXME debugging message
1244 neighbours.pos += 1;
1248 /* Cycle on the list */
1249 if (neighbours.pos == neighbours.size)
1252 searching_devices_count += 1;
1254 if (searching_devices_count == MAX_LOOPS)
1256 fprintf (stderr, "LOG : Force to inquiry for new devices\n");
1257 searching_devices_count = 0;
1258 goto inquiry_devices;
1261 /* If a new device wasn't found, search an old one */
1262 if (connection_successful == 0)
1264 int loop_check = neighbours.pos;
1265 while (neighbours.fds[neighbours.pos] == -1)
1267 if (neighbours.pos == neighbours.size)
1270 if (neighbours.pos == loop_check)
1272 if (errno_copy == ECONNREFUSED)
1274 fprintf (stderr, "LOG : No device found. Go back and search again\n"); //FIXME debugging message
1277 goto search_for_devices;
1281 return 1; // Skip the broadcast message
1285 neighbours.pos += 1;
1288 *sendsocket = neighbours.fds[neighbours.pos++];
1295 * Main function of the helper. This code accesses a bluetooth interface
1296 * forwards traffic in both directions between the bluetooth interface and
1297 * stdin/stdout of this process. Error messages are written to stderr.
1299 * @param argc number of arguments, must be 2
1300 * @param argv arguments only argument is the name of the interface (i.e. 'hci0')
1301 * @return 0 on success (never happens, as we don't return unless aborted), 1 on error
1303 **** similar to gnunet-helper-transport-wlan.c ****
1306 main (int argc, char *argv[])
1308 struct HardwareInfos dev;
1309 char readbuf[MAXLINE];
1314 struct MessageStreamTokenizer *stdin_mst;
1317 int crt_rfds = 0, rfds_list[MAX_PORTS];
1318 int broadcast, sendsocket;
1319 /* Assert privs so we can modify the firewall rules! */
1321 #ifdef HAVE_SETRESUID
1322 if (0 != setresuid (uid, 0, 0))
1324 fprintf (stderr, "Failed to setresuid to root: %s\n", strerror (errno));
1328 if (0 != seteuid (0))
1330 fprintf (stderr, "Failed to seteuid back to root: %s\n", strerror (errno));
1335 /* Make use of SGID capabilities on POSIX */
1336 memset (&dev, 0, sizeof (dev));
1337 dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1338 raw_eno = errno; /* remember for later */
1340 /* Now that we've dropped root rights, we can do error checking */
1343 fprintf (stderr, "You must specify the name of the interface as the first \
1344 and only argument to this program.\n");
1345 if (-1 != dev.fd_rfcomm)
1346 (void) close (dev.fd_rfcomm);
1350 if (-1 == dev.fd_rfcomm)
1352 fprintf (stderr, "Failed to create a HCI socket: %s\n", strerror (raw_eno));
1355 if (dev.fd_rfcomm >= FD_SETSIZE)
1357 fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1358 dev.fd_rfcomm, FD_SETSIZE);
1359 (void) close (dev.fd_rfcomm);
1362 if (0 != test_bluetooth_interface (argv[1]))
1364 (void) close (dev.fd_rfcomm);
1367 strncpy (dev.iface, argv[1], IFNAMSIZ);
1368 if (0 != open_device (&dev))
1370 (void) close (dev.fd_rfcomm);
1376 uid_t uid = getuid ();
1377 #ifdef HAVE_SETRESUID
1378 if (0 != setresuid (uid, uid, uid))
1380 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1381 if (-1 != dev.fd_rfcomm)
1382 (void) close (dev.fd_rfcomm);
1386 if (0 != (setuid (uid) | seteuid (uid)))
1388 fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
1389 if (-1 != dev.fd_rfcomm)
1390 (void) close (dev.fd_rfcomm);
1396 /* Send MAC address of the bluetooth interface to STDOUT first */
1398 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
1400 macmsg.hdr.size = htons (sizeof (macmsg));
1401 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
1402 memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1403 memcpy (write_std.buf, &macmsg, sizeof (macmsg));
1404 write_std.size = sizeof (macmsg);
1408 stdin_mst = mst_create (&stdin_send_hw, &dev);
1411 fprintf (stderr, "\n-----------------------------------------------\n Check if the program exits\n-----------------------------------------------\n");
1413 * TODO : When a connection fails I should ignore only the CONTROL messages.
1414 * For DATA messages I should retry to send the message until it doesn't fail
1415 * Also I should make the time out of a mac endpoint smaller and check if the rate
1416 * from get_wlan_header (plugin_transport_bluetooth.c) is correct.
1425 if ((0 == write_pout.size) && (1 == stdin_open))
1427 FD_SET (STDIN_FILENO, &rfds);
1428 maxfd = MAX (maxfd, STDIN_FILENO);
1430 if (0 == write_std.size)
1432 FD_SET (dev.fd_rfcomm, &rfds);
1433 maxfd = MAX (maxfd, dev.fd_rfcomm);
1436 for (i = 0; i < crt_rfds; i++) // it can receive messages from multiple devices
1438 FD_SET (rfds_list[i], &rfds);
1439 maxfd = MAX (maxfd, rfds_list[i]);
1442 if (0 < write_std.size)
1444 FD_SET (STDOUT_FILENO, &wfds);
1445 maxfd = MAX (maxfd, STDOUT_FILENO);
1447 if (0 < write_pout.size) //it can send messages only to one device per loop
1449 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *frame;
1450 /* Get the destination address */
1451 frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) write_pout.buf;
1453 if (memcmp (&frame->addr1, &dev.pl_mac,
1454 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1457 memset (&write_pout, 0, sizeof (write_pout)); //clear the buffer
1459 else if (memcmp (&frame->addr1, &broadcast_address,
1460 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1462 fprintf (stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n", dev.iface, neighbours.pos, neighbours.size); //FIXME: debugging message
1463 // broadcast = 1; // IF I HAVE A BROADCAST MESSAGE I skip.
1464 // memset (&write_pout, 0, sizeof (write_pout));
1466 if (send_broadcast(&dev, &sendsocket) != 0) //if the searching wasn't successful don't get stuck on the select stage
1469 memset (&write_pout, 0, sizeof (write_pout)); //remove the message
1470 fprintf (stderr, "LOG : Skip the broadcast message (pos %d, size %d)\n", neighbours.pos, neighbours.size);
1474 FD_SET (sendsocket, &wfds);
1475 maxfd = MAX (maxfd, sendsocket);
1482 /* Search if the address already exists on the list */
1483 for (i = 0; i < neighbours.size; i++)
1485 if (memcmp (&frame->addr1, &(neighbours.devices[i]), sizeof (bdaddr_t)) == 0)
1488 if (neighbours.fds[i] != -1)
1490 found = 1; //save the position where it was found
1491 FD_SET (neighbours.fds[i], &wfds);
1492 maxfd = MAX (maxfd, neighbours.fds[i]);
1493 sendsocket = neighbours.fds[i];
1494 fprintf (stderr, "LOG: the address was found in the list\n");
1502 struct sockaddr_rc addr = { 0 };
1504 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,
1505 frame->addr1.mac[5], frame->addr1.mac[4], frame->addr1.mac[3],
1506 frame->addr1.mac[2], frame->addr1.mac[1], frame->addr1.mac[0]); //FIXME: debugging message
1508 sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1512 fprintf (stderr, "Failed to create a RFCOMM socket (sending stage): %s\n",
1517 memcpy (&addr.rc_bdaddr, &frame->addr1, sizeof (bdaddr_t));
1518 addr.rc_family = AF_BLUETOOTH;
1519 addr.rc_channel = get_channel (&dev, addr.rc_bdaddr);
1523 status = connect (sendsocket, (struct sockaddr *) &addr, sizeof (addr));
1524 if (0 != status && errno != EAGAIN)
1526 if (errno == ECONNREFUSED && tries < 2)
1528 fprintf (stderr, "LOG : %.*s failed to connect. Trying again!\n", IFNAMSIZ, dev.iface);
1532 else if (errno == EBADF)
1534 fprintf (stderr, "LOG : %s failed to connect : %s. Skip it!\n", dev.iface, strerror (errno));
1535 memset (&write_pout, 0, sizeof (write_pout));
1540 fprintf (stderr, "LOG : %s failed to connect : %s. Try again later!\n", dev.iface, strerror (errno));
1541 memset (&write_pout, 0, sizeof (write_pout));
1548 FD_SET (sendsocket, &wfds);
1549 maxfd = MAX (maxfd, sendsocket);
1550 fprintf (stderr, "LOG : Connection successful\n");
1551 if (pos != 0) // save the socket
1553 neighbours.fds[pos] = sendsocket;
1557 /* Add the new device to the discovered devices list */
1558 if (neighbours.size < MAX_PORTS)
1560 neighbours.fds[neighbours.size] = sendsocket;
1561 memcpy (&(neighbours.devices[neighbours.size++]), &addr.rc_bdaddr, sizeof (bdaddr_t));
1565 fprintf (stderr, "The top limit for the discovarable devices' list was reached\n");
1575 /* Select a fd which is ready for action :) */
1577 int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
1578 if ((-1 == retval) && (EINTR == errno))
1580 if (0 > retval && errno != EBADF) // we handle BADF errors later
1582 fprintf (stderr, "select failed: %s\n", strerror (errno));
1586 if (FD_ISSET (STDOUT_FILENO , &wfds))
1589 write (STDOUT_FILENO, write_std.buf + write_std.pos,
1590 write_std.size - write_std.pos);
1593 fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1596 write_std.pos += ret;
1597 if (write_std.pos == write_std.size)
1602 fprintf (stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); //FIXME: debugging message
1605 if (sendsocket != -1)
1607 if (FD_ISSET (sendsocket , &wfds))
1610 write (sendsocket, write_pout.buf + write_std.pos,
1611 write_pout.size - write_pout.pos);
1612 if (0 > ret) //FIXME should I first check the error type?
1614 fprintf (stderr, "Failed to write to bluetooth device: %s. Closing the socket!\n",
1616 for (i = 0; i < neighbours.size; i++)
1618 if (neighbours.fds[i] == sendsocket)
1620 (void) close(sendsocket);
1621 neighbours.fds[i] = -1;
1625 /* Remove the message */
1626 memset (&write_pout.buf + write_std.pos, 0, (write_pout.size - write_pout.pos));
1627 write_pout.pos = 0 ;
1628 write_pout.size = 0;
1632 write_pout.pos += ret;
1633 if ((write_pout.pos != write_pout.size) && (0 != ret))
1635 /* We should not get partial sends with packet-oriented devices... */
1636 fprintf (stderr, "Write error, partial send: %u/%u\n",
1637 (unsigned int) write_pout.pos,
1638 (unsigned int) write_pout.size);
1642 if (write_pout.pos == write_pout.size)
1645 write_pout.size = 0;
1647 fprintf (stderr, "LOG : %s sends a message to a DEVICE\n", dev.iface); //FIXME: debugging message
1651 for (i = 0; i <= maxfd; i++)
1653 if (FD_ISSET (i, &rfds))
1655 if (i == STDIN_FILENO)
1658 read (i, readbuf, sizeof (readbuf));
1661 fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno));
1666 /* stop reading... */
1671 mst_receive (stdin_mst, readbuf, ret);
1672 fprintf (stderr, "LOG : %s receives a message from STDIN\n", dev.iface); //FIXME: debugging message
1675 else if (i == dev.fd_rfcomm)
1678 struct sockaddr_rc addr = { 0 };
1679 unsigned int opt = sizeof (addr);
1681 readsocket = accept (dev.fd_rfcomm, (struct sockaddr *) &addr, &opt);
1682 fprintf(stderr, "LOG : %s accepts a message\n", dev.iface); //FIXME: debugging message
1683 if (readsocket == -1)
1685 fprintf (stderr, "Failed to accept a connection on interface: %.*s\n", IFNAMSIZ,
1691 FD_SET (readsocket, &rfds);
1692 maxfd = MAX (maxfd, readsocket);
1694 if (crt_rfds < MAX_PORTS)
1695 rfds_list[crt_rfds++] = readsocket;
1698 fprintf (stderr, "The limit for the read file descriptors list was \
1707 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
1709 fprintf (stderr, "LOG : %s reads something from the socket\n", dev.iface);//FIXME : debugging message
1710 rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
1712 read_from_the_socket (i, (unsigned char *) &rrm->frame,
1713 sizeof (write_std.buf)
1714 - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
1715 + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
1722 /* Remove the socket from the list */
1723 for (j = 0; j < crt_rfds; j++)
1725 if (rfds_list[j] == i)
1727 rfds_list[j] ^= rfds_list[crt_rfds - 1];
1728 rfds_list[crt_rfds - 1] ^= rfds_list[j];
1729 rfds_list[j] ^= rfds_list[crt_rfds - 1];
1735 fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
1738 if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
1740 write_std.size = ret
1741 + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
1742 - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
1743 rrm->header.size = htons (write_std.size);
1744 rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
1751 /* Error handling, try to clean up a bit at least */
1752 mst_destroy (stdin_mst);
1754 sdp_close (dev.session);
1755 (void) close (dev.fd_rfcomm);
1756 (void) close (sendsocket);
1758 for (i = 0; i < crt_rfds; i++)
1759 (void) close (rfds_list[i]);
1761 for (i = 0; i < neighbours.size; i++)
1762 (void) close (neighbours.fds[i]);
1764 return 1; /* we never exit 'normally' */