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 * Copyright (C) 2009-2010 Motorola Inc.
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 <stdint.h>
30 #include <errno.h>
31
32 #include <bluetooth/bluetooth.h>
33 #include <bluetooth/sdp.h>
34
35 #include <glib.h>
36 #include <dbus/dbus.h>
37 #include <gdbus.h>
38
39 #include "log.h"
40
41 #include "device.h"
42 #include "avdtp.h"
43 #include "a2dp.h"
44 #include "error.h"
45 #include "sink.h"
46 #include "dbus-common.h"
47 #include "../src/adapter.h"
48 #include "../src/device.h"
49
50 #define STREAM_SETUP_RETRY_TIMER 2
51
52 struct pending_request {
53 DBusConnection *conn;
54 DBusMessage *msg;
55 unsigned int id;
56 };
57
58 struct sink {
59 struct audio_device *dev;
60 struct avdtp *session;
61 struct avdtp_stream *stream;
62 unsigned int cb_id;
63 guint dc_id;
64 guint retry_id;
65 avdtp_session_state_t session_state;
66 avdtp_state_t stream_state;
67 sink_state_t state;
68 struct pending_request *connect;
69 struct pending_request *disconnect;
70 DBusConnection *conn;
71 };
72
73 struct sink_state_callback {
74 sink_state_cb cb;
75 void *user_data;
76 unsigned int id;
77 };
78
79 static GSList *sink_callbacks = NULL;
80
81 static unsigned int avdtp_callback_id = 0;
82
state2str(sink_state_t state)83 static const char *state2str(sink_state_t state)
84 {
85 switch (state) {
86 case SINK_STATE_DISCONNECTED:
87 return "disconnected";
88 case SINK_STATE_CONNECTING:
89 return "connecting";
90 case SINK_STATE_CONNECTED:
91 return "connected";
92 case SINK_STATE_PLAYING:
93 return "playing";
94 default:
95 error("Invalid sink state %d", state);
96 return NULL;
97 }
98 }
99
sink_set_state(struct audio_device * dev,sink_state_t new_state)100 static void sink_set_state(struct audio_device *dev, sink_state_t new_state)
101 {
102 struct sink *sink = dev->sink;
103 const char *state_str;
104 sink_state_t old_state = sink->state;
105 GSList *l;
106
107 sink->state = new_state;
108
109 state_str = state2str(new_state);
110 if (state_str)
111 emit_property_changed(dev->conn, dev->path,
112 AUDIO_SINK_INTERFACE, "State",
113 DBUS_TYPE_STRING, &state_str);
114
115 for (l = sink_callbacks; l != NULL; l = l->next) {
116 struct sink_state_callback *cb = l->data;
117 cb->cb(dev, old_state, new_state, cb->user_data);
118 }
119 }
120
avdtp_state_callback(struct audio_device * dev,struct avdtp * session,avdtp_session_state_t old_state,avdtp_session_state_t new_state,void * user_data)121 static void avdtp_state_callback(struct audio_device *dev,
122 struct avdtp *session,
123 avdtp_session_state_t old_state,
124 avdtp_session_state_t new_state,
125 void *user_data)
126 {
127 struct sink *sink = dev->sink;
128
129 if (sink == NULL)
130 return;
131
132 switch (new_state) {
133 case AVDTP_SESSION_STATE_DISCONNECTED:
134 if (sink->state != SINK_STATE_CONNECTING) {
135 gboolean value = FALSE;
136 g_dbus_emit_signal(dev->conn, dev->path,
137 AUDIO_SINK_INTERFACE, "Disconnected",
138 DBUS_TYPE_INVALID);
139 emit_property_changed(dev->conn, dev->path,
140 AUDIO_SINK_INTERFACE, "Connected",
141 DBUS_TYPE_BOOLEAN, &value);
142 if (sink->dc_id) {
143 device_remove_disconnect_watch(dev->btd_dev,
144 sink->dc_id);
145 sink->dc_id = 0;
146 }
147 }
148 sink_set_state(dev, SINK_STATE_DISCONNECTED);
149 break;
150 case AVDTP_SESSION_STATE_CONNECTING:
151 sink_set_state(dev, SINK_STATE_CONNECTING);
152 break;
153 case AVDTP_SESSION_STATE_CONNECTED:
154 break;
155 }
156
157 sink->session_state = new_state;
158 }
159
pending_request_free(struct audio_device * dev,struct pending_request * pending)160 static void pending_request_free(struct audio_device *dev,
161 struct pending_request *pending)
162 {
163 if (pending->conn)
164 dbus_connection_unref(pending->conn);
165 if (pending->msg)
166 dbus_message_unref(pending->msg);
167 if (pending->id)
168 a2dp_cancel(dev, pending->id);
169
170 g_free(pending);
171 }
172
disconnect_cb(struct btd_device * btd_dev,gboolean removal,void * user_data)173 static void disconnect_cb(struct btd_device *btd_dev, gboolean removal,
174 void *user_data)
175 {
176 struct audio_device *device = user_data;
177 struct sink *sink = device->sink;
178
179 DBG("Sink: disconnect %s", device->path);
180
181 avdtp_close(sink->session, sink->stream, TRUE);
182 }
183
stream_state_changed(struct avdtp_stream * stream,avdtp_state_t old_state,avdtp_state_t new_state,struct avdtp_error * err,void * user_data)184 static void stream_state_changed(struct avdtp_stream *stream,
185 avdtp_state_t old_state,
186 avdtp_state_t new_state,
187 struct avdtp_error *err,
188 void *user_data)
189 {
190 struct audio_device *dev = user_data;
191 struct sink *sink = dev->sink;
192 gboolean value;
193
194 if (err)
195 return;
196
197 switch (new_state) {
198 case AVDTP_STATE_IDLE:
199 if (sink->disconnect) {
200 DBusMessage *reply;
201 struct pending_request *p;
202
203 p = sink->disconnect;
204 sink->disconnect = NULL;
205
206 reply = dbus_message_new_method_return(p->msg);
207 g_dbus_send_message(p->conn, reply);
208 pending_request_free(dev, p);
209 }
210
211 if (sink->dc_id) {
212 device_remove_disconnect_watch(dev->btd_dev,
213 sink->dc_id);
214 sink->dc_id = 0;
215 }
216
217 if (sink->session) {
218 avdtp_unref(sink->session);
219 sink->session = NULL;
220 }
221 sink->stream = NULL;
222 sink->cb_id = 0;
223 break;
224 case AVDTP_STATE_OPEN:
225 if (old_state == AVDTP_STATE_CONFIGURED &&
226 sink->state == SINK_STATE_CONNECTING) {
227 value = TRUE;
228 g_dbus_emit_signal(dev->conn, dev->path,
229 AUDIO_SINK_INTERFACE,
230 "Connected",
231 DBUS_TYPE_INVALID);
232 emit_property_changed(dev->conn, dev->path,
233 AUDIO_SINK_INTERFACE,
234 "Connected",
235 DBUS_TYPE_BOOLEAN, &value);
236 sink->dc_id = device_add_disconnect_watch(dev->btd_dev,
237 disconnect_cb,
238 dev, NULL);
239 } else if (old_state == AVDTP_STATE_STREAMING) {
240 value = FALSE;
241 g_dbus_emit_signal(dev->conn, dev->path,
242 AUDIO_SINK_INTERFACE,
243 "Stopped",
244 DBUS_TYPE_INVALID);
245 emit_property_changed(dev->conn, dev->path,
246 AUDIO_SINK_INTERFACE,
247 "Playing",
248 DBUS_TYPE_BOOLEAN, &value);
249 }
250 sink_set_state(dev, SINK_STATE_CONNECTED);
251 break;
252 case AVDTP_STATE_STREAMING:
253 value = TRUE;
254 g_dbus_emit_signal(dev->conn, dev->path, AUDIO_SINK_INTERFACE,
255 "Playing", DBUS_TYPE_INVALID);
256 emit_property_changed(dev->conn, dev->path,
257 AUDIO_SINK_INTERFACE, "Playing",
258 DBUS_TYPE_BOOLEAN, &value);
259 sink_set_state(dev, SINK_STATE_PLAYING);
260 break;
261 case AVDTP_STATE_CONFIGURED:
262 case AVDTP_STATE_CLOSING:
263 case AVDTP_STATE_ABORTING:
264 default:
265 break;
266 }
267
268 sink->stream_state = new_state;
269 }
270
error_failed(DBusConnection * conn,DBusMessage * msg,const char * desc)271 static DBusHandlerResult error_failed(DBusConnection *conn,
272 DBusMessage *msg, const char * desc)
273 {
274 return error_common_reply(conn, msg, ERROR_INTERFACE ".Failed", desc);
275 }
276
stream_setup_retry(gpointer user_data)277 static gboolean stream_setup_retry(gpointer user_data)
278 {
279 struct sink *sink = user_data;
280 struct pending_request *pending = sink->connect;
281
282 sink->retry_id = 0;
283
284 if (sink->stream_state >= AVDTP_STATE_OPEN) {
285 DBG("Stream successfully created, after XCASE connect:connect");
286 if (pending->msg) {
287 DBusMessage *reply;
288 reply = dbus_message_new_method_return(pending->msg);
289 g_dbus_send_message(pending->conn, reply);
290 }
291 } else {
292 DBG("Stream setup failed, after XCASE connect:connect");
293 if (pending->msg)
294 error_failed(pending->conn, pending->msg, "Stream setup failed");
295 }
296
297 sink->connect = NULL;
298 pending_request_free(sink->dev, pending);
299
300 return FALSE;
301 }
302
stream_setup_complete(struct avdtp * session,struct a2dp_sep * sep,struct avdtp_stream * stream,struct avdtp_error * err,void * user_data)303 static void stream_setup_complete(struct avdtp *session, struct a2dp_sep *sep,
304 struct avdtp_stream *stream,
305 struct avdtp_error *err, void *user_data)
306 {
307 struct sink *sink = user_data;
308 struct pending_request *pending;
309
310 pending = sink->connect;
311
312 pending->id = 0;
313
314 if (stream) {
315 DBG("Stream successfully created");
316
317 if (pending->msg) {
318 DBusMessage *reply;
319 reply = dbus_message_new_method_return(pending->msg);
320 g_dbus_send_message(pending->conn, reply);
321 }
322
323 sink->connect = NULL;
324 pending_request_free(sink->dev, pending);
325
326 return;
327 }
328
329 avdtp_unref(sink->session);
330 sink->session = NULL;
331 if (avdtp_error_type(err) == AVDTP_ERROR_ERRNO
332 && avdtp_error_posix_errno(err) != EHOSTDOWN) {
333 DBG("connect:connect XCASE detected");
334 sink->retry_id = g_timeout_add_seconds(STREAM_SETUP_RETRY_TIMER,
335 stream_setup_retry,
336 sink);
337 } else {
338 if (pending->msg)
339 error_failed(pending->conn, pending->msg, "Stream setup failed");
340 sink->connect = NULL;
341 pending_request_free(sink->dev, pending);
342 DBG("Stream setup failed : %s", avdtp_strerror(err));
343 }
344 }
345
default_bitpool(uint8_t freq,uint8_t mode)346 static uint8_t default_bitpool(uint8_t freq, uint8_t mode)
347 {
348 switch (freq) {
349 case SBC_SAMPLING_FREQ_16000:
350 case SBC_SAMPLING_FREQ_32000:
351 return 53;
352 case SBC_SAMPLING_FREQ_44100:
353 switch (mode) {
354 case SBC_CHANNEL_MODE_MONO:
355 case SBC_CHANNEL_MODE_DUAL_CHANNEL:
356 return 31;
357 case SBC_CHANNEL_MODE_STEREO:
358 case SBC_CHANNEL_MODE_JOINT_STEREO:
359 return 53;
360 default:
361 error("Invalid channel mode %u", mode);
362 return 53;
363 }
364 case SBC_SAMPLING_FREQ_48000:
365 switch (mode) {
366 case SBC_CHANNEL_MODE_MONO:
367 case SBC_CHANNEL_MODE_DUAL_CHANNEL:
368 return 29;
369 case SBC_CHANNEL_MODE_STEREO:
370 case SBC_CHANNEL_MODE_JOINT_STEREO:
371 return 51;
372 default:
373 error("Invalid channel mode %u", mode);
374 return 51;
375 }
376 default:
377 error("Invalid sampling freq %u", freq);
378 return 53;
379 }
380 }
381
select_sbc_params(struct sbc_codec_cap * cap,struct sbc_codec_cap * supported)382 static gboolean select_sbc_params(struct sbc_codec_cap *cap,
383 struct sbc_codec_cap *supported)
384 {
385 unsigned int max_bitpool, min_bitpool;
386
387 memset(cap, 0, sizeof(struct sbc_codec_cap));
388
389 cap->cap.media_type = AVDTP_MEDIA_TYPE_AUDIO;
390 cap->cap.media_codec_type = A2DP_CODEC_SBC;
391
392 if (supported->frequency & SBC_SAMPLING_FREQ_44100)
393 cap->frequency = SBC_SAMPLING_FREQ_44100;
394 else if (supported->frequency & SBC_SAMPLING_FREQ_48000)
395 cap->frequency = SBC_SAMPLING_FREQ_48000;
396 else if (supported->frequency & SBC_SAMPLING_FREQ_32000)
397 cap->frequency = SBC_SAMPLING_FREQ_32000;
398 else if (supported->frequency & SBC_SAMPLING_FREQ_16000)
399 cap->frequency = SBC_SAMPLING_FREQ_16000;
400 else {
401 error("No supported frequencies");
402 return FALSE;
403 }
404
405 if (supported->channel_mode & SBC_CHANNEL_MODE_JOINT_STEREO)
406 cap->channel_mode = SBC_CHANNEL_MODE_JOINT_STEREO;
407 else if (supported->channel_mode & SBC_CHANNEL_MODE_STEREO)
408 cap->channel_mode = SBC_CHANNEL_MODE_STEREO;
409 else if (supported->channel_mode & SBC_CHANNEL_MODE_DUAL_CHANNEL)
410 cap->channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL;
411 else if (supported->channel_mode & SBC_CHANNEL_MODE_MONO)
412 cap->channel_mode = SBC_CHANNEL_MODE_MONO;
413 else {
414 error("No supported channel modes");
415 return FALSE;
416 }
417
418 if (supported->block_length & SBC_BLOCK_LENGTH_16)
419 cap->block_length = SBC_BLOCK_LENGTH_16;
420 else if (supported->block_length & SBC_BLOCK_LENGTH_12)
421 cap->block_length = SBC_BLOCK_LENGTH_12;
422 else if (supported->block_length & SBC_BLOCK_LENGTH_8)
423 cap->block_length = SBC_BLOCK_LENGTH_8;
424 else if (supported->block_length & SBC_BLOCK_LENGTH_4)
425 cap->block_length = SBC_BLOCK_LENGTH_4;
426 else {
427 error("No supported block lengths");
428 return FALSE;
429 }
430
431 if (supported->subbands & SBC_SUBBANDS_8)
432 cap->subbands = SBC_SUBBANDS_8;
433 else if (supported->subbands & SBC_SUBBANDS_4)
434 cap->subbands = SBC_SUBBANDS_4;
435 else {
436 error("No supported subbands");
437 return FALSE;
438 }
439
440 if (supported->allocation_method & SBC_ALLOCATION_LOUDNESS)
441 cap->allocation_method = SBC_ALLOCATION_LOUDNESS;
442 else if (supported->allocation_method & SBC_ALLOCATION_SNR)
443 cap->allocation_method = SBC_ALLOCATION_SNR;
444
445 min_bitpool = MAX(MIN_BITPOOL, supported->min_bitpool);
446 max_bitpool = MIN(default_bitpool(cap->frequency, cap->channel_mode),
447 supported->max_bitpool);
448
449 cap->min_bitpool = min_bitpool;
450 cap->max_bitpool = max_bitpool;
451
452 return TRUE;
453 }
454
select_capabilities(struct avdtp * session,struct avdtp_remote_sep * rsep,GSList ** caps)455 static gboolean select_capabilities(struct avdtp *session,
456 struct avdtp_remote_sep *rsep,
457 GSList **caps)
458 {
459 struct avdtp_service_capability *media_transport, *media_codec;
460 struct sbc_codec_cap sbc_cap;
461
462 media_codec = avdtp_get_codec(rsep);
463 if (!media_codec)
464 return FALSE;
465
466 select_sbc_params(&sbc_cap, (struct sbc_codec_cap *) media_codec->data);
467
468 media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
469 NULL, 0);
470
471 *caps = g_slist_append(*caps, media_transport);
472
473 media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &sbc_cap,
474 sizeof(sbc_cap));
475
476 *caps = g_slist_append(*caps, media_codec);
477
478 if (avdtp_get_delay_reporting(rsep)) {
479 struct avdtp_service_capability *delay_reporting;
480 delay_reporting = avdtp_service_cap_new(AVDTP_DELAY_REPORTING,
481 NULL, 0);
482 *caps = g_slist_append(*caps, delay_reporting);
483 }
484
485 return TRUE;
486 }
487
discovery_complete(struct avdtp * session,GSList * seps,struct avdtp_error * err,void * user_data)488 static void discovery_complete(struct avdtp *session, GSList *seps, struct avdtp_error *err,
489 void *user_data)
490 {
491 struct sink *sink = user_data;
492 struct pending_request *pending;
493 struct avdtp_local_sep *lsep;
494 struct avdtp_remote_sep *rsep;
495 struct a2dp_sep *sep;
496 GSList *caps = NULL;
497 int id;
498
499 pending = sink->connect;
500
501 if (err) {
502 avdtp_unref(sink->session);
503 sink->session = NULL;
504 if (avdtp_error_type(err) == AVDTP_ERROR_ERRNO
505 && avdtp_error_posix_errno(err) != EHOSTDOWN) {
506 DBG("connect:connect XCASE detected");
507 sink->retry_id =
508 g_timeout_add_seconds(STREAM_SETUP_RETRY_TIMER,
509 stream_setup_retry,
510 sink);
511 } else
512 goto failed;
513 return;
514 }
515
516 DBG("Discovery complete");
517
518 if (avdtp_get_seps(session, AVDTP_SEP_TYPE_SINK, AVDTP_MEDIA_TYPE_AUDIO,
519 A2DP_CODEC_SBC, &lsep, &rsep) < 0) {
520 error("No matching ACP and INT SEPs found");
521 goto failed;
522 }
523
524 if (!select_capabilities(session, rsep, &caps)) {
525 error("Unable to select remote SEP capabilities");
526 goto failed;
527 }
528
529 sep = a2dp_get(session, rsep);
530 if (!sep) {
531 error("Unable to get a local source SEP");
532 goto failed;
533 }
534
535 id = a2dp_config(sink->session, sep, stream_setup_complete, caps, sink);
536 if (id == 0)
537 goto failed;
538
539 pending->id = id;
540 return;
541
542 failed:
543 if (pending->msg)
544 error_failed(pending->conn, pending->msg, "Stream setup failed");
545 pending_request_free(sink->dev, pending);
546 sink->connect = NULL;
547 avdtp_unref(sink->session);
548 sink->session = NULL;
549 }
550
sink_setup_stream(struct sink * sink,struct avdtp * session)551 gboolean sink_setup_stream(struct sink *sink, struct avdtp *session)
552 {
553 if (sink->connect || sink->disconnect)
554 return FALSE;
555
556 if (session && !sink->session)
557 sink->session = avdtp_ref(session);
558
559 if (!sink->session)
560 return FALSE;
561
562 avdtp_set_auto_disconnect(sink->session, FALSE);
563
564 if (avdtp_discover(sink->session, discovery_complete, sink) < 0)
565 return FALSE;
566
567 sink->connect = g_new0(struct pending_request, 1);
568
569 return TRUE;
570 }
571
sink_connect(DBusConnection * conn,DBusMessage * msg,void * data)572 static DBusMessage *sink_connect(DBusConnection *conn,
573 DBusMessage *msg, void *data)
574 {
575 struct audio_device *dev = data;
576 struct sink *sink = dev->sink;
577 struct pending_request *pending;
578
579 if (!sink->session)
580 sink->session = avdtp_get(&dev->src, &dev->dst);
581
582 if (!sink->session)
583 return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
584 "Unable to get a session");
585
586 if (sink->connect || sink->disconnect)
587 return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
588 "%s", strerror(EBUSY));
589
590 if (sink->stream_state >= AVDTP_STATE_OPEN)
591 return g_dbus_create_error(msg, ERROR_INTERFACE
592 ".AlreadyConnected",
593 "Device Already Connected");
594
595 if (!sink_setup_stream(sink, NULL))
596 return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
597 "Failed to create a stream");
598
599 dev->auto_connect = FALSE;
600
601 pending = sink->connect;
602
603 pending->conn = dbus_connection_ref(conn);
604 pending->msg = dbus_message_ref(msg);
605
606 DBG("stream creation in progress");
607
608 return NULL;
609 }
610
sink_disconnect(DBusConnection * conn,DBusMessage * msg,void * data)611 static DBusMessage *sink_disconnect(DBusConnection *conn,
612 DBusMessage *msg, void *data)
613 {
614 struct audio_device *device = data;
615 struct sink *sink = device->sink;
616 struct pending_request *pending;
617 int err;
618
619 if (!sink->session)
620 return g_dbus_create_error(msg, ERROR_INTERFACE
621 ".NotConnected",
622 "Device not Connected");
623
624 if (sink->connect || sink->disconnect)
625 return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
626 "%s", strerror(EBUSY));
627
628 if (sink->stream_state < AVDTP_STATE_OPEN) {
629 DBusMessage *reply = dbus_message_new_method_return(msg);
630 if (!reply)
631 return NULL;
632 avdtp_unref(sink->session);
633 sink->session = NULL;
634 return reply;
635 }
636
637 err = avdtp_close(sink->session, sink->stream, FALSE);
638 if (err < 0)
639 return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
640 "%s", strerror(-err));
641
642 pending = g_new0(struct pending_request, 1);
643 pending->conn = dbus_connection_ref(conn);
644 pending->msg = dbus_message_ref(msg);
645 sink->disconnect = pending;
646
647 return NULL;
648 }
649
sink_suspend(DBusConnection * conn,DBusMessage * msg,void * data)650 static DBusMessage *sink_suspend(DBusConnection *conn,
651 DBusMessage *msg, void *data)
652 {
653 struct audio_device *device = data;
654 struct sink *sink = device->sink;
655 struct pending_request *pending;
656 int err;
657
658 if (!sink->session)
659 return g_dbus_create_error(msg, ERROR_INTERFACE
660 ".NotConnected",
661 "Device not Connected");
662
663 if (sink->connect || sink->disconnect)
664 return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
665 "%s", strerror(EBUSY));
666
667 if (sink->state < AVDTP_STATE_OPEN) {
668 DBusMessage *reply = dbus_message_new_method_return(msg);
669 if (!reply)
670 return NULL;
671 avdtp_unref(sink->session);
672 sink->session = NULL;
673 return reply;
674 }
675
676 err = avdtp_suspend(sink->session, sink->stream);
677 if (err < 0)
678 return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
679 "%s", strerror(-err));
680
681 return NULL;
682 }
683
sink_resume(DBusConnection * conn,DBusMessage * msg,void * data)684 static DBusMessage *sink_resume(DBusConnection *conn,
685 DBusMessage *msg, void *data)
686 {
687 struct audio_device *device = data;
688 struct sink *sink = device->sink;
689 struct pending_request *pending;
690 int err;
691
692 if (!sink->session)
693 return g_dbus_create_error(msg, ERROR_INTERFACE
694 ".NotConnected",
695 "Device not Connected");
696
697 if (sink->connect || sink->disconnect)
698 return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
699 "%s", strerror(EBUSY));
700
701 if (sink->state < AVDTP_STATE_OPEN) {
702 DBusMessage *reply = dbus_message_new_method_return(msg);
703 if (!reply)
704 return NULL;
705 avdtp_unref(sink->session);
706 sink->session = NULL;
707 return reply;
708 }
709
710 err = avdtp_start(sink->session, sink->stream);
711 if (err < 0)
712 return g_dbus_create_error(msg, ERROR_INTERFACE ".Failed",
713 "%s", strerror(-err));
714
715 return NULL;
716 }
717
sink_is_connected(DBusConnection * conn,DBusMessage * msg,void * data)718 static DBusMessage *sink_is_connected(DBusConnection *conn,
719 DBusMessage *msg,
720 void *data)
721 {
722 struct audio_device *device = data;
723 struct sink *sink = device->sink;
724 DBusMessage *reply;
725 dbus_bool_t connected;
726
727 reply = dbus_message_new_method_return(msg);
728 if (!reply)
729 return NULL;
730
731 connected = (sink->stream_state >= AVDTP_STATE_CONFIGURED);
732
733 dbus_message_append_args(reply, DBUS_TYPE_BOOLEAN, &connected,
734 DBUS_TYPE_INVALID);
735
736 return reply;
737 }
738
sink_get_properties(DBusConnection * conn,DBusMessage * msg,void * data)739 static DBusMessage *sink_get_properties(DBusConnection *conn,
740 DBusMessage *msg, void *data)
741 {
742 struct audio_device *device = data;
743 struct sink *sink = device->sink;
744 DBusMessage *reply;
745 DBusMessageIter iter;
746 DBusMessageIter dict;
747 const char *state;
748 gboolean value;
749
750 reply = dbus_message_new_method_return(msg);
751 if (!reply)
752 return NULL;
753
754 dbus_message_iter_init_append(reply, &iter);
755
756 dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY,
757 DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING
758 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_VARIANT_AS_STRING
759 DBUS_DICT_ENTRY_END_CHAR_AS_STRING, &dict);
760
761 /* Playing */
762 value = (sink->stream_state == AVDTP_STATE_STREAMING);
763 dict_append_entry(&dict, "Playing", DBUS_TYPE_BOOLEAN, &value);
764
765 /* Connected */
766 value = (sink->stream_state >= AVDTP_STATE_CONFIGURED);
767 dict_append_entry(&dict, "Connected", DBUS_TYPE_BOOLEAN, &value);
768
769 /* State */
770 state = state2str(sink->state);
771 if (state)
772 dict_append_entry(&dict, "State", DBUS_TYPE_STRING, &state);
773
774 dbus_message_iter_close_container(&iter, &dict);
775
776 return reply;
777 }
778
779 static GDBusMethodTable sink_methods[] = {
780 { "Connect", "", "", sink_connect,
781 G_DBUS_METHOD_FLAG_ASYNC },
782 { "Disconnect", "", "", sink_disconnect,
783 G_DBUS_METHOD_FLAG_ASYNC },
784 { "Suspend", "", "", sink_suspend,
785 G_DBUS_METHOD_FLAG_ASYNC },
786 { "Resume", "", "", sink_resume,
787 G_DBUS_METHOD_FLAG_ASYNC },
788 { "IsConnected", "", "b", sink_is_connected,
789 G_DBUS_METHOD_FLAG_DEPRECATED },
790 { "GetProperties", "", "a{sv}",sink_get_properties },
791 { NULL, NULL, NULL, NULL }
792 };
793
794 static GDBusSignalTable sink_signals[] = {
795 { "Connected", "", G_DBUS_SIGNAL_FLAG_DEPRECATED },
796 { "Disconnected", "", G_DBUS_SIGNAL_FLAG_DEPRECATED },
797 { "Playing", "", G_DBUS_SIGNAL_FLAG_DEPRECATED },
798 { "Stopped", "", G_DBUS_SIGNAL_FLAG_DEPRECATED },
799 { "PropertyChanged", "sv" },
800 { NULL, NULL }
801 };
802
sink_free(struct audio_device * dev)803 static void sink_free(struct audio_device *dev)
804 {
805 struct sink *sink = dev->sink;
806
807 if (sink->cb_id)
808 avdtp_stream_remove_cb(sink->session, sink->stream,
809 sink->cb_id);
810
811 if (sink->dc_id)
812 device_remove_disconnect_watch(dev->btd_dev, sink->dc_id);
813
814 if (sink->session)
815 avdtp_unref(sink->session);
816
817 if (sink->connect)
818 pending_request_free(dev, sink->connect);
819
820 if (sink->disconnect)
821 pending_request_free(dev, sink->disconnect);
822
823 if (sink->retry_id)
824 g_source_remove(sink->retry_id);
825
826 g_free(sink);
827 dev->sink = NULL;
828 }
829
path_unregister(void * data)830 static void path_unregister(void *data)
831 {
832 struct audio_device *dev = data;
833
834 DBG("Unregistered interface %s on path %s",
835 AUDIO_SINK_INTERFACE, dev->path);
836
837 sink_free(dev);
838 }
839
sink_unregister(struct audio_device * dev)840 void sink_unregister(struct audio_device *dev)
841 {
842 g_dbus_unregister_interface(dev->conn, dev->path,
843 AUDIO_SINK_INTERFACE);
844 }
845
sink_init(struct audio_device * dev)846 struct sink *sink_init(struct audio_device *dev)
847 {
848 struct sink *sink;
849
850 if (!g_dbus_register_interface(dev->conn, dev->path,
851 AUDIO_SINK_INTERFACE,
852 sink_methods, sink_signals, NULL,
853 dev, path_unregister))
854 return NULL;
855
856 DBG("Registered interface %s on path %s",
857 AUDIO_SINK_INTERFACE, dev->path);
858
859 if (avdtp_callback_id == 0)
860 avdtp_callback_id = avdtp_add_state_cb(avdtp_state_callback,
861 NULL);
862
863 sink = g_new0(struct sink, 1);
864
865 sink->dev = dev;
866
867 return sink;
868 }
869
sink_is_active(struct audio_device * dev)870 gboolean sink_is_active(struct audio_device *dev)
871 {
872 struct sink *sink = dev->sink;
873
874 if (sink->session)
875 return TRUE;
876
877 return FALSE;
878 }
879
sink_is_streaming(struct audio_device * dev)880 gboolean sink_is_streaming(struct audio_device *dev)
881 {
882 struct sink *sink = dev->sink;
883
884 if (sink_get_state(dev) == AVDTP_STATE_STREAMING)
885 return TRUE;
886
887 return FALSE;
888 }
889
sink_get_state(struct audio_device * dev)890 avdtp_state_t sink_get_state(struct audio_device *dev)
891 {
892 struct sink *sink = dev->sink;
893
894 return sink->stream_state;
895 }
896
sink_new_stream(struct audio_device * dev,struct avdtp * session,struct avdtp_stream * stream)897 gboolean sink_new_stream(struct audio_device *dev, struct avdtp *session,
898 struct avdtp_stream *stream)
899 {
900 struct sink *sink = dev->sink;
901
902 if (sink->stream)
903 return FALSE;
904
905 if (!sink->session)
906 sink->session = avdtp_ref(session);
907
908 sink->stream = stream;
909
910 sink->cb_id = avdtp_stream_add_cb(session, stream,
911 stream_state_changed, dev);
912
913 return TRUE;
914 }
915
sink_shutdown(struct sink * sink)916 gboolean sink_shutdown(struct sink *sink)
917 {
918 if (!sink->stream)
919 return FALSE;
920
921 if (avdtp_close(sink->session, sink->stream, FALSE) < 0)
922 return FALSE;
923
924 return TRUE;
925 }
926
sink_add_state_cb(sink_state_cb cb,void * user_data)927 unsigned int sink_add_state_cb(sink_state_cb cb, void *user_data)
928 {
929 struct sink_state_callback *state_cb;
930 static unsigned int id = 0;
931
932 state_cb = g_new(struct sink_state_callback, 1);
933 state_cb->cb = cb;
934 state_cb->user_data = user_data;
935 state_cb->id = ++id;
936
937 sink_callbacks = g_slist_append(sink_callbacks, state_cb);
938
939 return state_cb->id;
940 }
941
sink_remove_state_cb(unsigned int id)942 gboolean sink_remove_state_cb(unsigned int id)
943 {
944 GSList *l;
945
946 for (l = sink_callbacks; l != NULL; l = l->next) {
947 struct sink_state_callback *cb = l->data;
948 if (cb && cb->id == id) {
949 sink_callbacks = g_slist_remove(sink_callbacks, cb);
950 g_free(cb);
951 return TRUE;
952 }
953 }
954
955 return FALSE;
956 }
957