2 This file is part of GNUnet.
3 Copyright (C) 2010, 2011, 2012 GNUnet e.V.
4 Copyright (c) 2007, 2008, Andy Green <andy@warmcat.com>
5 Copyright Copyright (C) 2009 Thomas d'Otreppe
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"
25 #include <bluetooth/bluetooth.h>
26 #include <bluetooth/hci.h>
27 #include <bluetooth/hci_lib.h>
28 #include <bluetooth/rfcomm.h>
29 #include <bluetooth/sdp.h>
30 #include <bluetooth/sdp_lib.h>
35 #include <sys/ioctl.h>
36 #include <sys/param.h>
37 #include <sys/socket.h>
39 #include <sys/types.h>
42 #include "plugin_transport_wlan.h"
43 #include "gnunet_protocols.h"
47 * Maximum number of ports assignable for RFCOMMM protocol.
52 * Maximum size of a message allowed in either direction
53 * (used for our receive and sent buffers).
59 * Maximum number of loops without inquiring for new devices.
64 * In bluez library, the maximum name length of a device is 8
66 #define BLUEZ_DEVNAME_SIZE 8
69 * struct for storing the information of the hardware. There is only
75 * Name of the interface, not necessarily 0-terminated (!).
80 * file descriptor for the rfcomm socket
85 * MAC address of our own bluetooth interface.
87 struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac;
92 sdp_session_t *session;
96 * IO buffer used for buffering data in transit (to wireless or to stdout).
101 * How many bytes of data are stored in 'buf' for transmission right now?
102 * Data always starts at offset 0 and extends to 'size'.
107 * How many bytes that were stored in 'buf' did we already write to the
108 * destination? Always smaller than 'size'.
113 * Buffered data; twice the maximum allowed message size as we add some
116 char buf[MAXLINE * 2];
121 * Devices buffer used to keep a list with all the discoverable devices in
122 * order to send them HELLO messages one by one when it receive a broadcast message.
124 struct BroadcastMessages
126 /* List with the discoverable devices' addresses */
127 bdaddr_t devices[MAX_PORTS];
129 /* List with the open sockets */
133 /* The number of the devices */
136 /* The current position */
144 * Address used to identify the broadcast messages.
146 static struct GNUNET_TRANSPORT_WLAN_MacAddress broadcast_address = { { 255, 255,
152 * Buffer with the discoverable devices.
154 static struct BroadcastMessages neighbours;
156 static int searching_devices_count = 0;
160 * Buffer for data read from stdin to be transmitted to the bluetooth device
162 static struct SendBuffer write_pout;
165 * Buffer for data read from the bluetooth device to be transmitted to stdout.
167 static struct SendBuffer write_std;
170 /* ****** this are the same functions as the ones used in gnunet-helper-transport-wlan.c ****** */
173 * To what multiple do we align messages? 8 byte should suffice for everyone
176 #define ALIGN_FACTOR 8
179 * Smallest supported message.
181 #define MIN_BUFFER_SIZE sizeof(struct GNUNET_MessageHeader)
185 * Functions with this signature are called whenever a
186 * complete message is received by the tokenizer.
189 * @param message the actual message
191 typedef void (*MessageTokenizerCallback) (void *cls,
193 GNUNET_MessageHeader *
197 * Handle to a message stream tokenizer.
199 struct MessageStreamTokenizer
202 * Function to call on completed messages.
204 MessageTokenizerCallback cb;
212 * Size of the buffer (starting at 'hdr').
217 * How many bytes in buffer have we already processed?
222 * How many bytes in buffer are valid right now?
227 * Beginning of the buffer. Typed like this to force alignment.
229 struct GNUNET_MessageHeader *hdr;
234 * Create a message stream tokenizer.
236 * @param cb function to call on completed messages
237 * @param cb_cls closure for cb
238 * @return handle to tokenizer
240 static struct MessageStreamTokenizer *
241 mst_create (MessageTokenizerCallback cb,
244 struct MessageStreamTokenizer *ret;
246 ret = malloc (sizeof(struct MessageStreamTokenizer));
249 fprintf (stderr, "Failed to allocate buffer for tokenizer\n");
252 ret->hdr = malloc (MIN_BUFFER_SIZE);
253 if (NULL == ret->hdr)
255 fprintf (stderr, "Failed to allocate buffer for alignment\n");
258 ret->curr_buf = MIN_BUFFER_SIZE;
260 ret->cb_cls = cb_cls;
268 * Add incoming data to the receive buffer and call the
269 * callback for all complete messages.
271 * @param mst tokenizer to use
272 * @param buf input data to add
273 * @param size number of bytes in buf
274 * @return GNUNET_OK if we are done processing (need more data)
275 * GNUNET_SYSERR if the data stream is corrupt
278 mst_receive (struct MessageStreamTokenizer *mst,
279 const char *buf, size_t size)
281 const struct GNUNET_MessageHeader *hdr;
286 unsigned long offset;
290 ibuf = (char *) mst->hdr;
294 if (mst->pos < mst->off)
296 // fprintf (stderr, "We processed too many bytes!\n");
297 return GNUNET_SYSERR;
299 if ((mst->curr_buf - mst->off < sizeof(struct GNUNET_MessageHeader)) ||
300 (0 != (mst->off % ALIGN_FACTOR)))
302 /* need to align or need more space */
303 mst->pos -= mst->off;
304 memmove (ibuf, &ibuf[mst->off], mst->pos);
307 if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader))
310 GNUNET_MIN (sizeof(struct GNUNET_MessageHeader)
311 - (mst->pos - mst->off), size);
312 GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
317 if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader))
319 // FIXME should I reset ??
324 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
325 want = ntohs (hdr->size);
326 if (want < sizeof(struct GNUNET_MessageHeader))
329 "Received invalid message from stdin\n");
330 return GNUNET_SYSERR;
332 if ((mst->curr_buf - mst->off < want) &&
335 /* need more space */
336 mst->pos -= mst->off;
337 memmove (ibuf, &ibuf[mst->off], mst->pos);
340 if (want > mst->curr_buf)
344 fprintf (stderr, "Error! We should proceeded 0 bytes\n");
345 return GNUNET_SYSERR;
347 mst->hdr = realloc (mst->hdr, want);
348 if (NULL == mst->hdr)
350 fprintf (stderr, "Failed to allocate buffer for alignment\n");
353 ibuf = (char *) mst->hdr;
354 mst->curr_buf = want;
356 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
357 if (mst->pos - mst->off < want)
359 delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
360 if (mst->pos + delta > mst->curr_buf)
362 fprintf (stderr, "The size of the buffer will be exceeded!\n");
363 return GNUNET_SYSERR;
365 GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
370 if (mst->pos - mst->off < want)
372 // FIXME should I use this?
377 mst->cb (mst->cb_cls, hdr);
379 if (mst->off == mst->pos)
381 /* reset to beginning of buffer, it's free right now! */
389 "There should some valid bytes in the buffer on this stage\n");
390 return GNUNET_SYSERR;
394 if (size < sizeof(struct GNUNET_MessageHeader))
396 offset = (unsigned long) buf;
397 need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
398 if (GNUNET_NO == need_align)
400 /* can try to do zero-copy and process directly from original buffer */
401 hdr = (const struct GNUNET_MessageHeader *) buf;
402 want = ntohs (hdr->size);
403 if (want < sizeof(struct GNUNET_MessageHeader))
406 "Received invalid message from stdin\n");
409 return GNUNET_SYSERR;
412 break; /* or not, buffer incomplete, so copy to private buffer... */
413 mst->cb (mst->cb_cls, hdr);
419 /* need to copy to private buffer to align;
420 * yes, we go a bit more spagetti than usual here */
426 if (size + mst->pos > mst->curr_buf)
428 mst->hdr = realloc (mst->hdr, size + mst->pos);
429 if (NULL == mst->hdr)
431 fprintf (stderr, "Failed to allocate buffer for alignment\n");
434 ibuf = (char *) mst->hdr;
435 mst->curr_buf = size + mst->pos;
437 if (mst->pos + size > mst->curr_buf)
440 "Assertion failed\n");
443 GNUNET_memcpy (&ibuf[mst->pos], buf, size);
451 * Destroys a tokenizer.
453 * @param mst tokenizer to destroy
456 mst_destroy (struct MessageStreamTokenizer *mst)
464 * Calculate crc32, the start of the calculation
466 * @param buf buffer to calc the crc
467 * @param len len of the buffer
471 calc_crc_osdep (const unsigned char *buf, size_t len)
473 static const unsigned long int crc_tbl_osdep[256] = {
474 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
475 0xE963A535, 0x9E6495A3,
476 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
477 0xE7B82D07, 0x90BF1D91,
478 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
479 0xF4D4B551, 0x83D385C7,
480 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
481 0xFA0F3D63, 0x8D080DF5,
482 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
483 0xD20D85FD, 0xA50AB56B,
484 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
485 0xDCD60DCF, 0xABD13D59,
486 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
487 0xCFBA9599, 0xB8BDA50F,
488 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
489 0xC1611DAB, 0xB6662D3D,
490 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
491 0x9FBFE4A5, 0xE8B8D433,
492 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
493 0x91646C97, 0xE6635C01,
494 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
495 0x8208F4C1, 0xF50FC457,
496 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
497 0x8CD37CF3, 0xFBD44C65,
498 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
499 0xA4D1C46D, 0xD3D6F4FB,
500 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
501 0xAA0A4C5F, 0xDD0D7CC9,
502 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
503 0xB966D409, 0xCE61E49F,
504 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
505 0xB7BD5C3B, 0xC0BA6CAD,
506 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
507 0x04DB2615, 0x73DC1683,
508 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
509 0x0A00AE27, 0x7D079EB1,
510 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
511 0x196C3671, 0x6E6B06E7,
512 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
513 0x17B7BE43, 0x60B08ED5,
514 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
515 0x3FB506DD, 0x48B2364B,
516 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
517 0x316E8EEF, 0x4669BE79,
518 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
519 0x220216B9, 0x5505262F,
520 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
521 0x2CD99E8B, 0x5BDEAE1D,
522 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
523 0x72076785, 0x05005713,
524 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
525 0x7CDCEFB7, 0x0BDBDF21,
526 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
527 0x6FB077E1, 0x18B74777,
528 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
529 0x616BFFD3, 0x166CCF45,
530 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
531 0x4969474D, 0x3E6E77DB,
532 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
533 0x47B2CF7F, 0x30B5FFE9,
534 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
535 0x54DE5729, 0x23D967BF,
536 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
537 0x5A05DF1B, 0x2D02EF8D
540 unsigned long crc = 0xFFFFFFFF;
542 for (; len > 0; len--, buf++)
543 crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
549 * Calculate and check crc of the bluetooth packet
551 * @param buf buffer of the packet, with len + 4 bytes of data,
552 * the last 4 bytes being the checksum
553 * @param len length of the payload in data
554 * @return 0 on success (checksum matches), 1 on error
557 check_crc_buf_osdep (const unsigned char *buf, size_t len)
561 crc = calc_crc_osdep (buf, len);
563 if ((((crc) & 0xFF) == buf[0]) && (((crc >> 8) & 0xFF) == buf[1]) &&
564 ( ((crc >> 16) & 0xFF) == buf[2]) && ( ((crc >> 24) & 0xFF) == buf[3]) )
570 /* ************** end of clone ***************** */
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
602 * Function used for creating the service record and registering it.
604 * @param dev pointer to the device struct
605 * @param rc_channel the rfcomm channel
606 * @return 0 on success
609 register_service (struct HardwareInfos *dev, int rc_channel)
613 * 2. set the service ID, class, profile information
614 * 3. make the service record publicly browsable
615 * 4. register the RFCOMM channel
616 * 5. set the name, provider and description
617 * 6. register the service record to the local SDP server
619 */uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
620 dev->pl_mac.mac[5], dev->pl_mac.mac[4],
622 dev->pl_mac.mac[2], dev->pl_mac.mac[1],
623 dev->pl_mac.mac[0] };
624 const char *service_dsc = "Bluetooth plugin services";
625 const char *service_prov = "GNUnet provider";
626 uuid_t root_uuid, rfcomm_uuid, svc_uuid;
627 sdp_list_t *root_list = 0, *rfcomm_list = 0, *proto_list = 0,
628 *access_proto_list = 0, *svc_list = 0;
629 sdp_record_t *record = 0;
630 sdp_data_t *channel = 0;
632 record = sdp_record_alloc ();
634 /* Set the general service ID */
635 sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
636 svc_list = sdp_list_append (0, &svc_uuid);
637 sdp_set_service_classes (record, svc_list);
638 sdp_set_service_id (record, svc_uuid);
640 /* Make the service record publicly browsable */
641 sdp_uuid16_create (&root_uuid, PUBLIC_BROWSE_GROUP);
642 root_list = sdp_list_append (0, &root_uuid);
643 sdp_set_browse_groups (record, root_list);
645 /* Register the RFCOMM channel */
646 sdp_uuid16_create (&rfcomm_uuid, RFCOMM_UUID);
647 channel = sdp_data_alloc (SDP_UINT8, &rc_channel);
648 rfcomm_list = sdp_list_append (0, &rfcomm_uuid);
649 sdp_list_append (rfcomm_list, channel);
650 proto_list = sdp_list_append (0, rfcomm_list);
652 /* Set protocol information */
653 access_proto_list = sdp_list_append (0, proto_list);
654 sdp_set_access_protos (record, access_proto_list);
656 /* Set the name, provider, and description */
657 sdp_set_info_attr (record, dev->iface, service_prov, service_dsc);
659 /* Connect to the local SDP server */
660 dev->session = sdp_connect (BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
665 "Failed to connect to the SDP server on interface `%.*s': %s\n",
666 IFNAMSIZ, dev->iface, strerror (errno));
671 /* Register the service record */
672 if (sdp_record_register (dev->session, record, 0) < 0)
675 "Failed to register a service record on interface `%.*s': %s\n",
676 IFNAMSIZ, dev->iface, strerror (errno));
682 sdp_data_free (channel);
683 sdp_list_free (root_list, 0);
684 sdp_list_free (rfcomm_list, 0);
685 sdp_list_free (proto_list, 0);
686 sdp_list_free (access_proto_list, 0);
687 sdp_list_free (svc_list, 0);
688 sdp_record_free (record);
695 * Function used for searching and browsing for a service. This will return the
696 * port number on which the service is running.
698 * @param dev pointer to the device struct
699 * @param dest target address
703 get_channel (struct HardwareInfos *dev, bdaddr_t dest)
706 * 1. detect all nearby devices
707 * 2. for each device:
708 * 2.1. connect to the SDP server running
709 * 2.2. get a list of service records with the specific UUID
710 * 2.3. for each service record get a list of the protocol sequences and get
712 */uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
713 dest.b[5], dest.b[4], dest.b[3],
714 dest.b[2], dest.b[1], dest.b[0] };
715 sdp_session_t *session = 0;
716 sdp_list_t *search_list = 0, *attrid_list = 0, *response_list = 0, *it = 0;
718 uint32_t range = 0x0000ffff;
721 /* Connect to the local SDP server */
722 session = sdp_connect (BDADDR_ANY, &dest, 0);
726 "Failed to connect to the SDP server on interface `%.*s': %s\n",
727 IFNAMSIZ, dev->iface, strerror (errno));
731 sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
732 search_list = sdp_list_append (0, &svc_uuid);
733 attrid_list = sdp_list_append (0, &range);
735 if (sdp_service_search_attr_req (session, search_list,
736 SDP_ATTR_REQ_RANGE, attrid_list,
737 &response_list) == 0)
739 for (it = response_list; it; it = it->next)
741 sdp_record_t *record = (sdp_record_t*) it->data;
742 sdp_list_t *proto_list = 0;
743 if (sdp_get_access_protos (record, &proto_list) == 0)
745 channel = sdp_get_proto_port (proto_list, RFCOMM_UUID);
746 sdp_list_free (proto_list, 0);
748 sdp_record_free (record);
752 sdp_list_free (search_list, 0);
753 sdp_list_free (attrid_list, 0);
754 sdp_list_free (response_list, 0);
760 "Failed to find the listening channel for interface `%.*s': %s\n",
770 * Read from the socket and put the result into the buffer for transmission to 'stdout'.
772 * @param sock file descriptor for reading
773 * @param buf buffer to read to; first bytes will be the 'struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame',
774 * followed by the actual payload
775 * @param buf_size size of the buffer
776 * @param ri where to write radiotap_rx info
777 * @return number of bytes written to 'buf'
780 read_from_the_socket (void *sock,
781 unsigned char *buf, size_t buf_size,
782 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri)
784 unsigned char tmpbuf[buf_size];
786 count = read (*((int *) sock), tmpbuf, buf_size);
793 fprintf (stderr, "Failed to read from the HCI socket: %s\n", strerror (
800 /* Get the channel used */
802 struct sockaddr_rc rc_addr = { 0 };
804 memset (&rc_addr, 0, sizeof(rc_addr));
805 len = sizeof(rc_addr);
806 if (0 > getsockname (*((int *) sock), (struct sockaddr *) &rc_addr,
809 fprintf (stderr, "getsockname() call failed : %s\n", strerror (errno));
813 memset (ri, 0, sizeof(*ri));
814 ri->ri_channel = rc_addr.rc_channel;
817 /* Detect CRC32 at the end */
818 if (0 == check_crc_buf_osdep (tmpbuf, count - sizeof(uint32_t)))
820 count -= sizeof(uint32_t);
823 GNUNET_memcpy (buf, tmpbuf, count);
830 * Open the bluetooth interface for reading/writing
832 * @param dev pointer to the device struct
833 * @return 0 on success, non-zero on error
836 open_device (struct HardwareInfos *dev)
838 int i, dev_id = -1, fd_hci;
841 struct hci_dev_list_req list;
842 struct hci_dev_req dev[HCI_MAX_DEV];
843 } request; // used for detecting the local devices
844 struct sockaddr_rc rc_addr = { 0 }; // used for binding
846 /* Initialize the neighbour structure */
847 neighbours.dev_id = -1;
848 for (i = 0; i < MAX_PORTS; i++)
849 neighbours.fds[i] = -1;
851 /* Open a HCI socket */
852 fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
857 "Failed to create HCI socket: %s\n",
862 memset (&request, 0, sizeof(request));
863 request.list.dev_num = HCI_MAX_DEV;
865 if (ioctl (fd_hci, HCIGETDEVLIST, (void *) &request) < 0)
868 "ioctl(HCIGETDEVLIST) on interface `%.*s' failed: %s\n",
872 (void) close (fd_hci);
876 /* Search for a device with dev->iface name */
877 for (i = 0; i < request.list.dev_num; i++)
879 struct hci_dev_info dev_info;
881 memset (&dev_info, 0, sizeof(struct hci_dev_info));
882 dev_info.dev_id = request.dev[i].dev_id;
883 strncpy (dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE);
885 if (ioctl (fd_hci, HCIGETDEVINFO, (void *) &dev_info))
888 "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n",
892 (void) close (fd_hci);
896 if (strncmp (dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE) == 0)
898 dev_id = dev_info.dev_id; // the device was found
900 * Copy the MAC address to the device structure
902 GNUNET_memcpy (&dev->pl_mac, &dev_info.bdaddr, sizeof(bdaddr_t));
904 /* Check if the interface is up */
905 if (hci_test_bit (HCI_UP, (void *) &dev_info.flags) == 0)
907 /* Bring the interface up */
908 if (ioctl (fd_hci, HCIDEVUP, dev_info.dev_id))
911 "ioctl(HCIDEVUP) on interface `%.*s' failed: %s\n",
915 (void) close (fd_hci);
920 /* Check if the device is discoverable */
921 if ((hci_test_bit (HCI_PSCAN, (void *) &dev_info.flags) == 0) ||
922 (hci_test_bit (HCI_ISCAN, (void *) &dev_info.flags) == 0) )
924 /* Set interface Page Scan and Inqury Scan ON */
925 struct hci_dev_req dev_req;
927 memset (&dev_req, 0, sizeof(dev_req));
928 dev_req.dev_id = dev_info.dev_id;
929 dev_req.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
931 if (ioctl (fd_hci, HCISETSCAN, (unsigned long) &dev_req))
934 "ioctl(HCISETSCAN) on interface `%.*s' failed: %s\n",
938 (void) close (fd_hci);
946 /* Check if the interface was not found */
950 "The interface %s was not found\n",
952 (void) close (fd_hci);
956 /* Close the hci socket */
957 (void) close (fd_hci);
960 /* Bind the rfcomm socket to the interface */
961 memset (&rc_addr, 0, sizeof(rc_addr));
962 rc_addr.rc_family = AF_BLUETOOTH;
963 rc_addr.rc_bdaddr = *BDADDR_ANY;
965 if (bind_socket (dev->fd_rfcomm, &rc_addr) != 0)
968 "Failed to bind interface `%.*s': %s\n",
975 /* Register a SDP service */
976 if (register_service (dev, rc_addr.rc_channel) != 0)
979 "Failed to register a service on interface `%.*s': %s\n",
981 dev->iface, strerror (errno));
985 /* Switch socket in listening mode */
986 if (listen (dev->fd_rfcomm, 5) == -1) // FIXME: probably we need a bigger number
988 fprintf (stderr, "Failed to listen on socket for interface `%.*s': %s\n",
990 dev->iface, strerror (errno));
999 * Set the header to sane values to make attacks more difficult
1001 * @param taIeeeHeader pointer to the header of the packet
1002 * @param dev pointer to the Hardware_Infos struct
1004 **** copy from gnunet-helper-transport-wlan.c ****
1007 mac_set (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1008 const struct HardwareInfos *dev)
1010 taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
1011 taIeeeHeader->addr3 = mac_bssid_gnunet;
1012 taIeeeHeader->addr2 = dev->pl_mac;
1018 * Test if the given interface name really corresponds to a bluetooth
1021 * @param iface name of the interface
1022 * @return 0 on success, 1 on error
1023 **** similar with the one from gnunet-helper-transport-wlan.c ****
1026 test_bluetooth_interface (const char *iface)
1032 ret = snprintf (strbuf, sizeof(strbuf),
1033 "/sys/class/bluetooth/%s/subsystem",
1035 if ((ret < 0) || (ret >= sizeof(strbuf)) || (0 != stat (strbuf, &sbuf)))
1038 "Did not find 802.15.1 interface `%s'. Exiting.\n",
1049 * Test incoming packets mac for being our own.
1051 * @param taIeeeHeader buffer of the packet
1052 * @param dev the Hardware_Infos struct
1053 * @return 0 if mac belongs to us, 1 if mac is for another target
1055 **** same as the one from gnunet-helper-transport-wlan.c ****
1058 mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1059 const struct HardwareInfos *dev)
1061 static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
1063 if ((0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
1064 (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)))
1065 return 0; /* some drivers set no Macs, then assume it is all for us! */
1067 if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1068 return 1; /* not a GNUnet ad-hoc package */
1069 if ((0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
1070 (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)))
1071 return 0; /* for us, or broadcast */
1072 return 1; /* not for us */
1077 * Process data from the stdin. Takes the message, forces the sender MAC to be correct
1078 * and puts it into our buffer for transmission to the receiver.
1080 * @param cls pointer to the device struct ('struct HardwareInfos*')
1081 * @param hdr pointer to the start of the packet
1083 **** same as the one from gnunet-helper-transport-wlan.c ****
1086 stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1088 struct HardwareInfos *dev = cls;
1089 const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header;
1090 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *blueheader;
1093 sendsize = ntohs (hdr->size);
1095 sizeof(struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
1096 (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)))
1098 fprintf (stderr, "Received malformed message\n");
1101 sendsize -= (sizeof(struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)
1102 - sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1103 if (MAXLINE < sendsize)
1105 fprintf (stderr, "Packet too big for buffer\n");
1108 header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
1109 GNUNET_memcpy (&write_pout.buf, &header->frame, sendsize);
1110 blueheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf;
1112 /* payload contains MAC address, but we don't trust it, so we'll
1113 * overwrite it with OUR MAC address to prevent mischief */
1114 mac_set (blueheader, dev);
1115 GNUNET_memcpy (&blueheader->addr1, &header->frame.addr1,
1116 sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress));
1117 write_pout.size = sendsize;
1123 * Broadcast a HELLO message for peer discovery
1125 * @param dev pointer to the device struct
1126 * @param dev pointer to the socket which was added to the set
1127 * @return 0 on success
1130 send_broadcast (struct HardwareInfos *dev, int *sendsocket)
1136 if (((neighbours.size == neighbours.pos) && (new_device == 1)) ||
1137 (neighbours.size == 0) )
1139 inquiry_devices: // skip the conditions and force a inquiry for new devices
1142 * It means that I sent HELLO messages to all the devices from the list and I should search
1143 * for new ones or that this is the first time when I do a search.
1145 inquiry_info *devices = NULL;
1146 int i, responses, max_responses = MAX_PORTS;
1149 if (neighbours.size >= MAX_PORTS)
1152 "%.*s reached the top limit for the discovarable devices\n",
1158 /* Get the device id */
1159 if (neighbours.dev_id == -1)
1161 char addr[19] = { 0 }; // the device MAC address
1163 ba2str ((bdaddr_t *) &dev->pl_mac, addr);
1164 neighbours.dev_id = hci_devid (addr);
1165 if (neighbours.dev_id < 0)
1168 "Failed to get the device id for interface %.*s : %s\n",
1170 dev->iface, strerror (errno));
1175 devices = malloc (max_responses * sizeof(inquiry_info));
1176 if (devices == NULL)
1179 "Failed to allocate memory for inquiry info list on interface %.*s\n",
1185 responses = hci_inquiry (neighbours.dev_id, 8, max_responses, NULL,
1186 &devices, IREQ_CACHE_FLUSH);
1189 fprintf (stderr, "Failed to inquiry on interface %.*s\n", IFNAMSIZ,
1194 fprintf (stderr, "LOG : Found %d devices\n", responses); // FIXME delete it after debugging stage
1198 fprintf (stderr, "LOG : No devices discoverable\n");
1202 for (i = 0; i < responses; i++)
1211 "%.*s reached the top limit for the discoverable devices (after inquiry)\n",
1217 /* Search if the address already exists on the list */
1218 for (j = 0; j < neighbours.size; j++)
1220 if (memcmp (&(devices + i)->bdaddr, &(neighbours.devices[j]),
1221 sizeof(bdaddr_t)) == 0)
1224 fprintf (stderr, "LOG : the device already exists on the list\n"); // FIXME debugging message
1231 char addr[19] = { 0 };
1233 ba2str (&(devices + i)->bdaddr, addr);
1234 fprintf (stderr, "LOG : %s was added to the list\n", addr); // FIXME debugging message
1235 GNUNET_memcpy (&(neighbours.devices[neighbours.size++]), &(devices
1237 bdaddr, sizeof(bdaddr_t));
1245 int connection_successful = 0;
1246 struct sockaddr_rc addr_rc = { 0 };
1248 addr_rc.rc_family = AF_BLUETOOTH;
1250 /* Try to connect to a new device from the list */
1251 while (neighbours.pos < neighbours.size)
1253 /* Check if we are already connected to this device */
1254 if (neighbours.fds[neighbours.pos] == -1)
1256 memset (&addr_rc.rc_bdaddr, 0, sizeof(addr_rc.rc_bdaddr));
1257 GNUNET_memcpy (&addr_rc.rc_bdaddr, &(neighbours.devices[neighbours.pos]),
1258 sizeof(addr_rc.rc_bdaddr));
1260 addr_rc.rc_channel = get_channel (dev, addr_rc.rc_bdaddr);
1262 *sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1263 if ((-1 < *sendsocket) &&
1264 (0 == connect (*sendsocket,
1265 (struct sockaddr *) &addr_rc,
1268 neighbours.fds[neighbours.pos++] = *sendsocket;
1269 connection_successful = 1;
1270 char addr[19] = { 0 };
1271 ba2str (&(neighbours.devices[neighbours.pos - 1]), addr);
1272 fprintf (stderr, "LOG : Connected to %s\n", addr);
1277 char addr[19] = { 0 };
1278 errno_copy = errno; // Save a copy for later
1280 if (-1 != *sendsocket)
1282 (void) close (*sendsocket);
1285 ba2str (&(neighbours.devices[neighbours.pos]), addr);
1287 "LOG : Couldn't connect on device %s, error : %s\n",
1290 if (errno != ECONNREFUSED) // FIXME be sure that this works
1292 fprintf (stderr, "LOG : Removes %d device from the list\n",
1294 /* Remove the device from the list */
1295 GNUNET_memcpy (&neighbours.devices[neighbours.pos],
1296 &neighbours.devices[neighbours.size - 1],
1298 memset (&neighbours.devices[neighbours.size - 1], 0,
1300 neighbours.fds[neighbours.pos] = neighbours.fds[neighbours.size - 1];
1301 neighbours.fds[neighbours.size - 1] = -1;
1302 neighbours.size -= 1;
1305 neighbours.pos += 1;
1307 if (neighbours.pos >= neighbours.size)
1312 if (loops == MAX_LOOPS) // don't get stuck trying to connect to one device
1318 fprintf (stderr, "LOG : Search for a new device\n"); // FIXME debugging message
1319 neighbours.pos += 1;
1323 /* Cycle on the list */
1324 if (neighbours.pos == neighbours.size)
1327 searching_devices_count += 1;
1329 if (searching_devices_count == MAX_LOOPS)
1331 fprintf (stderr, "LOG : Force to inquiry for new devices\n");
1332 searching_devices_count = 0;
1333 goto inquiry_devices;
1336 /* If a new device wasn't found, search an old one */
1337 if (connection_successful == 0)
1339 int loop_check = neighbours.pos;
1340 while (neighbours.fds[neighbours.pos] == -1)
1342 if (neighbours.pos == neighbours.size)
1345 if (neighbours.pos == loop_check)
1347 if (errno_copy == ECONNREFUSED)
1349 fprintf (stderr, "LOG : No device found. Go back and search again\n"); // FIXME debugging message
1352 goto search_for_devices;
1356 return 1; // Skip the broadcast message
1360 neighbours.pos += 1;
1363 *sendsocket = neighbours.fds[neighbours.pos++];
1373 * Main function of the helper. This code accesses a bluetooth interface
1374 * forwards traffic in both directions between the bluetooth interface and
1375 * stdin/stdout of this process. Error messages are written to stderr.
1377 * @param argc number of arguments, must be 2
1378 * @param argv arguments only argument is the name of the interface (i.e. 'hci0')
1379 * @return 0 on success (never happens, as we don't return unless aborted), 1 on error
1381 **** similar to gnunet-helper-transport-wlan.c ****
1384 main (int argc, char *argv[])
1387 struct HardwareInfos dev;
1388 char readbuf[MAXLINE];
1393 struct MessageStreamTokenizer *stdin_mst;
1395 int crt_rfds = 0, rfds_list[MAX_PORTS];
1396 int broadcast, sendsocket;
1398 /* Assert privs so we can modify the firewall rules! */
1400 #ifdef HAVE_SETRESUID
1401 uid_t uid = getuid ();
1403 if (0 != setresuid (uid, 0, 0))
1406 "Failed to setresuid to root: %s\n",
1411 if (0 != seteuid (0))
1414 "Failed to seteuid back to root: %s\n", strerror (errno));
1420 /* Make use of SGID capabilities on POSIX */
1421 memset (&dev, 0, sizeof(dev));
1422 dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1423 raw_eno = errno; /* remember for later */
1425 /* Now that we've dropped root rights, we can do error checking */
1429 "You must specify the name of the interface as the first \
1430 and only argument to this program.\n");
1431 if (-1 != dev.fd_rfcomm)
1432 (void) close (dev.fd_rfcomm);
1436 if (-1 == dev.fd_rfcomm)
1438 fprintf (stderr, "Failed to create a RFCOMM socket: %s\n", strerror (
1442 if (dev.fd_rfcomm >= FD_SETSIZE)
1444 fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1445 dev.fd_rfcomm, FD_SETSIZE);
1446 (void) close (dev.fd_rfcomm);
1449 if (0 != test_bluetooth_interface (argv[1]))
1451 (void) close (dev.fd_rfcomm);
1454 strncpy (dev.iface, argv[1], IFNAMSIZ);
1455 if (0 != open_device (&dev))
1457 (void) close (dev.fd_rfcomm);
1463 uid_t uid = getuid ();
1464 #ifdef HAVE_SETRESUID
1465 if (0 != setresuid (uid, uid, uid))
1467 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1468 if (-1 != dev.fd_rfcomm)
1469 (void) close (dev.fd_rfcomm);
1473 if (0 != (setuid (uid) | seteuid (uid)))
1475 fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
1476 if (-1 != dev.fd_rfcomm)
1477 (void) close (dev.fd_rfcomm);
1483 /* Send MAC address of the bluetooth interface to STDOUT first */
1485 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
1487 macmsg.hdr.size = htons (sizeof(macmsg));
1488 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
1489 GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof(struct
1490 GNUNET_TRANSPORT_WLAN_MacAddress));
1491 GNUNET_memcpy (write_std.buf, &macmsg, sizeof(macmsg));
1492 write_std.size = sizeof(macmsg);
1496 stdin_mst = mst_create (&stdin_send_hw, &dev);
1500 * TODO : I should make the time out of a mac endpoint smaller and check if the rate
1501 * from get_wlan_header (plugin_transport_bluetooth.c) is correct.
1510 if ((0 == write_pout.size) && (1 == stdin_open))
1512 FD_SET (STDIN_FILENO, &rfds);
1513 maxfd = MAX (maxfd, STDIN_FILENO);
1515 if (0 == write_std.size)
1517 FD_SET (dev.fd_rfcomm, &rfds);
1518 maxfd = MAX (maxfd, dev.fd_rfcomm);
1521 for (i = 0; i < crt_rfds; i++) // it can receive messages from multiple devices
1523 FD_SET (rfds_list[i], &rfds);
1524 maxfd = MAX (maxfd, rfds_list[i]);
1527 if (0 < write_std.size)
1529 FD_SET (STDOUT_FILENO, &wfds);
1530 maxfd = MAX (maxfd, STDOUT_FILENO);
1532 if (0 < write_pout.size) // it can send messages only to one device per loop
1534 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *frame;
1535 /* Get the destination address */
1536 frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) write_pout.buf;
1538 if (memcmp (&frame->addr1, &dev.pl_mac,
1539 sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1542 memset (&write_pout, 0, sizeof(write_pout)); // clear the buffer
1544 else if (memcmp (&frame->addr1, &broadcast_address,
1545 sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1547 fprintf (stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n",
1548 dev.iface, neighbours.pos, neighbours.size); // FIXME: debugging message
1550 if (send_broadcast (&dev, &sendsocket) != 0) // if the searching wasn't successful don't get stuck on the select stage
1553 memset (&write_pout, 0, sizeof(write_pout)); // remove the message
1555 "LOG : Skipping the broadcast message (pos %d, size %d)\n",
1556 neighbours.pos, neighbours.size);
1560 FD_SET (sendsocket, &wfds);
1561 maxfd = MAX (maxfd, sendsocket);
1568 /* Search if the address already exists on the list */
1569 for (i = 0; i < neighbours.size; i++)
1571 if (memcmp (&frame->addr1, &(neighbours.devices[i]),
1572 sizeof(bdaddr_t)) == 0)
1575 if (neighbours.fds[i] != -1)
1577 found = 1; // save the position where it was found
1578 FD_SET (neighbours.fds[i], &wfds);
1579 maxfd = MAX (maxfd, neighbours.fds[i]);
1580 sendsocket = neighbours.fds[i];
1581 fprintf (stderr, "LOG: the address was found in the list\n");
1589 struct sockaddr_rc addr = { 0 };
1592 "LOG : %s has a new message for %.2X:%.2X:%.2X:%.2X:%.2X:%.2X which isn't on the broadcast list\n",
1594 frame->addr1.mac[5], frame->addr1.mac[4],
1595 frame->addr1.mac[3],
1596 frame->addr1.mac[2], frame->addr1.mac[1],
1597 frame->addr1.mac[0]); // FIXME: debugging message
1599 sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1604 "Failed to create a RFCOMM socket (sending stage): %s\n",
1609 GNUNET_memcpy (&addr.rc_bdaddr, &frame->addr1, sizeof(bdaddr_t));
1610 addr.rc_family = AF_BLUETOOTH;
1611 addr.rc_channel = get_channel (&dev, addr.rc_bdaddr);
1615 status = connect (sendsocket, (struct sockaddr *) &addr,
1617 if ((0 != status) && (errno != EAGAIN) )
1619 if ((errno == ECONNREFUSED) && (tries < 2) )
1621 fprintf (stderr, "LOG : %.*s failed to connect. Trying again!\n",
1622 IFNAMSIZ, dev.iface);
1626 else if (errno == EBADF)
1628 fprintf (stderr, "LOG : %s failed to connect : %s. Skip it!\n",
1629 dev.iface, strerror (errno));
1630 memset (&write_pout, 0, sizeof(write_pout));
1636 "LOG : %s failed to connect : %s. Try again later!\n",
1639 memset (&write_pout, 0, sizeof(write_pout));
1645 FD_SET (sendsocket, &wfds);
1646 maxfd = MAX (maxfd, sendsocket);
1647 fprintf (stderr, "LOG : Connection successful\n");
1648 if (pos != 0) // save the socket
1650 neighbours.fds[pos] = sendsocket;
1654 /* Add the new device to the discovered devices list */
1655 if (neighbours.size < MAX_PORTS)
1657 neighbours.fds[neighbours.size] = sendsocket;
1658 GNUNET_memcpy (&(neighbours.devices[neighbours.size++]),
1659 &addr.rc_bdaddr, sizeof(bdaddr_t));
1664 "The top limit for the discovarable devices' list was reached\n");
1674 /* Select a fd which is ready for action :) */
1676 int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
1677 if ((-1 == retval) && (EINTR == errno))
1679 if ((0 > retval) && (errno != EBADF) ) // we handle BADF errors later
1681 fprintf (stderr, "select failed: %s\n", strerror (errno));
1685 if (FD_ISSET (STDOUT_FILENO, &wfds))
1688 write (STDOUT_FILENO, write_std.buf + write_std.pos,
1689 write_std.size - write_std.pos);
1692 fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1695 write_std.pos += ret;
1696 if (write_std.pos == write_std.size)
1701 fprintf (stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); // FIXME: debugging message
1703 if (-1 != sendsocket)
1705 if (FD_ISSET (sendsocket, &wfds))
1707 ssize_t ret = write (sendsocket,
1708 write_pout.buf + write_std.pos,
1709 write_pout.size - write_pout.pos);
1710 if (0 > ret) // FIXME should I first check the error type?
1713 "Failed to write to bluetooth device: %s. Closing the socket!\n",
1715 for (i = 0; i < neighbours.size; i++)
1717 if (neighbours.fds[i] == sendsocket)
1719 (void) close (sendsocket);
1720 neighbours.fds[i] = -1;
1724 /* Remove the message */
1725 memset (&write_pout.buf + write_std.pos, 0, (write_pout.size
1728 write_pout.size = 0;
1732 write_pout.pos += ret;
1733 if ((write_pout.pos != write_pout.size) && (0 != ret))
1735 /* We should not get partial sends with packet-oriented devices... */
1736 fprintf (stderr, "Write error, partial send: %u/%u\n",
1737 (unsigned int) write_pout.pos,
1738 (unsigned int) write_pout.size);
1742 if (write_pout.pos == write_pout.size)
1745 write_pout.size = 0;
1747 fprintf (stderr, "LOG : %s sends a message to a DEVICE\n",
1748 dev.iface); // FIXME: debugging message
1752 for (i = 0; i <= maxfd; i++)
1754 if (FD_ISSET (i, &rfds))
1756 if (i == STDIN_FILENO)
1759 read (i, readbuf, sizeof(readbuf));
1763 "Read error from STDIN: %s\n",
1769 /* stop reading... */
1774 mst_receive (stdin_mst, readbuf, ret);
1775 fprintf (stderr, "LOG : %s receives a message from STDIN\n",
1776 dev.iface); // FIXME: debugging message
1779 else if (i == dev.fd_rfcomm)
1782 struct sockaddr_rc addr = { 0 };
1783 unsigned int opt = sizeof(addr);
1785 readsocket = accept (dev.fd_rfcomm, (struct sockaddr *) &addr,
1787 fprintf (stderr, "LOG : %s accepts a message\n", dev.iface); // FIXME: debugging message
1788 if (readsocket == -1)
1791 "Failed to accept a connection on interface: %.*s\n",
1798 FD_SET (readsocket, &rfds);
1799 maxfd = MAX (maxfd, readsocket);
1801 if (crt_rfds < MAX_PORTS)
1802 rfds_list[crt_rfds++] = readsocket;
1806 "The limit for the read file descriptors list was \
1814 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
1816 fprintf (stderr, "LOG : %s reads something from the socket\n",
1817 dev.iface); // FIXME : debugging message
1819 GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
1821 read_from_the_socket ((void *) &i, (unsigned char *) &rrm->frame,
1822 sizeof(write_std.buf)
1824 GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
1826 GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
1833 /* Remove the socket from the list */
1834 for (j = 0; j < crt_rfds; j++)
1836 if (rfds_list[j] == i)
1838 rfds_list[j] ^= rfds_list[crt_rfds - 1];
1839 rfds_list[crt_rfds - 1] ^= rfds_list[j];
1840 rfds_list[j] ^= rfds_list[crt_rfds - 1];
1846 fprintf (stderr, "Read error from raw socket: %s\n", strerror (
1850 if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
1852 write_std.size = ret
1854 GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
1856 GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
1857 rrm->header.size = htons (write_std.size);
1858 rrm->header.type = htons (
1859 GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
1866 /* Error handling, try to clean up a bit at least */
1867 mst_destroy (stdin_mst);
1869 sdp_close (dev.session);
1870 (void) close (dev.fd_rfcomm);
1871 if (-1 != sendsocket)
1872 (void) close (sendsocket);
1874 for (i = 0; i < crt_rfds; i++)
1875 (void) close (rfds_list[i]);
1877 for (i = 0; i < neighbours.size; i++)
1878 (void) close (neighbours.fds[i]);
1880 struct HardwareInfos dev;
1881 struct GNUNET_NETWORK_Handle *sendsocket;
1882 struct GNUNET_NETWORK_FDSet *rfds;
1883 struct GNUNET_NETWORK_FDSet *wfds;
1884 struct GNUNET_NETWORK_Handle *rfds_list[MAX_PORTS];
1885 char readbuf[MAXLINE] = { 0 };
1886 SOCKADDR_BTH acc_addr = { 0 };
1887 int addr_len = sizeof(SOCKADDR_BTH);
1888 int broadcast, i, stdin_open, crt_rfds = 0;
1889 HANDLE stdin_handle = GetStdHandle (STD_INPUT_HANDLE);
1890 HANDLE stdout_handle = GetStdHandle (STD_OUTPUT_HANDLE);
1891 struct MessageStreamTokenizer *stdin_mst;
1893 /* check the handles */
1894 if (stdin_handle == INVALID_HANDLE_VALUE)
1896 fprintf (stderr, "Failed to get the stdin handle\n");
1900 if (stdout_handle == INVALID_HANDLE_VALUE)
1902 fprintf (stderr, "Failed to get the stdout handle\n");
1906 /* initialize windows sockets */
1907 initialize_windows_sockets ();
1909 // /* test bluetooth socket family support */ --> it return false because the GNUNET_NETWORK_test_pf should also receive the type of socket (BTHPROTO_RFCOMM)
1910 // if (GNUNET_NETWORK_test_pf (AF_BTH) != GNUNET_OK)
1912 // fprintf (stderr, "AF_BTH family is not supported\n");
1916 /* create the socket */
1917 dev.handle = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM,
1919 if (dev.handle == NULL)
1921 fprintf (stderr, "Failed to create RFCOMM socket: ");
1922 print_last_error ();
1927 if (open_device (&dev) == -1)
1929 fprintf (stderr, "Failed to open the device\n");
1930 print_last_error ();
1931 if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
1933 fprintf (stderr, "Failed to close the socket!\n");
1934 print_last_error ();
1939 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (dev.handle, 1))
1941 fprintf (stderr, "Failed to change the socket mode\n");
1945 memset (&write_std, 0, sizeof(write_std));
1946 memset (&write_pout, 0, sizeof(write_pout));
1949 rfds = GNUNET_NETWORK_fdset_create ();
1950 wfds = GNUNET_NETWORK_fdset_create ();
1952 /* Send MAC address of the bluetooth interface to STDOUT first */
1954 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
1956 macmsg.hdr.size = htons (sizeof(macmsg));
1957 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
1958 GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof(struct
1959 GNUNET_TRANSPORT_WLAN_MacAddress_Copy));
1960 GNUNET_memcpy (write_std.buf, &macmsg, sizeof(macmsg));
1961 write_std.size = sizeof(macmsg);
1965 stdin_mst = mst_create (&stdin_send_hw, &dev);
1970 int stdout_pos = -1;
1977 sendsocket = NULL; // FIXME ???memleaks
1979 GNUNET_NETWORK_fdset_zero (rfds);
1980 if ((0 == write_pout.size) && (1 == stdin_open))
1984 GNUNET_NETWORK_fdset_handle_set (rfds, (struct
1985 GNUNET_DISK_FileHandle*) &
1989 if (0 == write_std.size)
1992 GNUNET_NETWORK_fdset_set (rfds, dev.handle);
1995 for (i = 0; i < crt_rfds; i++)
1998 GNUNET_NETWORK_fdset_set (rfds, rfds_list[i]);
2001 GNUNET_NETWORK_fdset_zero (wfds);
2002 if (0 < write_std.size)
2005 GNUNET_NETWORK_fdset_handle_set (wfds, (struct
2006 GNUNET_DISK_FileHandle*) &
2008 // printf ("%s\n", write_std.buf);
2009 // memset (write_std.buf, 0, write_std.size);
2010 // write_std.size = 0;
2013 if (0 < write_pout.size)
2015 if (strcmp (argv[1], "ff:ff:ff:ff:ff:ff") == 0)
2017 fprintf (stderr, "LOG: BROADCAST! Skipping the message\n");
2020 memset (write_pout.buf, 0, write_pout.size);
2021 write_pout.size = 0;
2026 fprintf (stderr, "LOG : has a new message for %s\n", argv[1]);
2027 sendsocket = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM,
2030 if (sendsocket == NULL)
2032 fprintf (stderr, "Failed to create RFCOMM socket: \n");
2033 print_last_error ();
2037 memset (&addr, 0, sizeof(addr));
2038 // addr.addressFamily = AF_BTH;
2040 WSAStringToAddress (argv[1], AF_BTH, NULL, (LPSOCKADDR) &addr,
2043 fprintf (stderr, "Failed to translate the address: ");
2044 print_last_error ();
2047 addr.port = get_channel (argv[1]);
2048 if (addr.port == -1)
2051 "Couldn't find the sdp service for the address: %s\n",
2053 memset (write_pout.buf, 0, write_pout.size);
2054 write_pout.size = 0;
2055 broadcast = 1; // skipping the select part
2059 if (GNUNET_OK != GNUNET_NETWORK_socket_connect (sendsocket,
2063 fprintf (stderr, "Failed to connect: ");
2064 print_last_error ();
2068 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (sendsocket, 1))
2070 fprintf (stderr, "Failed to change the socket mode\n");
2074 GNUNET_NETWORK_fdset_set (wfds, sendsocket);
2081 int retval = GNUNET_NETWORK_socket_select (rfds, wfds, NULL,
2082 GNUNET_TIME_relative_get_forever_ ());
2085 fprintf (stderr, "Select error\n");
2088 // if (GNUNET_NETWORK_fdset_isset (wfds, (struct GNUNET_NETWORK_Handle*)&stdout_handle))
2089 if (retval == stdout_pos)
2091 fprintf (stderr, "LOG : sends a message to STDOUT\n"); // FIXME: debugging message
2093 // ret = GNUNET_NETWORK_socket_send ((struct GNUNET_NETWORK_Handle *)&stdout_handle, write_std.buf + write_std.pos, write_std.size - write_std.pos);
2094 // ret = write (STDOUT_FILENO, write_std.buf + write_std.pos, write_std.size - write_std.pos);
2096 if (FALSE == WriteFile (stdout_handle, write_std.buf + write_std.pos,
2097 write_std.size - write_std.pos, &ret, NULL))
2099 fprintf (stderr, "Failed to write to STDOUT: ");
2100 print_last_error ();
2106 fprintf (stderr, "Failed to write to STDOUT\n");
2110 write_std.pos += ret;
2111 if (write_std.pos == write_std.size)
2117 if (sendsocket != NULL)
2119 if (GNUNET_NETWORK_fdset_isset (wfds, sendsocket))
2122 ret = GNUNET_NETWORK_socket_send (sendsocket, write_pout.buf
2124 write_pout.size - write_pout.pos);
2126 if (GNUNET_SYSERR == ret)
2129 "Failed to send to the socket. Closing the socket. Error: \n");
2130 print_last_error ();
2131 if (GNUNET_NETWORK_socket_close (sendsocket) != GNUNET_OK)
2133 fprintf (stderr, "Failed to close the sendsocket!\n");
2134 print_last_error ();
2140 write_pout.pos += ret;
2141 if ((write_pout.pos != write_pout.size) && (0 != ret))
2143 /* we should not get partial sends with packet-oriented devices... */
2144 fprintf (stderr, "Write error, partial send: %u/%u\n",
2145 (unsigned int) write_pout.pos,
2146 (unsigned int) write_pout.size);
2150 if (write_pout.pos == write_pout.size)
2153 write_pout.size = 0;
2155 fprintf (stderr, "LOG : sends a message to a DEVICE\n"); // FIXME: debugging message
2160 // if (GNUNET_NETWORK_fdset_isset (rfds, (struct GNUNET_NETWORK_Handle*)&stdin_handle))
2161 if (retval == stdin_pos)
2164 // ret = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)&stdin_handle, readbuf, sizeof (write_pout.buf));
2165 // ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
2167 if (FALSE == ReadFile (stdin_handle, readbuf, sizeof(readbuf), &ret,
2168 NULL)) /* do nothing asynchronous */
2170 fprintf (stderr, "Read error from STDIN: ");
2171 print_last_error ();
2176 /* stop reading... */
2181 mst_receive (stdin_mst, readbuf, ret);
2182 fprintf (stderr, "LOG : receives a message from STDIN\n"); // FIXME: debugging message
2185 else if (GNUNET_NETWORK_fdset_isset (rfds, dev.handle))
2187 fprintf (stderr, "LOG: accepting connection\n");
2188 struct GNUNET_NETWORK_Handle *readsocket;
2189 readsocket = GNUNET_NETWORK_socket_accept (dev.handle,
2190 (LPSOCKADDR) &acc_addr,
2192 if (readsocket == NULL)
2194 fprintf (stderr, "Accept error %d: ", GetLastError ());
2195 print_last_error ();
2200 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (readsocket, 1))
2202 fprintf (stderr, "Failed to change the socket mode\n");
2205 GNUNET_NETWORK_fdset_set (rfds, readsocket);
2207 if (crt_rfds < MAX_PORTS)
2208 rfds_list[crt_rfds++] = readsocket;
2212 "The limit for the read file descriptors list was reached\n");
2218 for (i = 0; i < crt_rfds; i++)
2220 if (GNUNET_NETWORK_fdset_isset (rfds, rfds_list[i]))
2222 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
2224 fprintf (stderr, "LOG: reading something from the socket\n"); // FIXME : debugging message
2226 GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
2227 ret = read_from_the_socket (rfds_list[i], (unsigned
2228 char *) &rrm->frame,
2229 sizeof(write_std.buf)
2231 GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2233 GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2237 // TODO remove the socket from the list
2238 if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2240 fprintf (stderr, "Failed to close the sendsocket!\n");
2241 print_last_error ();
2244 fprintf (stderr, "Read error from raw socket: ");
2245 print_last_error ();
2248 if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2250 write_std.size = ret
2252 GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2254 GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2255 rrm->header.size = htons (write_std.size);
2256 rrm->header.type = htons (
2257 GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2265 mst_destroy (stdin_mst);
2268 if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
2270 fprintf (stderr, "Failed to close the socket!\n");
2271 print_last_error ();
2274 for (i = 0; i < crt_rfds; i++)
2276 if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2278 fprintf (stderr, "Failed to close the socket!\n");
2279 print_last_error ();
2285 return 1; /* we never exit 'normally' */