device.c revision 11b636e6b857a67c802a739234b4f14d1d3ce93b
1/* 2 * 3 * BlueZ - Bluetooth protocol stack for Linux 4 * 5 * Copyright (C) 2006-2007 Nokia Corporation 6 * Copyright (C) 2004-2009 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 <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 "logging.h" 47#include "textfile.h" 48 49#include "error.h" 50#include "ipc.h" 51#include "dbus-common.h" 52#include "device.h" 53#include "avdtp.h" 54#include "control.h" 55#include "headset.h" 56#include "sink.h" 57 58#define AUDIO_INTERFACE "org.bluez.Audio" 59 60#define CONTROL_CONNECT_TIMEOUT 2 61#define AVDTP_CONNECT_TIMEOUT 1 62#define HEADSET_CONNECT_TIMEOUT 1 63 64typedef enum { 65 AUDIO_STATE_DISCONNECTED, 66 AUDIO_STATE_CONNECTING, 67 AUDIO_STATE_CONNECTED, 68} audio_state_t; 69 70struct dev_priv { 71 audio_state_t state; 72 73 headset_state_t hs_state; 74 avdtp_state_t avdtp_state; 75 avctp_state_t avctp_state; 76 77 guint control_timer; 78 guint avdtp_timer; 79 guint headset_timer; 80}; 81 82static unsigned int avdtp_callback_id = 0; 83static unsigned int avctp_callback_id = 0; 84static unsigned int headset_callback_id = 0; 85 86static void device_free(struct audio_device *dev) 87{ 88 if (dev->conn) 89 dbus_connection_unref(dev->conn); 90 91 if (dev->priv) { 92 if (dev->priv->control_timer) 93 g_source_remove(dev->priv->control_timer); 94 if (dev->priv->avdtp_timer) 95 g_source_remove(dev->priv->avdtp_timer); 96 if (dev->priv->headset_timer) 97 g_source_remove(dev->priv->headset_timer); 98 g_free(dev->priv); 99 } 100 101 g_free(dev->path); 102 g_free(dev); 103} 104 105static const char *state2str(audio_state_t state) 106{ 107 switch (state) { 108 case AUDIO_STATE_DISCONNECTED: 109 return "disconnected"; 110 case AUDIO_STATE_CONNECTING: 111 return "connecting"; 112 case AUDIO_STATE_CONNECTED: 113 return "connected"; 114 default: 115 error("Invalid audio state %d", state); 116 return NULL; 117 } 118} 119 120static void device_set_state(struct audio_device *dev, audio_state_t new_state) 121{ 122 const char *state_str; 123 124 state_str = state2str(new_state); 125 if (!state_str) 126 return; 127 128 if (dev->priv->state == new_state) { 129 debug("state change attempted from %s to %s", 130 state_str, state_str); 131 return; 132 } 133 134 dev->priv->state = new_state; 135 136 emit_property_changed(dev->conn, dev->path, 137 AUDIO_INTERFACE, "State", 138 DBUS_TYPE_STRING, &state_str); 139} 140 141static gboolean control_connect_timeout(gpointer user_data) 142{ 143 struct audio_device *dev = user_data; 144 145 dev->priv->control_timer = 0; 146 147 if (dev->control) 148 avrcp_connect(dev); 149 150 return FALSE; 151} 152 153static gboolean device_set_control_timer(struct audio_device *dev) 154{ 155 struct dev_priv *priv = dev->priv; 156 157 if (!dev->control) 158 return FALSE; 159 160 if (priv->control_timer) 161 return FALSE; 162 163 priv->control_timer = g_timeout_add_seconds(CONTROL_CONNECT_TIMEOUT, 164 control_connect_timeout, 165 dev); 166 167 return TRUE; 168} 169 170static void device_remove_control_timer(struct audio_device *dev) 171{ 172 if (dev->priv->control_timer) 173 g_source_remove(dev->priv->control_timer); 174 dev->priv->control_timer = 0; 175} 176 177static gboolean avdtp_connect_timeout(gpointer user_data) 178{ 179 struct audio_device *dev = user_data; 180 181 dev->priv->avdtp_timer = 0; 182 183 if (dev->sink) { 184 struct avdtp *session = avdtp_get(&dev->src, &dev->dst); 185 186 if (!session) 187 return FALSE; 188 189 sink_setup_stream(dev->sink, session); 190 avdtp_unref(session); 191 } 192 193 return FALSE; 194} 195 196static gboolean device_set_avdtp_timer(struct audio_device *dev) 197{ 198 struct dev_priv *priv = dev->priv; 199 200 if (!dev->sink) 201 return FALSE; 202 203 if (priv->avdtp_timer) 204 return FALSE; 205 206 priv->avdtp_timer = g_timeout_add_seconds(AVDTP_CONNECT_TIMEOUT, 207 avdtp_connect_timeout, 208 dev); 209 210 return TRUE; 211} 212 213static void device_remove_avdtp_timer(struct audio_device *dev) 214{ 215 if (dev->priv->avdtp_timer) 216 g_source_remove(dev->priv->avdtp_timer); 217 dev->priv->avdtp_timer = 0; 218} 219 220static gboolean headset_connect_timeout(gpointer user_data) 221{ 222 struct audio_device *dev = user_data; 223 224 dev->priv->headset_timer = 0; 225 226 if (dev->headset) 227 headset_config_stream(dev, NULL, NULL); 228 229 return FALSE; 230} 231 232static gboolean device_set_headset_timer(struct audio_device *dev) 233{ 234 struct dev_priv *priv = dev->priv; 235 236 if (!dev->headset) 237 return FALSE; 238 239 if (priv->headset_timer) 240 return FALSE; 241 242 priv->headset_timer = g_timeout_add_seconds(HEADSET_CONNECT_TIMEOUT, 243 headset_connect_timeout, dev); 244 245 return TRUE; 246} 247 248static void device_remove_headset_timer(struct audio_device *dev) 249{ 250 if (dev->priv->headset_timer) 251 g_source_remove(dev->priv->headset_timer); 252 dev->priv->headset_timer = 0; 253} 254 255static void device_avdtp_cb(struct audio_device *dev, 256 struct avdtp *session, 257 avdtp_session_state_t old_state, 258 avdtp_session_state_t new_state, 259 void *user_data) 260{ 261 struct dev_priv *priv = dev->priv; 262 263 if (!dev->sink) 264 return; 265 266 dev->priv->avdtp_state = new_state; 267 268 switch (new_state) { 269 case AVDTP_SESSION_STATE_DISCONNECTED: 270 if (dev->control) { 271 device_remove_control_timer(dev); 272 avrcp_disconnect(dev); 273 } 274 if (priv->hs_state == HEADSET_STATE_DISCONNECTED) 275 device_set_state(dev, AUDIO_STATE_DISCONNECTED); 276 else if (old_state == AVDTP_SESSION_STATE_CONNECTING && 277 priv->hs_state == HEADSET_STATE_CONNECTED) 278 device_set_state(dev, AUDIO_STATE_CONNECTED); 279 break; 280 case AVDTP_SESSION_STATE_CONNECTING: 281 device_remove_avdtp_timer(dev); 282 if (priv->hs_state == HEADSET_STATE_DISCONNECTED) 283 device_set_state(dev, AUDIO_STATE_CONNECTING); 284 break; 285 case AVDTP_SESSION_STATE_CONNECTED: 286 if (dev->control) { 287 if (avdtp_stream_setup_active(session)) 288 device_set_control_timer(dev); 289 else 290 avrcp_connect(dev); 291 } 292 if (dev->auto_connect) { 293 if (!dev->headset) 294 device_set_state(dev, AUDIO_STATE_CONNECTED); 295 if (priv->hs_state == HEADSET_STATE_DISCONNECTED) 296 device_set_headset_timer(dev); 297 else if (priv->hs_state == HEADSET_STATE_CONNECTED) 298 device_set_state(dev, AUDIO_STATE_CONNECTED); 299 } else if (priv->hs_state != HEADSET_STATE_CONNECTED) 300 device_set_state(dev, AUDIO_STATE_CONNECTED); 301 break; 302 } 303} 304 305static void device_avctp_cb(struct audio_device *dev, 306 avctp_state_t old_state, 307 avctp_state_t new_state, 308 void *user_data) 309{ 310 if (!dev->control) 311 return; 312 313 dev->priv->avctp_state = new_state; 314 315 switch (new_state) { 316 case AVCTP_STATE_DISCONNECTED: 317 break; 318 case AVCTP_STATE_CONNECTING: 319 device_remove_control_timer(dev); 320 break; 321 case AVCTP_STATE_CONNECTED: 322 break; 323 } 324} 325 326static void device_headset_cb(struct audio_device *dev, 327 headset_state_t old_state, 328 headset_state_t new_state, 329 void *user_data) 330{ 331 struct dev_priv *priv = dev->priv; 332 333 if (!dev->headset) 334 return; 335 336 priv->hs_state = new_state; 337 338 switch (new_state) { 339 case HEADSET_STATE_DISCONNECTED: 340 device_remove_avdtp_timer(dev); 341 if (priv->avdtp_state == AVDTP_SESSION_STATE_DISCONNECTED) 342 device_set_state(dev, AUDIO_STATE_DISCONNECTED); 343 else if (old_state == HEADSET_STATE_CONNECT_IN_PROGRESS && 344 priv->avdtp_state == AVDTP_SESSION_STATE_CONNECTED) 345 device_set_state(dev, AUDIO_STATE_CONNECTED); 346 break; 347 case HEADSET_STATE_CONNECT_IN_PROGRESS: 348 device_remove_headset_timer(dev); 349 if (priv->avdtp_state == AVDTP_SESSION_STATE_DISCONNECTED) 350 device_set_state(dev, AUDIO_STATE_CONNECTING); 351 break; 352 case HEADSET_STATE_CONNECTED: 353 if (old_state == HEADSET_STATE_PLAYING) 354 break; 355 if (dev->auto_connect) { 356 if (!dev->sink) 357 device_set_state(dev, AUDIO_STATE_CONNECTED); 358 else if (priv->avdtp_state == AVDTP_SESSION_STATE_DISCONNECTED) 359 device_set_avdtp_timer(dev); 360 else if (priv->avdtp_state == AVDTP_SESSION_STATE_CONNECTED) 361 device_set_state(dev, AUDIO_STATE_CONNECTED); 362 } else if (priv->avdtp_state != AVDTP_SESSION_STATE_CONNECTED) 363 device_set_state(dev, AUDIO_STATE_CONNECTED); 364 break; 365 case HEADSET_STATE_PLAY_IN_PROGRESS: 366 break; 367 case HEADSET_STATE_PLAYING: 368 break; 369 } 370} 371 372static DBusMessage *dev_connect(DBusConnection *conn, DBusMessage *msg, 373 void *data) 374{ 375 return g_dbus_create_error(msg, ERROR_INTERFACE ".NotImplemented", 376 "Not yet implemented"); 377} 378 379static DBusMessage *dev_disconnect(DBusConnection *conn, DBusMessage *msg, 380 void *data) 381{ 382 return g_dbus_create_error(msg, ERROR_INTERFACE ".NotImplemented", 383 "Not yet implemented"); 384} 385 386static DBusMessage *dev_get_properties(DBusConnection *conn, DBusMessage *msg, 387 void *data) 388{ 389 struct audio_device *device = data; 390 DBusMessage *reply; 391 DBusMessageIter iter; 392 DBusMessageIter dict; 393 const char *state; 394 395 reply = dbus_message_new_method_return(msg); 396 if (!reply) 397 return NULL; 398 399 dbus_message_iter_init_append(reply, &iter); 400 401 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, 402 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING 403 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING 404 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict); 405 406 /* State */ 407 state = state2str(device->priv->state); 408 if (state) 409 dict_append_entry(&dict, "State", DBUS_TYPE_STRING, &state); 410 411 dbus_message_iter_close_container(&iter, &dict); 412 413 return reply; 414} 415 416static GDBusMethodTable dev_methods[] = { 417 { "Connect", "", "", dev_connect, 418 G_DBUS_METHOD_FLAG_ASYNC }, 419 { "Disconnect", "", "", dev_disconnect }, 420 { "GetProperties", "", "a{sv}",dev_get_properties }, 421 { NULL, NULL, NULL, NULL } 422}; 423 424static GDBusSignalTable dev_signals[] = { 425 { "PropertyChanged", "sv" }, 426 { NULL, NULL } 427}; 428 429struct audio_device *audio_device_register(DBusConnection *conn, 430 const char *path, const bdaddr_t *src, 431 const bdaddr_t *dst) 432{ 433 struct audio_device *dev; 434 435 if (!conn || !path) 436 return NULL; 437 438 dev = g_new0(struct audio_device, 1); 439 440 dev->path = g_strdup(path); 441 bacpy(&dev->dst, dst); 442 bacpy(&dev->src, src); 443 dev->conn = dbus_connection_ref(conn); 444 dev->priv = g_new0(struct dev_priv, 1); 445 dev->priv->state = AUDIO_STATE_DISCONNECTED; 446 447 if (!g_dbus_register_interface(dev->conn, dev->path, 448 AUDIO_INTERFACE, 449 dev_methods, dev_signals, NULL, 450 dev, NULL)) { 451 error("Unable to register %s on %s", AUDIO_INTERFACE, 452 dev->path); 453 device_free(dev); 454 return NULL; 455 } 456 457 debug("Registered interface %s on path %s", AUDIO_INTERFACE, 458 dev->path); 459 460 if (avdtp_callback_id == 0) 461 avdtp_callback_id = avdtp_add_state_cb(device_avdtp_cb, NULL); 462 463 if (avctp_callback_id == 0) 464 avctp_callback_id = avctp_add_state_cb(device_avctp_cb, NULL); 465 466 if (headset_callback_id == 0) 467 headset_callback_id = headset_add_state_cb(device_headset_cb, 468 NULL); 469 470 return dev; 471} 472 473gboolean audio_device_is_connected(struct audio_device *dev, 474 const char *interface) 475{ 476 if (!interface) { 477 if ((dev->sink || dev->source) && 478 avdtp_is_connected(&dev->src, &dev->dst)) 479 return TRUE; 480 481 if (dev->headset && headset_is_active(dev)) 482 return TRUE; 483 } 484 else if (!strcmp(interface, AUDIO_SINK_INTERFACE) && dev->sink && 485 avdtp_is_connected(&dev->src, &dev->dst)) 486 return TRUE; 487 else if (!strcmp(interface, AUDIO_SOURCE_INTERFACE) && dev->source && 488 avdtp_is_connected(&dev->src, &dev->dst)) 489 return TRUE; 490 else if (!strcmp(interface, AUDIO_HEADSET_INTERFACE) && dev->headset && 491 headset_is_active(dev)) 492 return TRUE; 493 else if (!strcmp(interface, AUDIO_CONTROL_INTERFACE) && dev->control && 494 control_is_active(dev)) 495 return TRUE; 496 497 return FALSE; 498} 499 500void audio_device_unregister(struct audio_device *device) 501{ 502 if (device->headset) 503 headset_unregister(device); 504 505 if (device->sink) 506 sink_unregister(device); 507 508 if (device->control) 509 control_unregister(device); 510 511 device_free(device); 512} 513