gstavdtpsink.c revision 489c2e0dbd76d9cecec62d19fafd9e7baddb72e7
1a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz/*
2a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz *
3a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz *  BlueZ - Bluetooth protocol stack for Linux
4a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz *
5a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz *  Copyright (C) 2004-2007  Marcel Holtmann <marcel@holtmann.org>
6a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz *
7a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz *
8a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz *  This library is free software; you can redistribute it and/or
9a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz *  modify it under the terms of the GNU Lesser General Public
10a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz *  License as published by the Free Software Foundation; either
11a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz *  version 2.1 of the License, or (at your option) any later version.
12a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz *
13a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz *  This library is distributed in the hope that it will be useful,
14a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
16a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz *  Lesser General Public License for more details.
17a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz *
18a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz *  You should have received a copy of the GNU Lesser General Public
19a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz *  License along with this library; if not, write to the Free Software
20a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz *
22a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz */
23a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
24a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#ifdef HAVE_CONFIG_H
25a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#include <config.h>
26a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#endif
27a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
28a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#include <unistd.h>
29a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#include <sys/un.h>
30a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#include <sys/socket.h>
31a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#include <fcntl.h>
32a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#include <pthread.h>
33a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
34a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#include <netinet/in.h>
35a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
36a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#include <bluetooth/bluetooth.h>
37a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
38a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#include "ipc.h"
39a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#include "rtp.h"
40a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#include "gstsbcutil.h"
41a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
42a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#include "gsta2dpsendersink.h"
43a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
44a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von DentzGST_DEBUG_CATEGORY_STATIC(a2dp_sender_sink_debug);
45a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#define GST_CAT_DEFAULT a2dp_sender_sink_debug
46a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
47a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#define BUFFER_SIZE 2048
48a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#define TEMPLATE_MAX_BITPOOL 64
49a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
50a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#define GST_A2DP_SENDER_SINK_MUTEX_LOCK(s) G_STMT_START {	\
51a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_mutex_lock (s->sink_lock);		\
52a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	} G_STMT_END
53a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
54a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#define GST_A2DP_SENDER_SINK_MUTEX_UNLOCK(s) G_STMT_START {	\
55a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_mutex_unlock (s->sink_lock);		\
56a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	} G_STMT_END
57a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
58a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
59a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstruct bluetooth_data {
60a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	struct bt_getcapabilities_rsp caps; /* Bluetooth device caps */
61a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	guint link_mtu;
62a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
63a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gchar buffer[BUFFER_SIZE];	/* Codec transfer buffer */
64a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz};
65a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
66a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#define IS_SBC(n) (strcmp((n), "audio/x-sbc") == 0)
67a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#define IS_MPEG(n) (strcmp((n), "audio/mpeg") == 0)
68a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
69a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzenum {
70a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	PROP_0,
71a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	PROP_DEVICE,
72a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz};
73a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
74a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von DentzGST_BOILERPLATE(GstA2dpSenderSink, gst_a2dp_sender_sink, GstBaseSink,
75a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			GST_TYPE_BASE_SINK);
76a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
77a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic const GstElementDetails a2dp_sender_sink_details =
78a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_ELEMENT_DETAILS("Bluetooth A2DP sink",
79a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"Sink/Audio",
80a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"Plays audio to an A2DP device",
81a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"Marcel Holtmann <marcel@holtmann.org>");
82a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
83a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic GstStaticPadTemplate a2dp_sender_sink_factory =
84a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_STATIC_PAD_TEMPLATE("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
85a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_STATIC_CAPS("application/x-rtp, "
86a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"media = (string) \"audio\", "
87a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"encoding-name = (string) \"SBC\""
88a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				));
89a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
90a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic GIOError gst_a2dp_sender_sink_audioservice_send(GstA2dpSenderSink *self,
91a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					const bt_audio_msg_header_t *msg);
92a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic GIOError gst_a2dp_sender_sink_audioservice_expect(
93a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				GstA2dpSenderSink *self,
94a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				bt_audio_msg_header_t *outmsg,
95a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				int expected_type);
96a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
97a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
98a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic void gst_a2dp_sender_sink_base_init(gpointer g_class)
99a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
100a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GstElementClass *element_class = GST_ELEMENT_CLASS(g_class);
101a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
102a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gst_element_class_add_pad_template(element_class,
103a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_static_pad_template_get(&a2dp_sender_sink_factory));
104a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
105a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gst_element_class_set_details(element_class, &a2dp_sender_sink_details);
106a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
107a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
108a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic gboolean gst_a2dp_sender_sink_stop(GstBaseSink *basesink)
109a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
110a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GstA2dpSenderSink *self = GST_A2DP_SENDER_SINK(basesink);
111a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
112a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_INFO_OBJECT(self, "stop");
113a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
114a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->watch_id != 0) {
115a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_source_remove(self->watch_id);
116a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		self->watch_id = 0;
117a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
118a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
119a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->server) {
120a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		bt_audio_service_close(g_io_channel_unix_get_fd(self->server));
121a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_io_channel_unref(self->server);
122a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		self->server = NULL;
123a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
124a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
125a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->stream) {
126a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_io_channel_flush(self->stream, NULL);
127a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_io_channel_close(self->stream);
128a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_io_channel_unref(self->stream);
129a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		self->stream = NULL;
130a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
131a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
132a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->data) {
133a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_free(self->data);
134a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		self->data = NULL;
135a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
136a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
137a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->stream_caps) {
138a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_caps_unref(self->stream_caps);
139a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		self->stream_caps = NULL;
140a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
141a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
142a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->dev_caps) {
143a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_caps_unref(self->dev_caps);
144a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		self->dev_caps = NULL;
145a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
146a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
147a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
148a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
149a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
150a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic void gst_a2dp_sender_sink_finalize(GObject *object)
151a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
152a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GstA2dpSenderSink *self = GST_A2DP_SENDER_SINK(object);
153a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
154a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->data)
155a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_a2dp_sender_sink_stop(GST_BASE_SINK(self));
156a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
157a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->device)
158a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_free(self->device);
159a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
160a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_mutex_free(self->sink_lock);
161a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
162a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	G_OBJECT_CLASS(parent_class)->finalize(object);
163a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
164a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
165a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic void gst_a2dp_sender_sink_set_property(GObject *object, guint prop_id,
166a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					const GValue *value, GParamSpec *pspec)
167a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
168a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GstA2dpSenderSink *sink = GST_A2DP_SENDER_SINK(object);
169a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
170a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	switch (prop_id) {
171a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	case PROP_DEVICE:
172a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (sink->device)
173a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			g_free(sink->device);
174a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		sink->device = g_value_dup_string(value);
175a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		break;
176a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
177a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	default:
178a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
179a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		break;
180a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
181a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
182a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
183a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic void gst_a2dp_sender_sink_get_property(GObject *object, guint prop_id,
184a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					GValue *value, GParamSpec *pspec)
185a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
186a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GstA2dpSenderSink *sink = GST_A2DP_SENDER_SINK(object);
187a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
188a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	switch (prop_id) {
189a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	case PROP_DEVICE:
190a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_string(value, sink->device);
191a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		break;
192a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
193a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	default:
194a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
195a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		break;
196a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
197a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
198a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
199a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic gint gst_a2dp_sender_sink_bluetooth_recvmsg_fd(GstA2dpSenderSink *sink)
200a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
201a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	int err, ret;
202a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
203a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	ret = bt_audio_service_get_data_fd(
204a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			g_io_channel_unix_get_fd(sink->server));
205a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
206a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (ret < 0) {
207a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		err = errno;
208a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(sink, "Unable to receive fd: %s (%d)",
209a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				strerror(err), err);
210a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return -err;
211a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
212a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
213a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	sink->stream = g_io_channel_unix_new(ret);
214a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_DEBUG_OBJECT(sink, "stream_fd=%d", ret);
215a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
216a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return 0;
217a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
218a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
219a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic gboolean gst_a2dp_sender_sink_init_pkt_conf(GstA2dpSenderSink *sink,
220a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					GstCaps *caps,
221a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					sbc_capabilities_t *pkt)
222a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
223a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	sbc_capabilities_t *cfg = &sink->data->caps.sbc_capabilities;
224a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	const GValue *value = NULL;
225a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	const char *pref, *name;
226a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gint rate, subbands, blocks;
227a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GstStructure *structure = gst_caps_get_structure(caps, 0);
228a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
229a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	name = gst_structure_get_name(structure);
230a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* FIXME only sbc supported here, should suport mp3 */
231a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (!(IS_SBC(name))) {
232a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(sink, "Unsupported format %s", name);
233a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
234a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
235a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
236a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = gst_structure_get_value(structure, "rate");
237a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	rate = g_value_get_int(value);
238a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (rate == 44100)
239489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		cfg->frequency = BT_SBC_SAMPLING_FREQ_44100;
240a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (rate == 48000)
241489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		cfg->frequency = BT_SBC_SAMPLING_FREQ_48000;
242a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (rate == 32000)
243489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		cfg->frequency = BT_SBC_SAMPLING_FREQ_32000;
244a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (rate == 16000)
245489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		cfg->frequency = BT_SBC_SAMPLING_FREQ_16000;
246a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else {
247a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(sink, "Invalid rate while setting caps");
248a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
249a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
250a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
251a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = gst_structure_get_value(structure, "mode");
252a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	pref = g_value_get_string(value);
253a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (strcmp(pref, "auto") == 0)
254a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->channel_mode = BT_A2DP_CHANNEL_MODE_AUTO;
255a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (strcmp(pref, "mono") == 0)
256a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->channel_mode = BT_A2DP_CHANNEL_MODE_MONO;
257a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (strcmp(pref, "dual") == 0)
258a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->channel_mode = BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL;
259a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (strcmp(pref, "stereo") == 0)
260a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->channel_mode = BT_A2DP_CHANNEL_MODE_STEREO;
261a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (strcmp(pref, "joint") == 0)
262a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->channel_mode = BT_A2DP_CHANNEL_MODE_JOINT_STEREO;
263a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else {
264a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(sink, "Invalid mode %s", pref);
265a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
266a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
267a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
268a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = gst_structure_get_value(structure, "allocation");
269a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	pref = g_value_get_string(value);
270a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (strcmp(pref, "auto") == 0)
271a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->allocation_method = BT_A2DP_ALLOCATION_AUTO;
272a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (strcmp(pref, "loudness") == 0)
273a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->allocation_method = BT_A2DP_ALLOCATION_LOUDNESS;
274a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (strcmp(pref, "snr") == 0)
275a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->allocation_method = BT_A2DP_ALLOCATION_SNR;
276a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else {
277a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(sink, "Invalid allocation: %s", pref);
278a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
279a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
280a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
281a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = gst_structure_get_value(structure, "subbands");
282a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	subbands = g_value_get_int(value);
283a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (subbands == 8)
284a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->subbands = BT_A2DP_SUBBANDS_8;
285a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (subbands == 4)
286a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->subbands = BT_A2DP_SUBBANDS_4;
287a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else {
288a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(sink, "Invalid subbands %d", subbands);
289a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
290a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
291a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
292a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = gst_structure_get_value(structure, "blocks");
293a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	blocks = g_value_get_int(value);
294a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (blocks == 16)
295a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->block_length = BT_A2DP_BLOCK_LENGTH_16;
296a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (blocks == 12)
297a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->block_length = BT_A2DP_BLOCK_LENGTH_12;
298a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (blocks == 8)
299a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->block_length = BT_A2DP_BLOCK_LENGTH_8;
300a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (blocks == 4)
301a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->block_length = BT_A2DP_BLOCK_LENGTH_4;
302a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else {
303a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(sink, "Invalid blocks %d", blocks);
304a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
305a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
306a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
307a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = gst_structure_get_value(structure, "bitpool");
308a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	cfg->max_bitpool = cfg->min_bitpool = g_value_get_int(value);
309a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
310a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	memcpy(pkt, cfg, sizeof(*pkt));
311a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
312a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
313a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
314a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
315a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic gboolean gst_a2dp_sender_sink_conf_recv_stream_fd(
316a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					GstA2dpSenderSink *self)
317a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
318a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	struct bluetooth_data *data = self->data;
319a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gint ret;
320a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GIOError err;
321a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GError *gerr = NULL;
322a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GIOStatus status;
323a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GIOFlags flags;
324a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gsize read;
325a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
326a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	ret = gst_a2dp_sender_sink_bluetooth_recvmsg_fd(self);
327a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (ret < 0)
328a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
329a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
330a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (!self->stream) {
331a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error while configuring device: "
332a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"could not acquire audio socket");
333a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
334a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
335a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
336a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* set stream socket to nonblock */
337a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_LOG_OBJECT(self, "setting stream socket to nonblock");
338a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	flags = g_io_channel_get_flags(self->stream);
339a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	flags |= G_IO_FLAG_NONBLOCK;
340a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	status = g_io_channel_set_flags(self->stream, flags, &gerr);
341a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (status != G_IO_STATUS_NORMAL) {
342a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (gerr)
343a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			GST_WARNING_OBJECT(self, "Error while "
344a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"setting server socket to nonblock: "
345a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"%s", gerr->message);
346a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		else
347a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			GST_WARNING_OBJECT(self, "Error while "
348a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					"setting server "
349a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					"socket to nonblock");
350a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
351a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
352a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* It is possible there is some outstanding
353a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	data in the pipe - we have to empty it */
354a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_LOG_OBJECT(self, "emptying stream pipe");
355a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	while (1) {
356a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		err = g_io_channel_read(self->stream, data->buffer,
357a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					(gsize) data->link_mtu,
358a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					&read);
359a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (err != G_IO_ERROR_NONE || read <= 0)
360a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			break;
361a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
362a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
363a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* set stream socket to block */
364a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_LOG_OBJECT(self, "setting stream socket to block");
365a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	flags = g_io_channel_get_flags(self->stream);
366a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	flags &= ~G_IO_FLAG_NONBLOCK;
367a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	status = g_io_channel_set_flags(self->stream, flags, &gerr);
368a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (status != G_IO_STATUS_NORMAL) {
369a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (gerr)
370a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			GST_WARNING_OBJECT(self, "Error while "
371a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"setting server socket to block:"
372a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"%s", gerr->message);
373a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		else
374a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			GST_WARNING_OBJECT(self, "Error while "
375a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"setting server "
376a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"socket to block");
377a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
378a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
379a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	memset(data->buffer, 0, sizeof(data->buffer));
380a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
381a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
382a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
383a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
384a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic gboolean server_callback(GIOChannel *chan,
385a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					GIOCondition cond, gpointer data)
386a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
387a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GstA2dpSenderSink *sink;
388a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
389a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (cond & G_IO_HUP || cond & G_IO_NVAL)
390a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
391a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (cond & G_IO_ERR) {
392a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		sink = GST_A2DP_SENDER_SINK(data);
393a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_WARNING_OBJECT(sink, "Untreated callback G_IO_ERR");
394a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
395a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
396a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
397a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
398a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
399489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentzstatic GstStructure *gst_a2dp_sender_sink_parse_sbc_caps(
400489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz			GstA2dpSenderSink *self, sbc_capabilities_t *sbc)
401a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
402a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GstStructure *structure;
403a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GValue *value;
404a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GValue *list;
405a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gboolean mono, stereo;
406a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
407a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	structure = gst_structure_empty_new("audio/x-sbc");
408a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = g_value_init(g_new0(GValue, 1), G_TYPE_STRING);
409a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
410a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* mode */
411a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
412a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sbc->channel_mode == BT_A2DP_CHANNEL_MODE_AUTO) {
413a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_static_string(value, "joint");
414a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
415a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_static_string(value, "stereo");
416a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
417a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_static_string(value, "mono");
418a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
419a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_static_string(value, "dual");
420a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
421a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	} else {
422a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_MONO) {
423a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			g_value_set_static_string(value, "mono");
424a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			gst_value_list_prepend_value(list, value);
425a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		}
426a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_STEREO) {
427a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			g_value_set_static_string(value, "stereo");
428a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			gst_value_list_prepend_value(list, value);
429a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		}
430a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL) {
431a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			g_value_set_static_string(value, "dual");
432a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			gst_value_list_prepend_value(list, value);
433a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		}
434a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_JOINT_STEREO) {
435a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			g_value_set_static_string(value, "joint");
436a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			gst_value_list_prepend_value(list, value);
437a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		}
438a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
439a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_value_unset(value);
440a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (list) {
441a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_structure_set_value(structure, "mode", list);
442a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_free(list);
443a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		list = NULL;
444a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
445a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
446a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* subbands */
447a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
448a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = g_value_init(value, G_TYPE_INT);
449a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sbc->subbands & BT_A2DP_SUBBANDS_4) {
450a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 4);
451a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
452a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
453a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sbc->subbands & BT_A2DP_SUBBANDS_8) {
454a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 8);
455a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
456a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
457a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_value_unset(value);
458a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (list) {
459a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_structure_set_value(structure, "subbands", list);
460a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_free(list);
461a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		list = NULL;
462a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
463a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
464a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* blocks */
465a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = g_value_init(value, G_TYPE_INT);
466a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
467a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sbc->block_length & BT_A2DP_BLOCK_LENGTH_16) {
468a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 16);
469a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
470a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
471a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sbc->block_length & BT_A2DP_BLOCK_LENGTH_12) {
472a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 12);
473a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
474a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
475a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sbc->block_length & BT_A2DP_BLOCK_LENGTH_8) {
476a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 8);
477a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
478a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
479a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sbc->block_length & BT_A2DP_BLOCK_LENGTH_4) {
480a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 4);
481a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
482a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
483a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_value_unset(value);
484a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (list) {
485a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_structure_set_value(structure, "blocks", list);
486a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_free(list);
487a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		list = NULL;
488a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
489a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
490a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* allocation */
491a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_value_init(value, G_TYPE_STRING);
492a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	list = g_value_init(g_new0(GValue,1), GST_TYPE_LIST);
493a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sbc->allocation_method == BT_A2DP_ALLOCATION_AUTO) {
494a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_static_string(value, "loudness");
495a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
496a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_static_string(value, "snr");
497a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
498a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	} else {
499a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (sbc->allocation_method & BT_A2DP_ALLOCATION_LOUDNESS) {
500a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			g_value_set_static_string(value, "loudness");
501a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			gst_value_list_prepend_value(list, value);
502a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		}
503a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (sbc->allocation_method & BT_A2DP_ALLOCATION_SNR) {
504a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			g_value_set_static_string(value, "snr");
505a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			gst_value_list_prepend_value(list, value);
506a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		}
507a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
508a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_value_unset(value);
509a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (list) {
510a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_structure_set_value(structure, "allocation", list);
511a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_free(list);
512a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		list = NULL;
513a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
514a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
515a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* rate */
516a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_value_init(value, G_TYPE_INT);
517a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
518489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (sbc->frequency & BT_SBC_SAMPLING_FREQ_48000) {
519a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 48000);
520a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
521a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
522489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (sbc->frequency & BT_SBC_SAMPLING_FREQ_44100) {
523a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 44100);
524a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
525a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
526489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (sbc->frequency & BT_SBC_SAMPLING_FREQ_32000) {
527a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 32000);
528a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
529a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
530489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (sbc->frequency & BT_SBC_SAMPLING_FREQ_16000) {
531a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 16000);
532a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
533a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
534a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_value_unset(value);
535a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (list) {
536a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_structure_set_value(structure, "rate", list);
537a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_free(list);
538a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		list = NULL;
539a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
540a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
541a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* bitpool */
542a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = g_value_init(value, GST_TYPE_INT_RANGE);
543a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gst_value_set_int_range(value,
544a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			MIN(sbc->min_bitpool, TEMPLATE_MAX_BITPOOL),
545a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			MIN(sbc->max_bitpool, TEMPLATE_MAX_BITPOOL));
546a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gst_structure_set_value(structure, "bitpool", value);
547a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_value_unset(value);
548a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
549a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* channels */
550a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sbc->channel_mode == BT_A2DP_CHANNEL_MODE_AUTO) {
551a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_init(value, GST_TYPE_INT_RANGE);
552a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_set_int_range(value, 1, 2);
553a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	} else {
554a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		mono = FALSE;
555a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		stereo = FALSE;
556a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_MONO)
557a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			mono = TRUE;
558a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if ((sbc->channel_mode & BT_A2DP_CHANNEL_MODE_STEREO) ||
559a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				(sbc->channel_mode &
560a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL) ||
561a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				(sbc->channel_mode &
562a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				BT_A2DP_CHANNEL_MODE_JOINT_STEREO))
563a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			stereo = TRUE;
564a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
565a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (mono && stereo) {
566a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			g_value_init(value, GST_TYPE_INT_RANGE);
567a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			gst_value_set_int_range(value, 1, 2);
568a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		} else {
569a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			g_value_init(value, G_TYPE_INT);
570a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			if (mono)
571a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				g_value_set_int(value, 1);
572a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			else if (stereo)
573a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				g_value_set_int(value, 2);
574a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			else {
575a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				GST_ERROR_OBJECT(self,
576a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					"Unexpected number of channels");
577a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				g_value_set_int(value, 0);
578a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			}
579a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		}
580a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
581a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gst_structure_set_value(structure, "channels", value);
582a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_free(value);
583a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
584489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	return structure;
585489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz}
586489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
587489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentzstatic gboolean gst_a2dp_sender_sink_update_caps(GstA2dpSenderSink *self)
588489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz{
589489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	sbc_capabilities_t *sbc = &self->data->caps.sbc_capabilities;
590489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_capabilities_t *mpeg = &self->data->caps.mpeg_capabilities;
591489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	GstStructure *structure;
592489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	gchar *tmp;
593489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
594489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	GST_LOG_OBJECT(self, "updating device caps");
595489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
596489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	structure = gst_a2dp_sender_sink_parse_sbc_caps(self, sbc);
597489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
598a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->dev_caps != NULL)
599a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_caps_unref(self->dev_caps);
600a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->dev_caps = gst_caps_new_full(structure, NULL);
601a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
602a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	tmp = gst_caps_to_string(self->dev_caps);
603a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_DEBUG_OBJECT(self, "Device capabilities: %s", tmp);
604a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_free(tmp);
605a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
606a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
607a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
608a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
609a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic gboolean gst_a2dp_sender_sink_get_capabilities(GstA2dpSenderSink *self)
610a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
611a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gchar *buf[BT_AUDIO_IPC_PACKET_SIZE];
612a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	struct bt_getcapabilities_req *req = (void *) buf;
613a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	struct bt_getcapabilities_rsp *rsp = (void *) buf;
614a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GIOError io_error;
615a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
616a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	memset(req, 0, BT_AUDIO_IPC_PACKET_SIZE);
617a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
618a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	req->h.msg_type = BT_GETCAPABILITIES_REQ;
619a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->device == NULL)
620a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
621a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	strncpy(req->device, self->device, 18);
622a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
623a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	io_error = gst_a2dp_sender_sink_audioservice_send(self, &req->h);
624a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (io_error != G_IO_ERROR_NONE) {
625a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error while asking device caps");
626a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
627a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
628a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	io_error = gst_a2dp_sender_sink_audioservice_expect(self,
629a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			&rsp->rsp_h.msg_h, BT_GETCAPABILITIES_RSP);
630a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (io_error != G_IO_ERROR_NONE) {
631a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error while getting device caps");
632a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
633a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
634a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
635a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (rsp->rsp_h.posix_errno != 0) {
636a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "BT_GETCAPABILITIES failed : %s(%d)",
637a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					strerror(rsp->rsp_h.posix_errno),
638a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					rsp->rsp_h.posix_errno);
639a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
640a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
641a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
642a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	memcpy(&self->data->caps, rsp, sizeof(*rsp));
643a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (!gst_a2dp_sender_sink_update_caps(self)) {
644a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_WARNING_OBJECT(self, "failed to update capabilities");
645a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
646a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
647a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
648a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
649a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
650a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
651a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic gboolean gst_a2dp_sender_sink_start(GstBaseSink *basesink)
652a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
653a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GstA2dpSenderSink *self = GST_A2DP_SENDER_SINK(basesink);
654a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gint sk;
655a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gint err;
656a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
657a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_INFO_OBJECT(self, "start");
658a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
659a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->watch_id = 0;
660a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
661a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	sk = bt_audio_service_open();
662a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sk <= 0) {
663a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		err = errno;
664a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Cannot open connection to bt "
665a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			"audio service: %s %d", strerror(err), err);
666a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		goto failed;
667a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
668a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
669a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->server = g_io_channel_unix_new(sk);
670a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->watch_id = g_io_add_watch(self->server, G_IO_HUP | G_IO_ERR |
671a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					G_IO_NVAL, server_callback, self);
672a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
673a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->data = g_new0(struct bluetooth_data, 1);
674a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	memset(self->data, 0, sizeof(struct bluetooth_data));
675a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
676a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->stream = NULL;
677a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->stream_caps = NULL;
678a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
679a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (!gst_a2dp_sender_sink_get_capabilities(self))
680a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		goto failed;
681a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
682a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
683a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
684a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzfailed:
685a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	bt_audio_service_close(sk);
686a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return FALSE;
687a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
688a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
689a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic gboolean gst_a2dp_sender_sink_stream_start(GstA2dpSenderSink *self)
690a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
691a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gchar buf[BT_AUDIO_IPC_PACKET_SIZE];
692a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	struct bt_streamstart_req *req = (void *) buf;
693a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	struct bt_streamstart_rsp *rsp = (void *) buf;
694a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	struct bt_streamfd_ind *ind = (void*) buf;
695a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GIOError io_error;
696a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
697a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_DEBUG_OBJECT(self, "stream start");
698a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
699a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	memset (req, 0, sizeof(buf));
700a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	req->h.msg_type = BT_STREAMSTART_REQ;
701a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
702a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	io_error = gst_a2dp_sender_sink_audioservice_send(self, &req->h);
703a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (io_error != G_IO_ERROR_NONE) {
704a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error ocurred while sending "
705a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					"start packet");
706a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
707a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
708a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
709a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_DEBUG_OBJECT(self, "stream start packet sent");
710a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
711a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	io_error = gst_a2dp_sender_sink_audioservice_expect(self,
712a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			&rsp->rsp_h.msg_h, BT_STREAMSTART_RSP);
713a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (io_error != G_IO_ERROR_NONE) {
714a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error while stream "
715a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			"start confirmation");
716a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
717a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
718a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
719a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (rsp->rsp_h.posix_errno != 0) {
720a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "BT_STREAMSTART_RSP failed : %s(%d)",
721a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					strerror(rsp->rsp_h.posix_errno),
722a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					rsp->rsp_h.posix_errno);
723a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
724a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
725a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
726a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_DEBUG_OBJECT(self, "stream started");
727a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
728a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	io_error = gst_a2dp_sender_sink_audioservice_expect(self, &ind->h,
729a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			BT_STREAMFD_IND);
730a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (io_error != G_IO_ERROR_NONE) {
731a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error while receiving "
732a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			"stream filedescriptor");
733a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
734a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
735a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
736a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (!gst_a2dp_sender_sink_conf_recv_stream_fd(self))
737a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
738a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
739a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
740a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
741a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
742a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic gboolean gst_a2dp_sender_sink_configure(GstA2dpSenderSink *self,
743a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			GstCaps *caps)
744a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
745a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gchar buf[BT_AUDIO_IPC_PACKET_SIZE];
746a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	struct bt_setconfiguration_req *req = (void *) buf;
747a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	struct bt_setconfiguration_rsp *rsp = (void *) buf;
748a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gboolean ret;
749a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GIOError io_error;
750a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gchar *temp;
751a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
752a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	temp = gst_caps_to_string(caps);
753a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_DEBUG_OBJECT(self, "configuring device with caps: %s", temp);
754a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_free(temp);
755a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
756a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	memset (req, 0, sizeof(buf));
757a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	req->h.msg_type = BT_SETCONFIGURATION_REQ;
758a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	req->access_mode = BT_CAPABILITIES_ACCESS_MODE_WRITE;
759a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	strncpy(req->device, self->device, 18);
760a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	ret = gst_a2dp_sender_sink_init_pkt_conf(self, caps,
761a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			&req->sbc_capabilities);
762a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (!ret) {
763a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Couldn't parse caps "
764a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"to packet configuration");
765a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
766a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
767a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
768a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	io_error = gst_a2dp_sender_sink_audioservice_send(self, &req->h);
769a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (io_error != G_IO_ERROR_NONE) {
770a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error ocurred while sending "
771a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					"configurarion packet");
772a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
773a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
774a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
775a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_DEBUG_OBJECT(self, "configuration packet sent");
776a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
777a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	io_error = gst_a2dp_sender_sink_audioservice_expect(self,
778a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			&rsp->rsp_h.msg_h, BT_SETCONFIGURATION_RSP);
779a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (io_error != G_IO_ERROR_NONE) {
780a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error while receiving device "
781a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					"confirmation");
782a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
783a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
784a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
785a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (rsp->rsp_h.posix_errno != 0) {
786a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "BT_SETCONFIGURATION_RSP failed : "
787a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					"%s(%d)",
788a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					strerror(rsp->rsp_h.posix_errno),
789a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					rsp->rsp_h.posix_errno);
790a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
791a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
792a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
793a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->data->link_mtu = rsp->link_mtu;
794a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_DEBUG_OBJECT(self, "configuration set");
795a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
796a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
797a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
798a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
799a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic GstFlowReturn gst_a2dp_sender_sink_preroll(GstBaseSink *basesink,
800a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					GstBuffer *buffer)
801a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
802a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GstA2dpSenderSink *sink = GST_A2DP_SENDER_SINK(basesink);
803a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gboolean ret;
804a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
805a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_A2DP_SENDER_SINK_MUTEX_LOCK(sink);
806a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
807a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	ret = gst_a2dp_sender_sink_stream_start(sink);
808a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
809a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_A2DP_SENDER_SINK_MUTEX_UNLOCK(sink);
810a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
811a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (!ret)
812a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return GST_FLOW_ERROR;
813a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
814a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return GST_FLOW_OK;
815a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
816a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
817a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic GstFlowReturn gst_a2dp_sender_sink_render(GstBaseSink *basesink,
818a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					GstBuffer *buffer)
819a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
820a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GstA2dpSenderSink *self = GST_A2DP_SENDER_SINK(basesink);
821a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gsize ret;
822a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GIOError err;
823a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
824a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	err = g_io_channel_write(self->stream, (gchar*)GST_BUFFER_DATA(buffer),
825a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			 (gsize)(GST_BUFFER_SIZE(buffer)), &ret);
826a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
827a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (err != G_IO_ERROR_NONE) {
828a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error while writting to socket: %d %s",
829a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				errno, strerror(errno));
830a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return GST_FLOW_ERROR;
831a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
832a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
833a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return GST_FLOW_OK;
834a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
835a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
836a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic gboolean gst_a2dp_sender_sink_unlock(GstBaseSink *basesink)
837a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
838a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GstA2dpSenderSink *self = GST_A2DP_SENDER_SINK(basesink);
839a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
840a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->stream != NULL)
841a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_io_channel_flush (self->stream, NULL);
842a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
843a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
844a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
845a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
846a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic GstFlowReturn gst_a2dp_sender_sink_buffer_alloc(GstBaseSink *basesink,
847a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				guint64 offset, guint size, GstCaps* caps,
848a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				GstBuffer **buf)
849a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
850a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GstA2dpSenderSink *self = GST_A2DP_SENDER_SINK(basesink);
851a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
852a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	*buf = gst_buffer_new_and_alloc(size);
853a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (!(*buf)) {
854a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "buffer allocation failed");
855a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return GST_FLOW_ERROR;
856a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
857a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
858a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gst_buffer_set_caps(*buf, caps);
859a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
860a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_BUFFER_OFFSET(*buf) = offset;
861a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
862a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return GST_FLOW_OK;
863a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
864a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
865a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic void gst_a2dp_sender_sink_class_init(GstA2dpSenderSinkClass *klass)
866a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
867a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GObjectClass *object_class = G_OBJECT_CLASS(klass);
868a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GstBaseSinkClass *basesink_class = GST_BASE_SINK_CLASS(klass);
869a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
870a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	parent_class = g_type_class_peek_parent(klass);
871a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
872a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	object_class->finalize = GST_DEBUG_FUNCPTR(
873a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					gst_a2dp_sender_sink_finalize);
874a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	object_class->set_property = GST_DEBUG_FUNCPTR(
875a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					gst_a2dp_sender_sink_set_property);
876a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	object_class->get_property = GST_DEBUG_FUNCPTR(
877a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					gst_a2dp_sender_sink_get_property);
878a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
879a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	basesink_class->start = GST_DEBUG_FUNCPTR(gst_a2dp_sender_sink_start);
880a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	basesink_class->stop = GST_DEBUG_FUNCPTR(gst_a2dp_sender_sink_stop);
881a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	basesink_class->render = GST_DEBUG_FUNCPTR(
882a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					gst_a2dp_sender_sink_render);
883a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	basesink_class->preroll = GST_DEBUG_FUNCPTR(
884a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					gst_a2dp_sender_sink_preroll);
885a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	basesink_class->unlock = GST_DEBUG_FUNCPTR(
886a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					gst_a2dp_sender_sink_unlock);
887a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
888a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	basesink_class->buffer_alloc =
889a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_DEBUG_FUNCPTR(gst_a2dp_sender_sink_buffer_alloc);
890a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
891a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_object_class_install_property(object_class, PROP_DEVICE,
892a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					g_param_spec_string("device", "Device",
893a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					"Bluetooth remote device address",
894a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					NULL, G_PARAM_READWRITE));
895a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
896a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_DEBUG_CATEGORY_INIT(a2dp_sender_sink_debug, "a2dpsendersink", 0,
897a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"A2DP sink element");
898a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
899a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
900a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic void gst_a2dp_sender_sink_init(GstA2dpSenderSink *self,
901a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			GstA2dpSenderSinkClass *klass)
902a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
903a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->device = NULL;
904a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->data = NULL;
905a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
906a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->stream = NULL;
907a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
908a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->dev_caps = NULL;
909a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
910a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->sink_lock = g_mutex_new();
911a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
912a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
913a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic GIOError gst_a2dp_sender_sink_audioservice_send(
914a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					GstA2dpSenderSink *self,
915a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					const bt_audio_msg_header_t *msg)
916a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
917a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GIOError error;
918a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gsize written;
919a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
920a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	error = g_io_channel_write(self->server, (const gchar*) msg,
921a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			BT_AUDIO_IPC_PACKET_SIZE, &written);
922a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (error != G_IO_ERROR_NONE)
923a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error sending data to audio service:"
924a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			" %s(%d)", strerror(errno), errno);
925a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
926a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return error;
927a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
928a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
929a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic GIOError gst_a2dp_sender_sink_audioservice_recv(
930a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					GstA2dpSenderSink *self,
931a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					bt_audio_msg_header_t *inmsg)
932a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
933a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GIOError status;
934a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gsize bytes_read;
935a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	const char *type;
936a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
937a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	status = g_io_channel_read(self->server, (gchar*) inmsg,
938a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			BT_AUDIO_IPC_PACKET_SIZE, &bytes_read);
939a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (status != G_IO_ERROR_NONE) {
940a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error receiving data from "
941a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"audio service");
942a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return status;
943a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
944a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
945a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	type = bt_audio_strmsg(inmsg->msg_type);
946a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (!type) {
947a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		status = G_IO_ERROR_INVAL;
948a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Bogus message type %d "
949a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"received from audio service",
950a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				inmsg->msg_type);
951a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
952a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
953a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return status;
954a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
955a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
956a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic GIOError gst_a2dp_sender_sink_audioservice_expect(
957a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			GstA2dpSenderSink *self, bt_audio_msg_header_t *outmsg,
958a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			int expected_type)
959a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
960a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GIOError status;
961a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
962a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	status = gst_a2dp_sender_sink_audioservice_recv(self, outmsg);
963a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (status != G_IO_ERROR_NONE)
964a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return status;
965a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
966a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (outmsg->msg_type != expected_type)
967a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		status = G_IO_ERROR_INVAL;
968a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
969a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return status;
970a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
971a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
972a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzgboolean gst_a2dp_sender_sink_plugin_init (GstPlugin * plugin)
973a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
974a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return gst_element_register (plugin, "a2dpsendersink",
975a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			GST_RANK_NONE, GST_TYPE_A2DP_SENDER_SINK);
976a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
977a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
978a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
979a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz/* public functions */
980a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von DentzGstCaps *gst_a2dp_sender_sink_get_device_caps(GstA2dpSenderSink *sink)
981a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
982a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sink->dev_caps == NULL)
983a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return NULL;
984a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
985a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return gst_caps_copy(sink->dev_caps);
986a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
987a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
988a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzgboolean gst_a2dp_sender_sink_set_device_caps(GstA2dpSenderSink *self,
989a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			GstCaps *caps)
990a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
991a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gboolean ret;
992a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
993a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_DEBUG_OBJECT(self, "setting device caps");
994a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_A2DP_SENDER_SINK_MUTEX_LOCK(self);
995a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	ret = gst_a2dp_sender_sink_configure(self, caps);
996a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
997a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->stream_caps)
998a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_caps_unref(self->stream_caps);
999a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->stream_caps = gst_caps_ref(caps);
1000a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1001a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_A2DP_SENDER_SINK_MUTEX_UNLOCK(self);
1002a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1003a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return ret;
1004a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1005a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1006a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzguint gst_a2dp_sender_sink_get_link_mtu(GstA2dpSenderSink *sink)
1007a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1008a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return sink->data->link_mtu;
1009a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1010a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1011a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzvoid gst_a2dp_sender_sink_set_device(GstA2dpSenderSink *self, const gchar* dev)
1012a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1013a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->device != NULL)
1014a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_free(self->device);
1015a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1016a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_LOG_OBJECT(self, "Setting device: %s", dev);
1017a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->device = g_strdup(dev);
1018a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1019a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1020a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzgchar *gst_a2dp_sender_sink_get_device(GstA2dpSenderSink *self)
1021a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1022a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return g_strdup(self->device);
1023a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1024a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1025