1 /* $NetBSD$ */ 2 3 /*- 4 * Copyright (c) 2015-2016 Nathanial Sloss <nathanialsloss@yahoo.com.au> 5 * Copyright (c) 2016-2019 Hans Petter Selasky <hps@selasky.org> 6 * Copyright (c) 2019 Google LLC, written by Richard Kralovic <riso@google.com> 7 * 8 * This software is dedicated to the memory of - 9 * Baron James Anlezark (Barry) - 1 Jan 1949 - 13 May 2012. 10 * 11 * Barry was a man who loved his music. 12 * 13 * Redistribution and use in source and binary forms, with or without 14 * modification, are permitted provided that the following conditions 15 * are met: 16 * 1. Redistributions of source code must retain the above copyright 17 * notice, this list of conditions and the following disclaimer. 18 * 2. Redistributions in binary form must reproduce the above copyright 19 * notice, this list of conditions and the following disclaimer in the 20 * documentation and/or other materials provided with the distribution. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 23 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 24 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 25 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 26 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 27 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 28 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 29 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 30 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 31 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 32 * POSSIBILITY OF SUCH DAMAGE. 33 */ 34 35 #include <sys/uio.h> 36 37 #include <stdio.h> 38 #include <errno.h> 39 #include <stdlib.h> 40 #include <string.h> 41 #include <unistd.h> 42 43 #include "avdtp_signal.h" 44 #include "bt.h" 45 46 #define DPRINTF(...) printf("backend_bt: " __VA_ARGS__) 47 48 struct avdtpGetPacketInfo { 49 uint8_t buffer_data[512]; 50 uint16_t buffer_len; 51 uint8_t trans; 52 uint8_t signalID; 53 }; 54 55 static int avdtpAutoConfig(struct bt_config *); 56 57 /* Return received message type if success, < 0 if failure. */ 58 static int 59 avdtpGetPacket(int fd, struct avdtpGetPacketInfo *info) 60 { 61 uint8_t *pos = info->buffer_data; 62 uint8_t *end = info->buffer_data + sizeof(info->buffer_data); 63 uint8_t message_type; 64 int len; 65 66 memset(info, 0, sizeof(*info)); 67 68 /* Handle fragmented packets */ 69 for (int remaining = 1; remaining > 0; --remaining) { 70 len = read(fd, pos, end - pos); 71 72 if (len < AVDTP_LEN_SUCCESS) 73 return (-1); 74 if (len == (int)(end - pos)) 75 return (-1); /* buffer too small */ 76 77 uint8_t trans = (pos[0] & TRANSACTIONLABEL) >> TRANSACTIONLABEL_S; 78 uint8_t packet_type = (pos[0] & PACKETTYPE) >> PACKETTYPE_S; 79 uint8_t current_message_type = (info->buffer_data[0] & MESSAGETYPE); 80 uint8_t shift; 81 if (pos == info->buffer_data) { 82 info->trans = trans; 83 message_type = current_message_type; 84 if (packet_type == singlePacket) { 85 info->signalID = (pos[1] & SIGNALID_MASK); 86 shift = 2; 87 } else { 88 if (packet_type != startPacket) 89 return (-1); 90 remaining = pos[1]; 91 info->signalID = (pos[2] & SIGNALID_MASK); 92 shift = 3; 93 } 94 } else { 95 if (info->trans != trans || 96 message_type != current_message_type || 97 (remaining == 1 && packet_type != endPacket) || 98 (remaining > 1 && packet_type != continuePacket)) { 99 return (-1); 100 } 101 shift = 1; 102 } 103 memmove(pos, pos + shift, len); 104 pos += len; 105 } 106 info->buffer_len = pos - info->buffer_data; 107 return (message_type); 108 } 109 110 /* Returns 0 on success, < 0 on failure. */ 111 static int 112 avdtpSendPacket(int fd, uint8_t command, uint8_t trans, uint8_t type, 113 uint8_t * data0, int datasize0, uint8_t * data1, 114 int datasize1) 115 { 116 struct iovec iov[3]; 117 uint8_t header[2]; 118 int retval; 119 120 /* fill out command header */ 121 header[0] = (trans << 4) | (type & 3); 122 if (command != 0) 123 header[1] = command & 0x3f; 124 else 125 header[1] = 3; 126 127 iov[0].iov_base = header; 128 iov[0].iov_len = 2; 129 iov[1].iov_base = data0; 130 iov[1].iov_len = datasize0; 131 iov[2].iov_base = data1; 132 iov[2].iov_len = datasize1; 133 134 retval = writev(fd, iov, 3); 135 if (retval != (2 + datasize0 + datasize1)) 136 return (-EINVAL); 137 else 138 return (0); 139 } 140 141 /* Returns 0 on success, < 0 on failure. */ 142 static int 143 avdtpSendSyncCommand(int fd, struct avdtpGetPacketInfo *info, 144 uint8_t command, uint8_t type, uint8_t * data0, 145 int datasize0, uint8_t * data1, int datasize1) 146 { 147 static uint8_t transLabel; 148 uint8_t trans; 149 int retval; 150 151 alarm(8); /* set timeout */ 152 153 trans = (transLabel++) & 0xF; 154 155 retval = avdtpSendPacket(fd, command, trans, type, 156 data0, datasize0, data1, datasize1); 157 if (retval) 158 goto done; 159 retry: 160 switch (avdtpGetPacket(fd, info)) { 161 case RESPONSEACCEPT: 162 if (info->trans != trans) 163 goto retry; 164 retval = 0; 165 break; 166 case RESPONSEREJECT: 167 if (info->trans != trans) 168 goto retry; 169 retval = -EINVAL; 170 break; 171 case COMMAND: 172 retval = avdtpSendReject(fd, info->trans, info->signalID); 173 if (retval == 0) 174 goto retry; 175 break; 176 default: 177 retval = -ENXIO; 178 break; 179 } 180 done: 181 alarm(0); /* clear timeout */ 182 183 return (retval); 184 } 185 186 /* 187 * Variant for acceptor role: We support any frequency, blocks, bands, and 188 * allocation. Returns 0 on success, < 0 on failure. 189 */ 190 static int 191 avdtpSendCapabilitiesResponseSBCForACP(int fd, int trans) 192 { 193 uint8_t data[10]; 194 195 data[0] = mediaTransport; 196 data[1] = 0; 197 data[2] = mediaCodec; 198 data[3] = 0x6; 199 data[4] = mediaTypeAudio; 200 data[5] = SBC_CODEC_ID; 201 data[6] = 202 (1 << (3 - MODE_STEREO)) | 203 (1 << (3 - MODE_JOINT)) | 204 (1 << (3 - MODE_DUAL)) | 205 (1 << (3 - MODE_MONO)) | 206 (1 << (7 - FREQ_44_1K)) | 207 (1 << (7 - FREQ_48K)) | 208 (1 << (7 - FREQ_32K)) | 209 (1 << (7 - FREQ_16K)); 210 data[7] = 211 (1 << (7 - BLOCKS_4)) | 212 (1 << (7 - BLOCKS_8)) | 213 (1 << (7 - BLOCKS_12)) | 214 (1 << (7 - BLOCKS_16)) | 215 (1 << (3 - BANDS_4)) | 216 (1 << (3 - BANDS_8)) | (1 << ALLOC_LOUDNESS) | (1 << ALLOC_SNR); 217 data[8] = MIN_BITPOOL; 218 data[9] = DEFAULT_MAXBPOOL; 219 220 return (avdtpSendPacket(fd, AVDTP_GET_CAPABILITIES, trans, 221 RESPONSEACCEPT, data, sizeof(data), NULL, 0)); 222 } 223 224 /* Returns 0 on success, < 0 on failure. */ 225 int 226 avdtpSendAccept(int fd, uint8_t trans, uint8_t myCommand) 227 { 228 return (avdtpSendPacket(fd, myCommand, trans, RESPONSEACCEPT, 229 NULL, 0, NULL, 0)); 230 } 231 232 /* Returns 0 on success, < 0 on failure. */ 233 int 234 avdtpSendReject(int fd, uint8_t trans, uint8_t myCommand) 235 { 236 uint8_t value = 0; 237 238 return (avdtpSendPacket(fd, myCommand, trans, RESPONSEREJECT, 239 &value, 1, NULL, 0)); 240 } 241 242 /* Returns 0 on success, < 0 on failure. */ 243 int 244 avdtpSendDiscResponseAudio(int fd, uint8_t trans, 245 uint8_t mySep, uint8_t is_sink) 246 { 247 uint8_t data[2]; 248 249 data[0] = mySep << 2; 250 data[1] = mediaTypeAudio << 4 | (is_sink ? (1 << 3) : 0); 251 252 return (avdtpSendPacket(fd, AVDTP_DISCOVER, trans, RESPONSEACCEPT, 253 data, 2, NULL, 0)); 254 } 255 256 /* Returns 0 on success, < 0 on failure. */ 257 int 258 avdtpDiscoverAndConfig(struct bt_config *cfg, bool isSink) 259 { 260 struct avdtpGetPacketInfo info; 261 uint16_t offset; 262 uint8_t chmode = cfg->chmode; 263 uint8_t aacMode1 = cfg->aacMode1; 264 uint8_t aacMode2 = cfg->aacMode2; 265 int retval; 266 267 retval = avdtpSendSyncCommand(cfg->hc, &info, AVDTP_DISCOVER, 0, 268 NULL, 0, NULL, 0); 269 if (retval) 270 return (retval); 271 272 retval = -EBUSY; 273 for (offset = 0; offset + 2 <= info.buffer_len; offset += 2) { 274 cfg->sep = info.buffer_data[offset] >> 2; 275 cfg->media_Type = info.buffer_data[offset + 1] >> 4; 276 cfg->chmode = chmode; 277 cfg->aacMode1 = aacMode1; 278 cfg->aacMode2 = aacMode2; 279 if (info.buffer_data[offset] & DISCOVER_SEP_IN_USE) 280 continue; 281 if (info.buffer_data[offset + 1] & DISCOVER_IS_SINK) { 282 if (!isSink) 283 continue; 284 } else { 285 if (isSink) 286 continue; 287 } 288 /* try to configure SBC */ 289 retval = avdtpAutoConfig(cfg); 290 if (retval == 0) 291 return (0); 292 } 293 return (retval); 294 } 295 296 /* Returns 0 on success, < 0 on failure. */ 297 static int 298 avdtpGetCapabilities(int fd, uint8_t sep, struct avdtpGetPacketInfo *info) 299 { 300 uint8_t address = (sep << 2); 301 302 return (avdtpSendSyncCommand(fd, info, 303 AVDTP_GET_CAPABILITIES, 0, &address, 1, 304 NULL, 0)); 305 } 306 307 /* Returns 0 on success, < 0 on failure. */ 308 int 309 avdtpSetConfiguration(int fd, uint8_t sep, uint8_t * data, int datasize) 310 { 311 struct avdtpGetPacketInfo info; 312 uint8_t configAddresses[2]; 313 314 configAddresses[0] = sep << 2; 315 configAddresses[1] = INTSEP << 2; 316 317 return (avdtpSendSyncCommand(fd, &info, AVDTP_SET_CONFIGURATION, 0, 318 configAddresses, 2, data, datasize)); 319 } 320 321 /* Returns 0 on success, < 0 on failure. */ 322 int 323 avdtpOpen(int fd, uint8_t sep) 324 { 325 struct avdtpGetPacketInfo info; 326 uint8_t address = sep << 2; 327 328 return (avdtpSendSyncCommand(fd, &info, AVDTP_OPEN, 0, 329 &address, 1, NULL, 0)); 330 } 331 332 /* Returns 0 on success, < 0 on failure. */ 333 int 334 avdtpStart(int fd, uint8_t sep) 335 { 336 struct avdtpGetPacketInfo info; 337 uint8_t address = sep << 2; 338 339 return (avdtpSendSyncCommand(fd, &info, AVDTP_START, 0, 340 &address, 1, NULL, 0)); 341 } 342 343 /* Returns 0 on success, < 0 on failure. */ 344 int 345 avdtpClose(int fd, uint8_t sep) 346 { 347 struct avdtpGetPacketInfo info; 348 uint8_t address = sep << 2; 349 350 return (avdtpSendSyncCommand(fd, &info, AVDTP_CLOSE, 0, 351 &address, 1, NULL, 0)); 352 } 353 354 /* Returns 0 on success, < 0 on failure. */ 355 int 356 avdtpSuspend(int fd, uint8_t sep) 357 { 358 struct avdtpGetPacketInfo info; 359 uint8_t address = sep << 2; 360 361 return (avdtpSendSyncCommand(fd, &info, AVDTP_SUSPEND, 0, 362 &address, 1, NULL, 0)); 363 } 364 365 /* Returns 0 on success, < 0 on failure. */ 366 int 367 avdtpAbort(int fd, uint8_t sep) 368 { 369 struct avdtpGetPacketInfo info; 370 uint8_t address = sep << 2; 371 372 return (avdtpSendSyncCommand(fd, &info, AVDTP_ABORT, 0, 373 &address, 1, NULL, 0)); 374 } 375 376 static int 377 avdtpAutoConfig(struct bt_config *cfg) 378 { 379 struct avdtpGetPacketInfo info; 380 uint8_t freqmode; 381 uint8_t blk_len_sb_alloc; 382 uint8_t availFreqMode = 0; 383 uint8_t availConfig = 0; 384 uint8_t supBitpoolMin = 0; 385 uint8_t supBitpoolMax = 0; 386 uint8_t aacMode1 = 0; 387 uint8_t aacMode2 = 0; 388 #ifdef HAVE_LIBAV 389 uint8_t aacBitrate3 = 0; 390 uint8_t aacBitrate4 = 0; 391 uint8_t aacBitrate5 = 0; 392 #endif 393 int retval; 394 int i; 395 396 retval = avdtpGetCapabilities(cfg->hc, cfg->sep, &info); 397 if (retval) { 398 DPRINTF("Cannot get capabilities\n"); 399 return (retval); 400 } 401 retry: 402 for (i = 0; (i + 1) < info.buffer_len;) { 403 #if 0 404 DPRINTF("0x%x 0x%x 0x%x 0x%x 0x%x 0x%x\n", 405 info.buffer_data[i + 0], 406 info.buffer_data[i + 1], 407 info.buffer_data[i + 2], 408 info.buffer_data[i + 3], 409 info.buffer_data[i + 4], info.buffer_data[i + 5]); 410 #endif 411 if (i + 2 + info.buffer_data[i + 1] > info.buffer_len) 412 break; 413 switch (info.buffer_data[i]) { 414 case mediaTransport: 415 break; 416 case mediaCodec: 417 if (info.buffer_data[i + 1] < 2) 418 break; 419 /* check codec */ 420 switch (info.buffer_data[i + 3]) { 421 case 0: /* SBC */ 422 if (info.buffer_data[i + 1] < 6) 423 break; 424 availFreqMode = info.buffer_data[i + 4]; 425 availConfig = info.buffer_data[i + 5]; 426 supBitpoolMin = info.buffer_data[i + 6]; 427 supBitpoolMax = info.buffer_data[i + 7]; 428 break; 429 case 2: /* MPEG2/4 AAC */ 430 if (info.buffer_data[i + 1] < 8) 431 break; 432 aacMode1 = info.buffer_data[i + 5]; 433 aacMode2 = info.buffer_data[i + 6]; 434 #ifdef HAVE_LIBAV 435 aacBitrate3 = info.buffer_data[i + 7]; 436 aacBitrate4 = info.buffer_data[i + 8]; 437 aacBitrate5 = info.buffer_data[i + 9]; 438 #endif 439 break; 440 default: 441 break; 442 } 443 } 444 /* jump to next information element */ 445 i += 2 + info.buffer_data[i + 1]; 446 } 447 aacMode1 &= cfg->aacMode1; 448 aacMode2 &= cfg->aacMode2; 449 450 /* Try AAC first */ 451 if (aacMode1 == cfg->aacMode1 && aacMode2 == cfg->aacMode2) { 452 #ifdef HAVE_LIBAV 453 uint8_t config[12] = { mediaTransport, 0x0, mediaCodec, 454 0x8, 0x0, 0x02, 0x80, aacMode1, aacMode2, aacBitrate3, 455 aacBitrate4, aacBitrate5 456 }; 457 458 if (avdtpSetConfiguration 459 (cfg->hc, cfg->sep, config, sizeof(config)) == 0) { 460 cfg->codec = CODEC_AAC; 461 return (0); 462 } 463 #endif 464 } 465 /* Try SBC second */ 466 if (cfg->freq == FREQ_UNDEFINED) 467 goto auto_config_failed; 468 469 freqmode = (1 << (3 - cfg->freq + 4)) | (1 << (3 - cfg->chmode)); 470 471 if ((availFreqMode & freqmode) != freqmode) { 472 DPRINTF("No frequency and mode match\n"); 473 goto auto_config_failed; 474 } 475 for (i = 0; i != 4; i++) { 476 blk_len_sb_alloc = (1 << (i + 4)) | 477 (1 << (1 - cfg->bands + 2)) | (1 << cfg->allocm); 478 479 if ((availConfig & blk_len_sb_alloc) == blk_len_sb_alloc) 480 break; 481 } 482 if (i == 4) { 483 DPRINTF("No bands available\n"); 484 goto auto_config_failed; 485 } 486 cfg->blocks = (3 - i); 487 488 if (cfg->allocm == ALLOC_SNR) 489 supBitpoolMax &= ~1; 490 491 if (cfg->chmode == MODE_DUAL || cfg->chmode == MODE_MONO) 492 supBitpoolMax /= 2; 493 494 if (cfg->bands == BANDS_4) 495 supBitpoolMax /= 2; 496 497 if (supBitpoolMax > cfg->bitpool) 498 supBitpoolMax = cfg->bitpool; 499 else 500 cfg->bitpool = supBitpoolMax; 501 502 do { 503 uint8_t config[10] = { mediaTransport, 0x0, mediaCodec, 0x6, 504 0x0, 0x0, freqmode, blk_len_sb_alloc, supBitpoolMin, 505 supBitpoolMax 506 }; 507 508 if (avdtpSetConfiguration 509 (cfg->hc, cfg->sep, config, sizeof(config)) == 0) { 510 cfg->codec = CODEC_SBC; 511 return (0); 512 } 513 } while (0); 514 515 auto_config_failed: 516 if (cfg->chmode == MODE_STEREO) { 517 cfg->chmode = MODE_MONO; 518 cfg->aacMode2 ^= 0x0C; 519 goto retry; 520 } 521 return (-EINVAL); 522 } 523 524 void 525 avdtpACPFree(struct bt_config *cfg) 526 { 527 if (cfg->handle.sbc_enc) { 528 free(cfg->handle.sbc_enc); 529 cfg->handle.sbc_enc = NULL; 530 } 531 } 532 533 /* Returns 0 on success, < 0 on failure. */ 534 static int 535 avdtpParseSBCConfig(uint8_t * data, struct bt_config *cfg) 536 { 537 if (data[0] & (1 << (7 - FREQ_48K))) { 538 cfg->freq = FREQ_48K; 539 } else if (data[0] & (1 << (7 - FREQ_44_1K))) { 540 cfg->freq = FREQ_44_1K; 541 } else if (data[0] & (1 << (7 - FREQ_32K))) { 542 cfg->freq = FREQ_32K; 543 } else if (data[0] & (1 << (7 - FREQ_16K))) { 544 cfg->freq = FREQ_16K; 545 } else { 546 return -EINVAL; 547 } 548 549 if (data[0] & (1 << (3 - MODE_STEREO))) { 550 cfg->chmode = MODE_STEREO; 551 } else if (data[0] & (1 << (3 - MODE_JOINT))) { 552 cfg->chmode = MODE_JOINT; 553 } else if (data[0] & (1 << (3 - MODE_DUAL))) { 554 cfg->chmode = MODE_DUAL; 555 } else if (data[0] & (1 << (3 - MODE_MONO))) { 556 cfg->chmode = MODE_MONO; 557 } else { 558 return -EINVAL; 559 } 560 561 if (data[1] & (1 << (7 - BLOCKS_16))) { 562 cfg->blocks = BLOCKS_16; 563 } else if (data[1] & (1 << (7 - BLOCKS_12))) { 564 cfg->blocks = BLOCKS_12; 565 } else if (data[1] & (1 << (7 - BLOCKS_8))) { 566 cfg->blocks = BLOCKS_8; 567 } else if (data[1] & (1 << (7 - BLOCKS_4))) { 568 cfg->blocks = BLOCKS_4; 569 } else { 570 return -EINVAL; 571 } 572 573 if (data[1] & (1 << (3 - BANDS_8))) { 574 cfg->bands = BANDS_8; 575 } else if (data[1] & (1 << (3 - BANDS_4))) { 576 cfg->bands = BANDS_4; 577 } else { 578 return -EINVAL; 579 } 580 581 if (data[1] & (1 << ALLOC_LOUDNESS)) { 582 cfg->allocm = ALLOC_LOUDNESS; 583 } else if (data[1] & (1 << ALLOC_SNR)) { 584 cfg->allocm = ALLOC_SNR; 585 } else { 586 return -EINVAL; 587 } 588 cfg->bitpool = data[3]; 589 return 0; 590 } 591 592 int 593 avdtpACPHandlePacket(struct bt_config *cfg) 594 { 595 struct avdtpGetPacketInfo info; 596 int retval; 597 598 if (avdtpGetPacket(cfg->hc, &info) != COMMAND) 599 return (-ENXIO); 600 601 switch (info.signalID) { 602 case AVDTP_DISCOVER: 603 retval = 604 avdtpSendDiscResponseAudio(cfg->hc, info.trans, ACPSEP, 1); 605 if (!retval) 606 retval = AVDTP_DISCOVER; 607 break; 608 case AVDTP_GET_CAPABILITIES: 609 retval = 610 avdtpSendCapabilitiesResponseSBCForACP(cfg->hc, info.trans); 611 if (!retval) 612 retval = AVDTP_GET_CAPABILITIES; 613 break; 614 case AVDTP_SET_CONFIGURATION: 615 if (cfg->acceptor_state != acpInitial) 616 goto err; 617 cfg->sep = info.buffer_data[1] >> 2; 618 int is_configured = 0; 619 for (int i = 2; (i + 1) < info.buffer_len;) { 620 if (i + 2 + info.buffer_data[i + 1] > info.buffer_len) 621 break; 622 switch (info.buffer_data[i]) { 623 case mediaTransport: 624 break; 625 case mediaCodec: 626 if (info.buffer_data[i + 1] < 2) 627 break; 628 /* check codec */ 629 switch (info.buffer_data[i + 3]) { 630 case 0: /* SBC */ 631 if (info.buffer_data[i + 1] < 6) 632 break; 633 retval = 634 avdtpParseSBCConfig(info.buffer_data + i + 4, cfg); 635 if (retval) 636 return retval; 637 is_configured = 1; 638 break; 639 case 2: /* MPEG2/4 AAC */ 640 /* TODO: Add support */ 641 default: 642 break; 643 } 644 } 645 /* jump to next information element */ 646 i += 2 + info.buffer_data[i + 1]; 647 } 648 if (!is_configured) 649 goto err; 650 651 retval = 652 avdtpSendAccept(cfg->hc, info.trans, AVDTP_SET_CONFIGURATION); 653 if (retval) 654 return (retval); 655 656 /* TODO: Handle other codecs */ 657 if (cfg->handle.sbc_enc == NULL) { 658 cfg->handle.sbc_enc = malloc(sizeof(*cfg->handle.sbc_enc)); 659 if (cfg->handle.sbc_enc == NULL) 660 return (-ENOMEM); 661 } 662 memset(cfg->handle.sbc_enc, 0, sizeof(*cfg->handle.sbc_enc)); 663 664 retval = AVDTP_SET_CONFIGURATION; 665 cfg->acceptor_state = acpConfigurationSet; 666 break; 667 case AVDTP_OPEN: 668 if (cfg->acceptor_state != acpConfigurationSet) 669 goto err; 670 retval = avdtpSendAccept(cfg->hc, info.trans, info.signalID); 671 if (retval) 672 return (retval); 673 retval = info.signalID; 674 cfg->acceptor_state = acpStreamOpened; 675 break; 676 case AVDTP_START: 677 if (cfg->acceptor_state != acpStreamOpened && 678 cfg->acceptor_state != acpStreamSuspended) { 679 goto err; 680 } 681 retval = avdtpSendAccept(cfg->hc, info.trans, info.signalID); 682 if (retval) 683 return retval; 684 retval = info.signalID; 685 cfg->acceptor_state = acpStreamStarted; 686 break; 687 case AVDTP_CLOSE: 688 if (cfg->acceptor_state != acpStreamOpened && 689 cfg->acceptor_state != acpStreamStarted && 690 cfg->acceptor_state != acpStreamSuspended) { 691 goto err; 692 } 693 retval = avdtpSendAccept(cfg->hc, info.trans, info.signalID); 694 if (retval) 695 return (retval); 696 retval = info.signalID; 697 cfg->acceptor_state = acpStreamClosed; 698 break; 699 case AVDTP_SUSPEND: 700 if (cfg->acceptor_state != acpStreamOpened && 701 cfg->acceptor_state != acpStreamStarted) { 702 goto err; 703 } 704 retval = avdtpSendAccept(cfg->hc, info.trans, info.signalID); 705 if (retval) 706 return (retval); 707 retval = info.signalID; 708 cfg->acceptor_state = acpStreamSuspended; 709 break; 710 case AVDTP_GET_CONFIGURATION: 711 case AVDTP_RECONFIGURE: 712 case AVDTP_ABORT: 713 /* TODO: Implement this. */ 714 default: 715 err: 716 avdtpSendReject(cfg->hc, info.trans, info.signalID); 717 return (-ENXIO); 718 } 719 return (retval); 720 } 721