xref: /netbsd-src/usr.sbin/bta2dpd/bta2dpd/bta2dpd.c (revision a838dcd9d31947db40a955b03c45260c6a7dbec2)
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