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