2 This file is part of GNUnet.
3 Copyright (C) 2010, 2011, 2012 GNUnet e.V.
4 Copyright (c) 2007, 2008, Andy Green <andy@warmcat.com>
5 Copyright Copyright (C) 2009 Thomas d'Otreppe
7 GNUnet is free software; you can redistribute it and/or modify
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., 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA.
22 #include "gnunet_config.h"
26 #include "gnunet_util_lib.h"
31 #include <bluetooth/bluetooth.h>
32 #include <bluetooth/hci.h>
33 #include <bluetooth/hci_lib.h>
34 #include <bluetooth/rfcomm.h>
35 #include <bluetooth/sdp.h>
36 #include <bluetooth/sdp_lib.h>
41 #include <sys/ioctl.h>
42 #include <sys/param.h>
43 #include <sys/socket.h>
45 #include <sys/types.h>
49 #include "plugin_transport_wlan.h"
50 #include "gnunet_protocols.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 * In bluez library, the maximum name length of a device is 8
102 #define BLUEZ_DEVNAME_SIZE 8
105 * struct for storing the information of the hardware. There is only
111 * Name of the interface, not necessarily 0-terminated (!).
113 char iface[IFNAMSIZ];
119 struct GNUNET_NETWORK_Handle *handle;
122 * MAC address of our own bluetooth interface.
124 struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy pl_mac;
127 * file descriptor for the rfcomm socket
132 * MAC address of our own bluetooth interface.
134 struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac;
139 sdp_session_t *session ;
144 * IO buffer used for buffering data in transit (to wireless or to stdout).
149 * How many bytes of data are stored in 'buf' for transmission right now?
150 * Data always starts at offset 0 and extends to 'size'.
155 * How many bytes that were stored in 'buf' did we already write to the
156 * destination? Always smaller than 'size'.
161 * Buffered data; twice the maximum allowed message size as we add some
164 char buf[MAXLINE * 2];
169 * Devices buffer used to keep a list with all the discoverable devices in
170 * order to send them HELLO messages one by one when it receive a broadcast message.
172 struct BroadcastMessages
174 /* List with the discoverable devices' addresses */
175 bdaddr_t devices[MAX_PORTS];
177 /* List with the open sockets */
181 /* The number of the devices */
184 /* The current position */
192 * Address used to identify the broadcast messages.
194 static struct GNUNET_TRANSPORT_WLAN_MacAddress broadcast_address = {{255, 255, 255, 255, 255, 255}};
197 * Buffer with the discoverable devices.
199 static struct BroadcastMessages neighbours;
201 static int searching_devices_count = 0;
205 * Buffer for data read from stdin to be transmitted to the bluetooth device
207 static struct SendBuffer write_pout;
210 * Buffer for data read from the bluetooth device to be transmitted to stdout.
212 static struct SendBuffer write_std;
215 /* ****** this are the same functions as the ones used in gnunet-helper-transport-wlan.c ****** */
218 * To what multiple do we align messages? 8 byte should suffice for everyone
221 #define ALIGN_FACTOR 8
224 * Smallest supported message.
226 #define MIN_BUFFER_SIZE sizeof (struct GNUNET_MessageHeader)
230 * Functions with this signature are called whenever a
231 * complete message is received by the tokenizer.
234 * @param message the actual message
236 typedef void (*MessageTokenizerCallback) (void *cls,
238 GNUNET_MessageHeader *
242 * Handle to a message stream tokenizer.
244 struct MessageStreamTokenizer
248 * Function to call on completed messages.
250 MessageTokenizerCallback cb;
258 * Size of the buffer (starting at 'hdr').
263 * How many bytes in buffer have we already processed?
268 * How many bytes in buffer are valid right now?
273 * Beginning of the buffer. Typed like this to force alignment.
275 struct GNUNET_MessageHeader *hdr;
281 * Create a message stream tokenizer.
283 * @param cb function to call on completed messages
284 * @param cb_cls closure for cb
285 * @return handle to tokenizer
287 static struct MessageStreamTokenizer *
288 mst_create (MessageTokenizerCallback cb,
291 struct MessageStreamTokenizer *ret;
293 ret = malloc (sizeof (struct MessageStreamTokenizer));
296 fprintf (stderr, "Failed to allocate buffer for tokenizer\n");
299 ret->hdr = malloc (MIN_BUFFER_SIZE);
300 if (NULL == ret->hdr)
302 fprintf (stderr, "Failed to allocate buffer for alignment\n");
305 ret->curr_buf = MIN_BUFFER_SIZE;
307 ret->cb_cls = cb_cls;
315 * Add incoming data to the receive buffer and call the
316 * callback for all complete messages.
318 * @param mst tokenizer to use
319 * @param buf input data to add
320 * @param size number of bytes in buf
321 * @return GNUNET_OK if we are done processing (need more data)
322 * GNUNET_SYSERR if the data stream is corrupt
325 mst_receive (struct MessageStreamTokenizer *mst,
326 const char *buf, size_t size)
328 const struct GNUNET_MessageHeader *hdr;
333 unsigned long offset;
337 ibuf = (char *) mst->hdr;
341 if (mst->pos < mst->off)
343 //fprintf (stderr, "We processed too many bytes!\n");
344 return GNUNET_SYSERR;
346 if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) ||
347 (0 != (mst->off % ALIGN_FACTOR)))
349 /* need to align or need more space */
350 mst->pos -= mst->off;
351 memmove (ibuf, &ibuf[mst->off], mst->pos);
354 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
357 GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) -
358 (mst->pos - mst->off), size);
359 GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
364 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
366 //FIXME should I reset ??
371 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
372 want = ntohs (hdr->size);
373 if (want < sizeof (struct GNUNET_MessageHeader))
376 "Received invalid message from stdin\n");
377 return GNUNET_SYSERR;
379 if ((mst->curr_buf - mst->off < want) &&
382 /* need more space */
383 mst->pos -= mst->off;
384 memmove (ibuf, &ibuf[mst->off], mst->pos);
387 if (want > mst->curr_buf)
391 fprintf (stderr, "Error! We should proceeded 0 bytes\n");
392 return GNUNET_SYSERR;
394 mst->hdr = realloc (mst->hdr, want);
395 if (NULL == mst->hdr)
397 fprintf (stderr, "Failed to allocate buffer for alignment\n");
400 ibuf = (char *) mst->hdr;
401 mst->curr_buf = want;
403 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
404 if (mst->pos - mst->off < want)
406 delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
407 if (mst->pos + delta > mst->curr_buf)
409 fprintf (stderr, "The size of the buffer will be exceeded!\n");
410 return GNUNET_SYSERR;
412 GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
417 if (mst->pos - mst->off < want)
419 //FIXME should I use this?
424 mst->cb (mst->cb_cls, hdr);
426 if (mst->off == mst->pos)
428 /* reset to beginning of buffer, it's free right now! */
435 fprintf (stderr, "There should some valid bytes in the buffer on this stage\n");
436 return GNUNET_SYSERR;
440 if (size < sizeof (struct GNUNET_MessageHeader))
442 offset = (unsigned long) buf;
443 need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
444 if (GNUNET_NO == need_align)
446 /* can try to do zero-copy and process directly from original buffer */
447 hdr = (const struct GNUNET_MessageHeader *) buf;
448 want = ntohs (hdr->size);
449 if (want < sizeof (struct GNUNET_MessageHeader))
452 "Received invalid message from stdin\n");
455 return GNUNET_SYSERR;
458 break; /* or not, buffer incomplete, so copy to private buffer... */
459 mst->cb (mst->cb_cls, hdr);
465 /* need to copy to private buffer to align;
466 * yes, we go a bit more spagetti than usual here */
472 if (size + mst->pos > mst->curr_buf)
474 mst->hdr = realloc (mst->hdr, size + mst->pos);
475 if (NULL == mst->hdr)
477 fprintf (stderr, "Failed to allocate buffer for alignment\n");
480 ibuf = (char *) mst->hdr;
481 mst->curr_buf = size + mst->pos;
483 if (mst->pos + size > mst->curr_buf)
486 "Assertion failed\n");
489 GNUNET_memcpy (&ibuf[mst->pos], buf, size);
496 * Destroys a tokenizer.
498 * @param mst tokenizer to destroy
501 mst_destroy (struct MessageStreamTokenizer *mst)
508 * Calculate crc32, the start of the calculation
510 * @param buf buffer to calc the crc
511 * @param len len of the buffer
515 calc_crc_osdep (const unsigned char *buf, size_t len)
517 static const unsigned long int crc_tbl_osdep[256] = {
518 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
519 0xE963A535, 0x9E6495A3,
520 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
521 0xE7B82D07, 0x90BF1D91,
522 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
523 0xF4D4B551, 0x83D385C7,
524 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
525 0xFA0F3D63, 0x8D080DF5,
526 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
527 0xD20D85FD, 0xA50AB56B,
528 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
529 0xDCD60DCF, 0xABD13D59,
530 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
531 0xCFBA9599, 0xB8BDA50F,
532 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
533 0xC1611DAB, 0xB6662D3D,
534 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
535 0x9FBFE4A5, 0xE8B8D433,
536 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
537 0x91646C97, 0xE6635C01,
538 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
539 0x8208F4C1, 0xF50FC457,
540 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
541 0x8CD37CF3, 0xFBD44C65,
542 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
543 0xA4D1C46D, 0xD3D6F4FB,
544 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
545 0xAA0A4C5F, 0xDD0D7CC9,
546 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
547 0xB966D409, 0xCE61E49F,
548 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
549 0xB7BD5C3B, 0xC0BA6CAD,
550 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
551 0x04DB2615, 0x73DC1683,
552 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
553 0x0A00AE27, 0x7D079EB1,
554 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
555 0x196C3671, 0x6E6B06E7,
556 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
557 0x17B7BE43, 0x60B08ED5,
558 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
559 0x3FB506DD, 0x48B2364B,
560 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
561 0x316E8EEF, 0x4669BE79,
562 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
563 0x220216B9, 0x5505262F,
564 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
565 0x2CD99E8B, 0x5BDEAE1D,
566 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
567 0x72076785, 0x05005713,
568 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
569 0x7CDCEFB7, 0x0BDBDF21,
570 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
571 0x6FB077E1, 0x18B74777,
572 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
573 0x616BFFD3, 0x166CCF45,
574 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
575 0x4969474D, 0x3E6E77DB,
576 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
577 0x47B2CF7F, 0x30B5FFE9,
578 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
579 0x54DE5729, 0x23D967BF,
580 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
581 0x5A05DF1B, 0x2D02EF8D
584 unsigned long crc = 0xFFFFFFFF;
586 for (; len > 0; len--, buf++)
587 crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
593 * Calculate and check crc of the bluetooth packet
595 * @param buf buffer of the packet, with len + 4 bytes of data,
596 * the last 4 bytes being the checksum
597 * @param len length of the payload in data
598 * @return 0 on success (checksum matches), 1 on error
601 check_crc_buf_osdep (const unsigned char *buf, size_t len)
605 crc = calc_crc_osdep (buf, len);
607 if (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
608 ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3])
615 /* ************** end of clone ***************** */
619 * Function used to get the code of last error and to print the type of error.
624 LPVOID lpMsgBuf = NULL;
626 if (FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
627 NULL, GetLastError(), 0, (LPTSTR) &lpMsgBuf, 0, NULL))
628 fprintf (stderr, "%s\n", (char *)lpMsgBuf);
630 fprintf (stderr, "Failed to format the message for the last error! Error number : %d\n", GetLastError());
634 * Function used to initialize the Windows Sockets
637 initialize_windows_sockets()
640 WORD wVersionRequested = MAKEWORD (2, 0);
641 if (WSAStartup (wVersionRequested, &wsaData) != NO_ERROR)
643 fprintf (stderr , "Error initializing window sockets!\n");
650 * Function used to convert the GUID.
651 * @param bytes the GUID represented as a char array
652 * @param uuid pointer to the GUID
655 convert_guid(char *bytes, GUID * uuid)
658 uuid->Data1 = ((bytes[0] << 24) & 0xff000000) | ((bytes[1] << 16) & 0x00ff0000) | ((bytes[2] << 8) & 0x0000ff00) | (bytes[3] & 0x000000ff);
659 uuid->Data2 = ((bytes[4] << 8) & 0xff00) | (bytes[5] & 0x00ff);
660 uuid->Data3 = ((bytes[6] << 8) & 0xff00) | (bytes[7] & 0x00ff);
662 for (i = 0; i < 8; i++)
664 uuid->Data4[i] = bytes[i + 8];
671 * Function for assigning a port number
673 * @param socket the socket used to bind
674 * @param addr pointer to the rfcomm address
675 * @return 0 on success
678 bind_socket (int socket, struct sockaddr_rc *addr)
682 /* Bind every possible port (from 0 to 30) and stop when binding doesn't fail */
683 //FIXME : it should start from port 1, but on my computer it doesn't work :)
684 for (port = 3; port <= 30; port++)
686 addr->rc_channel = port;
687 status = bind (socket, (struct sockaddr *) addr, sizeof (struct sockaddr_rc));
698 * Function used for creating the service record and registering it.
700 * @param dev pointer to the device struct
701 * @return 0 on success
704 register_service (struct HardwareInfos *dev)
706 /* advertise the service */
707 CSADDR_INFO addr_info;
710 unsigned char uuid[] = GNUNET_BLUETOOTH_SDP_UUID;
712 int addr_len = sizeof (SOCKADDR_BTH);
714 /* get the port on which we are listening on */
715 memset (& addr, 0, sizeof (SOCKADDR_BTH));
716 fd = GNUNET_NETWORK_get_fd (dev->handle);
719 fprintf (stderr, "Failed to get the file descriptor\n");
722 if (SOCKET_ERROR == getsockname (fd, (SOCKADDR*)&addr, &addr_len))
724 fprintf (stderr, "Failed to get the port on which we are listening on: \n");
729 /* save the device address */
730 GNUNET_memcpy (&dev->pl_mac, &addr.btAddr, sizeof (BTH_ADDR));
732 /* set the address information */
733 memset (&addr_info, 0, sizeof (CSADDR_INFO));
734 addr_info.iProtocol = BTHPROTO_RFCOMM;
735 addr_info.iSocketType = SOCK_STREAM;
736 addr_info.LocalAddr.lpSockaddr = (LPSOCKADDR)&addr;
737 addr_info.LocalAddr.iSockaddrLength = sizeof (addr);
738 addr_info.RemoteAddr.lpSockaddr = (LPSOCKADDR)&addr;
739 addr_info.RemoteAddr.iSockaddrLength = sizeof (addr);
741 convert_guid((char *) uuid, &guid);
743 /* register the service */
744 memset (&wqs, 0, sizeof (WSAQUERYSET));
745 wqs.dwSize = sizeof (WSAQUERYSET);
746 wqs.dwNameSpace = NS_BTH;
747 wqs.lpszServiceInstanceName = "GNUnet Bluetooth Service";
748 wqs.lpszComment = "This is the service used by the GNUnnet plugin transport";
749 wqs.lpServiceClassId = &guid;
750 wqs.dwNumberOfCsAddrs = 1;
751 wqs.lpcsaBuffer = &addr_info ;
754 if (SOCKET_ERROR == WSASetService (&wqs , RNRSERVICE_REGISTER, 0))
756 fprintf (stderr, "Failed to register the SDP service: ");
762 fprintf (stderr, "The SDP service was registered\n");
769 * Function used for creating the service record and registering it.
771 * @param dev pointer to the device struct
772 * @param rc_channel the rfcomm channel
773 * @return 0 on success
776 register_service (struct HardwareInfos *dev, int rc_channel)
780 * 2. set the service ID, class, profile information
781 * 3. make the service record publicly browsable
782 * 4. register the RFCOMM channel
783 * 5. set the name, provider and description
784 * 6. register the service record to the local SDP server
787 uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
788 dev->pl_mac.mac[5], dev->pl_mac.mac[4], dev->pl_mac.mac[3],
789 dev->pl_mac.mac[2], dev->pl_mac.mac[1], dev->pl_mac.mac[0]};
790 const char *service_dsc = "Bluetooth plugin services";
791 const char *service_prov = "GNUnet provider";
792 uuid_t root_uuid, rfcomm_uuid, svc_uuid;
793 sdp_list_t *root_list = 0, *rfcomm_list = 0, *proto_list = 0,
794 *access_proto_list = 0, *svc_list = 0;
795 sdp_record_t *record = 0;
796 sdp_data_t *channel = 0;
798 record = sdp_record_alloc();
800 /* Set the general service ID */
801 sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
802 svc_list = sdp_list_append (0, &svc_uuid);
803 sdp_set_service_classes (record, svc_list);
804 sdp_set_service_id (record, svc_uuid);
806 /* Make the service record publicly browsable */
807 sdp_uuid16_create (&root_uuid, PUBLIC_BROWSE_GROUP);
808 root_list = sdp_list_append (0, &root_uuid);
809 sdp_set_browse_groups (record, root_list);
811 /* Register the RFCOMM channel */
812 sdp_uuid16_create (&rfcomm_uuid, RFCOMM_UUID);
813 channel = sdp_data_alloc (SDP_UINT8, &rc_channel);
814 rfcomm_list = sdp_list_append (0, &rfcomm_uuid);
815 sdp_list_append (rfcomm_list, channel);
816 proto_list = sdp_list_append (0, rfcomm_list);
818 /* Set protocol information */
819 access_proto_list = sdp_list_append (0, proto_list);
820 sdp_set_access_protos (record, access_proto_list);
822 /* Set the name, provider, and description */
823 sdp_set_info_attr (record, dev->iface, service_prov, service_dsc);
825 /* Connect to the local SDP server */
826 dev->session = sdp_connect (BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
830 fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
831 IFNAMSIZ, dev->iface, strerror (errno));
836 /* Register the service record */
837 if (sdp_record_register (dev->session, record, 0) < 0)
839 fprintf (stderr, "Failed to register a service record on interface `%.*s': %s\n",
840 IFNAMSIZ, dev->iface, strerror (errno));
846 sdp_data_free (channel);
847 sdp_list_free (root_list, 0);
848 sdp_list_free (rfcomm_list, 0);
849 sdp_list_free (proto_list, 0);
850 sdp_list_free (access_proto_list, 0);
851 sdp_list_free (svc_list, 0);
852 sdp_record_free (record);
860 * Function for searching and browsing for a service. This will return the
861 * port number on which the service is running.
863 * @param dest target address
867 get_channel(const char *dest)
871 DWORD wqs_len = sizeof (WSAQUERYSET);
875 unsigned char uuid[] = GNUNET_BLUETOOTH_SDP_UUID;
876 convert_guid ((char *) uuid, &guid);
878 wqs = (WSAQUERYSET*)malloc (wqs_len);
879 ZeroMemory (wqs, wqs_len);
881 wqs->dwSize = sizeof (WSAQUERYSET) ;
882 wqs->lpServiceClassId = &guid;
883 wqs->dwNameSpace = NS_BTH;
884 wqs->dwNumberOfCsAddrs = 0;
885 wqs->lpszContext = (LPSTR)dest;
887 if (SOCKET_ERROR == WSALookupServiceBegin (wqs, LUP_FLUSHCACHE | LUP_RETURN_ALL, &h))
889 if (GetLastError() == WSASERVICE_NOT_FOUND)
891 fprintf (stderr, "WARNING! The device with address %s wasn't found. Skipping the message!", dest);
896 fprintf (stderr, "Failed to find the port number: ");
903 /* search the sdp service */
906 if (SOCKET_ERROR == WSALookupServiceNext (h, LUP_FLUSHCACHE | LUP_RETURN_ALL, &wqs_len, wqs))
908 int error = WSAGetLastError();
914 wqs = (WSAQUERYSET*)malloc (wqs_len);
917 fprintf (stderr, "Failed! The address was valid but there was no data record of requested type\n");
924 fprintf (stderr, "Failed to look over the services: ");
926 WSALookupServiceEnd (h);
932 channel = ((SOCKADDR_BTH*)wqs->lpcsaBuffer->RemoteAddr.lpSockaddr)->port;
937 WSALookupServiceEnd (h);
943 * Function used for searching and browsing for a service. This will return the
944 * port number on which the service is running.
946 * @param dev pointer to the device struct
947 * @param dest target address
951 get_channel(struct HardwareInfos *dev, bdaddr_t dest)
954 * 1. detect all nearby devices
955 * 2. for each device:
956 * 2.1. connect to the SDP server running
957 * 2.2. get a list of service records with the specific UUID
958 * 2.3. for each service record get a list of the protocol sequences and get
961 uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
962 dest.b[5], dest.b[4], dest.b[3],
963 dest.b[2], dest.b[1], dest.b[0]};
964 sdp_session_t *session = 0;
965 sdp_list_t *search_list = 0, *attrid_list = 0, *response_list = 0, *it = 0;
967 uint32_t range = 0x0000ffff;
970 /* Connect to the local SDP server */
971 session = sdp_connect (BDADDR_ANY, &dest, 0);
974 fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
975 IFNAMSIZ, dev->iface, strerror (errno));
979 sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
980 search_list = sdp_list_append (0, &svc_uuid);
981 attrid_list = sdp_list_append (0, &range);
983 if (sdp_service_search_attr_req (session, search_list,
984 SDP_ATTR_REQ_RANGE, attrid_list, &response_list) == 0)
986 for (it = response_list; it; it = it->next)
988 sdp_record_t *record = (sdp_record_t*) it->data;
989 sdp_list_t *proto_list = 0;
990 if (sdp_get_access_protos (record, &proto_list) == 0)
992 channel = sdp_get_proto_port (proto_list, RFCOMM_UUID);
993 sdp_list_free (proto_list, 0);
995 sdp_record_free (record);
999 sdp_list_free (search_list, 0);
1000 sdp_list_free (attrid_list, 0);
1001 sdp_list_free (response_list, 0);
1003 sdp_close (session);
1007 "Failed to find the listening channel for interface `%.*s': %s\n",
1017 * Read from the socket and put the result into the buffer for transmission to 'stdout'.
1019 * @param sock file descriptor for reading
1020 * @param buf buffer to read to; first bytes will be the 'struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame',
1021 * followed by the actual payload
1022 * @param buf_size size of the buffer
1023 * @param ri where to write radiotap_rx info
1024 * @return number of bytes written to 'buf'
1027 read_from_the_socket (void *sock,
1028 unsigned char *buf, size_t buf_size,
1029 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri)
1031 unsigned char tmpbuf[buf_size];
1035 count = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)sock, tmpbuf, buf_size);
1037 count = read (*((int *)sock), tmpbuf, buf_size);
1042 if (EAGAIN == errno)
1047 fprintf (stderr, "Failed to read from the HCI socket: %s\n", strerror (errno));
1054 /* Get the channel used */
1056 struct sockaddr_rc rc_addr = { 0 };
1058 memset (&rc_addr, 0, sizeof (rc_addr));
1059 len = sizeof (rc_addr);
1060 if (0 > getsockname (*((int *)sock), (struct sockaddr *) &rc_addr, (socklen_t *) &len))
1062 fprintf (stderr, "getsockname() call failed : %s\n", strerror (errno));
1066 memset (ri, 0, sizeof (*ri));
1067 ri->ri_channel = rc_addr.rc_channel;
1070 /* Detect CRC32 at the end */
1071 if (0 == check_crc_buf_osdep (tmpbuf, count - sizeof (uint32_t)))
1073 count -= sizeof(uint32_t);
1076 GNUNET_memcpy (buf, tmpbuf, count);
1083 * Open the bluetooth interface for reading/writing
1085 * @param dev pointer to the device struct
1086 * @return 0 on success, non-zero on error
1089 open_device (struct HardwareInfos *dev)
1094 /* bind the RFCOMM socket to the interface */
1095 addr.addressFamily = AF_BTH;
1097 addr.port = BT_PORT_ANY;
1100 GNUNET_NETWORK_socket_bind (dev->handle, (const SOCKADDR*)&addr, sizeof (SOCKADDR_BTH)))
1102 fprintf (stderr, "Failed to bind the socket: ");
1103 if (GetLastError() == WSAENETDOWN)
1105 fprintf (stderr, "Please make sure that your Bluetooth device is ON!\n");
1112 /* start listening on the socket */
1113 if (GNUNET_NETWORK_socket_listen (dev->handle, 4) != GNUNET_OK)
1115 fprintf (stderr, "Failed to listen on the socket: ");
1120 /* register the sdp service */
1121 if (register_service(dev) != 0)
1123 fprintf (stderr, "Failed to register a service: ");
1128 int i, dev_id = -1, fd_hci;
1131 struct hci_dev_list_req list;
1132 struct hci_dev_req dev[HCI_MAX_DEV];
1133 } request; //used for detecting the local devices
1134 struct sockaddr_rc rc_addr = { 0 }; //used for binding
1136 /* Initialize the neighbour structure */
1137 neighbours.dev_id = -1;
1138 for (i = 0; i < MAX_PORTS; i++)
1139 neighbours.fds[i] = -1;
1141 /* Open a HCI socket */
1142 fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
1147 "Failed to create HCI socket: %s\n",
1152 memset (&request, 0, sizeof(request));
1153 request.list.dev_num = HCI_MAX_DEV;
1155 if (ioctl (fd_hci, HCIGETDEVLIST, (void *) &request) < 0)
1158 "ioctl(HCIGETDEVLIST) on interface `%.*s' failed: %s\n",
1162 (void) close (fd_hci);
1166 /* Search for a device with dev->iface name */
1167 for (i = 0; i < request.list.dev_num; i++)
1169 struct hci_dev_info dev_info;
1171 memset (&dev_info, 0, sizeof(struct hci_dev_info));
1172 dev_info.dev_id = request.dev[i].dev_id;
1173 strncpy (dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE);
1175 if (ioctl (fd_hci, HCIGETDEVINFO, (void *) &dev_info))
1178 "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n",
1182 (void) close (fd_hci);
1186 if (strncmp (dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE) == 0)
1189 dev_id = dev_info.dev_id; //the device was found
1191 * Copy the MAC address to the device structure
1193 GNUNET_memcpy (&dev->pl_mac, &dev_info.bdaddr, sizeof (bdaddr_t));
1195 /* Check if the interface is up */
1196 if (hci_test_bit (HCI_UP, (void *) &dev_info.flags) == 0)
1198 /* Bring the interface up */
1199 if (ioctl (fd_hci, HCIDEVUP, dev_info.dev_id))
1202 "ioctl(HCIDEVUP) on interface `%.*s' failed: %s\n",
1206 (void) close (fd_hci);
1211 /* Check if the device is discoverable */
1212 if (hci_test_bit (HCI_PSCAN, (void *) &dev_info.flags) == 0 ||
1213 hci_test_bit (HCI_ISCAN, (void *) &dev_info.flags) == 0)
1215 /* Set interface Page Scan and Inqury Scan ON */
1216 struct hci_dev_req dev_req;
1218 memset (&dev_req, 0, sizeof (dev_req));
1219 dev_req.dev_id = dev_info.dev_id;
1220 dev_req.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
1222 if (ioctl (fd_hci, HCISETSCAN, (unsigned long) &dev_req))
1225 "ioctl(HCISETSCAN) on interface `%.*s' failed: %s\n",
1229 (void) close (fd_hci);
1239 /* Check if the interface was not found */
1243 "The interface %s was not found\n",
1245 (void) close (fd_hci);
1249 /* Close the hci socket */
1250 (void) close(fd_hci);
1254 /* Bind the rfcomm socket to the interface */
1255 memset (&rc_addr, 0, sizeof (rc_addr));
1256 rc_addr.rc_family = AF_BLUETOOTH;
1257 rc_addr.rc_bdaddr = *BDADDR_ANY;
1259 if (bind_socket (dev->fd_rfcomm, &rc_addr) != 0)
1262 "Failed to bind interface `%.*s': %s\n",
1269 /* Register a SDP service */
1270 if (register_service (dev, rc_addr.rc_channel) != 0)
1273 "Failed to register a service on interface `%.*s': %s\n",
1275 dev->iface, strerror (errno));
1279 /* Switch socket in listening mode */
1280 if (listen (dev->fd_rfcomm, 5) == -1) //FIXME: probably we need a bigger number
1282 fprintf (stderr, "Failed to listen on socket for interface `%.*s': %s\n", IFNAMSIZ,
1283 dev->iface, strerror (errno));
1294 * Set the header to sane values to make attacks more difficult
1296 * @param taIeeeHeader pointer to the header of the packet
1297 * @param dev pointer to the Hardware_Infos struct
1299 **** copy from gnunet-helper-transport-wlan.c ****
1302 mac_set (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1303 const struct HardwareInfos *dev)
1305 taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
1306 taIeeeHeader->addr3 = mac_bssid_gnunet;
1309 GNUNET_memcpy (&taIeeeHeader->addr2, &dev->pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1311 taIeeeHeader->addr2 = dev->pl_mac;
1317 * Test if the given interface name really corresponds to a bluetooth
1320 * @param iface name of the interface
1321 * @return 0 on success, 1 on error
1322 **** similar with the one from gnunet-helper-transport-wlan.c ****
1325 test_bluetooth_interface (const char *iface)
1331 ret = snprintf (strbuf, sizeof (strbuf),
1332 "/sys/class/bluetooth/%s/subsystem",
1334 if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
1337 "Did not find 802.15.1 interface `%s'. Exiting.\n",
1346 * Test incoming packets mac for being our own.
1348 * @param taIeeeHeader buffer of the packet
1349 * @param dev the Hardware_Infos struct
1350 * @return 0 if mac belongs to us, 1 if mac is for another target
1352 **** same as the one from gnunet-helper-transport-wlan.c ****
1355 mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1356 const struct HardwareInfos *dev)
1358 static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
1360 if ( (0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
1361 (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)) )
1362 return 0; /* some drivers set no Macs, then assume it is all for us! */
1364 if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1365 return 1; /* not a GNUnet ad-hoc package */
1366 if ( (0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
1367 (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)) )
1368 return 0; /* for us, or broadcast */
1369 return 1; /* not for us */
1374 * Process data from the stdin. Takes the message, forces the sender MAC to be correct
1375 * and puts it into our buffer for transmission to the receiver.
1377 * @param cls pointer to the device struct ('struct HardwareInfos*')
1378 * @param hdr pointer to the start of the packet
1380 **** same as the one from gnunet-helper-transport-wlan.c ****
1383 stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1385 struct HardwareInfos *dev = cls;
1386 const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header;
1387 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *blueheader;
1390 sendsize = ntohs (hdr->size);
1392 sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
1393 (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) )
1395 fprintf (stderr, "Received malformed message\n");
1398 sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) -
1399 sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1400 if (MAXLINE < sendsize)
1402 fprintf (stderr, "Packet too big for buffer\n");
1405 header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
1406 GNUNET_memcpy (&write_pout.buf, &header->frame, sendsize);
1407 blueheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf;
1409 /* payload contains MAC address, but we don't trust it, so we'll
1410 * overwrite it with OUR MAC address to prevent mischief */
1411 mac_set (blueheader, dev);
1412 GNUNET_memcpy (&blueheader->addr1, &header->frame.addr1,
1413 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1414 write_pout.size = sendsize;
1419 * Broadcast a HELLO message for peer discovery
1421 * @param dev pointer to the device struct
1422 * @param dev pointer to the socket which was added to the set
1423 * @return 0 on success
1426 send_broadcast (struct HardwareInfos *dev, int *sendsocket)
1432 if ((neighbours.size == neighbours.pos && new_device == 1) || neighbours.size == 0)
1434 inquiry_devices: //skip the conditions and force a inquiry for new devices
1437 * It means that I sent HELLO messages to all the devices from the list and I should search
1438 * for new ones or that this is the first time when I do a search.
1440 inquiry_info *devices = NULL;
1441 int i, responses, max_responses = MAX_PORTS;
1444 if (neighbours.size >= MAX_PORTS)
1446 fprintf (stderr, "%.*s reached the top limit for the discovarable devices\n", IFNAMSIZ, dev->iface);
1450 /* Get the device id */
1451 if (neighbours.dev_id == -1)
1453 char addr[19] = { 0 }; //the device MAC address
1455 ba2str ((bdaddr_t *) &dev->pl_mac, addr);
1456 neighbours.dev_id = hci_devid (addr);
1457 if (neighbours.dev_id < 0)
1459 fprintf (stderr, "Failed to get the device id for interface %.*s : %s\n", IFNAMSIZ,
1460 dev->iface, strerror (errno));
1465 devices = malloc (max_responses * sizeof (inquiry_info));
1466 if (devices == NULL)
1468 fprintf (stderr, "Failed to allocate memory for inquiry info list on interface %.*s\n", IFNAMSIZ,
1473 responses = hci_inquiry (neighbours.dev_id, 8, max_responses, NULL, &devices, IREQ_CACHE_FLUSH);
1476 fprintf (stderr, "Failed to inquiry on interface %.*s\n", IFNAMSIZ, dev->iface);
1480 fprintf (stderr, "LOG : Found %d devices\n", responses); //FIXME delete it after debugging stage
1484 fprintf (stderr, "LOG : No devices discoverable\n");
1488 for (i = 0; i < responses; i++)
1496 fprintf (stderr, "%.*s reached the top limit for the discoverable devices (after inquiry)\n", IFNAMSIZ,
1501 /* Search if the address already exists on the list */
1502 for (j = 0; j < neighbours.size; j++)
1504 if (memcmp (&(devices + i)->bdaddr, &(neighbours.devices[j]), sizeof (bdaddr_t)) == 0)
1507 fprintf (stderr, "LOG : the device already exists on the list\n"); //FIXME debugging message
1514 char addr[19] = { 0 };
1516 ba2str (&(devices +i)->bdaddr, addr);
1517 fprintf (stderr, "LOG : %s was added to the list\n", addr); //FIXME debugging message
1518 GNUNET_memcpy (&(neighbours.devices[neighbours.size++]), &(devices + i)->bdaddr, sizeof (bdaddr_t));
1526 int connection_successful = 0;
1527 struct sockaddr_rc addr_rc = { 0 };
1529 addr_rc.rc_family = AF_BLUETOOTH;
1531 /* Try to connect to a new device from the list */
1532 while (neighbours.pos < neighbours.size)
1534 /* Check if we are already connected to this device */
1535 if (neighbours.fds[neighbours.pos] == -1)
1538 memset (&addr_rc.rc_bdaddr, 0, sizeof (addr_rc.rc_bdaddr));
1539 GNUNET_memcpy (&addr_rc.rc_bdaddr, &(neighbours.devices[neighbours.pos]), sizeof (addr_rc.rc_bdaddr));
1541 addr_rc.rc_channel = get_channel (dev, addr_rc.rc_bdaddr);
1543 *sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1544 if ( (-1 < *sendsocket) &&
1545 (0 == connect (*sendsocket,
1546 (struct sockaddr *) &addr_rc,
1547 sizeof (addr_rc))) )
1549 neighbours.fds[neighbours.pos++] = *sendsocket;
1550 connection_successful = 1;
1551 char addr[19] = { 0 };
1552 ba2str (&(neighbours.devices[neighbours.pos - 1]), addr);
1553 fprintf (stderr, "LOG : Connected to %s\n", addr);
1558 char addr[19] = { 0 };
1559 errno_copy = errno; //Save a copy for later
1561 if (-1 != *sendsocket)
1563 (void) close (*sendsocket);
1566 ba2str (&(neighbours.devices[neighbours.pos]), addr);
1568 "LOG : Couldn't connect on device %s, error : %s\n",
1571 if (errno != ECONNREFUSED) //FIXME be sure that this works
1573 fprintf (stderr, "LOG : Removes %d device from the list\n", neighbours.pos);
1574 /* Remove the device from the list */
1575 GNUNET_memcpy (&neighbours.devices[neighbours.pos], &neighbours.devices[neighbours.size - 1], sizeof (bdaddr_t));
1576 memset (&neighbours.devices[neighbours.size - 1], 0, sizeof (bdaddr_t));
1577 neighbours.fds[neighbours.pos] = neighbours.fds[neighbours.size - 1];
1578 neighbours.fds[neighbours.size - 1] = -1;
1579 neighbours.size -= 1;
1582 neighbours.pos += 1;
1584 if (neighbours.pos >= neighbours.size)
1589 if (loops == MAX_LOOPS) //don't get stuck trying to connect to one device
1595 fprintf (stderr, "LOG : Search for a new device\n"); //FIXME debugging message
1596 neighbours.pos += 1;
1600 /* Cycle on the list */
1601 if (neighbours.pos == neighbours.size)
1604 searching_devices_count += 1;
1606 if (searching_devices_count == MAX_LOOPS)
1608 fprintf (stderr, "LOG : Force to inquiry for new devices\n");
1609 searching_devices_count = 0;
1610 goto inquiry_devices;
1613 /* If a new device wasn't found, search an old one */
1614 if (connection_successful == 0)
1616 int loop_check = neighbours.pos;
1617 while (neighbours.fds[neighbours.pos] == -1)
1619 if (neighbours.pos == neighbours.size)
1622 if (neighbours.pos == loop_check)
1624 if (errno_copy == ECONNREFUSED)
1626 fprintf (stderr, "LOG : No device found. Go back and search again\n"); //FIXME debugging message
1629 goto search_for_devices;
1633 return 1; // Skip the broadcast message
1637 neighbours.pos += 1;
1640 *sendsocket = neighbours.fds[neighbours.pos++];
1648 * Main function of the helper. This code accesses a bluetooth interface
1649 * forwards traffic in both directions between the bluetooth interface and
1650 * stdin/stdout of this process. Error messages are written to stderr.
1652 * @param argc number of arguments, must be 2
1653 * @param argv arguments only argument is the name of the interface (i.e. 'hci0')
1654 * @return 0 on success (never happens, as we don't return unless aborted), 1 on error
1656 **** similar to gnunet-helper-transport-wlan.c ****
1659 main (int argc, char *argv[])
1662 struct HardwareInfos dev;
1663 char readbuf[MAXLINE];
1668 struct MessageStreamTokenizer *stdin_mst;
1670 int crt_rfds = 0, rfds_list[MAX_PORTS];
1671 int broadcast, sendsocket;
1673 /* Assert privs so we can modify the firewall rules! */
1675 #ifdef HAVE_SETRESUID
1676 uid_t uid = getuid ();
1678 if (0 != setresuid (uid, 0, 0))
1681 "Failed to setresuid to root: %s\n",
1686 if (0 != seteuid (0))
1689 "Failed to seteuid back to root: %s\n", strerror (errno));
1695 /* Make use of SGID capabilities on POSIX */
1696 memset (&dev, 0, sizeof (dev));
1697 dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1698 raw_eno = errno; /* remember for later */
1700 /* Now that we've dropped root rights, we can do error checking */
1703 fprintf (stderr, "You must specify the name of the interface as the first \
1704 and only argument to this program.\n");
1705 if (-1 != dev.fd_rfcomm)
1706 (void) close (dev.fd_rfcomm);
1710 if (-1 == dev.fd_rfcomm)
1712 fprintf (stderr, "Failed to create a RFCOMM socket: %s\n", strerror (raw_eno));
1715 if (dev.fd_rfcomm >= FD_SETSIZE)
1717 fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1718 dev.fd_rfcomm, FD_SETSIZE);
1719 (void) close (dev.fd_rfcomm);
1722 if (0 != test_bluetooth_interface (argv[1]))
1724 (void) close (dev.fd_rfcomm);
1727 strncpy (dev.iface, argv[1], IFNAMSIZ);
1728 if (0 != open_device (&dev))
1730 (void) close (dev.fd_rfcomm);
1736 uid_t uid = getuid ();
1737 #ifdef HAVE_SETRESUID
1738 if (0 != setresuid (uid, uid, uid))
1740 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1741 if (-1 != dev.fd_rfcomm)
1742 (void) close (dev.fd_rfcomm);
1746 if (0 != (setuid (uid) | seteuid (uid)))
1748 fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
1749 if (-1 != dev.fd_rfcomm)
1750 (void) close (dev.fd_rfcomm);
1756 /* Send MAC address of the bluetooth interface to STDOUT first */
1758 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
1760 macmsg.hdr.size = htons (sizeof (macmsg));
1761 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
1762 GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1763 GNUNET_memcpy (write_std.buf, &macmsg, sizeof (macmsg));
1764 write_std.size = sizeof (macmsg);
1768 stdin_mst = mst_create (&stdin_send_hw, &dev);
1772 * TODO : I should make the time out of a mac endpoint smaller and check if the rate
1773 * from get_wlan_header (plugin_transport_bluetooth.c) is correct.
1782 if ((0 == write_pout.size) && (1 == stdin_open))
1784 FD_SET (STDIN_FILENO, &rfds);
1785 maxfd = MAX (maxfd, STDIN_FILENO);
1787 if (0 == write_std.size)
1789 FD_SET (dev.fd_rfcomm, &rfds);
1790 maxfd = MAX (maxfd, dev.fd_rfcomm);
1793 for (i = 0; i < crt_rfds; i++) // it can receive messages from multiple devices
1795 FD_SET (rfds_list[i], &rfds);
1796 maxfd = MAX (maxfd, rfds_list[i]);
1799 if (0 < write_std.size)
1801 FD_SET (STDOUT_FILENO, &wfds);
1802 maxfd = MAX (maxfd, STDOUT_FILENO);
1804 if (0 < write_pout.size) //it can send messages only to one device per loop
1806 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *frame;
1807 /* Get the destination address */
1808 frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) write_pout.buf;
1810 if (memcmp (&frame->addr1, &dev.pl_mac,
1811 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1814 memset (&write_pout, 0, sizeof (write_pout)); //clear the buffer
1816 else if (memcmp (&frame->addr1, &broadcast_address,
1817 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1819 fprintf (stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n", dev.iface, neighbours.pos, neighbours.size); //FIXME: debugging message
1821 if (send_broadcast(&dev, &sendsocket) != 0) //if the searching wasn't successful don't get stuck on the select stage
1824 memset (&write_pout, 0, sizeof (write_pout)); //remove the message
1825 fprintf (stderr, "LOG : Skipping the broadcast message (pos %d, size %d)\n", neighbours.pos, neighbours.size);
1829 FD_SET (sendsocket, &wfds);
1830 maxfd = MAX (maxfd, sendsocket);
1837 /* Search if the address already exists on the list */
1838 for (i = 0; i < neighbours.size; i++)
1840 if (memcmp (&frame->addr1, &(neighbours.devices[i]), sizeof (bdaddr_t)) == 0)
1843 if (neighbours.fds[i] != -1)
1845 found = 1; //save the position where it was found
1846 FD_SET (neighbours.fds[i], &wfds);
1847 maxfd = MAX (maxfd, neighbours.fds[i]);
1848 sendsocket = neighbours.fds[i];
1849 fprintf (stderr, "LOG: the address was found in the list\n");
1857 struct sockaddr_rc addr = { 0 };
1859 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,
1860 frame->addr1.mac[5], frame->addr1.mac[4], frame->addr1.mac[3],
1861 frame->addr1.mac[2], frame->addr1.mac[1], frame->addr1.mac[0]); //FIXME: debugging message
1863 sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1867 fprintf (stderr, "Failed to create a RFCOMM socket (sending stage): %s\n",
1872 GNUNET_memcpy (&addr.rc_bdaddr, &frame->addr1, sizeof (bdaddr_t));
1873 addr.rc_family = AF_BLUETOOTH;
1874 addr.rc_channel = get_channel (&dev, addr.rc_bdaddr);
1878 status = connect (sendsocket, (struct sockaddr *) &addr, sizeof (addr));
1879 if (0 != status && errno != EAGAIN)
1881 if (errno == ECONNREFUSED && tries < 2)
1883 fprintf (stderr, "LOG : %.*s failed to connect. Trying again!\n", IFNAMSIZ, dev.iface);
1887 else if (errno == EBADF)
1889 fprintf (stderr, "LOG : %s failed to connect : %s. Skip it!\n", dev.iface, strerror (errno));
1890 memset (&write_pout, 0, sizeof (write_pout));
1895 fprintf (stderr, "LOG : %s failed to connect : %s. Try again later!\n", dev.iface, strerror (errno));
1896 memset (&write_pout, 0, sizeof (write_pout));
1903 FD_SET (sendsocket, &wfds);
1904 maxfd = MAX (maxfd, sendsocket);
1905 fprintf (stderr, "LOG : Connection successful\n");
1906 if (pos != 0) // save the socket
1908 neighbours.fds[pos] = sendsocket;
1912 /* Add the new device to the discovered devices list */
1913 if (neighbours.size < MAX_PORTS)
1915 neighbours.fds[neighbours.size] = sendsocket;
1916 GNUNET_memcpy (&(neighbours.devices[neighbours.size++]), &addr.rc_bdaddr, sizeof (bdaddr_t));
1920 fprintf (stderr, "The top limit for the discovarable devices' list was reached\n");
1930 /* Select a fd which is ready for action :) */
1932 int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
1933 if ((-1 == retval) && (EINTR == errno))
1935 if (0 > retval && errno != EBADF) // we handle BADF errors later
1937 fprintf (stderr, "select failed: %s\n", strerror (errno));
1941 if (FD_ISSET (STDOUT_FILENO , &wfds))
1944 write (STDOUT_FILENO, write_std.buf + write_std.pos,
1945 write_std.size - write_std.pos);
1948 fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1951 write_std.pos += ret;
1952 if (write_std.pos == write_std.size)
1957 fprintf (stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); //FIXME: debugging message
1960 if (-1 != sendsocket)
1962 if (FD_ISSET (sendsocket , &wfds))
1964 ssize_t ret = write (sendsocket,
1965 write_pout.buf + write_std.pos,
1966 write_pout.size - write_pout.pos);
1967 if (0 > ret) //FIXME should I first check the error type?
1969 fprintf (stderr, "Failed to write to bluetooth device: %s. Closing the socket!\n",
1971 for (i = 0; i < neighbours.size; i++)
1973 if (neighbours.fds[i] == sendsocket)
1975 (void) close(sendsocket);
1976 neighbours.fds[i] = -1;
1980 /* Remove the message */
1981 memset (&write_pout.buf + write_std.pos, 0, (write_pout.size - write_pout.pos));
1982 write_pout.pos = 0 ;
1983 write_pout.size = 0;
1987 write_pout.pos += ret;
1988 if ((write_pout.pos != write_pout.size) && (0 != ret))
1990 /* We should not get partial sends with packet-oriented devices... */
1991 fprintf (stderr, "Write error, partial send: %u/%u\n",
1992 (unsigned int) write_pout.pos,
1993 (unsigned int) write_pout.size);
1997 if (write_pout.pos == write_pout.size)
2000 write_pout.size = 0;
2002 fprintf (stderr, "LOG : %s sends a message to a DEVICE\n", dev.iface); //FIXME: debugging message
2006 for (i = 0; i <= maxfd; i++)
2008 if (FD_ISSET (i, &rfds))
2010 if (i == STDIN_FILENO)
2013 read (i, readbuf, sizeof (readbuf));
2017 "Read error from STDIN: %s\n",
2023 /* stop reading... */
2028 mst_receive (stdin_mst, readbuf, ret);
2029 fprintf (stderr, "LOG : %s receives a message from STDIN\n", dev.iface); //FIXME: debugging message
2032 else if (i == dev.fd_rfcomm)
2035 struct sockaddr_rc addr = { 0 };
2036 unsigned int opt = sizeof (addr);
2038 readsocket = accept (dev.fd_rfcomm, (struct sockaddr *) &addr, &opt);
2039 fprintf(stderr, "LOG : %s accepts a message\n", dev.iface); //FIXME: debugging message
2040 if (readsocket == -1)
2042 fprintf (stderr, "Failed to accept a connection on interface: %.*s\n", IFNAMSIZ,
2048 FD_SET (readsocket, &rfds);
2049 maxfd = MAX (maxfd, readsocket);
2051 if (crt_rfds < MAX_PORTS)
2052 rfds_list[crt_rfds++] = readsocket;
2055 fprintf (stderr, "The limit for the read file descriptors list was \
2064 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
2066 fprintf (stderr, "LOG : %s reads something from the socket\n", dev.iface);//FIXME : debugging message
2067 rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
2069 read_from_the_socket ((void *)&i, (unsigned char *) &rrm->frame,
2070 sizeof (write_std.buf)
2071 - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2072 + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2079 /* Remove the socket from the list */
2080 for (j = 0; j < crt_rfds; j++)
2082 if (rfds_list[j] == i)
2084 rfds_list[j] ^= rfds_list[crt_rfds - 1];
2085 rfds_list[crt_rfds - 1] ^= rfds_list[j];
2086 rfds_list[j] ^= rfds_list[crt_rfds - 1];
2092 fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
2095 if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2097 write_std.size = ret
2098 + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2099 - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2100 rrm->header.size = htons (write_std.size);
2101 rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2108 /* Error handling, try to clean up a bit at least */
2109 mst_destroy (stdin_mst);
2111 sdp_close (dev.session);
2112 (void) close (dev.fd_rfcomm);
2113 if (-1 != sendsocket)
2114 (void) close (sendsocket);
2116 for (i = 0; i < crt_rfds; i++)
2117 (void) close (rfds_list[i]);
2119 for (i = 0; i < neighbours.size; i++)
2120 (void) close (neighbours.fds[i]);
2122 struct HardwareInfos dev;
2123 struct GNUNET_NETWORK_Handle *sendsocket;
2124 struct GNUNET_NETWORK_FDSet *rfds;
2125 struct GNUNET_NETWORK_FDSet *wfds;
2126 struct GNUNET_NETWORK_Handle *rfds_list[MAX_PORTS];
2127 char readbuf[MAXLINE] = { 0 };
2128 SOCKADDR_BTH acc_addr = { 0 };
2129 int addr_len = sizeof (SOCKADDR_BTH);
2130 int broadcast, i, stdin_open, crt_rfds = 0;
2131 HANDLE stdin_handle = GetStdHandle (STD_INPUT_HANDLE);
2132 HANDLE stdout_handle = GetStdHandle (STD_OUTPUT_HANDLE);
2133 struct MessageStreamTokenizer *stdin_mst;
2135 /* check the handles */
2136 if (stdin_handle == INVALID_HANDLE_VALUE)
2138 fprintf (stderr, "Failed to get the stdin handle\n");
2142 if (stdout_handle == INVALID_HANDLE_VALUE)
2144 fprintf (stderr, "Failed to get the stdout handle\n");
2148 /* initialize windows sockets */
2149 initialize_windows_sockets();
2151 // /* test bluetooth socket family support */ --> it return false because the GNUNET_NETWORK_test_pf should also receive the type of socket (BTHPROTO_RFCOMM)
2152 // if (GNUNET_NETWORK_test_pf (AF_BTH) != GNUNET_OK)
2154 // fprintf (stderr, "AF_BTH family is not supported\n");
2158 /* create the socket */
2159 dev.handle = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
2160 if (dev.handle == NULL)
2162 fprintf (stderr, "Failed to create RFCOMM socket: ");
2168 if (open_device (&dev) == -1)
2170 fprintf (stderr, "Failed to open the device\n");
2172 if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
2174 fprintf (stderr, "Failed to close the socket!\n");
2180 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (dev.handle, 1) )
2182 fprintf (stderr, "Failed to change the socket mode\n");
2186 memset (&write_std, 0, sizeof (write_std));
2187 memset (&write_pout, 0, sizeof (write_pout));
2190 rfds = GNUNET_NETWORK_fdset_create ();
2191 wfds = GNUNET_NETWORK_fdset_create ();
2193 /* Send MAC address of the bluetooth interface to STDOUT first */
2195 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
2197 macmsg.hdr.size = htons (sizeof (macmsg));
2198 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
2199 GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy));
2200 GNUNET_memcpy (write_std.buf, &macmsg, sizeof (macmsg));
2201 write_std.size = sizeof (macmsg);
2205 stdin_mst = mst_create (&stdin_send_hw, &dev);
2210 int stdout_pos = -1;
2217 sendsocket = NULL; //FIXME ???memleaks
2219 GNUNET_NETWORK_fdset_zero (rfds);
2220 if ((0 == write_pout.size) && (1 == stdin_open))
2224 GNUNET_NETWORK_fdset_handle_set (rfds, (struct GNUNET_DISK_FileHandle*) &stdin_handle);
2227 if (0 == write_std.size)
2230 GNUNET_NETWORK_fdset_set (rfds, dev.handle);
2233 for (i = 0; i < crt_rfds; i++)
2236 GNUNET_NETWORK_fdset_set (rfds, rfds_list[i]);
2239 GNUNET_NETWORK_fdset_zero (wfds);
2240 if (0 < write_std.size)
2243 GNUNET_NETWORK_fdset_handle_set (wfds, (struct GNUNET_DISK_FileHandle*) &stdout_handle);
2244 // printf ("%s\n", write_std.buf);
2245 // memset (write_std.buf, 0, write_std.size);
2246 // write_std.size = 0;
2249 if (0 < write_pout.size)
2251 if (strcmp (argv[1], "ff:ff:ff:ff:ff:ff") == 0) {
2252 fprintf(stderr, "LOG: BROADCAST! Skipping the message\n");
2255 memset (write_pout.buf, 0, write_pout.size);
2256 write_pout.size = 0;
2261 fprintf (stderr, "LOG : has a new message for %s\n", argv[1]);
2262 sendsocket = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
2264 if (sendsocket == NULL)
2266 fprintf (stderr, "Failed to create RFCOMM socket: \n");
2271 memset (&addr, 0, sizeof (addr));
2272 //addr.addressFamily = AF_BTH;
2274 WSAStringToAddress (argv[1], AF_BTH, NULL, (LPSOCKADDR) &addr, &addr_len))
2276 fprintf (stderr, "Failed to translate the address: ");
2280 addr.port = get_channel (argv[1]);
2281 if (addr.port == -1)
2283 fprintf (stderr, "Couldn't find the sdp service for the address: %s\n", argv[1]);
2284 memset (write_pout.buf, 0, write_pout.size);
2285 write_pout.size = 0;
2286 broadcast = 1; //skipping the select part
2290 if (GNUNET_OK != GNUNET_NETWORK_socket_connect (sendsocket, (LPSOCKADDR)&addr, addr_len))
2292 fprintf (stderr, "Failed to connect: ");
2297 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (sendsocket, 1) )
2299 fprintf (stderr, "Failed to change the socket mode\n");
2303 GNUNET_NETWORK_fdset_set (wfds, sendsocket);
2310 int retval = GNUNET_NETWORK_socket_select (rfds, wfds, NULL, GNUNET_TIME_relative_get_forever_());
2313 fprintf (stderr, "Select error\n");
2316 //if (GNUNET_NETWORK_fdset_isset (wfds, (struct GNUNET_NETWORK_Handle*)&stdout_handle))
2317 if (retval == stdout_pos)
2319 fprintf(stderr, "LOG : sends a message to STDOUT\n"); //FIXME: debugging message
2321 //ret = GNUNET_NETWORK_socket_send ((struct GNUNET_NETWORK_Handle *)&stdout_handle, write_std.buf + write_std.pos, write_std.size - write_std.pos);
2322 //ret = write (STDOUT_FILENO, write_std.buf + write_std.pos, write_std.size - write_std.pos);
2324 if (FALSE == WriteFile (stdout_handle, write_std.buf + write_std.pos, write_std.size - write_std.pos, &ret, NULL))
2326 fprintf (stderr, "Failed to write to STDOUT: ");
2333 fprintf (stderr, "Failed to write to STDOUT\n");
2337 write_std.pos += ret;
2338 if (write_std.pos == write_std.size)
2344 if (sendsocket != NULL)
2346 if (GNUNET_NETWORK_fdset_isset (wfds, sendsocket))
2349 ret = GNUNET_NETWORK_socket_send (sendsocket, write_pout.buf + write_pout.pos,
2350 write_pout.size - write_pout.pos);
2352 if (GNUNET_SYSERR == ret)
2354 fprintf (stderr, "Failed to send to the socket. Closing the socket. Error: \n");
2356 if (GNUNET_NETWORK_socket_close (sendsocket) != GNUNET_OK)
2358 fprintf (stderr, "Failed to close the sendsocket!\n");
2365 write_pout.pos += ret;
2366 if ((write_pout.pos != write_pout.size) && (0 != ret))
2368 /* we should not get partial sends with packet-oriented devices... */
2369 fprintf (stderr, "Write error, partial send: %u/%u\n",
2370 (unsigned int) write_pout.pos,
2371 (unsigned int) write_pout.size);
2375 if (write_pout.pos == write_pout.size)
2378 write_pout.size = 0;
2381 fprintf(stderr, "LOG : sends a message to a DEVICE\n"); //FIXME: debugging message
2386 //if (GNUNET_NETWORK_fdset_isset (rfds, (struct GNUNET_NETWORK_Handle*)&stdin_handle))
2387 if (retval == stdin_pos)
2390 //ret = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)&stdin_handle, readbuf, sizeof (write_pout.buf));
2391 //ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
2393 if (FALSE == ReadFile (stdin_handle, readbuf, sizeof (readbuf), &ret, NULL)) /* do nothing asynchronous */
2395 fprintf (stderr, "Read error from STDIN: ");
2401 /* stop reading... */
2404 mst_receive (stdin_mst, readbuf, ret);
2405 fprintf (stderr, "LOG : receives a message from STDIN\n"); //FIXME: debugging message
2409 if (GNUNET_NETWORK_fdset_isset (rfds, dev.handle))
2411 fprintf (stderr, "LOG: accepting connection\n");
2412 struct GNUNET_NETWORK_Handle *readsocket;
2413 readsocket = GNUNET_NETWORK_socket_accept (dev.handle, (LPSOCKADDR)&acc_addr, &addr_len);
2414 if (readsocket == NULL)
2416 fprintf (stderr, "Accept error %d: ", GetLastError());
2422 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (readsocket, 1) )
2424 fprintf (stderr, "Failed to change the socket mode\n");
2427 GNUNET_NETWORK_fdset_set (rfds, readsocket);
2429 if (crt_rfds < MAX_PORTS)
2430 rfds_list[crt_rfds++] = readsocket;
2433 fprintf (stderr, "The limit for the read file descriptors list was reached\n");
2439 for (i = 0; i < crt_rfds; i++)
2441 if (GNUNET_NETWORK_fdset_isset (rfds, rfds_list[i]))
2443 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
2445 fprintf (stderr, "LOG: reading something from the socket\n");//FIXME : debugging message
2446 rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
2447 ret = read_from_the_socket (rfds_list[i], (unsigned char *) &rrm->frame,
2448 sizeof (write_std.buf)
2449 - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2450 + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2455 //TODO remove the socket from the list
2456 if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2458 fprintf (stderr, "Failed to close the sendsocket!\n");
2462 fprintf (stderr, "Read error from raw socket: ");
2467 if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2469 write_std.size = ret
2470 + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2471 - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2472 rrm->header.size = htons (write_std.size);
2473 rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2481 mst_destroy (stdin_mst);
2484 if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
2486 fprintf (stderr, "Failed to close the socket!\n");
2490 for (i = 0; i < crt_rfds; i++)
2492 if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2494 fprintf (stderr, "Failed to close the socket!\n");
2501 return 1; /* we never exit 'normally' */