2 This file is part of GNUnet.
3 Copyright (C) 2010, 2011, 2012 GNUnet e.V.
4 Copyright (c) 2007, 2008, Andy Green <andy@warmcat.com>
5 Copyright Copyright (C) 2009 Thomas d'Otreppe
7 GNUnet is free software: you can redistribute it and/or modify it
8 under the terms of the GNU Affero General Public License as published
9 by the Free Software Foundation, either version 3 of the License,
10 or (at your option) any later version.
12 GNUnet is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 Affero General Public License for more details.
17 You should have received a copy of the GNU Affero General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
20 #include "gnunet_config.h"
24 #include "gnunet_util_lib.h"
29 #include <bluetooth/bluetooth.h>
30 #include <bluetooth/hci.h>
31 #include <bluetooth/hci_lib.h>
32 #include <bluetooth/rfcomm.h>
33 #include <bluetooth/sdp.h>
34 #include <bluetooth/sdp_lib.h>
39 #include <sys/ioctl.h>
40 #include <sys/param.h>
41 #include <sys/socket.h>
43 #include <sys/types.h>
47 #include "plugin_transport_wlan.h"
48 #include "gnunet_protocols.h"
52 * Maximum number of ports assignable for RFCOMMM protocol.
57 * Maximum size of a message allowed in either direction
58 * (used for our receive and sent buffers).
64 * Maximum number of loops without inquiring for new devices.
69 /* Maximum size of the interface's name */
76 * A copy of the MAC Address.
78 struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy
80 UINT8 mac[MAC_ADDR_SIZE];
84 * The UUID used for the SDP service.
85 * {31191E56-FA7E-4517-870E-71B86BBCC52F}
87 #define GNUNET_BLUETOOTH_SDP_UUID \
89 0x31, 0x19, 0x1E, 0x56, \
93 0x71, 0xB8, 0x6B, 0xBC, 0xC5, 0x2F \
98 * In bluez library, the maximum name length of a device is 8
100 #define BLUEZ_DEVNAME_SIZE 8
103 * struct for storing the information of the hardware. There is only
109 * Name of the interface, not necessarily 0-terminated (!).
111 char iface[IFNAMSIZ];
117 struct GNUNET_NETWORK_Handle *handle;
120 * MAC address of our own bluetooth interface.
122 struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy pl_mac;
125 * file descriptor for the rfcomm socket
130 * MAC address of our own bluetooth interface.
132 struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac;
137 sdp_session_t *session ;
142 * IO buffer used for buffering data in transit (to wireless or to stdout).
147 * How many bytes of data are stored in 'buf' for transmission right now?
148 * Data always starts at offset 0 and extends to 'size'.
153 * How many bytes that were stored in 'buf' did we already write to the
154 * destination? Always smaller than 'size'.
159 * Buffered data; twice the maximum allowed message size as we add some
162 char buf[MAXLINE * 2];
167 * Devices buffer used to keep a list with all the discoverable devices in
168 * order to send them HELLO messages one by one when it receive a broadcast message.
170 struct BroadcastMessages
172 /* List with the discoverable devices' addresses */
173 bdaddr_t devices[MAX_PORTS];
175 /* List with the open sockets */
179 /* The number of the devices */
182 /* The current position */
190 * Address used to identify the broadcast messages.
192 static struct GNUNET_TRANSPORT_WLAN_MacAddress broadcast_address = {{255, 255, 255, 255, 255, 255}};
195 * Buffer with the discoverable devices.
197 static struct BroadcastMessages neighbours;
199 static int searching_devices_count = 0;
203 * Buffer for data read from stdin to be transmitted to the bluetooth device
205 static struct SendBuffer write_pout;
208 * Buffer for data read from the bluetooth device to be transmitted to stdout.
210 static struct SendBuffer write_std;
213 /* ****** this are the same functions as the ones used in gnunet-helper-transport-wlan.c ****** */
216 * To what multiple do we align messages? 8 byte should suffice for everyone
219 #define ALIGN_FACTOR 8
222 * Smallest supported message.
224 #define MIN_BUFFER_SIZE sizeof (struct GNUNET_MessageHeader)
228 * Functions with this signature are called whenever a
229 * complete message is received by the tokenizer.
232 * @param message the actual message
234 typedef void (*MessageTokenizerCallback) (void *cls,
236 GNUNET_MessageHeader *
240 * Handle to a message stream tokenizer.
242 struct MessageStreamTokenizer
246 * Function to call on completed messages.
248 MessageTokenizerCallback cb;
256 * Size of the buffer (starting at 'hdr').
261 * How many bytes in buffer have we already processed?
266 * How many bytes in buffer are valid right now?
271 * Beginning of the buffer. Typed like this to force alignment.
273 struct GNUNET_MessageHeader *hdr;
279 * Create a message stream tokenizer.
281 * @param cb function to call on completed messages
282 * @param cb_cls closure for cb
283 * @return handle to tokenizer
285 static struct MessageStreamTokenizer *
286 mst_create (MessageTokenizerCallback cb,
289 struct MessageStreamTokenizer *ret;
291 ret = malloc (sizeof (struct MessageStreamTokenizer));
294 fprintf (stderr, "Failed to allocate buffer for tokenizer\n");
297 ret->hdr = malloc (MIN_BUFFER_SIZE);
298 if (NULL == ret->hdr)
300 fprintf (stderr, "Failed to allocate buffer for alignment\n");
303 ret->curr_buf = MIN_BUFFER_SIZE;
305 ret->cb_cls = cb_cls;
313 * Add incoming data to the receive buffer and call the
314 * callback for all complete messages.
316 * @param mst tokenizer to use
317 * @param buf input data to add
318 * @param size number of bytes in buf
319 * @return GNUNET_OK if we are done processing (need more data)
320 * GNUNET_SYSERR if the data stream is corrupt
323 mst_receive (struct MessageStreamTokenizer *mst,
324 const char *buf, size_t size)
326 const struct GNUNET_MessageHeader *hdr;
331 unsigned long offset;
335 ibuf = (char *) mst->hdr;
339 if (mst->pos < mst->off)
341 //fprintf (stderr, "We processed too many bytes!\n");
342 return GNUNET_SYSERR;
344 if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) ||
345 (0 != (mst->off % ALIGN_FACTOR)))
347 /* need to align or need more space */
348 mst->pos -= mst->off;
349 memmove (ibuf, &ibuf[mst->off], mst->pos);
352 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
355 GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) -
356 (mst->pos - mst->off), size);
357 GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
362 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
364 //FIXME should I reset ??
369 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
370 want = ntohs (hdr->size);
371 if (want < sizeof (struct GNUNET_MessageHeader))
374 "Received invalid message from stdin\n");
375 return GNUNET_SYSERR;
377 if ((mst->curr_buf - mst->off < want) &&
380 /* need more space */
381 mst->pos -= mst->off;
382 memmove (ibuf, &ibuf[mst->off], mst->pos);
385 if (want > mst->curr_buf)
389 fprintf (stderr, "Error! We should proceeded 0 bytes\n");
390 return GNUNET_SYSERR;
392 mst->hdr = realloc (mst->hdr, want);
393 if (NULL == mst->hdr)
395 fprintf (stderr, "Failed to allocate buffer for alignment\n");
398 ibuf = (char *) mst->hdr;
399 mst->curr_buf = want;
401 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
402 if (mst->pos - mst->off < want)
404 delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
405 if (mst->pos + delta > mst->curr_buf)
407 fprintf (stderr, "The size of the buffer will be exceeded!\n");
408 return GNUNET_SYSERR;
410 GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
415 if (mst->pos - mst->off < want)
417 //FIXME should I use this?
422 mst->cb (mst->cb_cls, hdr);
424 if (mst->off == mst->pos)
426 /* reset to beginning of buffer, it's free right now! */
433 fprintf (stderr, "There should some valid bytes in the buffer on this stage\n");
434 return GNUNET_SYSERR;
438 if (size < sizeof (struct GNUNET_MessageHeader))
440 offset = (unsigned long) buf;
441 need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
442 if (GNUNET_NO == need_align)
444 /* can try to do zero-copy and process directly from original buffer */
445 hdr = (const struct GNUNET_MessageHeader *) buf;
446 want = ntohs (hdr->size);
447 if (want < sizeof (struct GNUNET_MessageHeader))
450 "Received invalid message from stdin\n");
453 return GNUNET_SYSERR;
456 break; /* or not, buffer incomplete, so copy to private buffer... */
457 mst->cb (mst->cb_cls, hdr);
463 /* need to copy to private buffer to align;
464 * yes, we go a bit more spagetti than usual here */
470 if (size + mst->pos > mst->curr_buf)
472 mst->hdr = realloc (mst->hdr, size + mst->pos);
473 if (NULL == mst->hdr)
475 fprintf (stderr, "Failed to allocate buffer for alignment\n");
478 ibuf = (char *) mst->hdr;
479 mst->curr_buf = size + mst->pos;
481 if (mst->pos + size > mst->curr_buf)
484 "Assertion failed\n");
487 GNUNET_memcpy (&ibuf[mst->pos], buf, size);
494 * Destroys a tokenizer.
496 * @param mst tokenizer to destroy
499 mst_destroy (struct MessageStreamTokenizer *mst)
506 * Calculate crc32, the start of the calculation
508 * @param buf buffer to calc the crc
509 * @param len len of the buffer
513 calc_crc_osdep (const unsigned char *buf, size_t len)
515 static const unsigned long int crc_tbl_osdep[256] = {
516 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
517 0xE963A535, 0x9E6495A3,
518 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
519 0xE7B82D07, 0x90BF1D91,
520 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
521 0xF4D4B551, 0x83D385C7,
522 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
523 0xFA0F3D63, 0x8D080DF5,
524 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
525 0xD20D85FD, 0xA50AB56B,
526 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
527 0xDCD60DCF, 0xABD13D59,
528 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
529 0xCFBA9599, 0xB8BDA50F,
530 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
531 0xC1611DAB, 0xB6662D3D,
532 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
533 0x9FBFE4A5, 0xE8B8D433,
534 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
535 0x91646C97, 0xE6635C01,
536 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
537 0x8208F4C1, 0xF50FC457,
538 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
539 0x8CD37CF3, 0xFBD44C65,
540 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
541 0xA4D1C46D, 0xD3D6F4FB,
542 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
543 0xAA0A4C5F, 0xDD0D7CC9,
544 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
545 0xB966D409, 0xCE61E49F,
546 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
547 0xB7BD5C3B, 0xC0BA6CAD,
548 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
549 0x04DB2615, 0x73DC1683,
550 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
551 0x0A00AE27, 0x7D079EB1,
552 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
553 0x196C3671, 0x6E6B06E7,
554 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
555 0x17B7BE43, 0x60B08ED5,
556 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
557 0x3FB506DD, 0x48B2364B,
558 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
559 0x316E8EEF, 0x4669BE79,
560 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
561 0x220216B9, 0x5505262F,
562 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
563 0x2CD99E8B, 0x5BDEAE1D,
564 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
565 0x72076785, 0x05005713,
566 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
567 0x7CDCEFB7, 0x0BDBDF21,
568 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
569 0x6FB077E1, 0x18B74777,
570 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
571 0x616BFFD3, 0x166CCF45,
572 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
573 0x4969474D, 0x3E6E77DB,
574 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
575 0x47B2CF7F, 0x30B5FFE9,
576 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
577 0x54DE5729, 0x23D967BF,
578 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
579 0x5A05DF1B, 0x2D02EF8D
582 unsigned long crc = 0xFFFFFFFF;
584 for (; len > 0; len--, buf++)
585 crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
591 * Calculate and check crc of the bluetooth packet
593 * @param buf buffer of the packet, with len + 4 bytes of data,
594 * the last 4 bytes being the checksum
595 * @param len length of the payload in data
596 * @return 0 on success (checksum matches), 1 on error
599 check_crc_buf_osdep (const unsigned char *buf, size_t len)
603 crc = calc_crc_osdep (buf, len);
605 if (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
606 ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3])
613 /* ************** end of clone ***************** */
617 * Function used to get the code of last error and to print the type of error.
622 LPVOID lpMsgBuf = NULL;
624 if (FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
625 NULL, GetLastError(), 0, (LPTSTR) &lpMsgBuf, 0, NULL))
626 fprintf (stderr, "%s\n", (char *)lpMsgBuf);
628 fprintf (stderr, "Failed to format the message for the last error! Error number : %d\n", GetLastError());
632 * Function used to initialize the Windows Sockets
635 initialize_windows_sockets()
638 WORD wVersionRequested = MAKEWORD (2, 0);
639 if (WSAStartup (wVersionRequested, &wsaData) != NO_ERROR)
641 fprintf (stderr , "Error initializing window sockets!\n");
648 * Function used to convert the GUID.
649 * @param bytes the GUID represented as a char array
650 * @param uuid pointer to the GUID
653 convert_guid(char *bytes, GUID * uuid)
656 uuid->Data1 = ((bytes[0] << 24) & 0xff000000) | ((bytes[1] << 16) & 0x00ff0000) | ((bytes[2] << 8) & 0x0000ff00) | (bytes[3] & 0x000000ff);
657 uuid->Data2 = ((bytes[4] << 8) & 0xff00) | (bytes[5] & 0x00ff);
658 uuid->Data3 = ((bytes[6] << 8) & 0xff00) | (bytes[7] & 0x00ff);
660 for (i = 0; i < 8; i++)
662 uuid->Data4[i] = bytes[i + 8];
669 * Function for assigning a port number
671 * @param socket the socket used to bind
672 * @param addr pointer to the rfcomm address
673 * @return 0 on success
676 bind_socket (int socket, struct sockaddr_rc *addr)
680 /* Bind every possible port (from 0 to 30) and stop when binding doesn't fail */
681 //FIXME : it should start from port 1, but on my computer it doesn't work :)
682 for (port = 3; port <= 30; port++)
684 addr->rc_channel = port;
685 status = bind (socket, (struct sockaddr *) addr, sizeof (struct sockaddr_rc));
696 * Function used for creating the service record and registering it.
698 * @param dev pointer to the device struct
699 * @return 0 on success
702 register_service (struct HardwareInfos *dev)
704 /* advertise the service */
705 CSADDR_INFO addr_info;
708 unsigned char uuid[] = GNUNET_BLUETOOTH_SDP_UUID;
710 int addr_len = sizeof (SOCKADDR_BTH);
712 /* get the port on which we are listening on */
713 memset (& addr, 0, sizeof (SOCKADDR_BTH));
714 fd = GNUNET_NETWORK_get_fd (dev->handle);
717 fprintf (stderr, "Failed to get the file descriptor\n");
720 if (SOCKET_ERROR == getsockname (fd, (SOCKADDR*)&addr, &addr_len))
722 fprintf (stderr, "Failed to get the port on which we are listening on: \n");
727 /* save the device address */
728 GNUNET_memcpy (&dev->pl_mac, &addr.btAddr, sizeof (BTH_ADDR));
730 /* set the address information */
731 memset (&addr_info, 0, sizeof (CSADDR_INFO));
732 addr_info.iProtocol = BTHPROTO_RFCOMM;
733 addr_info.iSocketType = SOCK_STREAM;
734 addr_info.LocalAddr.lpSockaddr = (LPSOCKADDR)&addr;
735 addr_info.LocalAddr.iSockaddrLength = sizeof (addr);
736 addr_info.RemoteAddr.lpSockaddr = (LPSOCKADDR)&addr;
737 addr_info.RemoteAddr.iSockaddrLength = sizeof (addr);
739 convert_guid((char *) uuid, &guid);
741 /* register the service */
742 memset (&wqs, 0, sizeof (WSAQUERYSET));
743 wqs.dwSize = sizeof (WSAQUERYSET);
744 wqs.dwNameSpace = NS_BTH;
745 wqs.lpszServiceInstanceName = "GNUnet Bluetooth Service";
746 wqs.lpszComment = "This is the service used by the GNUnnet plugin transport";
747 wqs.lpServiceClassId = &guid;
748 wqs.dwNumberOfCsAddrs = 1;
749 wqs.lpcsaBuffer = &addr_info ;
752 if (SOCKET_ERROR == WSASetService (&wqs , RNRSERVICE_REGISTER, 0))
754 fprintf (stderr, "Failed to register the SDP service: ");
760 fprintf (stderr, "The SDP service was registered\n");
767 * Function used for creating the service record and registering it.
769 * @param dev pointer to the device struct
770 * @param rc_channel the rfcomm channel
771 * @return 0 on success
774 register_service (struct HardwareInfos *dev, int rc_channel)
778 * 2. set the service ID, class, profile information
779 * 3. make the service record publicly browsable
780 * 4. register the RFCOMM channel
781 * 5. set the name, provider and description
782 * 6. register the service record to the local SDP server
785 uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
786 dev->pl_mac.mac[5], dev->pl_mac.mac[4], dev->pl_mac.mac[3],
787 dev->pl_mac.mac[2], dev->pl_mac.mac[1], dev->pl_mac.mac[0]};
788 const char *service_dsc = "Bluetooth plugin services";
789 const char *service_prov = "GNUnet provider";
790 uuid_t root_uuid, rfcomm_uuid, svc_uuid;
791 sdp_list_t *root_list = 0, *rfcomm_list = 0, *proto_list = 0,
792 *access_proto_list = 0, *svc_list = 0;
793 sdp_record_t *record = 0;
794 sdp_data_t *channel = 0;
796 record = sdp_record_alloc();
798 /* Set the general service ID */
799 sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
800 svc_list = sdp_list_append (0, &svc_uuid);
801 sdp_set_service_classes (record, svc_list);
802 sdp_set_service_id (record, svc_uuid);
804 /* Make the service record publicly browsable */
805 sdp_uuid16_create (&root_uuid, PUBLIC_BROWSE_GROUP);
806 root_list = sdp_list_append (0, &root_uuid);
807 sdp_set_browse_groups (record, root_list);
809 /* Register the RFCOMM channel */
810 sdp_uuid16_create (&rfcomm_uuid, RFCOMM_UUID);
811 channel = sdp_data_alloc (SDP_UINT8, &rc_channel);
812 rfcomm_list = sdp_list_append (0, &rfcomm_uuid);
813 sdp_list_append (rfcomm_list, channel);
814 proto_list = sdp_list_append (0, rfcomm_list);
816 /* Set protocol information */
817 access_proto_list = sdp_list_append (0, proto_list);
818 sdp_set_access_protos (record, access_proto_list);
820 /* Set the name, provider, and description */
821 sdp_set_info_attr (record, dev->iface, service_prov, service_dsc);
823 /* Connect to the local SDP server */
824 dev->session = sdp_connect (BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
828 fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
829 IFNAMSIZ, dev->iface, strerror (errno));
834 /* Register the service record */
835 if (sdp_record_register (dev->session, record, 0) < 0)
837 fprintf (stderr, "Failed to register a service record on interface `%.*s': %s\n",
838 IFNAMSIZ, dev->iface, strerror (errno));
844 sdp_data_free (channel);
845 sdp_list_free (root_list, 0);
846 sdp_list_free (rfcomm_list, 0);
847 sdp_list_free (proto_list, 0);
848 sdp_list_free (access_proto_list, 0);
849 sdp_list_free (svc_list, 0);
850 sdp_record_free (record);
858 * Function for searching and browsing for a service. This will return the
859 * port number on which the service is running.
861 * @param dest target address
865 get_channel(const char *dest)
869 DWORD wqs_len = sizeof (WSAQUERYSET);
873 unsigned char uuid[] = GNUNET_BLUETOOTH_SDP_UUID;
874 convert_guid ((char *) uuid, &guid);
876 wqs = (WSAQUERYSET*)malloc (wqs_len);
877 ZeroMemory (wqs, wqs_len);
879 wqs->dwSize = sizeof (WSAQUERYSET) ;
880 wqs->lpServiceClassId = &guid;
881 wqs->dwNameSpace = NS_BTH;
882 wqs->dwNumberOfCsAddrs = 0;
883 wqs->lpszContext = (LPSTR)dest;
885 if (SOCKET_ERROR == WSALookupServiceBegin (wqs, LUP_FLUSHCACHE | LUP_RETURN_ALL, &h))
887 if (GetLastError() == WSASERVICE_NOT_FOUND)
889 fprintf (stderr, "WARNING! The device with address %s wasn't found. Skipping the message!", dest);
894 fprintf (stderr, "Failed to find the port number: ");
901 /* search the sdp service */
904 if (SOCKET_ERROR == WSALookupServiceNext (h, LUP_FLUSHCACHE | LUP_RETURN_ALL, &wqs_len, wqs))
906 int error = WSAGetLastError();
912 wqs = (WSAQUERYSET*)malloc (wqs_len);
915 fprintf (stderr, "Failed! The address was valid but there was no data record of requested type\n");
922 fprintf (stderr, "Failed to look over the services: ");
924 WSALookupServiceEnd (h);
930 channel = ((SOCKADDR_BTH*)wqs->lpcsaBuffer->RemoteAddr.lpSockaddr)->port;
935 WSALookupServiceEnd (h);
941 * Function used for searching and browsing for a service. This will return the
942 * port number on which the service is running.
944 * @param dev pointer to the device struct
945 * @param dest target address
949 get_channel(struct HardwareInfos *dev, bdaddr_t dest)
952 * 1. detect all nearby devices
953 * 2. for each device:
954 * 2.1. connect to the SDP server running
955 * 2.2. get a list of service records with the specific UUID
956 * 2.3. for each service record get a list of the protocol sequences and get
959 uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
960 dest.b[5], dest.b[4], dest.b[3],
961 dest.b[2], dest.b[1], dest.b[0]};
962 sdp_session_t *session = 0;
963 sdp_list_t *search_list = 0, *attrid_list = 0, *response_list = 0, *it = 0;
965 uint32_t range = 0x0000ffff;
968 /* Connect to the local SDP server */
969 session = sdp_connect (BDADDR_ANY, &dest, 0);
972 fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
973 IFNAMSIZ, dev->iface, strerror (errno));
977 sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
978 search_list = sdp_list_append (0, &svc_uuid);
979 attrid_list = sdp_list_append (0, &range);
981 if (sdp_service_search_attr_req (session, search_list,
982 SDP_ATTR_REQ_RANGE, attrid_list, &response_list) == 0)
984 for (it = response_list; it; it = it->next)
986 sdp_record_t *record = (sdp_record_t*) it->data;
987 sdp_list_t *proto_list = 0;
988 if (sdp_get_access_protos (record, &proto_list) == 0)
990 channel = sdp_get_proto_port (proto_list, RFCOMM_UUID);
991 sdp_list_free (proto_list, 0);
993 sdp_record_free (record);
997 sdp_list_free (search_list, 0);
998 sdp_list_free (attrid_list, 0);
999 sdp_list_free (response_list, 0);
1001 sdp_close (session);
1005 "Failed to find the listening channel for interface `%.*s': %s\n",
1015 * Read from the socket and put the result into the buffer for transmission to 'stdout'.
1017 * @param sock file descriptor for reading
1018 * @param buf buffer to read to; first bytes will be the 'struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame',
1019 * followed by the actual payload
1020 * @param buf_size size of the buffer
1021 * @param ri where to write radiotap_rx info
1022 * @return number of bytes written to 'buf'
1025 read_from_the_socket (void *sock,
1026 unsigned char *buf, size_t buf_size,
1027 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri)
1029 unsigned char tmpbuf[buf_size];
1033 count = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)sock, tmpbuf, buf_size);
1035 count = read (*((int *)sock), tmpbuf, buf_size);
1040 if (EAGAIN == errno)
1045 fprintf (stderr, "Failed to read from the HCI socket: %s\n", strerror (errno));
1052 /* Get the channel used */
1054 struct sockaddr_rc rc_addr = { 0 };
1056 memset (&rc_addr, 0, sizeof (rc_addr));
1057 len = sizeof (rc_addr);
1058 if (0 > getsockname (*((int *)sock), (struct sockaddr *) &rc_addr, (socklen_t *) &len))
1060 fprintf (stderr, "getsockname() call failed : %s\n", strerror (errno));
1064 memset (ri, 0, sizeof (*ri));
1065 ri->ri_channel = rc_addr.rc_channel;
1068 /* Detect CRC32 at the end */
1069 if (0 == check_crc_buf_osdep (tmpbuf, count - sizeof (uint32_t)))
1071 count -= sizeof(uint32_t);
1074 GNUNET_memcpy (buf, tmpbuf, count);
1081 * Open the bluetooth interface for reading/writing
1083 * @param dev pointer to the device struct
1084 * @return 0 on success, non-zero on error
1087 open_device (struct HardwareInfos *dev)
1092 /* bind the RFCOMM socket to the interface */
1093 addr.addressFamily = AF_BTH;
1095 addr.port = BT_PORT_ANY;
1098 GNUNET_NETWORK_socket_bind (dev->handle, (const SOCKADDR*)&addr, sizeof (SOCKADDR_BTH)))
1100 fprintf (stderr, "Failed to bind the socket: ");
1101 if (GetLastError() == WSAENETDOWN)
1103 fprintf (stderr, "Please make sure that your Bluetooth device is ON!\n");
1110 /* start listening on the socket */
1111 if (GNUNET_NETWORK_socket_listen (dev->handle, 4) != GNUNET_OK)
1113 fprintf (stderr, "Failed to listen on the socket: ");
1118 /* register the sdp service */
1119 if (register_service(dev) != 0)
1121 fprintf (stderr, "Failed to register a service: ");
1126 int i, dev_id = -1, fd_hci;
1129 struct hci_dev_list_req list;
1130 struct hci_dev_req dev[HCI_MAX_DEV];
1131 } request; //used for detecting the local devices
1132 struct sockaddr_rc rc_addr = { 0 }; //used for binding
1134 /* Initialize the neighbour structure */
1135 neighbours.dev_id = -1;
1136 for (i = 0; i < MAX_PORTS; i++)
1137 neighbours.fds[i] = -1;
1139 /* Open a HCI socket */
1140 fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
1145 "Failed to create HCI socket: %s\n",
1150 memset (&request, 0, sizeof(request));
1151 request.list.dev_num = HCI_MAX_DEV;
1153 if (ioctl (fd_hci, HCIGETDEVLIST, (void *) &request) < 0)
1156 "ioctl(HCIGETDEVLIST) on interface `%.*s' failed: %s\n",
1160 (void) close (fd_hci);
1164 /* Search for a device with dev->iface name */
1165 for (i = 0; i < request.list.dev_num; i++)
1167 struct hci_dev_info dev_info;
1169 memset (&dev_info, 0, sizeof(struct hci_dev_info));
1170 dev_info.dev_id = request.dev[i].dev_id;
1171 strncpy (dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE);
1173 if (ioctl (fd_hci, HCIGETDEVINFO, (void *) &dev_info))
1176 "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n",
1180 (void) close (fd_hci);
1184 if (strncmp (dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE) == 0)
1187 dev_id = dev_info.dev_id; //the device was found
1189 * Copy the MAC address to the device structure
1191 GNUNET_memcpy (&dev->pl_mac, &dev_info.bdaddr, sizeof (bdaddr_t));
1193 /* Check if the interface is up */
1194 if (hci_test_bit (HCI_UP, (void *) &dev_info.flags) == 0)
1196 /* Bring the interface up */
1197 if (ioctl (fd_hci, HCIDEVUP, dev_info.dev_id))
1200 "ioctl(HCIDEVUP) on interface `%.*s' failed: %s\n",
1204 (void) close (fd_hci);
1209 /* Check if the device is discoverable */
1210 if (hci_test_bit (HCI_PSCAN, (void *) &dev_info.flags) == 0 ||
1211 hci_test_bit (HCI_ISCAN, (void *) &dev_info.flags) == 0)
1213 /* Set interface Page Scan and Inqury Scan ON */
1214 struct hci_dev_req dev_req;
1216 memset (&dev_req, 0, sizeof (dev_req));
1217 dev_req.dev_id = dev_info.dev_id;
1218 dev_req.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
1220 if (ioctl (fd_hci, HCISETSCAN, (unsigned long) &dev_req))
1223 "ioctl(HCISETSCAN) on interface `%.*s' failed: %s\n",
1227 (void) close (fd_hci);
1237 /* Check if the interface was not found */
1241 "The interface %s was not found\n",
1243 (void) close (fd_hci);
1247 /* Close the hci socket */
1248 (void) close(fd_hci);
1252 /* Bind the rfcomm socket to the interface */
1253 memset (&rc_addr, 0, sizeof (rc_addr));
1254 rc_addr.rc_family = AF_BLUETOOTH;
1255 rc_addr.rc_bdaddr = *BDADDR_ANY;
1257 if (bind_socket (dev->fd_rfcomm, &rc_addr) != 0)
1260 "Failed to bind interface `%.*s': %s\n",
1267 /* Register a SDP service */
1268 if (register_service (dev, rc_addr.rc_channel) != 0)
1271 "Failed to register a service on interface `%.*s': %s\n",
1273 dev->iface, strerror (errno));
1277 /* Switch socket in listening mode */
1278 if (listen (dev->fd_rfcomm, 5) == -1) //FIXME: probably we need a bigger number
1280 fprintf (stderr, "Failed to listen on socket for interface `%.*s': %s\n", IFNAMSIZ,
1281 dev->iface, strerror (errno));
1292 * Set the header to sane values to make attacks more difficult
1294 * @param taIeeeHeader pointer to the header of the packet
1295 * @param dev pointer to the Hardware_Infos struct
1297 **** copy from gnunet-helper-transport-wlan.c ****
1300 mac_set (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1301 const struct HardwareInfos *dev)
1303 taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
1304 taIeeeHeader->addr3 = mac_bssid_gnunet;
1307 GNUNET_memcpy (&taIeeeHeader->addr2, &dev->pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1309 taIeeeHeader->addr2 = dev->pl_mac;
1315 * Test if the given interface name really corresponds to a bluetooth
1318 * @param iface name of the interface
1319 * @return 0 on success, 1 on error
1320 **** similar with the one from gnunet-helper-transport-wlan.c ****
1323 test_bluetooth_interface (const char *iface)
1329 ret = snprintf (strbuf, sizeof (strbuf),
1330 "/sys/class/bluetooth/%s/subsystem",
1332 if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
1335 "Did not find 802.15.1 interface `%s'. Exiting.\n",
1344 * Test incoming packets mac for being our own.
1346 * @param taIeeeHeader buffer of the packet
1347 * @param dev the Hardware_Infos struct
1348 * @return 0 if mac belongs to us, 1 if mac is for another target
1350 **** same as the one from gnunet-helper-transport-wlan.c ****
1353 mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1354 const struct HardwareInfos *dev)
1356 static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
1358 if ( (0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
1359 (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)) )
1360 return 0; /* some drivers set no Macs, then assume it is all for us! */
1362 if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1363 return 1; /* not a GNUnet ad-hoc package */
1364 if ( (0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
1365 (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)) )
1366 return 0; /* for us, or broadcast */
1367 return 1; /* not for us */
1372 * Process data from the stdin. Takes the message, forces the sender MAC to be correct
1373 * and puts it into our buffer for transmission to the receiver.
1375 * @param cls pointer to the device struct ('struct HardwareInfos*')
1376 * @param hdr pointer to the start of the packet
1378 **** same as the one from gnunet-helper-transport-wlan.c ****
1381 stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1383 struct HardwareInfos *dev = cls;
1384 const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header;
1385 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *blueheader;
1388 sendsize = ntohs (hdr->size);
1390 sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
1391 (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) )
1393 fprintf (stderr, "Received malformed message\n");
1396 sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) -
1397 sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1398 if (MAXLINE < sendsize)
1400 fprintf (stderr, "Packet too big for buffer\n");
1403 header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
1404 GNUNET_memcpy (&write_pout.buf, &header->frame, sendsize);
1405 blueheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf;
1407 /* payload contains MAC address, but we don't trust it, so we'll
1408 * overwrite it with OUR MAC address to prevent mischief */
1409 mac_set (blueheader, dev);
1410 GNUNET_memcpy (&blueheader->addr1, &header->frame.addr1,
1411 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1412 write_pout.size = sendsize;
1417 * Broadcast a HELLO message for peer discovery
1419 * @param dev pointer to the device struct
1420 * @param dev pointer to the socket which was added to the set
1421 * @return 0 on success
1424 send_broadcast (struct HardwareInfos *dev, int *sendsocket)
1430 if ((neighbours.size == neighbours.pos && new_device == 1) || neighbours.size == 0)
1432 inquiry_devices: //skip the conditions and force a inquiry for new devices
1435 * It means that I sent HELLO messages to all the devices from the list and I should search
1436 * for new ones or that this is the first time when I do a search.
1438 inquiry_info *devices = NULL;
1439 int i, responses, max_responses = MAX_PORTS;
1442 if (neighbours.size >= MAX_PORTS)
1444 fprintf (stderr, "%.*s reached the top limit for the discovarable devices\n", IFNAMSIZ, dev->iface);
1448 /* Get the device id */
1449 if (neighbours.dev_id == -1)
1451 char addr[19] = { 0 }; //the device MAC address
1453 ba2str ((bdaddr_t *) &dev->pl_mac, addr);
1454 neighbours.dev_id = hci_devid (addr);
1455 if (neighbours.dev_id < 0)
1457 fprintf (stderr, "Failed to get the device id for interface %.*s : %s\n", IFNAMSIZ,
1458 dev->iface, strerror (errno));
1463 devices = malloc (max_responses * sizeof (inquiry_info));
1464 if (devices == NULL)
1466 fprintf (stderr, "Failed to allocate memory for inquiry info list on interface %.*s\n", IFNAMSIZ,
1471 responses = hci_inquiry (neighbours.dev_id, 8, max_responses, NULL, &devices, IREQ_CACHE_FLUSH);
1474 fprintf (stderr, "Failed to inquiry on interface %.*s\n", IFNAMSIZ, dev->iface);
1478 fprintf (stderr, "LOG : Found %d devices\n", responses); //FIXME delete it after debugging stage
1482 fprintf (stderr, "LOG : No devices discoverable\n");
1486 for (i = 0; i < responses; i++)
1494 fprintf (stderr, "%.*s reached the top limit for the discoverable devices (after inquiry)\n", IFNAMSIZ,
1499 /* Search if the address already exists on the list */
1500 for (j = 0; j < neighbours.size; j++)
1502 if (memcmp (&(devices + i)->bdaddr, &(neighbours.devices[j]), sizeof (bdaddr_t)) == 0)
1505 fprintf (stderr, "LOG : the device already exists on the list\n"); //FIXME debugging message
1512 char addr[19] = { 0 };
1514 ba2str (&(devices +i)->bdaddr, addr);
1515 fprintf (stderr, "LOG : %s was added to the list\n", addr); //FIXME debugging message
1516 GNUNET_memcpy (&(neighbours.devices[neighbours.size++]), &(devices + i)->bdaddr, sizeof (bdaddr_t));
1524 int connection_successful = 0;
1525 struct sockaddr_rc addr_rc = { 0 };
1527 addr_rc.rc_family = AF_BLUETOOTH;
1529 /* Try to connect to a new device from the list */
1530 while (neighbours.pos < neighbours.size)
1532 /* Check if we are already connected to this device */
1533 if (neighbours.fds[neighbours.pos] == -1)
1536 memset (&addr_rc.rc_bdaddr, 0, sizeof (addr_rc.rc_bdaddr));
1537 GNUNET_memcpy (&addr_rc.rc_bdaddr, &(neighbours.devices[neighbours.pos]), sizeof (addr_rc.rc_bdaddr));
1539 addr_rc.rc_channel = get_channel (dev, addr_rc.rc_bdaddr);
1541 *sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1542 if ( (-1 < *sendsocket) &&
1543 (0 == connect (*sendsocket,
1544 (struct sockaddr *) &addr_rc,
1545 sizeof (addr_rc))) )
1547 neighbours.fds[neighbours.pos++] = *sendsocket;
1548 connection_successful = 1;
1549 char addr[19] = { 0 };
1550 ba2str (&(neighbours.devices[neighbours.pos - 1]), addr);
1551 fprintf (stderr, "LOG : Connected to %s\n", addr);
1556 char addr[19] = { 0 };
1557 errno_copy = errno; //Save a copy for later
1559 if (-1 != *sendsocket)
1561 (void) close (*sendsocket);
1564 ba2str (&(neighbours.devices[neighbours.pos]), addr);
1566 "LOG : Couldn't connect on device %s, error : %s\n",
1569 if (errno != ECONNREFUSED) //FIXME be sure that this works
1571 fprintf (stderr, "LOG : Removes %d device from the list\n", neighbours.pos);
1572 /* Remove the device from the list */
1573 GNUNET_memcpy (&neighbours.devices[neighbours.pos], &neighbours.devices[neighbours.size - 1], sizeof (bdaddr_t));
1574 memset (&neighbours.devices[neighbours.size - 1], 0, sizeof (bdaddr_t));
1575 neighbours.fds[neighbours.pos] = neighbours.fds[neighbours.size - 1];
1576 neighbours.fds[neighbours.size - 1] = -1;
1577 neighbours.size -= 1;
1580 neighbours.pos += 1;
1582 if (neighbours.pos >= neighbours.size)
1587 if (loops == MAX_LOOPS) //don't get stuck trying to connect to one device
1593 fprintf (stderr, "LOG : Search for a new device\n"); //FIXME debugging message
1594 neighbours.pos += 1;
1598 /* Cycle on the list */
1599 if (neighbours.pos == neighbours.size)
1602 searching_devices_count += 1;
1604 if (searching_devices_count == MAX_LOOPS)
1606 fprintf (stderr, "LOG : Force to inquiry for new devices\n");
1607 searching_devices_count = 0;
1608 goto inquiry_devices;
1611 /* If a new device wasn't found, search an old one */
1612 if (connection_successful == 0)
1614 int loop_check = neighbours.pos;
1615 while (neighbours.fds[neighbours.pos] == -1)
1617 if (neighbours.pos == neighbours.size)
1620 if (neighbours.pos == loop_check)
1622 if (errno_copy == ECONNREFUSED)
1624 fprintf (stderr, "LOG : No device found. Go back and search again\n"); //FIXME debugging message
1627 goto search_for_devices;
1631 return 1; // Skip the broadcast message
1635 neighbours.pos += 1;
1638 *sendsocket = neighbours.fds[neighbours.pos++];
1646 * Main function of the helper. This code accesses a bluetooth interface
1647 * forwards traffic in both directions between the bluetooth interface and
1648 * stdin/stdout of this process. Error messages are written to stderr.
1650 * @param argc number of arguments, must be 2
1651 * @param argv arguments only argument is the name of the interface (i.e. 'hci0')
1652 * @return 0 on success (never happens, as we don't return unless aborted), 1 on error
1654 **** similar to gnunet-helper-transport-wlan.c ****
1657 main (int argc, char *argv[])
1660 struct HardwareInfos dev;
1661 char readbuf[MAXLINE];
1666 struct MessageStreamTokenizer *stdin_mst;
1668 int crt_rfds = 0, rfds_list[MAX_PORTS];
1669 int broadcast, sendsocket;
1671 /* Assert privs so we can modify the firewall rules! */
1673 #ifdef HAVE_SETRESUID
1674 uid_t uid = getuid ();
1676 if (0 != setresuid (uid, 0, 0))
1679 "Failed to setresuid to root: %s\n",
1684 if (0 != seteuid (0))
1687 "Failed to seteuid back to root: %s\n", strerror (errno));
1693 /* Make use of SGID capabilities on POSIX */
1694 memset (&dev, 0, sizeof (dev));
1695 dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1696 raw_eno = errno; /* remember for later */
1698 /* Now that we've dropped root rights, we can do error checking */
1701 fprintf (stderr, "You must specify the name of the interface as the first \
1702 and only argument to this program.\n");
1703 if (-1 != dev.fd_rfcomm)
1704 (void) close (dev.fd_rfcomm);
1708 if (-1 == dev.fd_rfcomm)
1710 fprintf (stderr, "Failed to create a RFCOMM socket: %s\n", strerror (raw_eno));
1713 if (dev.fd_rfcomm >= FD_SETSIZE)
1715 fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1716 dev.fd_rfcomm, FD_SETSIZE);
1717 (void) close (dev.fd_rfcomm);
1720 if (0 != test_bluetooth_interface (argv[1]))
1722 (void) close (dev.fd_rfcomm);
1725 strncpy (dev.iface, argv[1], IFNAMSIZ);
1726 if (0 != open_device (&dev))
1728 (void) close (dev.fd_rfcomm);
1734 uid_t uid = getuid ();
1735 #ifdef HAVE_SETRESUID
1736 if (0 != setresuid (uid, uid, uid))
1738 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1739 if (-1 != dev.fd_rfcomm)
1740 (void) close (dev.fd_rfcomm);
1744 if (0 != (setuid (uid) | seteuid (uid)))
1746 fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
1747 if (-1 != dev.fd_rfcomm)
1748 (void) close (dev.fd_rfcomm);
1754 /* Send MAC address of the bluetooth interface to STDOUT first */
1756 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
1758 macmsg.hdr.size = htons (sizeof (macmsg));
1759 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
1760 GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1761 GNUNET_memcpy (write_std.buf, &macmsg, sizeof (macmsg));
1762 write_std.size = sizeof (macmsg);
1766 stdin_mst = mst_create (&stdin_send_hw, &dev);
1770 * TODO : I should make the time out of a mac endpoint smaller and check if the rate
1771 * from get_wlan_header (plugin_transport_bluetooth.c) is correct.
1780 if ((0 == write_pout.size) && (1 == stdin_open))
1782 FD_SET (STDIN_FILENO, &rfds);
1783 maxfd = MAX (maxfd, STDIN_FILENO);
1785 if (0 == write_std.size)
1787 FD_SET (dev.fd_rfcomm, &rfds);
1788 maxfd = MAX (maxfd, dev.fd_rfcomm);
1791 for (i = 0; i < crt_rfds; i++) // it can receive messages from multiple devices
1793 FD_SET (rfds_list[i], &rfds);
1794 maxfd = MAX (maxfd, rfds_list[i]);
1797 if (0 < write_std.size)
1799 FD_SET (STDOUT_FILENO, &wfds);
1800 maxfd = MAX (maxfd, STDOUT_FILENO);
1802 if (0 < write_pout.size) //it can send messages only to one device per loop
1804 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *frame;
1805 /* Get the destination address */
1806 frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) write_pout.buf;
1808 if (memcmp (&frame->addr1, &dev.pl_mac,
1809 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1812 memset (&write_pout, 0, sizeof (write_pout)); //clear the buffer
1814 else if (memcmp (&frame->addr1, &broadcast_address,
1815 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1817 fprintf (stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n", dev.iface, neighbours.pos, neighbours.size); //FIXME: debugging message
1819 if (send_broadcast(&dev, &sendsocket) != 0) //if the searching wasn't successful don't get stuck on the select stage
1822 memset (&write_pout, 0, sizeof (write_pout)); //remove the message
1823 fprintf (stderr, "LOG : Skipping the broadcast message (pos %d, size %d)\n", neighbours.pos, neighbours.size);
1827 FD_SET (sendsocket, &wfds);
1828 maxfd = MAX (maxfd, sendsocket);
1835 /* Search if the address already exists on the list */
1836 for (i = 0; i < neighbours.size; i++)
1838 if (memcmp (&frame->addr1, &(neighbours.devices[i]), sizeof (bdaddr_t)) == 0)
1841 if (neighbours.fds[i] != -1)
1843 found = 1; //save the position where it was found
1844 FD_SET (neighbours.fds[i], &wfds);
1845 maxfd = MAX (maxfd, neighbours.fds[i]);
1846 sendsocket = neighbours.fds[i];
1847 fprintf (stderr, "LOG: the address was found in the list\n");
1855 struct sockaddr_rc addr = { 0 };
1857 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,
1858 frame->addr1.mac[5], frame->addr1.mac[4], frame->addr1.mac[3],
1859 frame->addr1.mac[2], frame->addr1.mac[1], frame->addr1.mac[0]); //FIXME: debugging message
1861 sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1865 fprintf (stderr, "Failed to create a RFCOMM socket (sending stage): %s\n",
1870 GNUNET_memcpy (&addr.rc_bdaddr, &frame->addr1, sizeof (bdaddr_t));
1871 addr.rc_family = AF_BLUETOOTH;
1872 addr.rc_channel = get_channel (&dev, addr.rc_bdaddr);
1876 status = connect (sendsocket, (struct sockaddr *) &addr, sizeof (addr));
1877 if (0 != status && errno != EAGAIN)
1879 if (errno == ECONNREFUSED && tries < 2)
1881 fprintf (stderr, "LOG : %.*s failed to connect. Trying again!\n", IFNAMSIZ, dev.iface);
1885 else if (errno == EBADF)
1887 fprintf (stderr, "LOG : %s failed to connect : %s. Skip it!\n", dev.iface, strerror (errno));
1888 memset (&write_pout, 0, sizeof (write_pout));
1893 fprintf (stderr, "LOG : %s failed to connect : %s. Try again later!\n", dev.iface, strerror (errno));
1894 memset (&write_pout, 0, sizeof (write_pout));
1901 FD_SET (sendsocket, &wfds);
1902 maxfd = MAX (maxfd, sendsocket);
1903 fprintf (stderr, "LOG : Connection successful\n");
1904 if (pos != 0) // save the socket
1906 neighbours.fds[pos] = sendsocket;
1910 /* Add the new device to the discovered devices list */
1911 if (neighbours.size < MAX_PORTS)
1913 neighbours.fds[neighbours.size] = sendsocket;
1914 GNUNET_memcpy (&(neighbours.devices[neighbours.size++]), &addr.rc_bdaddr, sizeof (bdaddr_t));
1918 fprintf (stderr, "The top limit for the discovarable devices' list was reached\n");
1928 /* Select a fd which is ready for action :) */
1930 int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
1931 if ((-1 == retval) && (EINTR == errno))
1933 if (0 > retval && errno != EBADF) // we handle BADF errors later
1935 fprintf (stderr, "select failed: %s\n", strerror (errno));
1939 if (FD_ISSET (STDOUT_FILENO , &wfds))
1942 write (STDOUT_FILENO, write_std.buf + write_std.pos,
1943 write_std.size - write_std.pos);
1946 fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1949 write_std.pos += ret;
1950 if (write_std.pos == write_std.size)
1955 fprintf (stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); //FIXME: debugging message
1958 if (-1 != sendsocket)
1960 if (FD_ISSET (sendsocket , &wfds))
1962 ssize_t ret = write (sendsocket,
1963 write_pout.buf + write_std.pos,
1964 write_pout.size - write_pout.pos);
1965 if (0 > ret) //FIXME should I first check the error type?
1967 fprintf (stderr, "Failed to write to bluetooth device: %s. Closing the socket!\n",
1969 for (i = 0; i < neighbours.size; i++)
1971 if (neighbours.fds[i] == sendsocket)
1973 (void) close(sendsocket);
1974 neighbours.fds[i] = -1;
1978 /* Remove the message */
1979 memset (&write_pout.buf + write_std.pos, 0, (write_pout.size - write_pout.pos));
1980 write_pout.pos = 0 ;
1981 write_pout.size = 0;
1985 write_pout.pos += ret;
1986 if ((write_pout.pos != write_pout.size) && (0 != ret))
1988 /* We should not get partial sends with packet-oriented devices... */
1989 fprintf (stderr, "Write error, partial send: %u/%u\n",
1990 (unsigned int) write_pout.pos,
1991 (unsigned int) write_pout.size);
1995 if (write_pout.pos == write_pout.size)
1998 write_pout.size = 0;
2000 fprintf (stderr, "LOG : %s sends a message to a DEVICE\n", dev.iface); //FIXME: debugging message
2004 for (i = 0; i <= maxfd; i++)
2006 if (FD_ISSET (i, &rfds))
2008 if (i == STDIN_FILENO)
2011 read (i, readbuf, sizeof (readbuf));
2015 "Read error from STDIN: %s\n",
2021 /* stop reading... */
2026 mst_receive (stdin_mst, readbuf, ret);
2027 fprintf (stderr, "LOG : %s receives a message from STDIN\n", dev.iface); //FIXME: debugging message
2030 else if (i == dev.fd_rfcomm)
2033 struct sockaddr_rc addr = { 0 };
2034 unsigned int opt = sizeof (addr);
2036 readsocket = accept (dev.fd_rfcomm, (struct sockaddr *) &addr, &opt);
2037 fprintf(stderr, "LOG : %s accepts a message\n", dev.iface); //FIXME: debugging message
2038 if (readsocket == -1)
2040 fprintf (stderr, "Failed to accept a connection on interface: %.*s\n", IFNAMSIZ,
2046 FD_SET (readsocket, &rfds);
2047 maxfd = MAX (maxfd, readsocket);
2049 if (crt_rfds < MAX_PORTS)
2050 rfds_list[crt_rfds++] = readsocket;
2053 fprintf (stderr, "The limit for the read file descriptors list was \
2062 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
2064 fprintf (stderr, "LOG : %s reads something from the socket\n", dev.iface);//FIXME : debugging message
2065 rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
2067 read_from_the_socket ((void *)&i, (unsigned char *) &rrm->frame,
2068 sizeof (write_std.buf)
2069 - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2070 + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2077 /* Remove the socket from the list */
2078 for (j = 0; j < crt_rfds; j++)
2080 if (rfds_list[j] == i)
2082 rfds_list[j] ^= rfds_list[crt_rfds - 1];
2083 rfds_list[crt_rfds - 1] ^= rfds_list[j];
2084 rfds_list[j] ^= rfds_list[crt_rfds - 1];
2090 fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
2093 if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2095 write_std.size = ret
2096 + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2097 - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2098 rrm->header.size = htons (write_std.size);
2099 rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2106 /* Error handling, try to clean up a bit at least */
2107 mst_destroy (stdin_mst);
2109 sdp_close (dev.session);
2110 (void) close (dev.fd_rfcomm);
2111 if (-1 != sendsocket)
2112 (void) close (sendsocket);
2114 for (i = 0; i < crt_rfds; i++)
2115 (void) close (rfds_list[i]);
2117 for (i = 0; i < neighbours.size; i++)
2118 (void) close (neighbours.fds[i]);
2120 struct HardwareInfos dev;
2121 struct GNUNET_NETWORK_Handle *sendsocket;
2122 struct GNUNET_NETWORK_FDSet *rfds;
2123 struct GNUNET_NETWORK_FDSet *wfds;
2124 struct GNUNET_NETWORK_Handle *rfds_list[MAX_PORTS];
2125 char readbuf[MAXLINE] = { 0 };
2126 SOCKADDR_BTH acc_addr = { 0 };
2127 int addr_len = sizeof (SOCKADDR_BTH);
2128 int broadcast, i, stdin_open, crt_rfds = 0;
2129 HANDLE stdin_handle = GetStdHandle (STD_INPUT_HANDLE);
2130 HANDLE stdout_handle = GetStdHandle (STD_OUTPUT_HANDLE);
2131 struct MessageStreamTokenizer *stdin_mst;
2133 /* check the handles */
2134 if (stdin_handle == INVALID_HANDLE_VALUE)
2136 fprintf (stderr, "Failed to get the stdin handle\n");
2140 if (stdout_handle == INVALID_HANDLE_VALUE)
2142 fprintf (stderr, "Failed to get the stdout handle\n");
2146 /* initialize windows sockets */
2147 initialize_windows_sockets();
2149 // /* test bluetooth socket family support */ --> it return false because the GNUNET_NETWORK_test_pf should also receive the type of socket (BTHPROTO_RFCOMM)
2150 // if (GNUNET_NETWORK_test_pf (AF_BTH) != GNUNET_OK)
2152 // fprintf (stderr, "AF_BTH family is not supported\n");
2156 /* create the socket */
2157 dev.handle = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
2158 if (dev.handle == NULL)
2160 fprintf (stderr, "Failed to create RFCOMM socket: ");
2166 if (open_device (&dev) == -1)
2168 fprintf (stderr, "Failed to open the device\n");
2170 if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
2172 fprintf (stderr, "Failed to close the socket!\n");
2178 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (dev.handle, 1) )
2180 fprintf (stderr, "Failed to change the socket mode\n");
2184 memset (&write_std, 0, sizeof (write_std));
2185 memset (&write_pout, 0, sizeof (write_pout));
2188 rfds = GNUNET_NETWORK_fdset_create ();
2189 wfds = GNUNET_NETWORK_fdset_create ();
2191 /* Send MAC address of the bluetooth interface to STDOUT first */
2193 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
2195 macmsg.hdr.size = htons (sizeof (macmsg));
2196 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
2197 GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy));
2198 GNUNET_memcpy (write_std.buf, &macmsg, sizeof (macmsg));
2199 write_std.size = sizeof (macmsg);
2203 stdin_mst = mst_create (&stdin_send_hw, &dev);
2208 int stdout_pos = -1;
2215 sendsocket = NULL; //FIXME ???memleaks
2217 GNUNET_NETWORK_fdset_zero (rfds);
2218 if ((0 == write_pout.size) && (1 == stdin_open))
2222 GNUNET_NETWORK_fdset_handle_set (rfds, (struct GNUNET_DISK_FileHandle*) &stdin_handle);
2225 if (0 == write_std.size)
2228 GNUNET_NETWORK_fdset_set (rfds, dev.handle);
2231 for (i = 0; i < crt_rfds; i++)
2234 GNUNET_NETWORK_fdset_set (rfds, rfds_list[i]);
2237 GNUNET_NETWORK_fdset_zero (wfds);
2238 if (0 < write_std.size)
2241 GNUNET_NETWORK_fdset_handle_set (wfds, (struct GNUNET_DISK_FileHandle*) &stdout_handle);
2242 // printf ("%s\n", write_std.buf);
2243 // memset (write_std.buf, 0, write_std.size);
2244 // write_std.size = 0;
2247 if (0 < write_pout.size)
2249 if (strcmp (argv[1], "ff:ff:ff:ff:ff:ff") == 0) {
2250 fprintf(stderr, "LOG: BROADCAST! Skipping the message\n");
2253 memset (write_pout.buf, 0, write_pout.size);
2254 write_pout.size = 0;
2259 fprintf (stderr, "LOG : has a new message for %s\n", argv[1]);
2260 sendsocket = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
2262 if (sendsocket == NULL)
2264 fprintf (stderr, "Failed to create RFCOMM socket: \n");
2269 memset (&addr, 0, sizeof (addr));
2270 //addr.addressFamily = AF_BTH;
2272 WSAStringToAddress (argv[1], AF_BTH, NULL, (LPSOCKADDR) &addr, &addr_len))
2274 fprintf (stderr, "Failed to translate the address: ");
2278 addr.port = get_channel (argv[1]);
2279 if (addr.port == -1)
2281 fprintf (stderr, "Couldn't find the sdp service for the address: %s\n", argv[1]);
2282 memset (write_pout.buf, 0, write_pout.size);
2283 write_pout.size = 0;
2284 broadcast = 1; //skipping the select part
2288 if (GNUNET_OK != GNUNET_NETWORK_socket_connect (sendsocket, (LPSOCKADDR)&addr, addr_len))
2290 fprintf (stderr, "Failed to connect: ");
2295 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (sendsocket, 1) )
2297 fprintf (stderr, "Failed to change the socket mode\n");
2301 GNUNET_NETWORK_fdset_set (wfds, sendsocket);
2308 int retval = GNUNET_NETWORK_socket_select (rfds, wfds, NULL, GNUNET_TIME_relative_get_forever_());
2311 fprintf (stderr, "Select error\n");
2314 //if (GNUNET_NETWORK_fdset_isset (wfds, (struct GNUNET_NETWORK_Handle*)&stdout_handle))
2315 if (retval == stdout_pos)
2317 fprintf(stderr, "LOG : sends a message to STDOUT\n"); //FIXME: debugging message
2319 //ret = GNUNET_NETWORK_socket_send ((struct GNUNET_NETWORK_Handle *)&stdout_handle, write_std.buf + write_std.pos, write_std.size - write_std.pos);
2320 //ret = write (STDOUT_FILENO, write_std.buf + write_std.pos, write_std.size - write_std.pos);
2322 if (FALSE == WriteFile (stdout_handle, write_std.buf + write_std.pos, write_std.size - write_std.pos, &ret, NULL))
2324 fprintf (stderr, "Failed to write to STDOUT: ");
2331 fprintf (stderr, "Failed to write to STDOUT\n");
2335 write_std.pos += ret;
2336 if (write_std.pos == write_std.size)
2342 if (sendsocket != NULL)
2344 if (GNUNET_NETWORK_fdset_isset (wfds, sendsocket))
2347 ret = GNUNET_NETWORK_socket_send (sendsocket, write_pout.buf + write_pout.pos,
2348 write_pout.size - write_pout.pos);
2350 if (GNUNET_SYSERR == ret)
2352 fprintf (stderr, "Failed to send to the socket. Closing the socket. Error: \n");
2354 if (GNUNET_NETWORK_socket_close (sendsocket) != GNUNET_OK)
2356 fprintf (stderr, "Failed to close the sendsocket!\n");
2363 write_pout.pos += ret;
2364 if ((write_pout.pos != write_pout.size) && (0 != ret))
2366 /* we should not get partial sends with packet-oriented devices... */
2367 fprintf (stderr, "Write error, partial send: %u/%u\n",
2368 (unsigned int) write_pout.pos,
2369 (unsigned int) write_pout.size);
2373 if (write_pout.pos == write_pout.size)
2376 write_pout.size = 0;
2379 fprintf(stderr, "LOG : sends a message to a DEVICE\n"); //FIXME: debugging message
2384 //if (GNUNET_NETWORK_fdset_isset (rfds, (struct GNUNET_NETWORK_Handle*)&stdin_handle))
2385 if (retval == stdin_pos)
2388 //ret = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)&stdin_handle, readbuf, sizeof (write_pout.buf));
2389 //ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
2391 if (FALSE == ReadFile (stdin_handle, readbuf, sizeof (readbuf), &ret, NULL)) /* do nothing asynchronous */
2393 fprintf (stderr, "Read error from STDIN: ");
2399 /* stop reading... */
2402 mst_receive (stdin_mst, readbuf, ret);
2403 fprintf (stderr, "LOG : receives a message from STDIN\n"); //FIXME: debugging message
2407 if (GNUNET_NETWORK_fdset_isset (rfds, dev.handle))
2409 fprintf (stderr, "LOG: accepting connection\n");
2410 struct GNUNET_NETWORK_Handle *readsocket;
2411 readsocket = GNUNET_NETWORK_socket_accept (dev.handle, (LPSOCKADDR)&acc_addr, &addr_len);
2412 if (readsocket == NULL)
2414 fprintf (stderr, "Accept error %d: ", GetLastError());
2420 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (readsocket, 1) )
2422 fprintf (stderr, "Failed to change the socket mode\n");
2425 GNUNET_NETWORK_fdset_set (rfds, readsocket);
2427 if (crt_rfds < MAX_PORTS)
2428 rfds_list[crt_rfds++] = readsocket;
2431 fprintf (stderr, "The limit for the read file descriptors list was reached\n");
2437 for (i = 0; i < crt_rfds; i++)
2439 if (GNUNET_NETWORK_fdset_isset (rfds, rfds_list[i]))
2441 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
2443 fprintf (stderr, "LOG: reading something from the socket\n");//FIXME : debugging message
2444 rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
2445 ret = read_from_the_socket (rfds_list[i], (unsigned char *) &rrm->frame,
2446 sizeof (write_std.buf)
2447 - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2448 + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2453 //TODO remove the socket from the list
2454 if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2456 fprintf (stderr, "Failed to close the sendsocket!\n");
2460 fprintf (stderr, "Read error from raw socket: ");
2465 if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2467 write_std.size = ret
2468 + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2469 - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2470 rrm->header.size = htons (write_std.size);
2471 rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2479 mst_destroy (stdin_mst);
2482 if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
2484 fprintf (stderr, "Failed to close the socket!\n");
2488 for (i = 0; i < crt_rfds; i++)
2490 if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2492 fprintf (stderr, "Failed to close the socket!\n");
2499 return 1; /* we never exit 'normally' */