2 This file is part of GNUnet.
3 (C) 2010, 2011, 2012 Christian Grothoff (and other contributing authors)
4 Copyright (c) 2007, 2008, Andy Green <andy@warmcat.com>
5 Copyright (C) 2009 Thomas d'Otreppe
7 GNUnet is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published
9 by the Free Software Foundation; either version 3, or (at your
10 option) any later version.
12 GNUnet is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNUnet; see the file COPYING. If not, write to the
19 Free Software Foundation, Inc., 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.
22 #include "gnunet_config.h"
26 #include "gnunet_util_lib.h"
30 #include <bluetooth/bluetooth.h>
31 #include <bluetooth/hci.h>
32 #include <bluetooth/hci_lib.h>
33 #include <bluetooth/rfcomm.h>
34 #include <bluetooth/sdp.h>
35 #include <bluetooth/sdp_lib.h>
40 #include <sys/ioctl.h>
41 #include <sys/param.h>
42 #include <sys/socket.h>
44 #include <sys/types.h>
48 #include "plugin_transport_wlan.h"
49 #include "gnunet_protocols.h"
53 * Maximum number of ports assignable for RFCOMMM protocol.
58 * Maximum size of a message allowed in either direction
59 * (used for our receive and sent buffers).
65 * Maximum number of loops without inquiring for new devices.
70 /* Maximum size of the interface's name */
77 * A copy of the MAC Address.
79 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 * struct for storing the information of the hardware. There is only
105 * Name of the interface, not necessarily 0-terminated (!).
107 char iface[IFNAMSIZ];
113 struct GNUNET_NETWORK_Handle *handle;
116 * MAC address of our own bluetooth interface.
118 struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy pl_mac;
121 * file descriptor for the rfcomm socket
126 * MAC address of our own bluetooth interface.
128 struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac;
133 sdp_session_t *session ;
138 * IO buffer used for buffering data in transit (to wireless or to stdout).
143 * How many bytes of data are stored in 'buf' for transmission right now?
144 * Data always starts at offset 0 and extends to 'size'.
149 * How many bytes that were stored in 'buf' did we already write to the
150 * destination? Always smaller than 'size'.
155 * Buffered data; twice the maximum allowed message size as we add some
158 char buf[MAXLINE * 2];
163 * Devices buffer used to keep a list with all the discoverable devices in
164 * order to send them HELLO messages one by one when it receive a broadcast message.
166 struct BroadcastMessages
168 /* List with the discoverable devices' addresses */
169 bdaddr_t devices[MAX_PORTS];
171 /* List with the open sockets */
175 /* The number of the devices */
178 /* The current position */
186 * Address used to identify the broadcast messages.
188 static struct GNUNET_TRANSPORT_WLAN_MacAddress broadcast_address = {{255, 255, 255, 255, 255, 255}};
191 * Buffer with the discoverable devices.
193 static struct BroadcastMessages neighbours;
195 static int searching_devices_count = 0;
199 * Buffer for data read from stdin to be transmitted to the bluetooth device
201 static struct SendBuffer write_pout;
204 * Buffer for data read from the bluetooth device to be transmitted to stdout.
206 static struct SendBuffer write_std;
209 /* ****** this are the same functions as the ones used in gnunet-helper-transport-wlan.c ****** */
212 * To what multiple do we align messages? 8 byte should suffice for everyone
215 #define ALIGN_FACTOR 8
218 * Smallest supported message.
220 #define MIN_BUFFER_SIZE sizeof (struct GNUNET_MessageHeader)
224 * Functions with this signature are called whenever a
225 * complete message is received by the tokenizer.
228 * @param message the actual message
230 typedef void (*MessageTokenizerCallback) (void *cls,
232 GNUNET_MessageHeader *
236 * Handle to a message stream tokenizer.
238 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;
275 * Create a message stream tokenizer.
277 * @param cb function to call on completed messages
278 * @param cb_cls closure for cb
279 * @return handle to tokenizer
281 static struct MessageStreamTokenizer *
282 mst_create (MessageTokenizerCallback cb,
285 struct MessageStreamTokenizer *ret;
287 ret = malloc (sizeof (struct MessageStreamTokenizer));
290 fprintf (stderr, "Failed to allocate buffer for tokenizer\n");
293 ret->hdr = malloc (MIN_BUFFER_SIZE);
294 if (NULL == ret->hdr)
296 fprintf (stderr, "Failed to allocate buffer for alignment\n");
299 ret->curr_buf = MIN_BUFFER_SIZE;
301 ret->cb_cls = cb_cls;
309 * Add incoming data to the receive buffer and call the
310 * callback for all complete messages.
312 * @param mst tokenizer to use
313 * @param buf input data to add
314 * @param size number of bytes in buf
315 * @return GNUNET_OK if we are done processing (need more data)
316 * GNUNET_SYSERR if the data stream is corrupt
319 mst_receive (struct MessageStreamTokenizer *mst,
320 const char *buf, size_t size)
322 const struct GNUNET_MessageHeader *hdr;
327 unsigned long offset;
331 ibuf = (char *) mst->hdr;
335 if (mst->pos < mst->off)
337 //fprintf (stderr, "We processed too many bytes!\n");
338 return GNUNET_SYSERR;
340 if ((mst->curr_buf - mst->off < sizeof (struct GNUNET_MessageHeader)) ||
341 (0 != (mst->off % ALIGN_FACTOR)))
343 /* need to align or need more space */
344 mst->pos -= mst->off;
345 memmove (ibuf, &ibuf[mst->off], mst->pos);
348 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
351 GNUNET_MIN (sizeof (struct GNUNET_MessageHeader) -
352 (mst->pos - mst->off), size);
353 memcpy (&ibuf[mst->pos], buf, delta);
358 if (mst->pos - mst->off < sizeof (struct GNUNET_MessageHeader))
360 //FIXME should I reset ??
365 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
366 want = ntohs (hdr->size);
367 if (want < sizeof (struct GNUNET_MessageHeader))
370 "Received invalid message from stdin\n");
371 return GNUNET_SYSERR;
373 if ((mst->curr_buf - mst->off < want) &&
376 /* need more space */
377 mst->pos -= mst->off;
378 memmove (ibuf, &ibuf[mst->off], mst->pos);
381 if (want > mst->curr_buf)
385 fprintf (stderr, "Error! We should proceeded 0 bytes\n");
386 return GNUNET_SYSERR;
388 mst->hdr = realloc (mst->hdr, want);
389 if (NULL == mst->hdr)
391 fprintf (stderr, "Failed to allocate buffer for alignment\n");
394 ibuf = (char *) mst->hdr;
395 mst->curr_buf = want;
397 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
398 if (mst->pos - mst->off < want)
400 delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
401 if (mst->pos + delta > mst->curr_buf)
403 fprintf (stderr, "The size of the buffer will be exceeded!\n");
404 return GNUNET_SYSERR;
406 memcpy (&ibuf[mst->pos], buf, delta);
411 if (mst->pos - mst->off < want)
413 //FIXME should I use this?
418 mst->cb (mst->cb_cls, hdr);
420 if (mst->off == mst->pos)
422 /* reset to beginning of buffer, it's free right now! */
429 fprintf (stderr, "There should some valid bytes in the buffer on this stage\n");
430 return GNUNET_SYSERR;
434 if (size < sizeof (struct GNUNET_MessageHeader))
436 offset = (unsigned long) buf;
437 need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
438 if (GNUNET_NO == need_align)
440 /* can try to do zero-copy and process directly from original buffer */
441 hdr = (const struct GNUNET_MessageHeader *) buf;
442 want = ntohs (hdr->size);
443 if (want < sizeof (struct GNUNET_MessageHeader))
446 "Received invalid message from stdin\n");
449 return GNUNET_SYSERR;
452 break; /* or not, buffer incomplete, so copy to private buffer... */
453 mst->cb (mst->cb_cls, hdr);
459 /* need to copy to private buffer to align;
460 * yes, we go a bit more spagetti than usual here */
466 if (size + mst->pos > mst->curr_buf)
468 mst->hdr = realloc (mst->hdr, size + mst->pos);
469 if (NULL == mst->hdr)
471 fprintf (stderr, "Failed to allocate buffer for alignment\n");
474 ibuf = (char *) mst->hdr;
475 mst->curr_buf = size + mst->pos;
477 if (mst->pos + size > mst->curr_buf)
480 "Assertion failed\n");
483 memcpy (&ibuf[mst->pos], buf, size);
490 * Destroys a tokenizer.
492 * @param mst tokenizer to destroy
495 mst_destroy (struct MessageStreamTokenizer *mst)
502 * Calculate crc32, the start of the calculation
504 * @param buf buffer to calc the crc
505 * @param len len of the buffer
509 calc_crc_osdep (const unsigned char *buf, size_t len)
511 static const unsigned long int crc_tbl_osdep[256] = {
512 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
513 0xE963A535, 0x9E6495A3,
514 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
515 0xE7B82D07, 0x90BF1D91,
516 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
517 0xF4D4B551, 0x83D385C7,
518 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
519 0xFA0F3D63, 0x8D080DF5,
520 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
521 0xD20D85FD, 0xA50AB56B,
522 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
523 0xDCD60DCF, 0xABD13D59,
524 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
525 0xCFBA9599, 0xB8BDA50F,
526 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
527 0xC1611DAB, 0xB6662D3D,
528 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
529 0x9FBFE4A5, 0xE8B8D433,
530 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
531 0x91646C97, 0xE6635C01,
532 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
533 0x8208F4C1, 0xF50FC457,
534 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
535 0x8CD37CF3, 0xFBD44C65,
536 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
537 0xA4D1C46D, 0xD3D6F4FB,
538 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
539 0xAA0A4C5F, 0xDD0D7CC9,
540 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
541 0xB966D409, 0xCE61E49F,
542 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
543 0xB7BD5C3B, 0xC0BA6CAD,
544 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
545 0x04DB2615, 0x73DC1683,
546 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
547 0x0A00AE27, 0x7D079EB1,
548 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
549 0x196C3671, 0x6E6B06E7,
550 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
551 0x17B7BE43, 0x60B08ED5,
552 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
553 0x3FB506DD, 0x48B2364B,
554 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
555 0x316E8EEF, 0x4669BE79,
556 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
557 0x220216B9, 0x5505262F,
558 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
559 0x2CD99E8B, 0x5BDEAE1D,
560 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
561 0x72076785, 0x05005713,
562 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
563 0x7CDCEFB7, 0x0BDBDF21,
564 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
565 0x6FB077E1, 0x18B74777,
566 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
567 0x616BFFD3, 0x166CCF45,
568 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
569 0x4969474D, 0x3E6E77DB,
570 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
571 0x47B2CF7F, 0x30B5FFE9,
572 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
573 0x54DE5729, 0x23D967BF,
574 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
575 0x5A05DF1B, 0x2D02EF8D
578 unsigned long crc = 0xFFFFFFFF;
580 for (; len > 0; len--, buf++)
581 crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
587 * Calculate and check crc of the bluetooth packet
589 * @param buf buffer of the packet, with len + 4 bytes of data,
590 * the last 4 bytes being the checksum
591 * @param len length of the payload in data
592 * @return 0 on success (checksum matches), 1 on error
595 check_crc_buf_osdep (const unsigned char *buf, size_t len)
599 crc = calc_crc_osdep (buf, len);
601 if (((crc) & 0xFF) == buf[0] && ((crc >> 8) & 0xFF) == buf[1] &&
602 ((crc >> 16) & 0xFF) == buf[2] && ((crc >> 24) & 0xFF) == buf[3])
609 /* ************** end of clone ***************** */
613 * Function used to get the code of last error and to print the type of error.
618 LPVOID lpMsgBuf = NULL;
620 if (FormatMessage (FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
621 NULL, GetLastError(), 0, (LPTSTR) &lpMsgBuf, 0, NULL))
622 fprintf (stderr, "%s\n", (char *)lpMsgBuf);
624 fprintf (stderr, "Failed to format the message for the last error! Error number : %d\n", GetLastError());
628 * Function used to initialize the Windows Sockets
631 initialize_windows_sockets()
634 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)
652 uuid->Data1 = ((bytes[0] << 24) & 0xff000000) | ((bytes[1] << 16) & 0x00ff0000) | ((bytes[2] << 8) & 0x0000ff00) | (bytes[3] & 0x000000ff);
653 uuid->Data2 = ((bytes[4] << 8) & 0xff00) | (bytes[5] & 0x00ff);
654 uuid->Data3 = ((bytes[6] << 8) & 0xff00) | (bytes[7] & 0x00ff);
656 for (i = 0; i < 8; i++)
658 uuid->Data4[i] = bytes[i + 8];
665 * Function for assigning a port number
667 * @param socket the socket used to bind
668 * @param addr pointer to the rfcomm address
669 * @return 0 on success
672 bind_socket (int socket, struct sockaddr_rc *addr)
676 /* Bind every possible port (from 0 to 30) and stop when binding doesn't fail */
677 //FIXME : it should start from port 1, but on my computer it doesn't work :)
678 for (port = 3; port <= 30; port++)
680 addr->rc_channel = port;
681 status = bind (socket, (struct sockaddr *) addr, sizeof (struct sockaddr_rc));
692 * Function used for creating the service record and registering it.
694 * @param dev pointer to the device struct
695 * @return 0 on success
698 register_service (struct HardwareInfos *dev)
700 /* advertise the service */
701 CSADDR_INFO addr_info;
704 unsigned char uuid[] = GNUNET_BLUETOOTH_SDP_UUID;
706 int addr_len = sizeof (SOCKADDR_BTH);
708 /* get the port on which we are listening on */
709 memset (& addr, 0, sizeof (SOCKADDR_BTH));
710 fd = GNUNET_NETWORK_get_fd (dev->handle);
713 fprintf (stderr, "Failed to get the file descriptor\n");
716 if (SOCKET_ERROR == getsockname (fd, (SOCKADDR*)&addr, &addr_len))
718 fprintf (stderr, "Failed to get the port on which we are listening on: \n");
723 /* save the device address */
724 memcpy (&dev->pl_mac, &addr.btAddr, sizeof (BTH_ADDR));
726 /* set the address information */
727 memset (&addr_info, 0, sizeof (CSADDR_INFO));
728 addr_info.iProtocol = BTHPROTO_RFCOMM;
729 addr_info.iSocketType = SOCK_STREAM;
730 addr_info.LocalAddr.lpSockaddr = (LPSOCKADDR)&addr;
731 addr_info.LocalAddr.iSockaddrLength = sizeof (addr);
732 addr_info.RemoteAddr.lpSockaddr = (LPSOCKADDR)&addr;
733 addr_info.RemoteAddr.iSockaddrLength = sizeof (addr);
735 convert_guid((char *) uuid, &guid);
737 /* register the service */
738 memset (&wqs, 0, sizeof (WSAQUERYSET));
739 wqs.dwSize = sizeof (WSAQUERYSET);
740 wqs.dwNameSpace = NS_BTH;
741 wqs.lpszServiceInstanceName = "GNUnet Bluetooth Service";
742 wqs.lpszComment = "This is the service used by the GNUnnet plugin transport";
743 wqs.lpServiceClassId = &guid;
744 wqs.dwNumberOfCsAddrs = 1;
745 wqs.lpcsaBuffer = &addr_info ;
748 if (SOCKET_ERROR == WSASetService (&wqs , RNRSERVICE_REGISTER, 0))
750 fprintf (stderr, "Failed to register the SDP service: ");
756 fprintf (stderr, "The SDP service was registered\n");
763 * Function used for creating the service record and registering it.
765 * @param dev pointer to the device struct
766 * @param rc_channel the rfcomm channel
767 * @return 0 on success
770 register_service (struct HardwareInfos *dev, int rc_channel)
774 * 2. set the service ID, class, profile information
775 * 3. make the service record publicly browsable
776 * 4. register the RFCOMM channel
777 * 5. set the name, provider and description
778 * 6. register the service record to the local SDP server
781 uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
782 dev->pl_mac.mac[5], dev->pl_mac.mac[4], dev->pl_mac.mac[3],
783 dev->pl_mac.mac[2], dev->pl_mac.mac[1], dev->pl_mac.mac[0]};
784 const char *service_dsc = "Bluetooth plugin services";
785 const char *service_prov = "GNUnet provider";
786 uuid_t root_uuid, rfcomm_uuid, svc_uuid;
787 sdp_list_t *root_list = 0, *rfcomm_list = 0, *proto_list = 0,
788 *access_proto_list = 0, *svc_list = 0;
789 sdp_record_t *record = 0;
790 sdp_data_t *channel = 0;
792 record = sdp_record_alloc();
794 /* Set the general service ID */
795 sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
796 svc_list = sdp_list_append (0, &svc_uuid);
797 sdp_set_service_classes (record, svc_list);
798 sdp_set_service_id (record, svc_uuid);
800 /* Make the service record publicly browsable */
801 sdp_uuid16_create (&root_uuid, PUBLIC_BROWSE_GROUP);
802 root_list = sdp_list_append (0, &root_uuid);
803 sdp_set_browse_groups (record, root_list);
805 /* Register the RFCOMM channel */
806 sdp_uuid16_create (&rfcomm_uuid, RFCOMM_UUID);
807 channel = sdp_data_alloc (SDP_UINT8, &rc_channel);
808 rfcomm_list = sdp_list_append (0, &rfcomm_uuid);
809 sdp_list_append (rfcomm_list, channel);
810 proto_list = sdp_list_append (0, rfcomm_list);
812 /* Set protocol information */
813 access_proto_list = sdp_list_append (0, proto_list);
814 sdp_set_access_protos (record, access_proto_list);
816 /* Set the name, provider, and description */
817 sdp_set_info_attr (record, dev->iface, service_prov, service_dsc);
819 /* Connect to the local SDP server */
820 dev->session = sdp_connect (BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
824 fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
825 IFNAMSIZ, dev->iface, strerror (errno));
830 /* Register the service record */
831 if (sdp_record_register (dev->session, record, 0) < 0)
833 fprintf (stderr, "Failed to register a service record on interface `%.*s': %s\n",
834 IFNAMSIZ, dev->iface, strerror (errno));
840 sdp_data_free (channel);
841 sdp_list_free (root_list, 0);
842 sdp_list_free (rfcomm_list, 0);
843 sdp_list_free (proto_list, 0);
844 sdp_list_free (access_proto_list, 0);
845 sdp_list_free (svc_list, 0);
846 sdp_record_free (record);
854 * Function for searching and browsing for a service. This will return the
855 * port number on which the service is running.
857 * @param dest target address
861 get_channel(const char *dest)
865 DWORD wqs_len = sizeof (WSAQUERYSET);
869 unsigned char uuid[] = GNUNET_BLUETOOTH_SDP_UUID;
870 convert_guid ((char *) uuid, &guid);
872 wqs = (WSAQUERYSET*)malloc (wqs_len);
873 ZeroMemory (wqs, wqs_len);
875 wqs->dwSize = sizeof (WSAQUERYSET) ;
876 wqs->lpServiceClassId = &guid;
877 wqs->dwNameSpace = NS_BTH;
878 wqs->dwNumberOfCsAddrs = 0;
879 wqs->lpszContext = (LPSTR)dest;
881 if (SOCKET_ERROR == WSALookupServiceBegin (wqs, LUP_FLUSHCACHE | LUP_RETURN_ALL, &h))
883 if (GetLastError() == WSASERVICE_NOT_FOUND)
885 fprintf (stderr, "WARNING! The device with address %s wasn't found. Skipping the message!", dest);
890 fprintf (stderr, "Failed to find the port number: ");
897 /* search the sdp service */
900 if (SOCKET_ERROR == WSALookupServiceNext (h, LUP_FLUSHCACHE | LUP_RETURN_ALL, &wqs_len, wqs))
902 int error = WSAGetLastError();
908 wqs = (WSAQUERYSET*)malloc (wqs_len);
911 fprintf (stderr, "Failed! The address was valid but there was no data record of requested type\n");
918 fprintf (stderr, "Failed to look over the services: ");
920 WSALookupServiceEnd (h);
926 channel = ((SOCKADDR_BTH*)wqs->lpcsaBuffer->RemoteAddr.lpSockaddr)->port;
931 WSALookupServiceEnd (h);
937 * Function used for searching and browsing for a service. This will return the
938 * port number on which the service is running.
940 * @param dev pointer to the device struct
941 * @param dest target address
945 get_channel(struct HardwareInfos *dev, bdaddr_t dest)
948 * 1. detect all nearby devices
949 * 2. for each device:
950 * 2.1. connect to the SDP server running
951 * 2.2. get a list of service records with the specific UUID
952 * 2.3. for each service record get a list of the protocol sequences and get
955 uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
956 dest.b[5], dest.b[4], dest.b[3],
957 dest.b[2], dest.b[1], dest.b[0]};
958 sdp_session_t *session = 0;
959 sdp_list_t *search_list = 0, *attrid_list = 0, *response_list = 0, *it = 0;
961 uint32_t range = 0x0000ffff;
962 uint8_t channel = -1;
964 /* Connect to the local SDP server */
965 session = sdp_connect (BDADDR_ANY, &dest, 0);
968 fprintf (stderr, "Failed to connect to the SDP server on interface `%.*s': %s\n",
969 IFNAMSIZ, dev->iface, strerror (errno));
973 sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
974 search_list = sdp_list_append (0, &svc_uuid);
975 attrid_list = sdp_list_append (0, &range);
977 if (sdp_service_search_attr_req (session, search_list,
978 SDP_ATTR_REQ_RANGE, attrid_list, &response_list) == 0)
980 for (it = response_list; it; it = it->next)
982 sdp_record_t *record = (sdp_record_t*) it->data;
983 sdp_list_t *proto_list = 0;
984 if (sdp_get_access_protos (record, &proto_list) == 0)
986 channel = sdp_get_proto_port (proto_list, RFCOMM_UUID);
987 sdp_list_free (proto_list, 0);
989 sdp_record_free (record);
993 sdp_list_free (search_list, 0);
994 sdp_list_free (attrid_list, 0);
995 sdp_list_free (response_list, 0);
1000 fprintf (stderr, "Failed to find the listening channel for interface `%.*s': %s\n",
1001 IFNAMSIZ, dev->iface, strerror (errno));
1008 * Read from the socket and put the result into the buffer for transmission to 'stdout'.
1010 * @param sock file descriptor for reading
1011 * @param buf buffer to read to; first bytes will be the 'struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame',
1012 * followed by the actual payload
1013 * @param buf_size size of the buffer
1014 * @param ri where to write radiotap_rx info
1015 * @return number of bytes written to 'buf'
1018 read_from_the_socket (void *sock,
1019 unsigned char *buf, size_t buf_size,
1020 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri)
1022 unsigned char tmpbuf[buf_size];
1026 count = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)sock, tmpbuf, buf_size);
1028 count = read (*((int *)sock), tmpbuf, buf_size);
1033 if (EAGAIN == errno)
1038 fprintf (stderr, "Failed to read from the HCI socket: %s\n", strerror (errno));
1045 /* Get the channel used */
1047 struct sockaddr_rc rc_addr = { 0 };
1049 memset (&rc_addr, 0, sizeof (rc_addr));
1050 len = sizeof (rc_addr);
1051 if (0 > getsockname (*((int *)sock), (struct sockaddr *) &rc_addr, (socklen_t *) &len))
1053 fprintf (stderr, "getsockname() call failed : %s\n", strerror (errno));
1057 memset (ri, 0, sizeof (*ri));
1058 ri->ri_channel = rc_addr.rc_channel;
1061 /* Detect CRC32 at the end */
1062 if (0 == check_crc_buf_osdep (tmpbuf, count - sizeof (uint32_t)))
1064 count -= sizeof(uint32_t);
1067 memcpy (buf, tmpbuf, count);
1073 * Open the bluetooth interface for reading/writing
1075 * @param dev pointer to the device struct
1076 * @return 0 on success
1079 open_device (struct HardwareInfos *dev)
1084 /* bind the RFCOMM socket to the interface */
1085 addr.addressFamily = AF_BTH;
1087 addr.port = BT_PORT_ANY;
1089 if (GNUNET_NETWORK_socket_bind (dev->handle, (const SOCKADDR*)&addr, sizeof (SOCKADDR_BTH), 0) != GNUNET_OK)
1091 fprintf (stderr, "Failed to bind the socket: ");
1092 if (GetLastError() == WSAENETDOWN)
1094 fprintf (stderr, "Please make sure that your Bluetooth device is ON!\n");
1101 /* start listening on the socket */
1102 if (GNUNET_NETWORK_socket_listen (dev->handle, 4) != GNUNET_OK)
1104 fprintf (stderr, "Failed to listen on the socket: ");
1109 /* register the sdp service */
1110 if (register_service(dev) != 0)
1112 fprintf (stderr, "Failed to register a service: ");
1117 int i, dev_id = -1, fd_hci;
1120 struct hci_dev_list_req list;
1121 struct hci_dev_req dev[HCI_MAX_DEV];
1122 } request; //used for detecting the local devices
1123 struct sockaddr_rc rc_addr = { 0 }; //used for binding
1125 /* Initialize the neighbour structure */
1126 neighbours.dev_id = -1;
1127 for (i = 0; i < MAX_PORTS; i++)
1128 neighbours.fds[i] = -1;
1130 /* Open a HCI socket */
1131 fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
1135 fprintf (stderr, "Failed to create HCI socket: %s\n", strerror (errno));
1139 memset (&request, 0, sizeof(request));
1140 request.list.dev_num = HCI_MAX_DEV;
1142 if (ioctl (fd_hci, HCIGETDEVLIST, (void *) &request) < 0)
1144 fprintf (stderr, "ioctl(HCIGETDEVLIST) on interface `%.*s' failed: %s\n",
1145 IFNAMSIZ, dev->iface, strerror (errno));
1149 /* Search for a device with dev->iface name */
1150 for (i = 0; i < request.list.dev_num; i++)
1152 struct hci_dev_info dev_info;
1154 memset (&dev_info, 0, sizeof(struct hci_dev_info));
1155 dev_info.dev_id = request.dev[i].dev_id;
1156 strncpy (dev_info.name, dev->iface, IFNAMSIZ);
1158 if (ioctl (fd_hci, HCIGETDEVINFO, (void *) &dev_info))
1160 fprintf (stderr, "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n",
1161 IFNAMSIZ, dev->iface, strerror (errno));
1165 if (strcmp (dev_info.name, dev->iface) == 0)
1168 dev_id = dev_info.dev_id; //the device was found
1170 * Copy the MAC address to the device structure
1172 memcpy (&dev->pl_mac, &dev_info.bdaddr, sizeof (bdaddr_t));
1174 /* Check if the interface is up */
1175 if (hci_test_bit (HCI_UP, (void *) &dev_info.flags) == 0)
1177 /* Bring the interface up */
1178 if (ioctl (fd_hci, HCIDEVUP, dev_info.dev_id))
1180 fprintf (stderr, "ioctl(HCIDEVUP) on interface `%.*s' failed: %s\n",
1181 IFNAMSIZ, dev->iface, strerror (errno));
1186 /* Check if the device is discoverable */
1187 if (hci_test_bit (HCI_PSCAN, (void *) &dev_info.flags) == 0 ||
1188 hci_test_bit (HCI_ISCAN, (void *) &dev_info.flags) == 0)
1190 /* Set interface Page Scan and Inqury Scan ON */
1191 struct hci_dev_req dev_req;
1193 memset (&dev_req, 0, sizeof (dev_req));
1194 dev_req.dev_id = dev_info.dev_id;
1195 dev_req.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
1197 if (ioctl (fd_hci, HCISETSCAN, (unsigned long) &dev_req))
1199 fprintf (stderr, "ioctl(HCISETSCAN) on interface `%.*s' failed: %s\n",
1200 IFNAMSIZ, dev->iface, strerror (errno));
1210 /* Check if the interface was not found */
1213 fprintf (stderr, "The interface %s was not found\n", dev->iface);
1217 /* Close the hci socket */
1218 (void) close(fd_hci);
1222 /* Bind the rfcomm socket to the interface */
1223 memset (&rc_addr, 0, sizeof (rc_addr));
1224 rc_addr.rc_family = AF_BLUETOOTH;
1225 rc_addr.rc_bdaddr = *BDADDR_ANY;
1227 if (bind_socket (dev->fd_rfcomm, &rc_addr) != 0)
1229 fprintf (stderr, "Failed to bind interface `%.*s': %s\n", IFNAMSIZ,
1230 dev->iface, strerror (errno));
1234 /* Register a SDP service */
1235 if (register_service (dev, rc_addr.rc_channel) != 0)
1237 fprintf (stderr, "Failed to register a service on interface `%.*s': %s\n", IFNAMSIZ,
1238 dev->iface, strerror (errno));
1242 /* Switch socket in listening mode */
1243 if (listen (dev->fd_rfcomm, 5) == -1) //FIXME: probably we need a bigger number
1245 fprintf (stderr, "Failed to listen on socket for interface `%.*s': %s\n", IFNAMSIZ,
1246 dev->iface, strerror (errno));
1257 * Set the header to sane values to make attacks more difficult
1259 * @param taIeeeHeader pointer to the header of the packet
1260 * @param dev pointer to the Hardware_Infos struct
1262 **** copy from gnunet-helper-transport-wlan.c ****
1265 mac_set (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1266 const struct HardwareInfos *dev)
1268 taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
1269 taIeeeHeader->addr3 = mac_bssid_gnunet;
1272 memcpy (&taIeeeHeader->addr2, &dev->pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1274 taIeeeHeader->addr2 = dev->pl_mac;
1280 * Test if the given interface name really corresponds to a bluetooth
1283 * @param iface name of the interface
1284 * @return 0 on success, 1 on error
1285 **** similar with the one from gnunet-helper-transport-wlan.c ****
1288 test_bluetooth_interface (const char *iface)
1294 ret = snprintf (strbuf, sizeof (strbuf),
1295 "/sys/class/bluetooth/%s/subsystem",
1297 if ((ret < 0) || (ret >= sizeof (strbuf)) || (0 != stat (strbuf, &sbuf)))
1300 "Did not find 802.15.1 interface `%s'. Exiting.\n",
1309 * Test incoming packets mac for being our own.
1311 * @param taIeeeHeader buffer of the packet
1312 * @param dev the Hardware_Infos struct
1313 * @return 0 if mac belongs to us, 1 if mac is for another target
1315 **** same as the one from gnunet-helper-transport-wlan.c ****
1318 mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1319 const struct HardwareInfos *dev)
1321 static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
1323 if ( (0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
1324 (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)) )
1325 return 0; /* some drivers set no Macs, then assume it is all for us! */
1327 if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1328 return 1; /* not a GNUnet ad-hoc package */
1329 if ( (0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
1330 (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)) )
1331 return 0; /* for us, or broadcast */
1332 return 1; /* not for us */
1337 * Process data from the stdin. Takes the message, forces the sender MAC to be correct
1338 * and puts it into our buffer for transmission to the receiver.
1340 * @param cls pointer to the device struct ('struct HardwareInfos*')
1341 * @param hdr pointer to the start of the packet
1343 **** same as the one from gnunet-helper-transport-wlan.c ****
1346 stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1348 struct HardwareInfos *dev = cls;
1349 const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header;
1350 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *blueheader;
1353 sendsize = ntohs (hdr->size);
1355 sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
1356 (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)) )
1358 fprintf (stderr, "Received malformed message\n");
1361 sendsize -= (sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage) -
1362 sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1363 if (MAXLINE < sendsize)
1365 fprintf (stderr, "Packet too big for buffer\n");
1368 header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
1369 memcpy (&write_pout.buf, &header->frame, sendsize);
1370 blueheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf;
1372 /* payload contains MAC address, but we don't trust it, so we'll
1373 * overwrite it with OUR MAC address to prevent mischief */
1374 mac_set (blueheader, dev);
1375 memcpy (&blueheader->addr1, &header->frame.addr1,
1376 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1377 write_pout.size = sendsize;
1382 * Broadcast a HELLO message for peer discovery
1384 * @param dev pointer to the device struct
1385 * @param dev pointer to the socket which was added to the set
1386 * @return 0 on success
1389 send_broadcast (struct HardwareInfos *dev, int *sendsocket)
1395 if ((neighbours.size == neighbours.pos && new_device == 1) || neighbours.size == 0)
1397 inquiry_devices: //skip the conditions and force a inquiry for new devices
1400 * It means that I sent HELLO messages to all the devices from the list and I should search
1401 * for new ones or that this is the first time when I do a search.
1403 inquiry_info *devices = NULL;
1404 int i, responses, max_responses = MAX_PORTS;
1407 if (neighbours.size >= MAX_PORTS)
1409 fprintf (stderr, "%.*s reached the top limit for the discovarable devices\n", IFNAMSIZ, dev->iface);
1413 /* Get the device id */
1414 if (neighbours.dev_id == -1)
1416 char addr[19] = { 0 }; //the device MAC address
1418 ba2str ((bdaddr_t *) &dev->pl_mac, addr);
1419 neighbours.dev_id = hci_devid (addr);
1420 if (neighbours.dev_id < 0)
1422 fprintf (stderr, "Failed to get the device id for interface %.*s : %s\n", IFNAMSIZ,
1423 dev->iface, strerror (errno));
1428 devices = malloc (max_responses * sizeof (inquiry_info));
1429 if (devices == NULL)
1431 fprintf (stderr, "Failed to allocate memory for inquiry info list on interface %.*s\n", IFNAMSIZ,
1436 responses = hci_inquiry (neighbours.dev_id, 8, max_responses, NULL, &devices, IREQ_CACHE_FLUSH);
1439 fprintf (stderr, "Failed to inquiry on interface %.*s\n", IFNAMSIZ, dev->iface);
1443 fprintf (stderr, "LOG : Found %d devices\n", responses); //FIXME delete it after debugging stage
1447 fprintf (stderr, "LOG : No devices discoverable\n");
1451 for (i = 0; i < responses; i++)
1459 fprintf (stderr, "%.*s reached the top limit for the discoverable devices (after inquiry)\n", IFNAMSIZ,
1464 /* Search if the address already exists on the list */
1465 for (j = 0; j < neighbours.size; j++)
1467 if (memcmp (&(devices + i)->bdaddr, &(neighbours.devices[j]), sizeof (bdaddr_t)) == 0)
1470 fprintf (stderr, "LOG : the device already exists on the list\n"); //FIXME debugging message
1477 char addr[19] = { 0 };
1479 ba2str (&(devices +i)->bdaddr, addr);
1480 fprintf (stderr, "LOG : %s was added to the list\n", addr); //FIXME debugging message
1481 memcpy (&(neighbours.devices[neighbours.size++]), &(devices + i)->bdaddr, sizeof (bdaddr_t));
1489 int connection_successful = 0;
1490 struct sockaddr_rc addr_rc = { 0 };
1492 addr_rc.rc_family = AF_BLUETOOTH;
1494 /* Try to connect to a new device from the list */
1495 while (neighbours.pos < neighbours.size)
1497 /* Check if we are already connected to this device */
1498 if (neighbours.fds[neighbours.pos] == -1)
1501 memset (&addr_rc.rc_bdaddr, 0, sizeof (addr_rc.rc_bdaddr));
1502 memcpy (&addr_rc.rc_bdaddr, &(neighbours.devices[neighbours.pos]), sizeof (addr_rc.rc_bdaddr));
1504 addr_rc.rc_channel = get_channel (dev, addr_rc.rc_bdaddr);
1506 *sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1507 if (connect (*sendsocket, (struct sockaddr *)&addr_rc, sizeof (addr_rc)) == 0)
1509 neighbours.fds[neighbours.pos++] = *sendsocket;
1510 connection_successful = 1;
1511 char addr[19] = { 0 };
1512 ba2str (&(neighbours.devices[neighbours.pos - 1]), addr);
1513 fprintf (stderr, "LOG : Connected to %s\n", addr);
1519 char addr[19] = { 0 };
1520 errno_copy = errno; //Save a copy for later
1521 ba2str (&(neighbours.devices[neighbours.pos]), addr);
1522 fprintf (stderr, "LOG : Couldn't connect on device %s, error : %s\n", addr, strerror(errno));
1523 if (errno != ECONNREFUSED) //FIXME be sure that this works
1525 fprintf (stderr, "LOG : Removes %d device from the list\n", neighbours.pos);
1526 /* Remove the device from the list */
1527 memcpy (&neighbours.devices[neighbours.pos], &neighbours.devices[neighbours.size - 1], sizeof (bdaddr_t));
1528 memset (&neighbours.devices[neighbours.size - 1], 0, sizeof (bdaddr_t));
1529 neighbours.fds[neighbours.pos] = neighbours.fds[neighbours.size - 1];
1530 neighbours.fds[neighbours.size - 1] = -1;
1531 neighbours.size -= 1;
1534 neighbours.pos += 1;
1536 if (neighbours.pos >= neighbours.size)
1541 if (loops == MAX_LOOPS) //don't get stuck trying to connect to one device
1547 fprintf (stderr, "LOG : Search for a new device\n"); //FIXME debugging message
1548 neighbours.pos += 1;
1552 /* Cycle on the list */
1553 if (neighbours.pos == neighbours.size)
1556 searching_devices_count += 1;
1558 if (searching_devices_count == MAX_LOOPS)
1560 fprintf (stderr, "LOG : Force to inquiry for new devices\n");
1561 searching_devices_count = 0;
1562 goto inquiry_devices;
1565 /* If a new device wasn't found, search an old one */
1566 if (connection_successful == 0)
1568 int loop_check = neighbours.pos;
1569 while (neighbours.fds[neighbours.pos] == -1)
1571 if (neighbours.pos == neighbours.size)
1574 if (neighbours.pos == loop_check)
1576 if (errno_copy == ECONNREFUSED)
1578 fprintf (stderr, "LOG : No device found. Go back and search again\n"); //FIXME debugging message
1581 goto search_for_devices;
1585 return 1; // Skip the broadcast message
1589 neighbours.pos += 1;
1592 *sendsocket = neighbours.fds[neighbours.pos++];
1600 * Main function of the helper. This code accesses a bluetooth interface
1601 * forwards traffic in both directions between the bluetooth interface and
1602 * stdin/stdout of this process. Error messages are written to stderr.
1604 * @param argc number of arguments, must be 2
1605 * @param argv arguments only argument is the name of the interface (i.e. 'hci0')
1606 * @return 0 on success (never happens, as we don't return unless aborted), 1 on error
1608 **** similar to gnunet-helper-transport-wlan.c ****
1611 main (int argc, char *argv[])
1614 struct HardwareInfos dev;
1615 char readbuf[MAXLINE];
1620 struct MessageStreamTokenizer *stdin_mst;
1623 int crt_rfds = 0, rfds_list[MAX_PORTS];
1624 int broadcast, sendsocket;
1625 /* Assert privs so we can modify the firewall rules! */
1627 #ifdef HAVE_SETRESUID
1628 if (0 != setresuid (uid, 0, 0))
1630 fprintf (stderr, "Failed to setresuid to root: %s\n", strerror (errno));
1634 if (0 != seteuid (0))
1636 fprintf (stderr, "Failed to seteuid back to root: %s\n", strerror (errno));
1641 /* Make use of SGID capabilities on POSIX */
1642 memset (&dev, 0, sizeof (dev));
1643 dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1644 raw_eno = errno; /* remember for later */
1646 /* Now that we've dropped root rights, we can do error checking */
1649 fprintf (stderr, "You must specify the name of the interface as the first \
1650 and only argument to this program.\n");
1651 if (-1 != dev.fd_rfcomm)
1652 (void) close (dev.fd_rfcomm);
1656 if (-1 == dev.fd_rfcomm)
1658 fprintf (stderr, "Failed to create a RFCOMM socket: %s\n", strerror (raw_eno));
1661 if (dev.fd_rfcomm >= FD_SETSIZE)
1663 fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1664 dev.fd_rfcomm, FD_SETSIZE);
1665 (void) close (dev.fd_rfcomm);
1668 if (0 != test_bluetooth_interface (argv[1]))
1670 (void) close (dev.fd_rfcomm);
1673 strncpy (dev.iface, argv[1], IFNAMSIZ);
1674 if (0 != open_device (&dev))
1676 (void) close (dev.fd_rfcomm);
1682 uid_t uid = getuid ();
1683 #ifdef HAVE_SETRESUID
1684 if (0 != setresuid (uid, uid, uid))
1686 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1687 if (-1 != dev.fd_rfcomm)
1688 (void) close (dev.fd_rfcomm);
1692 if (0 != (setuid (uid) | seteuid (uid)))
1694 fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
1695 if (-1 != dev.fd_rfcomm)
1696 (void) close (dev.fd_rfcomm);
1702 /* Send MAC address of the bluetooth interface to STDOUT first */
1704 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
1706 macmsg.hdr.size = htons (sizeof (macmsg));
1707 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
1708 memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress));
1709 memcpy (write_std.buf, &macmsg, sizeof (macmsg));
1710 write_std.size = sizeof (macmsg);
1714 stdin_mst = mst_create (&stdin_send_hw, &dev);
1718 * TODO : I should make the time out of a mac endpoint smaller and check if the rate
1719 * from get_wlan_header (plugin_transport_bluetooth.c) is correct.
1728 if ((0 == write_pout.size) && (1 == stdin_open))
1730 FD_SET (STDIN_FILENO, &rfds);
1731 maxfd = MAX (maxfd, STDIN_FILENO);
1733 if (0 == write_std.size)
1735 FD_SET (dev.fd_rfcomm, &rfds);
1736 maxfd = MAX (maxfd, dev.fd_rfcomm);
1739 for (i = 0; i < crt_rfds; i++) // it can receive messages from multiple devices
1741 FD_SET (rfds_list[i], &rfds);
1742 maxfd = MAX (maxfd, rfds_list[i]);
1745 if (0 < write_std.size)
1747 FD_SET (STDOUT_FILENO, &wfds);
1748 maxfd = MAX (maxfd, STDOUT_FILENO);
1750 if (0 < write_pout.size) //it can send messages only to one device per loop
1752 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *frame;
1753 /* Get the destination address */
1754 frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) write_pout.buf;
1756 if (memcmp (&frame->addr1, &dev.pl_mac,
1757 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1760 memset (&write_pout, 0, sizeof (write_pout)); //clear the buffer
1762 else if (memcmp (&frame->addr1, &broadcast_address,
1763 sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1765 fprintf (stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n", dev.iface, neighbours.pos, neighbours.size); //FIXME: debugging message
1767 if (send_broadcast(&dev, &sendsocket) != 0) //if the searching wasn't successful don't get stuck on the select stage
1770 memset (&write_pout, 0, sizeof (write_pout)); //remove the message
1771 fprintf (stderr, "LOG : Skipping the broadcast message (pos %d, size %d)\n", neighbours.pos, neighbours.size);
1775 FD_SET (sendsocket, &wfds);
1776 maxfd = MAX (maxfd, sendsocket);
1783 /* Search if the address already exists on the list */
1784 for (i = 0; i < neighbours.size; i++)
1786 if (memcmp (&frame->addr1, &(neighbours.devices[i]), sizeof (bdaddr_t)) == 0)
1789 if (neighbours.fds[i] != -1)
1791 found = 1; //save the position where it was found
1792 FD_SET (neighbours.fds[i], &wfds);
1793 maxfd = MAX (maxfd, neighbours.fds[i]);
1794 sendsocket = neighbours.fds[i];
1795 fprintf (stderr, "LOG: the address was found in the list\n");
1803 struct sockaddr_rc addr = { 0 };
1805 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,
1806 frame->addr1.mac[5], frame->addr1.mac[4], frame->addr1.mac[3],
1807 frame->addr1.mac[2], frame->addr1.mac[1], frame->addr1.mac[0]); //FIXME: debugging message
1809 sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1813 fprintf (stderr, "Failed to create a RFCOMM socket (sending stage): %s\n",
1818 memcpy (&addr.rc_bdaddr, &frame->addr1, sizeof (bdaddr_t));
1819 addr.rc_family = AF_BLUETOOTH;
1820 addr.rc_channel = get_channel (&dev, addr.rc_bdaddr);
1824 status = connect (sendsocket, (struct sockaddr *) &addr, sizeof (addr));
1825 if (0 != status && errno != EAGAIN)
1827 if (errno == ECONNREFUSED && tries < 2)
1829 fprintf (stderr, "LOG : %.*s failed to connect. Trying again!\n", IFNAMSIZ, dev.iface);
1833 else if (errno == EBADF)
1835 fprintf (stderr, "LOG : %s failed to connect : %s. Skip it!\n", dev.iface, strerror (errno));
1836 memset (&write_pout, 0, sizeof (write_pout));
1841 fprintf (stderr, "LOG : %s failed to connect : %s. Try again later!\n", dev.iface, strerror (errno));
1842 memset (&write_pout, 0, sizeof (write_pout));
1849 FD_SET (sendsocket, &wfds);
1850 maxfd = MAX (maxfd, sendsocket);
1851 fprintf (stderr, "LOG : Connection successful\n");
1852 if (pos != 0) // save the socket
1854 neighbours.fds[pos] = sendsocket;
1858 /* Add the new device to the discovered devices list */
1859 if (neighbours.size < MAX_PORTS)
1861 neighbours.fds[neighbours.size] = sendsocket;
1862 memcpy (&(neighbours.devices[neighbours.size++]), &addr.rc_bdaddr, sizeof (bdaddr_t));
1866 fprintf (stderr, "The top limit for the discovarable devices' list was reached\n");
1876 /* Select a fd which is ready for action :) */
1878 int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
1879 if ((-1 == retval) && (EINTR == errno))
1881 if (0 > retval && errno != EBADF) // we handle BADF errors later
1883 fprintf (stderr, "select failed: %s\n", strerror (errno));
1887 if (FD_ISSET (STDOUT_FILENO , &wfds))
1890 write (STDOUT_FILENO, write_std.buf + write_std.pos,
1891 write_std.size - write_std.pos);
1894 fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1897 write_std.pos += ret;
1898 if (write_std.pos == write_std.size)
1903 fprintf (stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); //FIXME: debugging message
1906 if (sendsocket != -1)
1908 if (FD_ISSET (sendsocket , &wfds))
1911 write (sendsocket, write_pout.buf + write_std.pos,
1912 write_pout.size - write_pout.pos);
1913 if (0 > ret) //FIXME should I first check the error type?
1915 fprintf (stderr, "Failed to write to bluetooth device: %s. Closing the socket!\n",
1917 for (i = 0; i < neighbours.size; i++)
1919 if (neighbours.fds[i] == sendsocket)
1921 (void) close(sendsocket);
1922 neighbours.fds[i] = -1;
1926 /* Remove the message */
1927 memset (&write_pout.buf + write_std.pos, 0, (write_pout.size - write_pout.pos));
1928 write_pout.pos = 0 ;
1929 write_pout.size = 0;
1933 write_pout.pos += ret;
1934 if ((write_pout.pos != write_pout.size) && (0 != ret))
1936 /* We should not get partial sends with packet-oriented devices... */
1937 fprintf (stderr, "Write error, partial send: %u/%u\n",
1938 (unsigned int) write_pout.pos,
1939 (unsigned int) write_pout.size);
1943 if (write_pout.pos == write_pout.size)
1946 write_pout.size = 0;
1948 fprintf (stderr, "LOG : %s sends a message to a DEVICE\n", dev.iface); //FIXME: debugging message
1952 for (i = 0; i <= maxfd; i++)
1954 if (FD_ISSET (i, &rfds))
1956 if (i == STDIN_FILENO)
1959 read (i, readbuf, sizeof (readbuf));
1963 "Read error from STDIN: %s\n",
1969 /* stop reading... */
1974 mst_receive (stdin_mst, readbuf, ret);
1975 fprintf (stderr, "LOG : %s receives a message from STDIN\n", dev.iface); //FIXME: debugging message
1978 else if (i == dev.fd_rfcomm)
1981 struct sockaddr_rc addr = { 0 };
1982 unsigned int opt = sizeof (addr);
1984 readsocket = accept (dev.fd_rfcomm, (struct sockaddr *) &addr, &opt);
1985 fprintf(stderr, "LOG : %s accepts a message\n", dev.iface); //FIXME: debugging message
1986 if (readsocket == -1)
1988 fprintf (stderr, "Failed to accept a connection on interface: %.*s\n", IFNAMSIZ,
1994 FD_SET (readsocket, &rfds);
1995 maxfd = MAX (maxfd, readsocket);
1997 if (crt_rfds < MAX_PORTS)
1998 rfds_list[crt_rfds++] = readsocket;
2001 fprintf (stderr, "The limit for the read file descriptors list was \
2010 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
2012 fprintf (stderr, "LOG : %s reads something from the socket\n", dev.iface);//FIXME : debugging message
2013 rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
2015 read_from_the_socket ((void *)&i, (unsigned char *) &rrm->frame,
2016 sizeof (write_std.buf)
2017 - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2018 + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2025 /* Remove the socket from the list */
2026 for (j = 0; j < crt_rfds; j++)
2028 if (rfds_list[j] == i)
2030 rfds_list[j] ^= rfds_list[crt_rfds - 1];
2031 rfds_list[crt_rfds - 1] ^= rfds_list[j];
2032 rfds_list[j] ^= rfds_list[crt_rfds - 1];
2038 fprintf (stderr, "Read error from raw socket: %s\n", strerror (errno));
2041 if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2043 write_std.size = ret
2044 + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2045 - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2046 rrm->header.size = htons (write_std.size);
2047 rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2054 /* Error handling, try to clean up a bit at least */
2055 mst_destroy (stdin_mst);
2057 sdp_close (dev.session);
2058 (void) close (dev.fd_rfcomm);
2059 (void) close (sendsocket);
2061 for (i = 0; i < crt_rfds; i++)
2062 (void) close (rfds_list[i]);
2064 for (i = 0; i < neighbours.size; i++)
2065 (void) close (neighbours.fds[i]);
2067 struct HardwareInfos dev;
2068 struct GNUNET_NETWORK_Handle *sendsocket;
2069 struct GNUNET_NETWORK_FDSet *rfds;
2070 struct GNUNET_NETWORK_FDSet *wfds;
2071 struct GNUNET_NETWORK_Handle *rfds_list[MAX_PORTS];
2072 char readbuf[MAXLINE] = { 0 };
2073 SOCKADDR_BTH acc_addr = { 0 };
2074 int addr_len = sizeof (SOCKADDR_BTH);
2075 int broadcast, i, stdin_open, crt_rfds = 0;
2076 HANDLE stdin_handle = GetStdHandle (STD_INPUT_HANDLE);
2077 HANDLE stdout_handle = GetStdHandle (STD_OUTPUT_HANDLE);
2078 struct MessageStreamTokenizer *stdin_mst;
2080 /* check the handles */
2081 if (stdin_handle == INVALID_HANDLE_VALUE)
2083 fprintf (stderr, "Failed to get the stdin handle\n");
2087 if (stdout_handle == INVALID_HANDLE_VALUE)
2089 fprintf (stderr, "Failed to get the stdout handle\n");
2093 /* initialize windows sockets */
2094 initialize_windows_sockets();
2096 // /* test bluetooth socket family support */ --> it return false because the GNUNET_NETWORK_test_pf should also receive the type of socket (BTHPROTO_RFCOMM)
2097 // if (GNUNET_NETWORK_test_pf (AF_BTH) != GNUNET_OK)
2099 // fprintf (stderr, "AF_BTH family is not supported\n");
2103 /* create the socket */
2104 dev.handle = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
2105 if (dev.handle == NULL)
2107 fprintf (stderr, "Failed to create RFCOMM socket: ");
2113 if (open_device (&dev) == -1)
2115 fprintf (stderr, "Failed to open the device\n");
2117 if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
2119 fprintf (stderr, "Failed to close the socket!\n");
2125 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (dev.handle, 1) )
2127 fprintf (stderr, "Failed to change the socket mode\n");
2131 memset (&write_std, 0, sizeof (write_std));
2132 memset (&write_pout, 0, sizeof (write_pout));
2135 rfds = GNUNET_NETWORK_fdset_create ();
2136 wfds = GNUNET_NETWORK_fdset_create ();
2138 /* Send MAC address of the bluetooth interface to STDOUT first */
2140 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
2142 macmsg.hdr.size = htons (sizeof (macmsg));
2143 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
2144 memcpy (&macmsg.mac, &dev.pl_mac, sizeof (struct GNUNET_TRANSPORT_WLAN_MacAddress_Copy));
2145 memcpy (write_std.buf, &macmsg, sizeof (macmsg));
2146 write_std.size = sizeof (macmsg);
2150 stdin_mst = mst_create (&stdin_send_hw, &dev);
2155 int stdout_pos = -1;
2162 sendsocket = NULL; //FIXME ???memleaks
2164 GNUNET_NETWORK_fdset_zero (rfds);
2165 if ((0 == write_pout.size) && (1 == stdin_open))
2169 GNUNET_NETWORK_fdset_handle_set (rfds, (struct GNUNET_DISK_FileHandle*) &stdin_handle);
2172 if (0 == write_std.size)
2175 GNUNET_NETWORK_fdset_set (rfds, dev.handle);
2178 for (i = 0; i < crt_rfds; i++)
2181 GNUNET_NETWORK_fdset_set (rfds, rfds_list[i]);
2184 GNUNET_NETWORK_fdset_zero (wfds);
2185 if (0 < write_std.size)
2188 GNUNET_NETWORK_fdset_handle_set (wfds, (struct GNUNET_DISK_FileHandle*) &stdout_handle);
2189 // printf ("%s\n", write_std.buf);
2190 // memset (write_std.buf, 0, write_std.size);
2191 // write_std.size = 0;
2194 if (0 < write_pout.size)
2196 if (strcmp (argv[1], "ff:ff:ff:ff:ff:ff") == 0) {
2197 fprintf(stderr, "LOG: BROADCAST! Skipping the message\n");
2200 memset (write_pout.buf, 0, write_pout.size);
2201 write_pout.size = 0;
2206 fprintf (stderr, "LOG : has a new message for %s\n", argv[1]);
2207 sendsocket = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM, BTHPROTO_RFCOMM);
2209 if (sendsocket == NULL)
2211 fprintf (stderr, "Failed to create RFCOMM socket: \n");
2216 memset (&addr, 0, sizeof (addr));
2217 //addr.addressFamily = AF_BTH;
2219 WSAStringToAddress (argv[1], AF_BTH, NULL, (LPSOCKADDR) &addr, &addr_len))
2221 fprintf (stderr, "Failed to translate the address: ");
2225 addr.port = get_channel (argv[1]);
2226 if (addr.port == -1)
2228 fprintf (stderr, "Couldn't find the sdp service for the address: %s\n", argv[1]);
2229 memset (write_pout.buf, 0, write_pout.size);
2230 write_pout.size = 0;
2231 broadcast = 1; //skipping the select part
2235 if (GNUNET_OK != GNUNET_NETWORK_socket_connect (sendsocket, (LPSOCKADDR)&addr, addr_len))
2237 fprintf (stderr, "Failed to connect: ");
2242 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (sendsocket, 1) )
2244 fprintf (stderr, "Failed to change the socket mode\n");
2248 GNUNET_NETWORK_fdset_set (wfds, sendsocket);
2255 int retval = GNUNET_NETWORK_socket_select (rfds, wfds, NULL, GNUNET_TIME_relative_get_forever_());
2258 fprintf (stderr, "Select error\n");
2261 //if (GNUNET_NETWORK_fdset_isset (wfds, (struct GNUNET_NETWORK_Handle*)&stdout_handle))
2262 if (retval == stdout_pos)
2264 fprintf(stderr, "LOG : sends a message to STDOUT\n"); //FIXME: debugging message
2266 //ret = GNUNET_NETWORK_socket_send ((struct GNUNET_NETWORK_Handle *)&stdout_handle, write_std.buf + write_std.pos, write_std.size - write_std.pos);
2267 //ret = write (STDOUT_FILENO, write_std.buf + write_std.pos, write_std.size - write_std.pos);
2269 if (FALSE == WriteFile (stdout_handle, write_std.buf + write_std.pos, write_std.size - write_std.pos, &ret, NULL))
2271 fprintf (stderr, "Failed to write to STDOUT: ");
2278 fprintf (stderr, "Failed to write to STDOUT\n");
2282 write_std.pos += ret;
2283 if (write_std.pos == write_std.size)
2289 if (sendsocket != NULL)
2291 if (GNUNET_NETWORK_fdset_isset (wfds, sendsocket))
2294 ret = GNUNET_NETWORK_socket_send (sendsocket, write_pout.buf + write_pout.pos,
2295 write_pout.size - write_pout.pos);
2297 if (GNUNET_SYSERR == ret)
2299 fprintf (stderr, "Failed to send to the socket. Closing the socket. Error: \n");
2301 if (GNUNET_NETWORK_socket_close (sendsocket) != GNUNET_OK)
2303 fprintf (stderr, "Failed to close the sendsocket!\n");
2310 write_pout.pos += ret;
2311 if ((write_pout.pos != write_pout.size) && (0 != ret))
2313 /* we should not get partial sends with packet-oriented devices... */
2314 fprintf (stderr, "Write error, partial send: %u/%u\n",
2315 (unsigned int) write_pout.pos,
2316 (unsigned int) write_pout.size);
2320 if (write_pout.pos == write_pout.size)
2323 write_pout.size = 0;
2326 fprintf(stderr, "LOG : sends a message to a DEVICE\n"); //FIXME: debugging message
2331 //if (GNUNET_NETWORK_fdset_isset (rfds, (struct GNUNET_NETWORK_Handle*)&stdin_handle))
2332 if (retval == stdin_pos)
2335 //ret = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)&stdin_handle, readbuf, sizeof (write_pout.buf));
2336 //ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
2338 if (FALSE == ReadFile (stdin_handle, readbuf, sizeof (readbuf), &ret, NULL)) /* do nothing asynchronous */
2340 fprintf (stderr, "Read error from STDIN: ");
2346 /* stop reading... */
2349 mst_receive (stdin_mst, readbuf, ret);
2350 fprintf (stderr, "LOG : receives a message from STDIN\n"); //FIXME: debugging message
2354 if (GNUNET_NETWORK_fdset_isset (rfds, dev.handle))
2356 fprintf (stderr, "LOG: accepting connection\n");
2357 struct GNUNET_NETWORK_Handle *readsocket;
2358 readsocket = GNUNET_NETWORK_socket_accept (dev.handle, (LPSOCKADDR)&acc_addr, &addr_len);
2359 if (readsocket == NULL)
2361 fprintf (stderr, "Accept error %d: ", GetLastError());
2367 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (readsocket, 1) )
2369 fprintf (stderr, "Failed to change the socket mode\n");
2372 GNUNET_NETWORK_fdset_set (rfds, readsocket);
2374 if (crt_rfds < MAX_PORTS)
2375 rfds_list[crt_rfds++] = readsocket;
2378 fprintf (stderr, "The limit for the read file descriptors list was reached\n");
2384 for (i = 0; i < crt_rfds; i++)
2386 if (GNUNET_NETWORK_fdset_isset (rfds, rfds_list[i]))
2388 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
2390 fprintf (stderr, "LOG: reading something from the socket\n");//FIXME : debugging message
2391 rrm = (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
2392 ret = read_from_the_socket (rfds_list[i], (unsigned char *) &rrm->frame,
2393 sizeof (write_std.buf)
2394 - sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2395 + sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2400 //TODO remove the socket from the list
2401 if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2403 fprintf (stderr, "Failed to close the sendsocket!\n");
2407 fprintf (stderr, "Read error from raw socket: ");
2412 if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2414 write_std.size = ret
2415 + sizeof (struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2416 - sizeof (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2417 rrm->header.size = htons (write_std.size);
2418 rrm->header.type = htons (GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2426 mst_destroy (stdin_mst);
2429 if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
2431 fprintf (stderr, "Failed to close the socket!\n");
2435 for (i = 0; i < crt_rfds; i++)
2437 if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2439 fprintf (stderr, "Failed to close the socket!\n");
2446 return 1; /* we never exit 'normally' */