1 /* 2 * 3 * BlueZ - Bluetooth protocol stack for Linux 4 * 5 * Copyright (C) 2006-2010 Nokia Corporation 6 * Copyright (C) 2004-2010 Marcel Holtmann <marcel (at) holtmann.org> 7 * 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 22 * 23 */ 24 25 #ifdef HAVE_CONFIG_H 26 #include <config.h> 27 #endif 28 29 #include <stdlib.h> 30 #include <errno.h> 31 32 #include <dbus/dbus.h> 33 #include <glib.h> 34 35 #include <bluetooth/bluetooth.h> 36 #include <bluetooth/sdp.h> 37 #include <bluetooth/sdp_lib.h> 38 39 #include "log.h" 40 #include "device.h" 41 #include "manager.h" 42 #include "avdtp.h" 43 #include "sink.h" 44 #include "source.h" 45 #include "unix.h" 46 #include "a2dp.h" 47 #include "sdpd.h" 48 49 /* The duration that streams without users are allowed to stay in 50 * STREAMING state. */ 51 #define SUSPEND_TIMEOUT 5 52 #define RECONFIGURE_TIMEOUT 500 53 54 #ifndef MIN 55 # define MIN(x, y) ((x) < (y) ? (x) : (y)) 56 #endif 57 58 #ifndef MAX 59 # define MAX(x, y) ((x) > (y) ? (x) : (y)) 60 #endif 61 62 struct a2dp_sep { 63 uint8_t type; 64 uint8_t codec; 65 struct avdtp_local_sep *sep; 66 struct avdtp *session; 67 struct avdtp_stream *stream; 68 guint suspend_timer; 69 gboolean delay_reporting; 70 gboolean locked; 71 gboolean suspending; 72 gboolean starting; 73 }; 74 75 struct a2dp_setup_cb { 76 a2dp_config_cb_t config_cb; 77 a2dp_stream_cb_t resume_cb; 78 a2dp_stream_cb_t suspend_cb; 79 void *user_data; 80 unsigned int id; 81 }; 82 83 struct a2dp_setup { 84 struct audio_device *dev; 85 struct avdtp *session; 86 struct a2dp_sep *sep; 87 struct avdtp_stream *stream; 88 struct avdtp_error *err; 89 GSList *client_caps; 90 gboolean reconfigure; 91 gboolean start; 92 GSList *cb; 93 int ref; 94 }; 95 96 static DBusConnection *connection = NULL; 97 98 struct a2dp_server { 99 bdaddr_t src; 100 GSList *sinks; 101 GSList *sources; 102 uint32_t source_record_id; 103 uint32_t sink_record_id; 104 uint16_t version; 105 }; 106 107 static GSList *servers = NULL; 108 static GSList *setups = NULL; 109 static unsigned int cb_id = 0; 110 111 static struct a2dp_setup *setup_ref(struct a2dp_setup *setup) 112 { 113 setup->ref++; 114 115 DBG("%p: ref=%d", setup, setup->ref); 116 117 return setup; 118 } 119 120 static void setup_free(struct a2dp_setup *s) 121 { 122 DBG("%p", s); 123 setups = g_slist_remove(setups, s); 124 if (s->session) 125 avdtp_unref(s->session); 126 g_slist_foreach(s->cb, (GFunc) g_free, NULL); 127 g_slist_free(s->cb); 128 g_free(s); 129 } 130 131 static void setup_unref(struct a2dp_setup *setup) 132 { 133 setup->ref--; 134 135 DBG("%p: ref=%d", setup, setup->ref); 136 137 if (setup->ref <= 0) 138 setup_free(setup); 139 } 140 141 static struct audio_device *a2dp_get_dev(struct avdtp *session) 142 { 143 bdaddr_t src, dst; 144 145 avdtp_get_peers(session, &src, &dst); 146 147 return manager_find_device(NULL, &src, &dst, NULL, FALSE); 148 } 149 150 static gboolean finalize_config(struct a2dp_setup *s) 151 { 152 GSList *l; 153 154 setup_ref(s); 155 for (l = s->cb; l != NULL; l = l->next) { 156 struct a2dp_setup_cb *cb = l->data; 157 struct avdtp_stream *stream = s->err ? NULL : s->stream; 158 159 if (!cb->config_cb) 160 continue; 161 162 cb->config_cb(s->session, s->sep, stream, s->err, 163 cb->user_data); 164 cb->config_cb = NULL; 165 setup_unref(s); 166 } 167 168 setup_unref(s); 169 return FALSE; 170 } 171 172 static gboolean finalize_config_errno(struct a2dp_setup *s, int err) 173 { 174 struct avdtp_error avdtp_err; 175 176 avdtp_error_init(&avdtp_err, AVDTP_ERROR_ERRNO, -err); 177 s->err = err ? &avdtp_err : NULL; 178 179 return finalize_config(s); 180 } 181 182 static gboolean finalize_resume(struct a2dp_setup *s) 183 { 184 GSList *l; 185 186 setup_ref(s); 187 for (l = s->cb; l != NULL; l = l->next) { 188 struct a2dp_setup_cb *cb = l->data; 189 190 if (cb && cb->resume_cb) { 191 cb->resume_cb(s->session, s->err, cb->user_data); 192 cb->resume_cb = NULL; 193 setup_unref(s); 194 } 195 } 196 197 setup_unref(s); 198 return FALSE; 199 } 200 201 static gboolean finalize_suspend(struct a2dp_setup *s) 202 { 203 GSList *l; 204 205 setup_ref(s); 206 for (l = s->cb; l != NULL; l = l->next) { 207 struct a2dp_setup_cb *cb = l->data; 208 209 if (cb->suspend_cb) { 210 cb->suspend_cb(s->session, s->err, cb->user_data); 211 cb->suspend_cb = NULL; 212 setup_unref(s); 213 } 214 } 215 216 setup_unref(s); 217 return FALSE; 218 } 219 220 static gboolean finalize_suspend_errno(struct a2dp_setup *s, int err) 221 { 222 struct avdtp_error avdtp_err; 223 224 avdtp_error_init(&avdtp_err, AVDTP_ERROR_ERRNO, -err); 225 s->err = err ? &avdtp_err : NULL; 226 227 return finalize_suspend(s); 228 } 229 230 static struct a2dp_setup *find_setup_by_session(struct avdtp *session) 231 { 232 GSList *l; 233 234 for (l = setups; l != NULL; l = l->next) { 235 struct a2dp_setup *setup = l->data; 236 237 if (setup->session == session) 238 return setup; 239 } 240 241 return NULL; 242 } 243 244 static struct a2dp_setup *find_setup_by_dev(struct audio_device *dev) 245 { 246 GSList *l; 247 248 for (l = setups; l != NULL; l = l->next) { 249 struct a2dp_setup *setup = l->data; 250 251 if (setup->dev == dev) 252 return setup; 253 } 254 255 return NULL; 256 } 257 258 static void stream_state_changed(struct avdtp_stream *stream, 259 avdtp_state_t old_state, 260 avdtp_state_t new_state, 261 struct avdtp_error *err, 262 void *user_data) 263 { 264 struct a2dp_sep *sep = user_data; 265 266 if (new_state != AVDTP_STATE_IDLE) 267 return; 268 269 if (sep->suspend_timer) { 270 g_source_remove(sep->suspend_timer); 271 sep->suspend_timer = 0; 272 } 273 274 if (sep->session) { 275 avdtp_unref(sep->session); 276 sep->session = NULL; 277 } 278 279 sep->stream = NULL; 280 281 } 282 283 static gboolean sbc_setconf_ind(struct avdtp *session, 284 struct avdtp_local_sep *sep, 285 struct avdtp_stream *stream, 286 GSList *caps, uint8_t *err, 287 uint8_t *category, void *user_data) 288 { 289 struct a2dp_sep *a2dp_sep = user_data; 290 struct audio_device *dev; 291 292 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 293 DBG("Sink %p: Set_Configuration_Ind", sep); 294 else 295 DBG("Source %p: Set_Configuration_Ind", sep); 296 297 dev = a2dp_get_dev(session); 298 if (!dev) { 299 *err = AVDTP_UNSUPPORTED_CONFIGURATION; 300 *category = 0x00; 301 return FALSE; 302 } 303 304 /* Check valid settings */ 305 for (; caps != NULL; caps = g_slist_next(caps)) { 306 struct avdtp_service_capability *cap = caps->data; 307 struct avdtp_media_codec_capability *codec_cap; 308 struct sbc_codec_cap *sbc_cap; 309 310 if (cap->category == AVDTP_DELAY_REPORTING && 311 !a2dp_sep->delay_reporting) { 312 *err = AVDTP_UNSUPPORTED_CONFIGURATION; 313 *category = AVDTP_DELAY_REPORTING; 314 return FALSE; 315 } 316 317 if (cap->category != AVDTP_MEDIA_CODEC) 318 continue; 319 320 if (cap->length < sizeof(struct sbc_codec_cap)) 321 continue; 322 323 codec_cap = (void *) cap->data; 324 325 if (codec_cap->media_codec_type != A2DP_CODEC_SBC) 326 continue; 327 328 sbc_cap = (void *) codec_cap; 329 330 if (sbc_cap->min_bitpool < MIN_BITPOOL || 331 sbc_cap->max_bitpool > MAX_BITPOOL) { 332 *err = AVDTP_UNSUPPORTED_CONFIGURATION; 333 *category = AVDTP_MEDIA_CODEC; 334 return FALSE; 335 } 336 } 337 338 avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep); 339 a2dp_sep->stream = stream; 340 341 if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE) 342 sink_new_stream(dev, session, stream); 343 344 return TRUE; 345 } 346 347 static gboolean sbc_getcap_ind(struct avdtp *session, struct avdtp_local_sep *sep, 348 gboolean get_all, GSList **caps, uint8_t *err, 349 void *user_data) 350 { 351 struct a2dp_sep *a2dp_sep = user_data; 352 struct avdtp_service_capability *media_transport, *media_codec; 353 struct sbc_codec_cap sbc_cap; 354 355 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 356 DBG("Sink %p: Get_Capability_Ind", sep); 357 else 358 DBG("Source %p: Get_Capability_Ind", sep); 359 360 *caps = NULL; 361 362 media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT, 363 NULL, 0); 364 365 *caps = g_slist_append(*caps, media_transport); 366 367 memset(&sbc_cap, 0, sizeof(struct sbc_codec_cap)); 368 369 sbc_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO; 370 sbc_cap.cap.media_codec_type = A2DP_CODEC_SBC; 371 372 #ifdef ANDROID 373 sbc_cap.frequency = SBC_SAMPLING_FREQ_44100; 374 #else 375 sbc_cap.frequency = ( SBC_SAMPLING_FREQ_48000 | 376 SBC_SAMPLING_FREQ_44100 | 377 SBC_SAMPLING_FREQ_32000 | 378 SBC_SAMPLING_FREQ_16000 ); 379 #endif 380 381 sbc_cap.channel_mode = ( SBC_CHANNEL_MODE_JOINT_STEREO | 382 SBC_CHANNEL_MODE_STEREO | 383 SBC_CHANNEL_MODE_DUAL_CHANNEL | 384 SBC_CHANNEL_MODE_MONO ); 385 386 sbc_cap.block_length = ( SBC_BLOCK_LENGTH_16 | 387 SBC_BLOCK_LENGTH_12 | 388 SBC_BLOCK_LENGTH_8 | 389 SBC_BLOCK_LENGTH_4 ); 390 391 sbc_cap.subbands = ( SBC_SUBBANDS_8 | SBC_SUBBANDS_4 ); 392 393 sbc_cap.allocation_method = ( SBC_ALLOCATION_LOUDNESS | 394 SBC_ALLOCATION_SNR ); 395 396 sbc_cap.min_bitpool = MIN_BITPOOL; 397 sbc_cap.max_bitpool = MAX_BITPOOL; 398 399 media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &sbc_cap, 400 sizeof(sbc_cap)); 401 402 *caps = g_slist_append(*caps, media_codec); 403 404 if (get_all) { 405 struct avdtp_service_capability *delay_reporting; 406 delay_reporting = avdtp_service_cap_new(AVDTP_DELAY_REPORTING, 407 NULL, 0); 408 *caps = g_slist_append(*caps, delay_reporting); 409 } 410 411 return TRUE; 412 } 413 414 static gboolean mpeg_setconf_ind(struct avdtp *session, 415 struct avdtp_local_sep *sep, 416 struct avdtp_stream *stream, 417 GSList *caps, uint8_t *err, 418 uint8_t *category, void *user_data) 419 { 420 struct a2dp_sep *a2dp_sep = user_data; 421 struct audio_device *dev; 422 423 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 424 DBG("Sink %p: Set_Configuration_Ind", sep); 425 else 426 DBG("Source %p: Set_Configuration_Ind", sep); 427 428 dev = a2dp_get_dev(session); 429 if (!dev) { 430 *err = AVDTP_UNSUPPORTED_CONFIGURATION; 431 *category = 0x00; 432 return FALSE; 433 } 434 435 for (; caps != NULL; caps = g_slist_next(caps)) { 436 struct avdtp_service_capability *cap = caps->data; 437 438 if (cap->category == AVDTP_DELAY_REPORTING && 439 !a2dp_sep->delay_reporting) { 440 *err = AVDTP_UNSUPPORTED_CONFIGURATION; 441 *category = AVDTP_DELAY_REPORTING; 442 return FALSE; 443 } 444 } 445 446 avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep); 447 a2dp_sep->stream = stream; 448 449 if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE) 450 sink_new_stream(dev, session, stream); 451 452 return TRUE; 453 } 454 455 static gboolean mpeg_getcap_ind(struct avdtp *session, 456 struct avdtp_local_sep *sep, 457 gboolean get_all, 458 GSList **caps, uint8_t *err, void *user_data) 459 { 460 struct a2dp_sep *a2dp_sep = user_data; 461 struct avdtp_service_capability *media_transport, *media_codec; 462 struct mpeg_codec_cap mpeg_cap; 463 464 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 465 DBG("Sink %p: Get_Capability_Ind", sep); 466 else 467 DBG("Source %p: Get_Capability_Ind", sep); 468 469 *caps = NULL; 470 471 media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT, 472 NULL, 0); 473 474 *caps = g_slist_append(*caps, media_transport); 475 476 memset(&mpeg_cap, 0, sizeof(struct mpeg_codec_cap)); 477 478 mpeg_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO; 479 mpeg_cap.cap.media_codec_type = A2DP_CODEC_MPEG12; 480 481 mpeg_cap.frequency = ( MPEG_SAMPLING_FREQ_48000 | 482 MPEG_SAMPLING_FREQ_44100 | 483 MPEG_SAMPLING_FREQ_32000 | 484 MPEG_SAMPLING_FREQ_24000 | 485 MPEG_SAMPLING_FREQ_22050 | 486 MPEG_SAMPLING_FREQ_16000 ); 487 488 mpeg_cap.channel_mode = ( MPEG_CHANNEL_MODE_JOINT_STEREO | 489 MPEG_CHANNEL_MODE_STEREO | 490 MPEG_CHANNEL_MODE_DUAL_CHANNEL | 491 MPEG_CHANNEL_MODE_MONO ); 492 493 mpeg_cap.layer = ( MPEG_LAYER_MP3 | MPEG_LAYER_MP2 | MPEG_LAYER_MP1 ); 494 495 mpeg_cap.bitrate = 0xFFFF; 496 497 media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &mpeg_cap, 498 sizeof(mpeg_cap)); 499 500 *caps = g_slist_append(*caps, media_codec); 501 502 if (get_all) { 503 struct avdtp_service_capability *delay_reporting; 504 delay_reporting = avdtp_service_cap_new(AVDTP_DELAY_REPORTING, 505 NULL, 0); 506 *caps = g_slist_append(*caps, delay_reporting); 507 } 508 509 return TRUE; 510 } 511 512 static void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 513 struct avdtp_stream *stream, 514 struct avdtp_error *err, void *user_data) 515 { 516 struct a2dp_sep *a2dp_sep = user_data; 517 struct a2dp_setup *setup; 518 struct audio_device *dev; 519 int ret; 520 521 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 522 DBG("Sink %p: Set_Configuration_Cfm", sep); 523 else 524 DBG("Source %p: Set_Configuration_Cfm", sep); 525 526 setup = find_setup_by_session(session); 527 528 if (err) { 529 if (setup) { 530 setup->err = err; 531 finalize_config(setup); 532 } 533 return; 534 } 535 536 avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep); 537 a2dp_sep->stream = stream; 538 539 if (!setup) 540 return; 541 542 dev = a2dp_get_dev(session); 543 544 /* Notify D-Bus interface of the new stream */ 545 if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE) 546 sink_new_stream(dev, session, setup->stream); 547 else 548 source_new_stream(dev, session, setup->stream); 549 550 ret = avdtp_open(session, stream); 551 if (ret < 0) { 552 error("Error on avdtp_open %s (%d)", strerror(-ret), -ret); 553 setup->stream = NULL; 554 finalize_config_errno(setup, ret); 555 } 556 } 557 558 static gboolean getconf_ind(struct avdtp *session, struct avdtp_local_sep *sep, 559 uint8_t *err, void *user_data) 560 { 561 struct a2dp_sep *a2dp_sep = user_data; 562 563 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 564 DBG("Sink %p: Get_Configuration_Ind", sep); 565 else 566 DBG("Source %p: Get_Configuration_Ind", sep); 567 return TRUE; 568 } 569 570 static void getconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 571 struct avdtp_stream *stream, struct avdtp_error *err, 572 void *user_data) 573 { 574 struct a2dp_sep *a2dp_sep = user_data; 575 576 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 577 DBG("Sink %p: Set_Configuration_Cfm", sep); 578 else 579 DBG("Source %p: Set_Configuration_Cfm", sep); 580 } 581 582 static gboolean open_ind(struct avdtp *session, struct avdtp_local_sep *sep, 583 struct avdtp_stream *stream, uint8_t *err, 584 void *user_data) 585 { 586 struct a2dp_sep *a2dp_sep = user_data; 587 588 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 589 DBG("Sink %p: Open_Ind", sep); 590 else 591 DBG("Source %p: Open_Ind", sep); 592 return TRUE; 593 } 594 595 static void open_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 596 struct avdtp_stream *stream, struct avdtp_error *err, 597 void *user_data) 598 { 599 struct a2dp_sep *a2dp_sep = user_data; 600 struct a2dp_setup *setup; 601 602 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 603 DBG("Sink %p: Open_Cfm", sep); 604 else 605 DBG("Source %p: Open_Cfm", sep); 606 607 setup = find_setup_by_session(session); 608 if (!setup) 609 return; 610 611 if (setup->reconfigure) 612 setup->reconfigure = FALSE; 613 614 if (err) { 615 setup->stream = NULL; 616 setup->err = err; 617 } 618 619 finalize_config(setup); 620 } 621 622 static gboolean suspend_timeout(struct a2dp_sep *sep) 623 { 624 if (avdtp_suspend(sep->session, sep->stream) == 0) 625 sep->suspending = TRUE; 626 627 sep->suspend_timer = 0; 628 629 avdtp_unref(sep->session); 630 sep->session = NULL; 631 632 return FALSE; 633 } 634 635 static gboolean start_ind(struct avdtp *session, struct avdtp_local_sep *sep, 636 struct avdtp_stream *stream, uint8_t *err, 637 void *user_data) 638 { 639 struct a2dp_sep *a2dp_sep = user_data; 640 struct a2dp_setup *setup; 641 642 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 643 DBG("Sink %p: Start_Ind", sep); 644 else 645 DBG("Source %p: Start_Ind", sep); 646 647 setup = find_setup_by_session(session); 648 if (setup) 649 finalize_resume(setup); 650 651 if (!a2dp_sep->locked) { 652 a2dp_sep->session = avdtp_ref(session); 653 a2dp_sep->suspend_timer = g_timeout_add_seconds(SUSPEND_TIMEOUT, 654 (GSourceFunc) suspend_timeout, 655 a2dp_sep); 656 } 657 658 return TRUE; 659 } 660 661 static void start_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 662 struct avdtp_stream *stream, struct avdtp_error *err, 663 void *user_data) 664 { 665 struct a2dp_sep *a2dp_sep = user_data; 666 struct a2dp_setup *setup; 667 668 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 669 DBG("Sink %p: Start_Cfm", sep); 670 else 671 DBG("Source %p: Start_Cfm", sep); 672 673 setup = find_setup_by_session(session); 674 if (!setup) 675 return; 676 677 if (err) { 678 setup->stream = NULL; 679 setup->err = err; 680 } 681 682 finalize_resume(setup); 683 } 684 685 static gboolean suspend_ind(struct avdtp *session, struct avdtp_local_sep *sep, 686 struct avdtp_stream *stream, uint8_t *err, 687 void *user_data) 688 { 689 struct a2dp_sep *a2dp_sep = user_data; 690 691 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 692 DBG("Sink %p: Suspend_Ind", sep); 693 else 694 DBG("Source %p: Suspend_Ind", sep); 695 696 if (a2dp_sep->suspend_timer) { 697 g_source_remove(a2dp_sep->suspend_timer); 698 a2dp_sep->suspend_timer = 0; 699 avdtp_unref(a2dp_sep->session); 700 a2dp_sep->session = NULL; 701 } 702 703 return TRUE; 704 } 705 706 static void suspend_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 707 struct avdtp_stream *stream, struct avdtp_error *err, 708 void *user_data) 709 { 710 struct a2dp_sep *a2dp_sep = user_data; 711 struct a2dp_setup *setup; 712 gboolean start; 713 714 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 715 DBG("Sink %p: Suspend_Cfm", sep); 716 else 717 DBG("Source %p: Suspend_Cfm", sep); 718 719 a2dp_sep->suspending = FALSE; 720 721 setup = find_setup_by_session(session); 722 if (!setup) 723 return; 724 725 start = setup->start; 726 setup->start = FALSE; 727 728 if (err) { 729 setup->stream = NULL; 730 setup->err = err; 731 finalize_suspend(setup); 732 } 733 else 734 finalize_suspend_errno(setup, 0); 735 736 if (!start) 737 return; 738 739 if (err) { 740 setup->err = err; 741 finalize_suspend(setup); 742 } else if (avdtp_start(session, a2dp_sep->stream) < 0) { 743 struct avdtp_error start_err; 744 error("avdtp_start failed"); 745 avdtp_error_init(&start_err, AVDTP_ERROR_ERRNO, EIO); 746 setup->err = err; 747 finalize_suspend(setup); 748 } 749 } 750 751 static gboolean close_ind(struct avdtp *session, struct avdtp_local_sep *sep, 752 struct avdtp_stream *stream, uint8_t *err, 753 void *user_data) 754 { 755 struct a2dp_sep *a2dp_sep = user_data; 756 757 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 758 DBG("Sink %p: Close_Ind", sep); 759 else 760 DBG("Source %p: Close_Ind", sep); 761 762 return TRUE; 763 } 764 765 static gboolean a2dp_reconfigure(gpointer data) 766 { 767 struct a2dp_setup *setup = data; 768 struct avdtp_local_sep *lsep; 769 struct avdtp_remote_sep *rsep; 770 struct avdtp_service_capability *cap; 771 struct avdtp_media_codec_capability *codec_cap = NULL; 772 GSList *l; 773 int posix_err; 774 775 for (l = setup->client_caps; l != NULL; l = l->next) { 776 cap = l->data; 777 778 if (cap->category != AVDTP_MEDIA_CODEC) 779 continue; 780 781 codec_cap = (void *) cap->data; 782 break; 783 } 784 785 if (!codec_cap) { 786 error("Cannot find capabilities to reconfigure"); 787 posix_err = -EINVAL; 788 goto failed; 789 } 790 791 posix_err = avdtp_get_seps(setup->session, AVDTP_SEP_TYPE_SINK, 792 codec_cap->media_type, 793 codec_cap->media_codec_type, 794 &lsep, &rsep); 795 if (posix_err < 0) { 796 error("No matching ACP and INT SEPs found"); 797 goto failed; 798 } 799 800 posix_err = avdtp_set_configuration(setup->session, rsep, lsep, 801 setup->client_caps, 802 &setup->stream); 803 if (posix_err < 0) { 804 error("avdtp_set_configuration: %s", strerror(-posix_err)); 805 goto failed; 806 } 807 808 return FALSE; 809 810 failed: 811 finalize_config_errno(setup, posix_err); 812 return FALSE; 813 } 814 815 static void close_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 816 struct avdtp_stream *stream, struct avdtp_error *err, 817 void *user_data) 818 { 819 struct a2dp_sep *a2dp_sep = user_data; 820 struct a2dp_setup *setup; 821 822 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 823 DBG("Sink %p: Close_Cfm", sep); 824 else 825 DBG("Source %p: Close_Cfm", sep); 826 827 setup = find_setup_by_session(session); 828 if (!setup) 829 return; 830 831 if (err) { 832 setup->stream = NULL; 833 setup->err = err; 834 finalize_config(setup); 835 return; 836 } 837 838 if (setup->reconfigure) 839 g_timeout_add(RECONFIGURE_TIMEOUT, a2dp_reconfigure, setup); 840 } 841 842 static gboolean abort_ind(struct avdtp *session, struct avdtp_local_sep *sep, 843 struct avdtp_stream *stream, uint8_t *err, 844 void *user_data) 845 { 846 struct a2dp_sep *a2dp_sep = user_data; 847 848 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 849 DBG("Sink %p: Abort_Ind", sep); 850 else 851 DBG("Source %p: Abort_Ind", sep); 852 853 a2dp_sep->stream = NULL; 854 855 return TRUE; 856 } 857 858 static void abort_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 859 struct avdtp_stream *stream, struct avdtp_error *err, 860 void *user_data) 861 { 862 struct a2dp_sep *a2dp_sep = user_data; 863 struct a2dp_setup *setup; 864 865 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 866 DBG("Sink %p: Abort_Cfm", sep); 867 else 868 DBG("Source %p: Abort_Cfm", sep); 869 870 setup = find_setup_by_session(session); 871 if (!setup) 872 return; 873 874 setup_unref(setup); 875 } 876 877 static gboolean reconf_ind(struct avdtp *session, struct avdtp_local_sep *sep, 878 uint8_t *err, void *user_data) 879 { 880 struct a2dp_sep *a2dp_sep = user_data; 881 882 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 883 DBG("Sink %p: ReConfigure_Ind", sep); 884 else 885 DBG("Source %p: ReConfigure_Ind", sep); 886 887 return TRUE; 888 } 889 890 static gboolean delayreport_ind(struct avdtp *session, 891 struct avdtp_local_sep *sep, 892 uint8_t rseid, uint16_t delay, 893 uint8_t *err, void *user_data) 894 { 895 struct a2dp_sep *a2dp_sep = user_data; 896 struct audio_device *dev = a2dp_get_dev(session); 897 898 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 899 DBG("Sink %p: DelayReport_Ind", sep); 900 else 901 DBG("Source %p: DelayReport_Ind", sep); 902 903 unix_delay_report(dev, rseid, delay); 904 905 return TRUE; 906 } 907 908 static void reconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 909 struct avdtp_stream *stream, struct avdtp_error *err, 910 void *user_data) 911 { 912 struct a2dp_sep *a2dp_sep = user_data; 913 struct a2dp_setup *setup; 914 915 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 916 DBG("Sink %p: ReConfigure_Cfm", sep); 917 else 918 DBG("Source %p: ReConfigure_Cfm", sep); 919 920 setup = find_setup_by_session(session); 921 if (!setup) 922 return; 923 924 if (err) { 925 setup->stream = NULL; 926 setup->err = err; 927 } 928 929 finalize_config(setup); 930 } 931 932 static void delay_report_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 933 struct avdtp_stream *stream, 934 struct avdtp_error *err, void *user_data) 935 { 936 struct a2dp_sep *a2dp_sep = user_data; 937 938 if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 939 DBG("Sink %p: DelayReport_Cfm", sep); 940 else 941 DBG("Source %p: DelayReport_Cfm", sep); 942 } 943 944 static struct avdtp_sep_cfm cfm = { 945 .set_configuration = setconf_cfm, 946 .get_configuration = getconf_cfm, 947 .open = open_cfm, 948 .start = start_cfm, 949 .suspend = suspend_cfm, 950 .close = close_cfm, 951 .abort = abort_cfm, 952 .reconfigure = reconf_cfm, 953 .delay_report = delay_report_cfm, 954 }; 955 956 static struct avdtp_sep_ind sbc_ind = { 957 .get_capability = sbc_getcap_ind, 958 .set_configuration = sbc_setconf_ind, 959 .get_configuration = getconf_ind, 960 .open = open_ind, 961 .start = start_ind, 962 .suspend = suspend_ind, 963 .close = close_ind, 964 .abort = abort_ind, 965 .reconfigure = reconf_ind, 966 .delayreport = delayreport_ind, 967 }; 968 969 static struct avdtp_sep_ind mpeg_ind = { 970 .get_capability = mpeg_getcap_ind, 971 .set_configuration = mpeg_setconf_ind, 972 .get_configuration = getconf_ind, 973 .open = open_ind, 974 .start = start_ind, 975 .suspend = suspend_ind, 976 .close = close_ind, 977 .abort = abort_ind, 978 .reconfigure = reconf_ind, 979 .delayreport = delayreport_ind, 980 }; 981 982 static sdp_record_t *a2dp_record(uint8_t type, uint16_t avdtp_ver) 983 { 984 sdp_list_t *svclass_id, *pfseq, *apseq, *root; 985 uuid_t root_uuid, l2cap_uuid, avdtp_uuid, a2dp_uuid; 986 sdp_profile_desc_t profile[1]; 987 sdp_list_t *aproto, *proto[2]; 988 sdp_record_t *record; 989 sdp_data_t *psm, *version, *features; 990 uint16_t lp = AVDTP_UUID; 991 uint16_t a2dp_ver = 0x0102, feat = 0x000f; 992 993 #ifdef ANDROID 994 feat = 0x0001; 995 #endif 996 record = sdp_record_alloc(); 997 if (!record) 998 return NULL; 999 1000 sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); 1001 root = sdp_list_append(0, &root_uuid); 1002 sdp_set_browse_groups(record, root); 1003 1004 if (type == AVDTP_SEP_TYPE_SOURCE) 1005 sdp_uuid16_create(&a2dp_uuid, AUDIO_SOURCE_SVCLASS_ID); 1006 else 1007 sdp_uuid16_create(&a2dp_uuid, AUDIO_SINK_SVCLASS_ID); 1008 svclass_id = sdp_list_append(0, &a2dp_uuid); 1009 sdp_set_service_classes(record, svclass_id); 1010 1011 sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID); 1012 profile[0].version = a2dp_ver; 1013 pfseq = sdp_list_append(0, &profile[0]); 1014 sdp_set_profile_descs(record, pfseq); 1015 1016 sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID); 1017 proto[0] = sdp_list_append(0, &l2cap_uuid); 1018 psm = sdp_data_alloc(SDP_UINT16, &lp); 1019 proto[0] = sdp_list_append(proto[0], psm); 1020 apseq = sdp_list_append(0, proto[0]); 1021 1022 sdp_uuid16_create(&avdtp_uuid, AVDTP_UUID); 1023 proto[1] = sdp_list_append(0, &avdtp_uuid); 1024 version = sdp_data_alloc(SDP_UINT16, &avdtp_ver); 1025 proto[1] = sdp_list_append(proto[1], version); 1026 apseq = sdp_list_append(apseq, proto[1]); 1027 1028 aproto = sdp_list_append(0, apseq); 1029 sdp_set_access_protos(record, aproto); 1030 1031 features = sdp_data_alloc(SDP_UINT16, &feat); 1032 sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features); 1033 1034 if (type == AVDTP_SEP_TYPE_SOURCE) 1035 sdp_set_info_attr(record, "Audio Source", 0, 0); 1036 else 1037 sdp_set_info_attr(record, "Audio Sink", 0, 0); 1038 1039 free(psm); 1040 free(version); 1041 sdp_list_free(proto[0], 0); 1042 sdp_list_free(proto[1], 0); 1043 sdp_list_free(apseq, 0); 1044 sdp_list_free(pfseq, 0); 1045 sdp_list_free(aproto, 0); 1046 sdp_list_free(root, 0); 1047 sdp_list_free(svclass_id, 0); 1048 1049 return record; 1050 } 1051 1052 static struct a2dp_sep *a2dp_add_sep(struct a2dp_server *server, uint8_t type, 1053 uint8_t codec, gboolean delay_reporting) 1054 { 1055 struct a2dp_sep *sep; 1056 GSList **l; 1057 uint32_t *record_id; 1058 sdp_record_t *record; 1059 struct avdtp_sep_ind *ind; 1060 1061 sep = g_new0(struct a2dp_sep, 1); 1062 1063 ind = (codec == A2DP_CODEC_MPEG12) ? &mpeg_ind : &sbc_ind; 1064 sep->sep = avdtp_register_sep(&server->src, type, 1065 AVDTP_MEDIA_TYPE_AUDIO, codec, 1066 delay_reporting, ind, &cfm, sep); 1067 if (sep->sep == NULL) { 1068 g_free(sep); 1069 return NULL; 1070 } 1071 1072 sep->codec = codec; 1073 sep->type = type; 1074 sep->delay_reporting = delay_reporting; 1075 1076 if (type == AVDTP_SEP_TYPE_SOURCE) { 1077 l = &server->sources; 1078 record_id = &server->source_record_id; 1079 } else { 1080 l = &server->sinks; 1081 record_id = &server->sink_record_id; 1082 } 1083 1084 if (*record_id != 0) 1085 goto add; 1086 1087 record = a2dp_record(type, server->version); 1088 if (!record) { 1089 error("Unable to allocate new service record"); 1090 avdtp_unregister_sep(sep->sep); 1091 g_free(sep); 1092 return NULL; 1093 } 1094 1095 if (add_record_to_server(&server->src, record) < 0) { 1096 error("Unable to register A2DP service record");\ 1097 sdp_record_free(record); 1098 avdtp_unregister_sep(sep->sep); 1099 g_free(sep); 1100 return NULL; 1101 } 1102 *record_id = record->handle; 1103 1104 add: 1105 *l = g_slist_append(*l, sep); 1106 1107 return sep; 1108 } 1109 1110 static struct a2dp_server *find_server(GSList *list, const bdaddr_t *src) 1111 { 1112 GSList *l; 1113 1114 for (l = list; l; l = l->next) { 1115 struct a2dp_server *server = l->data; 1116 1117 if (bacmp(&server->src, src) == 0) 1118 return server; 1119 } 1120 1121 return NULL; 1122 } 1123 1124 int a2dp_register(DBusConnection *conn, const bdaddr_t *src, GKeyFile *config) 1125 { 1126 int sbc_srcs = 1, sbc_sinks = 1; 1127 int mpeg12_srcs = 0, mpeg12_sinks = 0; 1128 gboolean source = TRUE, sink = FALSE, delay_reporting; 1129 char *str; 1130 GError *err = NULL; 1131 int i; 1132 struct a2dp_server *server; 1133 1134 if (!config) 1135 goto proceed; 1136 1137 str = g_key_file_get_string(config, "General", "Enable", &err); 1138 1139 if (err) { 1140 DBG("audio.conf: %s", err->message); 1141 g_clear_error(&err); 1142 } else { 1143 if (strstr(str, "Sink")) 1144 source = TRUE; 1145 if (strstr(str, "Source")) 1146 sink = TRUE; 1147 g_free(str); 1148 } 1149 1150 str = g_key_file_get_string(config, "General", "Disable", &err); 1151 1152 if (err) { 1153 DBG("audio.conf: %s", err->message); 1154 g_clear_error(&err); 1155 } else { 1156 if (strstr(str, "Sink")) 1157 source = FALSE; 1158 if (strstr(str, "Source")) 1159 sink = FALSE; 1160 g_free(str); 1161 } 1162 1163 str = g_key_file_get_string(config, "A2DP", "SBCSources", &err); 1164 if (err) { 1165 DBG("audio.conf: %s", err->message); 1166 g_clear_error(&err); 1167 } else { 1168 sbc_srcs = atoi(str); 1169 g_free(str); 1170 } 1171 1172 str = g_key_file_get_string(config, "A2DP", "MPEG12Sources", &err); 1173 if (err) { 1174 DBG("audio.conf: %s", err->message); 1175 g_clear_error(&err); 1176 } else { 1177 mpeg12_srcs = atoi(str); 1178 g_free(str); 1179 } 1180 1181 str = g_key_file_get_string(config, "A2DP", "SBCSinks", &err); 1182 if (err) { 1183 DBG("audio.conf: %s", err->message); 1184 g_clear_error(&err); 1185 } else { 1186 sbc_sinks = atoi(str); 1187 g_free(str); 1188 } 1189 1190 str = g_key_file_get_string(config, "A2DP", "MPEG12Sinks", &err); 1191 if (err) { 1192 DBG("audio.conf: %s", err->message); 1193 g_clear_error(&err); 1194 } else { 1195 mpeg12_sinks = atoi(str); 1196 g_free(str); 1197 } 1198 1199 proceed: 1200 if (!connection) 1201 connection = dbus_connection_ref(conn); 1202 1203 server = find_server(servers, src); 1204 if (!server) { 1205 int av_err; 1206 1207 server = g_new0(struct a2dp_server, 1); 1208 if (!server) 1209 return -ENOMEM; 1210 1211 av_err = avdtp_init(src, config, &server->version); 1212 if (av_err < 0) { 1213 g_free(server); 1214 return av_err; 1215 } 1216 1217 bacpy(&server->src, src); 1218 servers = g_slist_append(servers, server); 1219 } 1220 1221 delay_reporting = g_key_file_get_boolean(config, "A2DP", 1222 "DelayReporting", NULL); 1223 if (delay_reporting) 1224 server->version = 0x0103; 1225 else 1226 server->version = 0x0102; 1227 1228 if (source) { 1229 for (i = 0; i < sbc_srcs; i++) 1230 a2dp_add_sep(server, AVDTP_SEP_TYPE_SOURCE, 1231 A2DP_CODEC_SBC, delay_reporting); 1232 1233 for (i = 0; i < mpeg12_srcs; i++) 1234 a2dp_add_sep(server, AVDTP_SEP_TYPE_SOURCE, 1235 A2DP_CODEC_MPEG12, delay_reporting); 1236 } 1237 1238 if (sink) { 1239 for (i = 0; i < sbc_sinks; i++) 1240 a2dp_add_sep(server, AVDTP_SEP_TYPE_SINK, 1241 A2DP_CODEC_SBC, delay_reporting); 1242 1243 for (i = 0; i < mpeg12_sinks; i++) 1244 a2dp_add_sep(server, AVDTP_SEP_TYPE_SINK, 1245 A2DP_CODEC_MPEG12, delay_reporting); 1246 } 1247 1248 return 0; 1249 } 1250 1251 static void a2dp_unregister_sep(struct a2dp_sep *sep) 1252 { 1253 avdtp_unregister_sep(sep->sep); 1254 g_free(sep); 1255 } 1256 1257 void a2dp_unregister(const bdaddr_t *src) 1258 { 1259 struct a2dp_server *server; 1260 1261 server = find_server(servers, src); 1262 if (!server) 1263 return; 1264 1265 g_slist_foreach(server->sinks, (GFunc) a2dp_unregister_sep, NULL); 1266 g_slist_free(server->sinks); 1267 1268 g_slist_foreach(server->sources, (GFunc) a2dp_unregister_sep, NULL); 1269 g_slist_free(server->sources); 1270 1271 avdtp_exit(src); 1272 1273 if (server->source_record_id) 1274 remove_record_from_server(server->source_record_id); 1275 1276 if (server->sink_record_id) 1277 remove_record_from_server(server->sink_record_id); 1278 1279 servers = g_slist_remove(servers, server); 1280 g_free(server); 1281 1282 if (servers) 1283 return; 1284 1285 dbus_connection_unref(connection); 1286 connection = NULL; 1287 } 1288 1289 struct a2dp_sep *a2dp_get(struct avdtp *session, 1290 struct avdtp_remote_sep *rsep) 1291 { 1292 GSList *l; 1293 struct a2dp_server *server; 1294 struct avdtp_service_capability *cap; 1295 struct avdtp_media_codec_capability *codec_cap = NULL; 1296 bdaddr_t src; 1297 1298 avdtp_get_peers(session, &src, NULL); 1299 server = find_server(servers, &src); 1300 if (!server) 1301 return NULL; 1302 1303 cap = avdtp_get_codec(rsep); 1304 codec_cap = (void *) cap->data; 1305 1306 if (avdtp_get_type(rsep) == AVDTP_SEP_TYPE_SINK) 1307 l = server->sources; 1308 else 1309 l = server->sinks; 1310 1311 for (; l != NULL; l = l->next) { 1312 struct a2dp_sep *sep = l->data; 1313 1314 if (sep->locked) 1315 continue; 1316 1317 if (sep->codec != codec_cap->media_codec_type) 1318 continue; 1319 1320 if (!sep->stream || avdtp_has_stream(session, sep->stream)) 1321 return sep; 1322 } 1323 1324 return NULL; 1325 } 1326 1327 unsigned int a2dp_config(struct avdtp *session, struct a2dp_sep *sep, 1328 a2dp_config_cb_t cb, GSList *caps, 1329 void *user_data) 1330 { 1331 struct a2dp_setup_cb *cb_data; 1332 GSList *l; 1333 struct a2dp_server *server; 1334 struct a2dp_setup *setup; 1335 struct a2dp_sep *tmp; 1336 struct avdtp_local_sep *lsep; 1337 struct avdtp_remote_sep *rsep; 1338 struct avdtp_service_capability *cap; 1339 struct avdtp_media_codec_capability *codec_cap = NULL; 1340 int posix_err; 1341 bdaddr_t src; 1342 uint8_t remote_type; 1343 1344 avdtp_get_peers(session, &src, NULL); 1345 server = find_server(servers, &src); 1346 if (!server) 1347 return 0; 1348 1349 for (l = caps; l != NULL; l = l->next) { 1350 cap = l->data; 1351 1352 if (cap->category != AVDTP_MEDIA_CODEC) 1353 continue; 1354 1355 codec_cap = (void *) cap->data; 1356 break; 1357 } 1358 1359 if (!codec_cap) 1360 return 0; 1361 1362 if (sep->codec != codec_cap->media_codec_type) 1363 return 0; 1364 1365 DBG("a2dp_config: selected SEP %p", sep->sep); 1366 1367 cb_data = g_new0(struct a2dp_setup_cb, 1); 1368 cb_data->config_cb = cb; 1369 cb_data->user_data = user_data; 1370 cb_data->id = ++cb_id; 1371 1372 setup = find_setup_by_session(session); 1373 if (!setup) { 1374 setup = g_new0(struct a2dp_setup, 1); 1375 setup->session = avdtp_ref(session); 1376 setup->dev = a2dp_get_dev(session); 1377 setups = g_slist_append(setups, setup); 1378 } 1379 1380 setup_ref(setup); 1381 setup->cb = g_slist_append(setup->cb, cb_data); 1382 setup->sep = sep; 1383 setup->stream = sep->stream; 1384 setup->client_caps = caps; 1385 1386 switch (avdtp_sep_get_state(sep->sep)) { 1387 case AVDTP_STATE_IDLE: 1388 if (sep->type == AVDTP_SEP_TYPE_SOURCE) { 1389 l = server->sources; 1390 remote_type = AVDTP_SEP_TYPE_SINK; 1391 } else { 1392 remote_type = AVDTP_SEP_TYPE_SOURCE; 1393 l = server->sinks; 1394 } 1395 1396 for (; l != NULL; l = l->next) { 1397 tmp = l->data; 1398 if (avdtp_has_stream(session, tmp->stream)) 1399 break; 1400 } 1401 1402 if (l != NULL) { 1403 setup->reconfigure = TRUE; 1404 if (avdtp_close(session, tmp->stream, FALSE) < 0) { 1405 error("avdtp_close failed"); 1406 goto failed; 1407 } 1408 break; 1409 } 1410 1411 if (avdtp_get_seps(session, remote_type, 1412 codec_cap->media_type, 1413 codec_cap->media_codec_type, 1414 &lsep, &rsep) < 0) { 1415 error("No matching ACP and INT SEPs found"); 1416 goto failed; 1417 } 1418 1419 posix_err = avdtp_set_configuration(session, rsep, lsep, 1420 caps, &setup->stream); 1421 if (posix_err < 0) { 1422 error("avdtp_set_configuration: %s", 1423 strerror(-posix_err)); 1424 goto failed; 1425 } 1426 break; 1427 case AVDTP_STATE_OPEN: 1428 case AVDTP_STATE_STREAMING: 1429 if (avdtp_stream_has_capabilities(setup->stream, caps)) { 1430 DBG("Configuration match: resuming"); 1431 g_idle_add((GSourceFunc) finalize_config, setup); 1432 } else if (!setup->reconfigure) { 1433 setup->reconfigure = TRUE; 1434 if (avdtp_close(session, sep->stream, FALSE) < 0) { 1435 error("avdtp_close failed"); 1436 goto failed; 1437 } 1438 } 1439 break; 1440 default: 1441 error("SEP in bad state for requesting a new stream"); 1442 goto failed; 1443 } 1444 1445 return cb_data->id; 1446 1447 failed: 1448 setup_unref(setup); 1449 cb_id--; 1450 return 0; 1451 } 1452 1453 unsigned int a2dp_resume(struct avdtp *session, struct a2dp_sep *sep, 1454 a2dp_stream_cb_t cb, void *user_data) 1455 { 1456 struct a2dp_setup_cb *cb_data; 1457 struct a2dp_setup *setup; 1458 1459 cb_data = g_new0(struct a2dp_setup_cb, 1); 1460 cb_data->resume_cb = cb; 1461 cb_data->user_data = user_data; 1462 cb_data->id = ++cb_id; 1463 1464 setup = find_setup_by_session(session); 1465 if (!setup) { 1466 setup = g_new0(struct a2dp_setup, 1); 1467 setup->session = avdtp_ref(session); 1468 setup->dev = a2dp_get_dev(session); 1469 setups = g_slist_append(setups, setup); 1470 } 1471 1472 setup_ref(setup); 1473 setup->cb = g_slist_append(setup->cb, cb_data); 1474 setup->sep = sep; 1475 setup->stream = sep->stream; 1476 1477 switch (avdtp_sep_get_state(sep->sep)) { 1478 case AVDTP_STATE_IDLE: 1479 goto failed; 1480 break; 1481 case AVDTP_STATE_OPEN: 1482 if (avdtp_start(session, sep->stream) < 0) { 1483 error("avdtp_start failed"); 1484 goto failed; 1485 } 1486 break; 1487 case AVDTP_STATE_STREAMING: 1488 if (!sep->suspending && sep->suspend_timer) { 1489 g_source_remove(sep->suspend_timer); 1490 sep->suspend_timer = 0; 1491 avdtp_unref(sep->session); 1492 sep->session = NULL; 1493 } 1494 if (sep->suspending) 1495 setup->start = TRUE; 1496 else 1497 g_idle_add((GSourceFunc) finalize_resume, setup); 1498 break; 1499 default: 1500 error("SEP in bad state for resume"); 1501 goto failed; 1502 } 1503 1504 return cb_data->id; 1505 1506 failed: 1507 setup_unref(setup); 1508 cb_id--; 1509 return 0; 1510 } 1511 1512 unsigned int a2dp_suspend(struct avdtp *session, struct a2dp_sep *sep, 1513 a2dp_stream_cb_t cb, void *user_data) 1514 { 1515 struct a2dp_setup_cb *cb_data; 1516 struct a2dp_setup *setup; 1517 1518 cb_data = g_new0(struct a2dp_setup_cb, 1); 1519 cb_data->suspend_cb = cb; 1520 cb_data->user_data = user_data; 1521 cb_data->id = ++cb_id; 1522 1523 setup = find_setup_by_session(session); 1524 if (!setup) { 1525 setup = g_new0(struct a2dp_setup, 1); 1526 setup->session = avdtp_ref(session); 1527 setup->dev = a2dp_get_dev(session); 1528 setups = g_slist_append(setups, setup); 1529 } 1530 1531 setup_ref(setup); 1532 setup->cb = g_slist_append(setup->cb, cb_data); 1533 setup->sep = sep; 1534 setup->stream = sep->stream; 1535 1536 switch (avdtp_sep_get_state(sep->sep)) { 1537 case AVDTP_STATE_IDLE: 1538 error("a2dp_suspend: no stream to suspend"); 1539 goto failed; 1540 break; 1541 case AVDTP_STATE_OPEN: 1542 g_idle_add((GSourceFunc) finalize_suspend, setup); 1543 break; 1544 case AVDTP_STATE_STREAMING: 1545 if (avdtp_suspend(session, sep->stream) < 0) { 1546 error("avdtp_suspend failed"); 1547 goto failed; 1548 } 1549 break; 1550 default: 1551 error("SEP in bad state for suspend"); 1552 goto failed; 1553 } 1554 1555 return cb_data->id; 1556 1557 failed: 1558 setup_unref(setup); 1559 cb_id--; 1560 return 0; 1561 } 1562 1563 gboolean a2dp_cancel(struct audio_device *dev, unsigned int id) 1564 { 1565 struct a2dp_setup_cb *cb_data; 1566 struct a2dp_setup *setup; 1567 GSList *l; 1568 1569 DBG("a2dp_cancel()"); 1570 1571 setup = find_setup_by_dev(dev); 1572 if (!setup) 1573 return FALSE; 1574 1575 for (cb_data = NULL, l = setup->cb; l != NULL; l = g_slist_next(l)) { 1576 struct a2dp_setup_cb *cb = l->data; 1577 1578 if (cb->id == id) { 1579 cb_data = cb; 1580 break; 1581 } 1582 } 1583 1584 if (!cb_data) 1585 error("a2dp_cancel: no matching callback with id %u", id); 1586 1587 setup->cb = g_slist_remove(setup->cb, cb_data); 1588 g_free(cb_data); 1589 1590 if (setup->cb) 1591 return TRUE; 1592 1593 avdtp_abort(setup->session, setup->stream); 1594 1595 return TRUE; 1596 } 1597 1598 gboolean a2dp_sep_lock(struct a2dp_sep *sep, struct avdtp *session) 1599 { 1600 if (sep->locked) 1601 return FALSE; 1602 1603 DBG("SEP %p locked", sep->sep); 1604 sep->locked = TRUE; 1605 1606 return TRUE; 1607 } 1608 1609 gboolean a2dp_sep_unlock(struct a2dp_sep *sep, struct avdtp *session) 1610 { 1611 avdtp_state_t state; 1612 1613 state = avdtp_sep_get_state(sep->sep); 1614 1615 sep->locked = FALSE; 1616 1617 DBG("SEP %p unlocked", sep->sep); 1618 1619 if (!sep->stream || state == AVDTP_STATE_IDLE) 1620 return TRUE; 1621 1622 switch (state) { 1623 case AVDTP_STATE_OPEN: 1624 /* Set timer here */ 1625 break; 1626 case AVDTP_STATE_STREAMING: 1627 if (avdtp_suspend(session, sep->stream) == 0) 1628 sep->suspending = TRUE; 1629 break; 1630 default: 1631 break; 1632 } 1633 1634 return TRUE; 1635 } 1636 1637 gboolean a2dp_sep_get_lock(struct a2dp_sep *sep) 1638 { 1639 return sep->locked; 1640 } 1641 1642 static int stream_cmp(gconstpointer data, gconstpointer user_data) 1643 { 1644 const struct a2dp_sep *sep = data; 1645 const struct avdtp_stream *stream = user_data; 1646 1647 return (sep->stream != stream); 1648 } 1649 1650 struct a2dp_sep *a2dp_get_sep(struct avdtp *session, 1651 struct avdtp_stream *stream) 1652 { 1653 struct a2dp_server *server; 1654 bdaddr_t src, dst; 1655 GSList *l; 1656 1657 avdtp_get_peers(session, &src, &dst); 1658 1659 for (l = servers; l; l = l->next) { 1660 server = l->data; 1661 1662 if (bacmp(&src, &server->src) == 0) 1663 break; 1664 } 1665 1666 if (!l) 1667 return NULL; 1668 1669 l = g_slist_find_custom(server->sources, stream, stream_cmp); 1670 if (l) 1671 return l->data; 1672 1673 l = g_slist_find_custom(server->sinks, stream, stream_cmp); 1674 if (l) 1675 return l->data; 1676 1677 return NULL; 1678 } 1679