diff options
Diffstat (limited to 'src/transport/gnunet-helper-transport-bluetooth.c')
-rw-r--r-- | src/transport/gnunet-helper-transport-bluetooth.c | 2285 |
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 | */ | ||
71 | struct 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 | */ | ||
97 | struct 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 | */ | ||
123 | struct 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 | */ | ||
145 | static 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 | */ | ||
153 | static struct BroadcastMessages neighbours; | ||
154 | |||
155 | static int searching_devices_count = 0; | ||
156 | #endif | ||
157 | |||
158 | /** | ||
159 | * Buffer for data read from stdin to be transmitted to the bluetooth device | ||
160 | */ | ||
161 | static struct SendBuffer write_pout; | ||
162 | |||
163 | /** | ||
164 | * Buffer for data read from the bluetooth device to be transmitted to stdout. | ||
165 | */ | ||
166 | static 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 | */ | ||
190 | typedef void (*MessageTokenizerCallback) (void *cls, | ||
191 | const struct | ||
192 | GNUNET_MessageHeader * | ||
193 | message); | ||
194 | |||
195 | /** | ||
196 | * Handle to a message stream tokenizer. | ||
197 | */ | ||
198 | struct 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 | */ | ||
239 | static struct MessageStreamTokenizer * | ||
240 | mst_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 | */ | ||
276 | static int | ||
277 | mst_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 | { | ||
292 | do_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 | */ | ||
454 | static void | ||
455 | mst_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 | */ | ||
469 | static unsigned long | ||
470 | calc_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 | */ | ||
555 | static int | ||
556 | check_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 | */ | ||
578 | static int | ||
579 | bind_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 | */ | ||
607 | static int | ||
608 | register_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 | */ | ||
701 | static int | ||
702 | get_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 | */ | ||
778 | static ssize_t | ||
779 | read_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 | */ | ||
834 | static int | ||
835 | open_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 | */ | ||
1005 | static void | ||
1006 | mac_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 | */ | ||
1024 | static int | ||
1025 | test_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 | */ | ||
1056 | static int | ||
1057 | mac_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 | */ | ||
1084 | static void | ||
1085 | stdin_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 | */ | ||
1128 | static int | ||
1129 | send_broadcast (struct HardwareInfos *dev, int *sendsocket) | ||
1130 | { | ||
1131 | int new_device = 0; | ||
1132 | int loops = 0; | ||
1133 | |||
1134 | search_for_devices: | ||
1135 | if (((neighbours.size == neighbours.pos) && (new_device == 1)) || | ||
1136 | (neighbours.size == 0) ) | ||
1137 | { | ||
1138 | inquiry_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 | */ | ||
1382 | int | ||
1383 | main (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; | ||
1613 | connect_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 | } | ||