gstavdtpsink.c revision e8e68d294cd662970de6082473e30ecd6ee8dd61
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
38de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz#include <gst/rtp/gstrtpbuffer.h>
39de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
40a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#include "ipc.h"
41a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#include "rtp.h"
42a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#include "gstsbcutil.h"
43a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
44e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz#include "gstavdtpsink.h"
45a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
46e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von DentzGST_DEBUG_CATEGORY_STATIC(avdtp_sink_debug);
47e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz#define GST_CAT_DEFAULT avdtp_sink_debug
48a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
49a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#define BUFFER_SIZE 2048
50a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#define TEMPLATE_MAX_BITPOOL 64
51de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz#define CRC_PROTECTED 1
52de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz#define CRC_UNPROTECTED 0
53a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
54e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz#define GST_AVDTP_SINK_MUTEX_LOCK(s) G_STMT_START {	\
55a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_mutex_lock (s->sink_lock);		\
56a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	} G_STMT_END
57a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
58e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz#define GST_AVDTP_SINK_MUTEX_UNLOCK(s) G_STMT_START {	\
59a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_mutex_unlock (s->sink_lock);		\
60a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	} G_STMT_END
61a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
62a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
63a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstruct bluetooth_data {
64a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	struct bt_getcapabilities_rsp caps; /* Bluetooth device caps */
65a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	guint link_mtu;
66a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
67a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gchar buffer[BUFFER_SIZE];	/* Codec transfer buffer */
68a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz};
69a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
70a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#define IS_SBC(n) (strcmp((n), "audio/x-sbc") == 0)
71a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#define IS_MPEG(n) (strcmp((n), "audio/mpeg") == 0)
72a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
73a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzenum {
74a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	PROP_0,
75a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	PROP_DEVICE,
76a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz};
77a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
78e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von DentzGST_BOILERPLATE(GstAvdtpSink, gst_avdtp_sink, GstBaseSink,
79a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			GST_TYPE_BASE_SINK);
80a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
81e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic const GstElementDetails avdtp_sink_details =
82e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GST_ELEMENT_DETAILS("Bluetooth AVDTP sink",
83a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"Sink/Audio",
84a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"Plays audio to an A2DP device",
85a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"Marcel Holtmann <marcel@holtmann.org>");
86a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
87e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic GstStaticPadTemplate avdtp_sink_factory =
88a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_STATIC_PAD_TEMPLATE("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
89a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_STATIC_CAPS("application/x-rtp, "
90a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"media = (string) \"audio\", "
91de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"encoding-name = (string) \"SBC\";"
92de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"application/x-rtp, "
93de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"media = (string) \"audio\", "
94de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"payload = (int) "
95de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				GST_RTP_PAYLOAD_MPA_STRING ", "
96de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"clock-rate = (int) 90000; "
97de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"application/x-rtp, "
98de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"media = (string) \"audio\", "
99de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"payload = (int) "
100de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
101de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"clock-rate = (int) 90000, "
102de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"encoding-name = (string) \"MPA\""
103a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				));
104a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
105e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic GIOError gst_avdtp_sink_audioservice_send(GstAvdtpSink *self,
106a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					const bt_audio_msg_header_t *msg);
107e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic GIOError gst_avdtp_sink_audioservice_expect(
108e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz				GstAvdtpSink *self,
109a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				bt_audio_msg_header_t *outmsg,
110a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				int expected_type);
111a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
112a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
113e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic void gst_avdtp_sink_base_init(gpointer g_class)
114a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
115a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GstElementClass *element_class = GST_ELEMENT_CLASS(g_class);
116a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
117a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gst_element_class_add_pad_template(element_class,
118e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz		gst_static_pad_template_get(&avdtp_sink_factory));
119a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
120e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	gst_element_class_set_details(element_class, &avdtp_sink_details);
121a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
122a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
123e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_stop(GstBaseSink *basesink)
124a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
125e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GstAvdtpSink *self = GST_AVDTP_SINK(basesink);
126a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
127a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_INFO_OBJECT(self, "stop");
128a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
129a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->watch_id != 0) {
130a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_source_remove(self->watch_id);
131a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		self->watch_id = 0;
132a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
133a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
134a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->server) {
135a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		bt_audio_service_close(g_io_channel_unix_get_fd(self->server));
136a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_io_channel_unref(self->server);
137a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		self->server = NULL;
138a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
139a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
140a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->stream) {
141a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_io_channel_flush(self->stream, NULL);
142a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_io_channel_close(self->stream);
143a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_io_channel_unref(self->stream);
144a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		self->stream = NULL;
145a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
146a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
147a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->data) {
148a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_free(self->data);
149a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		self->data = NULL;
150a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
151a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
152a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->stream_caps) {
153a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_caps_unref(self->stream_caps);
154a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		self->stream_caps = NULL;
155a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
156a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
157a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->dev_caps) {
158a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_caps_unref(self->dev_caps);
159a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		self->dev_caps = NULL;
160a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
161a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
162a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
163a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
164a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
165e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic void gst_avdtp_sink_finalize(GObject *object)
166a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
167e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GstAvdtpSink *self = GST_AVDTP_SINK(object);
168a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
169a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->data)
170e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz		gst_avdtp_sink_stop(GST_BASE_SINK(self));
171a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
172a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->device)
173a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_free(self->device);
174a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
175a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_mutex_free(self->sink_lock);
176a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
177a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	G_OBJECT_CLASS(parent_class)->finalize(object);
178a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
179a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
180e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic void gst_avdtp_sink_set_property(GObject *object, guint prop_id,
181a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					const GValue *value, GParamSpec *pspec)
182a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
183e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GstAvdtpSink *sink = GST_AVDTP_SINK(object);
184a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
185a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	switch (prop_id) {
186a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	case PROP_DEVICE:
187a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (sink->device)
188a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			g_free(sink->device);
189a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		sink->device = g_value_dup_string(value);
190a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		break;
191a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
192a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	default:
193a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
194a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		break;
195a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
196a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
197a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
198e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic void gst_avdtp_sink_get_property(GObject *object, guint prop_id,
199a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					GValue *value, GParamSpec *pspec)
200a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
201e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GstAvdtpSink *sink = GST_AVDTP_SINK(object);
202a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
203a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	switch (prop_id) {
204a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	case PROP_DEVICE:
205a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_string(value, sink->device);
206a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		break;
207a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
208a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	default:
209a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
210a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		break;
211a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
212a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
213a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
214e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gint gst_avdtp_sink_bluetooth_recvmsg_fd(GstAvdtpSink *sink)
215a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
216a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	int err, ret;
217a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
218a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	ret = bt_audio_service_get_data_fd(
219a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			g_io_channel_unix_get_fd(sink->server));
220a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
221a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (ret < 0) {
222a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		err = errno;
223a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(sink, "Unable to receive fd: %s (%d)",
224a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				strerror(err), err);
225a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return -err;
226a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
227a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
228a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	sink->stream = g_io_channel_unix_new(ret);
229a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_DEBUG_OBJECT(sink, "stream_fd=%d", ret);
230a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
231a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return 0;
232a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
233a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
234e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_init_pkt_conf(GstAvdtpSink *sink,
235a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					GstCaps *caps,
236a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					sbc_capabilities_t *pkt)
237a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
238a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	sbc_capabilities_t *cfg = &sink->data->caps.sbc_capabilities;
239a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	const GValue *value = NULL;
240a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	const char *pref, *name;
241a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gint rate, subbands, blocks;
242a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GstStructure *structure = gst_caps_get_structure(caps, 0);
243a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
244a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	name = gst_structure_get_name(structure);
245a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* FIXME only sbc supported here, should suport mp3 */
246a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (!(IS_SBC(name))) {
247a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(sink, "Unsupported format %s", name);
248a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
249a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
250a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
251a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = gst_structure_get_value(structure, "rate");
252a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	rate = g_value_get_int(value);
253a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (rate == 44100)
254489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		cfg->frequency = BT_SBC_SAMPLING_FREQ_44100;
255a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (rate == 48000)
256489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		cfg->frequency = BT_SBC_SAMPLING_FREQ_48000;
257a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (rate == 32000)
258489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		cfg->frequency = BT_SBC_SAMPLING_FREQ_32000;
259a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (rate == 16000)
260489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		cfg->frequency = BT_SBC_SAMPLING_FREQ_16000;
261a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else {
262a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(sink, "Invalid rate while setting caps");
263a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
264a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
265a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
266a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = gst_structure_get_value(structure, "mode");
267a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	pref = g_value_get_string(value);
268a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (strcmp(pref, "auto") == 0)
269a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->channel_mode = BT_A2DP_CHANNEL_MODE_AUTO;
270a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (strcmp(pref, "mono") == 0)
271a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->channel_mode = BT_A2DP_CHANNEL_MODE_MONO;
272a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (strcmp(pref, "dual") == 0)
273a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->channel_mode = BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL;
274a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (strcmp(pref, "stereo") == 0)
275a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->channel_mode = BT_A2DP_CHANNEL_MODE_STEREO;
276a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (strcmp(pref, "joint") == 0)
277a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->channel_mode = BT_A2DP_CHANNEL_MODE_JOINT_STEREO;
278a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else {
279a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(sink, "Invalid mode %s", pref);
280a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
281a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
282a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
283a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = gst_structure_get_value(structure, "allocation");
284a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	pref = g_value_get_string(value);
285a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (strcmp(pref, "auto") == 0)
286a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->allocation_method = BT_A2DP_ALLOCATION_AUTO;
287a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (strcmp(pref, "loudness") == 0)
288a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->allocation_method = BT_A2DP_ALLOCATION_LOUDNESS;
289a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (strcmp(pref, "snr") == 0)
290a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->allocation_method = BT_A2DP_ALLOCATION_SNR;
291a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else {
292a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(sink, "Invalid allocation: %s", pref);
293a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
294a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
295a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
296a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = gst_structure_get_value(structure, "subbands");
297a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	subbands = g_value_get_int(value);
298a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (subbands == 8)
299a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->subbands = BT_A2DP_SUBBANDS_8;
300a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (subbands == 4)
301a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->subbands = BT_A2DP_SUBBANDS_4;
302a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else {
303a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(sink, "Invalid subbands %d", subbands);
304a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
305a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
306a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
307a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = gst_structure_get_value(structure, "blocks");
308a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	blocks = g_value_get_int(value);
309a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (blocks == 16)
310a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->block_length = BT_A2DP_BLOCK_LENGTH_16;
311a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (blocks == 12)
312a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->block_length = BT_A2DP_BLOCK_LENGTH_12;
313a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (blocks == 8)
314a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->block_length = BT_A2DP_BLOCK_LENGTH_8;
315a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (blocks == 4)
316a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->block_length = BT_A2DP_BLOCK_LENGTH_4;
317a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else {
318a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(sink, "Invalid blocks %d", blocks);
319a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
320a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
321a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
322a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = gst_structure_get_value(structure, "bitpool");
323a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	cfg->max_bitpool = cfg->min_bitpool = g_value_get_int(value);
324a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
325a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	memcpy(pkt, cfg, sizeof(*pkt));
326a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
327a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
328a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
329a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
330e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_conf_recv_stream_fd(
331e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz					GstAvdtpSink *self)
332a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
333a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	struct bluetooth_data *data = self->data;
334a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gint ret;
335a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GIOError err;
336a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GError *gerr = NULL;
337a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GIOStatus status;
338a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GIOFlags flags;
339a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gsize read;
340a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
341e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	ret = gst_avdtp_sink_bluetooth_recvmsg_fd(self);
342a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (ret < 0)
343a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
344a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
345a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (!self->stream) {
346a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error while configuring device: "
347a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"could not acquire audio socket");
348a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
349a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
350a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
351a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* set stream socket to nonblock */
352a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_LOG_OBJECT(self, "setting stream socket to nonblock");
353a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	flags = g_io_channel_get_flags(self->stream);
354a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	flags |= G_IO_FLAG_NONBLOCK;
355a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	status = g_io_channel_set_flags(self->stream, flags, &gerr);
356a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (status != G_IO_STATUS_NORMAL) {
357a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (gerr)
358a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			GST_WARNING_OBJECT(self, "Error while "
359a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"setting server socket to nonblock: "
360a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"%s", gerr->message);
361a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		else
362a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			GST_WARNING_OBJECT(self, "Error while "
363a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					"setting server "
364a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					"socket to nonblock");
365a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
366a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
367a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* It is possible there is some outstanding
368a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	data in the pipe - we have to empty it */
369a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_LOG_OBJECT(self, "emptying stream pipe");
370a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	while (1) {
371a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		err = g_io_channel_read(self->stream, data->buffer,
372a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					(gsize) data->link_mtu,
373a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					&read);
374a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (err != G_IO_ERROR_NONE || read <= 0)
375a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			break;
376a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
377a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
378a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* set stream socket to block */
379a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_LOG_OBJECT(self, "setting stream socket to block");
380a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	flags = g_io_channel_get_flags(self->stream);
381a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	flags &= ~G_IO_FLAG_NONBLOCK;
382a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	status = g_io_channel_set_flags(self->stream, flags, &gerr);
383a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (status != G_IO_STATUS_NORMAL) {
384a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (gerr)
385a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			GST_WARNING_OBJECT(self, "Error while "
386a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"setting server socket to block:"
387a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"%s", gerr->message);
388a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		else
389a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			GST_WARNING_OBJECT(self, "Error while "
390a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"setting server "
391a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"socket to block");
392a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
393a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
394a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	memset(data->buffer, 0, sizeof(data->buffer));
395a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
396a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
397a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
398a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
399a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic gboolean server_callback(GIOChannel *chan,
400a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					GIOCondition cond, gpointer data)
401a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
402e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GstAvdtpSink *sink;
403a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
404a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (cond & G_IO_HUP || cond & G_IO_NVAL)
405a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
406a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (cond & G_IO_ERR) {
407e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz		sink = GST_AVDTP_SINK(data);
408a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_WARNING_OBJECT(sink, "Untreated callback G_IO_ERR");
409a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
410a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
411a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
412a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
413a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
414e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic GstStructure *gst_avdtp_sink_parse_sbc_caps(
415e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz			GstAvdtpSink *self, sbc_capabilities_t *sbc)
416a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
417a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GstStructure *structure;
418a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GValue *value;
419a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GValue *list;
420a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gboolean mono, stereo;
421a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
422a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	structure = gst_structure_empty_new("audio/x-sbc");
423a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = g_value_init(g_new0(GValue, 1), G_TYPE_STRING);
424a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
425a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* mode */
426a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
427a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sbc->channel_mode == BT_A2DP_CHANNEL_MODE_AUTO) {
428a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_static_string(value, "joint");
429a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
430a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_static_string(value, "stereo");
431a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
432a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_static_string(value, "mono");
433a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
434a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_static_string(value, "dual");
435a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
436a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	} else {
437a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_MONO) {
438a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			g_value_set_static_string(value, "mono");
439a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			gst_value_list_prepend_value(list, value);
440a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		}
441a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_STEREO) {
442a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			g_value_set_static_string(value, "stereo");
443a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			gst_value_list_prepend_value(list, value);
444a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		}
445a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL) {
446a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			g_value_set_static_string(value, "dual");
447a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			gst_value_list_prepend_value(list, value);
448a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		}
449a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_JOINT_STEREO) {
450a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			g_value_set_static_string(value, "joint");
451a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			gst_value_list_prepend_value(list, value);
452a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		}
453a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
454a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_value_unset(value);
455a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (list) {
456a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_structure_set_value(structure, "mode", list);
457a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_free(list);
458a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		list = NULL;
459a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
460a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
461a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* subbands */
462a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
463a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = g_value_init(value, G_TYPE_INT);
464a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sbc->subbands & BT_A2DP_SUBBANDS_4) {
465a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 4);
466a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
467a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
468a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sbc->subbands & BT_A2DP_SUBBANDS_8) {
469a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 8);
470a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
471a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
472a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_value_unset(value);
473a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (list) {
474a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_structure_set_value(structure, "subbands", list);
475a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_free(list);
476a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		list = NULL;
477a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
478a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
479a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* blocks */
480a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = g_value_init(value, G_TYPE_INT);
481a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
482a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sbc->block_length & BT_A2DP_BLOCK_LENGTH_16) {
483a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 16);
484a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
485a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
486a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sbc->block_length & BT_A2DP_BLOCK_LENGTH_12) {
487a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 12);
488a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
489a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
490a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sbc->block_length & BT_A2DP_BLOCK_LENGTH_8) {
491a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 8);
492a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
493a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
494a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sbc->block_length & BT_A2DP_BLOCK_LENGTH_4) {
495a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 4);
496a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
497a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
498a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_value_unset(value);
499a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (list) {
500a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_structure_set_value(structure, "blocks", list);
501a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_free(list);
502a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		list = NULL;
503a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
504a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
505a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* allocation */
506a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_value_init(value, G_TYPE_STRING);
507a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	list = g_value_init(g_new0(GValue,1), GST_TYPE_LIST);
508a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sbc->allocation_method == BT_A2DP_ALLOCATION_AUTO) {
509a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_static_string(value, "loudness");
510a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
511a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_static_string(value, "snr");
512a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
513a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	} else {
514a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (sbc->allocation_method & BT_A2DP_ALLOCATION_LOUDNESS) {
515a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			g_value_set_static_string(value, "loudness");
516a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			gst_value_list_prepend_value(list, value);
517a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		}
518a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (sbc->allocation_method & BT_A2DP_ALLOCATION_SNR) {
519a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			g_value_set_static_string(value, "snr");
520a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			gst_value_list_prepend_value(list, value);
521a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		}
522a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
523a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_value_unset(value);
524a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (list) {
525a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_structure_set_value(structure, "allocation", list);
526a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_free(list);
527a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		list = NULL;
528a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
529a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
530a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* rate */
531a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_value_init(value, G_TYPE_INT);
532a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
533489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (sbc->frequency & BT_SBC_SAMPLING_FREQ_48000) {
534a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 48000);
535a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
536a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
537489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (sbc->frequency & BT_SBC_SAMPLING_FREQ_44100) {
538a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 44100);
539a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
540a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
541489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (sbc->frequency & BT_SBC_SAMPLING_FREQ_32000) {
542a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 32000);
543a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
544a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
545489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (sbc->frequency & BT_SBC_SAMPLING_FREQ_16000) {
546a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 16000);
547a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
548a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
549a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_value_unset(value);
550a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (list) {
551a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_structure_set_value(structure, "rate", list);
552a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_free(list);
553a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		list = NULL;
554a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
555a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
556a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* bitpool */
557a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = g_value_init(value, GST_TYPE_INT_RANGE);
558a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gst_value_set_int_range(value,
559a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			MIN(sbc->min_bitpool, TEMPLATE_MAX_BITPOOL),
560a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			MIN(sbc->max_bitpool, TEMPLATE_MAX_BITPOOL));
561a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gst_structure_set_value(structure, "bitpool", value);
562a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_value_unset(value);
563a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
564a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* channels */
565a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sbc->channel_mode == BT_A2DP_CHANNEL_MODE_AUTO) {
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		mono = FALSE;
570a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		stereo = FALSE;
571a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_MONO)
572a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			mono = TRUE;
573a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if ((sbc->channel_mode & BT_A2DP_CHANNEL_MODE_STEREO) ||
574a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				(sbc->channel_mode &
575a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL) ||
576a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				(sbc->channel_mode &
577a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				BT_A2DP_CHANNEL_MODE_JOINT_STEREO))
578a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			stereo = TRUE;
579a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
580a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (mono && stereo) {
581a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			g_value_init(value, GST_TYPE_INT_RANGE);
582a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			gst_value_set_int_range(value, 1, 2);
583a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		} else {
584a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			g_value_init(value, G_TYPE_INT);
585a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			if (mono)
586a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				g_value_set_int(value, 1);
587a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			else if (stereo)
588a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				g_value_set_int(value, 2);
589a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			else {
590a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				GST_ERROR_OBJECT(self,
591a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					"Unexpected number of channels");
592a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				g_value_set_int(value, 0);
593a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			}
594a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		}
595a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
596a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gst_structure_set_value(structure, "channels", value);
597a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_free(value);
598a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
599489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	return structure;
600489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz}
601489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
602e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic GstStructure *gst_avdtp_sink_parse_mpeg_caps(
603e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz			GstAvdtpSink *self, mpeg_capabilities_t *mpeg)
604de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz{
605de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	GstStructure *structure;
606de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	GValue *value;
607de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	GValue *list;
608de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	gboolean valid_layer = FALSE;
609de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	gboolean mono, stereo;
610de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
611de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	GST_LOG_OBJECT(self, "parsing mpeg caps");
612de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
613de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	structure = gst_structure_empty_new("audio/mpeg");
614de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	value = g_new0(GValue, 1);
615de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	g_value_init(value, G_TYPE_INT);
616de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
617de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
618de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	g_value_set_int(value, 1);
619de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	gst_value_list_prepend_value(list, value);
620de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	g_value_set_int(value, 2);
621de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	gst_value_list_prepend_value(list, value);
622de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	gst_structure_set_value(structure, "mpegversion", list);
623de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	g_free(list);
624de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
625de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	/* layer */
626de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	GST_LOG_OBJECT(self, "setting mpeg layer");
627de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
628de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (mpeg->layer & BT_MPEG_LAYER_1) {
629de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_value_set_int(value, 1);
630de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
631de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		valid_layer = TRUE;
632de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
633de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (mpeg->layer & BT_MPEG_LAYER_2) {
634de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_value_set_int(value, 2);
635de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
636de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		valid_layer = TRUE;
637de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
638de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (mpeg->layer & BT_MPEG_LAYER_3) {
639de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_value_set_int(value, 3);
640de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
641de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		valid_layer = TRUE;
642de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
643de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (list) {
644de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_structure_set_value(structure, "layer", list);
645de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_free(list);
646de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		list = NULL;
647de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
648de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
649de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (!valid_layer) {
650de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_structure_free(structure);
651de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_free(value);
652de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		return NULL;
653de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
654de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
655de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	/* rate */
656de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	GST_LOG_OBJECT(self, "setting mpeg rate");
657de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
658de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (mpeg->frequency & BT_MPEG_SAMPLING_FREQ_48000) {
659de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_value_set_int(value, 48000);
660de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
661de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
662de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (mpeg->frequency & BT_MPEG_SAMPLING_FREQ_44100) {
663de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_value_set_int(value, 44100);
664de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
665de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
666de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (mpeg->frequency & BT_MPEG_SAMPLING_FREQ_32000) {
667de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_value_set_int(value, 32000);
668de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
669de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
670de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (mpeg->frequency & BT_MPEG_SAMPLING_FREQ_24000) {
671de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_value_set_int(value, 24000);
672de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
673de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
674de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (mpeg->frequency & BT_MPEG_SAMPLING_FREQ_22050) {
675de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_value_set_int(value, 22050);
676de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
677de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
678de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (mpeg->frequency & BT_MPEG_SAMPLING_FREQ_16000) {
679de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_value_set_int(value, 16000);
680de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
681de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
682de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	g_value_unset(value);
683de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (list) {
684de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_structure_set_value(structure, "rate", list);
685de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_free(list);
686de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		list = NULL;
687de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
688de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
689de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	/* channels */
690de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	GST_LOG_OBJECT(self, "setting mpeg channels");
691de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	mono = FALSE;
692de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	stereo = FALSE;
693de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (mpeg->channel_mode & BT_A2DP_CHANNEL_MODE_MONO)
694de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		mono = TRUE;
695de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if ((mpeg->channel_mode & BT_A2DP_CHANNEL_MODE_STEREO) ||
696de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			(mpeg->channel_mode &
697de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL) ||
698de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			(mpeg->channel_mode &
699de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			BT_A2DP_CHANNEL_MODE_JOINT_STEREO))
700de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		stereo = TRUE;
701de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
702de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (mono && stereo) {
703de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_value_init(value, GST_TYPE_INT_RANGE);
704de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_value_set_int_range(value, 1, 2);
705de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	} else {
706de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_value_init(value, G_TYPE_INT);
707de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		if (mono)
708de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			g_value_set_int(value, 1);
709de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		else if (stereo)
710de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			g_value_set_int(value, 2);
711de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		else {
712de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			GST_ERROR_OBJECT(self,
713de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"Unexpected number of channels");
714de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			g_value_set_int(value, 0);
715de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		}
716de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
717de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	gst_structure_set_value(structure, "channels", value);
718de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	g_free(value);
719de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
720de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	return structure;
721de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz}
722de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
723e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_update_caps(GstAvdtpSink *self)
724489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz{
725489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	sbc_capabilities_t *sbc = &self->data->caps.sbc_capabilities;
726489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_capabilities_t *mpeg = &self->data->caps.mpeg_capabilities;
727de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	GstStructure *sbc_structure;
728de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	GstStructure *mpeg_structure;
729489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	gchar *tmp;
730489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
731489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	GST_LOG_OBJECT(self, "updating device caps");
732489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
733e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	sbc_structure = gst_avdtp_sink_parse_sbc_caps(self, sbc);
734e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	mpeg_structure = gst_avdtp_sink_parse_mpeg_caps(self, mpeg);
735489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
736a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->dev_caps != NULL)
737a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_caps_unref(self->dev_caps);
738de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	self->dev_caps = gst_caps_new_full(sbc_structure, NULL);
739de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (mpeg_structure != NULL)
740de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_caps_append_structure(self->dev_caps, mpeg_structure);
741a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
742a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	tmp = gst_caps_to_string(self->dev_caps);
743a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_DEBUG_OBJECT(self, "Device capabilities: %s", tmp);
744a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_free(tmp);
745a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
746a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
747a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
748a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
749e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_get_capabilities(GstAvdtpSink *self)
750a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
751a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gchar *buf[BT_AUDIO_IPC_PACKET_SIZE];
752a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	struct bt_getcapabilities_req *req = (void *) buf;
753a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	struct bt_getcapabilities_rsp *rsp = (void *) buf;
754a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GIOError io_error;
755a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
756a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	memset(req, 0, BT_AUDIO_IPC_PACKET_SIZE);
757a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
758a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	req->h.msg_type = BT_GETCAPABILITIES_REQ;
759a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->device == NULL)
760a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
761a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	strncpy(req->device, self->device, 18);
762a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
763e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	io_error = gst_avdtp_sink_audioservice_send(self, &req->h);
764a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (io_error != G_IO_ERROR_NONE) {
765a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error while asking device caps");
766de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		return FALSE;
767a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
768a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
769e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	io_error = gst_avdtp_sink_audioservice_expect(self,
770a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			&rsp->rsp_h.msg_h, BT_GETCAPABILITIES_RSP);
771a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (io_error != G_IO_ERROR_NONE) {
772a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error while getting device caps");
773a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
774a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
775a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
776a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (rsp->rsp_h.posix_errno != 0) {
777a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "BT_GETCAPABILITIES failed : %s(%d)",
778a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					strerror(rsp->rsp_h.posix_errno),
779a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					rsp->rsp_h.posix_errno);
780a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
781a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
782a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
783a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	memcpy(&self->data->caps, rsp, sizeof(*rsp));
784e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	if (!gst_avdtp_sink_update_caps(self)) {
785a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_WARNING_OBJECT(self, "failed to update capabilities");
786a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
787a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
788a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
789a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
790a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
791a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
792e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gint gst_avdtp_sink_get_channel_mode(const gchar *mode)
793de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz{
794de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (strcmp(mode, "stereo") == 0)
795de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		return BT_A2DP_CHANNEL_MODE_STEREO;
796de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else if (strcmp(mode, "joint") == 0)
797de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		return BT_A2DP_CHANNEL_MODE_JOINT_STEREO;
798de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else if (strcmp(mode, "dual") == 0)
799de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		return BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL;
800de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else if (strcmp(mode, "mono") == 0)
801de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		return BT_A2DP_CHANNEL_MODE_MONO;
802de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else
803de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		return -1;
804de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz}
805de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
806e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic void gst_avdtp_sink_tag(const GstTagList *taglist,
807de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			const gchar* tag, gpointer user_data)
808de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz{
809de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	gboolean crc;
810de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	gchar *channel_mode = NULL;
811e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GstAvdtpSink *self = GST_AVDTP_SINK(user_data);
812de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
813de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (strcmp(tag, "has-crc") == 0) {
814de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
815de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		if (!gst_tag_list_get_boolean(taglist, tag, &crc)) {
816de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			GST_WARNING_OBJECT(self, "failed to get crc tag");
817de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			self->mpeg_stream_changed = TRUE;
818de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		}
819de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
820e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz		gst_avdtp_sink_set_crc(self, crc);
821de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
822de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	} else if (strcmp(tag, "channel-mode") == 0) {
823de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
824de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		if (!gst_tag_list_get_string(taglist, tag, &channel_mode)) {
825de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			GST_WARNING_OBJECT(self,
826de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"failed to get channel-mode tag");
827de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			self->mpeg_stream_changed = TRUE;
828de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		}
829de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
830e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz		self->channel_mode = gst_avdtp_sink_get_channel_mode(
831de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz					channel_mode);
832de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		if (self->channel_mode == -1)
833de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			GST_WARNING_OBJECT(self, "Received invalid channel "
834de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz					"mode: %s", channel_mode);
835de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_free(channel_mode);
836de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
837de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	} else
838de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		GST_DEBUG_OBJECT(self, "received unused tag: %s", tag);
839de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz}
840de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
841e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_event(GstBaseSink *basesink,
842de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			GstEvent *event)
843de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz{
844e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GstAvdtpSink *self = GST_AVDTP_SINK(basesink);
845de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	GstTagList *taglist = NULL;
846de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
847de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (GST_EVENT_TYPE(event) == GST_EVENT_TAG) {
848de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		/* we check the tags, mp3 has tags that are importants and
849de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		 * are outside caps */
850de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_event_parse_tag(event, &taglist);
851e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz		gst_tag_list_foreach(taglist, gst_avdtp_sink_tag, self);
852de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
853de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
854de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	return TRUE;
855de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz}
856de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
857e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_start(GstBaseSink *basesink)
858a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
859e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GstAvdtpSink *self = GST_AVDTP_SINK(basesink);
860a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gint sk;
861a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gint err;
862a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
863a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_INFO_OBJECT(self, "start");
864a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
865a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->watch_id = 0;
866a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
867a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	sk = bt_audio_service_open();
868a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sk <= 0) {
869a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		err = errno;
870a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Cannot open connection to bt "
871a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			"audio service: %s %d", strerror(err), err);
872a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		goto failed;
873a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
874a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
875a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->server = g_io_channel_unix_new(sk);
876a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->watch_id = g_io_add_watch(self->server, G_IO_HUP | G_IO_ERR |
877a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					G_IO_NVAL, server_callback, self);
878a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
879a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->data = g_new0(struct bluetooth_data, 1);
880a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	memset(self->data, 0, sizeof(struct bluetooth_data));
881a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
882a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->stream = NULL;
883a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->stream_caps = NULL;
884de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	self->mp3_using_crc = -1;
885de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	self->channel_mode = -1;
886de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	self->mpeg_stream_changed = FALSE;
887a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
888e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	if (!gst_avdtp_sink_get_capabilities(self)) {
889de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		GST_ERROR_OBJECT(self, "failed to get capabilities "
890de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"from device");
891a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		goto failed;
892de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
893a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
894a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
895a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
896a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzfailed:
897a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	bt_audio_service_close(sk);
898a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return FALSE;
899a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
900a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
901e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_stream_start(GstAvdtpSink *self)
902a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
903a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gchar buf[BT_AUDIO_IPC_PACKET_SIZE];
904a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	struct bt_streamstart_req *req = (void *) buf;
905a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	struct bt_streamstart_rsp *rsp = (void *) buf;
906a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	struct bt_streamfd_ind *ind = (void*) buf;
907a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GIOError io_error;
908a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
909a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_DEBUG_OBJECT(self, "stream start");
910a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
911a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	memset (req, 0, sizeof(buf));
912a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	req->h.msg_type = BT_STREAMSTART_REQ;
913a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
914e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	io_error = gst_avdtp_sink_audioservice_send(self, &req->h);
915a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (io_error != G_IO_ERROR_NONE) {
916a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error ocurred while sending "
917a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					"start packet");
918a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
919a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
920a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
921a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_DEBUG_OBJECT(self, "stream start packet sent");
922a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
923e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	io_error = gst_avdtp_sink_audioservice_expect(self,
924a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			&rsp->rsp_h.msg_h, BT_STREAMSTART_RSP);
925a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (io_error != G_IO_ERROR_NONE) {
926a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error while stream "
927a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			"start confirmation");
928a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
929a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
930a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
931a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (rsp->rsp_h.posix_errno != 0) {
932a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "BT_STREAMSTART_RSP failed : %s(%d)",
933a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					strerror(rsp->rsp_h.posix_errno),
934a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					rsp->rsp_h.posix_errno);
935a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
936a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
937a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
938a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_DEBUG_OBJECT(self, "stream started");
939a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
940e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	io_error = gst_avdtp_sink_audioservice_expect(self, &ind->h,
941a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			BT_STREAMFD_IND);
942a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (io_error != G_IO_ERROR_NONE) {
943a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error while receiving "
944a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			"stream filedescriptor");
945a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
946a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
947a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
948e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	if (!gst_avdtp_sink_conf_recv_stream_fd(self))
949a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
950a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
951a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
952a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
953a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
954e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_init_mp3_pkt_conf(
955e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz		GstAvdtpSink *self, GstCaps *caps,
956de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		mpeg_capabilities_t *pkt)
957de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz{
958de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	const GValue *value = NULL;
959de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	gint rate, layer;
960de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	GstStructure *structure = gst_caps_get_structure(caps, 0);
961de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
962de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	/* layer */
963de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	value = gst_structure_get_value(structure, "layer");
964de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	layer = g_value_get_int(value);
965de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (layer == 1)
966de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		pkt->layer = BT_MPEG_LAYER_1;
967de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else if (layer == 2)
968de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		pkt->layer = BT_MPEG_LAYER_2;
969de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else if (layer == 3)
970de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		pkt->layer = BT_MPEG_LAYER_3;
971de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else {
972de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Unexpected layer: %d", layer);
973de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		return FALSE;
974de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
975de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
976de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	/* crc */
977de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (self->mp3_using_crc != -1)
978de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		pkt->crc = self->mp3_using_crc;
979de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else {
980de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		GST_ERROR_OBJECT(self, "No info about crc was received, "
981de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				" can't proceed");
982de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		return FALSE;
983de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
984de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
985de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	/* channel mode */
986de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (self->channel_mode != -1)
987de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		pkt->channel_mode = self->channel_mode;
988de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else {
989de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		GST_ERROR_OBJECT(self, "No info about channel mode "
990de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"received, can't proceed");
991de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		return FALSE;
992de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
993de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
994de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	/* mpf - we will only use the mandatory one */
995de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	pkt->mpf = 0;
996de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
997de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	value = gst_structure_get_value(structure, "rate");
998de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	rate = g_value_get_int(value);
999de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (rate == 44100)
1000de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		pkt->frequency = BT_MPEG_SAMPLING_FREQ_44100;
1001de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else if (rate == 48000)
1002de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		pkt->frequency = BT_MPEG_SAMPLING_FREQ_48000;
1003de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else if (rate == 32000)
1004de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		pkt->frequency = BT_MPEG_SAMPLING_FREQ_32000;
1005de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else if (rate == 24000)
1006de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		pkt->frequency = BT_MPEG_SAMPLING_FREQ_24000;
1007de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else if (rate == 22050)
1008de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		pkt->frequency = BT_MPEG_SAMPLING_FREQ_22050;
1009de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else if (rate == 16000)
1010de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		pkt->frequency = BT_MPEG_SAMPLING_FREQ_16000;
1011de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else {
1012de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Invalid rate while setting caps");
1013de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		return FALSE;
1014de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
1015de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1016de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	/* vbr - we always say its vbr, we don't have how to know it */
1017de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	pkt->bitrate = 0x8000;
1018de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1019de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	/* bitrate - we don't set anything, its vbr */
1020de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	/* FIXME - is this right? */
1021de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1022de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	return TRUE;
1023de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz}
1024de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1025e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_configure(GstAvdtpSink *self,
1026a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			GstCaps *caps)
1027a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1028a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gchar buf[BT_AUDIO_IPC_PACKET_SIZE];
1029a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	struct bt_setconfiguration_req *req = (void *) buf;
1030a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	struct bt_setconfiguration_rsp *rsp = (void *) buf;
1031a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gboolean ret;
1032a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GIOError io_error;
1033a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gchar *temp;
1034de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	GstStructure *structure;
1035a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1036a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	temp = gst_caps_to_string(caps);
1037a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_DEBUG_OBJECT(self, "configuring device with caps: %s", temp);
1038a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_free(temp);
1039a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1040a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	memset (req, 0, sizeof(buf));
1041a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	req->h.msg_type = BT_SETCONFIGURATION_REQ;
1042a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	req->access_mode = BT_CAPABILITIES_ACCESS_MODE_WRITE;
1043a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	strncpy(req->device, self->device, 18);
1044de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	structure = gst_caps_get_structure(caps, 0);
1045de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1046de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (gst_structure_has_name(structure, "audio/x-sbc"))
1047e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz		ret = gst_avdtp_sink_init_pkt_conf(self, caps,
1048de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				&req->sbc_capabilities);
1049de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else if (gst_structure_has_name(structure, "audio/mpeg"))
1050e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz		ret = gst_avdtp_sink_init_mp3_pkt_conf(self, caps,
1051de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				&req->mpeg_capabilities);
1052de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else
1053de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		ret = FALSE;
1054de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1055a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (!ret) {
1056a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Couldn't parse caps "
1057a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"to packet configuration");
1058a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
1059a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
1060a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1061e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	io_error = gst_avdtp_sink_audioservice_send(self, &req->h);
1062a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (io_error != G_IO_ERROR_NONE) {
1063a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error ocurred while sending "
1064a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					"configurarion packet");
1065a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
1066a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
1067a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1068a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_DEBUG_OBJECT(self, "configuration packet sent");
1069a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1070e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	io_error = gst_avdtp_sink_audioservice_expect(self,
1071a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			&rsp->rsp_h.msg_h, BT_SETCONFIGURATION_RSP);
1072a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (io_error != G_IO_ERROR_NONE) {
1073a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error while receiving device "
1074a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					"confirmation");
1075a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
1076a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
1077a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1078a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (rsp->rsp_h.posix_errno != 0) {
1079a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "BT_SETCONFIGURATION_RSP failed : "
1080a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					"%s(%d)",
1081a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					strerror(rsp->rsp_h.posix_errno),
1082a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					rsp->rsp_h.posix_errno);
1083a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
1084a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
1085a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1086a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->data->link_mtu = rsp->link_mtu;
1087a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_DEBUG_OBJECT(self, "configuration set");
1088a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1089a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
1090a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1091a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1092e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic GstFlowReturn gst_avdtp_sink_preroll(GstBaseSink *basesink,
1093a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					GstBuffer *buffer)
1094a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1095e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GstAvdtpSink *sink = GST_AVDTP_SINK(basesink);
1096a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gboolean ret;
1097a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1098e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GST_AVDTP_SINK_MUTEX_LOCK(sink);
1099a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1100e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	ret = gst_avdtp_sink_stream_start(sink);
1101a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1102e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GST_AVDTP_SINK_MUTEX_UNLOCK(sink);
1103a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1104a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (!ret)
1105a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return GST_FLOW_ERROR;
1106a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1107a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return GST_FLOW_OK;
1108a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1109a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1110e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic GstFlowReturn gst_avdtp_sink_render(GstBaseSink *basesink,
1111a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					GstBuffer *buffer)
1112a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1113e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GstAvdtpSink *self = GST_AVDTP_SINK(basesink);
1114a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gsize ret;
1115a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GIOError err;
1116a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1117a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	err = g_io_channel_write(self->stream, (gchar*)GST_BUFFER_DATA(buffer),
1118a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			 (gsize)(GST_BUFFER_SIZE(buffer)), &ret);
1119a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1120a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (err != G_IO_ERROR_NONE) {
1121a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error while writting to socket: %d %s",
1122a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				errno, strerror(errno));
1123a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return GST_FLOW_ERROR;
1124a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
1125a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1126a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return GST_FLOW_OK;
1127a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1128a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1129e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_unlock(GstBaseSink *basesink)
1130a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1131e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GstAvdtpSink *self = GST_AVDTP_SINK(basesink);
1132a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1133a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->stream != NULL)
1134a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_io_channel_flush (self->stream, NULL);
1135a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1136a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
1137a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1138a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1139e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic GstFlowReturn gst_avdtp_sink_buffer_alloc(GstBaseSink *basesink,
1140a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				guint64 offset, guint size, GstCaps* caps,
1141a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				GstBuffer **buf)
1142a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1143e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GstAvdtpSink *self = GST_AVDTP_SINK(basesink);
1144a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1145a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	*buf = gst_buffer_new_and_alloc(size);
1146a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (!(*buf)) {
1147a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "buffer allocation failed");
1148a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return GST_FLOW_ERROR;
1149a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
1150a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1151a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gst_buffer_set_caps(*buf, caps);
1152a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1153a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_BUFFER_OFFSET(*buf) = offset;
1154a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1155a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return GST_FLOW_OK;
1156a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1157a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1158e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic void gst_avdtp_sink_class_init(GstAvdtpSinkClass *klass)
1159a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1160a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GObjectClass *object_class = G_OBJECT_CLASS(klass);
1161a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GstBaseSinkClass *basesink_class = GST_BASE_SINK_CLASS(klass);
1162a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1163a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	parent_class = g_type_class_peek_parent(klass);
1164a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1165a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	object_class->finalize = GST_DEBUG_FUNCPTR(
1166e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz					gst_avdtp_sink_finalize);
1167a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	object_class->set_property = GST_DEBUG_FUNCPTR(
1168e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz					gst_avdtp_sink_set_property);
1169a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	object_class->get_property = GST_DEBUG_FUNCPTR(
1170e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz					gst_avdtp_sink_get_property);
1171a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1172e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	basesink_class->start = GST_DEBUG_FUNCPTR(gst_avdtp_sink_start);
1173e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	basesink_class->stop = GST_DEBUG_FUNCPTR(gst_avdtp_sink_stop);
1174a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	basesink_class->render = GST_DEBUG_FUNCPTR(
1175e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz					gst_avdtp_sink_render);
1176a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	basesink_class->preroll = GST_DEBUG_FUNCPTR(
1177e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz					gst_avdtp_sink_preroll);
1178a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	basesink_class->unlock = GST_DEBUG_FUNCPTR(
1179e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz					gst_avdtp_sink_unlock);
1180de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	basesink_class->event = GST_DEBUG_FUNCPTR(
1181e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz					gst_avdtp_sink_event);
1182a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1183a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	basesink_class->buffer_alloc =
1184e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz		GST_DEBUG_FUNCPTR(gst_avdtp_sink_buffer_alloc);
1185a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1186a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_object_class_install_property(object_class, PROP_DEVICE,
1187a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					g_param_spec_string("device", "Device",
1188a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					"Bluetooth remote device address",
1189a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					NULL, G_PARAM_READWRITE));
1190a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1191e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GST_DEBUG_CATEGORY_INIT(avdtp_sink_debug, "a2dpsendersink", 0,
1192a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"A2DP sink element");
1193a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1194a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1195e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic void gst_avdtp_sink_init(GstAvdtpSink *self,
1196e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz			GstAvdtpSinkClass *klass)
1197a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1198a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->device = NULL;
1199a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->data = NULL;
1200a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1201a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->stream = NULL;
1202a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1203a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->dev_caps = NULL;
1204a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1205a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->sink_lock = g_mutex_new();
1206a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1207a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1208e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic GIOError gst_avdtp_sink_audioservice_send(
1209e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz					GstAvdtpSink *self,
1210a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					const bt_audio_msg_header_t *msg)
1211a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1212a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GIOError error;
1213a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gsize written;
1214a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1215a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	error = g_io_channel_write(self->server, (const gchar*) msg,
1216a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			BT_AUDIO_IPC_PACKET_SIZE, &written);
1217a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (error != G_IO_ERROR_NONE)
1218a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error sending data to audio service:"
1219a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			" %s(%d)", strerror(errno), errno);
1220a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1221a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return error;
1222a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1223a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1224e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic GIOError gst_avdtp_sink_audioservice_recv(
1225e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz					GstAvdtpSink *self,
1226a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					bt_audio_msg_header_t *inmsg)
1227a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1228a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GIOError status;
1229a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gsize bytes_read;
1230a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	const char *type;
1231a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1232a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	status = g_io_channel_read(self->server, (gchar*) inmsg,
1233a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			BT_AUDIO_IPC_PACKET_SIZE, &bytes_read);
1234a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (status != G_IO_ERROR_NONE) {
1235a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error receiving data from "
1236a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"audio service");
1237a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return status;
1238a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
1239a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1240a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	type = bt_audio_strmsg(inmsg->msg_type);
1241a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (!type) {
1242a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		status = G_IO_ERROR_INVAL;
1243a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Bogus message type %d "
1244a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"received from audio service",
1245a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				inmsg->msg_type);
1246a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
1247a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1248a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return status;
1249a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1250a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1251e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic GIOError gst_avdtp_sink_audioservice_expect(
1252e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz			GstAvdtpSink *self, bt_audio_msg_header_t *outmsg,
1253a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			int expected_type)
1254a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1255a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GIOError status;
1256a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1257e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	status = gst_avdtp_sink_audioservice_recv(self, outmsg);
1258a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (status != G_IO_ERROR_NONE)
1259a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return status;
1260a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1261a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (outmsg->msg_type != expected_type)
1262a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		status = G_IO_ERROR_INVAL;
1263a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1264a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return status;
1265a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1266a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1267e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzgboolean gst_avdtp_sink_plugin_init (GstPlugin * plugin)
1268a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1269e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	return gst_element_register (plugin, "avdtpsink",
1270e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz			GST_RANK_NONE, GST_TYPE_AVDTP_SINK);
1271a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1272a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1273a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1274a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz/* public functions */
1275e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von DentzGstCaps *gst_avdtp_sink_get_device_caps(GstAvdtpSink *sink)
1276a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1277a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sink->dev_caps == NULL)
1278a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return NULL;
1279a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1280a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return gst_caps_copy(sink->dev_caps);
1281a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1282a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1283e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzgboolean gst_avdtp_sink_set_device_caps(GstAvdtpSink *self,
1284a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			GstCaps *caps)
1285a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1286a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gboolean ret;
1287a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1288a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_DEBUG_OBJECT(self, "setting device caps");
1289e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GST_AVDTP_SINK_MUTEX_LOCK(self);
1290e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	ret = gst_avdtp_sink_configure(self, caps);
1291a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1292a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->stream_caps)
1293a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_caps_unref(self->stream_caps);
1294a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->stream_caps = gst_caps_ref(caps);
1295a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1296e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GST_AVDTP_SINK_MUTEX_UNLOCK(self);
1297a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1298a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return ret;
1299a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1300a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1301e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzguint gst_avdtp_sink_get_link_mtu(GstAvdtpSink *sink)
1302a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1303a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return sink->data->link_mtu;
1304a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1305a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1306e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzvoid gst_avdtp_sink_set_device(GstAvdtpSink *self, const gchar* dev)
1307a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1308a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->device != NULL)
1309a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_free(self->device);
1310a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1311a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_LOG_OBJECT(self, "Setting device: %s", dev);
1312a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->device = g_strdup(dev);
1313a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1314a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1315e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzgchar *gst_avdtp_sink_get_device(GstAvdtpSink *self)
1316a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1317a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return g_strdup(self->device);
1318a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1319a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1320e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzvoid gst_avdtp_sink_set_crc(GstAvdtpSink *self, gboolean crc)
1321de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz{
1322de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	gint new_crc;
1323de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1324de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	new_crc = crc ? CRC_PROTECTED : CRC_UNPROTECTED;
1325de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1326de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	/* test if we already received a different crc */
1327de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (self->mp3_using_crc != -1 && new_crc != self->mp3_using_crc) {
1328de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		GST_ERROR_OBJECT(self, "crc changed during stream");
1329de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		/* FIXME test this, its not being used anywhere */
1330de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		self->mpeg_stream_changed = TRUE;
1331de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		return;
1332de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
1333de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	self->mp3_using_crc = new_crc;
1334de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1335de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz}
1336de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1337e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzvoid gst_avdtp_sink_set_channel_mode(GstAvdtpSink *self,
1338de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			const gchar *mode)
1339de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz{
1340de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	gint new_mode;
1341de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1342e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	new_mode = gst_avdtp_sink_get_channel_mode(mode);
1343de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1344de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (self->channel_mode != -1 && new_mode != self->channel_mode) {
1345de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		GST_ERROR_OBJECT(self, "channel mode changed during stream");
1346de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		self->mpeg_stream_changed = TRUE;
1347de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
1348de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1349de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	self->channel_mode = new_mode;
1350de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (self->channel_mode == -1)
1351de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		GST_WARNING_OBJECT(self, "Received invalid channel "
1352de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"mode: %s", mode);
1353de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz}
1354de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1355de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1356