1 /* $NetBSD: bta2dpd.c,v 1.9 2023/06/24 05:26:01 msaitoh Exp $ */
2
3 /*-
4 * Copyright (c) 2015 - 2016 Nathanial Sloss <nathanialsloss@yahoo.com.au>
5 * All rights reserved.
6 *
7 * This software is dedicated to the memory of -
8 * Baron James Anlezark (Barry) - 1 Jan 1949 - 13 May 2012.
9 *
10 * Barry was a man who loved his music.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
22 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
23 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
24 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
25 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
26 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
27 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
28 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
29 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
30 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
31 * POSSIBILITY OF SUCH DAMAGE.
32 */
33
34 /*-
35 * Copyright (c) 2006 Itronix Inc.
36 * All rights reserved.
37 *
38 * Written by Iain Hibbert for Itronix Inc.
39 *
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
42 * are met:
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
48 * 3. The name of Itronix Inc. may not be used to endorse
49 * or promote products derived from this software without specific
50 * prior written permission.
51 *
52 * THIS SOFTWARE IS PROVIDED BY ITRONIX INC. ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
54 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
55 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ITRONIX INC. BE LIABLE FOR ANY
56 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
57 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
58 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
59 * ON ANY THEORY OF LIABILITY, WHETHER IN
60 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
61 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
62 * POSSIBILITY OF SUCH DAMAGE.
63 */
64
65 /* This was based upon bthset.c */
66
67 #include <sys/cdefs.h>
68 __COPYRIGHT("@(#) Copyright (c) 2006 Itronix, Inc. All rights reserved.");
69 __RCSID("$NetBSD");
70
71 #include <sys/ioctl.h>
72 #include <sys/types.h>
73 #include <sys/time.h>
74
75 #include <assert.h>
76 #include <bluetooth.h>
77 #include <err.h>
78 #include <event.h>
79 #include <fcntl.h>
80 #include <sdp.h>
81 #include <stdarg.h>
82 #include <stdio.h>
83 #include <stdlib.h>
84 #include <string.h>
85 #include <syslog.h>
86 #include <unistd.h>
87 #include <util.h>
88 #include <errno.h>
89
90 #include "avdtp_signal.h"
91 #include "sbc_encode.h"
92
93 #define A2DP_SINK 0x110b
94
95 /* A2DP Audio Source service record */
96 static uint8_t source_data[] = {
97 0x09, 0x00, 0x00, // uint16 ServiceRecordHandle
98 0x0a, 0x00, 0x00, 0x00, // uint32 0x00000000
99 0x00,
100
101 0x09, 0x00, 0x01, // uint16 ServiceClassIDList
102 0x35, 0x03, // seq8(3)
103 0x19, 0x11, 0x0a, // uuid16 AudioSource
104
105 0x09, 0x00, 0x04, // uint16 ProtocolDescriptorList
106 0x35, 0x10, // seq8(16)
107 0x35, 0x06, // seq8(6)
108 0x19, 0x01, 0x00, // uuid16 L2CAP
109 0x09, 0x00, 0x19, // uint16 %src_psm%
110 0x35, 0x06, // seq8(6)
111 0x19, 0x00, 0x19, // uuid16 AVDTP
112 0x09, 0x01, 0x00, // uint16 Ver 1.0
113
114 0x09, 0x00, 0x05, // uint16 BrowseGroupList
115 0x35, 0x03, // seq8(3)
116 0x19, 0x10, 0x02, // uuid16 PublicBrowseGroup
117
118 0x09, 0x00, 0x06, // uint16 LanguageBaseAttributeIDList
119 0x35, 0x09, // seq8(9)
120 0x09, 0x65, 0x6e, // uint16 0x656e ("en")
121 0x09, 0x00, 0x6a, // uint16 106 (UTF-8)
122 0x09, 0x01, 0x00, // uint16 PrimaryLanguageBaseID
123
124 0x09, 0x00, 0x09, // uint16 BluetoothProfileDescriptorList
125 0x35, 0x08, // seq8(8)
126 0x35, 0x06, // seq8(6)
127 0x19, 0x11, 0x0d, // uuid16 A2DP
128 0x09, 0x01, 0x02, // uint16 v1.2
129
130 0x09, 0x01, 0x00, // uint16 PrimaryLanguageBaseID +
131 // ServiceNameOffset
132 0x25, 0x09, // str8(9) "Audio SRC"
133 'A', 'u', 'd', 'i', 'o', ' ', 'S', 'R', 'C',
134
135 0x09, 0x01, 0x02, // uint16 PrimaryLanguageBaseID +
136 // ProviderName
137 0x25, 0x06, // str8(6) "NetBSD"
138 'N', 'e', 't', 'B', 'S', 'D',
139
140 0x09, 0x03, 0x11, // uint16 SupportedFeatures
141 0x09, 0x01, 0x02 // uint16 Headphone, Speaker
142 };
143
144 static sdp_data_t source_record = { source_data + 0, source_data + 103 };
145 static sdp_data_t source_psm = { source_data + 26, source_data + 29 };
146
147
148 /* A2DP Audio Sink service record */
149 static uint8_t sink_data[] = {
150 0x09, 0x00, 0x00, // uint16 ServiceRecordHandle
151 0x0a, 0x00, 0x00, 0x00, // uint32 0x00000000
152 0x00,
153
154 0x09, 0x00, 0x01, // uint16 ServiceClassIDList
155 0x35, 0x03, // seq8(3)
156 0x19, 0x11, 0x0b, // uuid16 AudioSink
157
158 0x09, 0x00, 0x04, // uint16 ProtocolDescriptorList
159 0x35, 0x10, // seq8(16)
160 0x35, 0x06, // seq8(6)
161 0x19, 0x01, 0x00, // uuid16 L2CAP
162 0x09, 0x00, 0x19, // uint16 %sink_psm%
163 0x35, 0x06, // seq8(6)
164 0x19, 0x00, 0x19, // uuid16 AVDTP
165 0x09, 0x01, 0x00, // uint16 Ver 1.0
166
167 0x09, 0x00, 0x05, // uint16 BrowseGroupList
168 0x35, 0x03, // seq8(3)
169 0x19, 0x10, 0x02, // uuid16 PublicBrowseGroup
170
171 0x09, 0x00, 0x06, // uint16 LanguageBaseAttributeIDList
172 0x35, 0x09, // seq8(9)
173 0x09, 0x65, 0x6e, // uint16 0x656e ("en")
174 0x09, 0x00, 0x6a, // uint16 106 (UTF-8)
175 0x09, 0x01, 0x00, // uint16 PrimaryLanguageBaseID
176
177 0x09, 0x00, 0x09, // uint16 BluetoothProfileDescriptorList
178 0x35, 0x08, // seq8(8)
179 0x35, 0x06, // seq8(6)
180 0x19, 0x11, 0x0d, // uuid16 A2DP
181 0x09, 0x01, 0x02, // uint16 v1.2
182
183 0x09, 0x01, 0x00, // uint16 PrimaryLanguageBaseID +
184 // ServiceNameOffset
185 0x25, 0x09, // str8(9) "Audio SNK"
186 'A', 'u', 'd', 'i', 'o', ' ', 'S', 'N', 'K',
187
188 0x09, 0x01, 0x02, // uint16 PrimaryLanguageBaseID +
189 // ProviderName
190 0x25, 0x06, // str8(6) "NetBSD"
191 'N', 'e', 't', 'B', 'S', 'D',
192
193 0x09, 0x03, 0x11, // uint16 SupportedFeatures
194 0x09, 0x00, 0x03 // uint16 Headphone, Speaker
195 };
196
197 static sdp_data_t sink_record = { sink_data + 0, sink_data + 103 };
198 static sdp_data_t sink_psm = { sink_data + 26, sink_data + 29 };
199
200 struct l2cap_info {
201 bdaddr_t laddr;
202 bdaddr_t raddr;
203 };
204
205 __dead static void usage(void);
206
207 static int init_server(struct l2cap_info *);
208 static int init_client(struct l2cap_info *);
209 static void client_query(void);
210 static void exit_func(void);
211
212 static int sc; /* avdtp streaming channel */
213 static int orighc; /* avdtp listening socket */
214 static int hc; /* avdtp control/command channel */
215 struct event_base *base;
216 static struct event interrupt_ev; /* audio event */
217 static struct event recv_ev; /* audio sink event */
218 static struct event ctl_ev; /* avdtp ctl event */
219
220 struct l2cap_info info;
221 static bool runasDaemon;
222 static bool asSpeaker;
223 static bool dontStop;
224 static bool initDiscover; /* initiate avdtp discover */
225 static bool verbose; /* copy to stdout */
226 static bool test_mode; /* copy to stdout */
227 static uint8_t channel_mode = MODE_STEREO;
228 static uint8_t alloc_method = ALLOC_LOUDNESS;
229 static uint8_t frequency = FREQ_44_1K;
230 static int freqnum = 44100;
231 static uint8_t freqs[4];
232 static uint8_t blocks_config[4];
233 static uint8_t channel_config[4];
234 static uint8_t bands_config[2];
235 static uint8_t alloc_config[2];
236 static uint8_t bitpool = 0;
237 static uint8_t bands = BANDS_8;
238 static uint8_t blocks = BLOCKS_16;
239 static int volume = 0;
240 static int state = 0;
241 static uint16_t l2cap_psm = 0;
242 static int l2cap_mode;
243 uint16_t mtu;
244 uint16_t userset_mtu = 1000, service_class = A2DP_SINK;
245 static const char* service_type = "A2DP";
246 struct avdtp_sepInfo mySepInfo;
247 static sdp_session_t ss; /* SDP server session */
248
249 char *files2open[255];
250 static int numfiles = 0;
251 static int startFileInd = 0;
252 int audfile;
253
254 static void do_interrupt(int, short, void *);
255 static void do_recv(int, short, void *);
256 static void do_ctlreq(int, short, void *);
257 static void bt_exit(int fd);
258
259 #define log_err(st, fmt, args...) \
260 do { syslog(LOG_ERR, fmt, ##args); exit(st); } while (0)
261 #define log_warn(fmt, args...) syslog(LOG_WARNING, fmt, ##args)
262 #define log_info(fmt, args...) syslog(LOG_INFO, fmt, ##args)
263 #define log_debug(fmt, args...) syslog(LOG_DEBUG, fmt, ##args)
264
265 int
main(int ac,char * av[])266 main(int ac, char *av[])
267 {
268 int enc, i, n, m, l, j, k, o, ch, blocksnum;
269 u_int tmpbitpool;
270 bdaddr_copy(&info.laddr, BDADDR_ANY);
271
272 sc = hc = -1;
273 verbose = asSpeaker = test_mode = initDiscover = runasDaemon = false;
274 dontStop = false;
275 n = m = l = i = j = o = 0;
276 freqs[0] = frequency;
277 channel_config[0] = channel_mode;
278 blocks_config[0] = blocks;
279 bands_config[0] = bands;
280 alloc_config[0] = alloc_method;
281 channel_config[0] = channel_mode;
282
283 while ((ch = getopt(ac, av, "A:a:B:b:Dd:e:f:IKnM:m:p:r:tV:v")) !=
284 EOF) {
285 switch (ch) {
286 case 'A':
287 for (k = 0; k < (int)strlen(optarg); k++) {
288 if (o > 1)
289 break;
290 switch (optarg[k]) {
291 case '0':
292 alloc_config[o++] = ALLOC_ANY;
293 break;
294 case 'S':
295 alloc_config[o++] = ALLOC_SNR;
296 break;
297 case 'L':
298 alloc_config[o++] = ALLOC_LOUDNESS;
299 break;
300 default:
301 usage();
302 }
303 }
304 break;
305 case 'a':
306 if (!bt_aton(optarg, &info.raddr)) {
307 struct hostent *he = NULL;
308
309 if ((he = bt_gethostbyname(optarg)) == NULL)
310 usage();
311
312 bdaddr_copy(&info.raddr,
313 (bdaddr_t *)he->h_addr);
314 }
315 break;
316 case 'B': /* Max bitpool value */
317 bitpool = (uint8_t)atoi(optarg);
318 break;
319 case 'b':
320 if (m > 3)
321 break;
322 blocksnum = atoi(optarg);
323 switch (blocksnum) {
324 case 0:
325 blocks_config[m++] = BLOCKS_ANY;
326 break;
327 case 4:
328 blocks_config[m++] = BLOCKS_4;
329 break;
330 case 8:
331 blocks_config[m++] = BLOCKS_8;
332 break;
333 case 12:
334 blocks_config[m++] = BLOCKS_12;
335 break;
336 case 16:
337 blocks_config[m++] = BLOCKS_16;
338 break;
339 default:
340 usage();
341 }
342 break;
343 case 'D':
344 runasDaemon = true;
345 break;
346 case 'd': /* local device address */
347 if (!bt_devaddr(optarg, &info.laddr))
348 usage();
349 break;
350 case 'e':
351 if (l > 1)
352 break;
353 enc = atoi(optarg);
354 switch (enc) {
355 case 0:
356 bands_config[l++] = BANDS_ANY;
357 break;
358 case 4:
359 bands_config[l++] = BANDS_4;
360 break;
361 case 8:
362 bands_config[l++] = BANDS_8;
363 break;
364 default:
365 usage();
366 }
367 break;
368 case 'f':
369 for (k = 0; k < (int)strlen(optarg); k++) {
370 if (n > 3)
371 break;
372 switch (optarg[k]) {
373 case '0':
374 channel_config[n++] = MODE_ANY;
375 break;
376 case '2':
377 channel_config[n++] = MODE_DUAL;
378 break;
379 case 'j':
380 channel_config[n++] = MODE_JOINT;
381 break;
382 case 'm':
383 channel_config[n++] = MODE_MONO;
384 break;
385 case 's':
386 channel_config[n++] = MODE_STEREO;
387 break;
388 default:
389 usage();
390 }
391 }
392 break;
393 case 'I':
394 initDiscover = true;
395 break;
396 case 'K':
397 asSpeaker = true;
398 break;
399 case 'M':
400 userset_mtu = (uint16_t)atoi(optarg);
401 break;
402 case 'm': /* link mode */
403 if (strcasecmp(optarg, "auth") == 0)
404 l2cap_mode = L2CAP_LM_AUTH;
405 else if (strcasecmp(optarg, "encrypt") == 0)
406 l2cap_mode = L2CAP_LM_ENCRYPT;
407 else if (strcasecmp(optarg, "secure") == 0)
408 l2cap_mode = L2CAP_LM_SECURE;
409 else if (strcasecmp(optarg, "none"))
410 errx(EXIT_FAILURE, "%s: unknown mode", optarg);
411
412 break;
413 case 'n':
414 dontStop = true;
415 break;
416 case 'p':
417 l2cap_psm = (uint16_t)atoi(optarg);
418 break;
419 case 'r':
420 if (i > 3)
421 break;
422 freqnum = atoi(optarg);
423 switch (freqnum) {
424 case 0:
425 freqs[i++] = FREQ_ANY;
426 break;
427 case 16000:
428 freqs[i++] = FREQ_16K;
429 break;
430 case 32000:
431 freqs[i++] = FREQ_32K;
432 break;
433 case 44100:
434 freqs[i++] = FREQ_44_1K;
435 break;
436 case 48000:
437 freqs[i++] = FREQ_48K;
438 break;
439 default:
440 usage();
441 }
442 break;
443 case 't':
444 test_mode = true;
445 break;
446 case 'V': /* Volume Multiplier */
447 volume = atoi(optarg);
448 break;
449 case 'v':
450 verbose = true;
451 break;
452 default:
453 usage();
454 }
455 }
456 av += optind;
457 ac -= optind;
458
459 numfiles = ac;
460
461 for (i = 0; i < numfiles; i++)
462 files2open[i] = av[i];
463
464 if (runasDaemon && test_mode)
465 usage();
466
467 if (bdaddr_any(&info.raddr) && (!asSpeaker && !test_mode))
468 usage();
469
470 if (volume < 0 || volume > 2)
471 usage();
472
473 if (!asSpeaker && l2cap_psm)
474 usage();
475
476 if (asSpeaker) {
477 if (l == 0)
478 bands = BANDS_ANY;
479 if (m == 0)
480 blocks = BLOCKS_ANY;
481 if (n == 0)
482 channel_mode = MODE_ANY;
483 if (o == 0)
484 alloc_method = ALLOC_ANY;
485 }
486
487 if (i) {
488 frequency = 0;
489 for (j = 0; j < i; j++)
490 frequency |= freqs[j];
491 }
492 if (m) {
493 blocks = 0;
494 for (j = 0; j < m; j++)
495 blocks |= blocks_config[j];
496 }
497 if (l) {
498 bands = 0;
499 for (j = 0; j < l; j++)
500 bands |= bands_config[j];
501 }
502 if (n) {
503 channel_mode = 0;
504 for (j = 0; j < n; j++)
505 channel_mode |= channel_config[j];
506 }
507 if (o) {
508 alloc_method = 0;
509 for (j = 0; j < o; j++)
510 alloc_method |= alloc_config[j];
511 }
512
513 if (channel_mode == MODE_MONO || channel_mode == MODE_DUAL)
514 tmpbitpool = 16;
515 else
516 tmpbitpool = 32;
517
518 if (bands == BANDS_8)
519 tmpbitpool *= 8;
520 else
521 tmpbitpool *= 4;
522
523 if (tmpbitpool > DEFAULT_MAXBPOOL)
524 tmpbitpool = DEFAULT_MAXBPOOL;
525
526 if (bitpool == 0 || tmpbitpool < bitpool)
527 bitpool = (uint8_t)tmpbitpool;
528
529 if (runasDaemon) {
530 if (daemon(0, 0) == -1)
531 err(EXIT_FAILURE, "daemon");
532 pidfile(NULL);
533 openlog(getprogname(), LOG_NDELAY | LOG_PID, LOG_DAEMON);
534 } else {
535 openlog(getprogname(), LOG_NLOG | LOG_PERROR | LOG_PTRIM,
536 LOG_USER);
537 }
538
539 again:
540 base = event_init();
541
542 if (asSpeaker == 0) {
543 if (init_client(&info) < 0)
544 log_err(EXIT_FAILURE, "init client: %m");
545 } else {
546 if (init_server(&info) < 0)
547 log_err(EXIT_FAILURE, "init server: %m");
548 }
549
550 if (verbose) {
551 log_info("A2DP:");
552 log_info("\tladdr: %s", bt_ntoa(&info.laddr, NULL));
553 log_info("\traddr: %s", bt_ntoa(&info.raddr, NULL));
554 }
555
556 event_base_loop(base, 0);
557 event_base_free(base);
558
559 sdp_close(ss);
560
561 if (audfile != -1 && audfile != STDIN_FILENO && audfile !=
562 STDOUT_FILENO) {
563 close(audfile);
564 audfile = -1;
565 }
566
567 if (runasDaemon)
568 goto again;
569
570 return EXIT_SUCCESS;
571 }
572
573 static void
usage(void)574 usage(void)
575 {
576 fprintf(stderr,
577 "usage:\t%s [-v] [-D] [-n] [-d device] [-m mode] [-r rate]\n"
578 "\t\t[-M mtu] [-V volume] [-f mode] [-b blocks] [-e bands]\n"
579 "\t\t[-A alloc] [-B bitpool] -a address files...\n"
580 "\t%s [-v] [-D] [-d device] [-m mode] [-p psm] [-B bitpool]\n"
581 "\t\t[-a address] [-M mtu] [-r rate] [-I] -K file\n"
582 "\t%s -t [-v] [-K] [-r rate] [-M mtu] [-V volume] [-f mode]\n"
583 "\t\t[-b blocks] [-e bands] [-A alloc] [-B bitpool] files...\n"
584 "Where:\n"
585 "\t-d device Local device address\n"
586 "\t-a address Remote device address\n"
587 "\tfiles... Files to read from (Defaults to stdin/stdout)\n"
588 "\t-v Verbose output\n"
589 "\t-D Run in the background\n"
590 "\t-M mtu MTU for transmission\n"
591 "\t-B bitpool Maximum bitpool value for encoding\n"
592 "\t-V volume Volume multiplier 0,1,2.\n"
593 "\t WARNING Can be VERY loud\n"
594 "\t-K Register as audio sink - Listens for incoming\n"
595 "\t connections.\n"
596 "\t-I Initiate DISCOVER - Used with audio sink\n"
597 "\t-m mode L2CAP link mode\n"
598 "\t-p psm Listens for incoming connections on psm\n"
599 "\t-t TEST MODE encodes from file to stdout or -K\n"
600 "\t read from stdin and decode to file/stdout.\n"
601 "\t Test mode does not communicate with bluetooth\n"
602 "\t only performs SBC de/encoding.\n"
603 "ENCODING OPTIONS:\n"
604 "\t-f mode\n"
605 "\t\t0 All input modes are accepted (only used with -K)\n"
606 "\t\t2 Input is dual channel\n"
607 "\t\tj Input is in joint stereo\n"
608 "\t\tm Input is mono\n"
609 "\t\ts Input is stereo (this is the default)\n"
610 "\t-r rate\n"
611 "\t\t0 All combinations of frequencies are accepted\n"
612 "\t\t16000 Encode with a rate of 16000Hz\n"
613 "\t\t32000 Encode with a rate of 32000Hz\n"
614 "\t\t44100 Encode with a rate of 44100Hz "
615 "(this is the default)\n"
616 "\t\t48000 Encode with a rate of 48000Hz\n"
617 "\t-b blocks\n"
618 "\t\t0 All combinations of blocks are accepted\n"
619 "\t\t4 Encode with 4 blocks\n"
620 "\t\t8 Encode with 8 blocks\n"
621 "\t\t12 Encode with 12 blocks\n"
622 "\t\t16 Encode with 16 blocks (this is the default)\n"
623 "\t-A alloc\n"
624 "\t\t0 All combinations of allocation methods are accepted\n"
625 "\t\tS Signal to Noise Ratio (SNR) bit allocation\n"
626 "\t\tL Loudness bit allocation (this is the default)\n"
627 "\n"
628 "\tWithout specifying any mode rate enoding and allocation\n"
629 "\tthe channel the default is stereo, 16 blocks, 8 subbands,\n"
630 "\tloudness bit allocation, 441000 Hz.\n"
631 , getprogname(), getprogname(), getprogname());
632
633 exit(EXIT_FAILURE);
634 }
635
636 static void
bt_exit(int fd)637 bt_exit(int fd)
638 {
639 if (!runasDaemon) {
640 close(fd);
641 fd = -1;
642 exit(1);
643 }
644 /* Not reached */
645 }
646
647 static void
do_ctlreq(int fd,short ev,void * arg)648 do_ctlreq(int fd, short ev, void *arg)
649 {
650 bool isCommand;
651 uint8_t sep, signal;
652 static struct sockaddr_bt addr;
653 size_t bufflen;
654 socklen_t len, mtusize;
655 static uint8_t trans;
656 uint8_t buff[1024];
657 static size_t offset = 0;
658 int result;
659
660 if(avdtpCheckResponse(fd, &isCommand, &trans, &signal, NULL, buff,
661 &bufflen, &sep) == ENOMEM) {
662 event_del(&ctl_ev);
663 close(fd);
664
665 if (asSpeaker) {
666 close(orighc);
667 orighc = -1;
668 event_del(&recv_ev);
669 } else
670 event_del(&interrupt_ev);
671
672 if (sc != -1)
673 close(sc);
674 sc = hc = -1;
675 state = 0;
676
677 return;
678 } else if (isCommand) {
679 switch (signal) {
680 case AVDTP_ABORT:
681 case AVDTP_CLOSE:
682 avdtpSendAccept(fd, fd, trans, signal);
683 if (asSpeaker) {
684 event_del(&recv_ev);
685 } else
686 event_del(&interrupt_ev);
687
688 if (sc != -1)
689 close(sc);
690 sc = -1;
691 state = 0;
692 break;
693 case AVDTP_DISCOVER:
694 avdtpSendDiscResponseAudio(fd, fd, trans,
695 (asSpeaker ? SNK_SEP : SRC_SEP), asSpeaker);
696 state = 1;
697 break;
698 case AVDTP_GET_CAPABILITIES:
699 avdtpSendCapabilitiesResponseSBC(fd, fd, trans,
700 (asSpeaker ? SNK_SEP : SRC_SEP), bitpool,
701 frequency , channel_mode, bands, blocks,
702 alloc_method);
703 state = 2;
704 break;
705 case AVDTP_SET_CONFIGURATION:
706 avdtpSendAccept(fd, fd, trans, signal);
707 state = 3;
708 break;
709 case AVDTP_OPEN:
710 avdtpSendAccept(fd, fd, trans, signal);
711 if (state < 5)
712 state = 5;
713 break;
714 case AVDTP_SUSPEND:
715 case AVDTP_START:
716 avdtpSendAccept(fd, fd, trans, signal);
717 if (state < 6)
718 state = 6;
719 break;
720 default:
721 avdtpSendReject(fd, fd, trans, signal);
722 }
723 if (verbose)
724 log_debug("Received command %d", signal);
725 } else {
726 switch (signal) {
727 case AVDTP_DISCOVER:
728 if (offset >= bufflen)
729 offset = 0;
730 avdtpDiscover(buff + offset, bufflen - offset,
731 &mySepInfo, !asSpeaker);
732 avdtpGetCapabilities(fd, fd, mySepInfo.sep);
733 break;
734 case AVDTP_GET_CAPABILITIES:
735 result = avdtpAutoConfigSBC(fd, fd, buff, bufflen,
736 mySepInfo.sep, &frequency, &channel_mode,
737 &alloc_method, &bitpool, &bands, &blocks,
738 (asSpeaker ? SNK_SEP : SRC_SEP));
739
740 if (result == EINVAL) {
741 offset += 2;
742 avdtpSendCommand(hc, AVDTP_DISCOVER, 0,
743 NULL, 0);
744 }
745
746 if (!result && verbose)
747 log_debug("Bitpool value = %d", bitpool);
748 state = 3;
749 break;
750 case AVDTP_SET_CONFIGURATION:
751 if (state == 3 && !asSpeaker)
752 avdtpOpen(fd, fd, mySepInfo.sep);
753 state = 4;
754 break;
755 case AVDTP_OPEN:
756 if (state == 4)
757 state = 5;
758 break;
759 case AVDTP_SUSPEND:
760 case AVDTP_START:
761 if (state < 6)
762 state = 6;
763 break;
764 default:
765 avdtpSendReject(fd, fd, trans, signal);
766 }
767 if (verbose)
768 log_debug("Responded to command %d", signal);
769 }
770
771
772 if (state < 5 || state > 7)
773 return;
774
775 if (asSpeaker && state == 6) {
776 len = sizeof(addr);
777 if ((sc = accept(orighc,(struct sockaddr*)&addr, &len)) < 0)
778 log_err(EXIT_FAILURE, "stream accept: %m");
779
780 }
781 if (state == 6)
782 goto opened_connection;
783
784 memset(&addr, 0, sizeof(addr));
785
786 addr.bt_len = sizeof(addr);
787 addr.bt_family = AF_BLUETOOTH;
788 bdaddr_copy(&addr.bt_bdaddr, &info.laddr);
789 addr.bt_psm = l2cap_psm;
790
791 sc = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
792 if (sc < 0)
793 return;
794
795 if (bind(sc, (struct sockaddr *)&addr, sizeof(addr)) < 0)
796 return;
797
798 if (setsockopt(sc, BTPROTO_L2CAP, SO_L2CAP_LM,
799 &l2cap_mode, sizeof(l2cap_mode)) == -1) {
800 log_err(EXIT_FAILURE, "Could not set link mode (0x%4.4x)",
801 l2cap_mode);
802 }
803
804 bdaddr_copy(&addr.bt_bdaddr, &info.raddr);
805 if (connect(sc,(struct sockaddr*)&addr, sizeof(addr)) < 0)
806 return;
807
808 if (!asSpeaker)
809 avdtpStart(fd, fd, mySepInfo.sep);
810
811 return;
812
813 opened_connection:
814 if (asSpeaker) {
815 event_set(&recv_ev, sc, EV_READ | EV_PERSIST, do_recv, NULL);
816 if (event_add(&recv_ev, NULL) < 0)
817 log_err(EXIT_FAILURE, "recv_ev: %m");
818 state = 7;
819 } else {
820 event_set(&interrupt_ev, audfile, EV_READ | EV_PERSIST,
821 do_interrupt, NULL);
822 if (event_add(&interrupt_ev, NULL) < 0)
823 log_err(EXIT_FAILURE, "interrupt_ev: %m");
824 state = 7;
825 }
826
827 mtusize = sizeof(uint16_t);
828 getsockopt(sc, BTPROTO_L2CAP, SO_L2CAP_OMTU, &mtu, &mtusize);
829 if (userset_mtu != 0 && userset_mtu > 100 && userset_mtu < mtu)
830 mtu = userset_mtu;
831 else if (userset_mtu == 0 && mtu >= 500)
832 mtu /= 2;
833 }
834
835 static void
do_recv(int fd,short ev,void * arg)836 do_recv(int fd, short ev, void *arg)
837 {
838 ssize_t len;
839
840 len = recvstream(fd, audfile);
841
842 if (verbose)
843 log_debug("Recving %zd bytes", len);
844
845 if (len < 0) {
846 event_del(&recv_ev);
847 bt_exit(fd);
848 }
849 }
850
851
852 static void
do_interrupt(int fd,short ev,void * arg)853 do_interrupt(int fd, short ev, void *arg)
854 {
855 static int currentFileInd = 0;
856 ssize_t len;
857
858 if (currentFileInd == 0)
859 currentFileInd = startFileInd;
860
861 len = stream(fd, sc, channel_mode, frequency, bands, blocks,
862 alloc_method, bitpool, mtu, volume);
863
864
865 next_file:
866 if (dontStop && len == -1)
867 usleep(1);
868 else if (len == -1 && currentFileInd >= numfiles -1) {
869 event_del(&interrupt_ev);
870 bt_exit(fd);
871 } else if (len == -1) {
872 close(fd);
873 currentFileInd++;
874 audfile = open(files2open[currentFileInd], O_RDONLY);
875 if (audfile < 0) {
876 log_warn("error opening file %s: %m",
877 files2open[currentFileInd]);
878 goto next_file;
879 }
880
881 event_del(&interrupt_ev);
882 event_set(&interrupt_ev, audfile, EV_READ |
883 EV_PERSIST, do_interrupt, NULL);
884 if (event_add(&interrupt_ev, NULL) < 0)
885 log_err(EXIT_FAILURE, "interrupt_ev: %m");
886 }
887
888 if (verbose)
889 log_debug("Streaming %zd bytes", len);
890 }
891
892 /*
893 * Initialise as an audio sink
894 */
895 static int
init_server(struct l2cap_info * myInfo)896 init_server(struct l2cap_info *myInfo)
897 {
898 struct sockaddr_bt addr;
899 socklen_t len;
900 int flags = O_WRONLY | O_CREAT;
901 static bool first_time = true;
902
903 if (atexit(exit_func))
904 log_err(EXIT_FAILURE, "atexit failed to initialize: %m");
905
906 if (numfiles == 0)
907 audfile = STDOUT_FILENO;
908 else if (numfiles > 1)
909 usage();
910 else {
911 if (first_time)
912 flags |= O_TRUNC;
913 else
914 flags |= O_APPEND;
915
916 first_time = false;
917
918 audfile = open(files2open[0], flags, 0600);
919 if (audfile < 0) {
920 log_err(EXIT_FAILURE, "error opening file %s: %m",
921 files2open[0]);
922 }
923 }
924 if (test_mode)
925 goto just_decode;
926
927 if (l2cap_psm == 0)
928 l2cap_psm = L2CAP_PSM_AVDTP;
929
930 sdp_set_uint(&sink_psm, l2cap_psm);
931
932 ss = sdp_open_local(NULL);
933 if (ss == NULL)
934 return -1;
935
936 if (!sdp_record_insert(ss, &myInfo->laddr, NULL, &sink_record)) {
937 sdp_close(ss);
938 return -1;
939 }
940
941 orighc = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
942 if (orighc < 0)
943 return -1;
944
945 memset(&addr, 0, sizeof(addr));
946 addr.bt_len = sizeof(addr);
947 addr.bt_family = AF_BLUETOOTH;
948 addr.bt_psm = l2cap_psm;
949 bdaddr_copy(&addr.bt_bdaddr, &myInfo->laddr);
950
951 if (bind(orighc, (struct sockaddr *)&addr, sizeof(addr)) < 0)
952 return -1;
953
954 if (setsockopt(orighc, BTPROTO_L2CAP, SO_L2CAP_LM,
955 &l2cap_mode, sizeof(l2cap_mode)) == -1) {
956 log_err(EXIT_FAILURE, "Could not set link mode (0x%4.4x)",
957 l2cap_mode);
958 }
959
960 bdaddr_copy(&addr.bt_bdaddr, &myInfo->raddr);
961 if (listen(orighc,0) < 0)
962 return -1;
963
964 len = sizeof(addr);
965 if ((hc = accept(orighc,(struct sockaddr*)&addr, &len)) < 0)
966 return -1;
967
968 if (initDiscover)
969 avdtpSendCommand(hc, AVDTP_DISCOVER, 0, NULL, 0);
970
971 event_set(&ctl_ev, hc, EV_READ | EV_PERSIST, do_ctlreq, NULL);
972 if (event_add(&ctl_ev, NULL) < 0)
973 log_err(EXIT_FAILURE, "ctl_ev: %m");
974
975 just_decode:
976 if (test_mode) {
977 if (userset_mtu)
978 mtu = userset_mtu;
979 sc = STDIN_FILENO;
980
981 event_set(&recv_ev, sc, EV_READ | EV_PERSIST, do_recv, NULL);
982 if (event_add(&recv_ev, NULL) < 0)
983 log_err(EXIT_FAILURE, "recv_ev: %m");
984 }
985
986 return 0;
987 }
988
989
990 /*
991 * Initialise as an audio source
992 */
993 static int
init_client(struct l2cap_info * myInfo)994 init_client(struct l2cap_info *myInfo)
995 {
996 struct sockaddr_bt addr;
997 int i;
998
999 if (atexit(exit_func))
1000 log_err(EXIT_FAILURE, "atexit failed to initialize: %m");
1001
1002 if (numfiles == 0)
1003 audfile = STDIN_FILENO;
1004 else {
1005 for (i = 0; i < numfiles; i++) {
1006 audfile = open(files2open[i], O_RDONLY);
1007 if (audfile < 0)
1008 log_warn("error opening file %s: %m",
1009 files2open[i]);
1010 else
1011 break;
1012 }
1013 startFileInd = i;
1014 if (startFileInd > numfiles - 1)
1015 log_err(EXIT_FAILURE, "error opening file%s",
1016 (numfiles > 1) ? "s":"");
1017 }
1018
1019 if (test_mode)
1020 goto just_encode;
1021
1022 if (l2cap_psm == 0)
1023 l2cap_psm = L2CAP_PSM_AVDTP;
1024
1025 sdp_set_uint(&source_psm, l2cap_psm);
1026
1027 ss = sdp_open_local(NULL);
1028 if (ss == NULL)
1029 return -1;
1030
1031 if (!sdp_record_insert(ss, &myInfo->laddr, NULL, &source_record)) {
1032 sdp_close(ss);
1033 return -1;
1034 }
1035
1036 client_query();
1037
1038 orighc = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_L2CAP);
1039 if (orighc < 0)
1040 return -1;
1041
1042 memset(&addr, 0, sizeof(addr));
1043 addr.bt_len = sizeof(addr);
1044 addr.bt_family = AF_BLUETOOTH;
1045 addr.bt_psm = l2cap_psm;
1046 bdaddr_copy(&addr.bt_bdaddr, &myInfo->laddr);
1047
1048 if (bind(orighc, (struct sockaddr *)&addr, sizeof(addr)) < 0)
1049 return -1;
1050
1051 if (setsockopt(orighc, BTPROTO_L2CAP, SO_L2CAP_LM,
1052 &l2cap_mode, sizeof(l2cap_mode)) == -1) {
1053 log_err(EXIT_FAILURE, "Could not set link mode (0x%4.4x)",
1054 l2cap_mode);
1055 }
1056
1057 bdaddr_copy(&addr.bt_bdaddr, &myInfo->raddr);
1058 if (connect(orighc,(struct sockaddr*)&addr, sizeof(addr)) < 0)
1059 return -1;
1060
1061 hc = orighc;
1062 avdtpSendCommand(hc, AVDTP_DISCOVER, 0, NULL, 0);
1063
1064 event_set(&ctl_ev, hc, EV_READ | EV_PERSIST, do_ctlreq, NULL);
1065 if (event_add(&ctl_ev, NULL) < 0)
1066 log_err(EXIT_FAILURE, "ctl_ev: %m");
1067
1068 just_encode:
1069 if (test_mode) {
1070 if (userset_mtu)
1071 mtu = userset_mtu;
1072 sc = STDOUT_FILENO;
1073 event_set(&interrupt_ev, audfile, EV_READ | EV_PERSIST,
1074 do_interrupt, NULL);
1075 if (event_add(&interrupt_ev, NULL) < 0)
1076 log_err(EXIT_FAILURE, "interrupt_ev: %m");
1077 }
1078
1079 return 0;
1080 }
1081
1082 static void
client_query(void)1083 client_query(void)
1084 {
1085 uint8_t buf[12]; /* enough for SSP and AIL both */
1086 sdp_session_t myss;
1087 sdp_data_t ssp, ail, rsp, rec, value, pdl, seq;
1088 uintmax_t psm, ver;
1089 uint16_t attr;
1090 bool rv;
1091
1092 myss = sdp_open(&info.laddr, &info.raddr);
1093 if (myss == NULL) {
1094 log_err(EXIT_FAILURE, "%s: Could not open sdp session",
1095 service_type);
1096 }
1097
1098 log_info("Searching for %s service at %s",
1099 service_type, bt_ntoa(&info.raddr, NULL));
1100
1101 seq.next = buf;
1102 seq.end = buf + sizeof(buf);
1103
1104 /*
1105 * build ServiceSearchPattern (9 bytes)
1106 *
1107 * uuid16 "service_class"
1108 * uuid16 L2CAP
1109 * uuid16 AVDTP
1110 */
1111 ssp.next = seq.next;
1112 sdp_put_uuid16(&seq, service_class);
1113 sdp_put_uuid16(&seq, SDP_UUID_PROTOCOL_L2CAP);
1114 sdp_put_uuid16(&seq, SDP_UUID_PROTOCOL_AVDTP);
1115 ssp.end = seq.next;
1116
1117 /*
1118 * build AttributeIDList (3 bytes)
1119 *
1120 * uint16 ProtocolDescriptorList
1121 */
1122 ail.next = seq.next;
1123 sdp_put_uint16(&seq, SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST);
1124 ail.end = seq.next;
1125
1126 rv = sdp_service_search_attribute(myss, &ssp, &ail, &rsp);
1127 if (!rv) {
1128 log_err(EXIT_FAILURE, "%s: Required sdp record not found",
1129 service_type);
1130 }
1131
1132 /*
1133 * we expect the response to contain a list of records
1134 * containing a ProtocolDescriptorList. Find the first
1135 * one containing L2CAP and AVDTP >= 1.0, and extract
1136 * the PSM.
1137 */
1138 rv = false;
1139 while (!rv && sdp_get_seq(&rsp, &rec)) {
1140 if (!sdp_get_attr(&rec, &attr, &value)
1141 || attr != SDP_ATTR_PROTOCOL_DESCRIPTOR_LIST)
1142 continue;
1143
1144 sdp_get_alt(&value, &value); /* drop any alt header */
1145 while (!rv && sdp_get_seq(&value, &pdl)) {
1146 if (sdp_get_seq(&pdl, &seq) &&
1147 sdp_match_uuid16(&seq, SDP_UUID_PROTOCOL_L2CAP) &&
1148 sdp_get_uint(&seq, &psm) &&
1149 sdp_get_seq(&pdl, &seq) &&
1150 sdp_match_uuid16(&seq, SDP_UUID_PROTOCOL_AVDTP) &&
1151 sdp_get_uint(&seq, &ver) && ver >= 0x0100)
1152 rv = true;
1153 }
1154 }
1155
1156 sdp_close(myss);
1157
1158 if (!rv) {
1159 log_err(EXIT_FAILURE, "%s query failed", service_type);
1160 }
1161
1162 l2cap_psm = (uint16_t)psm;
1163 log_info("Found PSM %u for service %s", l2cap_psm, service_type);
1164 }
1165
1166 static void
exit_func(void)1167 exit_func(void)
1168 {
1169 avdtpAbort(hc, hc, mySepInfo.sep);
1170 avdtpClose(hc, hc, mySepInfo.sep);
1171 close(sc);
1172 close(hc);
1173 sc = hc = -1;
1174 }
1175
1176