1 /* $NetBSD: bta2dpd.c,v 1.10 2026/07/30 22:39:02 andvar Exp $ */ 2 3 /*- 4 * Copyright (c) 2015 - 2016 Nathanial Sloss <nathanialsloss (at) 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: bta2dpd.c,v 1.10 2026/07/30 22:39:02 andvar Exp $"); 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 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 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 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 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 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 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 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 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 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 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