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"
23 #include "plugin_transport_wlan.h"
24 #include "gnunet_protocols.h"
28 #include "gnunet_util_lib.h"
31 #include "gnunet_protocols.h"
33 #include <bluetooth/bluetooth.h>
34 #include <bluetooth/hci.h>
35 #include <bluetooth/hci_lib.h>
36 #include <bluetooth/rfcomm.h>
37 #include <bluetooth/sdp.h>
38 #include <bluetooth/sdp_lib.h>
43 #include <sys/ioctl.h>
44 #include <sys/param.h>
45 #include <sys/socket.h>
47 #include <sys/types.h>
54 * Maximum number of ports assignable for RFCOMMM protocol.
59 * Maximum size of a message allowed in either direction
60 * (used for our receive and sent buffers).
66 * Maximum number of loops without inquiring for new devices.
71 /* Maximum size of the interface's name */
78 * A copy of the MAC Address.
80 struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy
82 UINT8 mac[MAC_ADDR_SIZE];
86 * The UUID used for the SDP service.
87 * {31191E56-FA7E-4517-870E-71B86BBCC52F}
89 #define GNUNET_BLUETOOTH_SDP_UUID \
91 0x31, 0x19, 0x1E, 0x56, \
95 0x71, 0xB8, 0x6B, 0xBC, 0xC5, 0x2F \
100 * struct for storing the information of the hardware. There is only
106 * Name of the interface, not necessarily 0-terminated (!).
108 char iface[IFNAMSIZ];
114 struct GNUNET_NETWORK_Handle *handle;
117 * MAC address of our own bluetooth interface.
119 struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy pl_mac;
122 * file descriptor for the rfcomm socket
127 * MAC address of our own bluetooth interface.
129 struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac;
134 sdp_session_t *session ;
139 * IO buffer used for buffering data in transit (to wireless or to stdout).
144 * How many bytes of data are stored in 'buf' for transmission right now?
145 * Data always starts at offset 0 and extends to 'size'.
150 * How many bytes that were stored in 'buf' did we already write to the
151 * destination? Always smaller than 'size'.
156 * Buffered data; twice the maximum allowed message size as we add some
159 char buf[MAXLINE * 2];
164 * Devices buffer used to keep a list with all the discoverable devices in
165 * order to send them HELLO messages one by one when it receive a broadcast message.
167 struct BroadcastMessages
169 /* List with the discoverable devices' addresses */
170 bdaddr_t devices[MAX_PORTS];
172 /* List with the open sockets */
176 /* The number of the devices */
179 /* The current position */
187 * Address used to identify the broadcast messages.
189 static struct GNUNET_TRANSPORT_WLAN_MacAddress broadcast_address = {{255, 255, 255, 255, 255, 255}};
192 * Buffer with the discoverable devices.
194 static struct BroadcastMessages neighbours;
196 static int searching_devices_count = 0;
200 * Buffer for data read from stdin to be transmitted to the bluetooth device
202 static struct SendBuffer write_pout;
205 * Buffer for data read from the bluetooth device to be transmitted to stdout.
207 static struct SendBuffer write_std;
210 /* ****** this are the same functions as the ones used in gnunet-helper-transport-wlan.c ****** */
213 * To what multiple do we align messages? 8 byte should suffice for everyone
216 #define ALIGN_FACTOR 8
219 * Smallest supported message.
221 #define MIN_BUFFER_SIZE sizeof (struct GNUNET_MessageHeader)
225 * Functions with this signature are called whenever a
226 * complete message is received by the tokenizer.
229 * @param message the actual message
231 typedef void (*MessageTokenizerCallback) (void *cls,
233 GNUNET_MessageHeader *
237 * Handle to a message stream tokenizer.
239 struct MessageStreamTokenizer
243 * Function to call on completed messages.
245 MessageTokenizerCallback cb;
253 * Size of the buffer (starting at 'hdr').
258 * How many bytes in buffer have we already processed?
263 * How many bytes in buffer are valid right now?
268 * Beginning of the buffer. Typed like this to force alignment.
270 struct GNUNET_MessageHeader *hdr;
276 * Create a message stream tokenizer.
278 * @param cb function to call on completed messages
279 * @param cb_cls closure for cb
280 * @return handle to tokenizer
282 static struct MessageStreamTokenizer *
283 mst_create (MessageTokenizerCallback cb,
286 struct MessageStreamTokenizer *ret;
288 ret = malloc (sizeof (struct MessageStreamTokenizer));
291 fprintf (stderr, "Failed to allocate buffer for tokenizer\n");
294 ret->hdr = malloc (MIN_BUFFER_SIZE);
295 if (NULL == ret->hdr)
297 fprintf (stderr, "Failed to allocate buffer for alignment\n");
300 ret->curr_buf = MIN_BUFFER_SIZE;
302 ret->cb_cls = cb_cls;
310 * Add incoming data to the receive buffer and call the
311 * callback for all complete messages.
313 * @param mst tokenizer to use
314 * @param buf input data to add
315 * @param size number of bytes in buf
316 * @return GNUNET_OK if we are done processing (need more data)
317 * GNUNET_SYSERR if the data stream is corrupt
320 mst_receive (struct MessageStreamTokenizer *mst,
321 const char *buf, size_t size)
323 const struct GNUNET_MessageHeader *hdr;
328 unsigned long offset;
332 ibuf = (char *) mst->hdr;
336 if (mst->pos < mst->off)
338 //fprintf (stderr, "We processed too many bytes!\n");
339 return GNUNET_SYSERR;
341 if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) ||
342 (0 != (mst->off % ALIGN_FACTOR)))
344 /* need to align or need more space */
345 mst->pos -= mst->off;
346 memmove (ibuf, &ibuf[mst->off], mst->pos);
349 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
352 GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) -
353 (mst->pos - mst->off), size);
354 memcpy (&ibuf[mst->pos], buf, delta);
359 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
361 //FIXME should I reset ??
366 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
367 want = ntohs (hdr->size);
368 if (want < sizeof (struct GNUNET_MessageHeader))
371 "Received invalid message from stdin\n");
372 return GNUNET_SYSERR;
374 if ((mst->curr_buf - mst->off < want) &&
377 /* need more space */
378 mst->pos -= mst->off;
379 memmove (ibuf, &ibuf[mst->off], mst->pos);
382 if (want > mst->curr_buf)
386 fprintf (stderr, "Error! We should proceeded 0 bytes\n");
387 return GNUNET_SYSERR;
389 mst->hdr = realloc (mst->hdr, want);
390 if (NULL == mst->hdr)
392 fprintf (stderr, "Failed to allocate buffer for alignment\n");
395 ibuf = (char *) mst->hdr;
396 mst->curr_buf = want;
398 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
399 if (mst->pos - mst->off < want)
401 delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
402 if (mst->pos + delta > mst->curr_buf)
404 fprintf (stderr, "The size of the buffer will be exceeded!\n");
405 return GNUNET_SYSERR;
407 memcpy (&ibuf[mst->pos], buf, delta);
412 if (mst->pos - mst->off < want)
414 //FIXME should I use this?
419 mst->cb (mst->cb_cls, hdr);
421 if (mst->off == mst->pos)
423 /* reset to beginning of buffer, it's free right now! */
430 fprintf (stderr, "There should some valid bytes in the buffer on this stage\n");
431 return GNUNET_SYSERR;
435 if (size < sizeof (struct GNUNET_MessageHeader))
437 offset = (unsigned long) buf;
438 need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
439 if (GNUNET_NO == need_align)
441 /* can try to do zero-copy and process directly from original buffer */
442 hdr = (const struct GNUNET_MessageHeader *) buf;
443 want = ntohs (hdr->size);
444 if (want < sizeof (struct GNUNET_MessageHeader))
447 "Received invalid message from stdin\n");
450 return GNUNET_SYSERR;
453 break; /* or not, buffer incomplete, so copy to private buffer... */
454 mst->cb (mst->cb_cls, hdr);
460 /* need to copy to private buffer to align;
461 * yes, we go a bit more spagetti than usual here */
467 if (size + mst->pos > mst->curr_buf)
469 mst->hdr = realloc (mst->hdr, size + mst->pos);
470 if (NULL == mst->hdr)
472 fprintf (stderr, "Failed to allocate buffer for alignment\n");
475 ibuf = (char *) mst->hdr;
476 mst->curr_buf = size + mst->pos;
478 if (mst->pos + size > mst->curr_buf)
481 "Assertion failed\n");
484 memcpy (&ibuf[mst->pos], buf, size);
491 * Destroys a tokenizer.
493 * @param mst tokenizer to destroy
496 mst_destroy (struct MessageStreamTokenizer *mst)
503 * Calculate crc32, the start of the calculation
505 * @param buf buffer to calc the crc
506 * @param len len of the buffer
510 calc_crc_osdep (const unsigned char *buf, size_t len)
512 static const unsigned long int crc_tbl_osdep[256] = {
513 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
514 0xE963A535, 0x9E6495A3,
515 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
516 0xE7B82D07, 0x90BF1D91,
517 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
518 0xF4D4B551, 0x83D385C7,
519 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
520 0xFA0F3D63, 0x8D080DF5,
521 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
522 0xD20D85FD, 0xA50AB56B,
523 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
524 0xDCD60DCF, 0xABD13D59,
525 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
526 0xCFBA9599, 0xB8BDA50F,
527 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
528 0xC1611DAB, 0xB6662D3D,
529 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
530 0x9FBFE4A5, 0xE8B8D433,
531 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
532 0x91646C97, 0xE6635C01,
533 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
534 0x8208F4C1, 0xF50FC457,
535 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
536 0x8CD37CF3, 0xFBD44C65,
537 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
538 0xA4D1C46D, 0xD3D6F4FB,
539 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
540 0xAA0A4C5F, 0xDD0D7CC9,
541 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
542 0xB966D409, 0xCE61E49F,
543 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
544 0xB7BD5C3B, 0xC0BA6CAD,
545 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
546 0x04DB2615, 0x73DC1683,
547 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
548 0x0A00AE27, 0x7D079EB1,
549 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
550 0x196C3671, 0x6E6B06E7,
551 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
552 0x17B7BE43, 0x60B08ED5,
553 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
554 0x3FB506DD, 0x48B2364B,
555 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
556 0x316E8EEF, 0x4669BE79,
557 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
558 0x220216B9, 0x5505262F,
559 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
560 0x2CD99E8B, 0x5BDEAE1D,
561 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
562 0x72076785, 0x05005713,
563 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
564 0x7CDCEFB7, 0x0BDBDF21,
565 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
566 0x6FB077E1, 0x18B74777,
567 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
568 0x616BFFD3, 0x166CCF45,
569 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
570 0x4969474D, 0x3E6E77DB,
571 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
572 0x47B2CF7F, 0x30B5FFE9,
573 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
574 0x54DE5729, 0x23D967BF,
575 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
576 0x5A05DF1B, 0x2D02EF8D
579 unsigned long crc = 0xFFFFFFFF;
581 for (; len > 0; len--, buf++)
582 crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
588 * Calculate and check crc of the bluetooth packet
590 * @param buf buffer of the packet, with len + 4 bytes of data,
591 * the last 4 bytes being the checksum
592 * @param len length of the payload in data
593 * @return 0 on success (checksum matches), 1 on error
596 check_crc_buf_osdep (const unsigned char *buf, size_t len)
600 crc = calc_crc_osdep (buf, len);
602 if (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
603 ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3])
610 /* ************** end of clone ***************** */
614 * Function used to get the code of last error and to print the type of error.
619 LPVOID lpMsgBuf = NULL;
621 if (FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
622 NULL, GetLastError(), 0, (LPTSTR) &lpMsgBuf, 0, NULL))
623 fprintf (stderr, "%s\n", (char *)lpMsgBuf);
625 fprintf (stderr, "Failed to format the message for the last error! Error number : %d\n", GetLastError());
629 * Function used to initialize the Windows Sockets
632 initialize_windows_sockets()
635 WORD wVersionRequested = MAKEWORD (2, 0);
636 if (WSAStartup (wVersionRequested, &wsaData) != NO_ERROR)
638 fprintf (stderr , "Error initializing window sockets!\n");
645 * Function used to convert the GUID.
646 * @param bytes the GUID represented as a char array
647 * @param uuid pointer to the GUID
650 convert_guid(char *bytes, GUID * uuid)
653 uuid->Data1 = ((bytes[0] << 24) & 0xff000000) | ((bytes[1] << 16) & 0x00ff0000) | ((bytes[2] << 8) & 0x0000ff00) | (bytes[3] & 0x000000ff);
654 uuid->Data2 = ((bytes[4] << 8) & 0xff00) | (bytes[5] & 0x00ff);
655 uuid->Data3 = ((bytes[6] << 8) & 0xff00) | (bytes[7] & 0x00ff);
657 for (i = 0; i < 8; i++)
659 uuid->Data4[i] = bytes[i + 8];
666 * Function for assigning a port number
668 * @param socket the socket used to bind
669 * @param addr pointer to the rfcomm address
670 * @return 0 on success
673 bind_socket (int socket, struct sockaddr_rc *addr)
677 /* Bind every possible port (from 0 to 30) and stop when binding doesn't fail */
678 //FIXME : it should start from port 1, but on my computer it doesn't work :)
679 for (port = 3; port <= 30; port++)
681 addr->rc_channel = port;
682 status = bind (socket, (struct sockaddr *) addr, sizeof (struct sockaddr_rc));
693 * Function used for creating the service record and registering it.
695 * @param dev pointer to the device struct
696 * @return 0 on success
699 register_service (struct HardwareInfos *dev)
701 /* advertise the service */
702 CSADDR_INFO addr_info;
705 unsigned char uuid[] = GNUNET_BLUETOOTH_SDP_UUID;
707 int addr_len = sizeof (SOCKADDR_BTH);
709 /* get the port on which we are listening on */
710 memset (& addr, 0, sizeof (SOCKADDR_BTH));
711 fd = GNUNET_NETWORK_get_fd (dev->handle);
714 fprintf (stderr, "Failed to get the file descriptor\n");
717 if (SOCKET_ERROR == getsockname (fd, (SOCKADDR*)&addr, &addr_len))
719 fprintf (stderr, "Failed to get the port on which we are listening on: \n");
724 /* save the device address */
725 memcpy (&dev->pl_mac, &addr.btAddr, sizeof (BTH_ADDR));
727 /* set the address information */
728 memset (&addr_info, 0, sizeof (CSADDR_INFO));
729 addr_info.iProtocol = BTHPROTO_RFCOMM;
730 addr_info.iSocketType = SOCK_STREAM;
731 addr_info.LocalAddr.lpSockaddr = (LPSOCKADDR)&addr;
732 addr_info.LocalAddr.iSockaddrLength = sizeof (addr);
733 addr_info.RemoteAddr.lpSockaddr = (LPSOCKADDR)&addr;
734 addr_info.RemoteAddr.iSockaddrLength = sizeof (addr);
736 convert_guid((char *) uuid, &guid);
738 /* register the service */
739 memset (&wqs, 0, sizeof (WSAQUERYSET));
740 wqs.dwSize = sizeof (WSAQUERYSET);
741 wqs.dwNameSpace = NS_BTH;
742 wqs.lpszServiceInstanceName = "GNUnet Bluetooth Service";
743 wqs.lpszComment = "This is the service used by the GNUnnet plugin transport";
744 wqs.lpServiceClassId = &guid;
745 wqs.dwNumberOfCsAddrs = 1;
746 wqs.lpcsaBuffer = &addr_info ;
749 if (SOCKET_ERROR == WSASetService (&wqs , RNRSERVICE_REGISTER, 0))
751 fprintf (stderr, "Failed to register the SDP service: ");
757 fprintf (stderr, "The SDP service was registered\n");
764 * Function used for creating the service record and registering it.
766 * @param dev pointer to the device struct
767 * @param rc_channel the rfcomm channel
768 * @return 0 on success
771 register_service (struct HardwareInfos *dev, int rc_channel)
775 * 2. set the service ID, class, profile information
776 * 3. make the service record publicly browsable
777 * 4. register the RFCOMM channel
778 * 5. set the name, provider and description
779 * 6. register the service record to the local SDP server
782 uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
783 dev->pl_mac.mac[5], dev->pl_mac.mac[4], dev->pl_mac.mac[3],
784 dev->pl_mac.mac[2], dev->pl_mac.mac[1], dev->pl_mac.mac[0]};
785 const char *service_dsc = "Bluetooth plugin services";
786 const char *service_prov = "GNUnet provider";
787 uuid_t root_uuid, rfcomm_uuid, svc_uuid;
788 sdp_list_t *root_list = 0, *rfcomm_list = 0, *proto_list = 0,
789 *access_proto_list = 0, *svc_list = 0;
790 sdp_record_t *record = 0;
791 sdp_data_t *channel = 0;
793 record = sdp_record_alloc();
795 /* Set the general service ID */
796 sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
797 svc_list = sdp_list_append (0, &svc_uuid);
798 sdp_set_service_classes (record, svc_list);
799 sdp_set_service_id (record, svc_uuid);
801 /* Make the service record publicly browsable */
802 sdp_uuid16_create (&root_uuid, PUBLIC_BROWSE_GROUP);
803 root_list = sdp_list_append (0, &root_uuid);
804 sdp_set_browse_groups (record, root_list);
806 /* Register the RFCOMM channel */
807 sdp_uuid16_create (&rfcomm_uuid, RFCOMM_UUID);
808 channel = sdp_data_alloc (SDP_UINT8, &rc_channel);
809 rfcomm_list = sdp_list_append (0, &rfcomm_uuid);
810 sdp_list_append (rfcomm_list, channel);
811 proto_list = sdp_list_append (0, rfcomm_list);
813 /* Set protocol information */
814 access_proto_list = sdp_list_append (0, proto_list);
815 sdp_set_access_protos (record, access_proto_list);
817 /* Set the name, provider, and description */
818 sdp_set_info_attr (record, dev->iface, service_prov, service_dsc);
820 /* Connect to the local SDP server */
821 dev->session = sdp_connect (BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
825 fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
826 IFNAMSIZ, dev->iface, strerror (errno));
831 /* Register the service record */
832 if (sdp_record_register (dev->session, record, 0) < 0)
834 fprintf (stderr, "Failed to register a service record on interface `%.*s': %s\n",
835 IFNAMSIZ, dev->iface, strerror (errno));
841 sdp_data_free (channel);
842 sdp_list_free (root_list, 0);
843 sdp_list_free (rfcomm_list, 0);
844 sdp_list_free (proto_list, 0);
845 sdp_list_free (access_proto_list, 0);
846 sdp_list_free (svc_list, 0);
847 sdp_record_free (record);
855 * Function for searching and browsing for a service. This will return the
856 * port number on which the service is running.
858 * @param dest target address
862 get_channel(const char *dest)
866 DWORD wqs_len = sizeof (WSAQUERYSET);
870 unsigned char uuid[] = GNUNET_BLUETOOTH_SDP_UUID;
871 convert_guid ((char *) uuid, &guid);
873 wqs = (WSAQUERYSET*)malloc (wqs_len);
874 ZeroMemory (wqs, wqs_len);
876 wqs->dwSize = sizeof (WSAQUERYSET) ;
877 wqs->lpServiceClassId = &guid;
878 wqs->dwNameSpace = NS_BTH;
879 wqs->dwNumberOfCsAddrs = 0;
880 wqs->lpszContext = (LPSTR)dest;
882 if (SOCKET_ERROR == WSALookupServiceBegin (wqs, LUP_FLUSHCACHE | LUP_RETURN_ALL, &h))
884 if (GetLastError() == WSASERVICE_NOT_FOUND)
886 fprintf (stderr, "WARNING! The device with address %s wasn't found. Skipping the message!", dest);
891 fprintf (stderr, "Failed to find the port number: ");
898 /* search the sdp service */
901 if (SOCKET_ERROR == WSALookupServiceNext (h, LUP_FLUSHCACHE | LUP_RETURN_ALL, &wqs_len, wqs))
903 int error = WSAGetLastError();
909 wqs = (WSAQUERYSET*)malloc (wqs_len);
912 fprintf (stderr, "Failed! The address was valid but there was no data record of requested type\n");
919 fprintf (stderr, "Failed to look over the services: ");
921 WSALookupServiceEnd (h);
927 channel = ((SOCKADDR_BTH*)wqs->lpcsaBuffer->RemoteAddr.lpSockaddr)->port;
932 WSALookupServiceEnd (h);
938 * Function used for searching and browsing for a service. This will return the
939 * port number on which the service is running.
941 * @param dev pointer to the device struct
942 * @param dest target address
946 get_channel(struct HardwareInfos *dev, bdaddr_t dest)
949 * 1. detect all nearby devices
950 * 2. for each device:
951 * 2.1. connect to the SDP server running
952 * 2.2. get a list of service records with the specific UUID
953 * 2.3. for each service record get a list of the protocol sequences and get
956 uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
957 dest.b[5], dest.b[4], dest.b[3],
958 dest.b[2], dest.b[1], dest.b[0]};
959 sdp_session_t *session = 0;
960 sdp_list_t *search_list = 0, *attrid_list = 0, *response_list = 0, *it = 0;
962 uint32_t range = 0x0000ffff;
963 uint8_t channel = -1;
965 /* Connect to the local SDP server */
966 session = sdp_connect (BDADDR_ANY, &dest, 0);
969 fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
970 IFNAMSIZ, dev->iface, strerror (errno));
974 sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
975 search_list = sdp_list_append (0, &svc_uuid);
976 attrid_list = sdp_list_append (0, &range);
978 if (sdp_service_search_attr_req (session, search_list,
979 SDP_ATTR_REQ_RANGE, attrid_list, &response_list) == 0)
981 for (it = response_list; it; it = it->next)
983 sdp_record_t *record = (sdp_record_t*) it->data;
984 sdp_list_t *proto_list = 0;
985 if (sdp_get_access_protos (record, &proto_list) == 0)
987 channel = sdp_get_proto_port (proto_list, RFCOMM_UUID);
988 sdp_list_free (proto_list, 0);
990 sdp_record_free (record);
994 sdp_list_free (search_list, 0);
995 sdp_list_free (attrid_list, 0);
996 sdp_list_free (response_list, 0);
1001 fprintf (stderr, "Failed to find the listening channel for interface `%.*s': %s\n",
1002 IFNAMSIZ, dev->iface, strerror (errno));
1009 * Read from the socket and put the result into the buffer for transmission to 'stdout'.
1011 * @param sock file descriptor for reading
1012 * @param buf buffer to read to; first bytes will be the 'struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame',
1013 * followed by the actual payload
1014 * @param buf_size size of the buffer
1015 * @param ri where to write radiotap_rx info
1016 * @return number of bytes written to 'buf'
1019 read_from_the_socket (void *sock,
1020 unsigned char *buf, size_t buf_size,
1021 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri)
1023 unsigned char tmpbuf[buf_size];
1027 count = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)sock, tmpbuf, buf_size);
1029 count = read (*((int *)sock), tmpbuf, buf_size);
1034 if (EAGAIN == errno)
1039 fprintf (stderr, "Failed to read from the HCI socket: %s\n", strerror (errno));
1046 /* Get the channel used */
1048 struct sockaddr_rc rc_addr = { 0 };
1050 memset (&rc_addr, 0, sizeof (rc_addr));
1051 len = sizeof (rc_addr);
1052 if (0 > getsockname (*((int *)sock), (struct sockaddr *) &rc_addr, (socklen_t *) &len))
1054 fprintf (stderr, "getsockname() call failed : %s\n", strerror (errno));
1058 memset (ri, 0, sizeof (*ri));
1059 ri->ri_channel = rc_addr.rc_channel;
1062 /* Detect CRC32 at the end */
1063 if (0 == check_crc_buf_osdep (tmpbuf, count - sizeof (uint32_t)))
1065 count -= sizeof(uint32_t);
1068 memcpy (buf, tmpbuf, count);
1074 * Open the bluetooth interface for reading/writing
1076 * @param dev pointer to the device struct
1077 * @return 0 on success
1080 open_device (struct HardwareInfos *dev)
1085 /* bind the RFCOMM socket to the interface */
1086 addr.addressFamily = AF_BTH;
1088 addr.port = BT_PORT_ANY;
1090 if (GNUNET_NETWORK_socket_bind (dev->handle, (const SOCKADDR*)&addr, sizeof (SOCKADDR_BTH), 0) != GNUNET_OK)
1092 fprintf (stderr, "Failed to bind the socket: ");
1093 if (GetLastError() == WSAENETDOWN)
1095 fprintf (stderr, "Please make sure that your Bluetooth device is ON!\n");
1102 /* start listening on the socket */
1103 if (GNUNET_NETWORK_socket_listen (dev->handle, 4) != GNUNET_OK)
1105 fprintf (stderr, "Failed to listen on the socket: ");
1110 /* register the sdp service */
1111 if (register_service(dev) != 0)
1113 fprintf (stderr, "Failed to register a service: ");
1118 int i, dev_id = -1, fd_hci;
1121 struct hci_dev_list_req list;
1122 struct hci_dev_req dev[HCI_MAX_DEV];
1123 } request; //used for detecting the local devices
1124 struct sockaddr_rc rc_addr = { 0 }; //used for binding
1126 /* Initialize the neighbour structure */
1127 neighbours.dev_id = -1;
1128 for (i = 0; i < MAX_PORTS; i++)
1129 neighbours.fds[i] = -1;
1131 /* Open a HCI socket */
1132 fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
1136 fprintf (stderr, "Failed to create HCI socket: %s\n", strerror (errno));
1140 memset (&request, 0, sizeof(request));
1141 request.list.dev_num = HCI_MAX_DEV;
1143 if (ioctl (fd_hci, HCIGETDEVLIST, (void *) &request) < 0)
1145 fprintf (stderr, "ioctl(HCIGETDEVLIST) on interface `%.*s' failed: %s\n",
1146 IFNAMSIZ, dev->iface, strerror (errno));
1150 /* Search for a device with dev->iface name */
1151 for (i = 0; i < request.list.dev_num; i++)
1153 struct hci_dev_info dev_info;
1155 memset (&dev_info, 0, sizeof(struct hci_dev_info));
1156 dev_info.dev_id = request.dev[i].dev_id;
1157 strncpy (dev_info.name, dev->iface, IFNAMSIZ);
1159 if (ioctl (fd_hci, HCIGETDEVINFO, (void *) &dev_info))
1161 fprintf (stderr, "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n",
1162 IFNAMSIZ, dev->iface, strerror (errno));
1166 if (strcmp (dev_info.name, dev->iface) == 0)
1169 dev_id = dev_info.dev_id; //the device was found
1171 * Copy the MAC address to the device structure
1173 memcpy (&dev->pl_mac, &dev_info.bdaddr, sizeof (bdaddr_t));
1175 /* Check if the interface is up */
1176 if (hci_test_bit (HCI_UP, (void *) &dev_info.flags) == 0)
1178 /* Bring the interface up */
1179 if (ioctl (fd_hci, HCIDEVUP, dev_info.dev_id))
1181 fprintf (stderr, "ioctl(HCIDEVUP) on interface `%.*s' failed: %s\n",
1182 IFNAMSIZ, dev->iface, strerror (errno));
1187 /* Check if the device is discoverable */
1188 if (hci_test_bit (HCI_PSCAN, (void *) &dev_info.flags) == 0 ||
1189 hci_test_bit (HCI_ISCAN, (void *) &dev_info.flags) == 0)
1191 /* Set interface Page Scan and Inqury Scan ON */
1192 struct hci_dev_req dev_req;
1194 memset (&dev_req, 0, sizeof (dev_req));
1195 dev_req.dev_id = dev_info.dev_id;
1196 dev_req.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
1198 if (ioctl (fd_hci, HCISETSCAN, (unsigned long) &dev_req))
1200 fprintf (stderr, "ioctl(HCISETSCAN) on interface `%.*s' failed: %s\n",
1201 IFNAMSIZ, dev->iface, strerror (errno));
1211 /* Check if the interface was not found */
1214 fprintf (stderr, "The interface %s was not found\n", dev->iface);
1218 /* Close the hci socket */
1219 (void) close(fd_hci);
1223 /* Bind the rfcomm socket to the interface */
1224 memset (&rc_addr, 0, sizeof (rc_addr));
1225 rc_addr.rc_family = AF_BLUETOOTH;
1226 rc_addr.rc_bdaddr = *BDADDR_ANY;
1228 if (bind_socket (dev->fd_rfcomm, &rc_addr) != 0)
1230 fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
1231 dev->iface, strerror (errno));
1235 /* Register a SDP service */
1236 if (register_service (dev, rc_addr.rc_channel) != 0)
1238 fprintf (stderr, "Failed to register a service on interface `%.*s': %s\n", IFNAMSIZ,
1239 dev->iface, strerror (errno));
1243 /* Switch socket in listening mode */
1244 if (listen (dev->fd_rfcomm, 5) == -1) //FIXME: probably we need a bigger number
1246 fprintf (stderr, "Failed to listen on socket for interface `%.*s': %s\n", IFNAMSIZ,
1247 dev->iface, strerror (errno));
1258 * Set the header to sane values to make attacks more difficult
1260 * @param taIeeeHeader pointer to the header of the packet
1261 * @param dev pointer to the Hardware_Infos struct
1263 **** copy from gnunet-helper-transport-wlan.c ****
1266 mac_set (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1267 const struct HardwareInfos *dev)
1269 taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
1270 taIeeeHeader->addr3 = mac_bssid_gnunet;
1273 memcpy (&taIeeeHeader->addr2, &dev->pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1275 taIeeeHeader->addr2 = dev->pl_mac;
1281 * Test if the given interface name really corresponds to a bluetooth
1284 * @param iface name of the interface
1285 * @return 0 on success, 1 on error
1286 **** similar with the one from gnunet-helper-transport-wlan.c ****
1289 test_bluetooth_interface (const char *iface)
1295 ret = snprintf (strbuf, sizeof (strbuf),
1296 "/sys/class/bluetooth/%s/subsystem",
1298 if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
1301 "Did not find 802.15.1 interface `%s'. Exiting.\n",
1310 * Test incoming packets mac for being our own.
1312 * @param taIeeeHeader buffer of the packet
1313 * @param dev the Hardware_Infos struct
1314 * @return 0 if mac belongs to us, 1 if mac is for another target
1316 **** same as the one from gnunet-helper-transport-wlan.c ****
1319 mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1320 const struct HardwareInfos *dev)
1322 static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
1324 if ( (0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
1325 (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)) )
1326 return 0; /* some drivers set no Macs, then assume it is all for us! */
1328 if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1329 return 1; /* not a GNUnet ad-hoc package */
1330 if ( (0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
1331 (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)) )
1332 return 0; /* for us, or broadcast */
1333 return 1; /* not for us */
1338 * Process data from the stdin. Takes the message, forces the sender MAC to be correct
1339 * and puts it into our buffer for transmission to the receiver.
1341 * @param cls pointer to the device struct ('struct HardwareInfos*')
1342 * @param hdr pointer to the start of the packet
1344 **** same as the one from gnunet-helper-transport-wlan.c ****
1347 stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1349 struct HardwareInfos *dev = cls;
1350 const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header;
1351 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *blueheader;
1354 sendsize = ntohs (hdr->size);
1356 sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
1357 (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) )
1359 fprintf (stderr, "Received malformed message\n");
1362 sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) -
1363 sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1364 if (MAXLINE < sendsize)
1366 fprintf (stderr, "Packet too big for buffer\n");
1369 header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
1370 memcpy (&write_pout.buf, &header->frame, sendsize);
1371 blueheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf;
1373 /* payload contains MAC address, but we don't trust it, so we'll
1374 * overwrite it with OUR MAC address to prevent mischief */
1375 mac_set (blueheader, dev);
1376 memcpy (&blueheader->addr1, &header->frame.addr1,
1377 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1378 write_pout.size = sendsize;
1383 * Broadcast a HELLO message for peer discovery
1385 * @param dev pointer to the device struct
1386 * @param dev pointer to the socket which was added to the set
1387 * @return 0 on success
1390 send_broadcast (struct HardwareInfos *dev, int *sendsocket)
1396 if ((neighbours.size == neighbours.pos && new_device == 1) || neighbours.size == 0)
1398 inquiry_devices: //skip the conditions and force a inquiry for new devices
1401 * It means that I sent HELLO messages to all the devices from the list and I should search
1402 * for new ones or that this is the first time when I do a search.
1404 inquiry_info *devices = NULL;
1405 int i, responses, max_responses = MAX_PORTS;
1408 if (neighbours.size >= MAX_PORTS)
1410 fprintf (stderr, "%.*s reached the top limit for the discovarable devices\n", IFNAMSIZ, dev->iface);
1414 /* Get the device id */
1415 if (neighbours.dev_id == -1)
1417 char addr[19] = { 0 }; //the device MAC address
1419 ba2str ((bdaddr_t *) &dev->pl_mac, addr);
1420 neighbours.dev_id = hci_devid (addr);
1421 if (neighbours.dev_id < 0)
1423 fprintf (stderr, "Failed to get the device id for interface %.*s : %s\n", IFNAMSIZ,
1424 dev->iface, strerror (errno));
1429 devices = malloc (max_responses * sizeof (inquiry_info));
1430 if (devices == NULL)
1432 fprintf (stderr, "Failed to allocate memory for inquiry info list on interface %.*s\n", IFNAMSIZ,
1437 responses = hci_inquiry (neighbours.dev_id, 8, max_responses, NULL, &devices, IREQ_CACHE_FLUSH);
1440 fprintf (stderr, "Failed to inquiry on interface %.*s\n", IFNAMSIZ, dev->iface);
1444 fprintf (stderr, "LOG : Found %d devices\n", responses); //FIXME delete it after debugging stage
1448 fprintf (stderr, "LOG : No devices discoverable\n");
1452 for (i = 0; i < responses; i++)
1460 fprintf (stderr, "%.*s reached the top limit for the discoverable devices (after inquiry)\n", IFNAMSIZ,
1465 /* Search if the address already exists on the list */
1466 for (j = 0; j < neighbours.size; j++)
1468 if (memcmp (&(devices + i)->bdaddr, &(neighbours.devices[j]), sizeof (bdaddr_t)) == 0)
1471 fprintf (stderr, "LOG : the device already exists on the list\n"); //FIXME debugging message
1478 char addr[19] = { 0 };
1480 ba2str (&(devices +i)->bdaddr, addr);
1481 fprintf (stderr, "LOG : %s was added to the list\n", addr); //FIXME debugging message
1482 memcpy (&(neighbours.devices[neighbours.size++]), &(devices + i)->bdaddr, sizeof (bdaddr_t));
1490 int connection_successful = 0;
1491 struct sockaddr_rc addr_rc = { 0 };
1493 addr_rc.rc_family = AF_BLUETOOTH;
1495 /* Try to connect to a new device from the list */
1496 while (neighbours.pos < neighbours.size)
1498 /* Check if we are already connected to this device */
1499 if (neighbours.fds[neighbours.pos] == -1)
1502 memset (&addr_rc.rc_bdaddr, 0, sizeof (addr_rc.rc_bdaddr));
1503 memcpy (&addr_rc.rc_bdaddr, &(neighbours.devices[neighbours.pos]), sizeof (addr_rc.rc_bdaddr));
1505 addr_rc.rc_channel = get_channel (dev, addr_rc.rc_bdaddr);
1507 *sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1508 if (connect (*sendsocket, (struct sockaddr *)&addr_rc, sizeof (addr_rc)) == 0)
1510 neighbours.fds[neighbours.pos++] = *sendsocket;
1511 connection_successful = 1;
1512 char addr[19] = { 0 };
1513 ba2str (&(neighbours.devices[neighbours.pos - 1]), addr);
1514 fprintf (stderr, "LOG : Connected to %s\n", addr);
1520 char addr[19] = { 0 };
1521 errno_copy = errno; //Save a copy for later
1522 ba2str (&(neighbours.devices[neighbours.pos]), addr);
1523 fprintf (stderr, "LOG : Couldn't connect on device %s, error : %s\n", addr, strerror(errno));
1524 if (errno != ECONNREFUSED) //FIXME be sure that this works
1526 fprintf (stderr, "LOG : Removes %d device from the list\n", neighbours.pos);
1527 /* Remove the device from the list */
1528 memcpy (&neighbours.devices[neighbours.pos], &neighbours.devices[neighbours.size - 1], sizeof (bdaddr_t));
1529 memset (&neighbours.devices[neighbours.size - 1], 0, sizeof (bdaddr_t));
1530 neighbours.fds[neighbours.pos] = neighbours.fds[neighbours.size - 1];
1531 neighbours.fds[neighbours.size - 1] = -1;
1532 neighbours.size -= 1;
1535 neighbours.pos += 1;
1537 if (neighbours.pos >= neighbours.size)
1542 if (loops == MAX_LOOPS) //don't get stuck trying to connect to one device
1548 fprintf (stderr, "LOG : Search for a new device\n"); //FIXME debugging message
1549 neighbours.pos += 1;
1553 /* Cycle on the list */
1554 if (neighbours.pos == neighbours.size)
1557 searching_devices_count += 1;
1559 if (searching_devices_count == MAX_LOOPS)
1561 fprintf (stderr, "LOG : Force to inquiry for new devices\n");
1562 searching_devices_count = 0;
1563 goto inquiry_devices;
1566 /* If a new device wasn't found, search an old one */
1567 if (connection_successful == 0)
1569 int loop_check = neighbours.pos;
1570 while (neighbours.fds[neighbours.pos] == -1)
1572 if (neighbours.pos == neighbours.size)
1575 if (neighbours.pos == loop_check)
1577 if (errno_copy == ECONNREFUSED)
1579 fprintf (stderr, "LOG : No device found. Go back and search again\n"); //FIXME debugging message
1582 goto search_for_devices;
1586 return 1; // Skip the broadcast message
1590 neighbours.pos += 1;
1593 *sendsocket = neighbours.fds[neighbours.pos++];
1601 * Main function of the helper. This code accesses a bluetooth interface
1602 * forwards traffic in both directions between the bluetooth interface and
1603 * stdin/stdout of this process. Error messages are written to stderr.
1605 * @param argc number of arguments, must be 2
1606 * @param argv arguments only argument is the name of the interface (i.e. 'hci0')
1607 * @return 0 on success (never happens, as we don't return unless aborted), 1 on error
1609 **** similar to gnunet-helper-transport-wlan.c ****
1612 main (int argc, char *argv[])
1615 struct HardwareInfos dev;
1616 char readbuf[MAXLINE];
1621 struct MessageStreamTokenizer *stdin_mst;
1624 int crt_rfds = 0, rfds_list[MAX_PORTS];
1625 int broadcast, sendsocket;
1626 /* Assert privs so we can modify the firewall rules! */
1628 #ifdef HAVE_SETRESUID
1629 if (0 != setresuid (uid, 0, 0))
1631 fprintf (stderr, "Failed to setresuid to root: %s\n", strerror (errno));
1635 if (0 != seteuid (0))
1637 fprintf (stderr, "Failed to seteuid back to root: %s\n", strerror (errno));
1642 /* Make use of SGID capabilities on POSIX */
1643 memset (&dev, 0, sizeof (dev));
1644 dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1645 raw_eno = errno; /* remember for later */
1647 /* Now that we've dropped root rights, we can do error checking */
1650 fprintf (stderr, "You must specify the name of the interface as the first \
1651 and only argument to this program.\n");
1652 if (-1 != dev.fd_rfcomm)
1653 (void) close (dev.fd_rfcomm);
1657 if (-1 == dev.fd_rfcomm)
1659 fprintf (stderr, "Failed to create a RFCOMM socket: %s\n", strerror (raw_eno));
1662 if (dev.fd_rfcomm >= FD_SETSIZE)
1664 fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1665 dev.fd_rfcomm, FD_SETSIZE);
1666 (void) close (dev.fd_rfcomm);
1669 if (0 != test_bluetooth_interface (argv[1]))
1671 (void) close (dev.fd_rfcomm);
1674 strncpy (dev.iface, argv[1], IFNAMSIZ);
1675 if (0 != open_device (&dev))
1677 (void) close (dev.fd_rfcomm);
1683 uid_t uid = getuid ();
1684 #ifdef HAVE_SETRESUID
1685 if (0 != setresuid (uid, uid, uid))
1687 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1688 if (-1 != dev.fd_rfcomm)
1689 (void) close (dev.fd_rfcomm);
1693 if (0 != (setuid (uid) | seteuid (uid)))
1695 fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
1696 if (-1 != dev.fd_rfcomm)
1697 (void) close (dev.fd_rfcomm);
1703 /* Send MAC address of the bluetooth interface to STDOUT first */
1705 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
1707 macmsg.hdr.size = htons (sizeof (macmsg));
1708 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
1709 memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1710 memcpy (write_std.buf, &macmsg, sizeof (macmsg));
1711 write_std.size = sizeof (macmsg);
1715 stdin_mst = mst_create (&stdin_send_hw, &dev);
1719 * TODO : I should make the time out of a mac endpoint smaller and check if the rate
1720 * from get_wlan_header (plugin_transport_bluetooth.c) is correct.
1729 if ((0 == write_pout.size) && (1 == stdin_open))
1731 FD_SET (STDIN_FILENO, &rfds);
1732 maxfd = MAX (maxfd, STDIN_FILENO);
1734 if (0 == write_std.size)
1736 FD_SET (dev.fd_rfcomm, &rfds);
1737 maxfd = MAX (maxfd, dev.fd_rfcomm);
1740 for (i = 0; i < crt_rfds; i++) // it can receive messages from multiple devices
1742 FD_SET (rfds_list[i], &rfds);
1743 maxfd = MAX (maxfd, rfds_list[i]);
1746 if (0 < write_std.size)
1748 FD_SET (STDOUT_FILENO, &wfds);
1749 maxfd = MAX (maxfd, STDOUT_FILENO);
1751 if (0 < write_pout.size) //it can send messages only to one device per loop
1753 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *frame;
1754 /* Get the destination address */
1755 frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) write_pout.buf;
1757 if (memcmp (&frame->addr1, &dev.pl_mac,
1758 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1761 memset (&write_pout, 0, sizeof (write_pout)); //clear the buffer
1763 else if (memcmp (&frame->addr1, &broadcast_address,
1764 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1766 fprintf (stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n", dev.iface, neighbours.pos, neighbours.size); //FIXME: debugging message
1768 if (send_broadcast(&dev, &sendsocket) != 0) //if the searching wasn't successful don't get stuck on the select stage
1771 memset (&write_pout, 0, sizeof (write_pout)); //remove the message
1772 fprintf (stderr, "LOG : Skipping the broadcast message (pos %d, size %d)\n", neighbours.pos, neighbours.size);
1776 FD_SET (sendsocket, &wfds);
1777 maxfd = MAX (maxfd, sendsocket);
1784 /* Search if the address already exists on the list */
1785 for (i = 0; i < neighbours.size; i++)
1787 if (memcmp (&frame->addr1, &(neighbours.devices[i]), sizeof (bdaddr_t)) == 0)
1790 if (neighbours.fds[i] != -1)
1792 found = 1; //save the position where it was found
1793 FD_SET (neighbours.fds[i], &wfds);
1794 maxfd = MAX (maxfd, neighbours.fds[i]);
1795 sendsocket = neighbours.fds[i];
1796 fprintf (stderr, "LOG: the address was found in the list\n");
1804 struct sockaddr_rc addr = { 0 };
1806 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,
1807 frame->addr1.mac[5], frame->addr1.mac[4], frame->addr1.mac[3],
1808 frame->addr1.mac[2], frame->addr1.mac[1], frame->addr1.mac[0]); //FIXME: debugging message
1810 sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1814 fprintf (stderr, "Failed to create a RFCOMM socket (sending stage): %s\n",
1819 memcpy (&addr.rc_bdaddr, &frame->addr1, sizeof (bdaddr_t));
1820 addr.rc_family = AF_BLUETOOTH;
1821 addr.rc_channel = get_channel (&dev, addr.rc_bdaddr);
1825 status = connect (sendsocket, (struct sockaddr *) &addr, sizeof (addr));
1826 if (0 != status && errno != EAGAIN)
1828 if (errno == ECONNREFUSED && tries < 2)
1830 fprintf (stderr, "LOG : %.*s failed to connect. Trying again!\n", IFNAMSIZ, dev.iface);
1834 else if (errno == EBADF)
1836 fprintf (stderr, "LOG : %s failed to connect : %s. Skip it!\n", dev.iface, strerror (errno));
1837 memset (&write_pout, 0, sizeof (write_pout));
1842 fprintf (stderr, "LOG : %s failed to connect : %s. Try again later!\n", dev.iface, strerror (errno));
1843 memset (&write_pout, 0, sizeof (write_pout));
1850 FD_SET (sendsocket, &wfds);
1851 maxfd = MAX (maxfd, sendsocket);
1852 fprintf (stderr, "LOG : Connection successful\n");
1853 if (pos != 0) // save the socket
1855 neighbours.fds[pos] = sendsocket;
1859 /* Add the new device to the discovered devices list */
1860 if (neighbours.size < MAX_PORTS)
1862 neighbours.fds[neighbours.size] = sendsocket;
1863 memcpy (&(neighbours.devices[neighbours.size++]), &addr.rc_bdaddr, sizeof (bdaddr_t));
1867 fprintf (stderr, "The top limit for the discovarable devices' list was reached\n");
1877 /* Select a fd which is ready for action :) */
1879 int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
1880 if ((-1 == retval) && (EINTR == errno))
1882 if (0 > retval && errno != EBADF) // we handle BADF errors later
1884 fprintf (stderr, "select failed: %s\n", strerror (errno));
1888 if (FD_ISSET (STDOUT_FILENO , &wfds))
1891 write (STDOUT_FILENO, write_std.buf + write_std.pos,
1892 write_std.size - write_std.pos);
1895 fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1898 write_std.pos += ret;
1899 if (write_std.pos == write_std.size)
1904 fprintf (stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); //FIXME: debugging message
1907 if (sendsocket != -1)
1909 if (FD_ISSET (sendsocket , &wfds))
1912 write (sendsocket, write_pout.buf + write_std.pos,
1913 write_pout.size - write_pout.pos);
1914 if (0 > ret) //FIXME should I first check the error type?
1916 fprintf (stderr, "Failed to write to bluetooth device: %s. Closing the socket!\n",
1918 for (i = 0; i < neighbours.size; i++)
1920 if (neighbours.fds[i] == sendsocket)
1922 (void) close(sendsocket);
1923 neighbours.fds[i] = -1;
1927 /* Remove the message */
1928 memset (&write_pout.buf + write_std.pos, 0, (write_pout.size - write_pout.pos));
1929 write_pout.pos = 0 ;
1930 write_pout.size = 0;
1934 write_pout.pos += ret;
1935 if ((write_pout.pos != write_pout.size) && (0 != ret))
1937 /* We should not get partial sends with packet-oriented devices... */
1938 fprintf (stderr, "Write error, partial send: %u/%u\n",
1939 (unsigned int) write_pout.pos,
1940 (unsigned int) write_pout.size);
1944 if (write_pout.pos == write_pout.size)
1947 write_pout.size = 0;
1949 fprintf (stderr, "LOG : %s sends a message to a DEVICE\n", dev.iface); //FIXME: debugging message
1953 for (i = 0; i <= maxfd; i++)
1955 if (FD_ISSET (i, &rfds))
1957 if (i == STDIN_FILENO)
1960 read (i, readbuf, sizeof (readbuf));
1964 "Read error from STDIN: %s\n",
1970 /* stop reading... */
1975 mst_receive (stdin_mst, readbuf, ret);
1976 fprintf (stderr, "LOG : %s receives a message from STDIN\n", dev.iface); //FIXME: debugging message
1979 else if (i == dev.fd_rfcomm)
1982 struct sockaddr_rc addr = { 0 };
1983 unsigned int opt = sizeof (addr);
1985 readsocket = accept (dev.fd_rfcomm, (struct sockaddr *) &addr, &opt);
1986 fprintf(stderr, "LOG : %s accepts a message\n", dev.iface); //FIXME: debugging message
1987 if (readsocket == -1)
1989 fprintf (stderr, "Failed to accept a connection on interface: %.*s\n", IFNAMSIZ,
1995 FD_SET (readsocket, &rfds);
1996 maxfd = MAX (maxfd, readsocket);
1998 if (crt_rfds < MAX_PORTS)
1999 rfds_list[crt_rfds++] = readsocket;
2002 fprintf (stderr, "The limit for the read file descriptors list was \
2011 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
2013 fprintf (stderr, "LOG : %s reads something from the socket\n", dev.iface);//FIXME : debugging message
2014 rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
2016 read_from_the_socket ((void *)&i, (unsigned char *) &rrm->frame,
2017 sizeof (write_std.buf)
2018 - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2019 + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2026 /* Remove the socket from the list */
2027 for (j = 0; j < crt_rfds; j++)
2029 if (rfds_list[j] == i)
2031 rfds_list[j] ^= rfds_list[crt_rfds - 1];
2032 rfds_list[crt_rfds - 1] ^= rfds_list[j];
2033 rfds_list[j] ^= rfds_list[crt_rfds - 1];
2039 fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
2042 if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2044 write_std.size = ret
2045 + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2046 - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2047 rrm->header.size = htons (write_std.size);
2048 rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2055 /* Error handling, try to clean up a bit at least */
2056 mst_destroy (stdin_mst);
2058 sdp_close (dev.session);
2059 (void) close (dev.fd_rfcomm);
2060 (void) close (sendsocket);
2062 for (i = 0; i < crt_rfds; i++)
2063 (void) close (rfds_list[i]);
2065 for (i = 0; i < neighbours.size; i++)
2066 (void) close (neighbours.fds[i]);
2068 struct HardwareInfos dev;
2069 struct GNUNET_NETWORK_Handle *sendsocket;
2070 struct GNUNET_NETWORK_FDSet *rfds;
2071 struct GNUNET_NETWORK_FDSet *wfds;
2072 struct GNUNET_NETWORK_Handle *rfds_list[MAX_PORTS];
2073 char readbuf[MAXLINE] = { 0 };
2074 SOCKADDR_BTH acc_addr = { 0 };
2075 int addr_len = sizeof (SOCKADDR_BTH);
2076 int broadcast, i, stdin_open, crt_rfds = 0;
2077 HANDLE stdin_handle = GetStdHandle (STD_INPUT_HANDLE);
2078 HANDLE stdout_handle = GetStdHandle (STD_OUTPUT_HANDLE);
2079 struct MessageStreamTokenizer *stdin_mst;
2081 /* check the handles */
2082 if (stdin_handle == INVALID_HANDLE_VALUE)
2084 fprintf (stderr, "Failed to get the stdin handle\n");
2088 if (stdout_handle == INVALID_HANDLE_VALUE)
2090 fprintf (stderr, "Failed to get the stdout handle\n");
2094 /* initialize windows sockets */
2095 initialize_windows_sockets();
2097 // /* test bluetooth socket family support */ --> it return false because the GNUNET_NETWORK_test_pf should also receive the type of socket (BTHPROTO_RFCOMM)
2098 // if (GNUNET_NETWORK_test_pf (AF_BTH) != GNUNET_OK)
2100 // fprintf (stderr, "AF_BTH family is not supported\n");
2104 /* create the socket */
2105 dev.handle = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
2106 if (dev.handle == NULL)
2108 fprintf (stderr, "Failed to create RFCOMM socket: ");
2114 if (open_device (&dev) == -1)
2116 fprintf (stderr, "Failed to open the device\n");
2118 if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
2120 fprintf (stderr, "Failed to close the socket!\n");
2126 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (dev.handle, 1) )
2128 fprintf (stderr, "Failed to change the socket mode\n");
2132 memset (&write_std, 0, sizeof (write_std));
2133 memset (&write_pout, 0, sizeof (write_pout));
2136 rfds = GNUNET_NETWORK_fdset_create ();
2137 wfds = GNUNET_NETWORK_fdset_create ();
2139 /* Send MAC address of the bluetooth interface to STDOUT first */
2141 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
2143 macmsg.hdr.size = htons (sizeof (macmsg));
2144 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
2145 memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy));
2146 memcpy (write_std.buf, &macmsg, sizeof (macmsg));
2147 write_std.size = sizeof (macmsg);
2151 stdin_mst = mst_create (&stdin_send_hw, &dev);
2156 int stdout_pos = -1;
2163 sendsocket = NULL; //FIXME ???memleaks
2165 GNUNET_NETWORK_fdset_zero (rfds);
2166 if ((0 == write_pout.size) && (1 == stdin_open))
2170 GNUNET_NETWORK_fdset_handle_set (rfds, (struct GNUNET_DISK_FileHandle*) &stdin_handle);
2173 if (0 == write_std.size)
2176 GNUNET_NETWORK_fdset_set (rfds, dev.handle);
2179 for (i = 0; i < crt_rfds; i++)
2182 GNUNET_NETWORK_fdset_set (rfds, rfds_list[i]);
2185 GNUNET_NETWORK_fdset_zero (wfds);
2186 if (0 < write_std.size)
2189 GNUNET_NETWORK_fdset_handle_set (wfds, (struct GNUNET_DISK_FileHandle*) &stdout_handle);
2190 // printf ("%s\n", write_std.buf);
2191 // memset (write_std.buf, 0, write_std.size);
2192 // write_std.size = 0;
2195 if (0 < write_pout.size)
2197 if (strcmp (argv[1], "ff:ff:ff:ff:ff:ff") == 0) {
2198 fprintf(stderr, "LOG: BROADCAST! Skipping the message\n");
2201 memset (write_pout.buf, 0, write_pout.size);
2202 write_pout.size = 0;
2207 fprintf (stderr, "LOG : has a new message for %s\n", argv[1]);
2208 sendsocket = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
2210 if (sendsocket == NULL)
2212 fprintf (stderr, "Failed to create RFCOMM socket: \n");
2217 memset (&addr, 0, sizeof (addr));
2218 //addr.addressFamily = AF_BTH;
2220 WSAStringToAddress (argv[1], AF_BTH, NULL, (LPSOCKADDR) &addr, &addr_len))
2222 fprintf (stderr, "Failed to translate the address: ");
2226 addr.port = get_channel (argv[1]);
2227 if (addr.port == -1)
2229 fprintf (stderr, "Couldn't find the sdp service for the address: %s\n", argv[1]);
2230 memset (write_pout.buf, 0, write_pout.size);
2231 write_pout.size = 0;
2232 broadcast = 1; //skipping the select part
2236 if (GNUNET_OK != GNUNET_NETWORK_socket_connect (sendsocket, (LPSOCKADDR)&addr, addr_len))
2238 fprintf (stderr, "Failed to connect: ");
2243 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (sendsocket, 1) )
2245 fprintf (stderr, "Failed to change the socket mode\n");
2249 GNUNET_NETWORK_fdset_set (wfds, sendsocket);
2256 int retval = GNUNET_NETWORK_socket_select (rfds, wfds, NULL, GNUNET_TIME_relative_get_forever_());
2259 fprintf (stderr, "Select error\n");
2262 //if (GNUNET_NETWORK_fdset_isset (wfds, (struct GNUNET_NETWORK_Handle*)&stdout_handle))
2263 if (retval == stdout_pos)
2265 fprintf(stderr, "LOG : sends a message to STDOUT\n"); //FIXME: debugging message
2267 //ret = GNUNET_NETWORK_socket_send ((struct GNUNET_NETWORK_Handle *)&stdout_handle, write_std.buf + write_std.pos, write_std.size - write_std.pos);
2268 //ret = write (STDOUT_FILENO, write_std.buf + write_std.pos, write_std.size - write_std.pos);
2270 if (FALSE == WriteFile (stdout_handle, write_std.buf + write_std.pos, write_std.size - write_std.pos, &ret, NULL))
2272 fprintf (stderr, "Failed to write to STDOUT: ");
2279 fprintf (stderr, "Failed to write to STDOUT\n");
2283 write_std.pos += ret;
2284 if (write_std.pos == write_std.size)
2290 if (sendsocket != NULL)
2292 if (GNUNET_NETWORK_fdset_isset (wfds, sendsocket))
2295 ret = GNUNET_NETWORK_socket_send (sendsocket, write_pout.buf + write_pout.pos,
2296 write_pout.size - write_pout.pos);
2298 if (GNUNET_SYSERR == ret)
2300 fprintf (stderr, "Failed to send to the socket. Closing the socket. Error: \n");
2302 if (GNUNET_NETWORK_socket_close (sendsocket) != GNUNET_OK)
2304 fprintf (stderr, "Failed to close the sendsocket!\n");
2311 write_pout.pos += ret;
2312 if ((write_pout.pos != write_pout.size) && (0 != ret))
2314 /* we should not get partial sends with packet-oriented devices... */
2315 fprintf (stderr, "Write error, partial send: %u/%u\n",
2316 (unsigned int) write_pout.pos,
2317 (unsigned int) write_pout.size);
2321 if (write_pout.pos == write_pout.size)
2324 write_pout.size = 0;
2327 fprintf(stderr, "LOG : sends a message to a DEVICE\n"); //FIXME: debugging message
2332 //if (GNUNET_NETWORK_fdset_isset (rfds, (struct GNUNET_NETWORK_Handle*)&stdin_handle))
2333 if (retval == stdin_pos)
2336 //ret = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)&stdin_handle, readbuf, sizeof (write_pout.buf));
2337 //ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
2339 if (FALSE == ReadFile (stdin_handle, readbuf, sizeof (readbuf), &ret, NULL)) /* do nothing asynchronous */
2341 fprintf (stderr, "Read error from STDIN: ");
2347 /* stop reading... */
2350 mst_receive (stdin_mst, readbuf, ret);
2351 fprintf (stderr, "LOG : receives a message from STDIN\n"); //FIXME: debugging message
2355 if (GNUNET_NETWORK_fdset_isset (rfds, dev.handle))
2357 fprintf (stderr, "LOG: accepting connection\n");
2358 struct GNUNET_NETWORK_Handle *readsocket;
2359 readsocket = GNUNET_NETWORK_socket_accept (dev.handle, (LPSOCKADDR)&acc_addr, &addr_len);
2360 if (readsocket == NULL)
2362 fprintf (stderr, "Accept error %d: ", GetLastError());
2368 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (readsocket, 1) )
2370 fprintf (stderr, "Failed to change the socket mode\n");
2373 GNUNET_NETWORK_fdset_set (rfds, readsocket);
2375 if (crt_rfds < MAX_PORTS)
2376 rfds_list[crt_rfds++] = readsocket;
2379 fprintf (stderr, "The limit for the read file descriptors list was reached\n");
2385 for (i = 0; i < crt_rfds; i++)
2387 if (GNUNET_NETWORK_fdset_isset (rfds, rfds_list[i]))
2389 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
2391 fprintf (stderr, "LOG: reading something from the socket\n");//FIXME : debugging message
2392 rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
2393 ret = read_from_the_socket (rfds_list[i], (unsigned char *) &rrm->frame,
2394 sizeof (write_std.buf)
2395 - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2396 + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2401 //TODO remove the socket from the list
2402 if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2404 fprintf (stderr, "Failed to close the sendsocket!\n");
2408 fprintf (stderr, "Read error from raw socket: ");
2413 if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2415 write_std.size = ret
2416 + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2417 - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2418 rrm->header.size = htons (write_std.size);
2419 rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2427 mst_destroy (stdin_mst);
2430 if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
2432 fprintf (stderr, "Failed to close the socket!\n");
2436 for (i = 0; i < crt_rfds; i++)
2438 if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2440 fprintf (stderr, "Failed to close the socket!\n");
2447 return 1; /* we never exit 'normally' */