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