Home | History | Annotate | Download | only in audio
      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  *
      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 "log.h"
     47 #include "textfile.h"
     48 #include "../src/adapter.h"
     49 #include "../src/device.h"
     50 
     51 #include "error.h"
     52 #include "ipc.h"
     53 #include "dbus-common.h"
     54 #include "device.h"
     55 #include "unix.h"
     56 #include "avdtp.h"
     57 #include "control.h"
     58 #include "headset.h"
     59 #include "gateway.h"
     60 #include "sink.h"
     61 #include "source.h"
     62 
     63 #define AUDIO_INTERFACE "org.bluez.Audio"
     64 
     65 #define CONTROL_CONNECT_TIMEOUT 2
     66 #define AVDTP_CONNECT_TIMEOUT 1
     67 #define HEADSET_CONNECT_TIMEOUT 1
     68 
     69 typedef enum {
     70 	AUDIO_STATE_DISCONNECTED,
     71 	AUDIO_STATE_CONNECTING,
     72 	AUDIO_STATE_CONNECTED,
     73 } audio_state_t;
     74 
     75 struct service_auth {
     76 	service_auth_cb cb;
     77 	void *user_data;
     78 };
     79 
     80 struct dev_priv {
     81 	audio_state_t state;
     82 
     83 	headset_state_t hs_state;
     84 	sink_state_t sink_state;
     85 	avctp_state_t avctp_state;
     86 	GSList *auths;
     87 
     88 	DBusMessage *conn_req;
     89 	DBusMessage *dc_req;
     90 
     91 	guint control_timer;
     92 	guint avdtp_timer;
     93 	guint headset_timer;
     94 
     95 	gboolean authorized;
     96 	guint auth_idle_id;
     97 };
     98 
     99 static unsigned int sink_callback_id = 0;
    100 static unsigned int avctp_callback_id = 0;
    101 static unsigned int avdtp_callback_id = 0;
    102 static unsigned int headset_callback_id = 0;
    103 
    104 static void device_free(struct audio_device *dev)
    105 {
    106 	struct dev_priv *priv = dev->priv;
    107 
    108 	if (dev->conn)
    109 		dbus_connection_unref(dev->conn);
    110 
    111 	btd_device_unref(dev->btd_dev);
    112 
    113 	if (priv) {
    114 		if (priv->control_timer)
    115 			g_source_remove(priv->control_timer);
    116 		if (priv->avdtp_timer)
    117 			g_source_remove(priv->avdtp_timer);
    118 		if (priv->headset_timer)
    119 			g_source_remove(priv->headset_timer);
    120 		if (priv->dc_req)
    121 			dbus_message_unref(priv->dc_req);
    122 		if (priv->conn_req)
    123 			dbus_message_unref(priv->conn_req);
    124 		g_free(priv);
    125 	}
    126 
    127 	g_free(dev->path);
    128 	g_free(dev);
    129 }
    130 
    131 static const char *state2str(audio_state_t state)
    132 {
    133 	switch (state) {
    134 	case AUDIO_STATE_DISCONNECTED:
    135 		return "disconnected";
    136 	case AUDIO_STATE_CONNECTING:
    137 		return "connecting";
    138 	case AUDIO_STATE_CONNECTED:
    139 		return "connected";
    140 	default:
    141 		error("Invalid audio state %d", state);
    142 		return NULL;
    143 	}
    144 }
    145 
    146 static void device_set_state(struct audio_device *dev, audio_state_t new_state)
    147 {
    148 	struct dev_priv *priv = dev->priv;
    149 	const char *state_str;
    150 	DBusMessage *reply = NULL;
    151 
    152 	state_str = state2str(new_state);
    153 	if (!state_str)
    154 		return;
    155 
    156 	if (new_state == AUDIO_STATE_DISCONNECTED)
    157 		priv->authorized = FALSE;
    158 
    159 	if (dev->priv->state == new_state) {
    160 		DBG("state change attempted from %s to %s",
    161 							state_str, state_str);
    162 		return;
    163 	}
    164 
    165 	dev->priv->state = new_state;
    166 
    167 	if (priv->dc_req && new_state == AUDIO_STATE_DISCONNECTED) {
    168 		reply = dbus_message_new_method_return(priv->dc_req);
    169 		dbus_message_unref(priv->dc_req);
    170 		priv->dc_req = NULL;
    171 		g_dbus_send_message(dev->conn, reply);
    172 	}
    173 
    174 	if (priv->conn_req && new_state != AUDIO_STATE_CONNECTING) {
    175 		if (new_state == AUDIO_STATE_CONNECTED)
    176 			reply = dbus_message_new_method_return(priv->conn_req);
    177 		else
    178 			reply = g_dbus_create_error(priv->conn_req,
    179 							ERROR_INTERFACE
    180 							".ConnectFailed",
    181 							"Connecting failed");
    182 		dbus_message_unref(priv->conn_req);
    183 		priv->conn_req = NULL;
    184 		g_dbus_send_message(dev->conn, reply);
    185 	}
    186 
    187 	emit_property_changed(dev->conn, dev->path,
    188 				AUDIO_INTERFACE, "State",
    189 				DBUS_TYPE_STRING, &state_str);
    190 }
    191 
    192 static gboolean control_connect_timeout(gpointer user_data)
    193 {
    194 	struct audio_device *dev = user_data;
    195 
    196 	dev->priv->control_timer = 0;
    197 
    198 	if (dev->control)
    199 		avrcp_connect(dev);
    200 
    201 	return FALSE;
    202 }
    203 
    204 static gboolean device_set_control_timer(struct audio_device *dev)
    205 {
    206 	struct dev_priv *priv = dev->priv;
    207 
    208 	if (!dev->control)
    209 		return FALSE;
    210 
    211 	if (priv->control_timer)
    212 		return FALSE;
    213 
    214 	priv->control_timer = g_timeout_add_seconds(CONTROL_CONNECT_TIMEOUT,
    215 							control_connect_timeout,
    216 							dev);
    217 
    218 	return TRUE;
    219 }
    220 
    221 static void device_remove_control_timer(struct audio_device *dev)
    222 {
    223 	if (dev->priv->control_timer)
    224 		g_source_remove(dev->priv->control_timer);
    225 	dev->priv->control_timer = 0;
    226 }
    227 
    228 static gboolean avdtp_connect_timeout(gpointer user_data)
    229 {
    230 	struct audio_device *dev = user_data;
    231 
    232 	dev->priv->avdtp_timer = 0;
    233 
    234 	if (dev->sink) {
    235 		struct avdtp *session = avdtp_get(&dev->src, &dev->dst);
    236 
    237 		if (!session)
    238 			return FALSE;
    239 
    240 		sink_setup_stream(dev->sink, session);
    241 		avdtp_unref(session);
    242 	}
    243 
    244 	return FALSE;
    245 }
    246 
    247 static gboolean device_set_avdtp_timer(struct audio_device *dev)
    248 {
    249 	struct dev_priv *priv = dev->priv;
    250 
    251 	if (!dev->sink)
    252 		return FALSE;
    253 
    254 	if (priv->avdtp_timer)
    255 		return FALSE;
    256 
    257 	priv->avdtp_timer = g_timeout_add_seconds(AVDTP_CONNECT_TIMEOUT,
    258 							avdtp_connect_timeout,
    259 							dev);
    260 
    261 	return TRUE;
    262 }
    263 
    264 static void device_remove_avdtp_timer(struct audio_device *dev)
    265 {
    266 	if (dev->priv->avdtp_timer)
    267 		g_source_remove(dev->priv->avdtp_timer);
    268 	dev->priv->avdtp_timer = 0;
    269 }
    270 
    271 static gboolean headset_connect_timeout(gpointer user_data)
    272 {
    273 	struct audio_device *dev = user_data;
    274 	struct dev_priv *priv = dev->priv;
    275 
    276 	dev->priv->headset_timer = 0;
    277 
    278 	if (dev->headset == NULL)
    279 		return FALSE;
    280 
    281 	if (headset_config_stream(dev, FALSE, NULL, NULL) == 0) {
    282 		if (priv->state != AUDIO_STATE_CONNECTED &&
    283 				(priv->sink_state == SINK_STATE_CONNECTED ||
    284 				priv->sink_state == SINK_STATE_PLAYING))
    285 			device_set_state(dev, AUDIO_STATE_CONNECTED);
    286 	}
    287 
    288 	return FALSE;
    289 }
    290 
    291 static gboolean device_set_headset_timer(struct audio_device *dev)
    292 {
    293 	struct dev_priv *priv = dev->priv;
    294 
    295 	if (!dev->headset)
    296 		return FALSE;
    297 
    298 	if (priv->headset_timer)
    299 		return FALSE;
    300 
    301 	priv->headset_timer = g_timeout_add_seconds(HEADSET_CONNECT_TIMEOUT,
    302 						headset_connect_timeout, dev);
    303 
    304 	return TRUE;
    305 }
    306 
    307 static void device_remove_headset_timer(struct audio_device *dev)
    308 {
    309 	if (dev->priv->headset_timer)
    310 		g_source_remove(dev->priv->headset_timer);
    311 	dev->priv->headset_timer = 0;
    312 }
    313 
    314 static void device_avdtp_cb(struct audio_device *dev, struct avdtp *session,
    315 				avdtp_session_state_t old_state,
    316 				avdtp_session_state_t new_state,
    317 				void *user_data)
    318 {
    319 	if (!dev->sink || !dev->control)
    320 		return;
    321 
    322 	if (new_state == AVDTP_SESSION_STATE_CONNECTED) {
    323 		if (avdtp_stream_setup_active(session))
    324 			device_set_control_timer(dev);
    325 		else
    326 			avrcp_connect(dev);
    327 	}
    328 }
    329 
    330 static void device_sink_cb(struct audio_device *dev,
    331 				sink_state_t old_state,
    332 				sink_state_t new_state,
    333 				void *user_data)
    334 {
    335 	struct dev_priv *priv = dev->priv;
    336 
    337 	if (!dev->sink)
    338 		return;
    339 
    340 	priv->sink_state = new_state;
    341 
    342 	switch (new_state) {
    343 	case SINK_STATE_DISCONNECTED:
    344 		if (dev->control) {
    345 			device_remove_control_timer(dev);
    346 			avrcp_disconnect(dev);
    347 		}
    348 		if (priv->hs_state != HEADSET_STATE_DISCONNECTED &&
    349 								priv->dc_req) {
    350 			headset_shutdown(dev);
    351 			break;
    352 		}
    353 		if (priv->hs_state == HEADSET_STATE_DISCONNECTED)
    354 			device_set_state(dev, AUDIO_STATE_DISCONNECTED);
    355 		else if (old_state == SINK_STATE_CONNECTING) {
    356 			switch (priv->hs_state) {
    357 			case HEADSET_STATE_CONNECTED:
    358 			case HEADSET_STATE_PLAY_IN_PROGRESS:
    359 			case HEADSET_STATE_PLAYING:
    360 				device_set_state(dev, AUDIO_STATE_CONNECTED);
    361 			default:
    362 				break;
    363 			}
    364 		}
    365 		break;
    366 	case SINK_STATE_CONNECTING:
    367 		device_remove_avdtp_timer(dev);
    368 		if (priv->hs_state == HEADSET_STATE_DISCONNECTED)
    369 			device_set_state(dev, AUDIO_STATE_CONNECTING);
    370 		break;
    371 	case SINK_STATE_CONNECTED:
    372 		if (old_state == SINK_STATE_PLAYING)
    373 			break;
    374 #ifdef ANDROID
    375 		android_set_high_priority(&dev->dst);
    376 #endif
    377 		if (dev->auto_connect) {
    378 			if (!dev->headset)
    379 				device_set_state(dev, AUDIO_STATE_CONNECTED);
    380 			else if (priv->hs_state == HEADSET_STATE_DISCONNECTED)
    381 				device_set_headset_timer(dev);
    382 			else if (priv->hs_state == HEADSET_STATE_CONNECTED ||
    383 					priv->hs_state == HEADSET_STATE_PLAY_IN_PROGRESS ||
    384 					priv->hs_state == HEADSET_STATE_PLAYING)
    385 				device_set_state(dev, AUDIO_STATE_CONNECTED);
    386 		} else if (priv->hs_state == HEADSET_STATE_DISCONNECTED ||
    387 				priv->hs_state == HEADSET_STATE_CONNECTING)
    388 			device_set_state(dev, AUDIO_STATE_CONNECTED);
    389 		break;
    390 	case SINK_STATE_PLAYING:
    391 		break;
    392 	}
    393 }
    394 
    395 static void device_avctp_cb(struct audio_device *dev,
    396 				avctp_state_t old_state,
    397 				avctp_state_t new_state,
    398 				void *user_data)
    399 {
    400 	if (!dev->control)
    401 		return;
    402 
    403 	dev->priv->avctp_state = new_state;
    404 
    405 	switch (new_state) {
    406 	case AVCTP_STATE_DISCONNECTED:
    407 		break;
    408 	case AVCTP_STATE_CONNECTING:
    409 		device_remove_control_timer(dev);
    410 		break;
    411 	case AVCTP_STATE_CONNECTED:
    412 		break;
    413 	}
    414 }
    415 
    416 static void device_headset_cb(struct audio_device *dev,
    417 				headset_state_t old_state,
    418 				headset_state_t new_state,
    419 				void *user_data)
    420 {
    421 	struct dev_priv *priv = dev->priv;
    422 
    423 	if (!dev->headset)
    424 		return;
    425 
    426 	priv->hs_state = new_state;
    427 
    428 	switch (new_state) {
    429 	case HEADSET_STATE_DISCONNECTED:
    430 		device_remove_avdtp_timer(dev);
    431 		if (priv->sink_state != SINK_STATE_DISCONNECTED &&
    432 						dev->sink && priv->dc_req) {
    433 			sink_shutdown(dev->sink);
    434 			break;
    435 		}
    436 		if (priv->sink_state == SINK_STATE_DISCONNECTED)
    437 			device_set_state(dev, AUDIO_STATE_DISCONNECTED);
    438 		else if (old_state == HEADSET_STATE_CONNECTING &&
    439 				(priv->sink_state == SINK_STATE_CONNECTED ||
    440 				priv->sink_state == SINK_STATE_PLAYING))
    441 			device_set_state(dev, AUDIO_STATE_CONNECTED);
    442 		break;
    443 	case HEADSET_STATE_CONNECTING:
    444 		device_remove_headset_timer(dev);
    445 		if (priv->sink_state == SINK_STATE_DISCONNECTED)
    446 			device_set_state(dev, AUDIO_STATE_CONNECTING);
    447 		break;
    448 	case HEADSET_STATE_CONNECTED:
    449 		if (old_state == HEADSET_STATE_CONNECTED ||
    450 				old_state == HEADSET_STATE_PLAY_IN_PROGRESS ||
    451 				old_state == HEADSET_STATE_PLAYING)
    452 			break;
    453 		if (dev->auto_connect) {
    454 			if (!dev->sink)
    455 				device_set_state(dev, AUDIO_STATE_CONNECTED);
    456 			else if (priv->sink_state == SINK_STATE_DISCONNECTED)
    457 				device_set_avdtp_timer(dev);
    458 			else if (priv->sink_state == SINK_STATE_CONNECTED ||
    459 					priv->sink_state == SINK_STATE_PLAYING)
    460 				device_set_state(dev, AUDIO_STATE_CONNECTED);
    461 		} else if (priv->sink_state == SINK_STATE_DISCONNECTED ||
    462 				priv->sink_state == SINK_STATE_CONNECTING)
    463 			device_set_state(dev, AUDIO_STATE_CONNECTED);
    464 		break;
    465 	case HEADSET_STATE_PLAY_IN_PROGRESS:
    466 		break;
    467 	case HEADSET_STATE_PLAYING:
    468 		break;
    469 	}
    470 }
    471 
    472 static DBusMessage *dev_connect(DBusConnection *conn, DBusMessage *msg,
    473 								void *data)
    474 {
    475 	struct audio_device *dev = data;
    476 	struct dev_priv *priv = dev->priv;
    477 
    478 	if (priv->state == AUDIO_STATE_CONNECTING)
    479 		return g_dbus_create_error(msg, ERROR_INTERFACE ".InProgress",
    480 						"Connect in Progress");
    481 	else if (priv->state == AUDIO_STATE_CONNECTED)
    482 		return g_dbus_create_error(msg, ERROR_INTERFACE
    483 						".AlreadyConnected",
    484 						"Already Connected");
    485 
    486 	dev->auto_connect = TRUE;
    487 
    488 	if (dev->headset)
    489 		headset_config_stream(dev, FALSE, NULL, NULL);
    490 
    491 	if (priv->state != AUDIO_STATE_CONNECTING && dev->sink) {
    492 		struct avdtp *session = avdtp_get(&dev->src, &dev->dst);
    493 
    494 		if (!session)
    495 			return g_dbus_create_error(msg, ERROR_INTERFACE
    496 					".Failed",
    497 					"Failed to get AVDTP session");
    498 
    499 		sink_setup_stream(dev->sink, session);
    500 		avdtp_unref(session);
    501 	}
    502 
    503 	/* The previous calls should cause a call to the state callback to
    504 	 * indicate AUDIO_STATE_CONNECTING */
    505 	if (priv->state != AUDIO_STATE_CONNECTING)
    506 		return g_dbus_create_error(msg, ERROR_INTERFACE
    507 				".ConnectFailed",
    508 				"Headset connect failed");
    509 
    510 	priv->conn_req = dbus_message_ref(msg);
    511 
    512 	return NULL;
    513 }
    514 
    515 static DBusMessage *dev_disconnect(DBusConnection *conn, DBusMessage *msg,
    516 								void *data)
    517 {
    518 	struct audio_device *dev = data;
    519 	struct dev_priv *priv = dev->priv;
    520 
    521 	if (priv->state == AUDIO_STATE_DISCONNECTED)
    522 		return g_dbus_create_error(msg, ERROR_INTERFACE ".NotConnected",
    523 						"Not connected");
    524 
    525 	if (priv->dc_req)
    526 		return dbus_message_new_method_return(msg);
    527 
    528 	priv->dc_req = dbus_message_ref(msg);
    529 
    530 	if (dev->control) {
    531 		device_remove_control_timer(dev);
    532 		avrcp_disconnect(dev);
    533 	}
    534 
    535 	if (dev->sink && priv->sink_state != SINK_STATE_DISCONNECTED)
    536 		sink_shutdown(dev->sink);
    537 	else if (priv->hs_state != HEADSET_STATE_DISCONNECTED)
    538 		headset_shutdown(dev);
    539 	else {
    540 		dbus_message_unref(priv->dc_req);
    541 		priv->dc_req = NULL;
    542 		return dbus_message_new_method_return(msg);
    543 	}
    544 
    545 	return NULL;
    546 }
    547 
    548 static DBusMessage *dev_get_properties(DBusConnection *conn, DBusMessage *msg,
    549 								void *data)
    550 {
    551 	struct audio_device *device = data;
    552 	DBusMessage *reply;
    553 	DBusMessageIter iter;
    554 	DBusMessageIter dict;
    555 	const char *state;
    556 
    557 	reply = dbus_message_new_method_return(msg);
    558 	if (!reply)
    559 		return NULL;
    560 
    561 	dbus_message_iter_init_append(reply, &iter);
    562 
    563 	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
    564 			DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
    565 			DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
    566 			DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
    567 
    568 	/* State */
    569 	state = state2str(device->priv->state);
    570 	if (state)
    571 		dict_append_entry(&dict, "State", DBUS_TYPE_STRING, &state);
    572 
    573 	dbus_message_iter_close_container(&iter, &dict);
    574 
    575 	return reply;
    576 }
    577 
    578 static GDBusMethodTable dev_methods[] = {
    579 	{ "Connect",		"",	"",	dev_connect,
    580 						G_DBUS_METHOD_FLAG_ASYNC },
    581 	{ "Disconnect",		"",	"",	dev_disconnect },
    582 	{ "GetProperties",	"",	"a{sv}",dev_get_properties },
    583 	{ NULL, NULL, NULL, NULL }
    584 };
    585 
    586 static GDBusSignalTable dev_signals[] = {
    587 	{ "PropertyChanged",		"sv"	},
    588 	{ NULL, NULL }
    589 };
    590 
    591 struct audio_device *audio_device_register(DBusConnection *conn,
    592 					struct btd_device *device,
    593 					const char *path, const bdaddr_t *src,
    594 					const bdaddr_t *dst)
    595 {
    596 	struct audio_device *dev;
    597 
    598 	if (!conn || !path)
    599 		return NULL;
    600 
    601 	dev = g_new0(struct audio_device, 1);
    602 
    603 	dev->btd_dev = btd_device_ref(device);
    604 	dev->path = g_strdup(path);
    605 	bacpy(&dev->dst, dst);
    606 	bacpy(&dev->src, src);
    607 	dev->conn = dbus_connection_ref(conn);
    608 	dev->priv = g_new0(struct dev_priv, 1);
    609 	dev->priv->state = AUDIO_STATE_DISCONNECTED;
    610 
    611 	if (!g_dbus_register_interface(dev->conn, dev->path,
    612 					AUDIO_INTERFACE,
    613 					dev_methods, dev_signals, NULL,
    614 					dev, NULL)) {
    615 		error("Unable to register %s on %s", AUDIO_INTERFACE,
    616 								dev->path);
    617 		device_free(dev);
    618 		return NULL;
    619 	}
    620 
    621 	DBG("Registered interface %s on path %s", AUDIO_INTERFACE,
    622 								dev->path);
    623 
    624 	if (sink_callback_id == 0)
    625 		sink_callback_id = sink_add_state_cb(device_sink_cb, NULL);
    626 
    627 	if (avdtp_callback_id == 0)
    628 		avdtp_callback_id = avdtp_add_state_cb(device_avdtp_cb, NULL);
    629 	if (avctp_callback_id == 0)
    630 		avctp_callback_id = avctp_add_state_cb(device_avctp_cb, NULL);
    631 
    632 	if (headset_callback_id == 0)
    633 		headset_callback_id = headset_add_state_cb(device_headset_cb,
    634 									NULL);
    635 
    636 	return dev;
    637 }
    638 
    639 gboolean audio_device_is_active(struct audio_device *dev,
    640 						const char *interface)
    641 {
    642 	if (!interface) {
    643 		if ((dev->sink || dev->source) &&
    644 				avdtp_is_connected(&dev->src, &dev->dst))
    645 			return TRUE;
    646 		if (dev->headset && headset_is_active(dev))
    647 			return TRUE;
    648 	} else if (!strcmp(interface, AUDIO_SINK_INTERFACE) && dev->sink &&
    649 				avdtp_is_connected(&dev->src, &dev->dst))
    650 		return TRUE;
    651 	else if (!strcmp(interface, AUDIO_SOURCE_INTERFACE) && dev->source &&
    652 				avdtp_is_connected(&dev->src, &dev->dst))
    653 		return TRUE;
    654 	else if (!strcmp(interface, AUDIO_HEADSET_INTERFACE) && dev->headset &&
    655 				headset_is_active(dev))
    656 		return TRUE;
    657 	else if (!strcmp(interface, AUDIO_CONTROL_INTERFACE) && dev->control &&
    658 				control_is_active(dev))
    659 		return TRUE;
    660 	else if (!strcmp(interface, AUDIO_GATEWAY_INTERFACE) && dev->gateway &&
    661 				gateway_is_connected(dev))
    662 		return TRUE;
    663 
    664 	return FALSE;
    665 }
    666 
    667 void audio_device_unregister(struct audio_device *device)
    668 {
    669 	unix_device_removed(device);
    670 
    671 	if (device->hs_preauth_id) {
    672 		g_source_remove(device->hs_preauth_id);
    673 		device->hs_preauth_id = 0;
    674 	}
    675 
    676 	if (device->headset)
    677 		headset_unregister(device);
    678 
    679 	if (device->gateway)
    680 		gateway_unregister(device);
    681 
    682 	if (device->sink)
    683 		sink_unregister(device);
    684 
    685 	if (device->source)
    686 		source_unregister(device);
    687 
    688 	if (device->control)
    689 		control_unregister(device);
    690 
    691 	g_dbus_unregister_interface(device->conn, device->path,
    692 						AUDIO_INTERFACE);
    693 
    694 	device_free(device);
    695 }
    696 
    697 static void auth_cb(DBusError *derr, void *user_data)
    698 {
    699 	struct audio_device *dev = user_data;
    700 	struct dev_priv *priv = dev->priv;
    701 
    702 	if (derr == NULL)
    703 		priv->authorized = TRUE;
    704 
    705 	while (priv->auths) {
    706 		struct service_auth *auth = priv->auths->data;
    707 
    708 		auth->cb(derr, auth->user_data);
    709 		priv->auths = g_slist_remove(priv->auths, auth);
    710 		g_free(auth);
    711 	}
    712 }
    713 
    714 static gboolean auth_idle_cb(gpointer user_data)
    715 {
    716 	struct audio_device *dev = user_data;
    717 	struct dev_priv *priv = dev->priv;
    718 
    719 	priv->auth_idle_id = 0;
    720 
    721 	auth_cb(NULL, dev);
    722 
    723 	return FALSE;
    724 }
    725 
    726 static gboolean audio_device_is_connected(struct audio_device *dev)
    727 {
    728 	if (dev->headset) {
    729 		headset_state_t state = headset_get_state(dev);
    730 
    731 		if (state == HEADSET_STATE_CONNECTED ||
    732 				state == HEADSET_STATE_PLAY_IN_PROGRESS ||
    733 				state == HEADSET_STATE_PLAYING)
    734 			return TRUE;
    735 	}
    736 
    737 	if (dev->sink) {
    738 		sink_state_t state = sink_get_state(dev);
    739 
    740 		if (state == SINK_STATE_CONNECTED ||
    741 				state == SINK_STATE_PLAYING)
    742 			return TRUE;
    743 	}
    744 
    745 	if (dev->source) {
    746 		source_state_t state = source_get_state(dev);
    747 
    748 		if (state == SOURCE_STATE_CONNECTED ||
    749 				state == SOURCE_STATE_PLAYING)
    750 			return TRUE;
    751 	}
    752 
    753 	return FALSE;
    754 }
    755 
    756 int audio_device_request_authorization(struct audio_device *dev,
    757 					const char *uuid, service_auth_cb cb,
    758 					void *user_data)
    759 {
    760 	struct dev_priv *priv = dev->priv;
    761 	struct service_auth *auth;
    762 	int err;
    763 
    764 	auth = g_try_new0(struct service_auth, 1);
    765 	if (!auth)
    766 		return -ENOMEM;
    767 
    768 	auth->cb = cb;
    769 	auth->user_data = user_data;
    770 
    771 	priv->auths = g_slist_append(priv->auths, auth);
    772 	if (g_slist_length(priv->auths) > 1)
    773 		return 0;
    774 
    775 	if (priv->authorized || audio_device_is_connected(dev)) {
    776 		priv->auth_idle_id = g_idle_add(auth_idle_cb, dev);
    777 		return 0;
    778 	}
    779 
    780 	err = btd_request_authorization(&dev->src, &dev->dst, uuid, auth_cb,
    781 					dev);
    782 	if (err < 0) {
    783 		priv->auths = g_slist_remove(priv->auths, auth);
    784 		g_free(auth);
    785 	}
    786 
    787 	return err;
    788 }
    789 
    790 int audio_device_cancel_authorization(struct audio_device *dev,
    791 					authorization_cb cb, void *user_data)
    792 {
    793 	struct dev_priv *priv = dev->priv;
    794 	GSList *l, *next;
    795 
    796 	for (l = priv->auths; l != NULL; l = next) {
    797 		struct service_auth *auth = l->data;
    798 
    799 		next = g_slist_next(l);
    800 
    801 		if (cb && auth->cb != cb)
    802 			continue;
    803 
    804 		if (user_data && auth->user_data != user_data)
    805 			continue;
    806 
    807 		priv->auths = g_slist_remove(priv->auths, auth);
    808 		g_free(auth);
    809 	}
    810 
    811 	if (g_slist_length(priv->auths) == 0) {
    812 		if (priv->auth_idle_id > 0) {
    813 			g_source_remove(priv->auth_idle_id);
    814 			priv->auth_idle_id = 0;
    815 		} else
    816 			btd_cancel_authorization(&dev->src, &dev->dst);
    817 	}
    818 
    819 	return 0;
    820 }
    821 
    822 void audio_device_set_authorized(struct audio_device *dev, gboolean auth)
    823 {
    824 	struct dev_priv *priv = dev->priv;
    825 
    826 	priv->authorized = auth;
    827 }
    828