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 SPDX-License-Identifier: AGPL3.0-or-later
22 #include "gnunet_config.h"
26 #include "gnunet_util_lib.h"
31 #include <bluetooth/bluetooth.h>
32 #include <bluetooth/hci.h>
33 #include <bluetooth/hci_lib.h>
34 #include <bluetooth/rfcomm.h>
35 #include <bluetooth/sdp.h>
36 #include <bluetooth/sdp_lib.h>
41 #include <sys/ioctl.h>
42 #include <sys/param.h>
43 #include <sys/socket.h>
45 #include <sys/types.h>
49 #include "plugin_transport_wlan.h"
50 #include "gnunet_protocols.h"
54 * Maximum number of ports assignable for RFCOMMM protocol.
59 * Maximum size of a message allowed in either direction
60 * (used for our receive and sent buffers).
66 * Maximum number of loops without inquiring for new devices.
71 /* Maximum size of the interface's name */
78 * A copy of the MAC Address.
80 struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy {
81 UINT8 mac[MAC_ADDR_SIZE];
85 * The UUID used for the SDP service.
86 * {31191E56-FA7E-4517-870E-71B86BBCC52F}
88 #define GNUNET_BLUETOOTH_SDP_UUID \
90 0x31, 0x19, 0x1E, 0x56, \
94 0x71, 0xB8, 0x6B, 0xBC, 0xC5, 0x2F \
99 * In bluez library, the maximum name length of a device is 8
101 #define BLUEZ_DEVNAME_SIZE 8
104 * struct for storing the information of the hardware. There is only
107 struct HardwareInfos {
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).
146 * How many bytes of data are stored in 'buf' for transmission right now?
147 * Data always starts at offset 0 and extends to 'size'.
152 * How many bytes that were stored in 'buf' did we already write to the
153 * destination? Always smaller than 'size'.
158 * Buffered data; twice the maximum allowed message size as we add some
161 char buf[MAXLINE * 2];
166 * Devices buffer used to keep a list with all the discoverable devices in
167 * order to send them HELLO messages one by one when it receive a broadcast message.
169 struct BroadcastMessages {
170 /* List with the discoverable devices' addresses */
171 bdaddr_t devices[MAX_PORTS];
173 /* List with the open sockets */
177 /* The number of the devices */
180 /* The current position */
188 * Address used to identify the broadcast messages.
190 static struct GNUNET_TRANSPORT_WLAN_MacAddress broadcast_address = { { 255, 255, 255, 255, 255, 255 } };
193 * Buffer with the discoverable devices.
195 static struct BroadcastMessages neighbours;
197 static int searching_devices_count = 0;
201 * Buffer for data read from stdin to be transmitted to the bluetooth device
203 static struct SendBuffer write_pout;
206 * Buffer for data read from the bluetooth device to be transmitted to stdout.
208 static struct SendBuffer write_std;
211 /* ****** this are the same functions as the ones used in gnunet-helper-transport-wlan.c ****** */
214 * To what multiple do we align messages? 8 byte should suffice for everyone
217 #define ALIGN_FACTOR 8
220 * Smallest supported message.
222 #define MIN_BUFFER_SIZE sizeof(struct GNUNET_MessageHeader)
226 * Functions with this signature are called whenever a
227 * complete message is received by the tokenizer.
230 * @param message the actual message
232 typedef void (*MessageTokenizerCallback) (void *cls,
234 GNUNET_MessageHeader *
238 * Handle to a message stream tokenizer.
240 struct MessageStreamTokenizer {
242 * Function to call on completed messages.
244 MessageTokenizerCallback cb;
252 * Size of the buffer (starting at 'hdr').
257 * How many bytes in buffer have we already processed?
262 * How many bytes in buffer are valid right now?
267 * Beginning of the buffer. Typed like this to force alignment.
269 struct GNUNET_MessageHeader *hdr;
274 * Create a message stream tokenizer.
276 * @param cb function to call on completed messages
277 * @param cb_cls closure for cb
278 * @return handle to tokenizer
280 static struct MessageStreamTokenizer *
281 mst_create(MessageTokenizerCallback cb,
284 struct MessageStreamTokenizer *ret;
286 ret = malloc(sizeof(struct MessageStreamTokenizer));
289 fprintf(stderr, "Failed to allocate buffer for tokenizer\n");
292 ret->hdr = malloc(MIN_BUFFER_SIZE);
293 if (NULL == ret->hdr)
295 fprintf(stderr, "Failed to allocate buffer for alignment\n");
298 ret->curr_buf = MIN_BUFFER_SIZE;
300 ret->cb_cls = cb_cls;
308 * Add incoming data to the receive buffer and call the
309 * callback for all complete messages.
311 * @param mst tokenizer to use
312 * @param buf input data to add
313 * @param size number of bytes in buf
314 * @return GNUNET_OK if we are done processing (need more data)
315 * GNUNET_SYSERR if the data stream is corrupt
318 mst_receive(struct MessageStreamTokenizer *mst,
319 const char *buf, size_t size)
321 const struct GNUNET_MessageHeader *hdr;
326 unsigned long offset;
330 ibuf = (char *)mst->hdr;
334 if (mst->pos < mst->off)
336 //fprintf (stderr, "We processed too many bytes!\n");
337 return GNUNET_SYSERR;
339 if ((mst->curr_buf - mst->off < sizeof(struct GNUNET_MessageHeader)) ||
340 (0 != (mst->off % ALIGN_FACTOR)))
342 /* need to align or need more space */
343 mst->pos -= mst->off;
344 memmove(ibuf, &ibuf[mst->off], mst->pos);
347 if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader))
350 GNUNET_MIN(sizeof(struct GNUNET_MessageHeader) -
351 (mst->pos - mst->off), size);
352 GNUNET_memcpy(&ibuf[mst->pos], buf, delta);
357 if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader))
359 //FIXME should I reset ??
364 hdr = (const struct GNUNET_MessageHeader *)&ibuf[mst->off];
365 want = ntohs(hdr->size);
366 if (want < sizeof(struct GNUNET_MessageHeader))
369 "Received invalid message from stdin\n");
370 return GNUNET_SYSERR;
372 if ((mst->curr_buf - mst->off < want) &&
375 /* need more space */
376 mst->pos -= mst->off;
377 memmove(ibuf, &ibuf[mst->off], mst->pos);
380 if (want > mst->curr_buf)
384 fprintf(stderr, "Error! We should proceeded 0 bytes\n");
385 return GNUNET_SYSERR;
387 mst->hdr = realloc(mst->hdr, want);
388 if (NULL == mst->hdr)
390 fprintf(stderr, "Failed to allocate buffer for alignment\n");
393 ibuf = (char *)mst->hdr;
394 mst->curr_buf = want;
396 hdr = (const struct GNUNET_MessageHeader *)&ibuf[mst->off];
397 if (mst->pos - mst->off < want)
399 delta = GNUNET_MIN(want - (mst->pos - mst->off), size);
400 if (mst->pos + delta > mst->curr_buf)
402 fprintf(stderr, "The size of the buffer will be exceeded!\n");
403 return GNUNET_SYSERR;
405 GNUNET_memcpy(&ibuf[mst->pos], buf, delta);
410 if (mst->pos - mst->off < want)
412 //FIXME should I use this?
417 mst->cb(mst->cb_cls, hdr);
419 if (mst->off == mst->pos)
421 /* reset to beginning of buffer, it's free right now! */
428 fprintf(stderr, "There should some valid bytes in the buffer on this stage\n");
429 return GNUNET_SYSERR;
433 if (size < sizeof(struct GNUNET_MessageHeader))
435 offset = (unsigned long)buf;
436 need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
437 if (GNUNET_NO == need_align)
439 /* can try to do zero-copy and process directly from original buffer */
440 hdr = (const struct GNUNET_MessageHeader *)buf;
441 want = ntohs(hdr->size);
442 if (want < sizeof(struct GNUNET_MessageHeader))
445 "Received invalid message from stdin\n");
448 return GNUNET_SYSERR;
451 break; /* or not, buffer incomplete, so copy to private buffer... */
452 mst->cb(mst->cb_cls, hdr);
458 /* need to copy to private buffer to align;
459 * yes, we go a bit more spagetti than usual here */
465 if (size + mst->pos > mst->curr_buf)
467 mst->hdr = realloc(mst->hdr, size + mst->pos);
468 if (NULL == mst->hdr)
470 fprintf(stderr, "Failed to allocate buffer for alignment\n");
473 ibuf = (char *)mst->hdr;
474 mst->curr_buf = size + mst->pos;
476 if (mst->pos + size > mst->curr_buf)
479 "Assertion failed\n");
482 GNUNET_memcpy(&ibuf[mst->pos], buf, size);
489 * Destroys a tokenizer.
491 * @param mst tokenizer to destroy
494 mst_destroy(struct MessageStreamTokenizer *mst)
501 * Calculate crc32, the start of the calculation
503 * @param buf buffer to calc the crc
504 * @param len len of the buffer
508 calc_crc_osdep(const unsigned char *buf, size_t len)
510 static const unsigned long int crc_tbl_osdep[256] = {
511 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
512 0xE963A535, 0x9E6495A3,
513 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
514 0xE7B82D07, 0x90BF1D91,
515 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
516 0xF4D4B551, 0x83D385C7,
517 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
518 0xFA0F3D63, 0x8D080DF5,
519 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
520 0xD20D85FD, 0xA50AB56B,
521 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
522 0xDCD60DCF, 0xABD13D59,
523 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
524 0xCFBA9599, 0xB8BDA50F,
525 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
526 0xC1611DAB, 0xB6662D3D,
527 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
528 0x9FBFE4A5, 0xE8B8D433,
529 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
530 0x91646C97, 0xE6635C01,
531 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
532 0x8208F4C1, 0xF50FC457,
533 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
534 0x8CD37CF3, 0xFBD44C65,
535 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
536 0xA4D1C46D, 0xD3D6F4FB,
537 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
538 0xAA0A4C5F, 0xDD0D7CC9,
539 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
540 0xB966D409, 0xCE61E49F,
541 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
542 0xB7BD5C3B, 0xC0BA6CAD,
543 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
544 0x04DB2615, 0x73DC1683,
545 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
546 0x0A00AE27, 0x7D079EB1,
547 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
548 0x196C3671, 0x6E6B06E7,
549 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
550 0x17B7BE43, 0x60B08ED5,
551 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
552 0x3FB506DD, 0x48B2364B,
553 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
554 0x316E8EEF, 0x4669BE79,
555 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
556 0x220216B9, 0x5505262F,
557 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
558 0x2CD99E8B, 0x5BDEAE1D,
559 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
560 0x72076785, 0x05005713,
561 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
562 0x7CDCEFB7, 0x0BDBDF21,
563 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
564 0x6FB077E1, 0x18B74777,
565 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
566 0x616BFFD3, 0x166CCF45,
567 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
568 0x4969474D, 0x3E6E77DB,
569 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
570 0x47B2CF7F, 0x30B5FFE9,
571 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
572 0x54DE5729, 0x23D967BF,
573 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
574 0x5A05DF1B, 0x2D02EF8D
577 unsigned long crc = 0xFFFFFFFF;
579 for (; len > 0; len--, buf++)
580 crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
586 * Calculate and check crc of the bluetooth packet
588 * @param buf buffer of the packet, with len + 4 bytes of data,
589 * the last 4 bytes being the checksum
590 * @param len length of the payload in data
591 * @return 0 on success (checksum matches), 1 on error
594 check_crc_buf_osdep(const unsigned char *buf, size_t len)
598 crc = calc_crc_osdep(buf, len);
600 if (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
601 ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3])
608 /* ************** end of clone ***************** */
612 * Function used to get the code of last error and to print the type of error.
617 LPVOID lpMsgBuf = NULL;
619 if (FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
620 NULL, GetLastError(), 0, (LPTSTR)&lpMsgBuf, 0, NULL))
621 fprintf(stderr, "%s\n", (char *)lpMsgBuf);
623 fprintf(stderr, "Failed to format the message for the last error! Error number : %d\n", GetLastError());
627 * Function used to initialize the Windows Sockets
630 initialize_windows_sockets()
633 WORD wVersionRequested = MAKEWORD(2, 0);
635 if (WSAStartup(wVersionRequested, &wsaData) != NO_ERROR)
637 fprintf(stderr, "Error initializing window sockets!\n");
644 * Function used to convert the GUID.
645 * @param bytes the GUID represented as a char array
646 * @param uuid pointer to the GUID
649 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);
710 /* get the port on which we are listening on */
711 memset(&addr, 0, sizeof(SOCKADDR_BTH));
712 fd = GNUNET_NETWORK_get_fd(dev->handle);
715 fprintf(stderr, "Failed to get the file descriptor\n");
718 if (SOCKET_ERROR == getsockname(fd, (SOCKADDR*)&addr, &addr_len))
720 fprintf(stderr, "Failed to get the port on which we are listening on: \n");
725 /* save the device address */
726 GNUNET_memcpy(&dev->pl_mac, &addr.btAddr, sizeof(BTH_ADDR));
728 /* set the address information */
729 memset(&addr_info, 0, sizeof(CSADDR_INFO));
730 addr_info.iProtocol = BTHPROTO_RFCOMM;
731 addr_info.iSocketType = SOCK_STREAM;
732 addr_info.LocalAddr.lpSockaddr = (LPSOCKADDR)&addr;
733 addr_info.LocalAddr.iSockaddrLength = sizeof(addr);
734 addr_info.RemoteAddr.lpSockaddr = (LPSOCKADDR)&addr;
735 addr_info.RemoteAddr.iSockaddrLength = sizeof(addr);
737 convert_guid((char *)uuid, &guid);
739 /* register the service */
740 memset(&wqs, 0, sizeof(WSAQUERYSET));
741 wqs.dwSize = sizeof(WSAQUERYSET);
742 wqs.dwNameSpace = NS_BTH;
743 wqs.lpszServiceInstanceName = "GNUnet Bluetooth Service";
744 wqs.lpszComment = "This is the service used by the GNUnnet plugin transport";
745 wqs.lpServiceClassId = &guid;
746 wqs.dwNumberOfCsAddrs = 1;
747 wqs.lpcsaBuffer = &addr_info;
750 if (SOCKET_ERROR == WSASetService(&wqs, RNRSERVICE_REGISTER, 0))
752 fprintf(stderr, "Failed to register the SDP service: ");
758 fprintf(stderr, "The SDP service was registered\n");
765 * Function used for creating the service record and registering it.
767 * @param dev pointer to the device struct
768 * @param rc_channel the rfcomm channel
769 * @return 0 on success
772 register_service(struct HardwareInfos *dev, int rc_channel)
776 * 2. set the service ID, class, profile information
777 * 3. make the service record publicly browsable
778 * 4. register the RFCOMM channel
779 * 5. set the name, provider and description
780 * 6. register the service record to the local SDP server
783 uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
784 dev->pl_mac.mac[5], dev->pl_mac.mac[4], dev->pl_mac.mac[3],
785 dev->pl_mac.mac[2], dev->pl_mac.mac[1], dev->pl_mac.mac[0] };
786 const char *service_dsc = "Bluetooth plugin services";
787 const char *service_prov = "GNUnet provider";
788 uuid_t root_uuid, rfcomm_uuid, svc_uuid;
789 sdp_list_t *root_list = 0, *rfcomm_list = 0, *proto_list = 0,
790 *access_proto_list = 0, *svc_list = 0;
791 sdp_record_t *record = 0;
792 sdp_data_t *channel = 0;
794 record = sdp_record_alloc();
796 /* Set the general service ID */
797 sdp_uuid128_create(&svc_uuid, &svc_uuid_int);
798 svc_list = sdp_list_append(0, &svc_uuid);
799 sdp_set_service_classes(record, svc_list);
800 sdp_set_service_id(record, svc_uuid);
802 /* Make the service record publicly browsable */
803 sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
804 root_list = sdp_list_append(0, &root_uuid);
805 sdp_set_browse_groups(record, root_list);
807 /* Register the RFCOMM channel */
808 sdp_uuid16_create(&rfcomm_uuid, RFCOMM_UUID);
809 channel = sdp_data_alloc(SDP_UINT8, &rc_channel);
810 rfcomm_list = sdp_list_append(0, &rfcomm_uuid);
811 sdp_list_append(rfcomm_list, channel);
812 proto_list = sdp_list_append(0, rfcomm_list);
814 /* Set protocol information */
815 access_proto_list = sdp_list_append(0, proto_list);
816 sdp_set_access_protos(record, access_proto_list);
818 /* Set the name, provider, and description */
819 sdp_set_info_attr(record, dev->iface, service_prov, service_dsc);
821 /* Connect to the local SDP server */
822 dev->session = sdp_connect(BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
826 fprintf(stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
827 IFNAMSIZ, dev->iface, strerror(errno));
832 /* Register the service record */
833 if (sdp_record_register(dev->session, record, 0) < 0)
835 fprintf(stderr, "Failed to register a service record on interface `%.*s': %s\n",
836 IFNAMSIZ, dev->iface, strerror(errno));
842 sdp_data_free(channel);
843 sdp_list_free(root_list, 0);
844 sdp_list_free(rfcomm_list, 0);
845 sdp_list_free(proto_list, 0);
846 sdp_list_free(access_proto_list, 0);
847 sdp_list_free(svc_list, 0);
848 sdp_record_free(record);
856 * Function for searching and browsing for a service. This will return the
857 * port number on which the service is running.
859 * @param dest target address
863 get_channel(const char *dest)
867 DWORD wqs_len = sizeof(WSAQUERYSET);
871 unsigned char uuid[] = GNUNET_BLUETOOTH_SDP_UUID;
873 convert_guid((char *)uuid, &guid);
875 wqs = (WSAQUERYSET*)malloc(wqs_len);
876 ZeroMemory(wqs, wqs_len);
878 wqs->dwSize = sizeof(WSAQUERYSET);
879 wqs->lpServiceClassId = &guid;
880 wqs->dwNameSpace = NS_BTH;
881 wqs->dwNumberOfCsAddrs = 0;
882 wqs->lpszContext = (LPSTR)dest;
884 if (SOCKET_ERROR == WSALookupServiceBegin(wqs, LUP_FLUSHCACHE | LUP_RETURN_ALL, &h))
886 if (GetLastError() == WSASERVICE_NOT_FOUND)
888 fprintf(stderr, "WARNING! The device with address %s wasn't found. Skipping the message!", dest);
893 fprintf(stderr, "Failed to find the port number: ");
900 /* search the sdp service */
903 if (SOCKET_ERROR == WSALookupServiceNext(h, LUP_FLUSHCACHE | LUP_RETURN_ALL, &wqs_len, wqs))
905 int error = WSAGetLastError();
911 wqs = (WSAQUERYSET*)malloc(wqs_len);
915 fprintf(stderr, "Failed! The address was valid but there was no data record of requested type\n");
924 fprintf(stderr, "Failed to look over the services: ");
926 WSALookupServiceEnd(h);
932 channel = ((SOCKADDR_BTH*)wqs->lpcsaBuffer->RemoteAddr.lpSockaddr)->port;
937 WSALookupServiceEnd(h);
943 * Function used for searching and browsing for a service. This will return the
944 * port number on which the service is running.
946 * @param dev pointer to the device struct
947 * @param dest target address
951 get_channel(struct HardwareInfos *dev, bdaddr_t dest)
954 * 1. detect all nearby devices
955 * 2. for each device:
956 * 2.1. connect to the SDP server running
957 * 2.2. get a list of service records with the specific UUID
958 * 2.3. for each service record get a list of the protocol sequences and get
961 uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
962 dest.b[5], dest.b[4], dest.b[3],
963 dest.b[2], dest.b[1], dest.b[0] };
964 sdp_session_t *session = 0;
965 sdp_list_t *search_list = 0, *attrid_list = 0, *response_list = 0, *it = 0;
967 uint32_t range = 0x0000ffff;
970 /* Connect to the local SDP server */
971 session = sdp_connect(BDADDR_ANY, &dest, 0);
974 fprintf(stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
975 IFNAMSIZ, dev->iface, strerror(errno));
979 sdp_uuid128_create(&svc_uuid, &svc_uuid_int);
980 search_list = sdp_list_append(0, &svc_uuid);
981 attrid_list = sdp_list_append(0, &range);
983 if (sdp_service_search_attr_req(session, search_list,
984 SDP_ATTR_REQ_RANGE, attrid_list, &response_list) == 0)
986 for (it = response_list; it; it = it->next)
988 sdp_record_t *record = (sdp_record_t*)it->data;
989 sdp_list_t *proto_list = 0;
990 if (sdp_get_access_protos(record, &proto_list) == 0)
992 channel = sdp_get_proto_port(proto_list, RFCOMM_UUID);
993 sdp_list_free(proto_list, 0);
995 sdp_record_free(record);
999 sdp_list_free(search_list, 0);
1000 sdp_list_free(attrid_list, 0);
1001 sdp_list_free(response_list, 0);
1007 "Failed to find the listening channel for interface `%.*s': %s\n",
1017 * Read from the socket and put the result into the buffer for transmission to 'stdout'.
1019 * @param sock file descriptor for reading
1020 * @param buf buffer to read to; first bytes will be the 'struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame',
1021 * followed by the actual payload
1022 * @param buf_size size of the buffer
1023 * @param ri where to write radiotap_rx info
1024 * @return number of bytes written to 'buf'
1027 read_from_the_socket(void *sock,
1028 unsigned char *buf, size_t buf_size,
1029 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri)
1031 unsigned char tmpbuf[buf_size];
1035 count = GNUNET_NETWORK_socket_recv((struct GNUNET_NETWORK_Handle *)sock, tmpbuf, buf_size);
1037 count = read(*((int *)sock), tmpbuf, buf_size);
1042 if (EAGAIN == errno)
1047 fprintf(stderr, "Failed to read from the HCI socket: %s\n", strerror(errno));
1054 /* Get the channel used */
1056 struct sockaddr_rc rc_addr = { 0 };
1058 memset(&rc_addr, 0, sizeof(rc_addr));
1059 len = sizeof(rc_addr);
1060 if (0 > getsockname(*((int *)sock), (struct sockaddr *)&rc_addr, (socklen_t *)&len))
1062 fprintf(stderr, "getsockname() call failed : %s\n", strerror(errno));
1066 memset(ri, 0, sizeof(*ri));
1067 ri->ri_channel = rc_addr.rc_channel;
1070 /* Detect CRC32 at the end */
1071 if (0 == check_crc_buf_osdep(tmpbuf, count - sizeof(uint32_t)))
1073 count -= sizeof(uint32_t);
1076 GNUNET_memcpy(buf, tmpbuf, count);
1083 * Open the bluetooth interface for reading/writing
1085 * @param dev pointer to the device struct
1086 * @return 0 on success, non-zero on error
1089 open_device(struct HardwareInfos *dev)
1094 /* bind the RFCOMM socket to the interface */
1095 addr.addressFamily = AF_BTH;
1097 addr.port = BT_PORT_ANY;
1100 GNUNET_NETWORK_socket_bind(dev->handle, (const SOCKADDR*)&addr, sizeof(SOCKADDR_BTH)))
1102 fprintf(stderr, "Failed to bind the socket: ");
1103 if (GetLastError() == WSAENETDOWN)
1105 fprintf(stderr, "Please make sure that your Bluetooth device is ON!\n");
1112 /* start listening on the socket */
1113 if (GNUNET_NETWORK_socket_listen(dev->handle, 4) != GNUNET_OK)
1115 fprintf(stderr, "Failed to listen on the socket: ");
1120 /* register the sdp service */
1121 if (register_service(dev) != 0)
1123 fprintf(stderr, "Failed to register a service: ");
1128 int i, dev_id = -1, fd_hci;
1130 struct hci_dev_list_req list;
1131 struct hci_dev_req dev[HCI_MAX_DEV];
1132 } request; //used for detecting the local devices
1133 struct sockaddr_rc rc_addr = { 0 }; //used for binding
1135 /* Initialize the neighbour structure */
1136 neighbours.dev_id = -1;
1137 for (i = 0; i < MAX_PORTS; i++)
1138 neighbours.fds[i] = -1;
1140 /* Open a HCI socket */
1141 fd_hci = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
1146 "Failed to create HCI socket: %s\n",
1151 memset(&request, 0, sizeof(request));
1152 request.list.dev_num = HCI_MAX_DEV;
1154 if (ioctl(fd_hci, HCIGETDEVLIST, (void *)&request) < 0)
1157 "ioctl(HCIGETDEVLIST) on interface `%.*s' failed: %s\n",
1161 (void)close(fd_hci);
1165 /* Search for a device with dev->iface name */
1166 for (i = 0; i < request.list.dev_num; i++)
1168 struct hci_dev_info dev_info;
1170 memset(&dev_info, 0, sizeof(struct hci_dev_info));
1171 dev_info.dev_id = request.dev[i].dev_id;
1172 strncpy(dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE);
1174 if (ioctl(fd_hci, HCIGETDEVINFO, (void *)&dev_info))
1177 "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n",
1181 (void)close(fd_hci);
1185 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);
1235 /* Check if the interface was not found */
1239 "The interface %s was not found\n",
1241 (void)close(fd_hci);
1245 /* Close the hci socket */
1246 (void)close(fd_hci);
1250 /* Bind the rfcomm socket to the interface */
1251 memset(&rc_addr, 0, sizeof(rc_addr));
1252 rc_addr.rc_family = AF_BLUETOOTH;
1253 rc_addr.rc_bdaddr = *BDADDR_ANY;
1255 if (bind_socket(dev->fd_rfcomm, &rc_addr) != 0)
1258 "Failed to bind interface `%.*s': %s\n",
1265 /* Register a SDP service */
1266 if (register_service(dev, rc_addr.rc_channel) != 0)
1269 "Failed to register a service on interface `%.*s': %s\n",
1271 dev->iface, strerror(errno));
1275 /* Switch socket in listening mode */
1276 if (listen(dev->fd_rfcomm, 5) == -1) //FIXME: probably we need a bigger number
1278 fprintf(stderr, "Failed to listen on socket for interface `%.*s': %s\n", IFNAMSIZ,
1279 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)
1532 memset(&addr_rc.rc_bdaddr, 0, sizeof(addr_rc.rc_bdaddr));
1533 GNUNET_memcpy(&addr_rc.rc_bdaddr, &(neighbours.devices[neighbours.pos]), sizeof(addr_rc.rc_bdaddr));
1535 addr_rc.rc_channel = get_channel(dev, addr_rc.rc_bdaddr);
1537 *sendsocket = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1538 if ((-1 < *sendsocket) &&
1539 (0 == connect(*sendsocket,
1540 (struct sockaddr *)&addr_rc,
1543 neighbours.fds[neighbours.pos++] = *sendsocket;
1544 connection_successful = 1;
1545 char addr[19] = { 0 };
1546 ba2str(&(neighbours.devices[neighbours.pos - 1]), addr);
1547 fprintf(stderr, "LOG : Connected to %s\n", addr);
1552 char addr[19] = { 0 };
1553 errno_copy = errno; //Save a copy for later
1555 if (-1 != *sendsocket)
1557 (void)close(*sendsocket);
1560 ba2str(&(neighbours.devices[neighbours.pos]), addr);
1562 "LOG : Couldn't connect on device %s, error : %s\n",
1565 if (errno != ECONNREFUSED) //FIXME be sure that this works
1567 fprintf(stderr, "LOG : Removes %d device from the list\n", neighbours.pos);
1568 /* Remove the device from the list */
1569 GNUNET_memcpy(&neighbours.devices[neighbours.pos], &neighbours.devices[neighbours.size - 1], sizeof(bdaddr_t));
1570 memset(&neighbours.devices[neighbours.size - 1], 0, sizeof(bdaddr_t));
1571 neighbours.fds[neighbours.pos] = neighbours.fds[neighbours.size - 1];
1572 neighbours.fds[neighbours.size - 1] = -1;
1573 neighbours.size -= 1;
1576 neighbours.pos += 1;
1578 if (neighbours.pos >= neighbours.size)
1583 if (loops == MAX_LOOPS) //don't get stuck trying to connect to one device
1589 fprintf(stderr, "LOG : Search for a new device\n"); //FIXME debugging message
1590 neighbours.pos += 1;
1594 /* Cycle on the list */
1595 if (neighbours.pos == neighbours.size)
1598 searching_devices_count += 1;
1600 if (searching_devices_count == MAX_LOOPS)
1602 fprintf(stderr, "LOG : Force to inquiry for new devices\n");
1603 searching_devices_count = 0;
1604 goto inquiry_devices;
1607 /* If a new device wasn't found, search an old one */
1608 if (connection_successful == 0)
1610 int loop_check = neighbours.pos;
1611 while (neighbours.fds[neighbours.pos] == -1)
1613 if (neighbours.pos == neighbours.size)
1616 if (neighbours.pos == loop_check)
1618 if (errno_copy == ECONNREFUSED)
1620 fprintf(stderr, "LOG : No device found. Go back and search again\n"); //FIXME debugging message
1623 goto search_for_devices;
1627 return 1; // Skip the broadcast message
1631 neighbours.pos += 1;
1634 *sendsocket = neighbours.fds[neighbours.pos++];
1642 * Main function of the helper. This code accesses a bluetooth interface
1643 * forwards traffic in both directions between the bluetooth interface and
1644 * stdin/stdout of this process. Error messages are written to stderr.
1646 * @param argc number of arguments, must be 2
1647 * @param argv arguments only argument is the name of the interface (i.e. 'hci0')
1648 * @return 0 on success (never happens, as we don't return unless aborted), 1 on error
1650 **** similar to gnunet-helper-transport-wlan.c ****
1653 main(int argc, char *argv[])
1656 struct HardwareInfos dev;
1657 char readbuf[MAXLINE];
1662 struct MessageStreamTokenizer *stdin_mst;
1664 int crt_rfds = 0, rfds_list[MAX_PORTS];
1665 int broadcast, sendsocket;
1667 /* Assert privs so we can modify the firewall rules! */
1669 #ifdef HAVE_SETRESUID
1670 uid_t uid = getuid();
1672 if (0 != setresuid(uid, 0, 0))
1675 "Failed to setresuid to root: %s\n",
1680 if (0 != seteuid(0))
1683 "Failed to seteuid back to root: %s\n", strerror(errno));
1689 /* Make use of SGID capabilities on POSIX */
1690 memset(&dev, 0, sizeof(dev));
1691 dev.fd_rfcomm = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1692 raw_eno = errno; /* remember for later */
1694 /* Now that we've dropped root rights, we can do error checking */
1697 fprintf(stderr, "You must specify the name of the interface as the first \
1698 and only argument to this program.\n");
1699 if (-1 != dev.fd_rfcomm)
1700 (void)close(dev.fd_rfcomm);
1704 if (-1 == dev.fd_rfcomm)
1706 fprintf(stderr, "Failed to create a RFCOMM socket: %s\n", strerror(raw_eno));
1709 if (dev.fd_rfcomm >= FD_SETSIZE)
1711 fprintf(stderr, "File descriptor too large for select (%d > %d)\n",
1712 dev.fd_rfcomm, FD_SETSIZE);
1713 (void)close(dev.fd_rfcomm);
1716 if (0 != test_bluetooth_interface(argv[1]))
1718 (void)close(dev.fd_rfcomm);
1721 strncpy(dev.iface, argv[1], IFNAMSIZ);
1722 if (0 != open_device(&dev))
1724 (void)close(dev.fd_rfcomm);
1730 uid_t uid = getuid();
1731 #ifdef HAVE_SETRESUID
1732 if (0 != setresuid(uid, uid, uid))
1734 fprintf(stderr, "Failed to setresuid: %s\n", strerror(errno));
1735 if (-1 != dev.fd_rfcomm)
1736 (void)close(dev.fd_rfcomm);
1740 if (0 != (setuid(uid) | seteuid(uid)))
1742 fprintf(stderr, "Failed to setuid: %s\n", strerror(errno));
1743 if (-1 != dev.fd_rfcomm)
1744 (void)close(dev.fd_rfcomm);
1750 /* Send MAC address of the bluetooth interface to STDOUT first */
1752 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
1754 macmsg.hdr.size = htons(sizeof(macmsg));
1755 macmsg.hdr.type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
1756 GNUNET_memcpy(&macmsg.mac, &dev.pl_mac, sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress));
1757 GNUNET_memcpy(write_std.buf, &macmsg, sizeof(macmsg));
1758 write_std.size = sizeof(macmsg);
1762 stdin_mst = mst_create(&stdin_send_hw, &dev);
1766 * TODO : I should make the time out of a mac endpoint smaller and check if the rate
1767 * from get_wlan_header (plugin_transport_bluetooth.c) is correct.
1776 if ((0 == write_pout.size) && (1 == stdin_open))
1778 FD_SET(STDIN_FILENO, &rfds);
1779 maxfd = MAX(maxfd, STDIN_FILENO);
1781 if (0 == write_std.size)
1783 FD_SET(dev.fd_rfcomm, &rfds);
1784 maxfd = MAX(maxfd, dev.fd_rfcomm);
1787 for (i = 0; i < crt_rfds; i++) // it can receive messages from multiple devices
1789 FD_SET(rfds_list[i], &rfds);
1790 maxfd = MAX(maxfd, rfds_list[i]);
1793 if (0 < write_std.size)
1795 FD_SET(STDOUT_FILENO, &wfds);
1796 maxfd = MAX(maxfd, STDOUT_FILENO);
1798 if (0 < write_pout.size) //it can send messages only to one device per loop
1800 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *frame;
1801 /* Get the destination address */
1802 frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *)write_pout.buf;
1804 if (memcmp(&frame->addr1, &dev.pl_mac,
1805 sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1808 memset(&write_pout, 0, sizeof(write_pout)); //clear the buffer
1810 else if (memcmp(&frame->addr1, &broadcast_address,
1811 sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1813 fprintf(stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n", dev.iface, neighbours.pos, neighbours.size); //FIXME: debugging message
1815 if (send_broadcast(&dev, &sendsocket) != 0) //if the searching wasn't successful don't get stuck on the select stage
1818 memset(&write_pout, 0, sizeof(write_pout)); //remove the message
1819 fprintf(stderr, "LOG : Skipping the broadcast message (pos %d, size %d)\n", neighbours.pos, neighbours.size);
1823 FD_SET(sendsocket, &wfds);
1824 maxfd = MAX(maxfd, sendsocket);
1831 /* Search if the address already exists on the list */
1832 for (i = 0; i < neighbours.size; i++)
1834 if (memcmp(&frame->addr1, &(neighbours.devices[i]), sizeof(bdaddr_t)) == 0)
1837 if (neighbours.fds[i] != -1)
1839 found = 1; //save the position where it was found
1840 FD_SET(neighbours.fds[i], &wfds);
1841 maxfd = MAX(maxfd, neighbours.fds[i]);
1842 sendsocket = neighbours.fds[i];
1843 fprintf(stderr, "LOG: the address was found in the list\n");
1851 struct sockaddr_rc addr = { 0 };
1853 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,
1854 frame->addr1.mac[5], frame->addr1.mac[4], frame->addr1.mac[3],
1855 frame->addr1.mac[2], frame->addr1.mac[1], frame->addr1.mac[0]); //FIXME: debugging message
1857 sendsocket = socket(AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1861 fprintf(stderr, "Failed to create a RFCOMM socket (sending stage): %s\n",
1866 GNUNET_memcpy(&addr.rc_bdaddr, &frame->addr1, sizeof(bdaddr_t));
1867 addr.rc_family = AF_BLUETOOTH;
1868 addr.rc_channel = get_channel(&dev, addr.rc_bdaddr);
1872 status = connect(sendsocket, (struct sockaddr *)&addr, sizeof(addr));
1873 if (0 != status && errno != EAGAIN)
1875 if (errno == ECONNREFUSED && tries < 2)
1877 fprintf(stderr, "LOG : %.*s failed to connect. Trying again!\n", IFNAMSIZ, dev.iface);
1881 else if (errno == EBADF)
1883 fprintf(stderr, "LOG : %s failed to connect : %s. Skip it!\n", dev.iface, strerror(errno));
1884 memset(&write_pout, 0, sizeof(write_pout));
1889 fprintf(stderr, "LOG : %s failed to connect : %s. Try again later!\n", dev.iface, strerror(errno));
1890 memset(&write_pout, 0, sizeof(write_pout));
1896 FD_SET(sendsocket, &wfds);
1897 maxfd = MAX(maxfd, sendsocket);
1898 fprintf(stderr, "LOG : Connection successful\n");
1899 if (pos != 0) // save the socket
1901 neighbours.fds[pos] = sendsocket;
1905 /* Add the new device to the discovered devices list */
1906 if (neighbours.size < MAX_PORTS)
1908 neighbours.fds[neighbours.size] = sendsocket;
1909 GNUNET_memcpy(&(neighbours.devices[neighbours.size++]), &addr.rc_bdaddr, sizeof(bdaddr_t));
1913 fprintf(stderr, "The top limit for the discovarable devices' list was reached\n");
1923 /* Select a fd which is ready for action :) */
1925 int retval = select(maxfd + 1, &rfds, &wfds, NULL, NULL);
1926 if ((-1 == retval) && (EINTR == errno))
1928 if (0 > retval && errno != EBADF) // we handle BADF errors later
1930 fprintf(stderr, "select failed: %s\n", strerror(errno));
1934 if (FD_ISSET(STDOUT_FILENO, &wfds))
1937 write(STDOUT_FILENO, write_std.buf + write_std.pos,
1938 write_std.size - write_std.pos);
1941 fprintf(stderr, "Failed to write to STDOUT: %s\n", strerror(errno));
1944 write_std.pos += ret;
1945 if (write_std.pos == write_std.size)
1950 fprintf(stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); //FIXME: debugging message
1952 if (-1 != sendsocket)
1954 if (FD_ISSET(sendsocket, &wfds))
1956 ssize_t ret = write(sendsocket,
1957 write_pout.buf + write_std.pos,
1958 write_pout.size - write_pout.pos);
1959 if (0 > ret) //FIXME should I first check the error type?
1961 fprintf(stderr, "Failed to write to bluetooth device: %s. Closing the socket!\n",
1963 for (i = 0; i < neighbours.size; i++)
1965 if (neighbours.fds[i] == sendsocket)
1967 (void)close(sendsocket);
1968 neighbours.fds[i] = -1;
1972 /* Remove the message */
1973 memset(&write_pout.buf + write_std.pos, 0, (write_pout.size - write_pout.pos));
1975 write_pout.size = 0;
1979 write_pout.pos += ret;
1980 if ((write_pout.pos != write_pout.size) && (0 != ret))
1982 /* We should not get partial sends with packet-oriented devices... */
1983 fprintf(stderr, "Write error, partial send: %u/%u\n",
1984 (unsigned int)write_pout.pos,
1985 (unsigned int)write_pout.size);
1989 if (write_pout.pos == write_pout.size)
1992 write_pout.size = 0;
1994 fprintf(stderr, "LOG : %s sends a message to a DEVICE\n", dev.iface); //FIXME: debugging message
1998 for (i = 0; i <= maxfd; i++)
2000 if (FD_ISSET(i, &rfds))
2002 if (i == STDIN_FILENO)
2005 read(i, readbuf, sizeof(readbuf));
2009 "Read error from STDIN: %s\n",
2015 /* stop reading... */
2020 mst_receive(stdin_mst, readbuf, ret);
2021 fprintf(stderr, "LOG : %s receives a message from STDIN\n", dev.iface); //FIXME: debugging message
2024 else if (i == dev.fd_rfcomm)
2027 struct sockaddr_rc addr = { 0 };
2028 unsigned int opt = sizeof(addr);
2030 readsocket = accept(dev.fd_rfcomm, (struct sockaddr *)&addr, &opt);
2031 fprintf(stderr, "LOG : %s accepts a message\n", dev.iface); //FIXME: debugging message
2032 if (readsocket == -1)
2034 fprintf(stderr, "Failed to accept a connection on interface: %.*s\n", IFNAMSIZ,
2040 FD_SET(readsocket, &rfds);
2041 maxfd = MAX(maxfd, readsocket);
2043 if (crt_rfds < MAX_PORTS)
2044 rfds_list[crt_rfds++] = readsocket;
2047 fprintf(stderr, "The limit for the read file descriptors list was \
2055 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
2057 fprintf(stderr, "LOG : %s reads something from the socket\n", dev.iface);//FIXME : debugging message
2058 rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *)write_std.buf;
2060 read_from_the_socket((void *)&i, (unsigned char *)&rrm->frame,
2061 sizeof(write_std.buf)
2062 - sizeof(struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2063 + sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2070 /* Remove the socket from the list */
2071 for (j = 0; j < crt_rfds; j++)
2073 if (rfds_list[j] == i)
2075 rfds_list[j] ^= rfds_list[crt_rfds - 1];
2076 rfds_list[crt_rfds - 1] ^= rfds_list[j];
2077 rfds_list[j] ^= rfds_list[crt_rfds - 1];
2083 fprintf(stderr, "Read error from raw socket: %s\n", strerror(errno));
2086 if ((0 < ret) && (0 == mac_test(&rrm->frame, &dev)))
2088 write_std.size = ret
2089 + sizeof(struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2090 - sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2091 rrm->header.size = htons(write_std.size);
2092 rrm->header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2099 /* Error handling, try to clean up a bit at least */
2100 mst_destroy(stdin_mst);
2102 sdp_close(dev.session);
2103 (void)close(dev.fd_rfcomm);
2104 if (-1 != sendsocket)
2105 (void)close(sendsocket);
2107 for (i = 0; i < crt_rfds; i++)
2108 (void)close(rfds_list[i]);
2110 for (i = 0; i < neighbours.size; i++)
2111 (void)close(neighbours.fds[i]);
2113 struct HardwareInfos dev;
2114 struct GNUNET_NETWORK_Handle *sendsocket;
2115 struct GNUNET_NETWORK_FDSet *rfds;
2116 struct GNUNET_NETWORK_FDSet *wfds;
2117 struct GNUNET_NETWORK_Handle *rfds_list[MAX_PORTS];
2118 char readbuf[MAXLINE] = { 0 };
2119 SOCKADDR_BTH acc_addr = { 0 };
2120 int addr_len = sizeof(SOCKADDR_BTH);
2121 int broadcast, i, stdin_open, crt_rfds = 0;
2122 HANDLE stdin_handle = GetStdHandle(STD_INPUT_HANDLE);
2123 HANDLE stdout_handle = GetStdHandle(STD_OUTPUT_HANDLE);
2124 struct MessageStreamTokenizer *stdin_mst;
2126 /* check the handles */
2127 if (stdin_handle == INVALID_HANDLE_VALUE)
2129 fprintf(stderr, "Failed to get the stdin handle\n");
2133 if (stdout_handle == INVALID_HANDLE_VALUE)
2135 fprintf(stderr, "Failed to get the stdout handle\n");
2139 /* initialize windows sockets */
2140 initialize_windows_sockets();
2142 // /* test bluetooth socket family support */ --> it return false because the GNUNET_NETWORK_test_pf should also receive the type of socket (BTHPROTO_RFCOMM)
2143 // if (GNUNET_NETWORK_test_pf (AF_BTH) != GNUNET_OK)
2145 // fprintf (stderr, "AF_BTH family is not supported\n");
2149 /* create the socket */
2150 dev.handle = GNUNET_NETWORK_socket_create(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
2151 if (dev.handle == NULL)
2153 fprintf(stderr, "Failed to create RFCOMM socket: ");
2159 if (open_device(&dev) == -1)
2161 fprintf(stderr, "Failed to open the device\n");
2163 if (GNUNET_NETWORK_socket_close(dev.handle) != GNUNET_OK)
2165 fprintf(stderr, "Failed to close the socket!\n");
2171 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking(dev.handle, 1))
2173 fprintf(stderr, "Failed to change the socket mode\n");
2177 memset(&write_std, 0, sizeof(write_std));
2178 memset(&write_pout, 0, sizeof(write_pout));
2181 rfds = GNUNET_NETWORK_fdset_create();
2182 wfds = GNUNET_NETWORK_fdset_create();
2184 /* Send MAC address of the bluetooth interface to STDOUT first */
2186 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
2188 macmsg.hdr.size = htons(sizeof(macmsg));
2189 macmsg.hdr.type = htons(GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
2190 GNUNET_memcpy(&macmsg.mac, &dev.pl_mac, sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy));
2191 GNUNET_memcpy(write_std.buf, &macmsg, sizeof(macmsg));
2192 write_std.size = sizeof(macmsg);
2196 stdin_mst = mst_create(&stdin_send_hw, &dev);
2201 int stdout_pos = -1;
2208 sendsocket = NULL; //FIXME ???memleaks
2210 GNUNET_NETWORK_fdset_zero(rfds);
2211 if ((0 == write_pout.size) && (1 == stdin_open))
2215 GNUNET_NETWORK_fdset_handle_set(rfds, (struct GNUNET_DISK_FileHandle*)&stdin_handle);
2218 if (0 == write_std.size)
2221 GNUNET_NETWORK_fdset_set(rfds, dev.handle);
2224 for (i = 0; i < crt_rfds; i++)
2227 GNUNET_NETWORK_fdset_set(rfds, rfds_list[i]);
2230 GNUNET_NETWORK_fdset_zero(wfds);
2231 if (0 < write_std.size)
2234 GNUNET_NETWORK_fdset_handle_set(wfds, (struct GNUNET_DISK_FileHandle*)&stdout_handle);
2235 // printf ("%s\n", write_std.buf);
2236 // memset (write_std.buf, 0, write_std.size);
2237 // write_std.size = 0;
2240 if (0 < write_pout.size)
2242 if (strcmp(argv[1], "ff:ff:ff:ff:ff:ff") == 0)
2244 fprintf(stderr, "LOG: BROADCAST! Skipping the message\n");
2247 memset(write_pout.buf, 0, write_pout.size);
2248 write_pout.size = 0;
2253 fprintf(stderr, "LOG : has a new message for %s\n", argv[1]);
2254 sendsocket = GNUNET_NETWORK_socket_create(AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
2256 if (sendsocket == NULL)
2258 fprintf(stderr, "Failed to create RFCOMM socket: \n");
2263 memset(&addr, 0, sizeof(addr));
2264 //addr.addressFamily = AF_BTH;
2266 WSAStringToAddress(argv[1], AF_BTH, NULL, (LPSOCKADDR)&addr, &addr_len))
2268 fprintf(stderr, "Failed to translate the address: ");
2272 addr.port = get_channel(argv[1]);
2273 if (addr.port == -1)
2275 fprintf(stderr, "Couldn't find the sdp service for the address: %s\n", argv[1]);
2276 memset(write_pout.buf, 0, write_pout.size);
2277 write_pout.size = 0;
2278 broadcast = 1; //skipping the select part
2282 if (GNUNET_OK != GNUNET_NETWORK_socket_connect(sendsocket, (LPSOCKADDR)&addr, addr_len))
2284 fprintf(stderr, "Failed to connect: ");
2289 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking(sendsocket, 1))
2291 fprintf(stderr, "Failed to change the socket mode\n");
2295 GNUNET_NETWORK_fdset_set(wfds, sendsocket);
2302 int retval = GNUNET_NETWORK_socket_select(rfds, wfds, NULL, GNUNET_TIME_relative_get_forever_());
2305 fprintf(stderr, "Select error\n");
2308 //if (GNUNET_NETWORK_fdset_isset (wfds, (struct GNUNET_NETWORK_Handle*)&stdout_handle))
2309 if (retval == stdout_pos)
2311 fprintf(stderr, "LOG : sends a message to STDOUT\n"); //FIXME: debugging message
2313 //ret = GNUNET_NETWORK_socket_send ((struct GNUNET_NETWORK_Handle *)&stdout_handle, write_std.buf + write_std.pos, write_std.size - write_std.pos);
2314 //ret = write (STDOUT_FILENO, write_std.buf + write_std.pos, write_std.size - write_std.pos);
2316 if (FALSE == WriteFile(stdout_handle, write_std.buf + write_std.pos, write_std.size - write_std.pos, &ret, NULL))
2318 fprintf(stderr, "Failed to write to STDOUT: ");
2325 fprintf(stderr, "Failed to write to STDOUT\n");
2329 write_std.pos += ret;
2330 if (write_std.pos == write_std.size)
2336 if (sendsocket != NULL)
2338 if (GNUNET_NETWORK_fdset_isset(wfds, sendsocket))
2341 ret = GNUNET_NETWORK_socket_send(sendsocket, write_pout.buf + write_pout.pos,
2342 write_pout.size - write_pout.pos);
2344 if (GNUNET_SYSERR == ret)
2346 fprintf(stderr, "Failed to send to the socket. Closing the socket. Error: \n");
2348 if (GNUNET_NETWORK_socket_close(sendsocket) != GNUNET_OK)
2350 fprintf(stderr, "Failed to close the sendsocket!\n");
2357 write_pout.pos += ret;
2358 if ((write_pout.pos != write_pout.size) && (0 != ret))
2360 /* we should not get partial sends with packet-oriented devices... */
2361 fprintf(stderr, "Write error, partial send: %u/%u\n",
2362 (unsigned int)write_pout.pos,
2363 (unsigned int)write_pout.size);
2367 if (write_pout.pos == write_pout.size)
2370 write_pout.size = 0;
2372 fprintf(stderr, "LOG : sends a message to a DEVICE\n"); //FIXME: debugging message
2377 //if (GNUNET_NETWORK_fdset_isset (rfds, (struct GNUNET_NETWORK_Handle*)&stdin_handle))
2378 if (retval == stdin_pos)
2381 //ret = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)&stdin_handle, readbuf, sizeof (write_pout.buf));
2382 //ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
2384 if (FALSE == ReadFile(stdin_handle, readbuf, sizeof(readbuf), &ret, NULL)) /* do nothing asynchronous */
2386 fprintf(stderr, "Read error from STDIN: ");
2392 /* stop reading... */
2397 mst_receive(stdin_mst, readbuf, ret);
2398 fprintf(stderr, "LOG : receives a message from STDIN\n"); //FIXME: debugging message
2402 if (GNUNET_NETWORK_fdset_isset(rfds, dev.handle))
2404 fprintf(stderr, "LOG: accepting connection\n");
2405 struct GNUNET_NETWORK_Handle *readsocket;
2406 readsocket = GNUNET_NETWORK_socket_accept(dev.handle, (LPSOCKADDR)&acc_addr, &addr_len);
2407 if (readsocket == NULL)
2409 fprintf(stderr, "Accept error %d: ", GetLastError());
2415 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking(readsocket, 1))
2417 fprintf(stderr, "Failed to change the socket mode\n");
2420 GNUNET_NETWORK_fdset_set(rfds, readsocket);
2422 if (crt_rfds < MAX_PORTS)
2423 rfds_list[crt_rfds++] = readsocket;
2426 fprintf(stderr, "The limit for the read file descriptors list was reached\n");
2432 for (i = 0; i < crt_rfds; i++)
2434 if (GNUNET_NETWORK_fdset_isset(rfds, rfds_list[i]))
2436 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
2438 fprintf(stderr, "LOG: reading something from the socket\n");//FIXME : debugging message
2439 rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *)write_std.buf;
2440 ret = read_from_the_socket(rfds_list[i], (unsigned char *)&rrm->frame,
2441 sizeof(write_std.buf)
2442 - sizeof(struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2443 + sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2447 //TODO remove the socket from the list
2448 if (GNUNET_NETWORK_socket_close(rfds_list[i]) != GNUNET_OK)
2450 fprintf(stderr, "Failed to close the sendsocket!\n");
2454 fprintf(stderr, "Read error from raw socket: ");
2458 if ((0 < ret) && (0 == mac_test(&rrm->frame, &dev)))
2460 write_std.size = ret
2461 + sizeof(struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2462 - sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2463 rrm->header.size = htons(write_std.size);
2464 rrm->header.type = htons(GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2472 mst_destroy(stdin_mst);
2475 if (GNUNET_NETWORK_socket_close(dev.handle) != GNUNET_OK)
2477 fprintf(stderr, "Failed to close the socket!\n");
2481 for (i = 0; i < crt_rfds; i++)
2483 if (GNUNET_NETWORK_socket_close(rfds_list[i]) != GNUNET_OK)
2485 fprintf(stderr, "Failed to close the socket!\n");
2492 return 1; /* we never exit 'normally' */