2 This file is part of GNUnet.
3 (C) 2010, 2011, 2012 Christian Grothoff (and other contributing authors)
4 Copyright (c) 2007, 2008, Andy Green <andy@warmcat.com>
5 Copyright (C) 2009 Thomas d'Otreppe
7 GNUnet is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published
9 by the Free Software Foundation; either version 3, or (at your
10 option) any later version.
12 GNUnet is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNUnet; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
22 #include "gnunet_config.h"
24 #include <bluetooth/bluetooth.h>
25 #include <bluetooth/hci.h>
26 #include <bluetooth/hci_lib.h>
27 #include <bluetooth/rfcomm.h>
28 #include <bluetooth/sdp.h>
29 #include <bluetooth/sdp_lib.h>
34 #include <sys/ioctl.h>
35 #include <sys/param.h>
36 #include <sys/socket.h>
38 #include <sys/types.h>
41 #include "gnunet_protocols.h"
42 #include "plugin_transport_wlan.h"
45 * Maximum number of ports assignable for RFCOMMM protocol.
50 * Maximum size of a message allowed in either direction
51 * (used for our receive and sent buffers).
57 * Maximum number of loops without inquiring for new devices.
62 * struct for storing the information of the hardware. There is only
69 * file descriptor for the rfcomm socket
74 * Name of the interface, not necessarily 0-terminated (!).
79 * MAC address of our own bluetooth interface.
81 struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac;
86 sdp_session_t *session ;
90 * IO buffer used for buffering data in transit (to wireless or to stdout).
95 * How many bytes of data are stored in 'buf' for transmission right now?
96 * Data always starts at offset 0 and extends to 'size'.
101 * How many bytes that were stored in 'buf' did we already write to the
102 * destination? Always smaller than 'size'.
107 * Buffered data; twice the maximum allowed message size as we add some
110 char buf[MAXLINE * 2];
114 * Devices buffer used to keep a list with all the discoverable devices in
115 * order to send them HELLO messages one by one when it receive a broadcast message.
117 struct BroadcastMessages
119 /* List with the discoverable devices' addresses */
120 bdaddr_t devices[MAX_PORTS]; //FIXME I should use a linked list but 30 isn't such a big number
122 /* List with the open sockets */
126 /* The number of the devices */
129 /* The current position */
138 * Buffer for data read from stdin to be transmitted to the bluetooth device
140 static struct SendBuffer write_pout;
143 * Buffer for data read from the bluetooth device to be transmitted to stdout.
145 static struct SendBuffer write_std;
148 * Address used to identify the broadcast messages.
150 static struct GNUNET_TRANSPORT_WLAN_MacAddress broadcast_address = {{255, 255, 255, 255, 255, 255}};
153 * Buffer with the discoverable devices.
155 static struct BroadcastMessages neighbours;
157 static int searching_devices_count = 0;
159 /* *********** specialized version of server_mst.c begins here ********** */
160 /* ****** this is the same version as the one used in gnunet-helper-transport-wlan.c ****** */
163 * To what multiple do we align messages? 8 byte should suffice for everyone
166 #define ALIGN_FACTOR 8
169 * Smallest supported message.
171 #define MIN_BUFFER_SIZE sizeof (struct GNUNET_MessageHeader)
175 * Functions with this signature are called whenever a
176 * complete message is received by the tokenizer.
179 * @param message the actual message
181 typedef void (*MessageTokenizerCallback) (void *cls,
183 GNUNET_MessageHeader *
187 * Handle to a message stream tokenizer.
189 struct MessageStreamTokenizer
193 * Function to call on completed messages.
195 MessageTokenizerCallback cb;
203 * Size of the buffer (starting at 'hdr').
208 * How many bytes in buffer have we already processed?
213 * How many bytes in buffer are valid right now?
218 * Beginning of the buffer. Typed like this to force alignment.
220 struct GNUNET_MessageHeader *hdr;
226 * Create a message stream tokenizer.
228 * @param cb function to call on completed messages
229 * @param cb_cls closure for cb
230 * @return handle to tokenizer
232 static struct MessageStreamTokenizer *
233 mst_create (MessageTokenizerCallback cb,
236 struct MessageStreamTokenizer *ret;
238 ret = malloc (sizeof (struct MessageStreamTokenizer));
241 fprintf (stderr, "Failed to allocate buffer for tokenizer\n");
244 ret->hdr = malloc (MIN_BUFFER_SIZE);
245 if (NULL == ret->hdr)
247 fprintf (stderr, "Failed to allocate buffer for alignment\n");
250 ret->curr_buf = MIN_BUFFER_SIZE;
252 ret->cb_cls = cb_cls;
260 * Add incoming data to the receive buffer and call the
261 * callback for all complete messages.
263 * @param mst tokenizer to use
264 * @param buf input data to add
265 * @param size number of bytes in buf
266 * @return GNUNET_OK if we are done processing (need more data)
267 * GNUNET_SYSERR if the data stream is corrupt
270 mst_receive (struct MessageStreamTokenizer *mst,
271 const char *buf, size_t size)
273 const struct GNUNET_MessageHeader *hdr;
278 unsigned long offset;
282 ibuf = (char *) mst->hdr;
286 if (mst->pos < mst->off)
288 //fprintf (stderr, "We processed too many bytes!\n");
289 return GNUNET_SYSERR;
291 if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) ||
292 (0 != (mst->off % ALIGN_FACTOR)))
294 /* need to align or need more space */
295 mst->pos -= mst->off;
296 memmove (ibuf, &ibuf[mst->off], mst->pos);
299 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
302 GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) -
303 (mst->pos - mst->off), size);
304 memcpy (&ibuf[mst->pos], buf, delta);
309 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
311 //FIXME should I reset ??
316 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
317 want = ntohs (hdr->size);
318 if (want < sizeof (struct GNUNET_MessageHeader))
321 "Received invalid message from stdin\n");
322 return GNUNET_SYSERR;
324 if ((mst->curr_buf - mst->off < want) &&
327 /* need more space */
328 mst->pos -= mst->off;
329 memmove (ibuf, &ibuf[mst->off], mst->pos);
332 if (want > mst->curr_buf)
336 fprintf (stderr, "Error! We should proceeded 0 bytes\n");
337 return GNUNET_SYSERR;
339 mst->hdr = realloc (mst->hdr, want);
340 if (NULL == mst->hdr)
342 fprintf (stderr, "Failed to allocate buffer for alignment\n");
345 ibuf = (char *) mst->hdr;
346 mst->curr_buf = want;
348 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
349 if (mst->pos - mst->off < want)
351 delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
352 if (mst->pos + delta > mst->curr_buf)
354 fprintf (stderr, "The size of the buffer will be exceeded!\n");
355 return GNUNET_SYSERR;
357 memcpy (&ibuf[mst->pos], buf, delta);
362 if (mst->pos - mst->off < want)
364 //FIXME should I use this?
369 mst->cb (mst->cb_cls, hdr);
371 if (mst->off == mst->pos)
373 /* reset to beginning of buffer, it's free right now! */
380 fprintf (stderr, "There should some valid bytes in the buffer on this stage\n");
381 return GNUNET_SYSERR;
385 if (size < sizeof (struct GNUNET_MessageHeader))
387 offset = (unsigned long) buf;
388 need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
389 if (GNUNET_NO == need_align)
391 /* can try to do zero-copy and process directly from original buffer */
392 hdr = (const struct GNUNET_MessageHeader *) buf;
393 want = ntohs (hdr->size);
394 if (want < sizeof (struct GNUNET_MessageHeader))
397 "Received invalid message from stdin\n");
400 return GNUNET_SYSERR;
403 break; /* or not, buffer incomplete, so copy to private buffer... */
404 mst->cb (mst->cb_cls, hdr);
410 /* need to copy to private buffer to align;
411 * yes, we go a bit more spagetti than usual here */
417 if (size + mst->pos > mst->curr_buf)
419 mst->hdr = realloc (mst->hdr, size + mst->pos);
420 if (NULL == mst->hdr)
422 fprintf (stderr, "Failed to allocate buffer for alignment\n");
425 ibuf = (char *) mst->hdr;
426 mst->curr_buf = size + mst->pos;
428 if (mst->pos + size > mst->curr_buf)
431 "Assertion failed\n");
434 memcpy (&ibuf[mst->pos], buf, size);
443 * Destroys a tokenizer.
445 * @param mst tokenizer to destroy
448 mst_destroy (struct MessageStreamTokenizer *mst)
454 /* ***************** end of server_mst.c clone ***************** **/
457 /* ****** same crc version as the one used in gnunet-helper-transport-wlan.c ****** */
460 * Calculate crc32, the start of the calculation
462 * @param buf buffer to calc the crc
463 * @param len len of the buffer
467 calc_crc_osdep (const unsigned char *buf, size_t len)
469 static const unsigned long int crc_tbl_osdep[256] = {
470 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
471 0xE963A535, 0x9E6495A3,
472 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
473 0xE7B82D07, 0x90BF1D91,
474 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
475 0xF4D4B551, 0x83D385C7,
476 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
477 0xFA0F3D63, 0x8D080DF5,
478 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
479 0xD20D85FD, 0xA50AB56B,
480 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
481 0xDCD60DCF, 0xABD13D59,
482 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
483 0xCFBA9599, 0xB8BDA50F,
484 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
485 0xC1611DAB, 0xB6662D3D,
486 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
487 0x9FBFE4A5, 0xE8B8D433,
488 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
489 0x91646C97, 0xE6635C01,
490 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
491 0x8208F4C1, 0xF50FC457,
492 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
493 0x8CD37CF3, 0xFBD44C65,
494 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
495 0xA4D1C46D, 0xD3D6F4FB,
496 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
497 0xAA0A4C5F, 0xDD0D7CC9,
498 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
499 0xB966D409, 0xCE61E49F,
500 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
501 0xB7BD5C3B, 0xC0BA6CAD,
502 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
503 0x04DB2615, 0x73DC1683,
504 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
505 0x0A00AE27, 0x7D079EB1,
506 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
507 0x196C3671, 0x6E6B06E7,
508 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
509 0x17B7BE43, 0x60B08ED5,
510 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
511 0x3FB506DD, 0x48B2364B,
512 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
513 0x316E8EEF, 0x4669BE79,
514 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
515 0x220216B9, 0x5505262F,
516 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
517 0x2CD99E8B, 0x5BDEAE1D,
518 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
519 0x72076785, 0x05005713,
520 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
521 0x7CDCEFB7, 0x0BDBDF21,
522 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
523 0x6FB077E1, 0x18B74777,
524 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
525 0x616BFFD3, 0x166CCF45,
526 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
527 0x4969474D, 0x3E6E77DB,
528 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
529 0x47B2CF7F, 0x30B5FFE9,
530 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
531 0x54DE5729, 0x23D967BF,
532 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
533 0x5A05DF1B, 0x2D02EF8D
536 unsigned long crc = 0xFFFFFFFF;
538 for (; len > 0; len--, buf++)
539 crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
545 * Calculate and check crc of the bluetooth packet
547 * @param buf buffer of the packet, with len + 4 bytes of data,
548 * the last 4 bytes being the checksum
549 * @param len length of the payload in data
550 * @return 0 on success (checksum matches), 1 on error
553 check_crc_buf_osdep (const unsigned char *buf, size_t len)
557 crc = calc_crc_osdep (buf, len);
559 if (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
560 ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3])
567 /* ************** end of crc version ***************** */
573 * Function for assigning a port number
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 bind 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 sockaddr_rc));
598 * Function used for creating the service record and registering it.
599 * @param dev pointer to the device struct
600 * @param rc_channel the rfcomm channel
601 * @return 0 on success
604 register_service (struct HardwareInfos *dev, int rc_channel)
608 * 2. set the service ID, class, profile information
609 * 3. make the service record publicly browsable
610 * 4. register the RFCOMM channel
611 * 5. set the name, provider and description
612 * 6. register the service record to the local SDP server
616 //FIXME: probably this is not the best idea. I should find a different uuid
617 uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
618 dev->pl_mac.mac[5], dev->pl_mac.mac[4], dev->pl_mac.mac[3],
619 dev->pl_mac.mac[2], dev->pl_mac.mac[1], dev->pl_mac.mac[0]};
620 // const char *service_name = "GNUnet";
621 const char *service_dsc = "Bluetooth plugin services";
622 const char *service_prov = "GNUnet provider";
623 uuid_t root_uuid, rfcomm_uuid, svc_uuid;
624 sdp_list_t *root_list = 0, *rfcomm_list = 0, *proto_list = 0,
625 *access_proto_list = 0, *svc_list = 0;
626 sdp_record_t *record = 0;
627 sdp_data_t *channel = 0;
629 record = sdp_record_alloc();
631 /* Set the general service ID */
632 sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
633 svc_list = sdp_list_append (0, &svc_uuid);
634 sdp_set_service_classes (record, svc_list);
635 sdp_set_service_id (record, svc_uuid);
637 /* Make the service record publicly browsable */
638 sdp_uuid16_create (&root_uuid, PUBLIC_BROWSE_GROUP);
639 root_list = sdp_list_append (0, &root_uuid);
640 sdp_set_browse_groups (record, root_list);
642 /* Register the RFCOMM channel */
643 sdp_uuid16_create (&rfcomm_uuid, RFCOMM_UUID);
644 channel = sdp_data_alloc (SDP_UINT8, &rc_channel);
645 rfcomm_list = sdp_list_append (0, &rfcomm_uuid);
646 sdp_list_append (rfcomm_list, channel);
647 proto_list = sdp_list_append (0, rfcomm_list);
649 /* Set protocol information */
650 access_proto_list = sdp_list_append (0, proto_list);
651 sdp_set_access_protos (record, access_proto_list);
653 /* Set the name, provider, and description */
654 sdp_set_info_attr (record, dev->iface, service_prov, service_dsc);
656 /* Connect to the local SDP server */
657 dev->session = sdp_connect (BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
661 fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
662 IFNAMSIZ, dev->iface, strerror (errno));
667 /* Register the service record */
668 if (sdp_record_register (dev->session, record, 0) < 0)
670 fprintf (stderr, "Failed to register a service record on interface `%.*s': %s\n",
671 IFNAMSIZ, dev->iface, strerror (errno));
677 sdp_data_free (channel);
678 sdp_list_free (root_list, 0);
679 sdp_list_free (rfcomm_list, 0);
680 sdp_list_free (proto_list, 0);
681 sdp_list_free (access_proto_list, 0);
682 sdp_list_free (svc_list, 0);
683 sdp_record_free (record);
689 * Function for searching and browsing for a service. This will return the
690 * port number on which the service is running.
691 * @param dev pointer to the device struct
692 * @param dest target address
696 get_channel(struct HardwareInfos *dev, bdaddr_t dest)
699 * 1. detect all nearby devices
700 * 2. for each device:
701 * 2.1. connect to the SDP server running
702 * 2.2. get a list of service records with the specific UUID
703 * 2.3. for each service record get a list of the protocol sequences and get
706 uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
707 dest.b[5], dest.b[4], dest.b[3],
708 dest.b[2], dest.b[1], dest.b[0]};
709 sdp_session_t *session = 0;
710 sdp_list_t *search_list = 0, *attrid_list = 0, *response_list = 0, *it = 0;
712 uint32_t range = 0x0000ffff;
713 uint8_t channel = -1;
715 /* Connect to the local SDP server */
716 session = sdp_connect (BDADDR_ANY, &dest, 0);
719 fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
720 IFNAMSIZ, dev->iface, strerror (errno));
725 sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
726 search_list = sdp_list_append (0, &svc_uuid);
727 attrid_list = sdp_list_append (0, &range);
729 if (sdp_service_search_attr_req (session, search_list,
730 SDP_ATTR_REQ_RANGE, attrid_list, &response_list) == 0)
732 for (it = response_list; it; it = it->next)
734 sdp_record_t *record = (sdp_record_t*) it->data;
735 //TODO print some record informations to be sure everything is good
736 sdp_list_t *proto_list = 0;
737 if (sdp_get_access_protos (record, &proto_list) == 0)
739 channel = sdp_get_proto_port (proto_list, RFCOMM_UUID);
740 sdp_list_free (proto_list, 0);
742 sdp_record_free (record);
746 sdp_list_free (search_list, 0);
747 sdp_list_free (attrid_list, 0);
748 sdp_list_free (response_list, 0);
753 fprintf (stderr, "Failed to find the listening channel for interface `%.*s': %s\n",
754 IFNAMSIZ, dev->iface, strerror (errno));
760 * Read from the socket and put the result into the buffer for transmission to 'stdout'.
761 * @param sock file descriptor for reading
762 * @param buf buffer to read to; first bytes will be the 'struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame',
763 * followed by the actual payload
764 * @param buf_size size of the buffer
765 * @param ri where to write radiotap_rx info
766 * @return number of bytes written to 'buf'
769 read_from_the_socket (int sock,
770 unsigned char *buf, size_t buf_size,
771 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri)
774 * 1. Read from the socket in a temporary buffer (check for errors)
775 * 2. Detect if the crc exists
776 * 3. Write the result to the buffer
778 unsigned char tmpbuf[buf_size];
781 struct sockaddr_rc rc_addr = { 0 };
783 count = read (sock, tmpbuf, buf_size);
790 fprintf (stderr, "Failed to read from the HCI socket: %s\n", strerror (errno));
794 /* Get the channel used */
795 memset (&rc_addr, 0, sizeof (rc_addr));
796 len = sizeof (rc_addr);
797 if (0 > getsockname (sock, (struct sockaddr *) &rc_addr, (socklen_t *) &len))
799 fprintf (stderr, "getsockname() call failed : %s\n", strerror (errno));
803 memset (ri, 0, sizeof (*ri));
804 ri->ri_channel = rc_addr.rc_channel;
806 /* Detect CRC32 at the end */
807 if (0 == check_crc_buf_osdep (tmpbuf, count - sizeof (uint32_t)))
809 count -= sizeof(uint32_t);
812 memcpy (buf, tmpbuf, count);
818 * Open the bluetooth interface for reading/writing
820 * @param dev pointer to the device struct
821 * @return 0 on success
824 open_device (struct HardwareInfos *dev)
826 int i, dev_id = -1, fd_hci;
829 struct hci_dev_list_req list;
830 struct hci_dev_req dev[HCI_MAX_DEV];
831 } request; //used for detecting the local devices
832 struct sockaddr_rc rc_addr = { 0 }; //used for binding
834 /* Initialize the neighbour structure */
835 neighbours.dev_id = -1;
836 for (i = 0; i < MAX_PORTS; i++)
837 neighbours.fds[i] = -1;
839 /* Open a HCI socket */
840 fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
844 fprintf (stderr, "Failed to create HCI socket: %s\n", strerror (errno));
848 memset (&request, 0, sizeof(request));
849 request.list.dev_num = HCI_MAX_DEV;
851 if (ioctl (fd_hci, HCIGETDEVLIST, (void *) &request) < 0)
853 fprintf (stderr, "ioctl(HCIGETDEVLIST) on interface `%.*s' failed: %s\n",
854 IFNAMSIZ, dev->iface, strerror (errno));
858 /* Search for a device with dev->iface name */
859 for (i = 0; i < request.list.dev_num; i++)
861 struct hci_dev_info dev_info;
863 memset (&dev_info, 0, sizeof(struct hci_dev_info));
864 dev_info.dev_id = request.dev[i].dev_id;
865 strncpy (dev_info.name, dev->iface, IFNAMSIZ);
867 if (ioctl (fd_hci, HCIGETDEVINFO, (void *) &dev_info))
869 fprintf (stderr, "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n",
870 IFNAMSIZ, dev->iface, strerror (errno));
874 if (strcmp (dev_info.name, dev->iface) == 0)
877 dev_id = dev_info.dev_id; //the device was found
879 * Copy the MAC address to the device structure
881 memcpy (&dev->pl_mac, &dev_info.bdaddr, sizeof (bdaddr_t));
883 /* Check if the interface is UP */
884 if (hci_test_bit (HCI_UP, (void *) &dev_info.flags) == 0)
886 /* Bring interface up */
887 if (ioctl (fd_hci, HCIDEVUP, dev_info.dev_id))
889 fprintf (stderr, "ioctl(HCIDEVUP) on interface `%.*s' failed: %s\n",
890 IFNAMSIZ, dev->iface, strerror (errno));
895 /* Check if the device is discoverable */
896 if (hci_test_bit (HCI_PSCAN, (void *) &dev_info.flags) == 0 ||
897 hci_test_bit (HCI_ISCAN, (void *) &dev_info.flags) == 0)
899 /* Set interface Page Scan and Inqury Scan ON */
900 struct hci_dev_req dev_req;
902 memset (&dev_req, 0, sizeof (dev_req));
903 dev_req.dev_id = dev_info.dev_id;
904 dev_req.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
906 if (ioctl (fd_hci, HCISETSCAN, (unsigned long) &dev_req))
908 fprintf (stderr, "ioctl(HCISETSCAN) on interface `%.*s' failed: %s\n",
909 IFNAMSIZ, dev->iface, strerror (errno));
919 /* Check if the interface was not found */
922 fprintf (stderr, "The interface %s was not found\n", dev->iface);
926 /* Close the hci socket */
927 (void) close(fd_hci);
931 /* Bind the rfcomm socket to the interface */
932 memset (&rc_addr, 0, sizeof (rc_addr));
933 rc_addr.rc_family = AF_BLUETOOTH;
934 rc_addr.rc_bdaddr = *BDADDR_ANY;
936 if (bind_socket (dev->fd_rfcomm, &rc_addr) != 0)
938 fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
939 dev->iface, strerror (errno));
943 /* Register a SDP service */
944 if (register_service (dev, rc_addr.rc_channel) != 0)
946 fprintf (stderr, "Failed to register a service on interface `%.*s': %s\n", IFNAMSIZ,
947 dev->iface, strerror (errno));
951 /* Switch socket in listening mode */
952 if (listen (dev->fd_rfcomm, 5) == -1) //FIXME: probably we need a bigger number
954 fprintf (stderr, "Failed to listen on socket for interface `%.*s': %s\n", IFNAMSIZ,
955 dev->iface, strerror (errno));
965 * Set the header to sane values to make attacks more difficult
967 * @param taIeeeHeader pointer to the header of the packet
968 * @param dev pointer to the Hardware_Infos struct
970 **** copy from gnunet-helper-transport-wlan.c ****
973 mac_set (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
974 const struct HardwareInfos *dev)
976 taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
977 taIeeeHeader->addr2 = dev->pl_mac;
978 taIeeeHeader->addr3 = mac_bssid_gnunet;
982 * Test if the given interface name really corresponds to a bluetooth
985 * @param iface name of the interface
986 * @return 0 on success, 1 on error
987 **** similar with the one from gnunet-helper-transport-wlan.c ****
990 test_bluetooth_interface (const char *iface)
996 ret = snprintf (strbuf, sizeof (strbuf),
997 "/sys/class/bluetooth/%s/subsystem",
999 if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
1002 "Did not find 802.15.1 interface `%s'. Exiting.\n",
1010 * Test incoming packets mac for being our own.
1012 * @param taIeeeHeader buffer of the packet
1013 * @param dev the Hardware_Infos struct
1014 * @return 0 if mac belongs to us, 1 if mac is for another target
1016 **** same as the one from gnunet-helper-transport-wlan.c ****
1019 mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1020 const struct HardwareInfos *dev)
1022 static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
1024 if ( (0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
1025 (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)) )
1026 return 0; /* some drivers set no Macs, then assume it is all for us! */
1028 if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1029 return 1; /* not a GNUnet ad-hoc package */
1030 if ( (0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
1031 (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)) )
1032 return 0; /* for us, or broadcast */
1033 return 1; /* not for us */
1038 * Process data from the stdin. Takes the message forces the sender MAC to be correct
1039 * and puts it into our buffer for transmission to the kernel. (the other device).
1041 * @param cls pointer to the device struct ('struct HardwareInfos*')
1042 * @param hdr pointer to the start of the packet
1044 **** same as the one from gnunet-helper-transport-wlan.c ****
1047 stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1049 struct HardwareInfos *dev = cls;
1050 const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header;
1051 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *blueheader;
1054 sendsize = ntohs (hdr->size);
1056 sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
1057 (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) )
1059 fprintf (stderr, "Received malformed message\n");
1062 sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) -
1063 sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1064 if (MAXLINE < sendsize)
1066 fprintf (stderr, "Packet too big for buffer\n");
1069 header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
1070 memcpy (&write_pout.buf, &header->frame, sendsize);
1071 blueheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf;
1073 /* payload contains MAC address, but we don't trust it, so we'll
1074 * overwrite it with OUR MAC address to prevent mischief */
1075 mac_set (blueheader, dev);
1076 memcpy (&blueheader->addr1, &header->frame.addr1,
1077 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)); //FIXME is this correct?
1078 write_pout.size = sendsize;
1082 * Broadcast a HELLO message for peer discovery
1083 * @param dev pointer to the device struct
1084 * @param dev pointer to the socket which was added to the set
1085 * @return 0 on success
1088 send_broadcast (struct HardwareInfos *dev, int *sendsocket)
1094 if ((neighbours.size == neighbours.pos && new_device == 1) || neighbours.size == 0)
1096 inquiry_devices: //skip the conditions and force a inquiry for new devices
1099 * It means that I sent HELLO messages to all the devices from the list and I should search
1100 * for another ones or that this is the first time when I do a search.
1102 inquiry_info *devices = NULL;
1103 int i, responses, max_responses = MAX_PORTS;
1106 if (neighbours.size >= MAX_PORTS)
1108 fprintf (stderr, "%.*s reached the top limit for the discovarable devices\n", IFNAMSIZ, dev->iface);
1112 /* Get the device id */
1113 if (neighbours.dev_id == -1)
1115 char addr[19] = { 0 }; //the device MAC address
1117 ba2str ((bdaddr_t *) &dev->pl_mac, addr);
1118 neighbours.dev_id = hci_devid (addr);
1119 if (neighbours.dev_id < 0)
1121 fprintf (stderr, "Failed to get the device id for interface %.*s : %s\n", IFNAMSIZ,
1122 dev->iface, strerror (errno));
1127 devices = malloc (max_responses * sizeof (inquiry_info));
1128 if (devices == NULL)
1130 fprintf (stderr, "Failed to allocate memory for inquiry info list on interface %.*s\n", IFNAMSIZ,
1135 responses = hci_inquiry (neighbours.dev_id, 8, max_responses, NULL, &devices, IREQ_CACHE_FLUSH);
1138 fprintf (stderr, "Failed to inquiry on interface %.*s\n", IFNAMSIZ, dev->iface);
1142 fprintf (stderr, "LOG : Found %d devices\n", responses); //FIXME delete it after debugging stage
1146 fprintf (stderr, "LOG : No devices discoverable\n");
1150 for (i = 0; i < responses; i++)
1158 fprintf (stderr, "%.*s reached the top limit for the discoverable devices (after inquiry)\n", IFNAMSIZ,
1163 /* Search if the address already exists on the list */
1164 for (j = 0; j < neighbours.size; j++)
1166 if (memcmp (&(devices + i)->bdaddr, &(neighbours.devices[j]), sizeof (bdaddr_t)) == 0)
1169 fprintf (stderr, "LOG : the device already exists on the list\n"); //FIXME debugging message
1176 char addr[19] = { 0 };
1178 ba2str (&(devices +i)->bdaddr, addr);
1179 fprintf (stderr, "LOG : %s was added to the list\n", addr); //FIXME debugging message
1180 memcpy (&(neighbours.devices[neighbours.size++]), &(devices + i)->bdaddr, sizeof (bdaddr_t));
1188 int connection_successful = 0;
1189 struct sockaddr_rc addr_rc = { 0 };
1191 addr_rc.rc_family = AF_BLUETOOTH;
1193 /* Try to connect to a new device from the list */
1194 while (neighbours.pos < neighbours.size)
1196 /* Check if we are connected to this device */
1197 if (neighbours.fds[neighbours.pos] == -1)
1200 memset (&addr_rc.rc_bdaddr, 0, sizeof (addr_rc.rc_bdaddr));
1201 memcpy (&addr_rc.rc_bdaddr, &(neighbours.devices[neighbours.pos]), sizeof (addr_rc.rc_bdaddr));
1203 addr_rc.rc_channel = get_channel (dev, addr_rc.rc_bdaddr);
1205 *sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1206 //TODO adauga un label aici si intoarcete de cateva ori daca nu reuseste
1207 if (connect (*sendsocket, (struct sockaddr *)&addr_rc, sizeof (addr_rc)) == 0)
1209 neighbours.fds[neighbours.pos++] = *sendsocket;
1210 connection_successful = 1;
1211 char addr[19] = { 0 };
1212 ba2str (&(neighbours.devices[neighbours.pos - 1]), addr);
1213 fprintf (stderr, "LOG : Connected to %s\n", addr);
1219 char addr[19] = { 0 };
1220 errno_copy = errno; //Save a copy for later
1221 ba2str (&(neighbours.devices[neighbours.pos]), addr);
1222 fprintf (stderr, "LOG : Couldn't connect on device %s, error : %s\n", addr, strerror(errno));
1223 if (errno != ECONNREFUSED) //FIXME nu merge!
1225 fprintf (stderr, "LOG : Removes %d device from the list\n", neighbours.pos);
1226 /* Remove the device from the list */
1227 memcpy (&neighbours.devices[neighbours.pos], &neighbours.devices[neighbours.size - 1], sizeof (bdaddr_t));
1228 memset (&neighbours.devices[neighbours.size - 1], 0, sizeof (bdaddr_t));
1229 neighbours.fds[neighbours.pos] = neighbours.fds[neighbours.size - 1];
1230 neighbours.fds[neighbours.size - 1] = -1;
1231 neighbours.size -= 1;
1234 neighbours.pos += 1;
1236 if (neighbours.pos >= neighbours.size)
1241 if (loops == MAX_LOOPS) //don't get stuck trying to connect to one device
1247 fprintf (stderr, "LOG : Search for a new device\n"); //FIXME debugging message
1248 neighbours.pos += 1;
1252 /* Cycle on the list */
1253 if (neighbours.pos == neighbours.size)
1256 searching_devices_count += 1;
1258 if (searching_devices_count == MAX_LOOPS)
1260 fprintf (stderr, "LOG : Force to inquiry for new devices\n");
1261 searching_devices_count = 0;
1262 goto inquiry_devices;
1265 /* If a new device wasn't found, search an old one */
1266 if (connection_successful == 0)
1268 int loop_check = neighbours.pos;
1269 while (neighbours.fds[neighbours.pos] == -1)
1271 if (neighbours.pos == neighbours.size)
1274 if (neighbours.pos == loop_check)
1276 if (errno_copy == ECONNREFUSED)
1278 fprintf (stderr, "LOG : No device found. Go back and search again\n"); //FIXME debugging message
1281 goto search_for_devices;
1285 return 1; // Skip the broadcast message
1289 neighbours.pos += 1;
1292 *sendsocket = neighbours.fds[neighbours.pos++];
1299 * Main function of the helper. This code accesses a bluetooth interface
1300 * forwards traffic in both directions between the bluetooth interface and
1301 * stdin/stdout of this process. Error messages are written to stdout.
1303 * @param argc number of arguments, must be 2
1304 * @param argv arguments only argument is the name of the interface (i.e. 'hci0')
1305 * @return 0 on success (never happens, as we don't return unless aborted), 1 on error
1307 **** same as the one from gnunet-helper-transport-wlan.c ****
1310 main (int argc, char *argv[])
1312 struct HardwareInfos dev;
1313 char readbuf[MAXLINE];
1318 struct MessageStreamTokenizer *stdin_mst;
1321 int crt_rfds = 0, rfds_list[MAX_PORTS];
1322 int broadcast, sendsocket;
1323 /* Assert privs so we can modify the firewall rules! */
1325 #ifdef HAVE_SETRESUID
1326 if (0 != setresuid (uid, 0, 0))
1328 fprintf (stderr, "Failed to setresuid to root: %s\n", strerror (errno));
1332 if (0 != seteuid (0))
1334 fprintf (stderr, "Failed to seteuid back to root: %s\n", strerror (errno));
1339 /* Make use of SGID capabilities on POSIX */
1340 memset (&dev, 0, sizeof (dev));
1341 dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1342 raw_eno = errno; /* remember for later */
1344 /* Now that we've dropped root rights, we can do error checking */
1347 fprintf (stderr, "You must specify the name of the interface as the first \
1348 and only argument to this program.\n");
1349 if (-1 != dev.fd_rfcomm)
1350 (void) close (dev.fd_rfcomm);
1354 if (-1 == dev.fd_rfcomm)
1356 fprintf (stderr, "Failed to create a HCI socket: %s\n", strerror (raw_eno));
1359 if (dev.fd_rfcomm >= FD_SETSIZE)
1361 fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1362 dev.fd_rfcomm, FD_SETSIZE);
1363 (void) close (dev.fd_rfcomm);
1366 if (0 != test_bluetooth_interface (argv[1]))
1368 (void) close (dev.fd_rfcomm);
1371 strncpy (dev.iface, argv[1], IFNAMSIZ);
1372 if (0 != open_device (&dev))
1374 (void) close (dev.fd_rfcomm);
1380 uid_t uid = getuid ();
1381 #ifdef HAVE_SETRESUID
1382 if (0 != setresuid (uid, uid, uid))
1384 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1385 if (-1 != dev.fd_rfcomm)
1386 (void) close (dev.fd_rfcomm);
1390 if (0 != (setuid (uid) | seteuid (uid)))
1392 fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
1393 if (-1 != dev.fd_rfcomm)
1394 (void) close (dev.fd_rfcomm);
1400 /* Send MAC address of the bluetooth interface to STDOUT first */
1402 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
1404 macmsg.hdr.size = htons (sizeof (macmsg));
1405 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
1406 memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1407 memcpy (write_std.buf, &macmsg, sizeof (macmsg));
1408 write_std.size = sizeof (macmsg);
1412 stdin_mst = mst_create (&stdin_send_hw, &dev);
1415 fprintf (stderr, "\n-----------------------------------------------\n Check if the program exits\n-----------------------------------------------\n");
1417 * TODO : When a connection fails I should ignore only the CONTROL messages.
1418 * For DATA messages I should retry to send the message until it doesn't fail
1419 * Also I should make the time out of a mac endpoint smaller and check if the rate
1420 * from get_wlan_header (plugin_transport_bluetooth.c) is correct.
1429 if ((0 == write_pout.size) && (1 == stdin_open))
1431 FD_SET (STDIN_FILENO, &rfds);
1432 maxfd = MAX (maxfd, STDIN_FILENO);
1434 if (0 == write_std.size)
1436 FD_SET (dev.fd_rfcomm, &rfds);
1437 maxfd = MAX (maxfd, dev.fd_rfcomm);
1440 for (i = 0; i < crt_rfds; i++) // it can receive messages from multiple devices
1442 FD_SET (rfds_list[i], &rfds);
1443 maxfd = MAX (maxfd, rfds_list[i]);
1446 if (0 < write_std.size)
1448 FD_SET (STDOUT_FILENO, &wfds);
1449 maxfd = MAX (maxfd, STDOUT_FILENO);
1451 if (0 < write_pout.size) //it can send messages only to one device per loop
1453 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *frame;
1454 /* Get the destination address */
1455 frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) write_pout.buf;
1457 if (memcmp (&frame->addr1, &dev.pl_mac,
1458 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1461 memset (&write_pout, 0, sizeof (write_pout)); //clear the buffer
1463 else if (memcmp (&frame->addr1, &broadcast_address,
1464 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1466 fprintf (stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n", dev.iface, neighbours.pos, neighbours.size); //FIXME: debugging message
1467 // broadcast = 1; // IF I HAVE A BROADCAST MESSAGE I skip.
1468 // memset (&write_pout, 0, sizeof (write_pout));
1470 if (send_broadcast(&dev, &sendsocket) != 0) //if the searching wasn't successful don't get stuck on the select stage
1473 memset (&write_pout, 0, sizeof (write_pout)); //remove the message
1474 fprintf (stderr, "LOG : Skip the broadcast message (pos %d, size %d)\n", neighbours.pos, neighbours.size);
1478 FD_SET (sendsocket, &wfds);
1479 maxfd = MAX (maxfd, sendsocket);
1486 /* Search if the address already exists on the list */
1487 for (i = 0; i < neighbours.size; i++)
1489 if (memcmp (&frame->addr1, &(neighbours.devices[i]), sizeof (bdaddr_t)) == 0)
1492 if (neighbours.fds[i] != -1)
1494 found = 1; //save the position where it was found
1495 FD_SET (neighbours.fds[i], &wfds);
1496 maxfd = MAX (maxfd, neighbours.fds[i]);
1497 sendsocket = neighbours.fds[i];
1498 fprintf (stderr, "LOG: the address was found in the list\n");
1506 struct sockaddr_rc addr = { 0 };
1508 fprintf (stderr, "LOG : %s has a new message for %.2X:%.2X:%.2X:%.2X:%.2X:%.2X which isn't on the broadcast list\n", dev.iface,
1509 frame->addr1.mac[5], frame->addr1.mac[4], frame->addr1.mac[3],
1510 frame->addr1.mac[2], frame->addr1.mac[1], frame->addr1.mac[0]); //FIXME: debugging message
1512 sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1516 fprintf (stderr, "Failed to create a RFCOMM socket (sending stage): %s\n",
1521 memcpy (&addr.rc_bdaddr, &frame->addr1, sizeof (bdaddr_t));
1522 addr.rc_family = AF_BLUETOOTH;
1523 addr.rc_channel = get_channel (&dev, addr.rc_bdaddr);
1527 status = connect (sendsocket, (struct sockaddr *) &addr, sizeof (addr));
1528 if (0 != status && errno != EAGAIN)
1530 if (errno == ECONNREFUSED && tries < 2)
1532 fprintf (stderr, "LOG : %.*s failed to connect. Trying again!\n", IFNAMSIZ, dev.iface);
1536 else if (errno == EBADF)
1538 fprintf (stderr, "LOG : %s failed to connect : %s. Skip it!\n", dev.iface, strerror (errno));
1539 memset (&write_pout, 0, sizeof (write_pout));
1544 fprintf (stderr, "LOG : %s failed to connect : %s. Try again later!\n", dev.iface, strerror (errno));
1545 memset (&write_pout, 0, sizeof (write_pout));
1552 FD_SET (sendsocket, &wfds);
1553 maxfd = MAX (maxfd, sendsocket);
1554 fprintf (stderr, "LOG : Connection successful\n");
1555 if (pos != 0) // save the socket
1557 neighbours.fds[pos] = sendsocket;
1561 /* Add the new device to the discovered devices list */
1562 if (neighbours.size < MAX_PORTS)
1564 neighbours.fds[neighbours.size] = sendsocket;
1565 memcpy (&(neighbours.devices[neighbours.size++]), &addr.rc_bdaddr, sizeof (bdaddr_t));
1569 fprintf (stderr, "The top limit for the discovarable devices' list was reached\n");
1579 /* Select a fd which is ready for action :) */
1581 int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
1582 if ((-1 == retval) && (EINTR == errno))
1584 if (0 > retval && errno != EBADF) // we handle BADF errors later
1586 fprintf (stderr, "select failed: %s\n", strerror (errno));
1590 if (FD_ISSET (STDOUT_FILENO , &wfds))
1593 write (STDOUT_FILENO, write_std.buf + write_std.pos,
1594 write_std.size - write_std.pos);
1597 fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1600 write_std.pos += ret;
1601 if (write_std.pos == write_std.size)
1606 fprintf (stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); //FIXME: debugging message
1609 if (sendsocket != -1)
1611 if (FD_ISSET (sendsocket , &wfds))
1614 write (sendsocket, write_pout.buf + write_std.pos,
1615 write_pout.size - write_pout.pos);
1616 if (0 > ret) //FIXME should I check first the error type?
1618 fprintf (stderr, "Failed to write to bluetooth device: %s. Closing the socket!\n",
1620 for (i = 0; i < neighbours.size; i++)
1622 if (neighbours.fds[i] == sendsocket)
1624 (void) close(sendsocket);
1625 neighbours.fds[i] = -1;
1629 /* Remove the message */
1630 memset (&write_pout.buf + write_std.pos, 0, (write_pout.size - write_pout.pos));
1631 write_pout.pos = 0 ;
1632 write_pout.size = 0;
1636 write_pout.pos += ret;
1637 if ((write_pout.pos != write_pout.size) && (0 != ret))
1639 /* We should not get partial sends with packet-oriented devices... */
1640 fprintf (stderr, "Write error, partial send: %u/%u\n",
1641 (unsigned int) write_pout.pos,
1642 (unsigned int) write_pout.size);
1646 if (write_pout.pos == write_pout.size)
1649 write_pout.size = 0;
1651 fprintf (stderr, "LOG : %s sends a message to a DEVICE\n", dev.iface); //FIXME: debugging message
1655 for (i = 0; i <= maxfd; i++)
1657 if (FD_ISSET (i, &rfds))
1659 if (i == STDIN_FILENO)
1662 read (i, readbuf, sizeof (readbuf));
1665 fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno));
1670 /* stop reading... */
1675 mst_receive (stdin_mst, readbuf, ret);
1676 fprintf (stderr, "LOG : %s receives a message from STDIN\n", dev.iface); //FIXME: debugging message
1679 else if (i == dev.fd_rfcomm)
1682 struct sockaddr_rc addr = { 0 };
1683 unsigned int opt = sizeof (addr);
1685 readsocket = accept (dev.fd_rfcomm, (struct sockaddr *) &addr, &opt);
1686 fprintf(stderr, "LOG : %s accepts a message\n", dev.iface); //FIXME: debugging message
1687 if (readsocket == -1)
1689 fprintf (stderr, "Failed to accept a connection on interface: %.*s\n", IFNAMSIZ,
1695 FD_SET (readsocket, &rfds);
1696 maxfd = MAX (maxfd, readsocket);
1698 if (crt_rfds < MAX_PORTS)
1699 rfds_list[crt_rfds++] = readsocket;
1702 fprintf (stderr, "The limit for the read file descriptors list was \
1711 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
1713 fprintf (stderr, "LOG : %s reads something from the socket\n", dev.iface);//FIXME : debugging message
1714 rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
1716 read_from_the_socket (i, (unsigned char *) &rrm->frame,
1717 sizeof (write_std.buf)
1718 - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
1719 + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
1726 /* Remove the socket from the list */
1727 for (j = 0; j < crt_rfds; j++)
1729 if (rfds_list[j] == i)
1731 rfds_list[j] ^= rfds_list[crt_rfds - 1];
1732 rfds_list[crt_rfds - 1] ^= rfds_list[j];
1733 rfds_list[j] ^= rfds_list[crt_rfds - 1];
1739 fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
1742 if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
1744 write_std.size = ret
1745 + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
1746 - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
1747 rrm->header.size = htons (write_std.size);
1748 rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
1755 /* Error handling, try to clean up a bit at least */
1756 mst_destroy (stdin_mst);
1758 sdp_close (dev.session);
1759 (void) close (dev.fd_rfcomm);
1760 (void) close (sendsocket);
1762 for (i = 0; i < crt_rfds; i++)
1763 (void) close (rfds_list[i]);
1765 for (i = 0; i < neighbours.size; i++)
1766 (void) close (neighbours.fds[i]);
1768 return 1; /* we never exit 'normally' */