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