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 * Copyright (C) 2009 Joao Paulo Rechi Vita 8 * 9 * 10 * This program is free software; you can redistribute it and/or modify 11 * it under the terms of the GNU General Public License as published by 12 * the Free Software Foundation; either version 2 of the License, or 13 * (at your option) any later version. 14 * 15 * This program is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU General Public License for more details. 19 * 20 * You should have received a copy of the GNU General Public License 21 * along with this program; if not, write to the Free Software 22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 23 * 24 */ 25 26 #ifdef HAVE_CONFIG_H 27 #include <config.h> 28 #endif 29 30 #include <stdint.h> 31 #include <errno.h> 32 33 #include <bluetooth/bluetooth.h> 34 #include <bluetooth/sdp.h> 35 36 #include <glib.h> 37 #include <dbus/dbus.h> 38 #include <gdbus.h> 39 40 #include "log.h" 41 42 #include "device.h" 43 #include "avdtp.h" 44 #include "media.h" 45 #include "a2dp.h" 46 #include "error.h" 47 #include "source.h" 48 #include "dbus-common.h" 49 #include "../src/adapter.h" 50 #include "../src/device.h" 51 52 #define STREAM_SETUP_RETRY_TIMER 2 53 54 struct pending_request { 55 DBusConnection *conn; 56 DBusMessage *msg; 57 unsigned int id; 58 }; 59 60 struct source { 61 struct audio_device *dev; 62 struct avdtp *session; 63 struct avdtp_stream *stream; 64 unsigned int cb_id; 65 guint retry_id; 66 avdtp_session_state_t session_state; 67 avdtp_state_t stream_state; 68 source_state_t state; 69 struct pending_request *connect; 70 struct pending_request *disconnect; 71 DBusConnection *conn; 72 }; 73 74 struct source_state_callback { 75 source_state_cb cb; 76 void *user_data; 77 unsigned int id; 78 }; 79 80 static GSList *source_callbacks = NULL; 81 82 static unsigned int avdtp_callback_id = 0; 83 84 static const char *state2str(source_state_t state) 85 { 86 switch (state) { 87 case SOURCE_STATE_DISCONNECTED: 88 return "disconnected"; 89 case SOURCE_STATE_CONNECTING: 90 return "connecting"; 91 case SOURCE_STATE_CONNECTED: 92 return "connected"; 93 case SOURCE_STATE_PLAYING: 94 return "playing"; 95 default: 96 error("Invalid source state %d", state); 97 return NULL; 98 } 99 } 100 101 static void source_set_state(struct audio_device *dev, source_state_t new_state) 102 { 103 struct source *source = dev->source; 104 const char *state_str; 105 source_state_t old_state = source->state; 106 GSList *l; 107 108 source->state = new_state; 109 110 state_str = state2str(new_state); 111 if (state_str) 112 emit_property_changed(dev->conn, dev->path, 113 AUDIO_SOURCE_INTERFACE, "State", 114 DBUS_TYPE_STRING, &state_str); 115 116 for (l = source_callbacks; l != NULL; l = l->next) { 117 struct source_state_callback *cb = l->data; 118 cb->cb(dev, old_state, new_state, cb->user_data); 119 } 120 } 121 122 static void avdtp_state_callback(struct audio_device *dev, 123 struct avdtp *session, 124 avdtp_session_state_t old_state, 125 avdtp_session_state_t new_state, 126 void *user_data) 127 { 128 struct source *source = dev->source; 129 130 if (source == NULL) 131 return; 132 133 switch (new_state) { 134 case AVDTP_SESSION_STATE_DISCONNECTED: 135 source_set_state(dev, SOURCE_STATE_DISCONNECTED); 136 break; 137 case AVDTP_SESSION_STATE_CONNECTING: 138 source_set_state(dev, SOURCE_STATE_CONNECTING); 139 break; 140 case AVDTP_SESSION_STATE_CONNECTED: 141 break; 142 } 143 144 source->session_state = new_state; 145 } 146 147 static void pending_request_free(struct audio_device *dev, 148 struct pending_request *pending) 149 { 150 if (pending->conn) 151 dbus_connection_unref(pending->conn); 152 if (pending->msg) 153 dbus_message_unref(pending->msg); 154 if (pending->id) 155 a2dp_cancel(dev, pending->id); 156 157 g_free(pending); 158 } 159 160 static void stream_state_changed(struct avdtp_stream *stream, 161 avdtp_state_t old_state, 162 avdtp_state_t new_state, 163 struct avdtp_error *err, 164 void *user_data) 165 { 166 struct audio_device *dev = user_data; 167 struct source *source = dev->source; 168 169 if (err) 170 return; 171 172 switch (new_state) { 173 case AVDTP_STATE_IDLE: 174 if (source->disconnect) { 175 DBusMessage *reply; 176 struct pending_request *p; 177 178 p = source->disconnect; 179 source->disconnect = NULL; 180 181 reply = dbus_message_new_method_return(p->msg); 182 g_dbus_send_message(p->conn, reply); 183 pending_request_free(dev, p); 184 } 185 186 if (source->session) { 187 avdtp_unref(source->session); 188 source->session = NULL; 189 } 190 source->stream = NULL; 191 source->cb_id = 0; 192 break; 193 case AVDTP_STATE_OPEN: 194 source_set_state(dev, SOURCE_STATE_CONNECTED); 195 break; 196 case AVDTP_STATE_STREAMING: 197 source_set_state(dev, SOURCE_STATE_PLAYING); 198 break; 199 case AVDTP_STATE_CONFIGURED: 200 case AVDTP_STATE_CLOSING: 201 case AVDTP_STATE_ABORTING: 202 default: 203 break; 204 } 205 206 source->stream_state = new_state; 207 } 208 209 static void error_failed(DBusConnection *conn, DBusMessage *msg, 210 const char *desc) 211 { 212 DBusMessage *reply = btd_error_failed(msg, desc); 213 g_dbus_send_message(conn, reply); 214 } 215 216 static gboolean stream_setup_retry(gpointer user_data) 217 { 218 struct source *source = user_data; 219 struct pending_request *pending = source->connect; 220 221 source->retry_id = 0; 222 223 if (source->stream_state >= AVDTP_STATE_OPEN) { 224 DBG("Stream successfully created, after XCASE connect:connect"); 225 if (pending->msg) { 226 DBusMessage *reply; 227 reply = dbus_message_new_method_return(pending->msg); 228 g_dbus_send_message(pending->conn, reply); 229 } 230 } else { 231 DBG("Stream setup failed, after XCASE connect:connect"); 232 if (pending->msg) 233 error_failed(pending->conn, pending->msg, "Stream setup failed"); 234 } 235 236 source->connect = NULL; 237 pending_request_free(source->dev, pending); 238 239 return FALSE; 240 } 241 242 static void stream_setup_complete(struct avdtp *session, struct a2dp_sep *sep, 243 struct avdtp_stream *stream, 244 struct avdtp_error *err, void *user_data) 245 { 246 struct source *source = user_data; 247 struct pending_request *pending; 248 249 pending = source->connect; 250 251 pending->id = 0; 252 253 if (stream) { 254 DBG("Stream successfully created"); 255 256 if (pending->msg) { 257 DBusMessage *reply; 258 reply = dbus_message_new_method_return(pending->msg); 259 g_dbus_send_message(pending->conn, reply); 260 } 261 262 source->connect = NULL; 263 pending_request_free(source->dev, pending); 264 265 return; 266 } 267 268 avdtp_unref(source->session); 269 source->session = NULL; 270 if (avdtp_error_category(err) == AVDTP_ERRNO 271 && avdtp_error_posix_errno(err) != EHOSTDOWN) { 272 DBG("connect:connect XCASE detected"); 273 source->retry_id = g_timeout_add_seconds(STREAM_SETUP_RETRY_TIMER, 274 stream_setup_retry, 275 source); 276 } else { 277 if (pending->msg) 278 error_failed(pending->conn, pending->msg, "Stream setup failed"); 279 source->connect = NULL; 280 pending_request_free(source->dev, pending); 281 DBG("Stream setup failed : %s", avdtp_strerror(err)); 282 } 283 } 284 285 static void select_complete(struct avdtp *session, struct a2dp_sep *sep, 286 GSList *caps, void *user_data) 287 { 288 struct source *source = user_data; 289 struct pending_request *pending; 290 int id; 291 292 pending = source->connect; 293 294 pending->id = 0; 295 296 if (caps == NULL) 297 goto failed; 298 299 id = a2dp_config(session, sep, stream_setup_complete, caps, source); 300 if (id == 0) 301 goto failed; 302 303 pending->id = id; 304 return; 305 306 failed: 307 if (pending->msg) 308 error_failed(pending->conn, pending->msg, "Stream setup failed"); 309 pending_request_free(source->dev, pending); 310 source->connect = NULL; 311 avdtp_unref(source->session); 312 source->session = NULL; 313 } 314 315 static void discovery_complete(struct avdtp *session, GSList *seps, struct avdtp_error *err, 316 void *user_data) 317 { 318 struct source *source = user_data; 319 struct pending_request *pending; 320 int id; 321 322 pending = source->connect; 323 324 if (err) { 325 avdtp_unref(source->session); 326 source->session = NULL; 327 if (avdtp_error_category(err) == AVDTP_ERRNO 328 && avdtp_error_posix_errno(err) != EHOSTDOWN) { 329 DBG("connect:connect XCASE detected"); 330 source->retry_id = 331 g_timeout_add_seconds(STREAM_SETUP_RETRY_TIMER, 332 stream_setup_retry, 333 source); 334 } else 335 goto failed; 336 return; 337 } 338 339 DBG("Discovery complete"); 340 341 id = a2dp_select_capabilities(source->session, AVDTP_SEP_TYPE_SOURCE, NULL, 342 select_complete, source); 343 if (id == 0) 344 goto failed; 345 346 pending->id = id; 347 return; 348 349 failed: 350 if (pending->msg) 351 error_failed(pending->conn, pending->msg, "Stream setup failed"); 352 pending_request_free(source->dev, pending); 353 source->connect = NULL; 354 avdtp_unref(source->session); 355 source->session = NULL; 356 } 357 358 gboolean source_setup_stream(struct source *source, struct avdtp *session) 359 { 360 if (source->connect || source->disconnect) 361 return FALSE; 362 363 if (session && !source->session) 364 source->session = avdtp_ref(session); 365 366 if (!source->session) 367 return FALSE; 368 369 avdtp_set_auto_disconnect(source->session, FALSE); 370 371 if (avdtp_discover(source->session, discovery_complete, source) < 0) 372 return FALSE; 373 374 source->connect = g_new0(struct pending_request, 1); 375 376 return TRUE; 377 } 378 379 static DBusMessage *source_connect(DBusConnection *conn, 380 DBusMessage *msg, void *data) 381 { 382 struct audio_device *dev = data; 383 struct source *source = dev->source; 384 struct pending_request *pending; 385 386 if (!source->session) 387 source->session = avdtp_get(&dev->src, &dev->dst); 388 389 if (!source->session) 390 return btd_error_failed(msg, "Unable to get a session"); 391 392 if (source->connect || source->disconnect) 393 return btd_error_busy(msg); 394 395 if (source->stream_state >= AVDTP_STATE_OPEN) 396 return btd_error_already_connected(msg); 397 398 if (!source_setup_stream(source, NULL)) 399 return btd_error_failed(msg, "Failed to create a stream"); 400 401 dev->auto_connect = FALSE; 402 403 pending = source->connect; 404 405 pending->conn = dbus_connection_ref(conn); 406 pending->msg = dbus_message_ref(msg); 407 408 DBG("stream creation in progress"); 409 410 return NULL; 411 } 412 413 static DBusMessage *source_disconnect(DBusConnection *conn, 414 DBusMessage *msg, void *data) 415 { 416 struct audio_device *device = data; 417 struct source *source = device->source; 418 struct pending_request *pending; 419 int err; 420 421 if (!source->session) 422 return btd_error_not_connected(msg); 423 424 if (source->connect || source->disconnect) 425 return btd_error_busy(msg); 426 427 if (source->stream_state < AVDTP_STATE_OPEN) { 428 DBusMessage *reply = dbus_message_new_method_return(msg); 429 if (!reply) 430 return NULL; 431 avdtp_unref(source->session); 432 source->session = NULL; 433 return reply; 434 } 435 436 err = avdtp_close(source->session, source->stream, FALSE); 437 if (err < 0) 438 return btd_error_failed(msg, strerror(-err)); 439 440 pending = g_new0(struct pending_request, 1); 441 pending->conn = dbus_connection_ref(conn); 442 pending->msg = dbus_message_ref(msg); 443 source->disconnect = pending; 444 445 return NULL; 446 } 447 448 static DBusMessage *source_get_properties(DBusConnection *conn, 449 DBusMessage *msg, void *data) 450 { 451 struct audio_device *device = data; 452 struct source *source = device->source; 453 DBusMessage *reply; 454 DBusMessageIter iter; 455 DBusMessageIter dict; 456 const char *state; 457 458 reply = dbus_message_new_method_return(msg); 459 if (!reply) 460 return NULL; 461 462 dbus_message_iter_init_append(reply, &iter); 463 464 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, 465 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 466 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING 467 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); 468 469 /* State */ 470 state = state2str(source->state); 471 if (state) 472 dict_append_entry(&dict, "State", DBUS_TYPE_STRING, &state); 473 474 dbus_message_iter_close_container(&iter, &dict); 475 476 return reply; 477 } 478 479 static GDBusMethodTable source_methods[] = { 480 { "Connect", "", "", source_connect, 481 G_DBUS_METHOD_FLAG_ASYNC }, 482 { "Disconnect", "", "", source_disconnect, 483 G_DBUS_METHOD_FLAG_ASYNC }, 484 { "GetProperties", "", "a{sv}",source_get_properties }, 485 { NULL, NULL, NULL, NULL } 486 }; 487 488 static GDBusSignalTable source_signals[] = { 489 { "PropertyChanged", "sv" }, 490 { NULL, NULL } 491 }; 492 493 static void source_free(struct audio_device *dev) 494 { 495 struct source *source = dev->source; 496 497 if (source->cb_id) 498 avdtp_stream_remove_cb(source->session, source->stream, 499 source->cb_id); 500 501 if (source->session) 502 avdtp_unref(source->session); 503 504 if (source->connect) 505 pending_request_free(dev, source->connect); 506 507 if (source->disconnect) 508 pending_request_free(dev, source->disconnect); 509 510 if (source->retry_id) 511 g_source_remove(source->retry_id); 512 513 g_free(source); 514 dev->source = NULL; 515 } 516 517 static void path_unregister(void *data) 518 { 519 struct audio_device *dev = data; 520 521 DBG("Unregistered interface %s on path %s", 522 AUDIO_SOURCE_INTERFACE, dev->path); 523 524 source_free(dev); 525 } 526 527 void source_unregister(struct audio_device *dev) 528 { 529 g_dbus_unregister_interface(dev->conn, dev->path, 530 AUDIO_SOURCE_INTERFACE); 531 } 532 533 struct source *source_init(struct audio_device *dev) 534 { 535 struct source *source; 536 537 if (!g_dbus_register_interface(dev->conn, dev->path, 538 AUDIO_SOURCE_INTERFACE, 539 source_methods, source_signals, NULL, 540 dev, path_unregister)) 541 return NULL; 542 543 DBG("Registered interface %s on path %s", 544 AUDIO_SOURCE_INTERFACE, dev->path); 545 546 if (avdtp_callback_id == 0) 547 avdtp_callback_id = avdtp_add_state_cb(avdtp_state_callback, 548 NULL); 549 550 source = g_new0(struct source, 1); 551 552 source->dev = dev; 553 554 return source; 555 } 556 557 gboolean source_is_active(struct audio_device *dev) 558 { 559 struct source *source = dev->source; 560 561 if (source->session) 562 return TRUE; 563 564 return FALSE; 565 } 566 567 avdtp_state_t source_get_state(struct audio_device *dev) 568 { 569 struct source *source = dev->source; 570 571 return source->stream_state; 572 } 573 574 gboolean source_new_stream(struct audio_device *dev, struct avdtp *session, 575 struct avdtp_stream *stream) 576 { 577 struct source *source = dev->source; 578 579 if (source->stream) 580 return FALSE; 581 582 if (!source->session) 583 source->session = avdtp_ref(session); 584 585 source->stream = stream; 586 587 source->cb_id = avdtp_stream_add_cb(session, stream, 588 stream_state_changed, dev); 589 590 return TRUE; 591 } 592 593 gboolean source_shutdown(struct source *source) 594 { 595 if (!source->stream) 596 return FALSE; 597 598 if (avdtp_close(source->session, source->stream, FALSE) < 0) 599 return FALSE; 600 601 return TRUE; 602 } 603 604 unsigned int source_add_state_cb(source_state_cb cb, void *user_data) 605 { 606 struct source_state_callback *state_cb; 607 static unsigned int id = 0; 608 609 state_cb = g_new(struct source_state_callback, 1); 610 state_cb->cb = cb; 611 state_cb->user_data = user_data; 612 state_cb->id = ++id; 613 614 source_callbacks = g_slist_append(source_callbacks, state_cb); 615 616 return state_cb->id; 617 } 618 619 gboolean source_remove_state_cb(unsigned int id) 620 { 621 GSList *l; 622 623 for (l = source_callbacks; l != NULL; l = l->next) { 624 struct source_state_callback *cb = l->data; 625 if (cb && cb->id == id) { 626 source_callbacks = g_slist_remove(source_callbacks, cb); 627 g_free(cb); 628 return TRUE; 629 } 630 } 631 632 return FALSE; 633 } 634