2 This file is part of GNUnet.
3 Copyright (C) 2010, 2011, 2012 GNUnet e.V.
4 Copyright (C) 2007, 2008, Andy Green <andy@warmcat.com>
5 Copyright (C) 2009 Thomas d'Otreppe
7 GNUnet is free software: you can redistribute it and/or modify it
8 under the terms of the GNU Affero General Public License as published
9 by the Free Software Foundation, either version 3 of the License,
10 or (at your option) any later version.
12 GNUnet is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Affero General Public License for more details.
17 You should have received a copy of the GNU Affero General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 SPDX-License-Identifier: AGPL3.0-or-later
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 "plugin_transport_wlan.h"
42 #include "gnunet_protocols.h"
46 * Maximum number of ports assignable for RFCOMMM protocol.
51 * Maximum size of a message allowed in either direction
52 * (used for our receive and sent buffers).
58 * Maximum number of loops without inquiring for new devices.
63 * In bluez library, the maximum name length of a device is 8
65 #define BLUEZ_DEVNAME_SIZE 8
68 * struct for storing the information of the hardware. There is only
74 * Name of the interface, not necessarily 0-terminated (!).
79 * file descriptor for the rfcomm socket
84 * MAC address of our own bluetooth interface.
86 struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac;
91 sdp_session_t *session;
95 * IO buffer used for buffering data in transit (to wireless or to stdout).
100 * How many bytes of data are stored in 'buf' for transmission right now?
101 * Data always starts at offset 0 and extends to 'size'.
106 * How many bytes that were stored in 'buf' did we already write to the
107 * destination? Always smaller than 'size'.
112 * Buffered data; twice the maximum allowed message size as we add some
115 char buf[MAXLINE * 2];
120 * Devices buffer used to keep a list with all the discoverable devices in
121 * order to send them HELLO messages one by one when it receive a broadcast message.
123 struct BroadcastMessages
125 /* List with the discoverable devices' addresses */
126 bdaddr_t devices[MAX_PORTS];
128 /* List with the open sockets */
132 /* The number of the devices */
135 /* The current position */
143 * Address used to identify the broadcast messages.
145 static struct GNUNET_TRANSPORT_WLAN_MacAddress broadcast_address = { { 255, 255,
151 * Buffer with the discoverable devices.
153 static struct BroadcastMessages neighbours;
155 static int searching_devices_count = 0;
159 * Buffer for data read from stdin to be transmitted to the bluetooth device
161 static struct SendBuffer write_pout;
164 * Buffer for data read from the bluetooth device to be transmitted to stdout.
166 static struct SendBuffer write_std;
169 /* ****** this are the same functions as the ones used in gnunet-helper-transport-wlan.c ****** */
172 * To what multiple do we align messages? 8 byte should suffice for everyone
175 #define ALIGN_FACTOR 8
178 * Smallest supported message.
180 #define MIN_BUFFER_SIZE sizeof(struct GNUNET_MessageHeader)
184 * Functions with this signature are called whenever a
185 * complete message is received by the tokenizer.
188 * @param message the actual message
190 typedef void (*MessageTokenizerCallback) (void *cls,
192 GNUNET_MessageHeader *
196 * Handle to a message stream tokenizer.
198 struct MessageStreamTokenizer
201 * Function to call on completed messages.
203 MessageTokenizerCallback cb;
211 * Size of the buffer (starting at 'hdr').
216 * How many bytes in buffer have we already processed?
221 * How many bytes in buffer are valid right now?
226 * Beginning of the buffer. Typed like this to force alignment.
228 struct GNUNET_MessageHeader *hdr;
233 * Create a message stream tokenizer.
235 * @param cb function to call on completed messages
236 * @param cb_cls closure for cb
237 * @return handle to tokenizer
239 static struct MessageStreamTokenizer *
240 mst_create (MessageTokenizerCallback cb,
243 struct MessageStreamTokenizer *ret;
245 ret = malloc (sizeof(struct MessageStreamTokenizer));
248 fprintf (stderr, "Failed to allocate buffer for tokenizer\n");
251 ret->hdr = malloc (MIN_BUFFER_SIZE);
252 if (NULL == ret->hdr)
254 fprintf (stderr, "Failed to allocate buffer for alignment\n");
257 ret->curr_buf = MIN_BUFFER_SIZE;
259 ret->cb_cls = cb_cls;
267 * Add incoming data to the receive buffer and call the
268 * callback for all complete messages.
270 * @param mst tokenizer to use
271 * @param buf input data to add
272 * @param size number of bytes in buf
273 * @return GNUNET_OK if we are done processing (need more data)
274 * GNUNET_SYSERR if the data stream is corrupt
277 mst_receive (struct MessageStreamTokenizer *mst,
278 const char *buf, size_t size)
280 const struct GNUNET_MessageHeader *hdr;
285 unsigned long offset;
289 ibuf = (char *) mst->hdr;
293 if (mst->pos < mst->off)
295 // fprintf (stderr, "We processed too many bytes!\n");
296 return GNUNET_SYSERR;
298 if ((mst->curr_buf - mst->off < sizeof(struct GNUNET_MessageHeader)) ||
299 (0 != (mst->off % ALIGN_FACTOR)))
301 /* need to align or need more space */
302 mst->pos -= mst->off;
303 memmove (ibuf, &ibuf[mst->off], mst->pos);
306 if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader))
309 GNUNET_MIN (sizeof(struct GNUNET_MessageHeader)
310 - (mst->pos - mst->off), size);
311 GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
316 if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader))
318 // FIXME should I reset ??
323 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
324 want = ntohs (hdr->size);
325 if (want < sizeof(struct GNUNET_MessageHeader))
328 "Received invalid message from stdin\n");
329 return GNUNET_SYSERR;
331 if ((mst->curr_buf - mst->off < want) &&
334 /* need more space */
335 mst->pos -= mst->off;
336 memmove (ibuf, &ibuf[mst->off], mst->pos);
339 if (want > mst->curr_buf)
343 fprintf (stderr, "Error! We should proceeded 0 bytes\n");
344 return GNUNET_SYSERR;
346 mst->hdr = realloc (mst->hdr, want);
347 if (NULL == mst->hdr)
349 fprintf (stderr, "Failed to allocate buffer for alignment\n");
352 ibuf = (char *) mst->hdr;
353 mst->curr_buf = want;
355 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
356 if (mst->pos - mst->off < want)
358 delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
359 if (mst->pos + delta > mst->curr_buf)
361 fprintf (stderr, "The size of the buffer will be exceeded!\n");
362 return GNUNET_SYSERR;
364 GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
369 if (mst->pos - mst->off < want)
371 // FIXME should I use this?
376 mst->cb (mst->cb_cls, hdr);
378 if (mst->off == mst->pos)
380 /* reset to beginning of buffer, it's free right now! */
388 "There should some valid bytes in the buffer on this stage\n");
389 return GNUNET_SYSERR;
393 if (size < sizeof(struct GNUNET_MessageHeader))
395 offset = (unsigned long) buf;
396 need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
397 if (GNUNET_NO == need_align)
399 /* can try to do zero-copy and process directly from original buffer */
400 hdr = (const struct GNUNET_MessageHeader *) buf;
401 want = ntohs (hdr->size);
402 if (want < sizeof(struct GNUNET_MessageHeader))
405 "Received invalid message from stdin\n");
408 return GNUNET_SYSERR;
411 break; /* or not, buffer incomplete, so copy to private buffer... */
412 mst->cb (mst->cb_cls, hdr);
418 /* need to copy to private buffer to align;
419 * yes, we go a bit more spagetti than usual here */
425 if (size + mst->pos > mst->curr_buf)
427 mst->hdr = realloc (mst->hdr, size + mst->pos);
428 if (NULL == mst->hdr)
430 fprintf (stderr, "Failed to allocate buffer for alignment\n");
433 ibuf = (char *) mst->hdr;
434 mst->curr_buf = size + mst->pos;
436 if (mst->pos + size > mst->curr_buf)
439 "Assertion failed\n");
442 GNUNET_memcpy (&ibuf[mst->pos], buf, size);
450 * Destroys a tokenizer.
452 * @param mst tokenizer to destroy
455 mst_destroy (struct MessageStreamTokenizer *mst)
463 * Calculate crc32, the start of the calculation
465 * @param buf buffer to calc the crc
466 * @param len len of the buffer
470 calc_crc_osdep (const unsigned char *buf, size_t len)
472 static const unsigned long int crc_tbl_osdep[256] = {
473 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
474 0xE963A535, 0x9E6495A3,
475 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
476 0xE7B82D07, 0x90BF1D91,
477 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
478 0xF4D4B551, 0x83D385C7,
479 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
480 0xFA0F3D63, 0x8D080DF5,
481 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
482 0xD20D85FD, 0xA50AB56B,
483 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
484 0xDCD60DCF, 0xABD13D59,
485 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
486 0xCFBA9599, 0xB8BDA50F,
487 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
488 0xC1611DAB, 0xB6662D3D,
489 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
490 0x9FBFE4A5, 0xE8B8D433,
491 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
492 0x91646C97, 0xE6635C01,
493 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
494 0x8208F4C1, 0xF50FC457,
495 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
496 0x8CD37CF3, 0xFBD44C65,
497 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
498 0xA4D1C46D, 0xD3D6F4FB,
499 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
500 0xAA0A4C5F, 0xDD0D7CC9,
501 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
502 0xB966D409, 0xCE61E49F,
503 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
504 0xB7BD5C3B, 0xC0BA6CAD,
505 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
506 0x04DB2615, 0x73DC1683,
507 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
508 0x0A00AE27, 0x7D079EB1,
509 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
510 0x196C3671, 0x6E6B06E7,
511 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
512 0x17B7BE43, 0x60B08ED5,
513 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
514 0x3FB506DD, 0x48B2364B,
515 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
516 0x316E8EEF, 0x4669BE79,
517 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
518 0x220216B9, 0x5505262F,
519 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
520 0x2CD99E8B, 0x5BDEAE1D,
521 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
522 0x72076785, 0x05005713,
523 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
524 0x7CDCEFB7, 0x0BDBDF21,
525 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
526 0x6FB077E1, 0x18B74777,
527 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
528 0x616BFFD3, 0x166CCF45,
529 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
530 0x4969474D, 0x3E6E77DB,
531 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
532 0x47B2CF7F, 0x30B5FFE9,
533 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
534 0x54DE5729, 0x23D967BF,
535 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
536 0x5A05DF1B, 0x2D02EF8D
539 unsigned long crc = 0xFFFFFFFF;
541 for (; len > 0; len--, buf++)
542 crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
548 * Calculate and check crc of the bluetooth packet
550 * @param buf buffer of the packet, with len + 4 bytes of data,
551 * the last 4 bytes being the checksum
552 * @param len length of the payload in data
553 * @return 0 on success (checksum matches), 1 on error
556 check_crc_buf_osdep (const unsigned char *buf, size_t len)
560 crc = calc_crc_osdep (buf, len);
562 if ((((crc) & 0xFF) == buf[0]) && (((crc >> 8) & 0xFF) == buf[1]) &&
563 ( ((crc >> 16) & 0xFF) == buf[2]) && ( ((crc >> 24) & 0xFF) == buf[3]) )
569 /* ************** end of clone ***************** */
572 * Function for assigning a port number
574 * @param socket the socket used to bind
575 * @param addr pointer to the rfcomm address
576 * @return 0 on success
579 bind_socket (int socket, struct sockaddr_rc *addr)
583 /* Bind every possible port (from 0 to 30) and stop when binding doesn't fail */
584 // FIXME : it should start from port 1, but on my computer it doesn't work :)
585 for (port = 3; port <= 30; port++)
587 addr->rc_channel = port;
588 status = bind (socket, (struct sockaddr *) addr, sizeof(struct
601 * Function used for creating the service record and registering it.
603 * @param dev pointer to the device struct
604 * @param rc_channel the rfcomm channel
605 * @return 0 on success
608 register_service (struct HardwareInfos *dev, int rc_channel)
612 * 2. set the service ID, class, profile information
613 * 3. make the service record publicly browsable
614 * 4. register the RFCOMM channel
615 * 5. set the name, provider and description
616 * 6. register the service record to the local SDP server
618 */uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
619 dev->pl_mac.mac[5], dev->pl_mac.mac[4],
621 dev->pl_mac.mac[2], dev->pl_mac.mac[1],
622 dev->pl_mac.mac[0] };
623 const char *service_dsc = "Bluetooth plugin services";
624 const char *service_prov = "GNUnet provider";
625 uuid_t root_uuid, rfcomm_uuid, svc_uuid;
626 sdp_list_t *root_list = 0, *rfcomm_list = 0, *proto_list = 0,
627 *access_proto_list = 0, *svc_list = 0;
628 sdp_record_t *record = 0;
629 sdp_data_t *channel = 0;
631 record = sdp_record_alloc ();
633 /* Set the general service ID */
634 sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
635 svc_list = sdp_list_append (0, &svc_uuid);
636 sdp_set_service_classes (record, svc_list);
637 sdp_set_service_id (record, svc_uuid);
639 /* Make the service record publicly browsable */
640 sdp_uuid16_create (&root_uuid, PUBLIC_BROWSE_GROUP);
641 root_list = sdp_list_append (0, &root_uuid);
642 sdp_set_browse_groups (record, root_list);
644 /* Register the RFCOMM channel */
645 sdp_uuid16_create (&rfcomm_uuid, RFCOMM_UUID);
646 channel = sdp_data_alloc (SDP_UINT8, &rc_channel);
647 rfcomm_list = sdp_list_append (0, &rfcomm_uuid);
648 sdp_list_append (rfcomm_list, channel);
649 proto_list = sdp_list_append (0, rfcomm_list);
651 /* Set protocol information */
652 access_proto_list = sdp_list_append (0, proto_list);
653 sdp_set_access_protos (record, access_proto_list);
655 /* Set the name, provider, and description */
656 sdp_set_info_attr (record, dev->iface, service_prov, service_dsc);
658 /* Connect to the local SDP server */
659 dev->session = sdp_connect (BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
664 "Failed to connect to the SDP server on interface `%.*s': %s\n",
665 IFNAMSIZ, dev->iface, strerror (errno));
670 /* Register the service record */
671 if (sdp_record_register (dev->session, record, 0) < 0)
674 "Failed to register a service record on interface `%.*s': %s\n",
675 IFNAMSIZ, dev->iface, strerror (errno));
681 sdp_data_free (channel);
682 sdp_list_free (root_list, 0);
683 sdp_list_free (rfcomm_list, 0);
684 sdp_list_free (proto_list, 0);
685 sdp_list_free (access_proto_list, 0);
686 sdp_list_free (svc_list, 0);
687 sdp_record_free (record);
694 * Function used for searching and browsing for a service. This will return the
695 * port number on which the service is running.
697 * @param dev pointer to the device struct
698 * @param dest target address
702 get_channel (struct HardwareInfos *dev, bdaddr_t dest)
705 * 1. detect all nearby devices
706 * 2. for each device:
707 * 2.1. connect to the SDP server running
708 * 2.2. get a list of service records with the specific UUID
709 * 2.3. for each service record get a list of the protocol sequences and get
711 */uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
712 dest.b[5], dest.b[4], dest.b[3],
713 dest.b[2], dest.b[1], dest.b[0] };
714 sdp_session_t *session = 0;
715 sdp_list_t *search_list = 0, *attrid_list = 0, *response_list = 0, *it = 0;
717 uint32_t range = 0x0000ffff;
720 /* Connect to the local SDP server */
721 session = sdp_connect (BDADDR_ANY, &dest, 0);
725 "Failed to connect to the SDP server on interface `%.*s': %s\n",
726 IFNAMSIZ, dev->iface, strerror (errno));
730 sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
731 search_list = sdp_list_append (0, &svc_uuid);
732 attrid_list = sdp_list_append (0, &range);
734 if (sdp_service_search_attr_req (session, search_list,
735 SDP_ATTR_REQ_RANGE, attrid_list,
736 &response_list) == 0)
738 for (it = response_list; it; it = it->next)
740 sdp_record_t *record = (sdp_record_t *) it->data;
741 sdp_list_t *proto_list = 0;
742 if (sdp_get_access_protos (record, &proto_list) == 0)
744 channel = sdp_get_proto_port (proto_list, RFCOMM_UUID);
745 sdp_list_free (proto_list, 0);
747 sdp_record_free (record);
751 sdp_list_free (search_list, 0);
752 sdp_list_free (attrid_list, 0);
753 sdp_list_free (response_list, 0);
759 "Failed to find the listening channel for interface `%.*s': %s\n",
769 * Read from the socket and put the result into the buffer for transmission to 'stdout'.
771 * @param sock file descriptor for reading
772 * @param buf buffer to read to; first bytes will be the 'struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame',
773 * followed by the actual payload
774 * @param buf_size size of the buffer
775 * @param ri where to write radiotap_rx info
776 * @return number of bytes written to 'buf'
779 read_from_the_socket (void *sock,
780 unsigned char *buf, size_t buf_size,
781 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri)
783 unsigned char tmpbuf[buf_size];
785 count = read (*((int *) sock), tmpbuf, buf_size);
792 fprintf (stderr, "Failed to read from the HCI socket: %s\n", strerror (
799 /* Get the channel used */
801 struct sockaddr_rc rc_addr = { 0 };
803 memset (&rc_addr, 0, sizeof(rc_addr));
804 len = sizeof(rc_addr);
805 if (0 > getsockname (*((int *) sock), (struct sockaddr *) &rc_addr,
808 fprintf (stderr, "getsockname() call failed : %s\n", strerror (errno));
812 memset (ri, 0, sizeof(*ri));
813 ri->ri_channel = rc_addr.rc_channel;
816 /* Detect CRC32 at the end */
817 if (0 == check_crc_buf_osdep (tmpbuf, count - sizeof(uint32_t)))
819 count -= sizeof(uint32_t);
822 GNUNET_memcpy (buf, tmpbuf, count);
829 * Open the bluetooth interface for reading/writing
831 * @param dev pointer to the device struct
832 * @return 0 on success, non-zero on error
835 open_device (struct HardwareInfos *dev)
837 int i, dev_id = -1, fd_hci;
840 struct hci_dev_list_req list;
841 struct hci_dev_req dev[HCI_MAX_DEV];
842 } request; // used for detecting the local devices
843 struct sockaddr_rc rc_addr = { 0 }; // used for binding
845 /* Initialize the neighbour structure */
846 neighbours.dev_id = -1;
847 for (i = 0; i < MAX_PORTS; i++)
848 neighbours.fds[i] = -1;
850 /* Open a HCI socket */
851 fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
856 "Failed to create HCI socket: %s\n",
861 memset (&request, 0, sizeof(request));
862 request.list.dev_num = HCI_MAX_DEV;
864 if (ioctl (fd_hci, HCIGETDEVLIST, (void *) &request) < 0)
867 "ioctl(HCIGETDEVLIST) on interface `%.*s' failed: %s\n",
871 (void) close (fd_hci);
875 /* Search for a device with dev->iface name */
876 for (i = 0; i < request.list.dev_num; i++)
878 struct hci_dev_info dev_info;
880 memset (&dev_info, 0, sizeof(struct hci_dev_info));
881 dev_info.dev_id = request.dev[i].dev_id;
882 strncpy (dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE);
884 if (ioctl (fd_hci, HCIGETDEVINFO, (void *) &dev_info))
887 "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n",
891 (void) close (fd_hci);
895 if (strncmp (dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE) == 0)
897 dev_id = dev_info.dev_id; // the device was found
899 * Copy the MAC address to the device structure
901 GNUNET_memcpy (&dev->pl_mac, &dev_info.bdaddr, sizeof(bdaddr_t));
903 /* Check if the interface is up */
904 if (hci_test_bit (HCI_UP, (void *) &dev_info.flags) == 0)
906 /* Bring the interface up */
907 if (ioctl (fd_hci, HCIDEVUP, dev_info.dev_id))
910 "ioctl(HCIDEVUP) on interface `%.*s' failed: %s\n",
914 (void) close (fd_hci);
919 /* Check if the device is discoverable */
920 if ((hci_test_bit (HCI_PSCAN, (void *) &dev_info.flags) == 0) ||
921 (hci_test_bit (HCI_ISCAN, (void *) &dev_info.flags) == 0) )
923 /* Set interface Page Scan and Inqury Scan ON */
924 struct hci_dev_req dev_req;
926 memset (&dev_req, 0, sizeof(dev_req));
927 dev_req.dev_id = dev_info.dev_id;
928 dev_req.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
930 if (ioctl (fd_hci, HCISETSCAN, (unsigned long) &dev_req))
933 "ioctl(HCISETSCAN) on interface `%.*s' failed: %s\n",
937 (void) close (fd_hci);
945 /* Check if the interface was not found */
949 "The interface %s was not found\n",
951 (void) close (fd_hci);
955 /* Close the hci socket */
956 (void) close (fd_hci);
959 /* Bind the rfcomm socket to the interface */
960 memset (&rc_addr, 0, sizeof(rc_addr));
961 rc_addr.rc_family = AF_BLUETOOTH;
962 rc_addr.rc_bdaddr = *BDADDR_ANY;
964 if (bind_socket (dev->fd_rfcomm, &rc_addr) != 0)
967 "Failed to bind interface `%.*s': %s\n",
974 /* Register a SDP service */
975 if (register_service (dev, rc_addr.rc_channel) != 0)
978 "Failed to register a service on interface `%.*s': %s\n",
980 dev->iface, strerror (errno));
984 /* Switch socket in listening mode */
985 if (listen (dev->fd_rfcomm, 5) == -1) // FIXME: probably we need a bigger number
987 fprintf (stderr, "Failed to listen on socket for interface `%.*s': %s\n",
989 dev->iface, strerror (errno));
998 * Set the header to sane values to make attacks more difficult
1000 * @param taIeeeHeader pointer to the header of the packet
1001 * @param dev pointer to the Hardware_Infos struct
1003 **** copy from gnunet-helper-transport-wlan.c ****
1006 mac_set (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1007 const struct HardwareInfos *dev)
1009 taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
1010 taIeeeHeader->addr3 = mac_bssid_gnunet;
1011 taIeeeHeader->addr2 = dev->pl_mac;
1017 * Test if the given interface name really corresponds to a bluetooth
1020 * @param iface name of the interface
1021 * @return 0 on success, 1 on error
1022 **** similar with the one from gnunet-helper-transport-wlan.c ****
1025 test_bluetooth_interface (const char *iface)
1031 ret = snprintf (strbuf, sizeof(strbuf),
1032 "/sys/class/bluetooth/%s/subsystem",
1034 if ((ret < 0) || (ret >= sizeof(strbuf)) || (0 != stat (strbuf, &sbuf)))
1037 "Did not find 802.15.1 interface `%s'. Exiting.\n",
1048 * Test incoming packets mac for being our own.
1050 * @param taIeeeHeader buffer of the packet
1051 * @param dev the Hardware_Infos struct
1052 * @return 0 if mac belongs to us, 1 if mac is for another target
1054 **** same as the one from gnunet-helper-transport-wlan.c ****
1057 mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1058 const struct HardwareInfos *dev)
1060 static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
1062 if ((0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
1063 (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)))
1064 return 0; /* some drivers set no Macs, then assume it is all for us! */
1066 if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1067 return 1; /* not a GNUnet ad-hoc package */
1068 if ((0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
1069 (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)))
1070 return 0; /* for us, or broadcast */
1071 return 1; /* not for us */
1076 * Process data from the stdin. Takes the message, forces the sender MAC to be correct
1077 * and puts it into our buffer for transmission to the receiver.
1079 * @param cls pointer to the device struct ('struct HardwareInfos*')
1080 * @param hdr pointer to the start of the packet
1082 **** same as the one from gnunet-helper-transport-wlan.c ****
1085 stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1087 struct HardwareInfos *dev = cls;
1088 const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header;
1089 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *blueheader;
1092 sendsize = ntohs (hdr->size);
1094 sizeof(struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
1095 (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)))
1097 fprintf (stderr, "Received malformed message\n");
1100 sendsize -= (sizeof(struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)
1101 - sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1102 if (MAXLINE < sendsize)
1104 fprintf (stderr, "Packet too big for buffer\n");
1107 header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
1108 GNUNET_memcpy (&write_pout.buf, &header->frame, sendsize);
1109 blueheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf;
1111 /* payload contains MAC address, but we don't trust it, so we'll
1112 * overwrite it with OUR MAC address to prevent mischief */
1113 mac_set (blueheader, dev);
1114 GNUNET_memcpy (&blueheader->addr1, &header->frame.addr1,
1115 sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress));
1116 write_pout.size = sendsize;
1122 * Broadcast a HELLO message for peer discovery
1124 * @param dev pointer to the device struct
1125 * @param dev pointer to the socket which was added to the set
1126 * @return 0 on success
1129 send_broadcast (struct HardwareInfos *dev, int *sendsocket)
1135 if (((neighbours.size == neighbours.pos) && (new_device == 1)) ||
1136 (neighbours.size == 0) )
1138 inquiry_devices: // skip the conditions and force a inquiry for new devices
1141 * It means that I sent HELLO messages to all the devices from the list and I should search
1142 * for new ones or that this is the first time when I do a search.
1144 inquiry_info *devices = NULL;
1145 int i, responses, max_responses = MAX_PORTS;
1148 if (neighbours.size >= MAX_PORTS)
1151 "%.*s reached the top limit for the discovarable devices\n",
1157 /* Get the device id */
1158 if (neighbours.dev_id == -1)
1160 char addr[19] = { 0 }; // the device MAC address
1162 ba2str ((bdaddr_t *) &dev->pl_mac, addr);
1163 neighbours.dev_id = hci_devid (addr);
1164 if (neighbours.dev_id < 0)
1167 "Failed to get the device id for interface %.*s : %s\n",
1169 dev->iface, strerror (errno));
1174 devices = malloc (max_responses * sizeof(inquiry_info));
1175 if (devices == NULL)
1178 "Failed to allocate memory for inquiry info list on interface %.*s\n",
1184 responses = hci_inquiry (neighbours.dev_id, 8, max_responses, NULL,
1185 &devices, IREQ_CACHE_FLUSH);
1188 fprintf (stderr, "Failed to inquiry on interface %.*s\n", IFNAMSIZ,
1193 fprintf (stderr, "LOG : Found %d devices\n", responses); // FIXME delete it after debugging stage
1197 fprintf (stderr, "LOG : No devices discoverable\n");
1201 for (i = 0; i < responses; i++)
1210 "%.*s reached the top limit for the discoverable devices (after inquiry)\n",
1216 /* Search if the address already exists on the list */
1217 for (j = 0; j < neighbours.size; j++)
1219 if (memcmp (&(devices + i)->bdaddr, &(neighbours.devices[j]),
1220 sizeof(bdaddr_t)) == 0)
1223 fprintf (stderr, "LOG : the device already exists on the list\n"); // FIXME debugging message
1230 char addr[19] = { 0 };
1232 ba2str (&(devices + i)->bdaddr, addr);
1233 fprintf (stderr, "LOG : %s was added to the list\n", addr); // FIXME debugging message
1234 GNUNET_memcpy (&(neighbours.devices[neighbours.size++]), &(devices
1236 bdaddr, sizeof(bdaddr_t));
1244 int connection_successful = 0;
1245 struct sockaddr_rc addr_rc = { 0 };
1247 addr_rc.rc_family = AF_BLUETOOTH;
1249 /* Try to connect to a new device from the list */
1250 while (neighbours.pos < neighbours.size)
1252 /* Check if we are already connected to this device */
1253 if (neighbours.fds[neighbours.pos] == -1)
1255 memset (&addr_rc.rc_bdaddr, 0, sizeof(addr_rc.rc_bdaddr));
1256 GNUNET_memcpy (&addr_rc.rc_bdaddr, &(neighbours.devices[neighbours.pos]),
1257 sizeof(addr_rc.rc_bdaddr));
1259 addr_rc.rc_channel = get_channel (dev, addr_rc.rc_bdaddr);
1261 *sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1262 if ((-1 < *sendsocket) &&
1263 (0 == connect (*sendsocket,
1264 (struct sockaddr *) &addr_rc,
1267 neighbours.fds[neighbours.pos++] = *sendsocket;
1268 connection_successful = 1;
1269 char addr[19] = { 0 };
1270 ba2str (&(neighbours.devices[neighbours.pos - 1]), addr);
1271 fprintf (stderr, "LOG : Connected to %s\n", addr);
1276 char addr[19] = { 0 };
1277 errno_copy = errno; // Save a copy for later
1279 if (-1 != *sendsocket)
1281 (void) close (*sendsocket);
1284 ba2str (&(neighbours.devices[neighbours.pos]), addr);
1286 "LOG : Couldn't connect on device %s, error : %s\n",
1289 if (errno != ECONNREFUSED) // FIXME be sure that this works
1291 fprintf (stderr, "LOG : Removes %d device from the list\n",
1293 /* Remove the device from the list */
1294 GNUNET_memcpy (&neighbours.devices[neighbours.pos],
1295 &neighbours.devices[neighbours.size - 1],
1297 memset (&neighbours.devices[neighbours.size - 1], 0,
1299 neighbours.fds[neighbours.pos] = neighbours.fds[neighbours.size - 1];
1300 neighbours.fds[neighbours.size - 1] = -1;
1301 neighbours.size -= 1;
1304 neighbours.pos += 1;
1306 if (neighbours.pos >= neighbours.size)
1311 if (loops == MAX_LOOPS) // don't get stuck trying to connect to one device
1317 fprintf (stderr, "LOG : Search for a new device\n"); // FIXME debugging message
1318 neighbours.pos += 1;
1322 /* Cycle on the list */
1323 if (neighbours.pos == neighbours.size)
1326 searching_devices_count += 1;
1328 if (searching_devices_count == MAX_LOOPS)
1330 fprintf (stderr, "LOG : Force to inquiry for new devices\n");
1331 searching_devices_count = 0;
1332 goto inquiry_devices;
1335 /* If a new device wasn't found, search an old one */
1336 if (connection_successful == 0)
1338 int loop_check = neighbours.pos;
1339 while (neighbours.fds[neighbours.pos] == -1)
1341 if (neighbours.pos == neighbours.size)
1344 if (neighbours.pos == loop_check)
1346 if (errno_copy == ECONNREFUSED)
1348 fprintf (stderr, "LOG : No device found. Go back and search again\n"); // FIXME debugging message
1351 goto search_for_devices;
1355 return 1; // Skip the broadcast message
1359 neighbours.pos += 1;
1362 *sendsocket = neighbours.fds[neighbours.pos++];
1372 * Main function of the helper. This code accesses a bluetooth interface
1373 * forwards traffic in both directions between the bluetooth interface and
1374 * stdin/stdout of this process. Error messages are written to stderr.
1376 * @param argc number of arguments, must be 2
1377 * @param argv arguments only argument is the name of the interface (i.e. 'hci0')
1378 * @return 0 on success (never happens, as we don't return unless aborted), 1 on error
1380 **** similar to gnunet-helper-transport-wlan.c ****
1383 main (int argc, char *argv[])
1386 struct HardwareInfos dev;
1387 char readbuf[MAXLINE];
1392 struct MessageStreamTokenizer *stdin_mst;
1394 int crt_rfds = 0, rfds_list[MAX_PORTS];
1395 int broadcast, sendsocket;
1397 /* Assert privs so we can modify the firewall rules! */
1399 #ifdef HAVE_SETRESUID
1400 uid_t uid = getuid ();
1402 if (0 != setresuid (uid, 0, 0))
1405 "Failed to setresuid to root: %s\n",
1410 if (0 != seteuid (0))
1413 "Failed to seteuid back to root: %s\n", strerror (errno));
1419 /* Make use of SGID capabilities on POSIX */
1420 memset (&dev, 0, sizeof(dev));
1421 dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1422 raw_eno = errno; /* remember for later */
1424 /* Now that we've dropped root rights, we can do error checking */
1428 "You must specify the name of the interface as the first \
1429 and only argument to this program.\n");
1430 if (-1 != dev.fd_rfcomm)
1431 (void) close (dev.fd_rfcomm);
1435 if (-1 == dev.fd_rfcomm)
1437 fprintf (stderr, "Failed to create a RFCOMM socket: %s\n", strerror (
1441 if (dev.fd_rfcomm >= FD_SETSIZE)
1443 fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1444 dev.fd_rfcomm, FD_SETSIZE);
1445 (void) close (dev.fd_rfcomm);
1448 if (0 != test_bluetooth_interface (argv[1]))
1450 (void) close (dev.fd_rfcomm);
1453 strncpy (dev.iface, argv[1], IFNAMSIZ);
1454 if (0 != open_device (&dev))
1456 (void) close (dev.fd_rfcomm);
1462 uid_t uid = getuid ();
1463 #ifdef HAVE_SETRESUID
1464 if (0 != setresuid (uid, uid, uid))
1466 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1467 if (-1 != dev.fd_rfcomm)
1468 (void) close (dev.fd_rfcomm);
1472 if (0 != (setuid (uid) | seteuid (uid)))
1474 fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
1475 if (-1 != dev.fd_rfcomm)
1476 (void) close (dev.fd_rfcomm);
1482 /* Send MAC address of the bluetooth interface to STDOUT first */
1484 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
1486 macmsg.hdr.size = htons (sizeof(macmsg));
1487 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
1488 GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof(struct
1489 GNUNET_TRANSPORT_WLAN_MacAddress));
1490 GNUNET_memcpy (write_std.buf, &macmsg, sizeof(macmsg));
1491 write_std.size = sizeof(macmsg);
1495 stdin_mst = mst_create (&stdin_send_hw, &dev);
1499 * TODO : I should make the time out of a mac endpoint smaller and check if the rate
1500 * from get_wlan_header (plugin_transport_bluetooth.c) is correct.
1509 if ((0 == write_pout.size) && (1 == stdin_open))
1511 FD_SET (STDIN_FILENO, &rfds);
1512 maxfd = MAX (maxfd, STDIN_FILENO);
1514 if (0 == write_std.size)
1516 FD_SET (dev.fd_rfcomm, &rfds);
1517 maxfd = MAX (maxfd, dev.fd_rfcomm);
1520 for (i = 0; i < crt_rfds; i++) // it can receive messages from multiple devices
1522 FD_SET (rfds_list[i], &rfds);
1523 maxfd = MAX (maxfd, rfds_list[i]);
1526 if (0 < write_std.size)
1528 FD_SET (STDOUT_FILENO, &wfds);
1529 maxfd = MAX (maxfd, STDOUT_FILENO);
1531 if (0 < write_pout.size) // it can send messages only to one device per loop
1533 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *frame;
1534 /* Get the destination address */
1535 frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) write_pout.buf;
1537 if (memcmp (&frame->addr1, &dev.pl_mac,
1538 sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1541 memset (&write_pout, 0, sizeof(write_pout)); // clear the buffer
1543 else if (memcmp (&frame->addr1, &broadcast_address,
1544 sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1546 fprintf (stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n",
1547 dev.iface, neighbours.pos, neighbours.size); // FIXME: debugging message
1549 if (send_broadcast (&dev, &sendsocket) != 0) // if the searching wasn't successful don't get stuck on the select stage
1552 memset (&write_pout, 0, sizeof(write_pout)); // remove the message
1554 "LOG : Skipping the broadcast message (pos %d, size %d)\n",
1555 neighbours.pos, neighbours.size);
1559 FD_SET (sendsocket, &wfds);
1560 maxfd = MAX (maxfd, sendsocket);
1567 /* Search if the address already exists on the list */
1568 for (i = 0; i < neighbours.size; i++)
1570 if (memcmp (&frame->addr1, &(neighbours.devices[i]),
1571 sizeof(bdaddr_t)) == 0)
1574 if (neighbours.fds[i] != -1)
1576 found = 1; // save the position where it was found
1577 FD_SET (neighbours.fds[i], &wfds);
1578 maxfd = MAX (maxfd, neighbours.fds[i]);
1579 sendsocket = neighbours.fds[i];
1580 fprintf (stderr, "LOG: the address was found in the list\n");
1588 struct sockaddr_rc addr = { 0 };
1591 "LOG : %s has a new message for %.2X:%.2X:%.2X:%.2X:%.2X:%.2X which isn't on the broadcast list\n",
1593 frame->addr1.mac[5], frame->addr1.mac[4],
1594 frame->addr1.mac[3],
1595 frame->addr1.mac[2], frame->addr1.mac[1],
1596 frame->addr1.mac[0]); // FIXME: debugging message
1598 sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1603 "Failed to create a RFCOMM socket (sending stage): %s\n",
1608 GNUNET_memcpy (&addr.rc_bdaddr, &frame->addr1, sizeof(bdaddr_t));
1609 addr.rc_family = AF_BLUETOOTH;
1610 addr.rc_channel = get_channel (&dev, addr.rc_bdaddr);
1614 status = connect (sendsocket, (struct sockaddr *) &addr,
1616 if ((0 != status) && (errno != EAGAIN) )
1618 if ((errno == ECONNREFUSED) && (tries < 2) )
1620 fprintf (stderr, "LOG : %.*s failed to connect. Trying again!\n",
1621 IFNAMSIZ, dev.iface);
1625 else if (errno == EBADF)
1627 fprintf (stderr, "LOG : %s failed to connect : %s. Skip it!\n",
1628 dev.iface, strerror (errno));
1629 memset (&write_pout, 0, sizeof(write_pout));
1635 "LOG : %s failed to connect : %s. Try again later!\n",
1638 memset (&write_pout, 0, sizeof(write_pout));
1644 FD_SET (sendsocket, &wfds);
1645 maxfd = MAX (maxfd, sendsocket);
1646 fprintf (stderr, "LOG : Connection successful\n");
1647 if (pos != 0) // save the socket
1649 neighbours.fds[pos] = sendsocket;
1653 /* Add the new device to the discovered devices list */
1654 if (neighbours.size < MAX_PORTS)
1656 neighbours.fds[neighbours.size] = sendsocket;
1657 GNUNET_memcpy (&(neighbours.devices[neighbours.size++]),
1658 &addr.rc_bdaddr, sizeof(bdaddr_t));
1663 "The top limit for the discovarable devices' list was reached\n");
1673 /* Select a fd which is ready for action :) */
1675 int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
1676 if ((-1 == retval) && (EINTR == errno))
1678 if ((0 > retval) && (errno != EBADF) ) // we handle BADF errors later
1680 fprintf (stderr, "select failed: %s\n", strerror (errno));
1684 if (FD_ISSET (STDOUT_FILENO, &wfds))
1687 write (STDOUT_FILENO, write_std.buf + write_std.pos,
1688 write_std.size - write_std.pos);
1691 fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1694 write_std.pos += ret;
1695 if (write_std.pos == write_std.size)
1700 fprintf (stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); // FIXME: debugging message
1702 if (-1 != sendsocket)
1704 if (FD_ISSET (sendsocket, &wfds))
1706 ssize_t ret = write (sendsocket,
1707 write_pout.buf + write_std.pos,
1708 write_pout.size - write_pout.pos);
1709 if (0 > ret) // FIXME should I first check the error type?
1712 "Failed to write to bluetooth device: %s. Closing the socket!\n",
1714 for (i = 0; i < neighbours.size; i++)
1716 if (neighbours.fds[i] == sendsocket)
1718 (void) close (sendsocket);
1719 neighbours.fds[i] = -1;
1723 /* Remove the message */
1724 memset (&write_pout.buf + write_std.pos, 0, (write_pout.size
1727 write_pout.size = 0;
1731 write_pout.pos += ret;
1732 if ((write_pout.pos != write_pout.size) && (0 != ret))
1734 /* We should not get partial sends with packet-oriented devices... */
1735 fprintf (stderr, "Write error, partial send: %u/%u\n",
1736 (unsigned int) write_pout.pos,
1737 (unsigned int) write_pout.size);
1741 if (write_pout.pos == write_pout.size)
1744 write_pout.size = 0;
1746 fprintf (stderr, "LOG : %s sends a message to a DEVICE\n",
1747 dev.iface); // FIXME: debugging message
1751 for (i = 0; i <= maxfd; i++)
1753 if (FD_ISSET (i, &rfds))
1755 if (i == STDIN_FILENO)
1758 read (i, readbuf, sizeof(readbuf));
1762 "Read error from STDIN: %s\n",
1768 /* stop reading... */
1773 mst_receive (stdin_mst, readbuf, ret);
1774 fprintf (stderr, "LOG : %s receives a message from STDIN\n",
1775 dev.iface); // FIXME: debugging message
1778 else if (i == dev.fd_rfcomm)
1781 struct sockaddr_rc addr = { 0 };
1782 unsigned int opt = sizeof(addr);
1784 readsocket = accept (dev.fd_rfcomm, (struct sockaddr *) &addr,
1786 fprintf (stderr, "LOG : %s accepts a message\n", dev.iface); // FIXME: debugging message
1787 if (readsocket == -1)
1790 "Failed to accept a connection on interface: %.*s\n",
1797 FD_SET (readsocket, &rfds);
1798 maxfd = MAX (maxfd, readsocket);
1800 if (crt_rfds < MAX_PORTS)
1801 rfds_list[crt_rfds++] = readsocket;
1805 "The limit for the read file descriptors list was \
1813 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
1815 fprintf (stderr, "LOG : %s reads something from the socket\n",
1816 dev.iface); // FIXME : debugging message
1818 GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
1820 read_from_the_socket ((void *) &i, (unsigned char *) &rrm->frame,
1821 sizeof(write_std.buf)
1823 GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
1825 GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
1832 /* Remove the socket from the list */
1833 for (j = 0; j < crt_rfds; j++)
1835 if (rfds_list[j] == i)
1837 rfds_list[j] ^= rfds_list[crt_rfds - 1];
1838 rfds_list[crt_rfds - 1] ^= rfds_list[j];
1839 rfds_list[j] ^= rfds_list[crt_rfds - 1];
1845 fprintf (stderr, "Read error from raw socket: %s\n", strerror (
1849 if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
1851 write_std.size = ret
1853 GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
1855 GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
1856 rrm->header.size = htons (write_std.size);
1857 rrm->header.type = htons (
1858 GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
1865 /* Error handling, try to clean up a bit at least */
1866 mst_destroy (stdin_mst);
1868 sdp_close (dev.session);
1869 (void) close (dev.fd_rfcomm);
1870 if (-1 != sendsocket)
1871 (void) close (sendsocket);
1873 for (i = 0; i < crt_rfds; i++)
1874 (void) close (rfds_list[i]);
1876 for (i = 0; i < neighbours.size; i++)
1877 (void) close (neighbours.fds[i]);
1879 struct HardwareInfos dev;
1880 struct GNUNET_NETWORK_Handle *sendsocket;
1881 struct GNUNET_NETWORK_FDSet *rfds;
1882 struct GNUNET_NETWORK_FDSet *wfds;
1883 struct GNUNET_NETWORK_Handle *rfds_list[MAX_PORTS];
1884 char readbuf[MAXLINE] = { 0 };
1885 SOCKADDR_BTH acc_addr = { 0 };
1886 int addr_len = sizeof(SOCKADDR_BTH);
1887 int broadcast, i, stdin_open, crt_rfds = 0;
1888 HANDLE stdin_handle = GetStdHandle (STD_INPUT_HANDLE);
1889 HANDLE stdout_handle = GetStdHandle (STD_OUTPUT_HANDLE);
1890 struct MessageStreamTokenizer *stdin_mst;
1892 /* check the handles */
1893 if (stdin_handle == INVALID_HANDLE_VALUE)
1895 fprintf (stderr, "Failed to get the stdin handle\n");
1899 if (stdout_handle == INVALID_HANDLE_VALUE)
1901 fprintf (stderr, "Failed to get the stdout handle\n");
1905 /* initialize windows sockets */
1906 initialize_windows_sockets ();
1908 // /* test bluetooth socket family support */ --> it return false because the GNUNET_NETWORK_test_pf should also receive the type of socket (BTHPROTO_RFCOMM)
1909 // if (GNUNET_NETWORK_test_pf (AF_BTH) != GNUNET_OK)
1911 // fprintf (stderr, "AF_BTH family is not supported\n");
1915 /* create the socket */
1916 dev.handle = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM,
1918 if (dev.handle == NULL)
1920 fprintf (stderr, "Failed to create RFCOMM socket: ");
1921 print_last_error ();
1926 if (open_device (&dev) == -1)
1928 fprintf (stderr, "Failed to open the device\n");
1929 print_last_error ();
1930 if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
1932 fprintf (stderr, "Failed to close the socket!\n");
1933 print_last_error ();
1938 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (dev.handle, 1))
1940 fprintf (stderr, "Failed to change the socket mode\n");
1944 memset (&write_std, 0, sizeof(write_std));
1945 memset (&write_pout, 0, sizeof(write_pout));
1948 rfds = GNUNET_NETWORK_fdset_create ();
1949 wfds = GNUNET_NETWORK_fdset_create ();
1951 /* Send MAC address of the bluetooth interface to STDOUT first */
1953 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
1955 macmsg.hdr.size = htons (sizeof(macmsg));
1956 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
1957 GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof(struct
1958 GNUNET_TRANSPORT_WLAN_MacAddress_Copy));
1959 GNUNET_memcpy (write_std.buf, &macmsg, sizeof(macmsg));
1960 write_std.size = sizeof(macmsg);
1964 stdin_mst = mst_create (&stdin_send_hw, &dev);
1969 int stdout_pos = -1;
1976 sendsocket = NULL; // FIXME ???memleaks
1978 GNUNET_NETWORK_fdset_zero (rfds);
1979 if ((0 == write_pout.size) && (1 == stdin_open))
1983 GNUNET_NETWORK_fdset_handle_set (rfds, (struct
1984 GNUNET_DISK_FileHandle*) &
1988 if (0 == write_std.size)
1991 GNUNET_NETWORK_fdset_set (rfds, dev.handle);
1994 for (i = 0; i < crt_rfds; i++)
1997 GNUNET_NETWORK_fdset_set (rfds, rfds_list[i]);
2000 GNUNET_NETWORK_fdset_zero (wfds);
2001 if (0 < write_std.size)
2004 GNUNET_NETWORK_fdset_handle_set (wfds, (struct
2005 GNUNET_DISK_FileHandle*) &
2007 // printf ("%s\n", write_std.buf);
2008 // memset (write_std.buf, 0, write_std.size);
2009 // write_std.size = 0;
2012 if (0 < write_pout.size)
2014 if (strcmp (argv[1], "ff:ff:ff:ff:ff:ff") == 0)
2016 fprintf (stderr, "LOG: BROADCAST! Skipping the message\n");
2019 memset (write_pout.buf, 0, write_pout.size);
2020 write_pout.size = 0;
2025 fprintf (stderr, "LOG : has a new message for %s\n", argv[1]);
2026 sendsocket = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM,
2029 if (sendsocket == NULL)
2031 fprintf (stderr, "Failed to create RFCOMM socket: \n");
2032 print_last_error ();
2036 memset (&addr, 0, sizeof(addr));
2037 // addr.addressFamily = AF_BTH;
2039 WSAStringToAddress (argv[1], AF_BTH, NULL, (LPSOCKADDR) &addr,
2042 fprintf (stderr, "Failed to translate the address: ");
2043 print_last_error ();
2046 addr.port = get_channel (argv[1]);
2047 if (addr.port == -1)
2050 "Couldn't find the sdp service for the address: %s\n",
2052 memset (write_pout.buf, 0, write_pout.size);
2053 write_pout.size = 0;
2054 broadcast = 1; // skipping the select part
2058 if (GNUNET_OK != GNUNET_NETWORK_socket_connect (sendsocket,
2062 fprintf (stderr, "Failed to connect: ");
2063 print_last_error ();
2067 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (sendsocket, 1))
2069 fprintf (stderr, "Failed to change the socket mode\n");
2073 GNUNET_NETWORK_fdset_set (wfds, sendsocket);
2080 int retval = GNUNET_NETWORK_socket_select (rfds, wfds, NULL,
2081 GNUNET_TIME_relative_get_forever_ ());
2084 fprintf (stderr, "Select error\n");
2087 // if (GNUNET_NETWORK_fdset_isset (wfds, (struct GNUNET_NETWORK_Handle*)&stdout_handle))
2088 if (retval == stdout_pos)
2090 fprintf (stderr, "LOG : sends a message to STDOUT\n"); // FIXME: debugging message
2092 // ret = GNUNET_NETWORK_socket_send ((struct GNUNET_NETWORK_Handle *)&stdout_handle, write_std.buf + write_std.pos, write_std.size - write_std.pos);
2093 // ret = write (STDOUT_FILENO, write_std.buf + write_std.pos, write_std.size - write_std.pos);
2095 if (FALSE == WriteFile (stdout_handle, write_std.buf + write_std.pos,
2096 write_std.size - write_std.pos, &ret, NULL))
2098 fprintf (stderr, "Failed to write to STDOUT: ");
2099 print_last_error ();
2105 fprintf (stderr, "Failed to write to STDOUT\n");
2109 write_std.pos += ret;
2110 if (write_std.pos == write_std.size)
2116 if (sendsocket != NULL)
2118 if (GNUNET_NETWORK_fdset_isset (wfds, sendsocket))
2121 ret = GNUNET_NETWORK_socket_send (sendsocket, write_pout.buf
2123 write_pout.size - write_pout.pos);
2125 if (GNUNET_SYSERR == ret)
2128 "Failed to send to the socket. Closing the socket. Error: \n");
2129 print_last_error ();
2130 if (GNUNET_NETWORK_socket_close (sendsocket) != GNUNET_OK)
2132 fprintf (stderr, "Failed to close the sendsocket!\n");
2133 print_last_error ();
2139 write_pout.pos += ret;
2140 if ((write_pout.pos != write_pout.size) && (0 != ret))
2142 /* we should not get partial sends with packet-oriented devices... */
2143 fprintf (stderr, "Write error, partial send: %u/%u\n",
2144 (unsigned int) write_pout.pos,
2145 (unsigned int) write_pout.size);
2149 if (write_pout.pos == write_pout.size)
2152 write_pout.size = 0;
2154 fprintf (stderr, "LOG : sends a message to a DEVICE\n"); // FIXME: debugging message
2159 // if (GNUNET_NETWORK_fdset_isset (rfds, (struct GNUNET_NETWORK_Handle*)&stdin_handle))
2160 if (retval == stdin_pos)
2163 // ret = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)&stdin_handle, readbuf, sizeof (write_pout.buf));
2164 // ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
2166 if (FALSE == ReadFile (stdin_handle, readbuf, sizeof(readbuf), &ret,
2167 NULL)) /* do nothing asynchronous */
2169 fprintf (stderr, "Read error from STDIN: ");
2170 print_last_error ();
2175 /* stop reading... */
2180 mst_receive (stdin_mst, readbuf, ret);
2181 fprintf (stderr, "LOG : receives a message from STDIN\n"); // FIXME: debugging message
2184 else if (GNUNET_NETWORK_fdset_isset (rfds, dev.handle))
2186 fprintf (stderr, "LOG: accepting connection\n");
2187 struct GNUNET_NETWORK_Handle *readsocket;
2188 readsocket = GNUNET_NETWORK_socket_accept (dev.handle,
2189 (LPSOCKADDR) &acc_addr,
2191 if (readsocket == NULL)
2193 fprintf (stderr, "Accept error %d: ", GetLastError ());
2194 print_last_error ();
2199 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (readsocket, 1))
2201 fprintf (stderr, "Failed to change the socket mode\n");
2204 GNUNET_NETWORK_fdset_set (rfds, readsocket);
2206 if (crt_rfds < MAX_PORTS)
2207 rfds_list[crt_rfds++] = readsocket;
2211 "The limit for the read file descriptors list was reached\n");
2217 for (i = 0; i < crt_rfds; i++)
2219 if (GNUNET_NETWORK_fdset_isset (rfds, rfds_list[i]))
2221 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
2223 fprintf (stderr, "LOG: reading something from the socket\n"); // FIXME : debugging message
2225 GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
2226 ret = read_from_the_socket (rfds_list[i], (unsigned
2227 char *) &rrm->frame,
2228 sizeof(write_std.buf)
2230 GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2232 GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2236 // TODO remove the socket from the list
2237 if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2239 fprintf (stderr, "Failed to close the sendsocket!\n");
2240 print_last_error ();
2243 fprintf (stderr, "Read error from raw socket: ");
2244 print_last_error ();
2247 if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2249 write_std.size = ret
2251 GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2253 GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2254 rrm->header.size = htons (write_std.size);
2255 rrm->header.type = htons (
2256 GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2264 mst_destroy (stdin_mst);
2267 if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
2269 fprintf (stderr, "Failed to close the socket!\n");
2270 print_last_error ();
2273 for (i = 0; i < crt_rfds; i++)
2275 if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2277 fprintf (stderr, "Failed to close the socket!\n");
2278 print_last_error ();
2284 return 1; /* we never exit 'normally' */