device.c revision de72271829f6bfd21aa6550a2ac6d81e35b53cad
1/* 2 * 3 * BlueZ - Bluetooth protocol stack for Linux 4 * 5 * Copyright (C) 2006-2007 Nokia Corporation 6 * Copyright (C) 2004-2007 Marcel Holtmann <marcel@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 <netinet/in.h> 34 35#include <glib.h> 36#include <dbus/dbus.h> 37 38#include <bluetooth/bluetooth.h> 39#include <bluetooth/hci.h> 40#include <bluetooth/hci_lib.h> 41#include <bluetooth/sdp.h> 42#include <bluetooth/sdp_lib.h> 43 44#include "dbus.h" 45#include "dbus-helper.h" 46#include "logging.h" 47#include "textfile.h" 48 49#include "error.h" 50#include "ipc.h" 51#include "device.h" 52#include "avdtp.h" 53#include "control.h" 54#include "headset.h" 55#include "sink.h" 56 57static DBusHandlerResult device_get_address(DBusConnection *conn, 58 DBusMessage *msg, void *data) 59{ 60 struct device *device = data; 61 DBusMessage *reply; 62 char address[18], *ptr = address; 63 64 reply = dbus_message_new_method_return(msg); 65 if (!reply) 66 return DBUS_HANDLER_RESULT_NEED_MEMORY; 67 68 ba2str(&device->dst, address); 69 70 dbus_message_append_args(reply, DBUS_TYPE_STRING, &ptr, 71 DBUS_TYPE_INVALID); 72 73 return send_message_and_unref(conn, reply); 74} 75 76static DBusHandlerResult device_get_name(DBusConnection *conn, 77 DBusMessage *msg, void *data) 78{ 79 struct device *device = data; 80 DBusMessage *reply, *reply2, *msg2; 81 DBusError derr; 82 const char *name; 83 char address[18], *addr_ptr = address; 84 85 msg2 = dbus_message_new_method_call("org.bluez", device->adapter_path, 86 "org.bluez.Adapter", "GetRemoteName"); 87 if (!msg2) 88 return DBUS_HANDLER_RESULT_NEED_MEMORY; 89 90 ba2str(&device->dst, address); 91 dbus_message_append_args(msg2, DBUS_TYPE_STRING, &addr_ptr, 92 DBUS_TYPE_INVALID); 93 94 dbus_error_init(&derr); 95 reply2 = dbus_connection_send_with_reply_and_block(conn, msg2, -1, 96 &derr); 97 98 dbus_message_unref(msg2); 99 100 if (dbus_error_is_set(&derr)) { 101 error("%s GetRemoteName(): %s", device->adapter_path, 102 derr.message); 103 dbus_error_free(&derr); 104 return err_failed(conn, msg, "Unable to get remote name"); 105 } 106 107 108 reply = dbus_message_new_method_return(msg); 109 if (!reply) 110 return DBUS_HANDLER_RESULT_NEED_MEMORY; 111 112 dbus_message_get_args(reply2, NULL, 113 DBUS_TYPE_STRING, &name, 114 DBUS_TYPE_INVALID); 115 116 dbus_message_append_args(reply, DBUS_TYPE_STRING, &name, 117 DBUS_TYPE_INVALID); 118 119 dbus_message_unref(reply2); 120 121 return send_message_and_unref(conn, reply); 122} 123 124static DBusHandlerResult device_get_adapter(DBusConnection *conn, 125 DBusMessage *msg, void *data) 126{ 127 struct device *device = data; 128 DBusMessage *reply; 129 char address[18], *ptr = address; 130 131 reply = dbus_message_new_method_return(msg); 132 if (!reply) 133 return DBUS_HANDLER_RESULT_NEED_MEMORY; 134 135 ba2str(&device->src, address); 136 137 dbus_message_append_args(reply, DBUS_TYPE_STRING, &ptr, 138 DBUS_TYPE_INVALID); 139 140 return send_message_and_unref(conn, reply); 141} 142 143 144static DBusHandlerResult device_get_connected(DBusConnection *conn, 145 DBusMessage *msg, void *data) 146{ 147 DBusMessageIter iter, array_iter; 148 struct device *device = data; 149 DBusMessage *reply; 150 const char *iface; 151 152 reply = dbus_message_new_method_return(msg); 153 if (!reply) 154 return DBUS_HANDLER_RESULT_NEED_MEMORY; 155 156 dbus_message_iter_init_append(reply, &iter); 157 158 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, 159 DBUS_TYPE_STRING_AS_STRING, 160 &array_iter); 161 162 if (device->headset && 163 headset_get_state(device) >= HEADSET_STATE_CONNECTED) { 164 iface = AUDIO_HEADSET_INTERFACE; 165 dbus_message_iter_append_basic(&array_iter, 166 DBUS_TYPE_STRING, &iface); 167 } 168 169 dbus_message_iter_close_container(&iter, &array_iter); 170 171 return send_message_and_unref(conn, reply); 172} 173 174static DBusMethodVTable device_methods[] = { 175 { "GetAddress", device_get_address, "", "s" }, 176 { "GetName", device_get_name, "", "s" }, 177 { "GetAdapter", device_get_adapter, "", "s" }, 178 { "GetConnectedInterfaces", device_get_connected, "", "as" }, 179 { NULL, NULL, NULL, NULL } 180}; 181 182static void device_free(struct device *dev) 183{ 184 if (dev->headset) 185 headset_free(dev); 186 187 if (dev->sink) 188 sink_free(dev); 189 190 if (dev->control) 191 control_free(dev); 192 193 if (dev->conn) 194 dbus_connection_unref(dev->conn); 195 196 if (dev->adapter_path) 197 g_free(dev->adapter_path); 198 199 if (dev->path) 200 g_free(dev->path); 201 202 g_free(dev); 203} 204 205static void device_unregister(DBusConnection *conn, void *data) 206{ 207 struct device *device = data; 208 209 info("Unregistered device path:%s", device->path); 210 211 device_free(device); 212} 213 214char *find_adapter(DBusConnection *conn, bdaddr_t *src) 215{ 216 DBusMessage *msg, *reply; 217 DBusError derr; 218 char address[18], *addr_ptr = address; 219 char *path, *ret; 220 221 msg = dbus_message_new_method_call("org.bluez", "/org/bluez", 222 "org.bluez.Manager", 223 "FindAdapter"); 224 if (!msg) { 225 error("Unable to allocate new method call"); 226 return NULL; 227 } 228 229 ba2str(src, address); 230 231 dbus_message_append_args(msg, DBUS_TYPE_STRING, &addr_ptr, 232 DBUS_TYPE_INVALID); 233 234 dbus_error_init(&derr); 235 reply = dbus_connection_send_with_reply_and_block(conn, msg, -1, 236 &derr); 237 238 dbus_message_unref(msg); 239 240 if (dbus_error_is_set(&derr) || 241 dbus_set_error_from_message(&derr, reply)) { 242 error("FindAdapter(%s) failed: %s", address, derr.message); 243 dbus_error_free(&derr); 244 return NULL; 245 } 246 247 dbus_error_init(&derr); 248 dbus_message_get_args(reply, &derr, 249 DBUS_TYPE_STRING, &path, 250 DBUS_TYPE_INVALID); 251 252 if (dbus_error_is_set(&derr)) { 253 error("Unable to get message args"); 254 dbus_message_unref(reply); 255 dbus_error_free(&derr); 256 return FALSE; 257 } 258 259 ret = g_strdup(path); 260 261 dbus_message_unref(reply); 262 263 debug("Got path %s for adapter with address %s", ret, address); 264 265 return ret; 266} 267 268struct device *device_register(DBusConnection *conn, 269 const char *path, bdaddr_t *bda) 270{ 271 struct device *dev; 272 bdaddr_t src; 273 int dev_id; 274 275 if (!conn || !path) 276 return NULL; 277 278 bacpy(&src, BDADDR_ANY); 279 dev_id = hci_get_route(&src); 280 if ((dev_id < 0) || (hci_devba(dev_id, &src) < 0)) 281 return NULL; 282 283 dev = g_new0(struct device, 1); 284 285 dev->adapter_path = find_adapter(conn, &src); 286 if (!dev->adapter_path) { 287 device_free(dev); 288 return NULL; 289 } 290 291 if (!dbus_connection_create_object_path(conn, path, dev, 292 device_unregister)) { 293 error("D-Bus failed to register %s path", path); 294 device_free(dev); 295 return NULL; 296 } 297 298 if (!dbus_connection_register_interface(conn, path, 299 AUDIO_DEVICE_INTERFACE, device_methods, NULL, NULL)) { 300 error("Failed to register %s interface to %s", 301 AUDIO_DEVICE_INTERFACE, path); 302 dbus_connection_destroy_object_path(conn, path); 303 return NULL; 304 } 305 306 dev->path = g_strdup(path); 307 bacpy(&dev->dst, bda); 308 bacpy(&dev->src, &src); 309 bacpy(&dev->store, &src); 310 dev->conn = dbus_connection_ref(conn); 311 312 return dev; 313} 314 315int device_store(struct device *dev, gboolean is_default) 316{ 317 char value[64]; 318 char filename[PATH_MAX + 1]; 319 char src_addr[18], dst_addr[18]; 320 int offset = 0; 321 322 if (!dev->path) 323 return -EINVAL; 324 325 ba2str(&dev->dst, dst_addr); 326 ba2str(&dev->store, src_addr); 327 328 create_name(filename, PATH_MAX, STORAGEDIR, src_addr, "audio"); 329 create_file(filename, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 330 331 if (is_default) 332 textfile_put(filename, "default", dst_addr); 333 if (dev->headset) { 334 snprintf(value, 64, "headset "); 335 offset += strlen("headset "); 336 } 337 if (dev->gateway) { 338 snprintf(value + offset, 64 - offset, "gateway "); 339 offset += strlen("gateway "); 340 } 341 if (dev->sink) { 342 snprintf(value + offset, 64 - offset, "sink "); 343 offset += strlen("sink "); 344 } 345 if (dev->source) { 346 snprintf(value + offset, 64 - offset, "source "); 347 offset += strlen("source "); 348 } 349 if (dev->control) { 350 snprintf(value + offset, 64 - offset, "control "); 351 offset += strlen("control "); 352 } 353 if (dev->target) 354 snprintf(value + offset, 64 - offset, "target"); 355 356 return textfile_put(filename, dst_addr, value); 357} 358 359int device_remove_stored(struct device *dev) 360{ 361 char filename[PATH_MAX + 1]; 362 char src_addr[18], dst_addr[18]; 363 364 ba2str(&dev->dst, dst_addr); 365 ba2str(&dev->store, src_addr); 366 367 create_name(filename, PATH_MAX, STORAGEDIR, src_addr, "audio"); 368 369 return textfile_del(filename, dst_addr); 370} 371 372void device_finish_sdp_transaction(struct device *dev) 373{ 374 char address[18], *addr_ptr = address; 375 DBusMessage *msg, *reply; 376 DBusError derr; 377 378 ba2str(&dev->dst, address); 379 380 msg = dbus_message_new_method_call("org.bluez", dev->adapter_path, 381 "org.bluez.Adapter", 382 "FinishRemoteServiceTransaction"); 383 if (!msg) { 384 error("Unable to allocate new method call"); 385 return; 386 } 387 388 dbus_message_append_args(msg, DBUS_TYPE_STRING, &addr_ptr, 389 DBUS_TYPE_INVALID); 390 391 dbus_error_init(&derr); 392 reply = dbus_connection_send_with_reply_and_block(dev->conn, 393 msg, -1, &derr); 394 395 dbus_message_unref(msg); 396 397 if (dbus_error_is_set(&derr) || 398 dbus_set_error_from_message(&derr, reply)) { 399 error("FinishRemoteServiceTransaction(%s) failed: %s", 400 address, derr.message); 401 dbus_error_free(&derr); 402 return; 403 } 404 405 dbus_message_unref(reply); 406} 407 408#if 0 409static avdtp_state_t ipc_to_avdtp_state(uint8_t ipc_state) 410{ 411 switch (ipc_state) { 412 case STATE_DISCONNECTED: 413 return AVDTP_STATE_IDLE; 414 case STATE_CONNECTING: 415 return AVDTP_STATE_CONFIGURED; 416 case STATE_CONNECTED: 417 return AVDTP_STATE_OPEN; 418 case STATE_STREAM_STARTING: 419 case STATE_STREAMING: 420 return AVDTP_STATE_STREAMING; 421 default: 422 error("Unknown ipc state"); 423 return AVDTP_STATE_IDLE; 424 } 425} 426 427static headset_state_t ipc_to_hs_state(uint8_t ipc_state) 428{ 429 switch (ipc_state) { 430 case STATE_DISCONNECTED: 431 return HEADSET_STATE_DISCONNECTED; 432 case STATE_CONNECTING: 433 return HEADSET_STATE_CONNECT_IN_PROGRESS; 434 case STATE_CONNECTED: 435 return HEADSET_STATE_CONNECTED; 436 case STATE_STREAM_STARTING: 437 return HEADSET_STATE_PLAY_IN_PROGRESS; 438 case STATE_STREAMING: 439 return HEADSET_STATE_PLAYING; 440 default: 441 error("Unknown ipc state"); 442 return HEADSET_STATE_DISCONNECTED; 443 } 444} 445#endif 446 447static uint8_t avdtp_to_ipc_state(avdtp_state_t state) 448{ 449 switch (state) { 450 case AVDTP_STATE_IDLE: 451 return STATE_DISCONNECTED; 452 case AVDTP_STATE_CONFIGURED: 453 return STATE_CONNECTING; 454 case AVDTP_STATE_OPEN: 455 return STATE_CONNECTED; 456 case AVDTP_STATE_STREAMING: 457 return STATE_STREAMING; 458 default: 459 error("Unknown avdt state"); 460 return AVDTP_STATE_IDLE; 461 } 462} 463 464static uint8_t hs_to_ipc_state(headset_state_t state) 465{ 466 switch (state) { 467 case HEADSET_STATE_DISCONNECTED: 468 return STATE_DISCONNECTED; 469 case HEADSET_STATE_CONNECT_IN_PROGRESS: 470 return STATE_CONNECTING; 471 case HEADSET_STATE_CONNECTED: 472 return STATE_CONNECTED; 473 case HEADSET_STATE_PLAY_IN_PROGRESS: 474 return STATE_STREAMING; 475 default: 476 error("Unknown headset state"); 477 return AVDTP_STATE_IDLE; 478 } 479} 480 481uint8_t device_get_state(struct device *dev) 482{ 483 avdtp_state_t sink_state; 484 headset_state_t hs_state; 485 486 if (dev->sink && sink_is_active(dev)) { 487 sink_state = sink_get_state(dev); 488 return avdtp_to_ipc_state(sink_state); 489 } 490 else if (dev->headset && headset_is_active(dev)) { 491 hs_state = headset_get_state(dev); 492 return hs_to_ipc_state(hs_state); 493 } 494 else if (dev->control && control_is_active(dev)) 495 return STATE_CONNECTED; 496 497 return STATE_DISCONNECTED; 498} 499 500gboolean device_is_connected(struct device *dev, const char *interface) 501{ 502 if (!interface) { 503 if ((dev->sink || dev->source) && 504 avdtp_is_connected(&dev->src, &dev->dst)) 505 return TRUE; 506 507 if (dev->headset && headset_is_active(dev)) 508 return TRUE; 509 } 510 else if (!strcmp(interface, AUDIO_SINK_INTERFACE) && dev->sink && 511 avdtp_is_connected(&dev->src, &dev->dst)) 512 return TRUE; 513 else if (!strcmp(interface, AUDIO_SOURCE_INTERFACE) && dev->source && 514 avdtp_is_connected(&dev->src, &dev->dst)) 515 return TRUE; 516 else if (!strcmp(interface, AUDIO_HEADSET_INTERFACE) && dev->headset && 517 headset_is_active(dev)) 518 return TRUE; 519 else if (!strcmp(interface, AUDIO_CONTROL_INTERFACE) && dev->headset && 520 control_is_active(dev)) 521 return TRUE; 522 523 return FALSE; 524} 525