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 a 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 //FIXME : Connect directly to the device with the service
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)
827 * 1. Open a HCI socket (if RFCOMM protocol is used. If not, the HCI socket is
828 * saved in dev->rfcomm).
829 * 2. Find the device id (request a list with all the devices and find the one
830 * with the dev->iface name)
831 * 3. If the interface is down try to get it up
832 * 4. Bind the RFCOMM socket to the interface using the bind_socket() method and register
834 * 5. For now use a hard coded port number(channel) value
835 * FIXME : if I use HCI sockets , should I enable RAW_SOCKET MODE?!?!?!
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 fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
855 fprintf (stderr, "Failed to create HCI socket: %s\n", strerror (errno));
859 memset (&request, 0, sizeof(request));
860 request.list.dev_num = HCI_MAX_DEV;
862 if (ioctl (fd_hci, HCIGETDEVLIST, (void *) &request) < 0)
864 fprintf (stderr, "ioctl(HCIGETDEVLIST) on interface `%.*s' failed: %s\n",
865 IFNAMSIZ, dev->iface, strerror (errno));
869 /* Search for a device with dev->iface name */
870 for (i = 0; i < request.list.dev_num; i++)
872 struct hci_dev_info dev_info;
874 memset (&dev_info, 0, sizeof(struct hci_dev_info));
875 dev_info.dev_id = request.dev[i].dev_id;
876 strncpy (dev_info.name, dev->iface, IFNAMSIZ);
878 if (ioctl (fd_hci, HCIGETDEVINFO, (void *) &dev_info))
880 fprintf (stderr, "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n",
881 IFNAMSIZ, dev->iface, strerror (errno));
885 if (strcmp (dev_info.name, dev->iface) == 0)
888 dev_id = dev_info.dev_id; //the device was found
890 * Copy the MAC address to the device structure
891 * FIXME: probably this is not the best solution
893 memcpy (&dev->pl_mac, &dev_info.bdaddr, sizeof (bdaddr_t));
895 /* Check if the interface is UP */
896 if (hci_test_bit (HCI_UP, (void *) &dev_info.flags) == 0)
898 /* Bring interface up */ //FIXME should I check if is HCI_RUNNING ?!?!??!
899 if (ioctl (fd_hci, HCIDEVUP, dev_info.dev_id))
901 fprintf (stderr, "ioctl(HCIDEVUP) on interface `%.*s' failed: %s\n",
902 IFNAMSIZ, dev->iface, strerror (errno));
907 /* Check if the device is discoverable */
908 if (hci_test_bit (HCI_PSCAN, (void *) &dev_info.flags) == 0 ||
909 hci_test_bit (HCI_ISCAN, (void *) &dev_info.flags) == 0)
911 /* Set interface Page Scan and Inqury Scan ON */
912 struct hci_dev_req dev_req;
914 memset (&dev_req, 0, sizeof (dev_req));
915 dev_req.dev_id = dev_info.dev_id;
916 dev_req.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
918 if (ioctl (fd_hci, HCISETSCAN, (unsigned long) &dev_req))
920 fprintf (stderr, "ioctl(HCISETSCAN) on interface `%.*s' failed: %s\n",
921 IFNAMSIZ, dev->iface, strerror (errno));
927 //FIXME : Sniff mode!?!
928 //FIXME : RAW MODE?!?
935 /* Check if the interface was not found */
938 fprintf (stderr, "The interface %s was not found\n", dev->iface);
942 /* Close the hci socket */
943 (void) close(fd_hci);
947 /* Bind the rfcomm socket to the interface */
948 memset (&rc_addr, 0, sizeof (rc_addr));
949 rc_addr.rc_family = AF_BLUETOOTH;
950 rc_addr.rc_bdaddr = *BDADDR_ANY;
952 if (bind_socket (dev->fd_rfcomm, &rc_addr) != 0)
954 fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
955 dev->iface, strerror (errno));
959 /* Register a SDP service */
960 if (register_service (dev, rc_addr.rc_channel) != 0)
962 fprintf (stderr, "Failed to register a service on interface `%.*s': %s\n", IFNAMSIZ,
963 dev->iface, strerror (errno));
967 /* Switch socket in listening mode */
968 if (listen (dev->fd_rfcomm, 5) == -1) //FIXME: probably we need a bigger number
970 fprintf (stderr, "Failed to listen on socket for interface `%.*s': %s\n", IFNAMSIZ,
971 dev->iface, strerror (errno));
981 * Set the header to sane values to make attacks more difficult
983 * @param taIeeeHeader pointer to the header of the packet
984 * @param dev pointer to the Hardware_Infos struct
986 **** copy from gnunet-helper-transport-wlan.c ****
989 mac_set (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
990 const struct HardwareInfos *dev)
992 taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
993 taIeeeHeader->addr2 = dev->pl_mac;
994 taIeeeHeader->addr3 = mac_bssid_gnunet;
998 * Test if the given interface name really corresponds to a bluetooth
1001 * @param iface name of the interface
1002 * @return 0 on success, 1 on error
1003 **** similar with the one from gnunet-helper-transport-wlan.c ****
1006 test_bluetooth_interface (const char *iface)
1012 ret = snprintf (strbuf, sizeof (strbuf),
1013 "/sys/class/bluetooth/%s/subsystem",
1015 if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
1018 "Did not find 802.15.1 interface `%s'. Exiting.\n",
1026 * Test incoming packets mac for being our own.
1028 * @param taIeeeHeader buffer of the packet
1029 * @param dev the Hardware_Infos struct
1030 * @return 0 if mac belongs to us, 1 if mac is for another target
1032 **** same as the one from gnunet-helper-transport-wlan.c ****
1035 mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1036 const struct HardwareInfos *dev)
1038 static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
1040 if ( (0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
1041 (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)) )
1042 return 0; /* some drivers set no Macs, then assume it is all for us! */
1044 if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1045 return 1; /* not a GNUnet ad-hoc package */
1046 if ( (0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
1047 (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)) )
1048 return 0; /* for us, or broadcast */
1049 return 1; /* not for us */
1054 * Process data from the stdin. Takes the message forces the sender MAC to be correct
1055 * and puts it into our buffer for transmission to the kernel. (the other device).
1057 * @param cls pointer to the device struct ('struct HardwareInfos*')
1058 * @param hdr pointer to the start of the packet
1060 **** same as the one from gnunet-helper-transport-wlan.c ****
1063 stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1065 struct HardwareInfos *dev = cls;
1066 const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header;
1067 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *blueheader;
1070 sendsize = ntohs (hdr->size);
1072 sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
1073 (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) )
1075 fprintf (stderr, "Received malformed message\n");
1078 sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) -
1079 sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1080 if (MAXLINE < sendsize)
1082 fprintf (stderr, "Packet too big for buffer\n");
1085 header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
1086 memcpy (&write_pout.buf, &header->frame, sendsize);
1087 blueheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf;
1089 /* payload contains MAC address, but we don't trust it, so we'll
1090 * overwrite it with OUR MAC address to prevent mischief */
1091 mac_set (blueheader, dev);
1092 memcpy (&blueheader->addr1, &header->frame.addr1,
1093 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)); //FIXME is this correct?
1094 write_pout.size = sendsize;
1098 * Broadcast a HELLO message for peer discovery
1099 * @param dev pointer to the device struct
1100 * @param dev pointer to the socket which was added to the set
1101 * @return 0 on success
1104 send_broadcast (struct HardwareInfos *dev, int *sendsocket)
1110 if ((neighbours.size == neighbours.pos && new_device == 1) || neighbours.size == 0)
1112 inquiry_devices: //skip the conditions and force a inquiry for new devices
1115 * It means that I sent HELLO message to all the devices from the list so I should search
1116 * for another devices or that this is the first time when I do a search for devices.
1118 inquiry_info *devices = NULL;
1119 int i, responses, max_responses = MAX_PORTS;
1122 if (neighbours.size >= MAX_PORTS)
1124 fprintf (stderr, "%s reached the top limit for the discovarable devices\n", dev->iface);
1128 /* Get the device id */
1129 if (neighbours.dev_id == -1)
1131 char addr[19] = { 0 }; //the device MAC address
1133 ba2str ((bdaddr_t *) &dev->pl_mac, addr);
1134 neighbours.dev_id = hci_devid (addr);
1135 if (neighbours.dev_id < 0)
1137 fprintf (stderr, "Failed to get the device id for interface %s : %s\n",
1138 dev->iface, strerror (errno));
1143 devices = malloc (max_responses * sizeof (inquiry_info));
1144 if (devices == NULL)
1146 fprintf (stderr, "Failed to allocate memory for inquiry info list on interface %s\n",
1151 responses = hci_inquiry (neighbours.dev_id, 8, max_responses, NULL, &devices, IREQ_CACHE_FLUSH);
1154 fprintf (stderr, "Failed to inquiry on interface %s\n", dev->iface);
1158 fprintf (stderr, "Found %d devices\n", responses); //FIXME delete it after debugging stage
1162 fprintf (stderr, "No devices discoverable\n");
1166 for (i = 0; i < responses; i++)
1174 fprintf (stderr, "%s reached the top limit for the discoverable devices (after inquiry)\n", dev->iface);
1178 /* Search if the address already exists on the list */
1179 for (j = 0; j < neighbours.size; j++)
1181 if (memcmp (&(devices + i)->bdaddr, &(neighbours.devices[j]), sizeof (bdaddr_t)) == 0)
1184 fprintf (stderr, "the device already exists on the list\n"); //FIXME debugging message
1191 char addr[19] = { 0 };
1193 ba2str (&(devices +i)->bdaddr, addr);
1194 fprintf (stderr, "%s was added to the list\n", addr); //FIXME debugging message
1195 memcpy (&(neighbours.devices[neighbours.size++]), &(devices + i)->bdaddr, sizeof (bdaddr_t));
1203 int connection_successful = 0;
1204 struct sockaddr_rc addr_rc = { 0 };
1206 addr_rc.rc_family = AF_BLUETOOTH;
1208 /* Try to connect to a new device from the list */
1209 while (neighbours.pos < neighbours.size)
1211 /* Check if we are connected to this device */
1212 if (neighbours.fds[neighbours.pos] == -1)
1215 memset (&addr_rc.rc_bdaddr, 0, sizeof (addr_rc.rc_bdaddr));
1216 memcpy (&addr_rc.rc_bdaddr, &(neighbours.devices[neighbours.pos]), sizeof (addr_rc.rc_bdaddr));
1218 addr_rc.rc_channel = get_channel (dev, addr_rc.rc_bdaddr);
1220 *sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1222 if (connect (*sendsocket, (struct sockaddr *)&addr_rc, sizeof (addr_rc)) == 0)
1224 neighbours.fds[neighbours.pos++] = *sendsocket;
1225 connection_successful = 1;
1226 char addr[19] = { 0 };
1227 ba2str (&(neighbours.devices[neighbours.pos - 1]), addr);
1228 fprintf (stderr, "Connected to %s\n", addr);
1234 char addr[19] = { 0 };
1235 errno_copy = errno; //Save a copy for later
1236 ba2str (&(neighbours.devices[neighbours.pos]), addr);
1237 fprintf (stderr, "Couldn't connect on device %s, error : %s\n", addr, strerror(errno));
1238 if (errno != ECONNREFUSED) //FIXME nu merge!
1240 fprintf (stderr, "Removes %d device from the list\n", neighbours.pos);
1241 /* Remove the device from the list */
1242 memcpy (&neighbours.devices[neighbours.pos], &neighbours.devices[neighbours.size - 1], sizeof (bdaddr_t));
1243 memset (&neighbours.devices[neighbours.size - 1], 0, sizeof (bdaddr_t));
1244 neighbours.fds[neighbours.pos] = neighbours.fds[neighbours.size - 1];
1245 neighbours.fds[neighbours.size - 1] = -1;
1246 neighbours.size -= 1;
1249 neighbours.pos += 1;
1251 if (neighbours.pos >= neighbours.size)
1256 if (loops == MAX_LOOPS) //don't get stuck trying to connect to one device
1262 fprintf (stderr, "Search for a new device\n"); //FIXME debugging message
1263 neighbours.pos += 1;
1267 /* Cycle on the list */
1268 if (neighbours.pos == neighbours.size)
1271 searching_devices_count += 1;
1273 if (searching_devices_count == MAX_LOOPS)
1275 fprintf (stderr, "Force to inquiry for new devices\n");
1276 searching_devices_count = 0;
1277 goto inquiry_devices;
1280 /* If a new device wasn't found, search an old one */
1281 if (connection_successful == 0)
1283 int loop_check = neighbours.pos;
1284 while (neighbours.fds[neighbours.pos] == -1)
1286 if (neighbours.pos == neighbours.size)
1289 if (neighbours.pos == loop_check)
1291 if (errno_copy == ECONNREFUSED)
1293 fprintf (stderr, "No device found. Go back and search again\n"); //FIXME debugging message
1296 goto search_for_devices;
1300 return 1; // Skip the broadcast message
1304 neighbours.pos += 1;
1307 *sendsocket = neighbours.fds[neighbours.pos++];
1314 * Main function of the helper. This code accesses a bluetooth interface
1315 * forwards traffic in both directions between the bluetooth interface and
1316 * stdin/stdout of this process. Error messages are written to stdout.
1318 * @param argc number of arguments, must be 2
1319 * @param argv arguments only argument is the name of the interface (i.e. 'hci0')
1320 * @return 0 on success (never happens, as we don't return unless aborted), 1 on error
1322 **** same as the one from gnunet-helper-transport-wlan.c ****
1325 main (int argc, char *argv[])
1327 struct HardwareInfos dev;
1328 char readbuf[MAXLINE];
1333 struct MessageStreamTokenizer *stdin_mst;
1336 int crt_rfds = 0, rfds_list[MAX_PORTS];
1337 int broadcast, sendsocket;
1338 /* Assert privs so we can modify the firewall rules! */
1340 #ifdef HAVE_SETRESUID
1341 if (0 != setresuid (uid, 0, 0))
1343 fprintf (stderr, "Failed to setresuid to root: %s\n", strerror (errno));
1347 if (0 != seteuid (0))
1349 fprintf (stderr, "Failed to seteuid back to root: %s\n", strerror (errno));
1354 /* Make use of SGID capabilities on POSIX */
1355 memset (&dev, 0, sizeof (dev));
1356 dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1357 raw_eno = errno; /* remember for later */
1359 /* Now that we've dropped root rights, we can do error checking */
1362 fprintf (stderr, "You must specify the name of the interface as the first \
1363 and only argument to this program.\n");
1364 if (-1 != dev.fd_rfcomm)
1365 (void) close (dev.fd_rfcomm);
1369 if (-1 == dev.fd_rfcomm)
1371 fprintf (stderr, "Failed to create a HCI socket: %s\n", strerror (raw_eno));
1374 if (dev.fd_rfcomm >= FD_SETSIZE)
1376 fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1377 dev.fd_rfcomm, FD_SETSIZE);
1378 (void) close (dev.fd_rfcomm);
1381 if (0 != test_bluetooth_interface (argv[1]))
1383 (void) close (dev.fd_rfcomm);
1386 strncpy (dev.iface, argv[1], IFNAMSIZ);
1387 if (0 != open_device (&dev))
1389 (void) close (dev.fd_rfcomm);
1395 uid_t uid = getuid ();
1396 #ifdef HAVE_SETRESUID
1397 if (0 != setresuid (uid, uid, uid))
1399 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1400 if (-1 != dev.fd_rfcomm)
1401 (void) close (dev.fd_rfcomm);
1405 if (0 != (setuid (uid) | seteuid (uid)))
1407 fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
1408 if (-1 != dev.fd_rfcomm)
1409 (void) close (dev.fd_rfcomm);
1415 /* Send MAC address of the bluetooth interface to STDOUT first */
1417 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
1419 macmsg.hdr.size = htons (sizeof (macmsg));
1420 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
1421 memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1422 memcpy (write_std.buf, &macmsg, sizeof (macmsg));
1423 write_std.size = sizeof (macmsg);
1427 stdin_mst = mst_create (&stdin_send_hw, &dev);
1430 fprintf (stderr, "\n-----------------------------------------------\n Check if the program exits\n-----------------------------------------------\n");
1432 * TODO : When a connection fails I should ignore only the CONTROL messages.
1433 * For DATA messages I should retry to send the message until it doesn't fail
1434 * Also I should make the time out of a mac endpoint smaller and check if the rate
1435 * from get_wlan_header (plugin_transport_bluetooth.c) is correct.
1444 if ((0 == write_pout.size) && (1 == stdin_open))
1446 // fprintf (stderr, "LOG : %s adds STDIN to rfds\n", dev.iface); //FIXME: debugging message
1447 FD_SET (STDIN_FILENO, &rfds);
1448 maxfd = MAX (maxfd, STDIN_FILENO);
1450 if (0 == write_std.size)
1452 // fprintf (stderr, "LOG : %s adds fd_rfcomm to rfds\n", dev.iface); //FIXME: debugging message
1453 FD_SET (dev.fd_rfcomm, &rfds);
1454 maxfd = MAX (maxfd, dev.fd_rfcomm);
1457 for (i = 0; i < crt_rfds; i++) // it can receive messages from multiple devices
1459 // fprintf (stderr, "LOG : %s adds extra fds to rfds\n", dev.iface); //FIXME: debugging message
1460 FD_SET (rfds_list[i], &rfds);
1461 maxfd = MAX (maxfd, rfds_list[i]);
1464 if (0 < write_std.size)
1466 // fprintf (stderr, "LOG : %s adds STDOUT to wfds\n", dev.iface); //FIXME: debugging message
1467 FD_SET (STDOUT_FILENO, &wfds);
1468 maxfd = MAX (maxfd, STDOUT_FILENO);
1470 if (0 < write_pout.size) //it can send messages only to one device per loop
1472 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *frame;
1473 /* Get the destination address */
1474 //FIXME : not sure if this is correct
1475 frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) write_pout.buf;
1477 if (memcmp (&frame->addr1, &dev.pl_mac,
1478 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1480 fprintf (stderr, "LOG : %s has a message for him:)\n", dev.iface); //FIXME: debugging message
1481 memset (&write_pout, 0, sizeof (write_pout)); // clear the buffer
1483 else if (memcmp (&frame->addr1, &broadcast_address,
1484 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1486 fprintf (stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n", dev.iface, neighbours.pos, neighbours.size); //FIXME: debugging message
1487 // broadcast = 1; // IF I HAVE A BROADCAST MESSAGE I skip.
1488 // memset (&write_pout, 0, sizeof (write_pout));
1490 if (send_broadcast(&dev, &sendsocket) != 0) //if the searching wasn't successful don't get stuck on the select stage
1493 memset (&write_pout, 0, sizeof (write_pout)); //remove the message
1494 fprintf (stderr, "Skip the broadcast message (pos %d, size %d)\n", neighbours.pos, neighbours.size);
1498 FD_SET (sendsocket, &wfds);
1499 maxfd = MAX (maxfd, sendsocket);
1505 /* Search if the address already exists on the list */
1506 for (i = 0; i < neighbours.size; i++)
1508 if (memcmp (&frame->addr1, &(neighbours.devices[i]), sizeof (bdaddr_t)) == 0 && neighbours.fds[i] != -1)
1511 FD_SET (neighbours.fds[i], &wfds);
1512 maxfd = MAX (maxfd, neighbours.fds[i]);
1513 sendsocket = neighbours.fds[i];
1514 fprintf (stderr, "LOG: the address was found in the list\n");
1521 struct sockaddr_rc addr = { 0 };
1523 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,
1524 frame->addr1.mac[5], frame->addr1.mac[4], frame->addr1.mac[3],
1525 frame->addr1.mac[2], frame->addr1.mac[1], frame->addr1.mac[0]); //FIXME: debugging message
1527 sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1531 fprintf (stderr, "Failed to create a RFCOMM socket (sending stage): %s\n",
1536 memcpy (&addr.rc_bdaddr, &frame->addr1, sizeof (bdaddr_t));
1537 addr.rc_family = AF_BLUETOOTH;
1538 addr.rc_channel = get_channel (&dev, addr.rc_bdaddr);
1541 *TODO: use a NON-BLOCKING socket
1542 * sock_flags = fcntl (sendsocket, F_GETFL, 0);
1543 * fcntl( sendsocket, F_SETFL, sock_flags | O_NONBLOCK);
1547 status = connect (sendsocket, (struct sockaddr *) &addr, sizeof (addr));
1548 if (0 != status && errno != EAGAIN)
1550 if (errno == ECONNREFUSED && tries < 2)
1552 fprintf (stderr, "%s failed to connect. Trying again!\n", dev.iface);
1556 else if (errno == EBADF)
1558 fprintf (stderr, "%s failed to connect : %s. Skip it!\n", dev.iface, strerror (errno));
1559 memset (&write_pout, 0, sizeof (write_pout));
1564 fprintf (stderr, "%s failed to connect : %s. Try again later!\n", dev.iface, strerror (errno));
1565 memset (&write_pout, 0, sizeof (write_pout));
1572 FD_SET (sendsocket, &wfds);
1573 maxfd = MAX (maxfd, sendsocket);
1574 fprintf (stderr, "Connection successful\n");
1575 /* Add the new device to the discovered devices list */
1576 if (neighbours.size < MAX_PORTS)
1578 neighbours.fds[neighbours.size] = sendsocket;
1579 memcpy (&(neighbours.devices[neighbours.size++]), &addr.rc_bdaddr, sizeof (bdaddr_t));
1583 fprintf (stderr, "The top limit for the discovarable devices' list was reached\n");
1592 /* Select a fd which is ready for action :) */
1594 int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL); //FIXME : when a device close the connection remove the socket from the list
1595 if ((-1 == retval) && (EINTR == errno))
1597 if (0 > retval && errno != EBADF) // we handle BADF errors later
1599 fprintf (stderr, "select failed: %s\n", strerror (errno));
1603 if (FD_ISSET (STDOUT_FILENO , &wfds))
1606 write (STDOUT_FILENO, write_std.buf + write_std.pos,
1607 write_std.size - write_std.pos);
1610 fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1613 write_std.pos += ret;
1614 if (write_std.pos == write_std.size)
1619 fprintf (stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); //FIXME: debugging message
1622 if (sendsocket != -1)
1624 if (FD_ISSET (sendsocket , &wfds))
1627 write (sendsocket, write_pout.buf + write_std.pos,
1628 write_pout.size - write_pout.pos);
1629 if (0 > ret) //FIXME should I check first the error type?
1631 fprintf (stderr, "Failed to write to bluetooth device: %s. Closing the socket!\n",
1634 for (i = 0; i < neighbours.size; i++)
1636 if (neighbours.fds[i] == sendsocket)
1638 (void) close(sendsocket);
1639 neighbours.fds[i] = -1;
1643 //memset (&(write_pout.buf + write_std.pos), 0, (write_pout.size - write_pout.pos)) // FIXME should I remove the message? or try to resend it
1644 //write_pour.pos = 0 ; write_pout.size = 0;
1648 write_pout.pos += ret;
1649 if ((write_pout.pos != write_pout.size) && (0 != ret))
1651 /* we should not get partial sends with packet-oriented devices... */
1652 fprintf (stderr, "Write error, partial send: %u/%u\n",
1653 (unsigned int) write_pout.pos,
1654 (unsigned int) write_pout.size);
1658 if (write_pout.pos == write_pout.size)
1661 write_pout.size = 0;
1663 fprintf (stderr, "LOG : %s sends a message to a DEVICE\n", dev.iface); //FIXME: debugging message
1667 for (i = 0; i <= maxfd; i++) //FIXME it should be incremented
1669 if (FD_ISSET (i, &rfds))
1671 if (i == STDIN_FILENO)
1674 read (i, readbuf, sizeof (readbuf));
1677 fprintf (stderr, "Read error from STDIN: %s\n", strerror (errno));
1682 /* stop reading... */
1687 mst_receive (stdin_mst, readbuf, ret);
1688 fprintf (stderr, "LOG : %s receives a message from STDIN\n", dev.iface); //FIXME: debugging message
1691 else if (i == dev.fd_rfcomm)
1694 struct sockaddr_rc addr = { 0 };
1695 unsigned int opt = sizeof (addr);
1697 readsocket = accept (dev.fd_rfcomm, (struct sockaddr *) &addr, &opt);
1698 fprintf(stderr, "LOG : %s accepts a message\n", dev.iface); //FIXME: debugging message
1699 if (readsocket == -1)
1701 fprintf (stderr, "Failed to accept a connection on interface: %s\n",
1703 return -1; //FIXME probably I should ignore the error and keep the process alive
1707 FD_SET (readsocket, &rfds);
1708 maxfd = MAX (maxfd, readsocket);
1710 if (crt_rfds < MAX_PORTS)
1711 rfds_list[crt_rfds++] = readsocket;
1714 fprintf (stderr, "The limit for the read file descriptors list was \
1723 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
1725 fprintf (stderr, "LOG : %s reads something from the socket\n", dev.iface);//FIXME : debugging message
1726 rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
1728 read_from_the_socket (i, (unsigned char *) &rrm->frame,
1729 sizeof (write_std.buf)
1730 - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
1731 + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
1738 /* Remove the socket from the list */
1739 for (j = 0; j < crt_rfds; j++)
1741 if (rfds_list[j] == i)
1743 rfds_list[j] ^= rfds_list[crt_rfds - 1];
1744 rfds_list[crt_rfds - 1] ^= rfds_list[j];
1745 rfds_list[j] ^= rfds_list[crt_rfds - 1];
1751 fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
1754 if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
1756 write_std.size = ret
1757 + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
1758 - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
1759 rrm->header.size = htons (write_std.size);
1760 rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
1762 /* Remove the socket from the list */
1764 for (j = 0; j < crt_rfds; j++)
1766 if (i == rfds_list[crt_rfds])
1768 rfds_list[j] ^= rfds_list[crt_rfds];
1769 rfds_list[crt_rfds] ^= rfds_list[j];
1770 rfds_list[j] ^= rfds_list[crt_rfds];
1781 /* Error handling, try to clean up a bit at least */
1782 mst_destroy (stdin_mst);
1784 sdp_close (dev.session);
1785 (void) close (dev.fd_rfcomm);
1786 (void) close (sendsocket);
1788 for (i = 0; i < crt_rfds; i++)
1789 (void) close (rfds_list[i]);
1791 for (i = 0; i < neighbours.size; i++)
1792 (void) close (neighbours.fds[i]);
1794 return 1; /* we never exit 'normally' */