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) 2008-2009 Leonid Movshovich <event.riga (at) gmail.org> 8 * Copyright (C) 2010 ProFUSION embedded systems 9 * 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 24 * 25 */ 26 27 #ifdef HAVE_CONFIG_H 28 #include <config.h> 29 #endif 30 31 #include <stdint.h> 32 #include <stdlib.h> 33 #include <string.h> 34 #include <fcntl.h> 35 #include <errno.h> 36 37 #include <glib.h> 38 #include <dbus/dbus.h> 39 #include <gdbus.h> 40 41 #include <bluetooth/bluetooth.h> 42 #include <bluetooth/sdp.h> 43 #include <bluetooth/sdp_lib.h> 44 45 #include "glib-helper.h" 46 #include "device.h" 47 #include "gateway.h" 48 #include "log.h" 49 #include "error.h" 50 #include "btio.h" 51 #include "dbus-common.h" 52 53 #ifndef DBUS_TYPE_UNIX_FD 54 #define DBUS_TYPE_UNIX_FD -1 55 #endif 56 57 struct hf_agent { 58 char *name; /* Bus id */ 59 char *path; /* D-Bus path */ 60 guint watch; /* Disconnect watch */ 61 }; 62 63 struct gateway { 64 gateway_state_t state; 65 GIOChannel *rfcomm; 66 GIOChannel *sco; 67 gateway_stream_cb_t sco_start_cb; 68 void *sco_start_cb_data; 69 struct hf_agent *agent; 70 DBusMessage *msg; 71 }; 72 73 int gateway_close(struct audio_device *device); 74 75 static const char *state2str(gateway_state_t state) 76 { 77 switch (state) { 78 case GATEWAY_STATE_DISCONNECTED: 79 return "disconnected"; 80 case GATEWAY_STATE_CONNECTING: 81 return "connecting"; 82 case GATEWAY_STATE_CONNECTED: 83 return "connected"; 84 case GATEWAY_STATE_PLAYING: 85 return "playing"; 86 default: 87 return ""; 88 } 89 } 90 91 static void agent_free(struct hf_agent *agent) 92 { 93 if (!agent) 94 return; 95 96 g_free(agent->name); 97 g_free(agent->path); 98 g_free(agent); 99 } 100 101 static void change_state(struct audio_device *dev, gateway_state_t new_state) 102 { 103 struct gateway *gw = dev->gateway; 104 const char *val; 105 106 if (gw->state == new_state) 107 return; 108 109 val = state2str(new_state); 110 gw->state = new_state; 111 112 emit_property_changed(dev->conn, dev->path, 113 AUDIO_GATEWAY_INTERFACE, "State", 114 DBUS_TYPE_STRING, &val); 115 } 116 117 static void agent_disconnect(struct audio_device *dev, struct hf_agent *agent) 118 { 119 DBusMessage *msg; 120 121 msg = dbus_message_new_method_call(agent->name, agent->path, 122 "org.bluez.HandsfreeAgent", "Release"); 123 124 g_dbus_send_message(dev->conn, msg); 125 } 126 127 static gboolean agent_sendfd(struct hf_agent *agent, int fd, 128 DBusPendingCallNotifyFunction notify, void *data) 129 { 130 struct audio_device *dev = data; 131 DBusMessage *msg; 132 DBusPendingCall *call; 133 134 msg = dbus_message_new_method_call(agent->name, agent->path, 135 "org.bluez.HandsfreeAgent", "NewConnection"); 136 137 dbus_message_append_args(msg, DBUS_TYPE_UNIX_FD, &fd, 138 DBUS_TYPE_INVALID); 139 140 if (dbus_connection_send_with_reply(dev->conn, msg, &call, -1) == FALSE) 141 return FALSE; 142 143 dbus_pending_call_set_notify(call, notify, dev, NULL); 144 dbus_pending_call_unref(call); 145 146 return TRUE; 147 } 148 149 static gboolean sco_io_cb(GIOChannel *chan, GIOCondition cond, 150 struct audio_device *dev) 151 { 152 struct gateway *gw = dev->gateway; 153 154 if (cond & G_IO_NVAL) 155 return FALSE; 156 157 if (cond & (G_IO_ERR | G_IO_HUP)) { 158 DBG("sco connection is released"); 159 g_io_channel_shutdown(gw->sco, TRUE, NULL); 160 g_io_channel_unref(gw->sco); 161 gw->sco = NULL; 162 change_state(dev, GATEWAY_STATE_CONNECTED); 163 return FALSE; 164 } 165 166 return TRUE; 167 } 168 169 static void sco_connect_cb(GIOChannel *chan, GError *err, gpointer user_data) 170 { 171 struct audio_device *dev = (struct audio_device *) user_data; 172 struct gateway *gw = dev->gateway; 173 174 DBG("at the begin of sco_connect_cb() in gateway.c"); 175 176 gw->sco = g_io_channel_ref(chan); 177 178 if (gw->sco_start_cb) 179 gw->sco_start_cb(dev, err, gw->sco_start_cb_data); 180 181 if (err) { 182 error("sco_connect_cb(): %s", err->message); 183 gateway_close(dev); 184 return; 185 } 186 187 g_io_add_watch(gw->sco, G_IO_ERR | G_IO_HUP | G_IO_NVAL, 188 (GIOFunc) sco_io_cb, dev); 189 } 190 191 static void newconnection_reply(DBusPendingCall *call, void *data) 192 { 193 struct audio_device *dev = data; 194 DBusMessage *reply = dbus_pending_call_steal_reply(call); 195 DBusError derr; 196 197 if (!dev->gateway->rfcomm) { 198 DBG("RFCOMM disconnected from server before agent reply"); 199 goto done; 200 } 201 202 dbus_error_init(&derr); 203 if (!dbus_set_error_from_message(&derr, reply)) { 204 DBG("Agent reply: file descriptor passed successfully"); 205 change_state(dev, GATEWAY_STATE_CONNECTED); 206 goto done; 207 } 208 209 DBG("Agent reply: %s", derr.message); 210 211 dbus_error_free(&derr); 212 gateway_close(dev); 213 214 done: 215 dbus_message_unref(reply); 216 } 217 218 static void rfcomm_connect_cb(GIOChannel *chan, GError *err, 219 gpointer user_data) 220 { 221 struct audio_device *dev = user_data; 222 struct gateway *gw = dev->gateway; 223 DBusMessage *reply; 224 int sk, ret; 225 226 if (err) { 227 error("connect(): %s", err->message); 228 if (gw->sco_start_cb) 229 gw->sco_start_cb(dev, err, gw->sco_start_cb_data); 230 goto fail; 231 } 232 233 if (!gw->agent) { 234 error("Handsfree Agent not registered"); 235 goto fail; 236 } 237 238 sk = g_io_channel_unix_get_fd(chan); 239 240 gw->rfcomm = g_io_channel_ref(chan); 241 242 ret = agent_sendfd(gw->agent, sk, newconnection_reply, dev); 243 244 if (!gw->msg) 245 return; 246 247 if (ret) 248 reply = dbus_message_new_method_return(gw->msg); 249 else 250 reply = btd_error_failed(gw->msg, "Can't pass file descriptor"); 251 252 g_dbus_send_message(dev->conn, reply); 253 254 return; 255 256 fail: 257 if (gw->msg) { 258 DBusMessage *reply; 259 reply = btd_error_failed(gw->msg, "Connect failed"); 260 g_dbus_send_message(dev->conn, reply); 261 } 262 263 change_state(dev, GATEWAY_STATE_DISCONNECTED); 264 } 265 266 static void get_record_cb(sdp_list_t *recs, int err, gpointer user_data) 267 { 268 struct audio_device *dev = user_data; 269 struct gateway *gw = dev->gateway; 270 int ch; 271 sdp_list_t *protos, *classes; 272 uuid_t uuid; 273 GIOChannel *io; 274 GError *gerr = NULL; 275 276 if (err < 0) { 277 error("Unable to get service record: %s (%d)", strerror(-err), 278 -err); 279 goto fail; 280 } 281 282 if (!recs || !recs->data) { 283 error("No records found"); 284 err = -EIO; 285 goto fail; 286 } 287 288 if (sdp_get_service_classes(recs->data, &classes) < 0) { 289 error("Unable to get service classes from record"); 290 err = -EINVAL; 291 goto fail; 292 } 293 294 if (sdp_get_access_protos(recs->data, &protos) < 0) { 295 error("Unable to get access protocols from record"); 296 err = -ENODATA; 297 goto fail; 298 } 299 300 memcpy(&uuid, classes->data, sizeof(uuid)); 301 sdp_list_free(classes, free); 302 303 if (!sdp_uuid128_to_uuid(&uuid) || uuid.type != SDP_UUID16 || 304 uuid.value.uuid16 != HANDSFREE_AGW_SVCLASS_ID) { 305 sdp_list_free(protos, NULL); 306 error("Invalid service record or not HFP"); 307 err = -EIO; 308 goto fail; 309 } 310 311 ch = sdp_get_proto_port(protos, RFCOMM_UUID); 312 sdp_list_foreach(protos, (sdp_list_func_t) sdp_list_free, NULL); 313 sdp_list_free(protos, NULL); 314 if (ch <= 0) { 315 error("Unable to extract RFCOMM channel from service record"); 316 err = -EIO; 317 goto fail; 318 } 319 320 io = bt_io_connect(BT_IO_RFCOMM, rfcomm_connect_cb, dev, NULL, &gerr, 321 BT_IO_OPT_SOURCE_BDADDR, &dev->src, 322 BT_IO_OPT_DEST_BDADDR, &dev->dst, 323 BT_IO_OPT_CHANNEL, ch, 324 BT_IO_OPT_INVALID); 325 if (!io) { 326 error("Unable to connect: %s", gerr->message); 327 gateway_close(dev); 328 goto fail; 329 } 330 331 g_io_channel_unref(io); 332 333 change_state(dev, GATEWAY_STATE_CONNECTING); 334 return; 335 336 fail: 337 if (gw->msg) { 338 DBusMessage *reply = btd_error_failed(gw->msg, 339 gerr ? gerr->message : strerror(-err)); 340 g_dbus_send_message(dev->conn, reply); 341 } 342 343 change_state(dev, GATEWAY_STATE_DISCONNECTED); 344 345 if (!gerr) 346 g_set_error(&gerr, BT_IO_ERROR, BT_IO_ERROR_FAILED, 347 "connect: %s (%d)", strerror(-err), -err); 348 349 if (gw->sco_start_cb) 350 gw->sco_start_cb(dev, gerr, gw->sco_start_cb_data); 351 352 g_error_free(gerr); 353 } 354 355 static int get_records(struct audio_device *device) 356 { 357 uuid_t uuid; 358 359 sdp_uuid16_create(&uuid, HANDSFREE_AGW_SVCLASS_ID); 360 return bt_search_service(&device->src, &device->dst, &uuid, 361 get_record_cb, device, NULL); 362 } 363 364 static DBusMessage *ag_connect(DBusConnection *conn, DBusMessage *msg, 365 void *data) 366 { 367 struct audio_device *au_dev = (struct audio_device *) data; 368 struct gateway *gw = au_dev->gateway; 369 int err; 370 371 if (!gw->agent) 372 return btd_error_agent_not_available(msg); 373 374 err = get_records(au_dev); 375 if (err < 0) 376 return btd_error_failed(msg, strerror(-err)); 377 378 gw->msg = dbus_message_ref(msg); 379 380 return NULL; 381 } 382 383 int gateway_close(struct audio_device *device) 384 { 385 struct gateway *gw = device->gateway; 386 int sock; 387 388 if (gw->rfcomm) { 389 sock = g_io_channel_unix_get_fd(gw->rfcomm); 390 shutdown(sock, SHUT_RDWR); 391 392 g_io_channel_shutdown(gw->rfcomm, TRUE, NULL); 393 g_io_channel_unref(gw->rfcomm); 394 gw->rfcomm = NULL; 395 } 396 397 if (gw->sco) { 398 g_io_channel_shutdown(gw->sco, TRUE, NULL); 399 g_io_channel_unref(gw->sco); 400 gw->sco = NULL; 401 gw->sco_start_cb = NULL; 402 gw->sco_start_cb_data = NULL; 403 } 404 405 change_state(device, GATEWAY_STATE_DISCONNECTED); 406 407 return 0; 408 } 409 410 static DBusMessage *ag_disconnect(DBusConnection *conn, DBusMessage *msg, 411 void *data) 412 { 413 struct audio_device *device = data; 414 struct gateway *gw = device->gateway; 415 DBusMessage *reply = NULL; 416 char gw_addr[18]; 417 418 if (!device->conn) 419 return NULL; 420 421 reply = dbus_message_new_method_return(msg); 422 if (!reply) 423 return NULL; 424 425 if (!gw->rfcomm) 426 return btd_error_not_connected(msg); 427 428 gateway_close(device); 429 ba2str(&device->dst, gw_addr); 430 DBG("Disconnected from %s, %s", gw_addr, device->path); 431 432 return reply; 433 } 434 435 static void agent_exited(DBusConnection *conn, void *data) 436 { 437 struct gateway *gateway = data; 438 struct hf_agent *agent = gateway->agent; 439 440 DBG("Agent %s exited", agent->name); 441 442 agent_free(agent); 443 gateway->agent = NULL; 444 } 445 446 static DBusMessage *ag_get_properties(DBusConnection *conn, DBusMessage *msg, 447 void *data) 448 { 449 struct audio_device *device = data; 450 struct gateway *gw = device->gateway; 451 DBusMessage *reply; 452 DBusMessageIter iter; 453 DBusMessageIter dict; 454 const char *value; 455 456 457 reply = dbus_message_new_method_return(msg); 458 if (!reply) 459 return NULL; 460 461 dbus_message_iter_init_append(reply, &iter); 462 463 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, 464 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 465 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING 466 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); 467 468 value = state2str(gw->state); 469 dict_append_entry(&dict, "State", 470 DBUS_TYPE_STRING, &value); 471 472 dbus_message_iter_close_container(&iter, &dict); 473 474 return reply; 475 } 476 477 static DBusMessage *register_agent(DBusConnection *conn, 478 DBusMessage *msg, void *data) 479 { 480 struct audio_device *device = data; 481 struct gateway *gw = device->gateway; 482 struct hf_agent *agent; 483 const char *path, *name; 484 485 if (gw->agent) 486 return btd_error_already_exists(msg); 487 488 if (!dbus_message_get_args(msg, NULL, DBUS_TYPE_OBJECT_PATH, &path, 489 DBUS_TYPE_INVALID)) 490 return btd_error_invalid_args(msg); 491 492 name = dbus_message_get_sender(msg); 493 agent = g_new0(struct hf_agent, 1); 494 495 agent->name = g_strdup(name); 496 agent->path = g_strdup(path); 497 498 agent->watch = g_dbus_add_disconnect_watch(conn, name, 499 agent_exited, gw, NULL); 500 501 gw->agent = agent; 502 503 return dbus_message_new_method_return(msg); 504 } 505 506 static DBusMessage *unregister_agent(DBusConnection *conn, 507 DBusMessage *msg, void *data) 508 { 509 struct audio_device *device = data; 510 struct gateway *gw = device->gateway; 511 const char *path; 512 513 if (!gw->agent) 514 goto done; 515 516 if (strcmp(gw->agent->name, dbus_message_get_sender(msg)) != 0) 517 return btd_error_not_authorized(msg); 518 519 if (!dbus_message_get_args(msg, NULL, 520 DBUS_TYPE_OBJECT_PATH, &path, 521 DBUS_TYPE_INVALID)) 522 return btd_error_invalid_args(msg); 523 524 if (strcmp(gw->agent->path, path) != 0) 525 return btd_error_does_not_exist(msg); 526 527 g_dbus_remove_watch(device->conn, gw->agent->watch); 528 529 agent_free(gw->agent); 530 gw->agent = NULL; 531 532 done: 533 return dbus_message_new_method_return(msg); 534 } 535 536 static GDBusMethodTable gateway_methods[] = { 537 { "Connect", "", "", ag_connect, G_DBUS_METHOD_FLAG_ASYNC }, 538 { "Disconnect", "", "", ag_disconnect, G_DBUS_METHOD_FLAG_ASYNC }, 539 { "GetProperties", "", "a{sv}", ag_get_properties }, 540 { "RegisterAgent", "o", "", register_agent }, 541 { "UnregisterAgent", "o", "", unregister_agent }, 542 { NULL, NULL, NULL, NULL } 543 }; 544 545 static GDBusSignalTable gateway_signals[] = { 546 { "PropertyChanged", "sv" }, 547 { NULL, NULL } 548 }; 549 550 static void path_unregister(void *data) 551 { 552 struct audio_device *dev = data; 553 554 DBG("Unregistered interface %s on path %s", 555 AUDIO_GATEWAY_INTERFACE, dev->path); 556 557 gateway_close(dev); 558 559 g_free(dev->gateway); 560 dev->gateway = NULL; 561 } 562 563 void gateway_unregister(struct audio_device *dev) 564 { 565 if (dev->gateway->agent) 566 agent_disconnect(dev, dev->gateway->agent); 567 568 g_dbus_unregister_interface(dev->conn, dev->path, 569 AUDIO_GATEWAY_INTERFACE); 570 } 571 572 struct gateway *gateway_init(struct audio_device *dev) 573 { 574 if (DBUS_TYPE_UNIX_FD < 0) 575 return NULL; 576 577 if (!g_dbus_register_interface(dev->conn, dev->path, 578 AUDIO_GATEWAY_INTERFACE, 579 gateway_methods, gateway_signals, 580 NULL, dev, path_unregister)) 581 return NULL; 582 583 return g_new0(struct gateway, 1); 584 585 } 586 587 gboolean gateway_is_connected(struct audio_device *dev) 588 { 589 return (dev && dev->gateway && 590 dev->gateway->state == GATEWAY_STATE_CONNECTED); 591 } 592 593 int gateway_connect_rfcomm(struct audio_device *dev, GIOChannel *io) 594 { 595 if (!io) 596 return -EINVAL; 597 598 dev->gateway->rfcomm = g_io_channel_ref(io); 599 600 return 0; 601 } 602 603 int gateway_connect_sco(struct audio_device *dev, GIOChannel *io) 604 { 605 struct gateway *gw = dev->gateway; 606 607 if (gw->sco) 608 return -EISCONN; 609 610 gw->sco = g_io_channel_ref(io); 611 612 g_io_add_watch(gw->sco, G_IO_ERR | G_IO_HUP | G_IO_NVAL, 613 (GIOFunc) sco_io_cb, dev); 614 615 change_state(dev, GATEWAY_STATE_PLAYING); 616 617 return 0; 618 } 619 620 void gateway_start_service(struct audio_device *dev) 621 { 622 struct gateway *gw = dev->gateway; 623 GError *err = NULL; 624 625 if (gw->rfcomm == NULL) 626 return; 627 628 if (!bt_io_accept(gw->rfcomm, rfcomm_connect_cb, dev, NULL, &err)) { 629 error("bt_io_accept: %s", err->message); 630 g_error_free(err); 631 } 632 } 633 634 /* These are functions to be called from unix.c for audio system 635 * ifaces (alsa, gstreamer, etc.) */ 636 gboolean gateway_request_stream(struct audio_device *dev, 637 gateway_stream_cb_t cb, void *user_data) 638 { 639 struct gateway *gw = dev->gateway; 640 GError *err = NULL; 641 GIOChannel *io; 642 643 if (!gw->rfcomm) { 644 gw->sco_start_cb = cb; 645 gw->sco_start_cb_data = user_data; 646 get_records(dev); 647 } else if (!gw->sco) { 648 gw->sco_start_cb = cb; 649 gw->sco_start_cb_data = user_data; 650 io = bt_io_connect(BT_IO_SCO, sco_connect_cb, dev, NULL, &err, 651 BT_IO_OPT_SOURCE_BDADDR, &dev->src, 652 BT_IO_OPT_DEST_BDADDR, &dev->dst, 653 BT_IO_OPT_INVALID); 654 if (!io) { 655 error("%s", err->message); 656 g_error_free(err); 657 return FALSE; 658 } 659 } else if (cb) 660 cb(dev, err, user_data); 661 662 return TRUE; 663 } 664 665 int gateway_config_stream(struct audio_device *dev, gateway_stream_cb_t sco_cb, 666 void *user_data) 667 { 668 struct gateway *gw = dev->gateway; 669 670 if (!gw->rfcomm) { 671 gw->sco_start_cb = sco_cb; 672 gw->sco_start_cb_data = user_data; 673 return get_records(dev); 674 } 675 676 if (sco_cb) 677 sco_cb(dev, NULL, user_data); 678 679 return 0; 680 } 681 682 gboolean gateway_cancel_stream(struct audio_device *dev, unsigned int id) 683 { 684 gateway_close(dev); 685 return TRUE; 686 } 687 688 int gateway_get_sco_fd(struct audio_device *dev) 689 { 690 struct gateway *gw = dev->gateway; 691 692 if (!gw || !gw->sco) 693 return -1; 694 695 return g_io_channel_unix_get_fd(gw->sco); 696 } 697 698 void gateway_suspend_stream(struct audio_device *dev) 699 { 700 struct gateway *gw = dev->gateway; 701 702 if (!gw || !gw->sco) 703 return; 704 705 g_io_channel_shutdown(gw->sco, TRUE, NULL); 706 g_io_channel_unref(gw->sco); 707 gw->sco = NULL; 708 gw->sco_start_cb = NULL; 709 gw->sco_start_cb_data = NULL; 710 change_state(dev, GATEWAY_STATE_CONNECTED); 711 } 712