aboutsummaryrefslogtreecommitdiff
path: root/src/transport/gnunet-helper-transport-bluetooth.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/transport/gnunet-helper-transport-bluetooth.c')
-rw-r--r--src/transport/gnunet-helper-transport-bluetooth.c2285
1 files changed, 0 insertions, 2285 deletions
diff --git a/src/transport/gnunet-helper-transport-bluetooth.c b/src/transport/gnunet-helper-transport-bluetooth.c
deleted file mode 100644
index 019f3914f..000000000
--- a/src/transport/gnunet-helper-transport-bluetooth.c
+++ /dev/null
@@ -1,2285 +0,0 @@
1/*
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 (C) 2009 Thomas d'Otreppe
6
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.
11
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.
16
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/>.
19
20 SPDX-License-Identifier: AGPL3.0-or-later
21 */
22#include "gnunet_config.h"
23
24#include <bluetooth/bluetooth.h>
25#include <bluetooth/hci.h>
26#include <bluetooth/hci_lib.h>
27#include <bluetooth/rfcomm.h>
28#include <bluetooth/sdp.h>
29#include <bluetooth/sdp_lib.h>
30#include <errno.h>
31#include <linux/if.h>
32#include <stdio.h>
33#include <stdlib.h>
34#include <sys/ioctl.h>
35#include <sys/param.h>
36#include <sys/socket.h>
37#include <sys/stat.h>
38#include <sys/types.h>
39#include <unistd.h>
40
41#include "plugin_transport_wlan.h"
42#include "gnunet_protocols.h"
43
44
45/**
46 * Maximum number of ports assignable for RFCOMMM protocol.
47 */
48#define MAX_PORTS 30
49
50/**
51 * Maximum size of a message allowed in either direction
52 * (used for our receive and sent buffers).
53 */
54#define MAXLINE 4096
55
56
57/**
58 * Maximum number of loops without inquiring for new devices.
59 */
60#define MAX_LOOPS 5
61
62/**
63 * In bluez library, the maximum name length of a device is 8
64 */
65#define BLUEZ_DEVNAME_SIZE 8
66
67/**
68 * struct for storing the information of the hardware. There is only
69 * one of these.
70 */
71struct HardwareInfos
72{
73 /**
74 * Name of the interface, not necessarily 0-terminated (!).
75 */
76 char iface[IFNAMSIZ];
77
78 /**
79 * file descriptor for the rfcomm socket
80 */
81 int fd_rfcomm;
82
83 /**
84 * MAC address of our own bluetooth interface.
85 */
86 struct GNUNET_TRANSPORT_WLAN_MacAddress pl_mac;
87
88 /**
89 * SDP session
90 */
91 sdp_session_t *session;
92};
93
94/**
95 * IO buffer used for buffering data in transit (to wireless or to stdout).
96 */
97struct SendBuffer
98{
99 /**
100 * How many bytes of data are stored in 'buf' for transmission right now?
101 * Data always starts at offset 0 and extends to 'size'.
102 */
103 size_t size;
104
105 /**
106 * How many bytes that were stored in 'buf' did we already write to the
107 * destination? Always smaller than 'size'.
108 */
109 size_t pos;
110
111 /**
112 * Buffered data; twice the maximum allowed message size as we add some
113 * headers.
114 */
115 char buf[MAXLINE * 2];
116};
117
118#ifdef __linux__
119/**
120 * Devices buffer used to keep a list with all the discoverable devices in
121 * order to send them HELLO messages one by one when it receive a broadcast message.
122 */
123struct BroadcastMessages
124{
125 /* List with the discoverable devices' addresses */
126 bdaddr_t devices[MAX_PORTS];
127
128 /* List with the open sockets */
129 int fds[MAX_PORTS];
130
131
132 /* The number of the devices */
133 int size;
134
135 /* The current position */
136 int pos;
137
138 /* The device id */
139 int dev_id;
140};
141
142/**
143 * Address used to identify the broadcast messages.
144 */
145static struct GNUNET_TRANSPORT_WLAN_MacAddress broadcast_address = { { 255, 255,
146 255, 255,
147 255,
148 255 } };
149
150/**
151 * Buffer with the discoverable devices.
152 */
153static struct BroadcastMessages neighbours;
154
155static int searching_devices_count = 0;
156#endif
157
158/**
159 * Buffer for data read from stdin to be transmitted to the bluetooth device
160 */
161static struct SendBuffer write_pout;
162
163/**
164 * Buffer for data read from the bluetooth device to be transmitted to stdout.
165 */
166static struct SendBuffer write_std;
167
168
169/* ****** this are the same functions as the ones used in gnunet-helper-transport-wlan.c ****** */
170
171/**
172 * To what multiple do we align messages? 8 byte should suffice for everyone
173 * for now.
174 */
175#define ALIGN_FACTOR 8
176
177/**
178 * Smallest supported message.
179 */
180#define MIN_BUFFER_SIZE sizeof(struct GNUNET_MessageHeader)
181
182
183/**
184 * Functions with this signature are called whenever a
185 * complete message is received by the tokenizer.
186 *
187 * @param cls closure
188 * @param message the actual message
189 */
190typedef void (*MessageTokenizerCallback) (void *cls,
191 const struct
192 GNUNET_MessageHeader *
193 message);
194
195/**
196 * Handle to a message stream tokenizer.
197 */
198struct MessageStreamTokenizer
199{
200 /**
201 * Function to call on completed messages.
202 */
203 MessageTokenizerCallback cb;
204
205 /**
206 * Closure for cb.
207 */
208 void *cb_cls;
209
210 /**
211 * Size of the buffer (starting at 'hdr').
212 */
213 size_t curr_buf;
214
215 /**
216 * How many bytes in buffer have we already processed?
217 */
218 size_t off;
219
220 /**
221 * How many bytes in buffer are valid right now?
222 */
223 size_t pos;
224
225 /**
226 * Beginning of the buffer. Typed like this to force alignment.
227 */
228 struct GNUNET_MessageHeader *hdr;
229};
230
231
232/**
233 * Create a message stream tokenizer.
234 *
235 * @param cb function to call on completed messages
236 * @param cb_cls closure for cb
237 * @return handle to tokenizer
238 */
239static struct MessageStreamTokenizer *
240mst_create (MessageTokenizerCallback cb,
241 void *cb_cls)
242{
243 struct MessageStreamTokenizer *ret;
244
245 ret = malloc (sizeof(struct MessageStreamTokenizer));
246 if (NULL == ret)
247 {
248 fprintf (stderr, "Failed to allocate buffer for tokenizer\n");
249 exit (1);
250 }
251 ret->hdr = malloc (MIN_BUFFER_SIZE);
252 if (NULL == ret->hdr)
253 {
254 fprintf (stderr, "Failed to allocate buffer for alignment\n");
255 exit (1);
256 }
257 ret->curr_buf = MIN_BUFFER_SIZE;
258 ret->cb = cb;
259 ret->cb_cls = cb_cls;
260 ret->pos = 0;
261
262 return ret;
263}
264
265
266/**
267 * Add incoming data to the receive buffer and call the
268 * callback for all complete messages.
269 *
270 * @param mst tokenizer to use
271 * @param buf input data to add
272 * @param size number of bytes in buf
273 * @return GNUNET_OK if we are done processing (need more data)
274 * GNUNET_SYSERR if the data stream is corrupt
275 */
276static int
277mst_receive (struct MessageStreamTokenizer *mst,
278 const char *buf, size_t size)
279{
280 const struct GNUNET_MessageHeader *hdr;
281 size_t delta;
282 uint16_t want;
283 char *ibuf;
284 int need_align;
285 unsigned long offset;
286 int ret;
287
288 ret = GNUNET_OK;
289 ibuf = (char *) mst->hdr;
290 while (mst->pos > 0)
291 {
292do_align:
293 if (mst->pos < mst->off)
294 {
295 // fprintf (stderr, "We processed too many bytes!\n");
296 return GNUNET_SYSERR;
297 }
298 if ((mst->curr_buf - mst->off < sizeof(struct GNUNET_MessageHeader)) ||
299 (0 != (mst->off % ALIGN_FACTOR)))
300 {
301 /* need to align or need more space */
302 mst->pos -= mst->off;
303 memmove (ibuf, &ibuf[mst->off], mst->pos);
304 mst->off = 0;
305 }
306 if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader))
307 {
308 delta =
309 GNUNET_MIN (sizeof(struct GNUNET_MessageHeader)
310 - (mst->pos - mst->off), size);
311 GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
312 mst->pos += delta;
313 buf += delta;
314 size -= delta;
315 }
316 if (mst->pos - mst->off < sizeof(struct GNUNET_MessageHeader))
317 {
318 // FIXME should I reset ??
319 // mst->off = 0;
320 // mst->pos = 0;
321 return GNUNET_OK;
322 }
323 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
324 want = ntohs (hdr->size);
325 if (want < sizeof(struct GNUNET_MessageHeader))
326 {
327 fprintf (stderr,
328 "Received invalid message from stdin\n");
329 return GNUNET_SYSERR;
330 }
331 if ((mst->curr_buf - mst->off < want) &&
332 (mst->off > 0))
333 {
334 /* need more space */
335 mst->pos -= mst->off;
336 memmove (ibuf, &ibuf[mst->off], mst->pos);
337 mst->off = 0;
338 }
339 if (want > mst->curr_buf)
340 {
341 if (mst->off != 0)
342 {
343 fprintf (stderr, "Error! We should proceeded 0 bytes\n");
344 return GNUNET_SYSERR;
345 }
346 mst->hdr = realloc (mst->hdr, want);
347 if (NULL == mst->hdr)
348 {
349 fprintf (stderr, "Failed to allocate buffer for alignment\n");
350 exit (1);
351 }
352 ibuf = (char *) mst->hdr;
353 mst->curr_buf = want;
354 }
355 hdr = (const struct GNUNET_MessageHeader *) &ibuf[mst->off];
356 if (mst->pos - mst->off < want)
357 {
358 delta = GNUNET_MIN (want - (mst->pos - mst->off), size);
359 if (mst->pos + delta > mst->curr_buf)
360 {
361 fprintf (stderr, "The size of the buffer will be exceeded!\n");
362 return GNUNET_SYSERR;
363 }
364 GNUNET_memcpy (&ibuf[mst->pos], buf, delta);
365 mst->pos += delta;
366 buf += delta;
367 size -= delta;
368 }
369 if (mst->pos - mst->off < want)
370 {
371 // FIXME should I use this?
372 // mst->off = 0;
373 // mst->pos = 0;
374 return GNUNET_OK;
375 }
376 mst->cb (mst->cb_cls, hdr);
377 mst->off += want;
378 if (mst->off == mst->pos)
379 {
380 /* reset to beginning of buffer, it's free right now! */
381 mst->off = 0;
382 mst->pos = 0;
383 }
384 }
385 if (0 != mst->pos)
386 {
387 fprintf (stderr,
388 "There should some valid bytes in the buffer on this stage\n");
389 return GNUNET_SYSERR;
390 }
391 while (size > 0)
392 {
393 if (size < sizeof(struct GNUNET_MessageHeader))
394 break;
395 offset = (unsigned long) buf;
396 need_align = (0 != offset % ALIGN_FACTOR) ? GNUNET_YES : GNUNET_NO;
397 if (GNUNET_NO == need_align)
398 {
399 /* can try to do zero-copy and process directly from original buffer */
400 hdr = (const struct GNUNET_MessageHeader *) buf;
401 want = ntohs (hdr->size);
402 if (want < sizeof(struct GNUNET_MessageHeader))
403 {
404 fprintf (stderr,
405 "Received invalid message from stdin\n");
406 // exit (1);
407 mst->off = 0;
408 return GNUNET_SYSERR;
409 }
410 if (size < want)
411 break; /* or not, buffer incomplete, so copy to private buffer... */
412 mst->cb (mst->cb_cls, hdr);
413 buf += want;
414 size -= want;
415 }
416 else
417 {
418 /* need to copy to private buffer to align;
419 * yes, we go a bit more spaghetti than usual here */
420 goto do_align;
421 }
422 }
423 if (size > 0)
424 {
425 if (size + mst->pos > mst->curr_buf)
426 {
427 mst->hdr = realloc (mst->hdr, size + mst->pos);
428 if (NULL == mst->hdr)
429 {
430 fprintf (stderr, "Failed to allocate buffer for alignment\n");
431 exit (1);
432 }
433 ibuf = (char *) mst->hdr;
434 mst->curr_buf = size + mst->pos;
435 }
436 if (mst->pos + size > mst->curr_buf)
437 {
438 fprintf (stderr,
439 "Assertion failed\n");
440 exit (1);
441 }
442 GNUNET_memcpy (&ibuf[mst->pos], buf, size);
443 mst->pos += size;
444 }
445 return ret;
446}
447
448
449/**
450 * Destroys a tokenizer.
451 *
452 * @param mst tokenizer to destroy
453 */
454static void
455mst_destroy (struct MessageStreamTokenizer *mst)
456{
457 free (mst->hdr);
458 free (mst);
459}
460
461
462/**
463 * Calculate crc32, the start of the calculation
464 *
465 * @param buf buffer to calc the crc
466 * @param len len of the buffer
467 * @return crc sum
468 */
469static unsigned long
470calc_crc_osdep (const unsigned char *buf, size_t len)
471{
472 static const unsigned long int crc_tbl_osdep[256] = {
473 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F,
474 0xE963A535, 0x9E6495A3,
475 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD,
476 0xE7B82D07, 0x90BF1D91,
477 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB,
478 0xF4D4B551, 0x83D385C7,
479 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9,
480 0xFA0F3D63, 0x8D080DF5,
481 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447,
482 0xD20D85FD, 0xA50AB56B,
483 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75,
484 0xDCD60DCF, 0xABD13D59,
485 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423,
486 0xCFBA9599, 0xB8BDA50F,
487 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
488 0xC1611DAB, 0xB6662D3D,
489 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F,
490 0x9FBFE4A5, 0xE8B8D433,
491 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D,
492 0x91646C97, 0xE6635C01,
493 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B,
494 0x8208F4C1, 0xF50FC457,
495 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49,
496 0x8CD37CF3, 0xFBD44C65,
497 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7,
498 0xA4D1C46D, 0xD3D6F4FB,
499 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5,
500 0xAA0A4C5F, 0xDD0D7CC9,
501 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3,
502 0xB966D409, 0xCE61E49F,
503 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81,
504 0xB7BD5C3B, 0xC0BA6CAD,
505 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF,
506 0x04DB2615, 0x73DC1683,
507 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D,
508 0x0A00AE27, 0x7D079EB1,
509 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
510 0x196C3671, 0x6E6B06E7,
511 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9,
512 0x17B7BE43, 0x60B08ED5,
513 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767,
514 0x3FB506DD, 0x48B2364B,
515 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55,
516 0x316E8EEF, 0x4669BE79,
517 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703,
518 0x220216B9, 0x5505262F,
519 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31,
520 0x2CD99E8B, 0x5BDEAE1D,
521 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F,
522 0x72076785, 0x05005713,
523 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D,
524 0x7CDCEFB7, 0x0BDBDF21,
525 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B,
526 0x6FB077E1, 0x18B74777,
527 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69,
528 0x616BFFD3, 0x166CCF45,
529 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7,
530 0x4969474D, 0x3E6E77DB,
531 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
532 0x47B2CF7F, 0x30B5FFE9,
533 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693,
534 0x54DE5729, 0x23D967BF,
535 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1,
536 0x5A05DF1B, 0x2D02EF8D
537 };
538
539 unsigned long crc = 0xFFFFFFFF;
540
541 for (; len > 0; len--, buf++)
542 crc = crc_tbl_osdep[(crc ^ *buf) & 0xFF] ^ (crc >> 8);
543 return(~crc);
544}
545
546
547/**
548 * Calculate and check crc of the bluetooth packet
549 *
550 * @param buf buffer of the packet, with len + 4 bytes of data,
551 * the last 4 bytes being the checksum
552 * @param len length of the payload in data
553 * @return 0 on success (checksum matches), 1 on error
554 */
555static int
556check_crc_buf_osdep (const unsigned char *buf, size_t len)
557{
558 unsigned long crc;
559
560 crc = calc_crc_osdep (buf, len);
561 buf += len;
562 if ((((crc) & 0xFF) == buf[0]) && (((crc >> 8) & 0xFF) == buf[1]) &&
563 ( ((crc >> 16) & 0xFF) == buf[2]) && ( ((crc >> 24) & 0xFF) == buf[3]) )
564 return 0;
565 return 1;
566}
567
568
569/* ************** end of clone ***************** */
570#ifdef __linux__
571/**
572 * Function for assigning a port number
573 *
574 * @param socket the socket used to bind
575 * @param addr pointer to the rfcomm address
576 * @return 0 on success
577 */
578static int
579bind_socket (int socket, struct sockaddr_rc *addr)
580{
581 int port, status;
582
583 /* Bind every possible port (from 0 to 30) and stop when binding doesn't fail */
584 // FIXME : it should start from port 1, but on my computer it doesn't work :)
585 for (port = 3; port <= 30; port++)
586 {
587 addr->rc_channel = port;
588 status = bind (socket, (struct sockaddr *) addr, sizeof(struct
589 sockaddr_rc));
590 if (status == 0)
591 return 0;
592 }
593
594 return -1;
595}
596
597
598#endif
599
600/**
601 * Function used for creating the service record and registering it.
602 *
603 * @param dev pointer to the device struct
604 * @param rc_channel the rfcomm channel
605 * @return 0 on success
606 */
607static int
608register_service (struct HardwareInfos *dev, int rc_channel)
609{
610 /**
611 * 1. initializations
612 * 2. set the service ID, class, profile information
613 * 3. make the service record publicly browsable
614 * 4. register the RFCOMM channel
615 * 5. set the name, provider and description
616 * 6. register the service record to the local SDP server
617 * 7. cleanup
618 */uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
619 dev->pl_mac.mac[5], dev->pl_mac.mac[4],
620 dev->pl_mac.mac[3],
621 dev->pl_mac.mac[2], dev->pl_mac.mac[1],
622 dev->pl_mac.mac[0] };
623 const char *service_dsc = "Bluetooth plugin services";
624 const char *service_prov = "GNUnet provider";
625 uuid_t root_uuid, rfcomm_uuid, svc_uuid;
626 sdp_list_t *root_list = 0, *rfcomm_list = 0, *proto_list = 0,
627 *access_proto_list = 0, *svc_list = 0;
628 sdp_record_t *record = 0;
629 sdp_data_t *channel = 0;
630
631 record = sdp_record_alloc ();
632
633 /* Set the general service ID */
634 sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
635 svc_list = sdp_list_append (0, &svc_uuid);
636 sdp_set_service_classes (record, svc_list);
637 sdp_set_service_id (record, svc_uuid);
638
639 /* Make the service record publicly browsable */
640 sdp_uuid16_create (&root_uuid, PUBLIC_BROWSE_GROUP);
641 root_list = sdp_list_append (0, &root_uuid);
642 sdp_set_browse_groups (record, root_list);
643
644 /* Register the RFCOMM channel */
645 sdp_uuid16_create (&rfcomm_uuid, RFCOMM_UUID);
646 channel = sdp_data_alloc (SDP_UINT8, &rc_channel);
647 rfcomm_list = sdp_list_append (0, &rfcomm_uuid);
648 sdp_list_append (rfcomm_list, channel);
649 proto_list = sdp_list_append (0, rfcomm_list);
650
651 /* Set protocol information */
652 access_proto_list = sdp_list_append (0, proto_list);
653 sdp_set_access_protos (record, access_proto_list);
654
655 /* Set the name, provider, and description */
656 sdp_set_info_attr (record, dev->iface, service_prov, service_dsc);
657
658 /* Connect to the local SDP server */
659 dev->session = sdp_connect (BDADDR_ANY, BDADDR_LOCAL, SDP_RETRY_IF_BUSY);
660
661 if (! dev->session)
662 {
663 fprintf (stderr,
664 "Failed to connect to the SDP server on interface `%.*s': %s\n",
665 IFNAMSIZ, dev->iface, strerror (errno));
666 // FIXME exit?
667 return 1;
668 }
669
670 /* Register the service record */
671 if (sdp_record_register (dev->session, record, 0) < 0)
672 {
673 fprintf (stderr,
674 "Failed to register a service record on interface `%.*s': %s\n",
675 IFNAMSIZ, dev->iface, strerror (errno));
676 // FIXME exit?
677 return 1;
678 }
679
680 /* Cleanup */
681 sdp_data_free (channel);
682 sdp_list_free (root_list, 0);
683 sdp_list_free (rfcomm_list, 0);
684 sdp_list_free (proto_list, 0);
685 sdp_list_free (access_proto_list, 0);
686 sdp_list_free (svc_list, 0);
687 sdp_record_free (record);
688
689 return 0;
690}
691
692
693/**
694 * Function used for searching and browsing for a service. This will return the
695 * port number on which the service is running.
696 *
697 * @param dev pointer to the device struct
698 * @param dest target address
699 * @return channel
700 */
701static int
702get_channel (struct HardwareInfos *dev, bdaddr_t dest)
703{
704 /**
705 * 1. detect all nearby devices
706 * 2. for each device:
707 * 2.1. connect to the SDP server running
708 * 2.2. get a list of service records with the specific UUID
709 * 2.3. for each service record get a list of the protocol sequences and get
710 * the port number
711 */uint8_t svc_uuid_int[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
712 dest.b[5], dest.b[4], dest.b[3],
713 dest.b[2], dest.b[1], dest.b[0] };
714 sdp_session_t *session = 0;
715 sdp_list_t *search_list = 0, *attrid_list = 0, *response_list = 0, *it = 0;
716 uuid_t svc_uuid;
717 uint32_t range = 0x0000ffff;
718 int channel = -1;
719
720 /* Connect to the local SDP server */
721 session = sdp_connect (BDADDR_ANY, &dest, 0);
722 if (! session)
723 {
724 fprintf (stderr,
725 "Failed to connect to the SDP server on interface `%.*s': %s\n",
726 IFNAMSIZ, dev->iface, strerror (errno));
727 return -1;
728 }
729
730 sdp_uuid128_create (&svc_uuid, &svc_uuid_int);
731 search_list = sdp_list_append (0, &svc_uuid);
732 attrid_list = sdp_list_append (0, &range);
733
734 if (sdp_service_search_attr_req (session, search_list,
735 SDP_ATTR_REQ_RANGE, attrid_list,
736 &response_list) == 0)
737 {
738 for (it = response_list; it; it = it->next)
739 {
740 sdp_record_t *record = (sdp_record_t *) it->data;
741 sdp_list_t *proto_list = 0;
742 if (sdp_get_access_protos (record, &proto_list) == 0)
743 {
744 channel = sdp_get_proto_port (proto_list, RFCOMM_UUID);
745 sdp_list_free (proto_list, 0);
746 }
747 sdp_record_free (record);
748 }
749 }
750
751 sdp_list_free (search_list, 0);
752 sdp_list_free (attrid_list, 0);
753 sdp_list_free (response_list, 0);
754
755 sdp_close (session);
756
757 if (-1 == channel)
758 fprintf (stderr,
759 "Failed to find the listening channel for interface `%.*s': %s\n",
760 IFNAMSIZ,
761 dev->iface,
762 strerror (errno));
763
764 return channel;
765}
766
767
768/**
769 * Read from the socket and put the result into the buffer for transmission to 'stdout'.
770 *
771 * @param sock file descriptor for reading
772 * @param buf buffer to read to; first bytes will be the 'struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame',
773 * followed by the actual payload
774 * @param buf_size size of the buffer
775 * @param ri where to write radiotap_rx info
776 * @return number of bytes written to 'buf'
777 */
778static ssize_t
779read_from_the_socket (void *sock,
780 unsigned char *buf, size_t buf_size,
781 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *ri)
782{
783 unsigned char tmpbuf[buf_size];
784 ssize_t count;
785 count = read (*((int *) sock), tmpbuf, buf_size);
786
787 if (0 > count)
788 {
789 if (EAGAIN == errno)
790 return 0;
791
792 fprintf (stderr, "Failed to read from the HCI socket: %s\n", strerror (
793 errno));
794
795 return -1;
796 }
797
798 #ifdef __linux__
799 /* Get the channel used */
800 int len;
801 struct sockaddr_rc rc_addr = { 0 };
802
803 memset (&rc_addr, 0, sizeof(rc_addr));
804 len = sizeof(rc_addr);
805 if (0 > getsockname (*((int *) sock), (struct sockaddr *) &rc_addr,
806 (socklen_t *) &len))
807 {
808 fprintf (stderr, "getsockname() call failed : %s\n", strerror (errno));
809 return -1;
810 }
811
812 memset (ri, 0, sizeof(*ri));
813 ri->ri_channel = rc_addr.rc_channel;
814 #endif
815
816 /* Detect CRC32 at the end */
817 if (0 == check_crc_buf_osdep (tmpbuf, count - sizeof(uint32_t)))
818 {
819 count -= sizeof(uint32_t);
820 }
821
822 GNUNET_memcpy (buf, tmpbuf, count);
823
824 return count;
825}
826
827
828/**
829 * Open the bluetooth interface for reading/writing
830 *
831 * @param dev pointer to the device struct
832 * @return 0 on success, non-zero on error
833 */
834static int
835open_device (struct HardwareInfos *dev)
836{
837 int i, dev_id = -1, fd_hci;
838 struct
839 {
840 struct hci_dev_list_req list;
841 struct hci_dev_req dev[HCI_MAX_DEV];
842 } request; // used for detecting the local devices
843 struct sockaddr_rc rc_addr = { 0 }; // used for binding
844
845 /* Initialize the neighbour structure */
846 neighbours.dev_id = -1;
847 for (i = 0; i < MAX_PORTS; i++)
848 neighbours.fds[i] = -1;
849
850 /* Open a HCI socket */
851 fd_hci = socket (AF_BLUETOOTH, SOCK_RAW, BTPROTO_HCI);
852
853 if (fd_hci < 0)
854 {
855 fprintf (stderr,
856 "Failed to create HCI socket: %s\n",
857 strerror (errno));
858 return -1;
859 }
860
861 memset (&request, 0, sizeof(request));
862 request.list.dev_num = HCI_MAX_DEV;
863
864 if (ioctl (fd_hci, HCIGETDEVLIST, (void *) &request) < 0)
865 {
866 fprintf (stderr,
867 "ioctl(HCIGETDEVLIST) on interface `%.*s' failed: %s\n",
868 IFNAMSIZ,
869 dev->iface,
870 strerror (errno));
871 (void) close (fd_hci);
872 return 1;
873 }
874
875 /* Search for a device with dev->iface name */
876 for (i = 0; i < request.list.dev_num; i++)
877 {
878 struct hci_dev_info dev_info;
879
880 memset (&dev_info, 0, sizeof(struct hci_dev_info));
881 dev_info.dev_id = request.dev[i].dev_id;
882 strncpy (dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE);
883
884 if (ioctl (fd_hci, HCIGETDEVINFO, (void *) &dev_info))
885 {
886 fprintf (stderr,
887 "ioctl(HCIGETDEVINFO) on interface `%.*s' failed: %s\n",
888 IFNAMSIZ,
889 dev->iface,
890 strerror (errno));
891 (void) close (fd_hci);
892 return 1;
893 }
894
895 if (strncmp (dev_info.name, dev->iface, BLUEZ_DEVNAME_SIZE) == 0)
896 {
897 dev_id = dev_info.dev_id; // the device was found
898 /**
899 * Copy the MAC address to the device structure
900 */
901 GNUNET_memcpy (&dev->pl_mac, &dev_info.bdaddr, sizeof(bdaddr_t));
902
903 /* Check if the interface is up */
904 if (hci_test_bit (HCI_UP, (void *) &dev_info.flags) == 0)
905 {
906 /* Bring the interface up */
907 if (ioctl (fd_hci, HCIDEVUP, dev_info.dev_id))
908 {
909 fprintf (stderr,
910 "ioctl(HCIDEVUP) on interface `%.*s' failed: %s\n",
911 IFNAMSIZ,
912 dev->iface,
913 strerror (errno));
914 (void) close (fd_hci);
915 return 1;
916 }
917 }
918
919 /* Check if the device is discoverable */
920 if ((hci_test_bit (HCI_PSCAN, (void *) &dev_info.flags) == 0) ||
921 (hci_test_bit (HCI_ISCAN, (void *) &dev_info.flags) == 0) )
922 {
923 /* Set interface Page Scan and Inqury Scan ON */
924 struct hci_dev_req dev_req;
925
926 memset (&dev_req, 0, sizeof(dev_req));
927 dev_req.dev_id = dev_info.dev_id;
928 dev_req.dev_opt = SCAN_PAGE | SCAN_INQUIRY;
929
930 if (ioctl (fd_hci, HCISETSCAN, (unsigned long) &dev_req))
931 {
932 fprintf (stderr,
933 "ioctl(HCISETSCAN) on interface `%.*s' failed: %s\n",
934 IFNAMSIZ,
935 dev->iface,
936 strerror (errno));
937 (void) close (fd_hci);
938 return 1;
939 }
940 }
941 break;
942 }
943 }
944
945 /* Check if the interface was not found */
946 if (-1 == dev_id)
947 {
948 fprintf (stderr,
949 "The interface %s was not found\n",
950 dev->iface);
951 (void) close (fd_hci);
952 return 1;
953 }
954
955 /* Close the hci socket */
956 (void) close (fd_hci);
957
958
959 /* Bind the rfcomm socket to the interface */
960 memset (&rc_addr, 0, sizeof(rc_addr));
961 rc_addr.rc_family = AF_BLUETOOTH;
962 rc_addr.rc_bdaddr = *BDADDR_ANY;
963
964 if (bind_socket (dev->fd_rfcomm, &rc_addr) != 0)
965 {
966 fprintf (stderr,
967 "Failed to bind interface `%.*s': %s\n",
968 IFNAMSIZ,
969 dev->iface,
970 strerror (errno));
971 return 1;
972 }
973
974 /* Register a SDP service */
975 if (register_service (dev, rc_addr.rc_channel) != 0)
976 {
977 fprintf (stderr,
978 "Failed to register a service on interface `%.*s': %s\n",
979 IFNAMSIZ,
980 dev->iface, strerror (errno));
981 return 1;
982 }
983
984 /* Switch socket in listening mode */
985 if (listen (dev->fd_rfcomm, 5) == -1) // FIXME: probably we need a bigger number
986 {
987 fprintf (stderr, "Failed to listen on socket for interface `%.*s': %s\n",
988 IFNAMSIZ,
989 dev->iface, strerror (errno));
990 return 1;
991 }
992
993 return 0;
994}
995
996
997/**
998 * Set the header to sane values to make attacks more difficult
999 *
1000 * @param taIeeeHeader pointer to the header of the packet
1001 * @param dev pointer to the Hardware_Infos struct
1002 *
1003 **** copy from gnunet-helper-transport-wlan.c ****
1004 */
1005static void
1006mac_set (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1007 const struct HardwareInfos *dev)
1008{
1009 taIeeeHeader->frame_control = htons (IEEE80211_FC0_TYPE_DATA);
1010 taIeeeHeader->addr3 = mac_bssid_gnunet;
1011 taIeeeHeader->addr2 = dev->pl_mac;
1012}
1013
1014
1015#ifdef __linux__
1016/**
1017 * Test if the given interface name really corresponds to a bluetooth
1018 * device.
1019 *
1020 * @param iface name of the interface
1021 * @return 0 on success, 1 on error
1022 **** similar with the one from gnunet-helper-transport-wlan.c ****
1023 */
1024static int
1025test_bluetooth_interface (const char *iface)
1026{
1027 char strbuf[512];
1028 struct stat sbuf;
1029 int ret;
1030
1031 ret = snprintf (strbuf, sizeof(strbuf),
1032 "/sys/class/bluetooth/%s/subsystem",
1033 iface);
1034 if ((ret < 0) || (ret >= sizeof(strbuf)) || (0 != stat (strbuf, &sbuf)))
1035 {
1036 fprintf (stderr,
1037 "Did not find 802.15.1 interface `%s'. Exiting.\n",
1038 iface);
1039 exit (1);
1040 }
1041 return 0;
1042}
1043
1044
1045#endif
1046
1047/**
1048 * Test incoming packets mac for being our own.
1049 *
1050 * @param taIeeeHeader buffer of the packet
1051 * @param dev the Hardware_Infos struct
1052 * @return 0 if mac belongs to us, 1 if mac is for another target
1053 *
1054 **** same as the one from gnunet-helper-transport-wlan.c ****
1055 */
1056static int
1057mac_test (const struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *taIeeeHeader,
1058 const struct HardwareInfos *dev)
1059{
1060 static struct GNUNET_TRANSPORT_WLAN_MacAddress all_zeros;
1061
1062 if ((0 == memcmp (&taIeeeHeader->addr3, &all_zeros, MAC_ADDR_SIZE)) ||
1063 (0 == memcmp (&taIeeeHeader->addr1, &all_zeros, MAC_ADDR_SIZE)))
1064 return 0; /* some drivers set no Macs, then assume it is all for us! */
1065
1066 if (0 != memcmp (&taIeeeHeader->addr3, &mac_bssid_gnunet, MAC_ADDR_SIZE))
1067 return 1; /* not a GNUnet ad-hoc package */
1068 if ((0 == memcmp (&taIeeeHeader->addr1, &dev->pl_mac, MAC_ADDR_SIZE)) ||
1069 (0 == memcmp (&taIeeeHeader->addr1, &bc_all_mac, MAC_ADDR_SIZE)))
1070 return 0; /* for us, or broadcast */
1071 return 1; /* not for us */
1072}
1073
1074
1075/**
1076 * Process data from the stdin. Takes the message, forces the sender MAC to be correct
1077 * and puts it into our buffer for transmission to the receiver.
1078 *
1079 * @param cls pointer to the device struct ('struct HardwareInfos*')
1080 * @param hdr pointer to the start of the packet
1081 *
1082 **** same as the one from gnunet-helper-transport-wlan.c ****
1083 */
1084static void
1085stdin_send_hw (void *cls, const struct GNUNET_MessageHeader *hdr)
1086{
1087 struct HardwareInfos *dev = cls;
1088 const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *header;
1089 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *blueheader;
1090 size_t sendsize;
1091
1092 sendsize = ntohs (hdr->size);
1093 if ((sendsize <
1094 sizeof(struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)) ||
1095 (GNUNET_MESSAGE_TYPE_WLAN_DATA_TO_HELPER != ntohs (hdr->type)))
1096 {
1097 fprintf (stderr, "Received malformed message\n");
1098 exit (1);
1099 }
1100 sendsize -= (sizeof(struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage)
1101 - sizeof(struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame));
1102 if (MAXLINE < sendsize)
1103 {
1104 fprintf (stderr, "Packet too big for buffer\n");
1105 exit (1);
1106 }
1107 header = (const struct GNUNET_TRANSPORT_WLAN_RadiotapSendMessage *) hdr;
1108 GNUNET_memcpy (&write_pout.buf, &header->frame, sendsize);
1109 blueheader = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) &write_pout.buf;
1110
1111 /* payload contains MAC address, but we don't trust it, so we'll
1112 * overwrite it with OUR MAC address to prevent mischief */
1113 mac_set (blueheader, dev);
1114 GNUNET_memcpy (&blueheader->addr1, &header->frame.addr1,
1115 sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress));
1116 write_pout.size = sendsize;
1117}
1118
1119
1120#ifdef __linux__
1121/**
1122 * Broadcast a HELLO message for peer discovery
1123 *
1124 * @param dev pointer to the device struct
1125 * @param dev pointer to the socket which was added to the set
1126 * @return 0 on success
1127 */
1128static int
1129send_broadcast (struct HardwareInfos *dev, int *sendsocket)
1130{
1131 int new_device = 0;
1132 int loops = 0;
1133
1134search_for_devices:
1135 if (((neighbours.size == neighbours.pos) && (new_device == 1)) ||
1136 (neighbours.size == 0) )
1137 {
1138inquiry_devices: // skip the conditions and force a inquiry for new devices
1139 {
1140 /**
1141 * It means that I sent HELLO messages to all the devices from the list and I should search
1142 * for new ones or that this is the first time when I do a search.
1143 */
1144 inquiry_info *devices = NULL;
1145 int i, responses, max_responses = MAX_PORTS;
1146
1147 /* sanity checks */
1148 if (neighbours.size >= MAX_PORTS)
1149 {
1150 fprintf (stderr,
1151 "%.*s reached the top limit for the discovarable devices\n",
1152 IFNAMSIZ,
1153 dev->iface);
1154 return 2;
1155 }
1156
1157 /* Get the device id */
1158 if (neighbours.dev_id == -1)
1159 {
1160 char addr[19] = { 0 }; // the device MAC address
1161
1162 ba2str ((bdaddr_t *) &dev->pl_mac, addr);
1163 neighbours.dev_id = hci_devid (addr);
1164 if (neighbours.dev_id < 0)
1165 {
1166 fprintf (stderr,
1167 "Failed to get the device id for interface %.*s : %s\n",
1168 IFNAMSIZ,
1169 dev->iface, strerror (errno));
1170 return 1;
1171 }
1172 }
1173
1174 devices = malloc (max_responses * sizeof(inquiry_info));
1175 if (devices == NULL)
1176 {
1177 fprintf (stderr,
1178 "Failed to allocate memory for inquiry info list on interface %.*s\n",
1179 IFNAMSIZ,
1180 dev->iface);
1181 return 1;
1182 }
1183
1184 responses = hci_inquiry (neighbours.dev_id, 8, max_responses, NULL,
1185 &devices, IREQ_CACHE_FLUSH);
1186 if (responses < 0)
1187 {
1188 fprintf (stderr, "Failed to inquiry on interface %.*s\n", IFNAMSIZ,
1189 dev->iface);
1190 return 1;
1191 }
1192
1193 fprintf (stderr, "LOG : Found %d devices\n", responses); // FIXME delete it after debugging stage
1194
1195 if (responses == 0)
1196 {
1197 fprintf (stderr, "LOG : No devices discoverable\n");
1198 return 1;
1199 }
1200
1201 for (i = 0; i < responses; i++)
1202 {
1203 int j;
1204 int found = 0;
1205
1206 /* sanity check */
1207 if (i >= MAX_PORTS)
1208 {
1209 fprintf (stderr,
1210 "%.*s reached the top limit for the discoverable devices (after inquiry)\n",
1211 IFNAMSIZ,
1212 dev->iface);
1213 return 2;
1214 }
1215
1216 /* Search if the address already exists on the list */
1217 for (j = 0; j < neighbours.size; j++)
1218 {
1219 if (memcmp (&(devices + i)->bdaddr, &(neighbours.devices[j]),
1220 sizeof(bdaddr_t)) == 0)
1221 {
1222 found = 1;
1223 fprintf (stderr, "LOG : the device already exists on the list\n"); // FIXME debugging message
1224 break;
1225 }
1226 }
1227
1228 if (found == 0)
1229 {
1230 char addr[19] = { 0 };
1231
1232 ba2str (&(devices + i)->bdaddr, addr);
1233 fprintf (stderr, "LOG : %s was added to the list\n", addr); // FIXME debugging message
1234 GNUNET_memcpy (&(neighbours.devices[neighbours.size++]), &(devices
1235 + i)->
1236 bdaddr, sizeof(bdaddr_t));
1237 }
1238 }
1239
1240 free (devices);
1241 }
1242 }
1243
1244 int connection_successful = 0;
1245 struct sockaddr_rc addr_rc = { 0 };
1246 int errno_copy = 0;
1247 addr_rc.rc_family = AF_BLUETOOTH;
1248
1249 /* Try to connect to a new device from the list */
1250 while (neighbours.pos < neighbours.size)
1251 {
1252 /* Check if we are already connected to this device */
1253 if (neighbours.fds[neighbours.pos] == -1)
1254 {
1255 memset (&addr_rc.rc_bdaddr, 0, sizeof(addr_rc.rc_bdaddr));
1256 GNUNET_memcpy (&addr_rc.rc_bdaddr, &(neighbours.devices[neighbours.pos]),
1257 sizeof(addr_rc.rc_bdaddr));
1258
1259 addr_rc.rc_channel = get_channel (dev, addr_rc.rc_bdaddr);
1260
1261 *sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1262 if ((-1 < *sendsocket) &&
1263 (0 == connect (*sendsocket,
1264 (struct sockaddr *) &addr_rc,
1265 sizeof(addr_rc))))
1266 {
1267 neighbours.fds[neighbours.pos++] = *sendsocket;
1268 connection_successful = 1;
1269 char addr[19] = { 0 };
1270 ba2str (&(neighbours.devices[neighbours.pos - 1]), addr);
1271 fprintf (stderr, "LOG : Connected to %s\n", addr);
1272 break;
1273 }
1274 else
1275 {
1276 char addr[19] = { 0 };
1277 errno_copy = errno; // Save a copy for later
1278
1279 if (-1 != *sendsocket)
1280 {
1281 (void) close (*sendsocket);
1282 *sendsocket = -1;
1283 }
1284 ba2str (&(neighbours.devices[neighbours.pos]), addr);
1285 fprintf (stderr,
1286 "LOG : Couldn't connect on device %s, error : %s\n",
1287 addr,
1288 strerror (errno));
1289 if (errno != ECONNREFUSED) // FIXME be sure that this works
1290 {
1291 fprintf (stderr, "LOG : Removes %d device from the list\n",
1292 neighbours.pos);
1293 /* Remove the device from the list */
1294 GNUNET_memcpy (&neighbours.devices[neighbours.pos],
1295 &neighbours.devices[neighbours.size - 1],
1296 sizeof(bdaddr_t));
1297 memset (&neighbours.devices[neighbours.size - 1], 0,
1298 sizeof(bdaddr_t));
1299 neighbours.fds[neighbours.pos] = neighbours.fds[neighbours.size - 1];
1300 neighbours.fds[neighbours.size - 1] = -1;
1301 neighbours.size -= 1;
1302 }
1303
1304 neighbours.pos += 1;
1305
1306 if (neighbours.pos >= neighbours.size)
1307 neighbours.pos = 0;
1308
1309 loops += 1;
1310
1311 if (loops == MAX_LOOPS) // don't get stuck trying to connect to one device
1312 return 1;
1313 }
1314 }
1315 else
1316 {
1317 fprintf (stderr, "LOG : Search for a new device\n"); // FIXME debugging message
1318 neighbours.pos += 1;
1319 }
1320 }
1321
1322 /* Cycle on the list */
1323 if (neighbours.pos == neighbours.size)
1324 {
1325 neighbours.pos = 0;
1326 searching_devices_count += 1;
1327
1328 if (searching_devices_count == MAX_LOOPS)
1329 {
1330 fprintf (stderr, "LOG : Force to inquiry for new devices\n");
1331 searching_devices_count = 0;
1332 goto inquiry_devices;
1333 }
1334 }
1335 /* If a new device wasn't found, search an old one */
1336 if (connection_successful == 0)
1337 {
1338 int loop_check = neighbours.pos;
1339 while (neighbours.fds[neighbours.pos] == -1)
1340 {
1341 if (neighbours.pos == neighbours.size)
1342 neighbours.pos = 0;
1343
1344 if (neighbours.pos == loop_check)
1345 {
1346 if (errno_copy == ECONNREFUSED)
1347 {
1348 fprintf (stderr, "LOG : No device found. Go back and search again\n"); // FIXME debugging message
1349 new_device = 1;
1350 loops += 1;
1351 goto search_for_devices;
1352 }
1353 else
1354 {
1355 return 1; // Skip the broadcast message
1356 }
1357 }
1358
1359 neighbours.pos += 1;
1360 }
1361
1362 *sendsocket = neighbours.fds[neighbours.pos++];
1363 }
1364
1365 return 0;
1366}
1367
1368
1369#endif
1370
1371/**
1372 * Main function of the helper. This code accesses a bluetooth interface
1373 * forwards traffic in both directions between the bluetooth interface and
1374 * stdin/stdout of this process. Error messages are written to stderr.
1375 *
1376 * @param argc number of arguments, must be 2
1377 * @param argv arguments only argument is the name of the interface (e.g. 'hci0')
1378 * @return 0 on success (never happens, as we don't return unless aborted), 1 on error
1379 *
1380 **** similar to gnunet-helper-transport-wlan.c ****
1381 */
1382int
1383main (int argc, char *argv[])
1384{
1385#ifdef __linux__
1386 struct HardwareInfos dev;
1387 char readbuf[MAXLINE];
1388 int maxfd;
1389 fd_set rfds;
1390 fd_set wfds;
1391 int stdin_open;
1392 struct MessageStreamTokenizer *stdin_mst;
1393 int raw_eno, i;
1394 int crt_rfds = 0, rfds_list[MAX_PORTS];
1395 int broadcast, sendsocket;
1396
1397 /* Assert privs so we can modify the firewall rules! */
1398 {
1399#ifdef HAVE_SETRESUID
1400 uid_t uid = getuid ();
1401
1402 if (0 != setresuid (uid, 0, 0))
1403 {
1404 fprintf (stderr,
1405 "Failed to setresuid to root: %s\n",
1406 strerror (errno));
1407 return 254;
1408 }
1409#else
1410 if (0 != seteuid (0))
1411 {
1412 fprintf (stderr,
1413 "Failed to seteuid back to root: %s\n", strerror (errno));
1414 return 254;
1415 }
1416#endif
1417 }
1418
1419 /* Make use of SGID capabilities on POSIX */
1420 memset (&dev, 0, sizeof(dev));
1421 dev.fd_rfcomm = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1422 raw_eno = errno; /* remember for later */
1423
1424 /* Now that we've dropped root rights, we can do error checking */
1425 if (2 != argc)
1426 {
1427 fprintf (stderr,
1428 "You must specify the name of the interface as the first \
1429 and only argument to this program.\n");
1430 if (-1 != dev.fd_rfcomm)
1431 (void) close (dev.fd_rfcomm);
1432 return 1;
1433 }
1434
1435 if (-1 == dev.fd_rfcomm)
1436 {
1437 fprintf (stderr, "Failed to create a RFCOMM socket: %s\n", strerror (
1438 raw_eno));
1439 return 1;
1440 }
1441 if (dev.fd_rfcomm >= FD_SETSIZE)
1442 {
1443 fprintf (stderr, "File descriptor too large for select (%d > %d)\n",
1444 dev.fd_rfcomm, FD_SETSIZE);
1445 (void) close (dev.fd_rfcomm);
1446 return 1;
1447 }
1448 if (0 != test_bluetooth_interface (argv[1]))
1449 {
1450 (void) close (dev.fd_rfcomm);
1451 return 1;
1452 }
1453 strncpy (dev.iface, argv[1], IFNAMSIZ);
1454 if (0 != open_device (&dev))
1455 {
1456 (void) close (dev.fd_rfcomm);
1457 return 1;
1458 }
1459
1460 /* Drop privs */
1461 {
1462 uid_t uid = getuid ();
1463 #ifdef HAVE_SETRESUID
1464 if (0 != setresuid (uid, uid, uid))
1465 {
1466 fprintf (stderr, "Failed to setresuid: %s\n", strerror (errno));
1467 if (-1 != dev.fd_rfcomm)
1468 (void) close (dev.fd_rfcomm);
1469 return 1;
1470 }
1471 #else
1472 if (0 != (setuid (uid) | seteuid (uid)))
1473 {
1474 fprintf (stderr, "Failed to setuid: %s\n", strerror (errno));
1475 if (-1 != dev.fd_rfcomm)
1476 (void) close (dev.fd_rfcomm);
1477 return 1;
1478 }
1479 #endif
1480 }
1481
1482 /* Send MAC address of the bluetooth interface to STDOUT first */
1483 {
1484 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
1485
1486 macmsg.hdr.size = htons (sizeof(macmsg));
1487 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
1488 GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof(struct
1489 GNUNET_TRANSPORT_WLAN_MacAddress));
1490 GNUNET_memcpy (write_std.buf, &macmsg, sizeof(macmsg));
1491 write_std.size = sizeof(macmsg);
1492 }
1493
1494
1495 stdin_mst = mst_create (&stdin_send_hw, &dev);
1496 stdin_open = 1;
1497
1498 /**
1499 * TODO : I should make the time out of a mac endpoint smaller and check if the rate
1500 * from get_wlan_header (plugin_transport_bluetooth.c) is correct.
1501 */
1502 while (1)
1503 {
1504 maxfd = -1;
1505 broadcast = 0;
1506 sendsocket = -1;
1507
1508 FD_ZERO (&rfds);
1509 if ((0 == write_pout.size) && (1 == stdin_open))
1510 {
1511 FD_SET (STDIN_FILENO, &rfds);
1512 maxfd = MAX (maxfd, STDIN_FILENO);
1513 }
1514 if (0 == write_std.size)
1515 {
1516 FD_SET (dev.fd_rfcomm, &rfds);
1517 maxfd = MAX (maxfd, dev.fd_rfcomm);
1518 }
1519
1520 for (i = 0; i < crt_rfds; i++) // it can receive messages from multiple devices
1521 {
1522 FD_SET (rfds_list[i], &rfds);
1523 maxfd = MAX (maxfd, rfds_list[i]);
1524 }
1525 FD_ZERO (&wfds);
1526 if (0 < write_std.size)
1527 {
1528 FD_SET (STDOUT_FILENO, &wfds);
1529 maxfd = MAX (maxfd, STDOUT_FILENO);
1530 }
1531 if (0 < write_pout.size) // it can send messages only to one device per loop
1532 {
1533 struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *frame;
1534 /* Get the destination address */
1535 frame = (struct GNUNET_TRANSPORT_WLAN_Ieee80211Frame *) write_pout.buf;
1536
1537 if (memcmp (&frame->addr1, &dev.pl_mac,
1538 sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1539 {
1540 broadcast = 1;
1541 memset (&write_pout, 0, sizeof(write_pout)); // clear the buffer
1542 }
1543 else if (memcmp (&frame->addr1, &broadcast_address,
1544 sizeof(struct GNUNET_TRANSPORT_WLAN_MacAddress)) == 0)
1545 {
1546 fprintf (stderr, "LOG : %s has a broadcast message (pos %d, size %d)\n",
1547 dev.iface, neighbours.pos, neighbours.size); // FIXME: debugging message
1548
1549 if (send_broadcast (&dev, &sendsocket) != 0) // if the searching wasn't successful don't get stuck on the select stage
1550 {
1551 broadcast = 1;
1552 memset (&write_pout, 0, sizeof(write_pout)); // remove the message
1553 fprintf (stderr,
1554 "LOG : Skipping the broadcast message (pos %d, size %d)\n",
1555 neighbours.pos, neighbours.size);
1556 }
1557 else
1558 {
1559 FD_SET (sendsocket, &wfds);
1560 maxfd = MAX (maxfd, sendsocket);
1561 }
1562 }
1563 else
1564 {
1565 int found = 0;
1566 int pos = 0;
1567 /* Search if the address already exists on the list */
1568 for (i = 0; i < neighbours.size; i++)
1569 {
1570 if (memcmp (&frame->addr1, &(neighbours.devices[i]),
1571 sizeof(bdaddr_t)) == 0)
1572 {
1573 pos = i;
1574 if (neighbours.fds[i] != -1)
1575 {
1576 found = 1; // save the position where it was found
1577 FD_SET (neighbours.fds[i], &wfds);
1578 maxfd = MAX (maxfd, neighbours.fds[i]);
1579 sendsocket = neighbours.fds[i];
1580 fprintf (stderr, "LOG: the address was found in the list\n");
1581 break;
1582 }
1583 }
1584 }
1585 if (found == 0)
1586 {
1587 int status;
1588 struct sockaddr_rc addr = { 0 };
1589
1590 fprintf (stderr,
1591 "LOG : %s has a new message for %.2X:%.2X:%.2X:%.2X:%.2X:%.2X which isn't on the broadcast list\n",
1592 dev.iface,
1593 frame->addr1.mac[5], frame->addr1.mac[4],
1594 frame->addr1.mac[3],
1595 frame->addr1.mac[2], frame->addr1.mac[1],
1596 frame->addr1.mac[0]); // FIXME: debugging message
1597
1598 sendsocket = socket (AF_BLUETOOTH, SOCK_STREAM, BTPROTO_RFCOMM);
1599
1600 if (sendsocket < 0)
1601 {
1602 fprintf (stderr,
1603 "Failed to create a RFCOMM socket (sending stage): %s\n",
1604 strerror (errno));
1605 return -1;
1606 }
1607
1608 GNUNET_memcpy (&addr.rc_bdaddr, &frame->addr1, sizeof(bdaddr_t));
1609 addr.rc_family = AF_BLUETOOTH;
1610 addr.rc_channel = get_channel (&dev, addr.rc_bdaddr);
1611
1612 int tries = 0;
1613connect_retry:
1614 status = connect (sendsocket, (struct sockaddr *) &addr,
1615 sizeof(addr));
1616 if ((0 != status) && (errno != EAGAIN) )
1617 {
1618 if ((errno == ECONNREFUSED) && (tries < 2) )
1619 {
1620 fprintf (stderr, "LOG : %.*s failed to connect. Trying again!\n",
1621 IFNAMSIZ, dev.iface);
1622 tries++;
1623 goto connect_retry;
1624 }
1625 else if (errno == EBADF)
1626 {
1627 fprintf (stderr, "LOG : %s failed to connect : %s. Skip it!\n",
1628 dev.iface, strerror (errno));
1629 memset (&write_pout, 0, sizeof(write_pout));
1630 broadcast = 1;
1631 }
1632 else
1633 {
1634 fprintf (stderr,
1635 "LOG : %s failed to connect : %s. Try again later!\n",
1636 dev.iface,
1637 strerror (errno));
1638 memset (&write_pout, 0, sizeof(write_pout));
1639 broadcast = 1;
1640 }
1641 }
1642 else
1643 {
1644 FD_SET (sendsocket, &wfds);
1645 maxfd = MAX (maxfd, sendsocket);
1646 fprintf (stderr, "LOG : Connection successful\n");
1647 if (pos != 0) // save the socket
1648 {
1649 neighbours.fds[pos] = sendsocket;
1650 }
1651 else
1652 {
1653 /* Add the new device to the discovered devices list */
1654 if (neighbours.size < MAX_PORTS)
1655 {
1656 neighbours.fds[neighbours.size] = sendsocket;
1657 GNUNET_memcpy (&(neighbours.devices[neighbours.size++]),
1658 &addr.rc_bdaddr, sizeof(bdaddr_t));
1659 }
1660 else
1661 {
1662 fprintf (stderr,
1663 "The top limit for the discovarable devices' list was reached\n");
1664 }
1665 }
1666 }
1667 }
1668 }
1669 }
1670
1671 if (broadcast == 0)
1672 {
1673 /* Select a fd which is ready for action :) */
1674 {
1675 int retval = select (maxfd + 1, &rfds, &wfds, NULL, NULL);
1676 if ((-1 == retval) && (EINTR == errno))
1677 continue;
1678 if ((0 > retval) && (errno != EBADF) ) // we handle BADF errors later
1679 {
1680 fprintf (stderr, "select failed: %s\n", strerror (errno));
1681 break;
1682 }
1683 }
1684 if (FD_ISSET (STDOUT_FILENO, &wfds))
1685 {
1686 ssize_t ret =
1687 write (STDOUT_FILENO, write_std.buf + write_std.pos,
1688 write_std.size - write_std.pos);
1689 if (0 > ret)
1690 {
1691 fprintf (stderr, "Failed to write to STDOUT: %s\n", strerror (errno));
1692 break;
1693 }
1694 write_std.pos += ret;
1695 if (write_std.pos == write_std.size)
1696 {
1697 write_std.pos = 0;
1698 write_std.size = 0;
1699 }
1700 fprintf (stderr, "LOG : %s sends a message to STDOUT\n", dev.iface); // FIXME: debugging message
1701 }
1702 if (-1 != sendsocket)
1703 {
1704 if (FD_ISSET (sendsocket, &wfds))
1705 {
1706 ssize_t ret = write (sendsocket,
1707 write_pout.buf + write_std.pos,
1708 write_pout.size - write_pout.pos);
1709 if (0 > ret) // FIXME should I first check the error type?
1710 {
1711 fprintf (stderr,
1712 "Failed to write to bluetooth device: %s. Closing the socket!\n",
1713 strerror (errno));
1714 for (i = 0; i < neighbours.size; i++)
1715 {
1716 if (neighbours.fds[i] == sendsocket)
1717 {
1718 (void) close (sendsocket);
1719 neighbours.fds[i] = -1;
1720 break;
1721 }
1722 }
1723 /* Remove the message */
1724 memset (&write_pout.buf + write_std.pos, 0, (write_pout.size
1725 - write_pout.pos));
1726 write_pout.pos = 0;
1727 write_pout.size = 0;
1728 }
1729 else
1730 {
1731 write_pout.pos += ret;
1732 if ((write_pout.pos != write_pout.size) && (0 != ret))
1733 {
1734 /* We should not get partial sends with packet-oriented devices... */
1735 fprintf (stderr, "Write error, partial send: %u/%u\n",
1736 (unsigned int) write_pout.pos,
1737 (unsigned int) write_pout.size);
1738 break;
1739 }
1740
1741 if (write_pout.pos == write_pout.size)
1742 {
1743 write_pout.pos = 0;
1744 write_pout.size = 0;
1745 }
1746 fprintf (stderr, "LOG : %s sends a message to a DEVICE\n",
1747 dev.iface); // FIXME: debugging message
1748 }
1749 }
1750 }
1751 for (i = 0; i <= maxfd; i++)
1752 {
1753 if (FD_ISSET (i, &rfds))
1754 {
1755 if (i == STDIN_FILENO)
1756 {
1757 ssize_t ret =
1758 read (i, readbuf, sizeof(readbuf));
1759 if (0 > ret)
1760 {
1761 fprintf (stderr,
1762 "Read error from STDIN: %s\n",
1763 strerror (errno));
1764 break;
1765 }
1766 if (0 == ret)
1767 {
1768 /* stop reading... */
1769 stdin_open = 0;
1770 }
1771 else
1772 {
1773 mst_receive (stdin_mst, readbuf, ret);
1774 fprintf (stderr, "LOG : %s receives a message from STDIN\n",
1775 dev.iface); // FIXME: debugging message
1776 }
1777 }
1778 else if (i == dev.fd_rfcomm)
1779 {
1780 int readsocket;
1781 struct sockaddr_rc addr = { 0 };
1782 unsigned int opt = sizeof(addr);
1783
1784 readsocket = accept (dev.fd_rfcomm, (struct sockaddr *) &addr,
1785 &opt);
1786 fprintf (stderr, "LOG : %s accepts a message\n", dev.iface); // FIXME: debugging message
1787 if (readsocket == -1)
1788 {
1789 fprintf (stderr,
1790 "Failed to accept a connection on interface: %.*s\n",
1791 IFNAMSIZ,
1792 strerror (errno));
1793 break;
1794 }
1795 else
1796 {
1797 FD_SET (readsocket, &rfds);
1798 maxfd = MAX (maxfd, readsocket);
1799
1800 if (crt_rfds < MAX_PORTS)
1801 rfds_list[crt_rfds++] = readsocket;
1802 else
1803 {
1804 fprintf (stderr,
1805 "The limit for the read file descriptors list was \
1806 reached\n");
1807 break;
1808 }
1809 }
1810 }
1811 else
1812 {
1813 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
1814 ssize_t ret;
1815 fprintf (stderr, "LOG : %s reads something from the socket\n",
1816 dev.iface); // FIXME : debugging message
1817 rrm = (struct
1818 GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
1819 ret =
1820 read_from_the_socket ((void *) &i, (unsigned char *) &rrm->frame,
1821 sizeof(write_std.buf)
1822 - sizeof(struct
1823 GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
1824 + sizeof(struct
1825 GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
1826 rrm);
1827 if (0 >= ret)
1828 {
1829 int j;
1830 FD_CLR (i, &rfds);
1831 close (i);
1832 /* Remove the socket from the list */
1833 for (j = 0; j < crt_rfds; j++)
1834 {
1835 if (rfds_list[j] == i)
1836 {
1837 rfds_list[j] ^= rfds_list[crt_rfds - 1];
1838 rfds_list[crt_rfds - 1] ^= rfds_list[j];
1839 rfds_list[j] ^= rfds_list[crt_rfds - 1];
1840 crt_rfds -= 1;
1841 break;
1842 }
1843 }
1844
1845 fprintf (stderr, "Read error from raw socket: %s\n", strerror (
1846 errno));
1847 break;
1848 }
1849 if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
1850 {
1851 write_std.size = ret
1852 + sizeof(struct
1853 GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
1854 - sizeof(struct
1855 GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
1856 rrm->header.size = htons (write_std.size);
1857 rrm->header.type = htons (
1858 GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
1859 }
1860 }
1861 }
1862 }
1863 }
1864 }
1865 /* Error handling, try to clean up a bit at least */
1866 mst_destroy (stdin_mst);
1867 stdin_mst = NULL;
1868 sdp_close (dev.session);
1869 (void) close (dev.fd_rfcomm);
1870 if (-1 != sendsocket)
1871 (void) close (sendsocket);
1872
1873 for (i = 0; i < crt_rfds; i++)
1874 (void) close (rfds_list[i]);
1875
1876 for (i = 0; i < neighbours.size; i++)
1877 (void) close (neighbours.fds[i]);
1878 #else
1879 struct HardwareInfos dev;
1880 struct GNUNET_NETWORK_Handle *sendsocket;
1881 struct GNUNET_NETWORK_FDSet *rfds;
1882 struct GNUNET_NETWORK_FDSet *wfds;
1883 struct GNUNET_NETWORK_Handle *rfds_list[MAX_PORTS];
1884 char readbuf[MAXLINE] = { 0 };
1885 SOCKADDR_BTH acc_addr = { 0 };
1886 int addr_len = sizeof(SOCKADDR_BTH);
1887 int broadcast, i, stdin_open, crt_rfds = 0;
1888 HANDLE stdin_handle = GetStdHandle (STD_INPUT_HANDLE);
1889 HANDLE stdout_handle = GetStdHandle (STD_OUTPUT_HANDLE);
1890 struct MessageStreamTokenizer *stdin_mst;
1891
1892 /* check the handles */
1893 if (stdin_handle == INVALID_HANDLE_VALUE)
1894 {
1895 fprintf (stderr, "Failed to get the stdin handle\n");
1896 ExitProcess (2);
1897 }
1898
1899 if (stdout_handle == INVALID_HANDLE_VALUE)
1900 {
1901 fprintf (stderr, "Failed to get the stdout handle\n");
1902 ExitProcess (2);
1903 }
1904
1905 /* initialize windows sockets */
1906 initialize_windows_sockets ();
1907
1908 // /* test bluetooth socket family support */ --> it return false because the GNUNET_NETWORK_test_pf should also receive the type of socket (BTHPROTO_RFCOMM)
1909 // if (GNUNET_NETWORK_test_pf (AF_BTH) != GNUNET_OK)
1910 // {
1911 // fprintf (stderr, "AF_BTH family is not supported\n");
1912 // ExitProcess (2);
1913 // }
1914
1915 /* create the socket */
1916 dev.handle = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM,
1917 BTHPROTO_RFCOMM);
1918 if (dev.handle == NULL)
1919 {
1920 fprintf (stderr, "Failed to create RFCOMM socket: ");
1921 print_last_error ();
1922 ExitProcess (2);
1923 }
1924
1925
1926 if (open_device (&dev) == -1)
1927 {
1928 fprintf (stderr, "Failed to open the device\n");
1929 print_last_error ();
1930 if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
1931 {
1932 fprintf (stderr, "Failed to close the socket!\n");
1933 print_last_error ();
1934 }
1935 ExitProcess (2);
1936 }
1937
1938 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (dev.handle, 1))
1939 {
1940 fprintf (stderr, "Failed to change the socket mode\n");
1941 ExitProcess (2);
1942 }
1943
1944 memset (&write_std, 0, sizeof(write_std));
1945 memset (&write_pout, 0, sizeof(write_pout));
1946 stdin_open = 1;
1947
1948 rfds = GNUNET_NETWORK_fdset_create ();
1949 wfds = GNUNET_NETWORK_fdset_create ();
1950
1951 /* Send MAC address of the bluetooth interface to STDOUT first */
1952 {
1953 struct GNUNET_TRANSPORT_WLAN_HelperControlMessage macmsg;
1954
1955 macmsg.hdr.size = htons (sizeof(macmsg));
1956 macmsg.hdr.type = htons (GNUNET_MESSAGE_TYPE_WLAN_HELPER_CONTROL);
1957 GNUNET_memcpy (&macmsg.mac, &dev.pl_mac, sizeof(struct
1958 GNUNET_TRANSPORT_WLAN_MacAddress_Copy));
1959 GNUNET_memcpy (write_std.buf, &macmsg, sizeof(macmsg));
1960 write_std.size = sizeof(macmsg);
1961 }
1962
1963
1964 stdin_mst = mst_create (&stdin_send_hw, &dev);
1965 stdin_open = 1;
1966
1967 int pos = 0;
1968 int stdin_pos = -1;
1969 int stdout_pos = -1;
1970 while (1)
1971 {
1972 broadcast = 0;
1973 pos = 0;
1974 stdin_pos = -1;
1975 stdout_pos = -1;
1976 sendsocket = NULL; // FIXME ???memleaks
1977
1978 GNUNET_NETWORK_fdset_zero (rfds);
1979 if ((0 == write_pout.size) && (1 == stdin_open))
1980 {
1981 stdin_pos = pos;
1982 pos += 1;
1983 GNUNET_NETWORK_fdset_handle_set (rfds, (struct
1984 GNUNET_DISK_FileHandle*) &
1985 stdin_handle);
1986 }
1987
1988 if (0 == write_std.size)
1989 {
1990 pos += 1;
1991 GNUNET_NETWORK_fdset_set (rfds, dev.handle);
1992 }
1993
1994 for (i = 0; i < crt_rfds; i++)
1995 {
1996 pos += 1;
1997 GNUNET_NETWORK_fdset_set (rfds, rfds_list[i]);
1998 }
1999
2000 GNUNET_NETWORK_fdset_zero (wfds);
2001 if (0 < write_std.size)
2002 {
2003 stdout_pos = pos;
2004 GNUNET_NETWORK_fdset_handle_set (wfds, (struct
2005 GNUNET_DISK_FileHandle*) &
2006 stdout_handle);
2007 // printf ("%s\n", write_std.buf);
2008 // memset (write_std.buf, 0, write_std.size);
2009 // write_std.size = 0;
2010 }
2011
2012 if (0 < write_pout.size)
2013 {
2014 if (strcmp (argv[1], "ff:ff:ff:ff:ff:ff") == 0)
2015 {
2016 fprintf (stderr, "LOG: BROADCAST! Skipping the message\n");
2017 // skip the message
2018 broadcast = 1;
2019 memset (write_pout.buf, 0, write_pout.size);
2020 write_pout.size = 0;
2021 }
2022 else
2023 {
2024 SOCKADDR_BTH addr;
2025 fprintf (stderr, "LOG : has a new message for %s\n", argv[1]);
2026 sendsocket = GNUNET_NETWORK_socket_create (AF_BTH, SOCK_STREAM,
2027 BTHPROTO_RFCOMM);
2028
2029 if (sendsocket == NULL)
2030 {
2031 fprintf (stderr, "Failed to create RFCOMM socket: \n");
2032 print_last_error ();
2033 ExitProcess (2);
2034 }
2035
2036 memset (&addr, 0, sizeof(addr));
2037 // addr.addressFamily = AF_BTH;
2038 if (SOCKET_ERROR ==
2039 WSAStringToAddress (argv[1], AF_BTH, NULL, (LPSOCKADDR) &addr,
2040 &addr_len))
2041 {
2042 fprintf (stderr, "Failed to translate the address: ");
2043 print_last_error ();
2044 ExitProcess (2);
2045 }
2046 addr.port = get_channel (argv[1]);
2047 if (addr.port == -1)
2048 {
2049 fprintf (stderr,
2050 "Couldn't find the sdp service for the address: %s\n",
2051 argv[1]);
2052 memset (write_pout.buf, 0, write_pout.size);
2053 write_pout.size = 0;
2054 broadcast = 1; // skipping the select part
2055 }
2056 else
2057 {
2058 if (GNUNET_OK != GNUNET_NETWORK_socket_connect (sendsocket,
2059 (LPSOCKADDR) &addr,
2060 addr_len))
2061 {
2062 fprintf (stderr, "Failed to connect: ");
2063 print_last_error ();
2064 ExitProcess (2);
2065 }
2066
2067 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (sendsocket, 1))
2068 {
2069 fprintf (stderr, "Failed to change the socket mode\n");
2070 ExitProcess (2);
2071 }
2072
2073 GNUNET_NETWORK_fdset_set (wfds, sendsocket);
2074 }
2075 }
2076 }
2077
2078 if (broadcast == 0)
2079 {
2080 int retval = GNUNET_NETWORK_socket_select (rfds, wfds, NULL,
2081 GNUNET_TIME_relative_get_forever_ ());
2082 if (retval < 0)
2083 {
2084 fprintf (stderr, "Select error\n");
2085 ExitProcess (2);
2086 }
2087 // if (GNUNET_NETWORK_fdset_isset (wfds, (struct GNUNET_NETWORK_Handle*)&stdout_handle))
2088 if (retval == stdout_pos)
2089 {
2090 fprintf (stderr, "LOG : sends a message to STDOUT\n"); // FIXME: debugging message
2091 // ssize_t ret;
2092 // ret = GNUNET_NETWORK_socket_send ((struct GNUNET_NETWORK_Handle *)&stdout_handle, write_std.buf + write_std.pos, write_std.size - write_std.pos);
2093 // ret = write (STDOUT_FILENO, write_std.buf + write_std.pos, write_std.size - write_std.pos);
2094 DWORD ret;
2095 if (FALSE == WriteFile (stdout_handle, write_std.buf + write_std.pos,
2096 write_std.size - write_std.pos, &ret, NULL))
2097 {
2098 fprintf (stderr, "Failed to write to STDOUT: ");
2099 print_last_error ();
2100 break;
2101 }
2102
2103 if (ret <= 0)
2104 {
2105 fprintf (stderr, "Failed to write to STDOUT\n");
2106 ExitProcess (2);
2107 }
2108
2109 write_std.pos += ret;
2110 if (write_std.pos == write_std.size)
2111 {
2112 write_std.pos = 0;
2113 write_std.size = 0;
2114 }
2115 }
2116 if (sendsocket != NULL)
2117 {
2118 if (GNUNET_NETWORK_fdset_isset (wfds, sendsocket))
2119 {
2120 ssize_t ret;
2121 ret = GNUNET_NETWORK_socket_send (sendsocket, write_pout.buf
2122 + write_pout.pos,
2123 write_pout.size - write_pout.pos);
2124
2125 if (GNUNET_SYSERR == ret)
2126 {
2127 fprintf (stderr,
2128 "Failed to send to the socket. Closing the socket. Error: \n");
2129 print_last_error ();
2130 if (GNUNET_NETWORK_socket_close (sendsocket) != GNUNET_OK)
2131 {
2132 fprintf (stderr, "Failed to close the sendsocket!\n");
2133 print_last_error ();
2134 }
2135 ExitProcess (2);
2136 }
2137 else
2138 {
2139 write_pout.pos += ret;
2140 if ((write_pout.pos != write_pout.size) && (0 != ret))
2141 {
2142 /* we should not get partial sends with packet-oriented devices... */
2143 fprintf (stderr, "Write error, partial send: %u/%u\n",
2144 (unsigned int) write_pout.pos,
2145 (unsigned int) write_pout.size);
2146 break;
2147 }
2148
2149 if (write_pout.pos == write_pout.size)
2150 {
2151 write_pout.pos = 0;
2152 write_pout.size = 0;
2153 }
2154 fprintf (stderr, "LOG : sends a message to a DEVICE\n"); // FIXME: debugging message
2155 }
2156 }
2157 }
2158
2159 // if (GNUNET_NETWORK_fdset_isset (rfds, (struct GNUNET_NETWORK_Handle*)&stdin_handle))
2160 if (retval == stdin_pos)
2161 {
2162 // ssize_t ret;
2163 // ret = GNUNET_NETWORK_socket_recv ((struct GNUNET_NETWORK_Handle *)&stdin_handle, readbuf, sizeof (write_pout.buf));
2164 // ret = read (STDIN_FILENO, readbuf, sizeof (readbuf));
2165 DWORD ret;
2166 if (FALSE == ReadFile (stdin_handle, readbuf, sizeof(readbuf), &ret,
2167 NULL)) /* do nothing asynchronous */
2168 {
2169 fprintf (stderr, "Read error from STDIN: ");
2170 print_last_error ();
2171 break;
2172 }
2173 if (0 == ret)
2174 {
2175 /* stop reading... */
2176 stdin_open = 0;
2177 }
2178 else
2179 {
2180 mst_receive (stdin_mst, readbuf, ret);
2181 fprintf (stderr, "LOG : receives a message from STDIN\n"); // FIXME: debugging message
2182 }
2183 }
2184 else if (GNUNET_NETWORK_fdset_isset (rfds, dev.handle))
2185 {
2186 fprintf (stderr, "LOG: accepting connection\n");
2187 struct GNUNET_NETWORK_Handle *readsocket;
2188 readsocket = GNUNET_NETWORK_socket_accept (dev.handle,
2189 (LPSOCKADDR) &acc_addr,
2190 &addr_len);
2191 if (readsocket == NULL)
2192 {
2193 fprintf (stderr, "Accept error %d: ", GetLastError ());
2194 print_last_error ();
2195 ExitProcess (2);
2196 }
2197 else
2198 {
2199 if (GNUNET_OK != GNUNET_NETWORK_socket_set_blocking (readsocket, 1))
2200 {
2201 fprintf (stderr, "Failed to change the socket mode\n");
2202 ExitProcess (2);
2203 }
2204 GNUNET_NETWORK_fdset_set (rfds, readsocket);
2205
2206 if (crt_rfds < MAX_PORTS)
2207 rfds_list[crt_rfds++] = readsocket;
2208 else
2209 {
2210 fprintf (stderr,
2211 "The limit for the read file descriptors list was reached\n");
2212 break;
2213 }
2214 }
2215 }
2216 else
2217 for (i = 0; i < crt_rfds; i++)
2218 {
2219 if (GNUNET_NETWORK_fdset_isset (rfds, rfds_list[i]))
2220 {
2221 struct GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *rrm;
2222 ssize_t ret;
2223 fprintf (stderr, "LOG: reading something from the socket\n"); // FIXME : debugging message
2224 rrm = (struct
2225 GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage *) write_std.buf;
2226 ret = read_from_the_socket (rfds_list[i], (unsigned
2227 char *) &rrm->frame,
2228 sizeof(write_std.buf)
2229 - sizeof(struct
2230 GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2231 + sizeof(struct
2232 GNUNET_TRANSPORT_WLAN_Ieee80211Frame),
2233 rrm);
2234 if (0 >= ret)
2235 {
2236 // TODO remove the socket from the list
2237 if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2238 {
2239 fprintf (stderr, "Failed to close the sendsocket!\n");
2240 print_last_error ();
2241 }
2242
2243 fprintf (stderr, "Read error from raw socket: ");
2244 print_last_error ();
2245 break;
2246 }
2247 if ((0 < ret) && (0 == mac_test (&rrm->frame, &dev)))
2248 {
2249 write_std.size = ret
2250 + sizeof(struct
2251 GNUNET_TRANSPORT_WLAN_RadiotapReceiveMessage)
2252 - sizeof(struct
2253 GNUNET_TRANSPORT_WLAN_Ieee80211Frame);
2254 rrm->header.size = htons (write_std.size);
2255 rrm->header.type = htons (
2256 GNUNET_MESSAGE_TYPE_WLAN_DATA_FROM_HELPER);
2257 }
2258 break;
2259 }
2260 }
2261 }
2262 }
2263
2264 mst_destroy (stdin_mst);
2265 stdin_mst = NULL;
2266
2267 if (GNUNET_NETWORK_socket_close (dev.handle) != GNUNET_OK)
2268 {
2269 fprintf (stderr, "Failed to close the socket!\n");
2270 print_last_error ();
2271 }
2272
2273 for (i = 0; i < crt_rfds; i++)
2274 {
2275 if (GNUNET_NETWORK_socket_close (rfds_list[i]) != GNUNET_OK)
2276 {
2277 fprintf (stderr, "Failed to close the socket!\n");
2278 print_last_error ();
2279 }
2280 }
2281
2282 WSACleanup ();
2283 #endif
2284 return 1; /* we never exit 'normally' */
2285}