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 #include "gnunet_config.h"
21 #include "gnunet_util_lib.h"
26 #include <bluetooth/bluetooth.h>
27 #include <bluetooth/hci.h>
28 #include <bluetooth/hci_lib.h>
29 #include <bluetooth/rfcomm.h>
30 #include <bluetooth/sdp.h>
31 #include <bluetooth/sdp_lib.h>
36 #include <sys/ioctl.h>
37 #include <sys/param.h>
38 #include <sys/socket.h>
40 #include <sys/types.h>
44 #include "plugin_transport_wlan.h"
45 #include "gnunet_protocols.h"
49 * Maximum number of ports assignable for RFCOMMM protocol.
54 * Maximum size of a message allowed in either direction
55 * (used for our receive and sent buffers).
61 * Maximum number of loops without inquiring for new devices.
66 /* Maximum size of the interface's name */
73 * A copy of the MAC Address.
75 struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy
77 UINT8 mac[MAC_ADDR_SIZE];
81 * The UUID used for the SDP service.
82 * {31191E56-FA7E-4517-870E-71B86BBCC52F}
84 #define GNUNET_BLUETOOTH_SDP_UUID \
86 0x31, 0x19, 0x1E, 0x56, \
90 0x71, 0xB8, 0x6B, 0xBC, 0xC5, 0x2F \
95 * In bluez library, the maximum name length of a device is 8
97 #define BLUEZ_DEVNAME_SIZE 8
100 * struct for storing the information of the hardware. There is only
106 * Name of the interface, not necessarily 0-terminated (!).
108 char iface[IFNAMSIZ];
114 struct GNUNET_NETWORK_Handle *handle;
117 * MAC address of our own bluetooth interface.
119 struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy pl_mac;
122 * file descriptor for the rfcomm socket
127 * MAC address of our own bluetooth interface.
129 struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac;
134 sdp_session_t *session ;
139 * IO buffer used for buffering data in transit (to wireless or to stdout).
144 * How many bytes of data are stored in 'buf' for transmission right now?
145 * Data always starts at offset 0 and extends to 'size'.
150 * How many bytes that were stored in 'buf' did we already write to the
151 * destination? Always smaller than 'size'.
156 * Buffered data; twice the maximum allowed message size as we add some
159 char buf[MAXLINE * 2];
164 * Devices buffer used to keep a list with all the discoverable devices in
165 * order to send them HELLO messages one by one when it receive a broadcast message.
167 struct BroadcastMessages
169 /* List with the discoverable devices' addresses */
170 bdaddr_t devices[MAX_PORTS];
172 /* List with the open sockets */
176 /* The number of the devices */
179 /* The current position */
187 * Address used to identify the broadcast messages.
189 static struct GNUNET_TRANSPORT_WLAN_MacAddress broadcast_address = {{255, 255, 255, 255, 255, 255}};
192 * Buffer with the discoverable devices.
194 static struct BroadcastMessages neighbours;
196 static int searching_devices_count = 0;
200 * Buffer for data read from stdin to be transmitted to the bluetooth device
202 static struct SendBuffer write_pout;
205 * Buffer for data read from the bluetooth device to be transmitted to stdout.
207 static struct SendBuffer write_std;
210 /* ****** this are the same functions as the ones used in gnunet-helper-transport-wlan.c ****** */
213 * To what multiple do we align messages? 8 byte should suffice for everyone
216 #define ALIGN_FACTOR 8
219 * Smallest supported message.
221 #define MIN_BUFFER_SIZE sizeof (struct GNUNET_MessageHeader)
225 * Functions with this signature are called whenever a
226 * complete message is received by the tokenizer.
229 * @param message the actual message
231 typedef void (*MessageTokenizerCallback) (void *cls,
233 GNUNET_MessageHeader *
237 * Handle to a message stream tokenizer.
239 struct MessageStreamTokenizer
243 * Function to call on completed messages.
245 MessageTokenizerCallback cb;
253 * Size of the buffer (starting at 'hdr').
258 * How many bytes in buffer have we already processed?
263 * How many bytes in buffer are valid right now?
268 * Beginning of the buffer. Typed like this to force alignment.
270 struct GNUNET_MessageHeader *hdr;
276 * Create a message stream tokenizer.
278 * @param cb function to call on completed messages
279 * @param cb_cls closure for cb
280 * @return handle to tokenizer
282 static struct MessageStreamTokenizer *
283 mst_create (MessageTokenizerCallback cb,
286 struct MessageStreamTokenizer *ret;
288 ret = malloc (sizeof (struct MessageStreamTokenizer));
291 fprintf (stderr, "Failed to allocate buffer for tokenizer\n");
294 ret->hdr = malloc (MIN_BUFFER_SIZE);
295 if (NULL == ret->hdr)
297 fprintf (stderr, "Failed to allocate buffer for alignment\n");
300 ret->curr_buf = MIN_BUFFER_SIZE;
302 ret->cb_cls = cb_cls;
310 * Add incoming data to the receive buffer and call the
311 * callback for all complete messages.
313 * @param mst tokenizer to use
314 * @param buf input data to add
315 * @param size number of bytes in buf
316 * @return GNUNET_OK if we are done processing (need more data)
317 * GNUNET_SYSERR if the data stream is corrupt
320 mst_receive (struct MessageStreamTokenizer *mst,
321 const char *buf, size_t size)
323 const struct GNUNET_MessageHeader *hdr;
328 unsigned long offset;
332 ibuf = (char *) mst->hdr;
336 if (mst->pos < mst->off)
338 //fprintf (stderr, "We processed too many bytes!\n");
339 return GNUNET_SYSERR;
341 if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) ||
342 (0 != (mst->off % ALIGN_FACTOR)))
344 /* need to align or need more space */
345 mst->pos -= mst->off;
346 memmove (ibuf, &ibuf[mst->off], mst->pos);
349 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
352 GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) -
353 (mst->pos - mst->off), size);
354 GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
359 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
361 //FIXME should I reset ??
366 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
367 want = ntohs (hdr->size);
368 if (want < sizeof (struct GNUNET_MessageHeader))
371 "Received invalid message from stdin\n");
372 return GNUNET_SYSERR;
374 if ((mst->curr_buf - mst->off < want) &&
377 /* need more space */
378 mst->pos -= mst->off;
379 memmove (ibuf, &ibuf[mst->off], mst->pos);
382 if (want > mst->curr_buf)
386 fprintf (stderr, "Error! We should proceeded 0 bytes\n");
387 return GNUNET_SYSERR;
389 mst->hdr = realloc (mst->hdr, want);
390 if (NULL == mst->hdr)
392 fprintf (stderr, "Failed to allocate buffer for alignment\n");
395 ibuf = (char *) mst->hdr;
396 mst->curr_buf = want;
398 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
399 if (mst->pos - mst->off < want)
401 delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
402 if (mst->pos + delta > mst->curr_buf)
404 fprintf (stderr, "The size of the buffer will be exceeded!\n");
405 return GNUNET_SYSERR;
407 GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
412 if (mst->pos - mst->off < want)
414 //FIXME should I use this?
419 mst->cb (mst->cb_cls, hdr);
421 if (mst->off == mst->pos)
423 /* reset to beginning of buffer, it's free right now! */
430 fprintf (stderr, "There should some valid bytes in the buffer on this stage\n");
431 return GNUNET_SYSERR;
435 if (size < sizeof (struct GNUNET_MessageHeader))
437 offset = (unsigned long) buf;
438 need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
439 if (GNUNET_NO == need_align)
441 /* can try to do zero-copy and process directly from original buffer */
442 hdr = (const struct GNUNET_MessageHeader *) buf;
443 want = ntohs (hdr->size);
444 if (want < sizeof (struct GNUNET_MessageHeader))
447 "Received invalid message from stdin\n");
450 return GNUNET_SYSERR;
453 break; /* or not, buffer incomplete, so copy to private buffer... */
454 mst->cb (mst->cb_cls, hdr);
460 /* need to copy to private buffer to align;
461 * yes, we go a bit more spagetti than usual here */
467 if (size + mst->pos > mst->curr_buf)
469 mst->hdr = realloc (mst->hdr, size + mst->pos);
470 if (NULL == mst->hdr)
472 fprintf (stderr, "Failed to allocate buffer for alignment\n");
475 ibuf = (char *) mst->hdr;
476 mst->curr_buf = size + mst->pos;
478 if (mst->pos + size > mst->curr_buf)
481 "Assertion failed\n");
484 GNUNET_memcpy (&ibuf[mst->pos], buf, size);
491 * Destroys a tokenizer.
493 * @param mst tokenizer to destroy
496 mst_destroy (struct MessageStreamTokenizer *mst)
503 * Calculate crc32, the start of the calculation
505 * @param buf buffer to calc the crc
506 * @param len len of the buffer
510 calc_crc_osdep (const unsigned char *buf, size_t len)
512 static const unsigned long int crc_tbl_osdep[256] = {
513 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
514 0xE963A535, 0x9E6495A3,
515 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
516 0xE7B82D07, 0x90BF1D91,
517 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
518 0xF4D4B551, 0x83D385C7,
519 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
520 0xFA0F3D63, 0x8D080DF5,
521 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
522 0xD20D85FD, 0xA50AB56B,
523 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
524 0xDCD60DCF, 0xABD13D59,
525 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
526 0xCFBA9599, 0xB8BDA50F,
527 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
528 0xC1611DAB, 0xB6662D3D,
529 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
530 0x9FBFE4A5, 0xE8B8D433,
531 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
532 0x91646C97, 0xE6635C01,
533 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
534 0x8208F4C1, 0xF50FC457,
535 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
536 0x8CD37CF3, 0xFBD44C65,
537 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
538 0xA4D1C46D, 0xD3D6F4FB,
539 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
540 0xAA0A4C5F, 0xDD0D7CC9,
541 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
542 0xB966D409, 0xCE61E49F,
543 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
544 0xB7BD5C3B, 0xC0BA6CAD,
545 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
546 0x04DB2615, 0x73DC1683,
547 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
548 0x0A00AE27, 0x7D079EB1,
549 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
550 0x196C3671, 0x6E6B06E7,
551 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
552 0x17B7BE43, 0x60B08ED5,
553 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
554 0x3FB506DD, 0x48B2364B,
555 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
556 0x316E8EEF, 0x4669BE79,
557 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
558 0x220216B9, 0x5505262F,
559 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
560 0x2CD99E8B, 0x5BDEAE1D,
561 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
562 0x72076785, 0x05005713,
563 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
564 0x7CDCEFB7, 0x0BDBDF21,
565 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
566 0x6FB077E1, 0x18B74777,
567 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
568 0x616BFFD3, 0x166CCF45,
569 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
570 0x4969474D, 0x3E6E77DB,
571 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
572 0x47B2CF7F, 0x30B5FFE9,
573 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
574 0x54DE5729, 0x23D967BF,
575 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
576 0x5A05DF1B, 0x2D02EF8D
579 unsigned long crc = 0xFFFFFFFF;
581 for (; len > 0; len--, buf++)
582 crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
588 * Calculate and check crc of the bluetooth packet
590 * @param buf buffer of the packet, with len + 4 bytes of data,
591 * the last 4 bytes being the checksum
592 * @param len length of the payload in data
593 * @return 0 on success (checksum matches), 1 on error
596 check_crc_buf_osdep (const unsigned char *buf, size_t len)
600 crc = calc_crc_osdep (buf, len);
602 if (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
603 ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3])
610 /* ************** end of clone ***************** */
614 * Function used to get the code of last error and to print the type of error.
619 LPVOID lpMsgBuf = NULL;
621 if (FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
622 NULL, GetLastError(), 0, (LPTSTR) &lpMsgBuf, 0, NULL))
623 fprintf (stderr, "%s\n", (char *)lpMsgBuf);
625 fprintf (stderr, "Failed to format the message for the last error! Error number : %d\n", GetLastError());
629 * Function used to initialize the Windows Sockets
632 initialize_windows_sockets()
635 WORD wVersionRequested = MAKEWORD (2, 0);
636 if (WSAStartup (wVersionRequested, &wsaData) != NO_ERROR)
638 fprintf (stderr , "Error initializing window sockets!\n");
645 * Function used to convert the GUID.
646 * @param bytes the GUID represented as a char array
647 * @param uuid pointer to the GUID
650 convert_guid(char *bytes, GUID * uuid)
653 uuid->Data1 = ((bytes[0] << 24) & 0xff000000) | ((bytes[1] << 16) & 0x00ff0000) | ((bytes[2] << 8) & 0x0000ff00) | (bytes[3] & 0x000000ff);
654 uuid->Data2 = ((bytes[4] << 8) & 0xff00) | (bytes[5] & 0x00ff);
655 uuid->Data3 = ((bytes[6] << 8) & 0xff00) | (bytes[7] & 0x00ff);
657 for (i = 0; i < 8; i++)
659 uuid->Data4[i] = bytes[i + 8];
666 * Function for assigning a port number
668 * @param socket the socket used to bind
669 * @param addr pointer to the rfcomm address
670 * @return 0 on success
673 bind_socket (int socket, struct sockaddr_rc *addr)
677 /* Bind every possible port (from 0 to 30) and stop when binding doesn't fail */
678 //FIXME : it should start from port 1, but on my computer it doesn't work :)
679 for (port = 3; port <= 30; port++)
681 addr->rc_channel = port;
682 status = bind (socket, (struct sockaddr *) addr, sizeof (struct sockaddr_rc));
693 * Function used for creating the service record and registering it.
695 * @param dev pointer to the device struct
696 * @return 0 on success
699 register_service (struct HardwareInfos *dev)
701 /* advertise the service */
702 CSADDR_INFO addr_info;
705 unsigned char uuid[] = GNUNET_BLUETOOTH_SDP_UUID;
707 int addr_len = sizeof (SOCKADDR_BTH);
709 /* get the port on which we are listening on */
710 memset (& addr, 0, sizeof (SOCKADDR_BTH));
711 fd = GNUNET_NETWORK_get_fd (dev->handle);
714 fprintf (stderr, "Failed to get the file descriptor\n");
717 if (SOCKET_ERROR == getsockname (fd, (SOCKADDR*)&addr, &addr_len))
719 fprintf (stderr, "Failed to get the port on which we are listening on: \n");
724 /* save the device address */
725 GNUNET_memcpy (&dev->pl_mac, &addr.btAddr, sizeof (BTH_ADDR));
727 /* set the address information */
728 memset (&addr_info, 0, sizeof (CSADDR_INFO));
729 addr_info.iProtocol = BTHPROTO_RFCOMM;
730 addr_info.iSocketType = SOCK_STREAM;
731 addr_info.LocalAddr.lpSockaddr = (LPSOCKADDR)&addr;
732 addr_info.LocalAddr.iSockaddrLength = sizeof (addr);
733 addr_info.RemoteAddr.lpSockaddr = (LPSOCKADDR)&addr;
734 addr_info.RemoteAddr.iSockaddrLength = sizeof (addr);
736 convert_guid((char *) uuid, &guid);
738 /* register the service */
739 memset (&wqs, 0, sizeof (WSAQUERYSET));
740 wqs.dwSize = sizeof (WSAQUERYSET);
741 wqs.dwNameSpace = NS_BTH;
742 wqs.lpszServiceInstanceName = "GNUnet Bluetooth Service";
743 wqs.lpszComment = "This is the service used by the GNUnnet plugin transport";
744 wqs.lpServiceClassId = &guid;
745 wqs.dwNumberOfCsAddrs = 1;
746 wqs.lpcsaBuffer = &addr_info ;
749 if (SOCKET_ERROR == WSASetService (&wqs , RNRSERVICE_REGISTER, 0))
751 fprintf (stderr, "Failed to register the SDP service: ");
757 fprintf (stderr, "The SDP service was registered\n");
764 * Function used for creating the service record and registering it.
766 * @param dev pointer to the device struct
767 * @param rc_channel the rfcomm channel
768 * @return 0 on success
771 register_service (struct HardwareInfos *dev, int rc_channel)
775 * 2. set the service ID, class, profile information
776 * 3. make the service record publicly browsable
777 * 4. register the RFCOMM channel
778 * 5. set the name, provider and description
779 * 6. register the service record to the local SDP server
782 uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
783 dev->pl_mac.mac[5], dev->pl_mac.mac[4], dev->pl_mac.mac[3],
784 dev->pl_mac.mac[2], dev->pl_mac.mac[1], dev->pl_mac.mac[0]};
785 const char *service_dsc = "Bluetooth plugin services";
786 const char *service_prov = "GNUnet provider";
787 uuid_t root_uuid, rfcomm_uuid, svc_uuid;
788 sdp_list_t *root_list = 0, *rfcomm_list = 0, *proto_list = 0,
789 *access_proto_list = 0, *svc_list = 0;
790 sdp_record_t *record = 0;
791 sdp_data_t *channel = 0;
793 record = sdp_record_alloc();
795 /* Set the general service ID */
796 sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
797 svc_list = sdp_list_append (0, &svc_uuid);
798 sdp_set_service_classes (record, svc_list);
799 sdp_set_service_id (record, svc_uuid);
801 /* Make the service record publicly browsable */
802 sdp_uuid16_create (&root_uuid, PUBLIC_BROWSE_GROUP);
803 root_list = sdp_list_append (0, &root_uuid);
804 sdp_set_browse_groups (record, root_list);
806 /* Register the RFCOMM channel */
807 sdp_uuid16_create (&rfcomm_uuid, RFCOMM_UUID);
808 channel = sdp_data_alloc (SDP_UINT8, &rc_channel);
809 rfcomm_list = sdp_list_append (0, &rfcomm_uuid);
810 sdp_list_append (rfcomm_list, channel);
811 proto_list = sdp_list_append (0, rfcomm_list);
813 /* Set protocol information */
814 access_proto_list = sdp_list_append (0, proto_list);
815 sdp_set_access_protos (record, access_proto_list);
817 /* Set the name, provider, and description */
818 sdp_set_info_attr (record, dev->iface, service_prov, service_dsc);
820 /* Connect to the local SDP server */
821 dev->session = sdp_connect (BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
825 fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
826 IFNAMSIZ, dev->iface, strerror (errno));
831 /* Register the service record */
832 if (sdp_record_register (dev->session, record, 0) < 0)
834 fprintf (stderr, "Failed to register a service record on interface `%.*s': %s\n",
835 IFNAMSIZ, dev->iface, strerror (errno));
841 sdp_data_free (channel);
842 sdp_list_free (root_list, 0);
843 sdp_list_free (rfcomm_list, 0);
844 sdp_list_free (proto_list, 0);
845 sdp_list_free (access_proto_list, 0);
846 sdp_list_free (svc_list, 0);
847 sdp_record_free (record);
855 * Function for searching and browsing for a service. This will return the
856 * port number on which the service is running.
858 * @param dest target address
862 get_channel(const char *dest)
866 DWORD wqs_len = sizeof (WSAQUERYSET);
870 unsigned char uuid[] = GNUNET_BLUETOOTH_SDP_UUID;
871 convert_guid ((char *) uuid, &guid);
873 wqs = (WSAQUERYSET*)malloc (wqs_len);
874 ZeroMemory (wqs, wqs_len);
876 wqs->dwSize = sizeof (WSAQUERYSET) ;
877 wqs->lpServiceClassId = &guid;
878 wqs->dwNameSpace = NS_BTH;
879 wqs->dwNumberOfCsAddrs = 0;
880 wqs->lpszContext = (LPSTR)dest;
882 if (SOCKET_ERROR == WSALookupServiceBegin (wqs, LUP_FLUSHCACHE | LUP_RETURN_ALL, &h))
884 if (GetLastError() == WSASERVICE_NOT_FOUND)
886 fprintf (stderr, "WARNING! The device with address %s wasn't found. Skipping the message!", dest);
891 fprintf (stderr, "Failed to find the port number: ");
898 /* search the sdp service */
901 if (SOCKET_ERROR == WSALookupServiceNext (h, LUP_FLUSHCACHE | LUP_RETURN_ALL, &wqs_len, wqs))
903 int error = WSAGetLastError();
909 wqs = (WSAQUERYSET*)malloc (wqs_len);
912 fprintf (stderr, "Failed! The address was valid but there was no data record of requested type\n");
919 fprintf (stderr, "Failed to look over the services: ");
921 WSALookupServiceEnd (h);
927 channel = ((SOCKADDR_BTH*)wqs->lpcsaBuffer->RemoteAddr.lpSockaddr)->port;
932 WSALookupServiceEnd (h);
938 * Function used for searching and browsing for a service. This will return the
939 * port number on which the service is running.
941 * @param dev pointer to the device struct
942 * @param dest target address
946 get_channel(struct HardwareInfos *dev, bdaddr_t dest)
949 * 1. detect all nearby devices
950 * 2. for each device:
951 * 2.1. connect to the SDP server running
952 * 2.2. get a list of service records with the specific UUID
953 * 2.3. for each service record get a list of the protocol sequences and get
956 uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
957 dest.b[5], dest.b[4], dest.b[3],
958 dest.b[2], dest.b[1], dest.b[0]};
959 sdp_session_t *session = 0;
960 sdp_list_t *search_list = 0, *attrid_list = 0, *response_list = 0, *it = 0;
962 uint32_t range = 0x0000ffff;
965 /* Connect to the local SDP server */
966 session = sdp_connect (BDADDR_ANY, &dest, 0);
969 fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
970 IFNAMSIZ, dev->iface, strerror (errno));
974 sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
975 search_list = sdp_list_append (0, &svc_uuid);
976 attrid_list = sdp_list_append (0, &range);
978 if (sdp_service_search_attr_req (session, search_list,
979 SDP_ATTR_REQ_RANGE, attrid_list, &response_list) == 0)
981 for (it = response_list; it; it = it->next)
983 sdp_record_t *record = (sdp_record_t*) it->data;
984 sdp_list_t *proto_list = 0;
985 if (sdp_get_access_protos (record, &proto_list) == 0)
987 channel = sdp_get_proto_port (proto_list, RFCOMM_UUID);
988 sdp_list_free (proto_list, 0);
990 sdp_record_free (record);
994 sdp_list_free (search_list, 0);
995 sdp_list_free (attrid_list, 0);
996 sdp_list_free (response_list, 0);
1002 "Failed to find the listening channel for interface `%.*s': %s\n",
1012 * Read from the socket and put the result into the buffer for transmission to 'stdout'.
1014 * @param sock file descriptor for reading
1015 * @param buf buffer to read to; first bytes will be the 'struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame',
1016 * followed by the actual payload
1017 * @param buf_size size of the buffer
1018 * @param ri where to write radiotap_rx info
1019 * @return number of bytes written to 'buf'
1022 read_from_the_socket (void *sock,
1023 unsigned char *buf, size_t buf_size,
1024 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri)
1026 unsigned char tmpbuf[buf_size];
1030 count = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)sock, tmpbuf, buf_size);
1032 count = read (*((int *)sock), tmpbuf, buf_size);
1037 if (EAGAIN == errno)
1042 fprintf (stderr, "Failed to read from the HCI socket: %s\n", strerror (errno));
1049 /* Get the channel used */
1051 struct sockaddr_rc rc_addr = { 0 };
1053 memset (&rc_addr, 0, sizeof (rc_addr));
1054 len = sizeof (rc_addr);
1055 if (0 > getsockname (*((int *)sock), (struct sockaddr *) &rc_addr, (socklen_t *) &len))
1057 fprintf (stderr, "getsockname() call failed : %s\n", strerror (errno));
1061 memset (ri, 0, sizeof (*ri));
1062 ri->ri_channel = rc_addr.rc_channel;
1065 /* Detect CRC32 at the end */
1066 if (0 == check_crc_buf_osdep (tmpbuf, count - sizeof (uint32_t)))
1068 count -= sizeof(uint32_t);
1071 GNUNET_memcpy (buf, tmpbuf, count);
1078 * Open the bluetooth interface for reading/writing
1080 * @param dev pointer to the device struct
1081 * @return 0 on success, non-zero on error
1084 open_device (struct HardwareInfos *dev)
1089 /* bind the RFCOMM socket to the interface */
1090 addr.addressFamily = AF_BTH;
1092 addr.port = BT_PORT_ANY;
1095 GNUNET_NETWORK_socket_bind (dev->handle, (const SOCKADDR*)&addr, sizeof (SOCKADDR_BTH)))
1097 fprintf (stderr, "Failed to bind the socket: ");
1098 if (GetLastError() == WSAENETDOWN)
1100 fprintf (stderr, "Please make sure that your Bluetooth device is ON!\n");
1107 /* start listening on the socket */
1108 if (GNUNET_NETWORK_socket_listen (dev->handle, 4) != GNUNET_OK)
1110 fprintf (stderr, "Failed to listen on the socket: ");
1115 /* register the sdp service */
1116 if (register_service(dev) != 0)
1118 fprintf (stderr, "Failed to register a service: ");
1123 int i, dev_id = -1, fd_hci;
1126 struct hci_dev_list_req list;
1127 struct hci_dev_req dev[HCI_MAX_DEV];
1128 } request; //used for detecting the local devices
1129 struct sockaddr_rc rc_addr = { 0 }; //used for binding
1131 /* Initialize the neighbour structure */
1132 neighbours.dev_id = -1;
1133 for (i = 0; i < MAX_PORTS; i++)
1134 neighbours.fds[i] = -1;
1136 /* Open a HCI socket */
1137 fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
1142 "Failed to create HCI socket: %s\n",
1147 memset (&request, 0, sizeof(request));
1148 request.list.dev_num = HCI_MAX_DEV;
1150 if (ioctl (fd_hci, HCIGETDEVLIST, (void *) &request) < 0)
1153 "ioctl(HCIGETDEVLIST) on interface `%.*s' failed: %s\n",
1157 (void) close (fd_hci);
1161 /* Search for a device with dev->iface name */
1162 for (i = 0; i < request.list.dev_num; i++)
1164 struct hci_dev_info dev_info;
1166 memset (&dev_info, 0, sizeof(struct hci_dev_info));
1167 dev_info.dev_id = request.dev[i].dev_id;
1168 strncpy (dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE);
1170 if (ioctl (fd_hci, HCIGETDEVINFO, (void *) &dev_info))
1173 "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n",
1177 (void) close (fd_hci);
1181 if (strncmp (dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE) == 0)
1184 dev_id = dev_info.dev_id; //the device was found
1186 * Copy the MAC address to the device structure
1188 GNUNET_memcpy (&dev->pl_mac, &dev_info.bdaddr, sizeof (bdaddr_t));
1190 /* Check if the interface is up */
1191 if (hci_test_bit (HCI_UP, (void *) &dev_info.flags) == 0)
1193 /* Bring the interface up */
1194 if (ioctl (fd_hci, HCIDEVUP, dev_info.dev_id))
1197 "ioctl(HCIDEVUP) on interface `%.*s' failed: %s\n",
1201 (void) close (fd_hci);
1206 /* Check if the device is discoverable */
1207 if (hci_test_bit (HCI_PSCAN, (void *) &dev_info.flags) == 0 ||
1208 hci_test_bit (HCI_ISCAN, (void *) &dev_info.flags) == 0)
1210 /* Set interface Page Scan and Inqury Scan ON */
1211 struct hci_dev_req dev_req;
1213 memset (&dev_req, 0, sizeof (dev_req));
1214 dev_req.dev_id = dev_info.dev_id;
1215 dev_req.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
1217 if (ioctl (fd_hci, HCISETSCAN, (unsigned long) &dev_req))
1220 "ioctl(HCISETSCAN) on interface `%.*s' failed: %s\n",
1224 (void) close (fd_hci);
1234 /* Check if the interface was not found */
1238 "The interface %s was not found\n",
1240 (void) close (fd_hci);
1244 /* Close the hci socket */
1245 (void) close(fd_hci);
1249 /* Bind the rfcomm socket to the interface */
1250 memset (&rc_addr, 0, sizeof (rc_addr));
1251 rc_addr.rc_family = AF_BLUETOOTH;
1252 rc_addr.rc_bdaddr = *BDADDR_ANY;
1254 if (bind_socket (dev->fd_rfcomm, &rc_addr) != 0)
1257 "Failed to bind interface `%.*s': %s\n",
1264 /* Register a SDP service */
1265 if (register_service (dev, rc_addr.rc_channel) != 0)
1268 "Failed to register a service on interface `%.*s': %s\n",
1270 dev->iface, strerror (errno));
1274 /* Switch socket in listening mode */
1275 if (listen (dev->fd_rfcomm, 5) == -1) //FIXME: probably we need a bigger number
1277 fprintf (stderr, "Failed to listen on socket for interface `%.*s': %s\n", IFNAMSIZ,
1278 dev->iface, strerror (errno));
1289 * Set the header to sane values to make attacks more difficult
1291 * @param taIeeeHeader pointer to the header of the packet
1292 * @param dev pointer to the Hardware_Infos struct
1294 **** copy from gnunet-helper-transport-wlan.c ****
1297 mac_set (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1298 const struct HardwareInfos *dev)
1300 taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
1301 taIeeeHeader->addr3 = mac_bssid_gnunet;
1304 GNUNET_memcpy (&taIeeeHeader->addr2, &dev->pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1306 taIeeeHeader->addr2 = dev->pl_mac;
1312 * Test if the given interface name really corresponds to a bluetooth
1315 * @param iface name of the interface
1316 * @return 0 on success, 1 on error
1317 **** similar with the one from gnunet-helper-transport-wlan.c ****
1320 test_bluetooth_interface (const char *iface)
1326 ret = snprintf (strbuf, sizeof (strbuf),
1327 "/sys/class/bluetooth/%s/subsystem",
1329 if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
1332 "Did not find 802.15.1 interface `%s'. Exiting.\n",
1341 * Test incoming packets mac for being our own.
1343 * @param taIeeeHeader buffer of the packet
1344 * @param dev the Hardware_Infos struct
1345 * @return 0 if mac belongs to us, 1 if mac is for another target
1347 **** same as the one from gnunet-helper-transport-wlan.c ****
1350 mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1351 const struct HardwareInfos *dev)
1353 static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
1355 if ( (0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
1356 (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)) )
1357 return 0; /* some drivers set no Macs, then assume it is all for us! */
1359 if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1360 return 1; /* not a GNUnet ad-hoc package */
1361 if ( (0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
1362 (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)) )
1363 return 0; /* for us, or broadcast */
1364 return 1; /* not for us */
1369 * Process data from the stdin. Takes the message, forces the sender MAC to be correct
1370 * and puts it into our buffer for transmission to the receiver.
1372 * @param cls pointer to the device struct ('struct HardwareInfos*')
1373 * @param hdr pointer to the start of the packet
1375 **** same as the one from gnunet-helper-transport-wlan.c ****
1378 stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1380 struct HardwareInfos *dev = cls;
1381 const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header;
1382 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *blueheader;
1385 sendsize = ntohs (hdr->size);
1387 sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
1388 (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) )
1390 fprintf (stderr, "Received malformed message\n");
1393 sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) -
1394 sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1395 if (MAXLINE < sendsize)
1397 fprintf (stderr, "Packet too big for buffer\n");
1400 header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
1401 GNUNET_memcpy (&write_pout.buf, &header->frame, sendsize);
1402 blueheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf;
1404 /* payload contains MAC address, but we don't trust it, so we'll
1405 * overwrite it with OUR MAC address to prevent mischief */
1406 mac_set (blueheader, dev);
1407 GNUNET_memcpy (&blueheader->addr1, &header->frame.addr1,
1408 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1409 write_pout.size = sendsize;
1414 * Broadcast a HELLO message for peer discovery
1416 * @param dev pointer to the device struct
1417 * @param dev pointer to the socket which was added to the set
1418 * @return 0 on success
1421 send_broadcast (struct HardwareInfos *dev, int *sendsocket)
1427 if ((neighbours.size == neighbours.pos && new_device == 1) || neighbours.size == 0)
1429 inquiry_devices: //skip the conditions and force a inquiry for new devices
1432 * It means that I sent HELLO messages to all the devices from the list and I should search
1433 * for new ones or that this is the first time when I do a search.
1435 inquiry_info *devices = NULL;
1436 int i, responses, max_responses = MAX_PORTS;
1439 if (neighbours.size >= MAX_PORTS)
1441 fprintf (stderr, "%.*s reached the top limit for the discovarable devices\n", IFNAMSIZ, dev->iface);
1445 /* Get the device id */
1446 if (neighbours.dev_id == -1)
1448 char addr[19] = { 0 }; //the device MAC address
1450 ba2str ((bdaddr_t *) &dev->pl_mac, addr);
1451 neighbours.dev_id = hci_devid (addr);
1452 if (neighbours.dev_id < 0)
1454 fprintf (stderr, "Failed to get the device id for interface %.*s : %s\n", IFNAMSIZ,
1455 dev->iface, strerror (errno));
1460 devices = malloc (max_responses * sizeof (inquiry_info));
1461 if (devices == NULL)
1463 fprintf (stderr, "Failed to allocate memory for inquiry info list on interface %.*s\n", IFNAMSIZ,
1468 responses = hci_inquiry (neighbours.dev_id, 8, max_responses, NULL, &devices, IREQ_CACHE_FLUSH);
1471 fprintf (stderr, "Failed to inquiry on interface %.*s\n", IFNAMSIZ, dev->iface);
1475 fprintf (stderr, "LOG : Found %d devices\n", responses); //FIXME delete it after debugging stage
1479 fprintf (stderr, "LOG : No devices discoverable\n");
1483 for (i = 0; i < responses; i++)
1491 fprintf (stderr, "%.*s reached the top limit for the discoverable devices (after inquiry)\n", IFNAMSIZ,
1496 /* Search if the address already exists on the list */
1497 for (j = 0; j < neighbours.size; j++)
1499 if (memcmp (&(devices + i)->bdaddr, &(neighbours.devices[j]), sizeof (bdaddr_t)) == 0)
1502 fprintf (stderr, "LOG : the device already exists on the list\n"); //FIXME debugging message
1509 char addr[19] = { 0 };
1511 ba2str (&(devices +i)->bdaddr, addr);
1512 fprintf (stderr, "LOG : %s was added to the list\n", addr); //FIXME debugging message
1513 GNUNET_memcpy (&(neighbours.devices[neighbours.size++]), &(devices + i)->bdaddr, sizeof (bdaddr_t));
1521 int connection_successful = 0;
1522 struct sockaddr_rc addr_rc = { 0 };
1524 addr_rc.rc_family = AF_BLUETOOTH;
1526 /* Try to connect to a new device from the list */
1527 while (neighbours.pos < neighbours.size)
1529 /* Check if we are already connected to this device */
1530 if (neighbours.fds[neighbours.pos] == -1)
1533 memset (&addr_rc.rc_bdaddr, 0, sizeof (addr_rc.rc_bdaddr));
1534 GNUNET_memcpy (&addr_rc.rc_bdaddr, &(neighbours.devices[neighbours.pos]), sizeof (addr_rc.rc_bdaddr));
1536 addr_rc.rc_channel = get_channel (dev, addr_rc.rc_bdaddr);
1538 *sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1539 if ( (-1 < *sendsocket) &&
1540 (0 == connect (*sendsocket,
1541 (struct sockaddr *) &addr_rc,
1542 sizeof (addr_rc))) )
1544 neighbours.fds[neighbours.pos++] = *sendsocket;
1545 connection_successful = 1;
1546 char addr[19] = { 0 };
1547 ba2str (&(neighbours.devices[neighbours.pos - 1]), addr);
1548 fprintf (stderr, "LOG : Connected to %s\n", addr);
1553 char addr[19] = { 0 };
1554 errno_copy = errno; //Save a copy for later
1556 if (-1 != *sendsocket)
1558 (void) close (*sendsocket);
1561 ba2str (&(neighbours.devices[neighbours.pos]), addr);
1563 "LOG : Couldn't connect on device %s, error : %s\n",
1566 if (errno != ECONNREFUSED) //FIXME be sure that this works
1568 fprintf (stderr, "LOG : Removes %d device from the list\n", neighbours.pos);
1569 /* Remove the device from the list */
1570 GNUNET_memcpy (&neighbours.devices[neighbours.pos], &neighbours.devices[neighbours.size - 1], sizeof (bdaddr_t));
1571 memset (&neighbours.devices[neighbours.size - 1], 0, sizeof (bdaddr_t));
1572 neighbours.fds[neighbours.pos] = neighbours.fds[neighbours.size - 1];
1573 neighbours.fds[neighbours.size - 1] = -1;
1574 neighbours.size -= 1;
1577 neighbours.pos += 1;
1579 if (neighbours.pos >= neighbours.size)
1584 if (loops == MAX_LOOPS) //don't get stuck trying to connect to one device
1590 fprintf (stderr, "LOG : Search for a new device\n"); //FIXME debugging message
1591 neighbours.pos += 1;
1595 /* Cycle on the list */
1596 if (neighbours.pos == neighbours.size)
1599 searching_devices_count += 1;
1601 if (searching_devices_count == MAX_LOOPS)
1603 fprintf (stderr, "LOG : Force to inquiry for new devices\n");
1604 searching_devices_count = 0;
1605 goto inquiry_devices;
1608 /* If a new device wasn't found, search an old one */
1609 if (connection_successful == 0)
1611 int loop_check = neighbours.pos;
1612 while (neighbours.fds[neighbours.pos] == -1)
1614 if (neighbours.pos == neighbours.size)
1617 if (neighbours.pos == loop_check)
1619 if (errno_copy == ECONNREFUSED)
1621 fprintf (stderr, "LOG : No device found. Go back and search again\n"); //FIXME debugging message
1624 goto search_for_devices;
1628 return 1; // Skip the broadcast message
1632 neighbours.pos += 1;
1635 *sendsocket = neighbours.fds[neighbours.pos++];
1643 * Main function of the helper. This code accesses a bluetooth interface
1644 * forwards traffic in both directions between the bluetooth interface and
1645 * stdin/stdout of this process. Error messages are written to stderr.
1647 * @param argc number of arguments, must be 2
1648 * @param argv arguments only argument is the name of the interface (i.e. 'hci0')
1649 * @return 0 on success (never happens, as we don't return unless aborted), 1 on error
1651 **** similar to gnunet-helper-transport-wlan.c ****
1654 main (int argc, char *argv[])
1657 struct HardwareInfos dev;
1658 char readbuf[MAXLINE];
1663 struct MessageStreamTokenizer *stdin_mst;
1665 int crt_rfds = 0, rfds_list[MAX_PORTS];
1666 int broadcast, sendsocket;
1668 /* Assert privs so we can modify the firewall rules! */
1670 #ifdef HAVE_SETRESUID
1671 uid_t uid = getuid ();
1673 if (0 != setresuid (uid, 0, 0))
1676 "Failed to setresuid to root: %s\n",
1681 if (0 != seteuid (0))
1684 "Failed to seteuid back to root: %s\n", strerror (errno));
1690 /* Make use of SGID capabilities on POSIX */
1691 memset (&dev, 0, sizeof (dev));
1692 dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1693 raw_eno = errno; /* remember for later */
1695 /* Now that we've dropped root rights, we can do error checking */
1698 fprintf (stderr, "You must specify the name of the interface as the first \
1699 and only argument to this program.\n");
1700 if (-1 != dev.fd_rfcomm)
1701 (void) close (dev.fd_rfcomm);
1705 if (-1 == dev.fd_rfcomm)
1707 fprintf (stderr, "Failed to create a RFCOMM socket: %s\n", strerror (raw_eno));
1710 if (dev.fd_rfcomm >= FD_SETSIZE)
1712 fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1713 dev.fd_rfcomm, FD_SETSIZE);
1714 (void) close (dev.fd_rfcomm);
1717 if (0 != test_bluetooth_interface (argv[1]))
1719 (void) close (dev.fd_rfcomm);
1722 strncpy (dev.iface, argv[1], IFNAMSIZ);
1723 if (0 != open_device (&dev))
1725 (void) close (dev.fd_rfcomm);
1731 uid_t uid = getuid ();
1732 #ifdef HAVE_SETRESUID
1733 if (0 != setresuid (uid, uid, uid))
1735 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1736 if (-1 != dev.fd_rfcomm)
1737 (void) close (dev.fd_rfcomm);
1741 if (0 != (setuid (uid) | seteuid (uid)))
1743 fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
1744 if (-1 != dev.fd_rfcomm)
1745 (void) close (dev.fd_rfcomm);
1751 /* Send MAC address of the bluetooth interface to STDOUT first */
1753 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
1755 macmsg.hdr.size = htons (sizeof (macmsg));
1756 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
1757 GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1758 GNUNET_memcpy (write_std.buf, &macmsg, sizeof (macmsg));
1759 write_std.size = sizeof (macmsg);
1763 stdin_mst = mst_create (&stdin_send_hw, &dev);
1767 * TODO : I should make the time out of a mac endpoint smaller and check if the rate
1768 * from get_wlan_header (plugin_transport_bluetooth.c) is correct.
1777 if ((0 == write_pout.size) && (1 == stdin_open))
1779 FD_SET (STDIN_FILENO, &rfds);
1780 maxfd = MAX (maxfd, STDIN_FILENO);
1782 if (0 == write_std.size)
1784 FD_SET (dev.fd_rfcomm, &rfds);
1785 maxfd = MAX (maxfd, dev.fd_rfcomm);
1788 for (i = 0; i < crt_rfds; i++) // it can receive messages from multiple devices
1790 FD_SET (rfds_list[i], &rfds);
1791 maxfd = MAX (maxfd, rfds_list[i]);
1794 if (0 < write_std.size)
1796 FD_SET (STDOUT_FILENO, &wfds);
1797 maxfd = MAX (maxfd, STDOUT_FILENO);
1799 if (0 < write_pout.size) //it can send messages only to one device per loop
1801 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *frame;
1802 /* Get the destination address */
1803 frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) write_pout.buf;
1805 if (memcmp (&frame->addr1, &dev.pl_mac,
1806 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1809 memset (&write_pout, 0, sizeof (write_pout)); //clear the buffer
1811 else if (memcmp (&frame->addr1, &broadcast_address,
1812 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1814 fprintf (stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n", dev.iface, neighbours.pos, neighbours.size); //FIXME: debugging message
1816 if (send_broadcast(&dev, &sendsocket) != 0) //if the searching wasn't successful don't get stuck on the select stage
1819 memset (&write_pout, 0, sizeof (write_pout)); //remove the message
1820 fprintf (stderr, "LOG : Skipping the broadcast message (pos %d, size %d)\n", neighbours.pos, neighbours.size);
1824 FD_SET (sendsocket, &wfds);
1825 maxfd = MAX (maxfd, sendsocket);
1832 /* Search if the address already exists on the list */
1833 for (i = 0; i < neighbours.size; i++)
1835 if (memcmp (&frame->addr1, &(neighbours.devices[i]), sizeof (bdaddr_t)) == 0)
1838 if (neighbours.fds[i] != -1)
1840 found = 1; //save the position where it was found
1841 FD_SET (neighbours.fds[i], &wfds);
1842 maxfd = MAX (maxfd, neighbours.fds[i]);
1843 sendsocket = neighbours.fds[i];
1844 fprintf (stderr, "LOG: the address was found in the list\n");
1852 struct sockaddr_rc addr = { 0 };
1854 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,
1855 frame->addr1.mac[5], frame->addr1.mac[4], frame->addr1.mac[3],
1856 frame->addr1.mac[2], frame->addr1.mac[1], frame->addr1.mac[0]); //FIXME: debugging message
1858 sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1862 fprintf (stderr, "Failed to create a RFCOMM socket (sending stage): %s\n",
1867 GNUNET_memcpy (&addr.rc_bdaddr, &frame->addr1, sizeof (bdaddr_t));
1868 addr.rc_family = AF_BLUETOOTH;
1869 addr.rc_channel = get_channel (&dev, addr.rc_bdaddr);
1873 status = connect (sendsocket, (struct sockaddr *) &addr, sizeof (addr));
1874 if (0 != status && errno != EAGAIN)
1876 if (errno == ECONNREFUSED && tries < 2)
1878 fprintf (stderr, "LOG : %.*s failed to connect. Trying again!\n", IFNAMSIZ, dev.iface);
1882 else if (errno == EBADF)
1884 fprintf (stderr, "LOG : %s failed to connect : %s. Skip it!\n", dev.iface, strerror (errno));
1885 memset (&write_pout, 0, sizeof (write_pout));
1890 fprintf (stderr, "LOG : %s failed to connect : %s. Try again later!\n", dev.iface, strerror (errno));
1891 memset (&write_pout, 0, sizeof (write_pout));
1898 FD_SET (sendsocket, &wfds);
1899 maxfd = MAX (maxfd, sendsocket);
1900 fprintf (stderr, "LOG : Connection successful\n");
1901 if (pos != 0) // save the socket
1903 neighbours.fds[pos] = sendsocket;
1907 /* Add the new device to the discovered devices list */
1908 if (neighbours.size < MAX_PORTS)
1910 neighbours.fds[neighbours.size] = sendsocket;
1911 GNUNET_memcpy (&(neighbours.devices[neighbours.size++]), &addr.rc_bdaddr, sizeof (bdaddr_t));
1915 fprintf (stderr, "The top limit for the discovarable devices' list was reached\n");
1925 /* Select a fd which is ready for action :) */
1927 int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
1928 if ((-1 == retval) && (EINTR == errno))
1930 if (0 > retval && errno != EBADF) // we handle BADF errors later
1932 fprintf (stderr, "select failed: %s\n", strerror (errno));
1936 if (FD_ISSET (STDOUT_FILENO , &wfds))
1939 write (STDOUT_FILENO, write_std.buf + write_std.pos,
1940 write_std.size - write_std.pos);
1943 fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1946 write_std.pos += ret;
1947 if (write_std.pos == write_std.size)
1952 fprintf (stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); //FIXME: debugging message
1955 if (-1 != sendsocket)
1957 if (FD_ISSET (sendsocket , &wfds))
1959 ssize_t ret = write (sendsocket,
1960 write_pout.buf + write_std.pos,
1961 write_pout.size - write_pout.pos);
1962 if (0 > ret) //FIXME should I first check the error type?
1964 fprintf (stderr, "Failed to write to bluetooth device: %s. Closing the socket!\n",
1966 for (i = 0; i < neighbours.size; i++)
1968 if (neighbours.fds[i] == sendsocket)
1970 (void) close(sendsocket);
1971 neighbours.fds[i] = -1;
1975 /* Remove the message */
1976 memset (&write_pout.buf + write_std.pos, 0, (write_pout.size - write_pout.pos));
1977 write_pout.pos = 0 ;
1978 write_pout.size = 0;
1982 write_pout.pos += ret;
1983 if ((write_pout.pos != write_pout.size) && (0 != ret))
1985 /* We should not get partial sends with packet-oriented devices... */
1986 fprintf (stderr, "Write error, partial send: %u/%u\n",
1987 (unsigned int) write_pout.pos,
1988 (unsigned int) write_pout.size);
1992 if (write_pout.pos == write_pout.size)
1995 write_pout.size = 0;
1997 fprintf (stderr, "LOG : %s sends a message to a DEVICE\n", dev.iface); //FIXME: debugging message
2001 for (i = 0; i <= maxfd; i++)
2003 if (FD_ISSET (i, &rfds))
2005 if (i == STDIN_FILENO)
2008 read (i, readbuf, sizeof (readbuf));
2012 "Read error from STDIN: %s\n",
2018 /* stop reading... */
2023 mst_receive (stdin_mst, readbuf, ret);
2024 fprintf (stderr, "LOG : %s receives a message from STDIN\n", dev.iface); //FIXME: debugging message
2027 else if (i == dev.fd_rfcomm)
2030 struct sockaddr_rc addr = { 0 };
2031 unsigned int opt = sizeof (addr);
2033 readsocket = accept (dev.fd_rfcomm, (struct sockaddr *) &addr, &opt);
2034 fprintf(stderr, "LOG : %s accepts a message\n", dev.iface); //FIXME: debugging message
2035 if (readsocket == -1)
2037 fprintf (stderr, "Failed to accept a connection on interface: %.*s\n", IFNAMSIZ,
2043 FD_SET (readsocket, &rfds);
2044 maxfd = MAX (maxfd, readsocket);
2046 if (crt_rfds < MAX_PORTS)
2047 rfds_list[crt_rfds++] = readsocket;
2050 fprintf (stderr, "The limit for the read file descriptors list was \
2059 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
2061 fprintf (stderr, "LOG : %s reads something from the socket\n", dev.iface);//FIXME : debugging message
2062 rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
2064 read_from_the_socket ((void *)&i, (unsigned char *) &rrm->frame,
2065 sizeof (write_std.buf)
2066 - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2067 + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2074 /* Remove the socket from the list */
2075 for (j = 0; j < crt_rfds; j++)
2077 if (rfds_list[j] == i)
2079 rfds_list[j] ^= rfds_list[crt_rfds - 1];
2080 rfds_list[crt_rfds - 1] ^= rfds_list[j];
2081 rfds_list[j] ^= rfds_list[crt_rfds - 1];
2087 fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
2090 if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2092 write_std.size = ret
2093 + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2094 - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2095 rrm->header.size = htons (write_std.size);
2096 rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2103 /* Error handling, try to clean up a bit at least */
2104 mst_destroy (stdin_mst);
2106 sdp_close (dev.session);
2107 (void) close (dev.fd_rfcomm);
2108 if (-1 != sendsocket)
2109 (void) close (sendsocket);
2111 for (i = 0; i < crt_rfds; i++)
2112 (void) close (rfds_list[i]);
2114 for (i = 0; i < neighbours.size; i++)
2115 (void) close (neighbours.fds[i]);
2117 struct HardwareInfos dev;
2118 struct GNUNET_NETWORK_Handle *sendsocket;
2119 struct GNUNET_NETWORK_FDSet *rfds;
2120 struct GNUNET_NETWORK_FDSet *wfds;
2121 struct GNUNET_NETWORK_Handle *rfds_list[MAX_PORTS];
2122 char readbuf[MAXLINE] = { 0 };
2123 SOCKADDR_BTH acc_addr = { 0 };
2124 int addr_len = sizeof (SOCKADDR_BTH);
2125 int broadcast, i, stdin_open, crt_rfds = 0;
2126 HANDLE stdin_handle = GetStdHandle (STD_INPUT_HANDLE);
2127 HANDLE stdout_handle = GetStdHandle (STD_OUTPUT_HANDLE);
2128 struct MessageStreamTokenizer *stdin_mst;
2130 /* check the handles */
2131 if (stdin_handle == INVALID_HANDLE_VALUE)
2133 fprintf (stderr, "Failed to get the stdin handle\n");
2137 if (stdout_handle == INVALID_HANDLE_VALUE)
2139 fprintf (stderr, "Failed to get the stdout handle\n");
2143 /* initialize windows sockets */
2144 initialize_windows_sockets();
2146 // /* test bluetooth socket family support */ --> it return false because the GNUNET_NETWORK_test_pf should also receive the type of socket (BTHPROTO_RFCOMM)
2147 // if (GNUNET_NETWORK_test_pf (AF_BTH) != GNUNET_OK)
2149 // fprintf (stderr, "AF_BTH family is not supported\n");
2153 /* create the socket */
2154 dev.handle = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
2155 if (dev.handle == NULL)
2157 fprintf (stderr, "Failed to create RFCOMM socket: ");
2163 if (open_device (&dev) == -1)
2165 fprintf (stderr, "Failed to open the device\n");
2167 if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
2169 fprintf (stderr, "Failed to close the socket!\n");
2175 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (dev.handle, 1) )
2177 fprintf (stderr, "Failed to change the socket mode\n");
2181 memset (&write_std, 0, sizeof (write_std));
2182 memset (&write_pout, 0, sizeof (write_pout));
2185 rfds = GNUNET_NETWORK_fdset_create ();
2186 wfds = GNUNET_NETWORK_fdset_create ();
2188 /* Send MAC address of the bluetooth interface to STDOUT first */
2190 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
2192 macmsg.hdr.size = htons (sizeof (macmsg));
2193 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
2194 GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy));
2195 GNUNET_memcpy (write_std.buf, &macmsg, sizeof (macmsg));
2196 write_std.size = sizeof (macmsg);
2200 stdin_mst = mst_create (&stdin_send_hw, &dev);
2205 int stdout_pos = -1;
2212 sendsocket = NULL; //FIXME ???memleaks
2214 GNUNET_NETWORK_fdset_zero (rfds);
2215 if ((0 == write_pout.size) && (1 == stdin_open))
2219 GNUNET_NETWORK_fdset_handle_set (rfds, (struct GNUNET_DISK_FileHandle*) &stdin_handle);
2222 if (0 == write_std.size)
2225 GNUNET_NETWORK_fdset_set (rfds, dev.handle);
2228 for (i = 0; i < crt_rfds; i++)
2231 GNUNET_NETWORK_fdset_set (rfds, rfds_list[i]);
2234 GNUNET_NETWORK_fdset_zero (wfds);
2235 if (0 < write_std.size)
2238 GNUNET_NETWORK_fdset_handle_set (wfds, (struct GNUNET_DISK_FileHandle*) &stdout_handle);
2239 // printf ("%s\n", write_std.buf);
2240 // memset (write_std.buf, 0, write_std.size);
2241 // write_std.size = 0;
2244 if (0 < write_pout.size)
2246 if (strcmp (argv[1], "ff:ff:ff:ff:ff:ff") == 0) {
2247 fprintf(stderr, "LOG: BROADCAST! Skipping the message\n");
2250 memset (write_pout.buf, 0, write_pout.size);
2251 write_pout.size = 0;
2256 fprintf (stderr, "LOG : has a new message for %s\n", argv[1]);
2257 sendsocket = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
2259 if (sendsocket == NULL)
2261 fprintf (stderr, "Failed to create RFCOMM socket: \n");
2266 memset (&addr, 0, sizeof (addr));
2267 //addr.addressFamily = AF_BTH;
2269 WSAStringToAddress (argv[1], AF_BTH, NULL, (LPSOCKADDR) &addr, &addr_len))
2271 fprintf (stderr, "Failed to translate the address: ");
2275 addr.port = get_channel (argv[1]);
2276 if (addr.port == -1)
2278 fprintf (stderr, "Couldn't find the sdp service for the address: %s\n", argv[1]);
2279 memset (write_pout.buf, 0, write_pout.size);
2280 write_pout.size = 0;
2281 broadcast = 1; //skipping the select part
2285 if (GNUNET_OK != GNUNET_NETWORK_socket_connect (sendsocket, (LPSOCKADDR)&addr, addr_len))
2287 fprintf (stderr, "Failed to connect: ");
2292 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (sendsocket, 1) )
2294 fprintf (stderr, "Failed to change the socket mode\n");
2298 GNUNET_NETWORK_fdset_set (wfds, sendsocket);
2305 int retval = GNUNET_NETWORK_socket_select (rfds, wfds, NULL, GNUNET_TIME_relative_get_forever_());
2308 fprintf (stderr, "Select error\n");
2311 //if (GNUNET_NETWORK_fdset_isset (wfds, (struct GNUNET_NETWORK_Handle*)&stdout_handle))
2312 if (retval == stdout_pos)
2314 fprintf(stderr, "LOG : sends a message to STDOUT\n"); //FIXME: debugging message
2316 //ret = GNUNET_NETWORK_socket_send ((struct GNUNET_NETWORK_Handle *)&stdout_handle, write_std.buf + write_std.pos, write_std.size - write_std.pos);
2317 //ret = write (STDOUT_FILENO, write_std.buf + write_std.pos, write_std.size - write_std.pos);
2319 if (FALSE == WriteFile (stdout_handle, write_std.buf + write_std.pos, write_std.size - write_std.pos, &ret, NULL))
2321 fprintf (stderr, "Failed to write to STDOUT: ");
2328 fprintf (stderr, "Failed to write to STDOUT\n");
2332 write_std.pos += ret;
2333 if (write_std.pos == write_std.size)
2339 if (sendsocket != NULL)
2341 if (GNUNET_NETWORK_fdset_isset (wfds, sendsocket))
2344 ret = GNUNET_NETWORK_socket_send (sendsocket, write_pout.buf + write_pout.pos,
2345 write_pout.size - write_pout.pos);
2347 if (GNUNET_SYSERR == ret)
2349 fprintf (stderr, "Failed to send to the socket. Closing the socket. Error: \n");
2351 if (GNUNET_NETWORK_socket_close (sendsocket) != GNUNET_OK)
2353 fprintf (stderr, "Failed to close the sendsocket!\n");
2360 write_pout.pos += ret;
2361 if ((write_pout.pos != write_pout.size) && (0 != ret))
2363 /* we should not get partial sends with packet-oriented devices... */
2364 fprintf (stderr, "Write error, partial send: %u/%u\n",
2365 (unsigned int) write_pout.pos,
2366 (unsigned int) write_pout.size);
2370 if (write_pout.pos == write_pout.size)
2373 write_pout.size = 0;
2376 fprintf(stderr, "LOG : sends a message to a DEVICE\n"); //FIXME: debugging message
2381 //if (GNUNET_NETWORK_fdset_isset (rfds, (struct GNUNET_NETWORK_Handle*)&stdin_handle))
2382 if (retval == stdin_pos)
2385 //ret = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)&stdin_handle, readbuf, sizeof (write_pout.buf));
2386 //ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
2388 if (FALSE == ReadFile (stdin_handle, readbuf, sizeof (readbuf), &ret, NULL)) /* do nothing asynchronous */
2390 fprintf (stderr, "Read error from STDIN: ");
2396 /* stop reading... */
2399 mst_receive (stdin_mst, readbuf, ret);
2400 fprintf (stderr, "LOG : receives a message from STDIN\n"); //FIXME: debugging message
2404 if (GNUNET_NETWORK_fdset_isset (rfds, dev.handle))
2406 fprintf (stderr, "LOG: accepting connection\n");
2407 struct GNUNET_NETWORK_Handle *readsocket;
2408 readsocket = GNUNET_NETWORK_socket_accept (dev.handle, (LPSOCKADDR)&acc_addr, &addr_len);
2409 if (readsocket == NULL)
2411 fprintf (stderr, "Accept error %d: ", GetLastError());
2417 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (readsocket, 1) )
2419 fprintf (stderr, "Failed to change the socket mode\n");
2422 GNUNET_NETWORK_fdset_set (rfds, readsocket);
2424 if (crt_rfds < MAX_PORTS)
2425 rfds_list[crt_rfds++] = readsocket;
2428 fprintf (stderr, "The limit for the read file descriptors list was reached\n");
2434 for (i = 0; i < crt_rfds; i++)
2436 if (GNUNET_NETWORK_fdset_isset (rfds, rfds_list[i]))
2438 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
2440 fprintf (stderr, "LOG: reading something from the socket\n");//FIXME : debugging message
2441 rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
2442 ret = read_from_the_socket (rfds_list[i], (unsigned char *) &rrm->frame,
2443 sizeof (write_std.buf)
2444 - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2445 + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2450 //TODO remove the socket from the list
2451 if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2453 fprintf (stderr, "Failed to close the sendsocket!\n");
2457 fprintf (stderr, "Read error from raw socket: ");
2462 if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2464 write_std.size = ret
2465 + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2466 - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2467 rrm->header.size = htons (write_std.size);
2468 rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2476 mst_destroy (stdin_mst);
2479 if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
2481 fprintf (stderr, "Failed to close the socket!\n");
2485 for (i = 0; i < crt_rfds; i++)
2487 if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2489 fprintf (stderr, "Failed to close the socket!\n");
2496 return 1; /* we never exit 'normally' */