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