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
52struct pending_request {
53	DBusConnection *conn;
54	DBusMessage *msg;
55	unsigned int id;
56};
57
58struct 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
73struct sink_state_callback {
74	sink_state_cb cb;
75	void *user_data;
76	unsigned int id;
77};
78
79static GSList *sink_callbacks = NULL;
80
81static unsigned int avdtp_callback_id = 0;
82
83static 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
100static 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
121static 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
160static 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
173static 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
184static 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
271static 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
277static 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
303static 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
346static 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
382static 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
455static 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
488static 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
542failed:
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
551gboolean 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
572static 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
611static 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
650static 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
684static 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
718static 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
739static 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
779static 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
794static 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
803static 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
830static 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
840void sink_unregister(struct audio_device *dev)
841{
842	g_dbus_unregister_interface(dev->conn, dev->path,
843		AUDIO_SINK_INTERFACE);
844}
845
846struct 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
870gboolean 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
880gboolean 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
890avdtp_state_t sink_get_state(struct audio_device *dev)
891{
892	struct sink *sink = dev->sink;
893
894	return sink->stream_state;
895}
896
897gboolean 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
916gboolean 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
927unsigned 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
942gboolean 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