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 <stdio.h> 30 #include <errno.h> 31 #include <unistd.h> 32 #include <sys/stat.h> 33 #include <sys/param.h> 34 #include <netinet/in.h> 35 36 #include <bluetooth/bluetooth.h> 37 #include <bluetooth/hci.h> 38 #include <bluetooth/hci_lib.h> 39 #include <bluetooth/sdp.h> 40 #include <bluetooth/sdp_lib.h> 41 42 #include <glib.h> 43 #include <dbus/dbus.h> 44 #include <gdbus.h> 45 46 #include "log.h" 47 #include "textfile.h" 48 #include "../src/adapter.h" 49 #include "../src/device.h" 50 51 #include "error.h" 52 #include "ipc.h" 53 #include "dbus-common.h" 54 #include "device.h" 55 #include "unix.h" 56 #include "avdtp.h" 57 #include "control.h" 58 #include "headset.h" 59 #include "gateway.h" 60 #include "sink.h" 61 #include "source.h" 62 63 #define AUDIO_INTERFACE "org.bluez.Audio" 64 65 #define CONTROL_CONNECT_TIMEOUT 2 66 #define AVDTP_CONNECT_TIMEOUT 1 67 #define HEADSET_CONNECT_TIMEOUT 1 68 69 typedef enum { 70 AUDIO_STATE_DISCONNECTED, 71 AUDIO_STATE_CONNECTING, 72 AUDIO_STATE_CONNECTED, 73 } audio_state_t; 74 75 struct service_auth { 76 service_auth_cb cb; 77 void *user_data; 78 }; 79 80 struct dev_priv { 81 audio_state_t state; 82 83 headset_state_t hs_state; 84 sink_state_t sink_state; 85 avctp_state_t avctp_state; 86 GSList *auths; 87 88 DBusMessage *conn_req; 89 DBusMessage *dc_req; 90 91 guint control_timer; 92 guint avdtp_timer; 93 guint headset_timer; 94 95 gboolean authorized; 96 guint auth_idle_id; 97 }; 98 99 static unsigned int sink_callback_id = 0; 100 static unsigned int avctp_callback_id = 0; 101 static unsigned int avdtp_callback_id = 0; 102 static unsigned int headset_callback_id = 0; 103 104 static void device_free(struct audio_device *dev) 105 { 106 struct dev_priv *priv = dev->priv; 107 108 if (dev->conn) 109 dbus_connection_unref(dev->conn); 110 111 btd_device_unref(dev->btd_dev); 112 113 if (priv) { 114 if (priv->control_timer) 115 g_source_remove(priv->control_timer); 116 if (priv->avdtp_timer) 117 g_source_remove(priv->avdtp_timer); 118 if (priv->headset_timer) 119 g_source_remove(priv->headset_timer); 120 if (priv->dc_req) 121 dbus_message_unref(priv->dc_req); 122 if (priv->conn_req) 123 dbus_message_unref(priv->conn_req); 124 g_free(priv); 125 } 126 127 g_free(dev->path); 128 g_free(dev); 129 } 130 131 static const char *state2str(audio_state_t state) 132 { 133 switch (state) { 134 case AUDIO_STATE_DISCONNECTED: 135 return "disconnected"; 136 case AUDIO_STATE_CONNECTING: 137 return "connecting"; 138 case AUDIO_STATE_CONNECTED: 139 return "connected"; 140 default: 141 error("Invalid audio state %d", state); 142 return NULL; 143 } 144 } 145 146 static void device_set_state(struct audio_device *dev, audio_state_t new_state) 147 { 148 struct dev_priv *priv = dev->priv; 149 const char *state_str; 150 DBusMessage *reply = NULL; 151 152 state_str = state2str(new_state); 153 if (!state_str) 154 return; 155 156 if (new_state == AUDIO_STATE_DISCONNECTED) 157 priv->authorized = FALSE; 158 159 if (dev->priv->state == new_state) { 160 DBG("state change attempted from %s to %s", 161 state_str, state_str); 162 return; 163 } 164 165 dev->priv->state = new_state; 166 167 if (priv->dc_req && new_state == AUDIO_STATE_DISCONNECTED) { 168 reply = dbus_message_new_method_return(priv->dc_req); 169 dbus_message_unref(priv->dc_req); 170 priv->dc_req = NULL; 171 g_dbus_send_message(dev->conn, reply); 172 } 173 174 if (priv->conn_req && new_state != AUDIO_STATE_CONNECTING) { 175 if (new_state == AUDIO_STATE_CONNECTED) 176 reply = dbus_message_new_method_return(priv->conn_req); 177 else 178 reply = g_dbus_create_error(priv->conn_req, 179 ERROR_INTERFACE 180 ".ConnectFailed", 181 "Connecting failed"); 182 dbus_message_unref(priv->conn_req); 183 priv->conn_req = NULL; 184 g_dbus_send_message(dev->conn, reply); 185 } 186 187 emit_property_changed(dev->conn, dev->path, 188 AUDIO_INTERFACE, "State", 189 DBUS_TYPE_STRING, &state_str); 190 } 191 192 static gboolean control_connect_timeout(gpointer user_data) 193 { 194 struct audio_device *dev = user_data; 195 196 dev->priv->control_timer = 0; 197 198 if (dev->control) 199 avrcp_connect(dev); 200 201 return FALSE; 202 } 203 204 static gboolean device_set_control_timer(struct audio_device *dev) 205 { 206 struct dev_priv *priv = dev->priv; 207 208 if (!dev->control) 209 return FALSE; 210 211 if (priv->control_timer) 212 return FALSE; 213 214 priv->control_timer = g_timeout_add_seconds(CONTROL_CONNECT_TIMEOUT, 215 control_connect_timeout, 216 dev); 217 218 return TRUE; 219 } 220 221 static void device_remove_control_timer(struct audio_device *dev) 222 { 223 if (dev->priv->control_timer) 224 g_source_remove(dev->priv->control_timer); 225 dev->priv->control_timer = 0; 226 } 227 228 static gboolean avdtp_connect_timeout(gpointer user_data) 229 { 230 struct audio_device *dev = user_data; 231 232 dev->priv->avdtp_timer = 0; 233 234 if (dev->sink) { 235 struct avdtp *session = avdtp_get(&dev->src, &dev->dst); 236 237 if (!session) 238 return FALSE; 239 240 sink_setup_stream(dev->sink, session); 241 avdtp_unref(session); 242 } 243 244 return FALSE; 245 } 246 247 static gboolean device_set_avdtp_timer(struct audio_device *dev) 248 { 249 struct dev_priv *priv = dev->priv; 250 251 if (!dev->sink) 252 return FALSE; 253 254 if (priv->avdtp_timer) 255 return FALSE; 256 257 priv->avdtp_timer = g_timeout_add_seconds(AVDTP_CONNECT_TIMEOUT, 258 avdtp_connect_timeout, 259 dev); 260 261 return TRUE; 262 } 263 264 static void device_remove_avdtp_timer(struct audio_device *dev) 265 { 266 if (dev->priv->avdtp_timer) 267 g_source_remove(dev->priv->avdtp_timer); 268 dev->priv->avdtp_timer = 0; 269 } 270 271 static gboolean headset_connect_timeout(gpointer user_data) 272 { 273 struct audio_device *dev = user_data; 274 struct dev_priv *priv = dev->priv; 275 276 dev->priv->headset_timer = 0; 277 278 if (dev->headset == NULL) 279 return FALSE; 280 281 if (headset_config_stream(dev, FALSE, NULL, NULL) == 0) { 282 if (priv->state != AUDIO_STATE_CONNECTED && 283 (priv->sink_state == SINK_STATE_CONNECTED || 284 priv->sink_state == SINK_STATE_PLAYING)) 285 device_set_state(dev, AUDIO_STATE_CONNECTED); 286 } 287 288 return FALSE; 289 } 290 291 static gboolean device_set_headset_timer(struct audio_device *dev) 292 { 293 struct dev_priv *priv = dev->priv; 294 295 if (!dev->headset) 296 return FALSE; 297 298 if (priv->headset_timer) 299 return FALSE; 300 301 priv->headset_timer = g_timeout_add_seconds(HEADSET_CONNECT_TIMEOUT, 302 headset_connect_timeout, dev); 303 304 return TRUE; 305 } 306 307 static void device_remove_headset_timer(struct audio_device *dev) 308 { 309 if (dev->priv->headset_timer) 310 g_source_remove(dev->priv->headset_timer); 311 dev->priv->headset_timer = 0; 312 } 313 314 static void device_avdtp_cb(struct audio_device *dev, struct avdtp *session, 315 avdtp_session_state_t old_state, 316 avdtp_session_state_t new_state, 317 void *user_data) 318 { 319 if (!dev->sink || !dev->control) 320 return; 321 322 if (new_state == AVDTP_SESSION_STATE_CONNECTED) { 323 if (avdtp_stream_setup_active(session)) 324 device_set_control_timer(dev); 325 else 326 avrcp_connect(dev); 327 } 328 } 329 330 static void device_sink_cb(struct audio_device *dev, 331 sink_state_t old_state, 332 sink_state_t new_state, 333 void *user_data) 334 { 335 struct dev_priv *priv = dev->priv; 336 337 if (!dev->sink) 338 return; 339 340 priv->sink_state = new_state; 341 342 switch (new_state) { 343 case SINK_STATE_DISCONNECTED: 344 if (dev->control) { 345 device_remove_control_timer(dev); 346 avrcp_disconnect(dev); 347 } 348 if (priv->hs_state != HEADSET_STATE_DISCONNECTED && 349 priv->dc_req) { 350 headset_shutdown(dev); 351 break; 352 } 353 if (priv->hs_state == HEADSET_STATE_DISCONNECTED) 354 device_set_state(dev, AUDIO_STATE_DISCONNECTED); 355 else if (old_state == SINK_STATE_CONNECTING) { 356 switch (priv->hs_state) { 357 case HEADSET_STATE_CONNECTED: 358 case HEADSET_STATE_PLAY_IN_PROGRESS: 359 case HEADSET_STATE_PLAYING: 360 device_set_state(dev, AUDIO_STATE_CONNECTED); 361 default: 362 break; 363 } 364 } 365 break; 366 case SINK_STATE_CONNECTING: 367 device_remove_avdtp_timer(dev); 368 if (priv->hs_state == HEADSET_STATE_DISCONNECTED) 369 device_set_state(dev, AUDIO_STATE_CONNECTING); 370 break; 371 case SINK_STATE_CONNECTED: 372 if (old_state == SINK_STATE_PLAYING) 373 break; 374 #ifdef ANDROID 375 android_set_high_priority(&dev->dst); 376 #endif 377 if (dev->auto_connect) { 378 if (!dev->headset) 379 device_set_state(dev, AUDIO_STATE_CONNECTED); 380 else if (priv->hs_state == HEADSET_STATE_DISCONNECTED) 381 device_set_headset_timer(dev); 382 else if (priv->hs_state == HEADSET_STATE_CONNECTED || 383 priv->hs_state == HEADSET_STATE_PLAY_IN_PROGRESS || 384 priv->hs_state == HEADSET_STATE_PLAYING) 385 device_set_state(dev, AUDIO_STATE_CONNECTED); 386 } else if (priv->hs_state == HEADSET_STATE_DISCONNECTED || 387 priv->hs_state == HEADSET_STATE_CONNECTING) 388 device_set_state(dev, AUDIO_STATE_CONNECTED); 389 break; 390 case SINK_STATE_PLAYING: 391 break; 392 } 393 } 394 395 static void device_avctp_cb(struct audio_device *dev, 396 avctp_state_t old_state, 397 avctp_state_t new_state, 398 void *user_data) 399 { 400 if (!dev->control) 401 return; 402 403 dev->priv->avctp_state = new_state; 404 405 switch (new_state) { 406 case AVCTP_STATE_DISCONNECTED: 407 break; 408 case AVCTP_STATE_CONNECTING: 409 device_remove_control_timer(dev); 410 break; 411 case AVCTP_STATE_CONNECTED: 412 break; 413 } 414 } 415 416 static void device_headset_cb(struct audio_device *dev, 417 headset_state_t old_state, 418 headset_state_t new_state, 419 void *user_data) 420 { 421 struct dev_priv *priv = dev->priv; 422 423 if (!dev->headset) 424 return; 425 426 priv->hs_state = new_state; 427 428 switch (new_state) { 429 case HEADSET_STATE_DISCONNECTED: 430 device_remove_avdtp_timer(dev); 431 if (priv->sink_state != SINK_STATE_DISCONNECTED && 432 dev->sink && priv->dc_req) { 433 sink_shutdown(dev->sink); 434 break; 435 } 436 if (priv->sink_state == SINK_STATE_DISCONNECTED) 437 device_set_state(dev, AUDIO_STATE_DISCONNECTED); 438 else if (old_state == HEADSET_STATE_CONNECTING && 439 (priv->sink_state == SINK_STATE_CONNECTED || 440 priv->sink_state == SINK_STATE_PLAYING)) 441 device_set_state(dev, AUDIO_STATE_CONNECTED); 442 break; 443 case HEADSET_STATE_CONNECTING: 444 device_remove_headset_timer(dev); 445 if (priv->sink_state == SINK_STATE_DISCONNECTED) 446 device_set_state(dev, AUDIO_STATE_CONNECTING); 447 break; 448 case HEADSET_STATE_CONNECTED: 449 if (old_state == HEADSET_STATE_CONNECTED || 450 old_state == HEADSET_STATE_PLAY_IN_PROGRESS || 451 old_state == HEADSET_STATE_PLAYING) 452 break; 453 if (dev->auto_connect) { 454 if (!dev->sink) 455 device_set_state(dev, AUDIO_STATE_CONNECTED); 456 else if (priv->sink_state == SINK_STATE_DISCONNECTED) 457 device_set_avdtp_timer(dev); 458 else if (priv->sink_state == SINK_STATE_CONNECTED || 459 priv->sink_state == SINK_STATE_PLAYING) 460 device_set_state(dev, AUDIO_STATE_CONNECTED); 461 } else if (priv->sink_state == SINK_STATE_DISCONNECTED || 462 priv->sink_state == SINK_STATE_CONNECTING) 463 device_set_state(dev, AUDIO_STATE_CONNECTED); 464 break; 465 case HEADSET_STATE_PLAY_IN_PROGRESS: 466 break; 467 case HEADSET_STATE_PLAYING: 468 break; 469 } 470 } 471 472 static DBusMessage *dev_connect(DBusConnection *conn, DBusMessage *msg, 473 void *data) 474 { 475 struct audio_device *dev = data; 476 struct dev_priv *priv = dev->priv; 477 478 if (priv->state == AUDIO_STATE_CONNECTING) 479 return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress", 480 "Connect in Progress"); 481 else if (priv->state == AUDIO_STATE_CONNECTED) 482 return g_dbus_create_error(msg, ERROR_INTERFACE 483 ".AlreadyConnected", 484 "Already Connected"); 485 486 dev->auto_connect = TRUE; 487 488 if (dev->headset) 489 headset_config_stream(dev, FALSE, NULL, NULL); 490 491 if (priv->state != AUDIO_STATE_CONNECTING && dev->sink) { 492 struct avdtp *session = avdtp_get(&dev->src, &dev->dst); 493 494 if (!session) 495 return g_dbus_create_error(msg, ERROR_INTERFACE 496 ".Failed", 497 "Failed to get AVDTP session"); 498 499 sink_setup_stream(dev->sink, session); 500 avdtp_unref(session); 501 } 502 503 /* The previous calls should cause a call to the state callback to 504 * indicate AUDIO_STATE_CONNECTING */ 505 if (priv->state != AUDIO_STATE_CONNECTING) 506 return g_dbus_create_error(msg, ERROR_INTERFACE 507 ".ConnectFailed", 508 "Headset connect failed"); 509 510 priv->conn_req = dbus_message_ref(msg); 511 512 return NULL; 513 } 514 515 static DBusMessage *dev_disconnect(DBusConnection *conn, DBusMessage *msg, 516 void *data) 517 { 518 struct audio_device *dev = data; 519 struct dev_priv *priv = dev->priv; 520 521 if (priv->state == AUDIO_STATE_DISCONNECTED) 522 return g_dbus_create_error(msg, ERROR_INTERFACE ".NotConnected", 523 "Not connected"); 524 525 if (priv->dc_req) 526 return dbus_message_new_method_return(msg); 527 528 priv->dc_req = dbus_message_ref(msg); 529 530 if (dev->control) { 531 device_remove_control_timer(dev); 532 avrcp_disconnect(dev); 533 } 534 535 if (dev->sink && priv->sink_state != SINK_STATE_DISCONNECTED) 536 sink_shutdown(dev->sink); 537 else if (priv->hs_state != HEADSET_STATE_DISCONNECTED) 538 headset_shutdown(dev); 539 else { 540 dbus_message_unref(priv->dc_req); 541 priv->dc_req = NULL; 542 return dbus_message_new_method_return(msg); 543 } 544 545 return NULL; 546 } 547 548 static DBusMessage *dev_get_properties(DBusConnection *conn, DBusMessage *msg, 549 void *data) 550 { 551 struct audio_device *device = data; 552 DBusMessage *reply; 553 DBusMessageIter iter; 554 DBusMessageIter dict; 555 const char *state; 556 557 reply = dbus_message_new_method_return(msg); 558 if (!reply) 559 return NULL; 560 561 dbus_message_iter_init_append(reply, &iter); 562 563 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, 564 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 565 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING 566 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); 567 568 /* State */ 569 state = state2str(device->priv->state); 570 if (state) 571 dict_append_entry(&dict, "State", DBUS_TYPE_STRING, &state); 572 573 dbus_message_iter_close_container(&iter, &dict); 574 575 return reply; 576 } 577 578 static GDBusMethodTable dev_methods[] = { 579 { "Connect", "", "", dev_connect, 580 G_DBUS_METHOD_FLAG_ASYNC }, 581 { "Disconnect", "", "", dev_disconnect }, 582 { "GetProperties", "", "a{sv}",dev_get_properties }, 583 { NULL, NULL, NULL, NULL } 584 }; 585 586 static GDBusSignalTable dev_signals[] = { 587 { "PropertyChanged", "sv" }, 588 { NULL, NULL } 589 }; 590 591 struct audio_device *audio_device_register(DBusConnection *conn, 592 struct btd_device *device, 593 const char *path, const bdaddr_t *src, 594 const bdaddr_t *dst) 595 { 596 struct audio_device *dev; 597 598 if (!conn || !path) 599 return NULL; 600 601 dev = g_new0(struct audio_device, 1); 602 603 dev->btd_dev = btd_device_ref(device); 604 dev->path = g_strdup(path); 605 bacpy(&dev->dst, dst); 606 bacpy(&dev->src, src); 607 dev->conn = dbus_connection_ref(conn); 608 dev->priv = g_new0(struct dev_priv, 1); 609 dev->priv->state = AUDIO_STATE_DISCONNECTED; 610 611 if (!g_dbus_register_interface(dev->conn, dev->path, 612 AUDIO_INTERFACE, 613 dev_methods, dev_signals, NULL, 614 dev, NULL)) { 615 error("Unable to register %s on %s", AUDIO_INTERFACE, 616 dev->path); 617 device_free(dev); 618 return NULL; 619 } 620 621 DBG("Registered interface %s on path %s", AUDIO_INTERFACE, 622 dev->path); 623 624 if (sink_callback_id == 0) 625 sink_callback_id = sink_add_state_cb(device_sink_cb, NULL); 626 627 if (avdtp_callback_id == 0) 628 avdtp_callback_id = avdtp_add_state_cb(device_avdtp_cb, NULL); 629 if (avctp_callback_id == 0) 630 avctp_callback_id = avctp_add_state_cb(device_avctp_cb, NULL); 631 632 if (headset_callback_id == 0) 633 headset_callback_id = headset_add_state_cb(device_headset_cb, 634 NULL); 635 636 return dev; 637 } 638 639 gboolean audio_device_is_active(struct audio_device *dev, 640 const char *interface) 641 { 642 if (!interface) { 643 if ((dev->sink || dev->source) && 644 avdtp_is_connected(&dev->src, &dev->dst)) 645 return TRUE; 646 if (dev->headset && headset_is_active(dev)) 647 return TRUE; 648 } else if (!strcmp(interface, AUDIO_SINK_INTERFACE) && dev->sink && 649 avdtp_is_connected(&dev->src, &dev->dst)) 650 return TRUE; 651 else if (!strcmp(interface, AUDIO_SOURCE_INTERFACE) && dev->source && 652 avdtp_is_connected(&dev->src, &dev->dst)) 653 return TRUE; 654 else if (!strcmp(interface, AUDIO_HEADSET_INTERFACE) && dev->headset && 655 headset_is_active(dev)) 656 return TRUE; 657 else if (!strcmp(interface, AUDIO_CONTROL_INTERFACE) && dev->control && 658 control_is_active(dev)) 659 return TRUE; 660 else if (!strcmp(interface, AUDIO_GATEWAY_INTERFACE) && dev->gateway && 661 gateway_is_connected(dev)) 662 return TRUE; 663 664 return FALSE; 665 } 666 667 void audio_device_unregister(struct audio_device *device) 668 { 669 unix_device_removed(device); 670 671 if (device->hs_preauth_id) { 672 g_source_remove(device->hs_preauth_id); 673 device->hs_preauth_id = 0; 674 } 675 676 if (device->headset) 677 headset_unregister(device); 678 679 if (device->gateway) 680 gateway_unregister(device); 681 682 if (device->sink) 683 sink_unregister(device); 684 685 if (device->source) 686 source_unregister(device); 687 688 if (device->control) 689 control_unregister(device); 690 691 g_dbus_unregister_interface(device->conn, device->path, 692 AUDIO_INTERFACE); 693 694 device_free(device); 695 } 696 697 static void auth_cb(DBusError *derr, void *user_data) 698 { 699 struct audio_device *dev = user_data; 700 struct dev_priv *priv = dev->priv; 701 702 if (derr == NULL) 703 priv->authorized = TRUE; 704 705 while (priv->auths) { 706 struct service_auth *auth = priv->auths->data; 707 708 auth->cb(derr, auth->user_data); 709 priv->auths = g_slist_remove(priv->auths, auth); 710 g_free(auth); 711 } 712 } 713 714 static gboolean auth_idle_cb(gpointer user_data) 715 { 716 struct audio_device *dev = user_data; 717 struct dev_priv *priv = dev->priv; 718 719 priv->auth_idle_id = 0; 720 721 auth_cb(NULL, dev); 722 723 return FALSE; 724 } 725 726 static gboolean audio_device_is_connected(struct audio_device *dev) 727 { 728 if (dev->headset) { 729 headset_state_t state = headset_get_state(dev); 730 731 if (state == HEADSET_STATE_CONNECTED || 732 state == HEADSET_STATE_PLAY_IN_PROGRESS || 733 state == HEADSET_STATE_PLAYING) 734 return TRUE; 735 } 736 737 if (dev->sink) { 738 sink_state_t state = sink_get_state(dev); 739 740 if (state == SINK_STATE_CONNECTED || 741 state == SINK_STATE_PLAYING) 742 return TRUE; 743 } 744 745 if (dev->source) { 746 source_state_t state = source_get_state(dev); 747 748 if (state == SOURCE_STATE_CONNECTED || 749 state == SOURCE_STATE_PLAYING) 750 return TRUE; 751 } 752 753 return FALSE; 754 } 755 756 int audio_device_request_authorization(struct audio_device *dev, 757 const char *uuid, service_auth_cb cb, 758 void *user_data) 759 { 760 struct dev_priv *priv = dev->priv; 761 struct service_auth *auth; 762 int err; 763 764 auth = g_try_new0(struct service_auth, 1); 765 if (!auth) 766 return -ENOMEM; 767 768 auth->cb = cb; 769 auth->user_data = user_data; 770 771 priv->auths = g_slist_append(priv->auths, auth); 772 if (g_slist_length(priv->auths) > 1) 773 return 0; 774 775 if (priv->authorized || audio_device_is_connected(dev)) { 776 priv->auth_idle_id = g_idle_add(auth_idle_cb, dev); 777 return 0; 778 } 779 780 err = btd_request_authorization(&dev->src, &dev->dst, uuid, auth_cb, 781 dev); 782 if (err < 0) { 783 priv->auths = g_slist_remove(priv->auths, auth); 784 g_free(auth); 785 } 786 787 return err; 788 } 789 790 int audio_device_cancel_authorization(struct audio_device *dev, 791 authorization_cb cb, void *user_data) 792 { 793 struct dev_priv *priv = dev->priv; 794 GSList *l, *next; 795 796 for (l = priv->auths; l != NULL; l = next) { 797 struct service_auth *auth = l->data; 798 799 next = g_slist_next(l); 800 801 if (cb && auth->cb != cb) 802 continue; 803 804 if (user_data && auth->user_data != user_data) 805 continue; 806 807 priv->auths = g_slist_remove(priv->auths, auth); 808 g_free(auth); 809 } 810 811 if (g_slist_length(priv->auths) == 0) { 812 if (priv->auth_idle_id > 0) { 813 g_source_remove(priv->auth_idle_id); 814 priv->auth_idle_id = 0; 815 } else 816 btd_cancel_authorization(&dev->src, &dev->dst); 817 } 818 819 return 0; 820 } 821 822 void audio_device_set_authorized(struct audio_device *dev, gboolean auth) 823 { 824 struct dev_priv *priv = dev->priv; 825 826 priv->authorized = auth; 827 } 828