1a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz/*
2a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz *
3a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz *  BlueZ - Bluetooth protocol stack for Linux
4a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz *
59184e2eeb7b97371c6b83b747c8984e2340d2b47Marcel Holtmann *  Copyright (C) 2004-2010  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
403622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz#include <dbus/dbus.h>
413622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
42a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#include "ipc.h"
43a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#include "rtp.h"
443622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz#include "a2dp-codecs.h"
45a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
46e20bd41482accdcd76d46111cccebb2cea46bf8cMarcel Holtmann#include "gstpragma.h"
47e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz#include "gstavdtpsink.h"
48a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
49e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von DentzGST_DEBUG_CATEGORY_STATIC(avdtp_sink_debug);
50e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz#define GST_CAT_DEFAULT avdtp_sink_debug
51a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
52a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#define BUFFER_SIZE 2048
53a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#define TEMPLATE_MAX_BITPOOL 64
54de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz#define CRC_PROTECTED 1
55de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz#define CRC_UNPROTECTED 0
56a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
576c4268df1dff13f3b1a7b778eb2e993648bff519Luiz Augusto von Dentz#define DEFAULT_AUTOCONNECT TRUE
586c4268df1dff13f3b1a7b778eb2e993648bff519Luiz Augusto von Dentz
59e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz#define GST_AVDTP_SINK_MUTEX_LOCK(s) G_STMT_START {	\
60cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg		g_mutex_lock(s->sink_lock);		\
61a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	} G_STMT_END
62a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
63e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz#define GST_AVDTP_SINK_MUTEX_UNLOCK(s) G_STMT_START {	\
64cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg		g_mutex_unlock(s->sink_lock);		\
65a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	} G_STMT_END
66a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
673622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz#ifndef DBUS_TYPE_UNIX_FD
683622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz#define DBUS_TYPE_UNIX_FD -1
693622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz#endif
70a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
71a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstruct bluetooth_data {
72b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	struct bt_get_capabilities_rsp *caps; /* Bluetooth device caps */
73a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	guint link_mtu;
74a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
753622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	DBusConnection *conn;
763622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	guint8 codec; /* Bluetooth transport configuration */
773622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	gchar *uuid;
783622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	guint8 *config;
793622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	gint config_size;
803622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
81a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gchar buffer[BUFFER_SIZE];	/* Codec transfer buffer */
82a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz};
83a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
84a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz#define IS_SBC(n) (strcmp((n), "audio/x-sbc") == 0)
853ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz#define IS_MPEG_AUDIO(n) (strcmp((n), "audio/mpeg") == 0)
86a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
87a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzenum {
88a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	PROP_0,
89a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	PROP_DEVICE,
903622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	PROP_AUTOCONNECT,
913622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	PROP_TRANSPORT
92a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz};
93a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
94e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von DentzGST_BOILERPLATE(GstAvdtpSink, gst_avdtp_sink, GstBaseSink,
95a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			GST_TYPE_BASE_SINK);
96a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
97e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic const GstElementDetails avdtp_sink_details =
98e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GST_ELEMENT_DETAILS("Bluetooth AVDTP sink",
99a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"Sink/Audio",
100a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"Plays audio to an A2DP device",
101a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"Marcel Holtmann <marcel@holtmann.org>");
102a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
103e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic GstStaticPadTemplate avdtp_sink_factory =
104a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_STATIC_PAD_TEMPLATE("sink", GST_PAD_SINK, GST_PAD_ALWAYS,
105a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_STATIC_CAPS("application/x-rtp, "
1063ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz				"media = (string) \"audio\","
1073ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz				"payload = (int) "
1083ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz					GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
1093ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz				"clock-rate = (int) { 16000, 32000, "
1103ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz					"44100, 48000 }, "
1113ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz				"encoding-name = (string) \"SBC\"; "
112de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"application/x-rtp, "
113de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"media = (string) \"audio\", "
114de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"payload = (int) "
115de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				GST_RTP_PAYLOAD_MPA_STRING ", "
116de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"clock-rate = (int) 90000; "
117de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"application/x-rtp, "
118de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"media = (string) \"audio\", "
119de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"payload = (int) "
120de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				GST_RTP_PAYLOAD_DYNAMIC_STRING ", "
121de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"clock-rate = (int) 90000, "
122de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"encoding-name = (string) \"MPA\""
123a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				));
124a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1254aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentzstatic int gst_avdtp_sink_audioservice_send(GstAvdtpSink *self,
126a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					const bt_audio_msg_header_t *msg);
1274aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentzstatic int gst_avdtp_sink_audioservice_expect(GstAvdtpSink *self,
1284aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz					bt_audio_msg_header_t *outmsg,
1294aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz					guint8 expected_name);
130a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
131a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
132e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic void gst_avdtp_sink_base_init(gpointer g_class)
133a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
134a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GstElementClass *element_class = GST_ELEMENT_CLASS(g_class);
135a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
136a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gst_element_class_add_pad_template(element_class,
137e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz		gst_static_pad_template_get(&avdtp_sink_factory));
138a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
139e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	gst_element_class_set_details(element_class, &avdtp_sink_details);
140a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
141a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1423622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentzstatic void gst_avdtp_sink_transport_release(GstAvdtpSink *self)
1433622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz{
1443622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	DBusMessage *msg;
1453622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	const char *access_type = "w";
1463622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
1473622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	msg = dbus_message_new_method_call("org.bluez", self->transport,
1483622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz						"org.bluez.MediaTransport",
1493622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz						"Release");
1503622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
1513622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	dbus_message_append_args(msg, DBUS_TYPE_STRING, &access_type,
1523622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz					DBUS_TYPE_INVALID);
1533622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
1543622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	dbus_connection_send(self->data->conn, msg, NULL);
1553622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
1563622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	dbus_message_unref(msg);
1573622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz}
1583622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
159e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_stop(GstBaseSink *basesink)
160a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
161e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GstAvdtpSink *self = GST_AVDTP_SINK(basesink);
162a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
163a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_INFO_OBJECT(self, "stop");
164a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
165a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->watch_id != 0) {
166a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_source_remove(self->watch_id);
167a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		self->watch_id = 0;
168a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
169a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
170a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->server) {
171a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		bt_audio_service_close(g_io_channel_unix_get_fd(self->server));
172a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_io_channel_unref(self->server);
173a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		self->server = NULL;
174a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
175a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
176a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->stream) {
17710d6858927cb3db0a06c42f41cdb5f3175082df3Luiz Augusto von Dentz		g_io_channel_shutdown(self->stream, TRUE, NULL);
178a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_io_channel_unref(self->stream);
179a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		self->stream = NULL;
180a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
181a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
182a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->data) {
1833622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		if (self->transport)
1843622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			gst_avdtp_sink_transport_release(self);
1853622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		if (self->data->conn)
1863622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			dbus_connection_unref(self->data->conn);
187a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_free(self->data);
188a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		self->data = NULL;
189a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
190a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
191a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->stream_caps) {
192a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_caps_unref(self->stream_caps);
193a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		self->stream_caps = NULL;
194a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
195a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
196a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->dev_caps) {
197a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_caps_unref(self->dev_caps);
198a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		self->dev_caps = NULL;
199a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
200a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
201a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
202a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
203a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
204e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic void gst_avdtp_sink_finalize(GObject *object)
205a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
206e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GstAvdtpSink *self = GST_AVDTP_SINK(object);
207a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
208a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->data)
209e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz		gst_avdtp_sink_stop(GST_BASE_SINK(self));
210a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
211a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->device)
212a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_free(self->device);
213a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
2143622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (self->transport)
2153622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_free(self->transport);
2163622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
217a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_mutex_free(self->sink_lock);
218a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
219a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	G_OBJECT_CLASS(parent_class)->finalize(object);
220a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
221a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
222e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic void gst_avdtp_sink_set_property(GObject *object, guint prop_id,
223a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					const GValue *value, GParamSpec *pspec)
224a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
225e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GstAvdtpSink *sink = GST_AVDTP_SINK(object);
226a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
227a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	switch (prop_id) {
228a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	case PROP_DEVICE:
229a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (sink->device)
230a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			g_free(sink->device);
231a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		sink->device = g_value_dup_string(value);
232a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		break;
233a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
2346c4268df1dff13f3b1a7b778eb2e993648bff519Luiz Augusto von Dentz	case PROP_AUTOCONNECT:
2356c4268df1dff13f3b1a7b778eb2e993648bff519Luiz Augusto von Dentz		sink->autoconnect = g_value_get_boolean(value);
2366c4268df1dff13f3b1a7b778eb2e993648bff519Luiz Augusto von Dentz		break;
2373622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
2383622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	case PROP_TRANSPORT:
2393622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		if (sink->transport)
2403622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			g_free(sink->transport);
2413622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		sink->transport = g_value_dup_string(value);
2423622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		break;
2433622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
244a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	default:
245a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
246a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		break;
247a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
248a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
249a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
250e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic void gst_avdtp_sink_get_property(GObject *object, guint prop_id,
251a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					GValue *value, GParamSpec *pspec)
252a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
253e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GstAvdtpSink *sink = GST_AVDTP_SINK(object);
254a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
255a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	switch (prop_id) {
256a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	case PROP_DEVICE:
257a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_string(value, sink->device);
258a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		break;
259a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
2606c4268df1dff13f3b1a7b778eb2e993648bff519Luiz Augusto von Dentz	case PROP_AUTOCONNECT:
2616c4268df1dff13f3b1a7b778eb2e993648bff519Luiz Augusto von Dentz		g_value_set_boolean(value, sink->autoconnect);
2626c4268df1dff13f3b1a7b778eb2e993648bff519Luiz Augusto von Dentz		break;
2633622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
2643622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	case PROP_TRANSPORT:
2653622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_string(value, sink->transport);
2663622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		break;
2673622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
268a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	default:
269a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
270a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		break;
271a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
272a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
273a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
274e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gint gst_avdtp_sink_bluetooth_recvmsg_fd(GstAvdtpSink *sink)
275a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
276a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	int err, ret;
277a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
278a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	ret = bt_audio_service_get_data_fd(
279a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			g_io_channel_unix_get_fd(sink->server));
280a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
281a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (ret < 0) {
282a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		err = errno;
283a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(sink, "Unable to receive fd: %s (%d)",
284a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				strerror(err), err);
285a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return -err;
286a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
287a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
288a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	sink->stream = g_io_channel_unix_new(ret);
2894aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	g_io_channel_set_encoding(sink->stream, NULL, NULL);
290a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_DEBUG_OBJECT(sink, "stream_fd=%d", ret);
291a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
292a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return 0;
293a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
294a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
295b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentzstatic codec_capabilities_t *gst_avdtp_find_caps(GstAvdtpSink *sink,
296b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz						uint8_t codec_type)
297b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz{
298b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	struct bt_get_capabilities_rsp *rsp = sink->data->caps;
299b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	codec_capabilities_t *codec = (void *) rsp->data;
300b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	int bytes_left = rsp->h.length - sizeof(*rsp);
301b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz
302b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	while (bytes_left > 0) {
303c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz		if ((codec->type == codec_type) &&
304c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz				!(codec->lock & BT_WRITE_LOCK))
305b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz			break;
306b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz
307b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz		bytes_left -= codec->length;
308b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz		codec = (void *) codec + codec->length;
309b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	}
310b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz
311b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	if (bytes_left <= 0)
312b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz		return NULL;
313b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz
314b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	return codec;
315b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz}
316b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz
3173ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentzstatic gboolean gst_avdtp_sink_init_sbc_pkt_conf(GstAvdtpSink *sink,
318a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					GstCaps *caps,
319a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					sbc_capabilities_t *pkt)
320a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
321b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	sbc_capabilities_t *cfg;
322a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	const GValue *value = NULL;
323a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	const char *pref, *name;
324a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gint rate, subbands, blocks;
325a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GstStructure *structure = gst_caps_get_structure(caps, 0);
326a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
327379d756055f32d46fe7e09e1d89be1f780abb144Luiz Augusto von Dentz	cfg = (void *) gst_avdtp_find_caps(sink, BT_A2DP_SBC_SINK);
328a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	name = gst_structure_get_name(structure);
3293ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz
330a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (!(IS_SBC(name))) {
3313ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz		GST_ERROR_OBJECT(sink, "Unexpected format %s, "
3323ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz				"was expecting sbc", name);
333a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
334a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
335a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
336a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = gst_structure_get_value(structure, "rate");
337a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	rate = g_value_get_int(value);
338a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (rate == 44100)
339489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		cfg->frequency = BT_SBC_SAMPLING_FREQ_44100;
340a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (rate == 48000)
341489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		cfg->frequency = BT_SBC_SAMPLING_FREQ_48000;
342a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (rate == 32000)
343489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		cfg->frequency = BT_SBC_SAMPLING_FREQ_32000;
344a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (rate == 16000)
345489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		cfg->frequency = BT_SBC_SAMPLING_FREQ_16000;
346a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else {
347a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(sink, "Invalid rate while setting caps");
348a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
349a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
350a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
351a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = gst_structure_get_value(structure, "mode");
352a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	pref = g_value_get_string(value);
3538fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz	if (strcmp(pref, "mono") == 0)
354a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->channel_mode = BT_A2DP_CHANNEL_MODE_MONO;
355a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (strcmp(pref, "dual") == 0)
356a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->channel_mode = BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL;
357a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (strcmp(pref, "stereo") == 0)
358a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->channel_mode = BT_A2DP_CHANNEL_MODE_STEREO;
359a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (strcmp(pref, "joint") == 0)
360a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->channel_mode = BT_A2DP_CHANNEL_MODE_JOINT_STEREO;
361a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else {
362a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(sink, "Invalid mode %s", pref);
363a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
364a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
365a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
366a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = gst_structure_get_value(structure, "allocation");
367a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	pref = g_value_get_string(value);
3688fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz	if (strcmp(pref, "loudness") == 0)
369a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->allocation_method = BT_A2DP_ALLOCATION_LOUDNESS;
370a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (strcmp(pref, "snr") == 0)
371a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->allocation_method = BT_A2DP_ALLOCATION_SNR;
372a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else {
373a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(sink, "Invalid allocation: %s", pref);
374a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
375a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
376a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
377a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = gst_structure_get_value(structure, "subbands");
378a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	subbands = g_value_get_int(value);
379a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (subbands == 8)
380a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->subbands = BT_A2DP_SUBBANDS_8;
381a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (subbands == 4)
382a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->subbands = BT_A2DP_SUBBANDS_4;
383a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else {
384a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(sink, "Invalid subbands %d", subbands);
385a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
386a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
387a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
388a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = gst_structure_get_value(structure, "blocks");
389a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	blocks = g_value_get_int(value);
390a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (blocks == 16)
391a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->block_length = BT_A2DP_BLOCK_LENGTH_16;
392a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (blocks == 12)
393a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->block_length = BT_A2DP_BLOCK_LENGTH_12;
394a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (blocks == 8)
395a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->block_length = BT_A2DP_BLOCK_LENGTH_8;
396a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else if (blocks == 4)
397a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		cfg->block_length = BT_A2DP_BLOCK_LENGTH_4;
398a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	else {
399a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(sink, "Invalid blocks %d", blocks);
400a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
401a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
402a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
403a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = gst_structure_get_value(structure, "bitpool");
404a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	cfg->max_bitpool = cfg->min_bitpool = g_value_get_int(value);
405a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
406a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	memcpy(pkt, cfg, sizeof(*pkt));
407a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
408a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
409a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
410a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
411e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_conf_recv_stream_fd(
412e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz					GstAvdtpSink *self)
413a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
414a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	struct bluetooth_data *data = self->data;
415a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gint ret;
416a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GError *gerr = NULL;
417a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GIOStatus status;
418a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GIOFlags flags;
4194aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	int fd;
420a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
4213622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	/* Proceed if stream was already acquired */
4223622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (self->stream != NULL)
4233622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		goto proceed;
4243622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
425e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	ret = gst_avdtp_sink_bluetooth_recvmsg_fd(self);
426a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (ret < 0)
427a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
428a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
429a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (!self->stream) {
430a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error while configuring device: "
431a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"could not acquire audio socket");
432a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
433a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
434a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
4353622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentzproceed:
436a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* set stream socket to nonblock */
437a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_LOG_OBJECT(self, "setting stream socket to nonblock");
438a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	flags = g_io_channel_get_flags(self->stream);
439a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	flags |= G_IO_FLAG_NONBLOCK;
440a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	status = g_io_channel_set_flags(self->stream, flags, &gerr);
441a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (status != G_IO_STATUS_NORMAL) {
442a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (gerr)
443a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			GST_WARNING_OBJECT(self, "Error while "
444a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"setting server socket to nonblock: "
445a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"%s", gerr->message);
446a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		else
447a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			GST_WARNING_OBJECT(self, "Error while "
448a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					"setting server "
449a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					"socket to nonblock");
450a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
451a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
4524aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	fd = g_io_channel_unix_get_fd(self->stream);
4534aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz
454a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* It is possible there is some outstanding
455a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	data in the pipe - we have to empty it */
456a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_LOG_OBJECT(self, "emptying stream pipe");
457a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	while (1) {
4584aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz		ssize_t bread = read(fd, data->buffer, data->link_mtu);
4594aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz		if (bread <= 0)
460a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			break;
461a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
462a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
463a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* set stream socket to block */
464a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_LOG_OBJECT(self, "setting stream socket to block");
465a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	flags = g_io_channel_get_flags(self->stream);
466a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	flags &= ~G_IO_FLAG_NONBLOCK;
467a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	status = g_io_channel_set_flags(self->stream, flags, &gerr);
468a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (status != G_IO_STATUS_NORMAL) {
469a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		if (gerr)
470a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			GST_WARNING_OBJECT(self, "Error while "
471a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"setting server socket to block:"
472a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"%s", gerr->message);
473a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		else
474a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			GST_WARNING_OBJECT(self, "Error while "
475a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"setting server "
476a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"socket to block");
477a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
478a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
479a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	memset(data->buffer, 0, sizeof(data->buffer));
480a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
481a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
482a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
483a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
484a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzstatic gboolean server_callback(GIOChannel *chan,
485a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					GIOCondition cond, gpointer data)
486a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
487a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (cond & G_IO_HUP || cond & G_IO_NVAL)
488a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
4895e8241cb3a319d4bd32c2b58d1d60d165d98ba73Luiz Augusto von Dentz	else if (cond & G_IO_ERR)
4905e8241cb3a319d4bd32c2b58d1d60d165d98ba73Luiz Augusto von Dentz		GST_WARNING_OBJECT(GST_AVDTP_SINK(data),
4915e8241cb3a319d4bd32c2b58d1d60d165d98ba73Luiz Augusto von Dentz					"Untreated callback G_IO_ERR");
492a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
493a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
494a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
495a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
496e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic GstStructure *gst_avdtp_sink_parse_sbc_caps(
497e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz			GstAvdtpSink *self, sbc_capabilities_t *sbc)
498a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
499a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GstStructure *structure;
500a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GValue *value;
501a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GValue *list;
502a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gboolean mono, stereo;
503a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
504dbf642ce320cc7241d78823dc4143a1fe71c35a7Luiz Augusto von Dentz	if (sbc == NULL)
505dbf642ce320cc7241d78823dc4143a1fe71c35a7Luiz Augusto von Dentz		return NULL;
506dbf642ce320cc7241d78823dc4143a1fe71c35a7Luiz Augusto von Dentz
507a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	structure = gst_structure_empty_new("audio/x-sbc");
508a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = g_value_init(g_new0(GValue, 1), G_TYPE_STRING);
509a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
510a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* mode */
511a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
5128fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz	if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_MONO) {
5138fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz		g_value_set_static_string(value, "mono");
514a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
5158fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz	}
5168fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz	if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_STEREO) {
517a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_static_string(value, "stereo");
518a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
5198fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz	}
5208fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz	if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL) {
521a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_static_string(value, "dual");
522a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
5238fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz	}
5248fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz	if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_JOINT_STEREO) {
5258fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz		g_value_set_static_string(value, "joint");
5268fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
527a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
528a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_value_unset(value);
529a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (list) {
530a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_structure_set_value(structure, "mode", list);
531a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_free(list);
532a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		list = NULL;
533a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
534a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
535a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* subbands */
536a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
537a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = g_value_init(value, G_TYPE_INT);
538a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sbc->subbands & BT_A2DP_SUBBANDS_4) {
539a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 4);
540a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
541a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
542a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sbc->subbands & BT_A2DP_SUBBANDS_8) {
543a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 8);
544a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
545a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
546a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_value_unset(value);
547a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (list) {
548a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_structure_set_value(structure, "subbands", list);
549a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_free(list);
550a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		list = NULL;
551a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
552a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
553a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* blocks */
554a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = g_value_init(value, G_TYPE_INT);
555a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
556a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sbc->block_length & BT_A2DP_BLOCK_LENGTH_16) {
557a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 16);
558a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
559a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
560a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sbc->block_length & BT_A2DP_BLOCK_LENGTH_12) {
561a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 12);
562a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
563a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
564a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sbc->block_length & BT_A2DP_BLOCK_LENGTH_8) {
565a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 8);
566a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
567a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
568a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sbc->block_length & BT_A2DP_BLOCK_LENGTH_4) {
569a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 4);
570a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
571a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
572a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_value_unset(value);
573a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (list) {
574a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_structure_set_value(structure, "blocks", list);
575a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_free(list);
576a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		list = NULL;
577a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
578a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
579a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* allocation */
580a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_value_init(value, G_TYPE_STRING);
581a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	list = g_value_init(g_new0(GValue,1), GST_TYPE_LIST);
5828fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz	if (sbc->allocation_method & BT_A2DP_ALLOCATION_LOUDNESS) {
583a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_static_string(value, "loudness");
584a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
5858fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz	}
5868fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz	if (sbc->allocation_method & BT_A2DP_ALLOCATION_SNR) {
587a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_static_string(value, "snr");
588a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
589a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
590a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_value_unset(value);
591a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (list) {
592a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_structure_set_value(structure, "allocation", list);
593a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_free(list);
594a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		list = NULL;
595a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
596a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
597a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* rate */
598a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_value_init(value, G_TYPE_INT);
599a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
600489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (sbc->frequency & BT_SBC_SAMPLING_FREQ_48000) {
601a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 48000);
602a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
603a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
604489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (sbc->frequency & BT_SBC_SAMPLING_FREQ_44100) {
605a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 44100);
606a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
607a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
608489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (sbc->frequency & BT_SBC_SAMPLING_FREQ_32000) {
609a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 32000);
610a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
611a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
612489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (sbc->frequency & BT_SBC_SAMPLING_FREQ_16000) {
613a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_set_int(value, 16000);
614a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
615a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
616a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_value_unset(value);
617a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (list) {
618a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_structure_set_value(structure, "rate", list);
619a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_free(list);
620a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		list = NULL;
621a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
622a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
623a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* bitpool */
624a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	value = g_value_init(value, GST_TYPE_INT_RANGE);
625a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gst_value_set_int_range(value,
626a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			MIN(sbc->min_bitpool, TEMPLATE_MAX_BITPOOL),
627a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			MIN(sbc->max_bitpool, TEMPLATE_MAX_BITPOOL));
628a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gst_structure_set_value(structure, "bitpool", value);
629a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_value_unset(value);
630a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
631a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	/* channels */
6328fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz	mono = FALSE;
6338fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz	stereo = FALSE;
6348fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz	if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_MONO)
6358fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz		mono = TRUE;
6368fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz	if ((sbc->channel_mode & BT_A2DP_CHANNEL_MODE_STEREO) ||
6378fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz			(sbc->channel_mode &
6388fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz			BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL) ||
6398fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz			(sbc->channel_mode &
6408fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz			BT_A2DP_CHANNEL_MODE_JOINT_STEREO))
6418fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz		stereo = TRUE;
6428fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz
6438fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz	if (mono && stereo) {
644a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_value_init(value, GST_TYPE_INT_RANGE);
645a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_value_set_int_range(value, 1, 2);
646a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	} else {
6478fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz		g_value_init(value, G_TYPE_INT);
6488fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz		if (mono)
6498fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz			g_value_set_int(value, 1);
6508fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz		else if (stereo)
6518fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz			g_value_set_int(value, 2);
6528fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz		else {
6538fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz			GST_ERROR_OBJECT(self,
6548fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz				"Unexpected number of channels");
6558fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz			g_value_set_int(value, 0);
656a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		}
657a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
6588fbc804e08629e5450d2641b4ba660f111dedbb2Luiz Augusto von Dentz
659a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gst_structure_set_value(structure, "channels", value);
660a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_free(value);
661a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
662489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	return structure;
663489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz}
664489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
665e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic GstStructure *gst_avdtp_sink_parse_mpeg_caps(
666e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz			GstAvdtpSink *self, mpeg_capabilities_t *mpeg)
667de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz{
668de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	GstStructure *structure;
669de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	GValue *value;
670de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	GValue *list;
671de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	gboolean valid_layer = FALSE;
672de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	gboolean mono, stereo;
673de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
674b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	if (!mpeg)
675b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz		return NULL;
676b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz
677de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	GST_LOG_OBJECT(self, "parsing mpeg caps");
678de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
679de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	structure = gst_structure_empty_new("audio/mpeg");
680de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	value = g_new0(GValue, 1);
681de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	g_value_init(value, G_TYPE_INT);
682de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
683de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
684de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	g_value_set_int(value, 1);
685de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	gst_value_list_prepend_value(list, value);
686de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	g_value_set_int(value, 2);
687de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	gst_value_list_prepend_value(list, value);
688de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	gst_structure_set_value(structure, "mpegversion", list);
689de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	g_free(list);
690de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
691de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	/* layer */
692de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	GST_LOG_OBJECT(self, "setting mpeg layer");
693de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
694de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (mpeg->layer & BT_MPEG_LAYER_1) {
695de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_value_set_int(value, 1);
696de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
697de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		valid_layer = TRUE;
698de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
699de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (mpeg->layer & BT_MPEG_LAYER_2) {
700de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_value_set_int(value, 2);
701de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
702de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		valid_layer = TRUE;
703de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
704de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (mpeg->layer & BT_MPEG_LAYER_3) {
705de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_value_set_int(value, 3);
706de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
707de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		valid_layer = TRUE;
708de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
709de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (list) {
710de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_structure_set_value(structure, "layer", list);
711de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_free(list);
712de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		list = NULL;
713de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
714de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
715de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (!valid_layer) {
716de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_structure_free(structure);
717de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_free(value);
718de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		return NULL;
719de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
720de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
721de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	/* rate */
722de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	GST_LOG_OBJECT(self, "setting mpeg rate");
723de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
724de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (mpeg->frequency & BT_MPEG_SAMPLING_FREQ_48000) {
725de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_value_set_int(value, 48000);
726de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
727de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
728de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (mpeg->frequency & BT_MPEG_SAMPLING_FREQ_44100) {
729de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_value_set_int(value, 44100);
730de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
731de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
732de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (mpeg->frequency & BT_MPEG_SAMPLING_FREQ_32000) {
733de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_value_set_int(value, 32000);
734de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
735de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
736de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (mpeg->frequency & BT_MPEG_SAMPLING_FREQ_24000) {
737de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_value_set_int(value, 24000);
738de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
739de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
740de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (mpeg->frequency & BT_MPEG_SAMPLING_FREQ_22050) {
741de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_value_set_int(value, 22050);
742de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
743de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
744de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (mpeg->frequency & BT_MPEG_SAMPLING_FREQ_16000) {
745de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_value_set_int(value, 16000);
746de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
747de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
748de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	g_value_unset(value);
749de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (list) {
750de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_structure_set_value(structure, "rate", list);
751de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_free(list);
752de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		list = NULL;
753de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
754de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
755de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	/* channels */
756de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	GST_LOG_OBJECT(self, "setting mpeg channels");
757de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	mono = FALSE;
758de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	stereo = FALSE;
759de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (mpeg->channel_mode & BT_A2DP_CHANNEL_MODE_MONO)
760de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		mono = TRUE;
761de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if ((mpeg->channel_mode & BT_A2DP_CHANNEL_MODE_STEREO) ||
762de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			(mpeg->channel_mode &
763de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL) ||
764de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			(mpeg->channel_mode &
765de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			BT_A2DP_CHANNEL_MODE_JOINT_STEREO))
766de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		stereo = TRUE;
767de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
768de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (mono && stereo) {
769de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_value_init(value, GST_TYPE_INT_RANGE);
770de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_value_set_int_range(value, 1, 2);
771de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	} else {
772de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_value_init(value, G_TYPE_INT);
773de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		if (mono)
774de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			g_value_set_int(value, 1);
775de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		else if (stereo)
776de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			g_value_set_int(value, 2);
777de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		else {
778de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			GST_ERROR_OBJECT(self,
779de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"Unexpected number of channels");
780de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			g_value_set_int(value, 0);
781de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		}
782de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
783de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	gst_structure_set_value(structure, "channels", value);
784de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	g_free(value);
785de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
786de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	return structure;
787de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz}
788de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
7893622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentzstatic GstStructure *gst_avdtp_sink_parse_sbc_raw(GstAvdtpSink *self)
7903622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz{
7913622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	a2dp_sbc_t *sbc = (a2dp_sbc_t *) self->data->config;
7923622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	GstStructure *structure;
7933622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	GValue *value;
7943622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	GValue *list;
7953622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	gboolean mono, stereo;
7963622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
7973622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	structure = gst_structure_empty_new("audio/x-sbc");
7983622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	value = g_value_init(g_new0(GValue, 1), G_TYPE_STRING);
7993622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
8003622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	/* mode */
8013622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
8023622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_MONO) {
8033622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_static_string(value, "mono");
8043622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
8053622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
8063622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_STEREO) {
8073622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_static_string(value, "stereo");
8083622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
8093622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
8103622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL) {
8113622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_static_string(value, "dual");
8123622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
8133622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
8143622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_JOINT_STEREO) {
8153622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_static_string(value, "joint");
8163622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
8173622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
8183622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	g_value_unset(value);
8193622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (list) {
8203622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_structure_set_value(structure, "mode", list);
8213622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_free(list);
8223622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		list = NULL;
8233622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
8243622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
8253622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	/* subbands */
8263622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
8273622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	value = g_value_init(value, G_TYPE_INT);
8283622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (sbc->subbands & BT_A2DP_SUBBANDS_4) {
8293622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_int(value, 4);
8303622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
8313622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
8323622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (sbc->subbands & BT_A2DP_SUBBANDS_8) {
8333622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_int(value, 8);
8343622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
8353622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
8363622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	g_value_unset(value);
8373622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (list) {
8383622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_structure_set_value(structure, "subbands", list);
8393622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_free(list);
8403622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		list = NULL;
8413622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
8423622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
8433622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	/* blocks */
8443622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	value = g_value_init(value, G_TYPE_INT);
8453622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
8463622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (sbc->block_length & BT_A2DP_BLOCK_LENGTH_16) {
8473622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_int(value, 16);
8483622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
8493622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
8503622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (sbc->block_length & BT_A2DP_BLOCK_LENGTH_12) {
8513622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_int(value, 12);
8523622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
8533622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
8543622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (sbc->block_length & BT_A2DP_BLOCK_LENGTH_8) {
8553622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_int(value, 8);
8563622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
8573622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
8583622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (sbc->block_length & BT_A2DP_BLOCK_LENGTH_4) {
8593622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_int(value, 4);
8603622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
8613622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
8623622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	g_value_unset(value);
8633622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (list) {
8643622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_structure_set_value(structure, "blocks", list);
8653622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_free(list);
8663622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		list = NULL;
8673622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
8683622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
8693622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	/* allocation */
8703622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	g_value_init(value, G_TYPE_STRING);
8713622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	list = g_value_init(g_new0(GValue,1), GST_TYPE_LIST);
8723622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (sbc->allocation_method & BT_A2DP_ALLOCATION_LOUDNESS) {
8733622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_static_string(value, "loudness");
8743622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
8753622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
8763622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (sbc->allocation_method & BT_A2DP_ALLOCATION_SNR) {
8773622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_static_string(value, "snr");
8783622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
8793622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
8803622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	g_value_unset(value);
8813622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (list) {
8823622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_structure_set_value(structure, "allocation", list);
8833622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_free(list);
8843622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		list = NULL;
8853622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
8863622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
8873622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	/* rate */
8883622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	g_value_init(value, G_TYPE_INT);
8893622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
8903622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (sbc->frequency & BT_SBC_SAMPLING_FREQ_48000) {
8913622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_int(value, 48000);
8923622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
8933622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
8943622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (sbc->frequency & BT_SBC_SAMPLING_FREQ_44100) {
8953622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_int(value, 44100);
8963622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
8973622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
8983622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (sbc->frequency & BT_SBC_SAMPLING_FREQ_32000) {
8993622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_int(value, 32000);
9003622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
9013622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
9023622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (sbc->frequency & BT_SBC_SAMPLING_FREQ_16000) {
9033622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_int(value, 16000);
9043622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
9053622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
9063622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	g_value_unset(value);
9073622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (list) {
9083622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_structure_set_value(structure, "rate", list);
9093622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_free(list);
9103622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		list = NULL;
9113622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
9123622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
9133622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	/* bitpool */
9143622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	value = g_value_init(value, GST_TYPE_INT_RANGE);
9153622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	gst_value_set_int_range(value,
9163622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			MIN(sbc->min_bitpool, TEMPLATE_MAX_BITPOOL),
9173622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			MIN(sbc->max_bitpool, TEMPLATE_MAX_BITPOOL));
9183622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	gst_structure_set_value(structure, "bitpool", value);
9193622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	g_value_unset(value);
9203622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
9213622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	/* channels */
9223622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	mono = FALSE;
9233622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	stereo = FALSE;
9243622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (sbc->channel_mode & BT_A2DP_CHANNEL_MODE_MONO)
9253622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		mono = TRUE;
9263622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if ((sbc->channel_mode & BT_A2DP_CHANNEL_MODE_STEREO) ||
9273622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			(sbc->channel_mode &
9283622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL) ||
9293622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			(sbc->channel_mode &
9303622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			BT_A2DP_CHANNEL_MODE_JOINT_STEREO))
9313622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		stereo = TRUE;
9323622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
9333622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (mono && stereo) {
9343622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_init(value, GST_TYPE_INT_RANGE);
9353622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_set_int_range(value, 1, 2);
9363622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	} else {
9373622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_init(value, G_TYPE_INT);
9383622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		if (mono)
9393622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			g_value_set_int(value, 1);
9403622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		else if (stereo)
9413622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			g_value_set_int(value, 2);
9423622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		else {
9433622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			GST_ERROR_OBJECT(self,
9443622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz				"Unexpected number of channels");
9453622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			g_value_set_int(value, 0);
9463622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		}
9473622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
9483622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
9493622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	gst_structure_set_value(structure, "channels", value);
9503622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	g_free(value);
9513622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
9523622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	return structure;
9533622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz}
9543622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
9553622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentzstatic GstStructure *gst_avdtp_sink_parse_mpeg_raw(GstAvdtpSink *self)
9563622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz{
9573622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	a2dp_mpeg_t *mpeg = (a2dp_mpeg_t *) self->data->config;
9583622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	GstStructure *structure;
9593622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	GValue *value;
9603622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	GValue *list;
9613622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	gboolean valid_layer = FALSE;
9623622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	gboolean mono, stereo;
9633622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
9643622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	GST_LOG_OBJECT(self, "parsing mpeg caps");
9653622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
9663622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	structure = gst_structure_empty_new("audio/mpeg");
9673622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	value = g_new0(GValue, 1);
9683622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	g_value_init(value, G_TYPE_INT);
9693622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
9703622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
9713622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	g_value_set_int(value, 1);
9723622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	gst_value_list_prepend_value(list, value);
9733622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	g_value_set_int(value, 2);
9743622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	gst_value_list_prepend_value(list, value);
9753622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	gst_structure_set_value(structure, "mpegversion", list);
9763622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	g_free(list);
9773622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
9783622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	/* layer */
9793622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	GST_LOG_OBJECT(self, "setting mpeg layer");
9803622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
9813622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (mpeg->layer & BT_MPEG_LAYER_1) {
9823622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_int(value, 1);
9833622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
9843622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		valid_layer = TRUE;
9853622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
9863622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (mpeg->layer & BT_MPEG_LAYER_2) {
9873622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_int(value, 2);
9883622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
9893622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		valid_layer = TRUE;
9903622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
9913622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (mpeg->layer & BT_MPEG_LAYER_3) {
9923622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_int(value, 3);
9933622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
9943622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		valid_layer = TRUE;
9953622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
9963622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (list) {
9973622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_structure_set_value(structure, "layer", list);
9983622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_free(list);
9993622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		list = NULL;
10003622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
10013622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
10023622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (!valid_layer) {
10033622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_structure_free(structure);
10043622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_free(value);
10053622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		return NULL;
10063622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
10073622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
10083622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	/* rate */
10093622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	GST_LOG_OBJECT(self, "setting mpeg rate");
10103622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	list = g_value_init(g_new0(GValue, 1), GST_TYPE_LIST);
10113622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (mpeg->frequency & BT_MPEG_SAMPLING_FREQ_48000) {
10123622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_int(value, 48000);
10133622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
10143622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
10153622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (mpeg->frequency & BT_MPEG_SAMPLING_FREQ_44100) {
10163622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_int(value, 44100);
10173622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
10183622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
10193622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (mpeg->frequency & BT_MPEG_SAMPLING_FREQ_32000) {
10203622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_int(value, 32000);
10213622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
10223622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
10233622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (mpeg->frequency & BT_MPEG_SAMPLING_FREQ_24000) {
10243622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_int(value, 24000);
10253622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
10263622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
10273622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (mpeg->frequency & BT_MPEG_SAMPLING_FREQ_22050) {
10283622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_int(value, 22050);
10293622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
10303622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
10313622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (mpeg->frequency & BT_MPEG_SAMPLING_FREQ_16000) {
10323622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_set_int(value, 16000);
10333622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_list_prepend_value(list, value);
10343622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
10353622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	g_value_unset(value);
10363622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (list) {
10373622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_structure_set_value(structure, "rate", list);
10383622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_free(list);
10393622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		list = NULL;
10403622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
10413622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
10423622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	/* channels */
10433622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	GST_LOG_OBJECT(self, "setting mpeg channels");
10443622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	mono = FALSE;
10453622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	stereo = FALSE;
10463622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (mpeg->channel_mode & BT_A2DP_CHANNEL_MODE_MONO)
10473622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		mono = TRUE;
10483622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if ((mpeg->channel_mode & BT_A2DP_CHANNEL_MODE_STEREO) ||
10493622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			(mpeg->channel_mode &
10503622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL) ||
10513622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			(mpeg->channel_mode &
10523622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			BT_A2DP_CHANNEL_MODE_JOINT_STEREO))
10533622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		stereo = TRUE;
10543622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
10553622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (mono && stereo) {
10563622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_init(value, GST_TYPE_INT_RANGE);
10573622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_value_set_int_range(value, 1, 2);
10583622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	} else {
10593622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_value_init(value, G_TYPE_INT);
10603622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		if (mono)
10613622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			g_value_set_int(value, 1);
10623622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		else if (stereo)
10633622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			g_value_set_int(value, 2);
10643622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		else {
10653622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			GST_ERROR_OBJECT(self,
10663622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz				"Unexpected number of channels");
10673622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			g_value_set_int(value, 0);
10683622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		}
10693622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
10703622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	gst_structure_set_value(structure, "channels", value);
10713622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	g_free(value);
10723622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
10733622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	return structure;
10743622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz}
10753622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
10763622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_update_config(GstAvdtpSink *self)
10773622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz{
10783622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	GstStructure *structure;
10793622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	gchar *tmp;
10803622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
10813622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	switch (self->data->codec) {
10823622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	case A2DP_CODEC_SBC:
10833622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		structure = gst_avdtp_sink_parse_sbc_raw(self);
10843622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		break;
10853622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	case A2DP_CODEC_MPEG12:
10863622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		structure = gst_avdtp_sink_parse_mpeg_raw(self);
10873622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		break;
10883622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	default:
10893622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Unsupported configuration");
10903622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		return FALSE;
10913622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
10923622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
10933622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (structure == NULL)
10943622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		return FALSE;
10953622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
10963622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (self->dev_caps != NULL)
10973622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		gst_caps_unref(self->dev_caps);
10983622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
10993622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	self->dev_caps = gst_caps_new_full(structure, NULL);
11003622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
11013622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	tmp = gst_caps_to_string(self->dev_caps);
11023622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	GST_DEBUG_OBJECT(self, "Transport configuration: %s", tmp);
11033622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	g_free(tmp);
11043622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
11053622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	return TRUE;
11063622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz}
11073622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
1108e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_update_caps(GstAvdtpSink *self)
1109489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz{
1110b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	sbc_capabilities_t *sbc;
1111b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	mpeg_capabilities_t *mpeg;
1112de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	GstStructure *sbc_structure;
1113de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	GstStructure *mpeg_structure;
1114489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	gchar *tmp;
1115489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
1116489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	GST_LOG_OBJECT(self, "updating device caps");
1117489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
11183622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (self->data->config_size != 0 && self->data->config != NULL)
11193622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		return gst_avdtp_sink_update_config(self);
11203622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
1121379d756055f32d46fe7e09e1d89be1f780abb144Luiz Augusto von Dentz	sbc = (void *) gst_avdtp_find_caps(self, BT_A2DP_SBC_SINK);
1122379d756055f32d46fe7e09e1d89be1f780abb144Luiz Augusto von Dentz	mpeg = (void *) gst_avdtp_find_caps(self, BT_A2DP_MPEG12_SINK);
1123b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz
1124e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	sbc_structure = gst_avdtp_sink_parse_sbc_caps(self, sbc);
1125e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	mpeg_structure = gst_avdtp_sink_parse_mpeg_caps(self, mpeg);
1126489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
1127a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->dev_caps != NULL)
1128a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_caps_unref(self->dev_caps);
1129de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	self->dev_caps = gst_caps_new_full(sbc_structure, NULL);
1130de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (mpeg_structure != NULL)
1131de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_caps_append_structure(self->dev_caps, mpeg_structure);
1132a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1133a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	tmp = gst_caps_to_string(self->dev_caps);
1134a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_DEBUG_OBJECT(self, "Device capabilities: %s", tmp);
1135a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_free(tmp);
1136a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1137a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
1138a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1139a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1140e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_get_capabilities(GstAvdtpSink *self)
1141a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1142b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	gchar *buf[BT_SUGGESTED_BUFFER_SIZE];
1143b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	struct bt_get_capabilities_req *req = (void *) buf;
1144b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	struct bt_get_capabilities_rsp *rsp = (void *) buf;
11454aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	int err;
1146a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1147b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	memset(req, 0, BT_SUGGESTED_BUFFER_SIZE);
1148b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz
1149b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	req->h.type = BT_REQUEST;
1150b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	req->h.name = BT_GET_CAPABILITIES;
1151b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	req->h.length = sizeof(*req);
1152a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1153a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->device == NULL)
1154a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
11559bdf6ba0c50a3d5500e616b0f9d63a190692cc2cLuiz Augusto von Dentz	strncpy(req->destination, self->device, 18);
11566c4268df1dff13f3b1a7b778eb2e993648bff519Luiz Augusto von Dentz	if (self->autoconnect)
11576c4268df1dff13f3b1a7b778eb2e993648bff519Luiz Augusto von Dentz		req->flags |= BT_FLAG_AUTOCONNECT;
1158a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
11594aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	err = gst_avdtp_sink_audioservice_send(self, &req->h);
11604aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	if (err < 0) {
1161a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error while asking device caps");
1162de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		return FALSE;
1163a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
1164a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
11651c7291138ae3d25d7f34803e4f354a90d012f6a1Johan Hedberg	rsp->h.length = 0;
11664aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	err = gst_avdtp_sink_audioservice_expect(self,
11674aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz					&rsp->h, BT_GET_CAPABILITIES);
11684aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	if (err < 0) {
1169a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error while getting device caps");
1170a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
1171a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
1172a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1173b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	self->data->caps = g_malloc0(rsp->h.length);
1174b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	memcpy(self->data->caps, rsp, rsp->h.length);
1175e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	if (!gst_avdtp_sink_update_caps(self)) {
1176a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_WARNING_OBJECT(self, "failed to update capabilities");
1177a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
1178a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
1179a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1180a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
1181a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1182a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1183e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gint gst_avdtp_sink_get_channel_mode(const gchar *mode)
1184de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz{
1185de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (strcmp(mode, "stereo") == 0)
1186de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		return BT_A2DP_CHANNEL_MODE_STEREO;
1187f4250658b1ff244f617d5489632a6c878514ad19Luiz Augusto von Dentz	else if (strcmp(mode, "joint-stereo") == 0)
1188de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		return BT_A2DP_CHANNEL_MODE_JOINT_STEREO;
1189b65d02ae48d96d1b2914ba203e404b695e596d84Luiz Augusto von Dentz	else if (strcmp(mode, "dual-channel") == 0)
1190de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		return BT_A2DP_CHANNEL_MODE_DUAL_CHANNEL;
1191de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else if (strcmp(mode, "mono") == 0)
1192de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		return BT_A2DP_CHANNEL_MODE_MONO;
1193de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else
1194de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		return -1;
1195de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz}
1196de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1197e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic void gst_avdtp_sink_tag(const GstTagList *taglist,
1198b0f85afdba9d51cecc21ac04606a2f759f95df86Johan Hedberg			const gchar *tag, gpointer user_data)
1199de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz{
1200de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	gboolean crc;
1201de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	gchar *channel_mode = NULL;
1202e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GstAvdtpSink *self = GST_AVDTP_SINK(user_data);
1203de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1204de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (strcmp(tag, "has-crc") == 0) {
1205de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1206de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		if (!gst_tag_list_get_boolean(taglist, tag, &crc)) {
1207de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			GST_WARNING_OBJECT(self, "failed to get crc tag");
12083ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz			return;
1209de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		}
1210de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1211e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz		gst_avdtp_sink_set_crc(self, crc);
1212de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1213de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	} else if (strcmp(tag, "channel-mode") == 0) {
1214de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1215de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		if (!gst_tag_list_get_string(taglist, tag, &channel_mode)) {
1216de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			GST_WARNING_OBJECT(self,
1217de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"failed to get channel-mode tag");
12183ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz			return;
1219de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		}
1220de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1221e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz		self->channel_mode = gst_avdtp_sink_get_channel_mode(
1222de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz					channel_mode);
1223de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		if (self->channel_mode == -1)
1224de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			GST_WARNING_OBJECT(self, "Received invalid channel "
1225de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz					"mode: %s", channel_mode);
1226de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		g_free(channel_mode);
1227de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1228de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	} else
1229de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		GST_DEBUG_OBJECT(self, "received unused tag: %s", tag);
1230de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz}
1231de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1232e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_event(GstBaseSink *basesink,
1233de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			GstEvent *event)
1234de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz{
1235e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GstAvdtpSink *self = GST_AVDTP_SINK(basesink);
1236de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	GstTagList *taglist = NULL;
1237de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1238de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (GST_EVENT_TYPE(event) == GST_EVENT_TAG) {
1239de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		/* we check the tags, mp3 has tags that are importants and
1240de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		 * are outside caps */
1241de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		gst_event_parse_tag(event, &taglist);
1242e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz		gst_tag_list_foreach(taglist, gst_avdtp_sink_tag, self);
1243de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
1244de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1245de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	return TRUE;
1246de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz}
1247de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
12483622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_transport_parse_property(GstAvdtpSink *self,
12493622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz							DBusMessageIter *i)
12503622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz{
12513622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	const char *key;
12523622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	DBusMessageIter variant_i;
12533622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
12543622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_STRING) {
12553622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Property name not a string.");
12563622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		return FALSE;
12573622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
12583622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
12593622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	dbus_message_iter_get_basic(i, &key);
12603622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
12613622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (!dbus_message_iter_next(i))  {
12623622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Property value missing");
12633622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		return FALSE;
12643622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
12653622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
12663622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(i) != DBUS_TYPE_VARIANT) {
12673622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Property value not a variant.");
12683622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		return FALSE;
12693622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
12703622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
12713622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	dbus_message_iter_recurse(i, &variant_i);
12723622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
12733622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	switch (dbus_message_iter_get_arg_type(&variant_i)) {
12743622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	case DBUS_TYPE_BYTE: {
12753622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		uint8_t value;
12763622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		dbus_message_iter_get_basic(&variant_i, &value);
12773622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
12783622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		if (g_str_equal(key, "Codec") == TRUE)
12793622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			self->data->codec = value;
12803622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
12813622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		break;
12823622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
1283dec7a257727935e9e97eba50c63d3d6bf20ca2a4Luiz Augusto von Dentz	case DBUS_TYPE_STRING: {
12843622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		const char *value;
12853622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		dbus_message_iter_get_basic(&variant_i, &value);
12863622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
12873622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		if (g_str_equal(key, "UUID") == TRUE) {
12883622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			g_free(self->data->uuid);
12893622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			self->data->uuid = g_strdup(value);
12903622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		}
12913622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
12923622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		break;
12933622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
12943622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	case DBUS_TYPE_ARRAY: {
12953622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		DBusMessageIter array_i;
12963622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		char *value;
12973622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		int size;
12983622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
12993622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		dbus_message_iter_recurse(&variant_i, &array_i);
13003622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		dbus_message_iter_get_fixed_array(&array_i, &value, &size);
13013622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
13023622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		if (g_str_equal(key, "Configuration")) {
13033622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			g_free(self->data->config);
13043622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			self->data->config = g_new0(guint8, size);
13053622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			self->data->config_size = size;
13063622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			memcpy(self->data->config, value, size);
13073622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		}
13083622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
13093622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		break;
13103622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
13113622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
13123622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
13133622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	return TRUE;
13143622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz}
13153622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
13163622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_transport_acquire(GstAvdtpSink *self)
13173622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz{
13183622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	DBusMessage *msg, *reply;
13193622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	DBusError err;
13203622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	const char *access_type = "w";
13213622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	int fd;
1322dec7a257727935e9e97eba50c63d3d6bf20ca2a4Luiz Augusto von Dentz	uint16_t imtu, omtu;
13233622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
13243622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	dbus_error_init(&err);
13253622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
13263622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (self->data->conn == NULL)
13273622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		self->data->conn = dbus_bus_get(DBUS_BUS_SYSTEM, &err);
13283622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
13293622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	msg = dbus_message_new_method_call("org.bluez", self->transport,
13303622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz						"org.bluez.MediaTransport",
13313622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz						"Acquire");
13323622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
13333622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	dbus_message_append_args(msg, DBUS_TYPE_STRING, &access_type,
13343622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz					DBUS_TYPE_INVALID);
13353622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
13363622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	reply = dbus_connection_send_with_reply_and_block(self->data->conn,
13373622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz							msg, -1, &err);
13383622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
13393622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (dbus_error_is_set(&err))
13403622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		goto fail;
13413622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
13423622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (dbus_message_get_args(reply, &err, DBUS_TYPE_UNIX_FD, &fd,
1343dec7a257727935e9e97eba50c63d3d6bf20ca2a4Luiz Augusto von Dentz						DBUS_TYPE_UINT16, &imtu,
1344dec7a257727935e9e97eba50c63d3d6bf20ca2a4Luiz Augusto von Dentz						DBUS_TYPE_UINT16, &omtu,
1345dec7a257727935e9e97eba50c63d3d6bf20ca2a4Luiz Augusto von Dentz						DBUS_TYPE_INVALID) == FALSE)
13463622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		goto fail;
13473622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
13483622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	dbus_message_unref(reply);
13493622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
13503622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	self->stream = g_io_channel_unix_new(fd);
13514aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	g_io_channel_set_encoding(self->stream, NULL, NULL);
13523622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	g_io_channel_set_close_on_unref(self->stream, TRUE);
1353dec7a257727935e9e97eba50c63d3d6bf20ca2a4Luiz Augusto von Dentz	self->data->link_mtu = omtu;
1354dec7a257727935e9e97eba50c63d3d6bf20ca2a4Luiz Augusto von Dentz	GST_DEBUG_OBJECT(self, "stream_fd=%d mtu=%d", fd, omtu);
13553622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
13563622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	return TRUE;
13573622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
13583622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentzfail:
13593622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	GST_ERROR_OBJECT(self, "Failed to acquire transport stream: %s",
13603622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz				err.message);
13613622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
13623622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	dbus_error_free(&err);
13633622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
13643622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (reply)
13653622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		dbus_message_unref(msg);
13663622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
13673622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	return FALSE;
13683622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz}
13693622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
13703622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_transport_get_properties(GstAvdtpSink *self)
13713622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz{
13723622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	DBusMessage *msg, *reply;
13733622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	DBusMessageIter arg_i, ele_i;
13743622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	DBusError err;
13753622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
13763622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	dbus_error_init(&err);
13773622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
13783622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	/* Transport need to be acquire first to make sure the MTUs are
13793622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	   available */
13803622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (gst_avdtp_sink_transport_acquire(self) == FALSE)
13813622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		return FALSE;
13823622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
13833622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	msg = dbus_message_new_method_call("org.bluez", self->transport,
13843622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz						"org.bluez.MediaTransport",
13853622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz						"GetProperties");
13863622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	reply = dbus_connection_send_with_reply_and_block(self->data->conn,
13873622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz							msg, -1, &err);
13883622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
13893622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (dbus_error_is_set(&err) || reply == NULL) {
13903622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Failed to get transport properties: %s",
13913622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz					err.message);
13923622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		goto fail;
13933622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
13943622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
13953622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (!dbus_message_iter_init(reply, &arg_i)) {
13963622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "GetProperties reply has no arguments.");
13973622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		goto fail;
13983622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
13993622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
14003622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (dbus_message_iter_get_arg_type(&arg_i) != DBUS_TYPE_ARRAY) {
14013622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "GetProperties argument is not an array.");
14023622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		goto fail;
14033622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
14043622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
14053622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	dbus_message_iter_recurse(&arg_i, &ele_i);
14063622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	while (dbus_message_iter_get_arg_type(&ele_i) != DBUS_TYPE_INVALID) {
14073622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
14083622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		if (dbus_message_iter_get_arg_type(&ele_i) ==
14093622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz				DBUS_TYPE_DICT_ENTRY) {
14103622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			DBusMessageIter dict_i;
14113622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
14123622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			dbus_message_iter_recurse(&ele_i, &dict_i);
14133622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
14143622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			gst_avdtp_sink_transport_parse_property(self, &dict_i);
14153622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		}
14163622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
14173622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		if (!dbus_message_iter_next(&ele_i))
14183622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz			break;
14193622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	}
14203622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
14213622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	return gst_avdtp_sink_update_caps(self);
14223622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
14233622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentzfail:
14243622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	dbus_message_unref(msg);
14253622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	dbus_message_unref(reply);
14263622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	return FALSE;
14273622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
14283622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz}
14293622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
1430e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_start(GstBaseSink *basesink)
1431a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1432e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GstAvdtpSink *self = GST_AVDTP_SINK(basesink);
1433a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gint sk;
1434a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gint err;
1435a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1436a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_INFO_OBJECT(self, "start");
1437a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
14383622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	self->data = g_new0(struct bluetooth_data, 1);
14393622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
14403622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	self->stream = NULL;
14413622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	self->stream_caps = NULL;
14423622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	self->mp3_using_crc = -1;
14433622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	self->channel_mode = -1;
14443622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
14453622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (self->transport != NULL)
14463622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		return gst_avdtp_sink_transport_get_properties(self);
14473622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
1448a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->watch_id = 0;
1449a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1450a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	sk = bt_audio_service_open();
1451a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sk <= 0) {
1452a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		err = errno;
1453a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Cannot open connection to bt "
1454a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			"audio service: %s %d", strerror(err), err);
1455a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		goto failed;
1456a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
1457a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1458a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->server = g_io_channel_unix_new(sk);
14594aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	g_io_channel_set_encoding(self->server, NULL, NULL);
1460a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->watch_id = g_io_add_watch(self->server, G_IO_HUP | G_IO_ERR |
1461a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					G_IO_NVAL, server_callback, self);
1462a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1463e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	if (!gst_avdtp_sink_get_capabilities(self)) {
1464de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		GST_ERROR_OBJECT(self, "failed to get capabilities "
1465de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"from device");
1466a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		goto failed;
1467de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
1468a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1469a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
1470a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1471a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentzfailed:
1472a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	bt_audio_service_close(sk);
1473a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return FALSE;
1474a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1475a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1476e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_stream_start(GstAvdtpSink *self)
1477a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1478b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	gchar buf[BT_SUGGESTED_BUFFER_SIZE];
1479b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	struct bt_start_stream_req *req = (void *) buf;
1480b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	struct bt_start_stream_rsp *rsp = (void *) buf;
1481cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg	struct bt_new_stream_ind *ind = (void *) buf;
14824aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	int err;
1483a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
14843622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (self->transport != NULL)
14853622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		return gst_avdtp_sink_conf_recv_stream_fd(self);
14863622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
1487cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg	memset(req, 0, sizeof(buf));
1488b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	req->h.type = BT_REQUEST;
1489b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	req->h.name = BT_START_STREAM;
1490b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	req->h.length = sizeof(*req);
1491a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
14924aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	err = gst_avdtp_sink_audioservice_send(self, &req->h);
14934aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	if (err < 0) {
1494a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error ocurred while sending "
1495a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					"start packet");
1496a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
1497a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
1498a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
14991c7291138ae3d25d7f34803e4f354a90d012f6a1Johan Hedberg	rsp->h.length = sizeof(*rsp);
15004aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	err = gst_avdtp_sink_audioservice_expect(self, &rsp->h,
15014aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz							BT_START_STREAM);
15024aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	if (err < 0) {
1503a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error while stream "
1504a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			"start confirmation");
1505a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
1506a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
1507a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
15081c7291138ae3d25d7f34803e4f354a90d012f6a1Johan Hedberg	ind->h.length = sizeof(*ind);
15094aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	err = gst_avdtp_sink_audioservice_expect(self, &ind->h,
15104aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz							BT_NEW_STREAM);
15114aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	if (err < 0) {
1512a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error while receiving "
1513a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			"stream filedescriptor");
1514a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
1515a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
1516a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1517e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	if (!gst_avdtp_sink_conf_recv_stream_fd(self))
1518a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
1519a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1520a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
1521a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1522a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1523e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_init_mp3_pkt_conf(
1524e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz		GstAvdtpSink *self, GstCaps *caps,
1525de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		mpeg_capabilities_t *pkt)
1526de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz{
1527de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	const GValue *value = NULL;
1528de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	gint rate, layer;
1529b0f85afdba9d51cecc21ac04606a2f759f95df86Johan Hedberg	const gchar *name;
1530de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	GstStructure *structure = gst_caps_get_structure(caps, 0);
1531de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
15323ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz	name = gst_structure_get_name(structure);
15333ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz
15343ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz	if (!(IS_MPEG_AUDIO(name))) {
15353ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Unexpected format %s, "
15363ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz				"was expecting mp3", name);
15373ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz		return FALSE;
15383ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz	}
15393ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz
1540de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	/* layer */
1541de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	value = gst_structure_get_value(structure, "layer");
1542de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	layer = g_value_get_int(value);
1543de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (layer == 1)
1544de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		pkt->layer = BT_MPEG_LAYER_1;
1545de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else if (layer == 2)
1546de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		pkt->layer = BT_MPEG_LAYER_2;
1547de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else if (layer == 3)
1548de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		pkt->layer = BT_MPEG_LAYER_3;
1549de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else {
1550de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Unexpected layer: %d", layer);
1551de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		return FALSE;
1552de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
1553de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1554de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	/* crc */
1555de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (self->mp3_using_crc != -1)
1556de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		pkt->crc = self->mp3_using_crc;
1557de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else {
1558de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		GST_ERROR_OBJECT(self, "No info about crc was received, "
1559de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				" can't proceed");
1560de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		return FALSE;
1561de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
1562de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1563de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	/* channel mode */
1564de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (self->channel_mode != -1)
1565de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		pkt->channel_mode = self->channel_mode;
1566de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else {
1567de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		GST_ERROR_OBJECT(self, "No info about channel mode "
1568de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"received, can't proceed");
1569de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		return FALSE;
1570de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
1571de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1572de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	/* mpf - we will only use the mandatory one */
1573de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	pkt->mpf = 0;
1574de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1575de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	value = gst_structure_get_value(structure, "rate");
1576de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	rate = g_value_get_int(value);
1577de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (rate == 44100)
1578de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		pkt->frequency = BT_MPEG_SAMPLING_FREQ_44100;
1579de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else if (rate == 48000)
1580de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		pkt->frequency = BT_MPEG_SAMPLING_FREQ_48000;
1581de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else if (rate == 32000)
1582de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		pkt->frequency = BT_MPEG_SAMPLING_FREQ_32000;
1583de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else if (rate == 24000)
1584de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		pkt->frequency = BT_MPEG_SAMPLING_FREQ_24000;
1585de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else if (rate == 22050)
1586de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		pkt->frequency = BT_MPEG_SAMPLING_FREQ_22050;
1587de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else if (rate == 16000)
1588de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		pkt->frequency = BT_MPEG_SAMPLING_FREQ_16000;
1589de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	else {
1590de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Invalid rate while setting caps");
1591de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		return FALSE;
1592de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
1593de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1594de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	/* vbr - we always say its vbr, we don't have how to know it */
1595de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	pkt->bitrate = 0x8000;
1596de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1597de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	return TRUE;
1598de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz}
1599de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1600e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_configure(GstAvdtpSink *self,
1601a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			GstCaps *caps)
1602a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1603b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	gchar buf[BT_SUGGESTED_BUFFER_SIZE];
1604bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	struct bt_open_req *open_req = (void *) buf;
1605bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	struct bt_open_rsp *open_rsp = (void *) buf;
1606b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	struct bt_set_configuration_req *req = (void *) buf;
1607b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	struct bt_set_configuration_rsp *rsp = (void *) buf;
1608a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gboolean ret;
1609a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gchar *temp;
1610de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	GstStructure *structure;
1611bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	codec_capabilities_t *codec = NULL;
16124aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	int err;
1613a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1614a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	temp = gst_caps_to_string(caps);
1615a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_DEBUG_OBJECT(self, "configuring device with caps: %s", temp);
1616a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_free(temp);
1617a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
16183622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	/* Transport already configured */
16193622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (self->transport != NULL)
16203622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		return TRUE;
16213622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
1622bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	structure = gst_caps_get_structure(caps, 0);
1623bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz
1624bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	if (gst_structure_has_name(structure, "audio/x-sbc"))
1625379d756055f32d46fe7e09e1d89be1f780abb144Luiz Augusto von Dentz		codec = (void *) gst_avdtp_find_caps(self, BT_A2DP_SBC_SINK);
1626bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	else if (gst_structure_has_name(structure, "audio/mpeg"))
1627379d756055f32d46fe7e09e1d89be1f780abb144Luiz Augusto von Dentz		codec = (void *) gst_avdtp_find_caps(self, BT_A2DP_MPEG12_SINK);
1628bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz
1629bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	if (codec == NULL) {
1630bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Couldn't parse caps "
1631bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz				"to packet configuration");
1632bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz		return FALSE;
1633bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	}
1634bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz
1635bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	memset(req, 0, BT_SUGGESTED_BUFFER_SIZE);
1636bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	open_req->h.type = BT_REQUEST;
1637bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	open_req->h.name = BT_OPEN;
1638bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	open_req->h.length = sizeof(*open_req);
1639bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz
1640bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	strncpy(open_req->destination, self->device, 18);
1641bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	open_req->seid = codec->seid;
1642bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	open_req->lock = BT_WRITE_LOCK;
1643bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz
16444aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	err = gst_avdtp_sink_audioservice_send(self, &open_req->h);
16454aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	if (err < 0) {
1646bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error ocurred while sending "
1647bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz					"open packet");
1648bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz		return FALSE;
1649bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	}
1650bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz
1651bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	open_rsp->h.length = sizeof(*open_rsp);
16524aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	err = gst_avdtp_sink_audioservice_expect(self, &open_rsp->h,
16534aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz								BT_OPEN);
16544aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	if (err < 0) {
1655bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error while receiving device "
1656bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz					"confirmation");
1657bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz		return FALSE;
1658bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	}
1659bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz
1660cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg	memset(req, 0, sizeof(buf));
1661b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	req->h.type = BT_REQUEST;
1662b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	req->h.name = BT_SET_CONFIGURATION;
1663b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	req->h.length = sizeof(*req);
166414179e9a3756e529e1a5750f326710ea3d1e4326Luiz Augusto von Dentz	memcpy(&req->codec, codec, sizeof(req->codec));
1665b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz
1666379d756055f32d46fe7e09e1d89be1f780abb144Luiz Augusto von Dentz	if (codec->type == BT_A2DP_SBC_SINK)
16673ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz		ret = gst_avdtp_sink_init_sbc_pkt_conf(self, caps,
1668b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz				(void *) &req->codec);
1669bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	else
1670e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz		ret = gst_avdtp_sink_init_mp3_pkt_conf(self, caps,
1671b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz				(void *) &req->codec);
1672de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
1673a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (!ret) {
1674a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Couldn't parse caps "
1675a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"to packet configuration");
1676a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
1677a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
1678a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
16791c7291138ae3d25d7f34803e4f354a90d012f6a1Johan Hedberg	req->h.length += req->codec.length - sizeof(req->codec);
16804aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	err = gst_avdtp_sink_audioservice_send(self, &req->h);
16814aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	if (err < 0) {
1682a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error ocurred while sending "
1683a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					"configurarion packet");
1684a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
1685a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
1686a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
16871c7291138ae3d25d7f34803e4f354a90d012f6a1Johan Hedberg	rsp->h.length = sizeof(*rsp);
16884aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	err = gst_avdtp_sink_audioservice_expect(self, &rsp->h,
16894aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz							BT_SET_CONFIGURATION);
16904aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	if (err < 0) {
1691a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error while receiving device "
1692a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					"confirmation");
1693a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return FALSE;
1694a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
1695a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1696a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->data->link_mtu = rsp->link_mtu;
1697a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1698a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
1699a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1700a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1701e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic GstFlowReturn gst_avdtp_sink_preroll(GstBaseSink *basesink,
1702a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					GstBuffer *buffer)
1703a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1704e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GstAvdtpSink *sink = GST_AVDTP_SINK(basesink);
1705a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gboolean ret;
1706a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1707e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GST_AVDTP_SINK_MUTEX_LOCK(sink);
1708a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1709e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	ret = gst_avdtp_sink_stream_start(sink);
1710a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1711e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GST_AVDTP_SINK_MUTEX_UNLOCK(sink);
1712a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1713a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (!ret)
1714a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return GST_FLOW_ERROR;
1715a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1716a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return GST_FLOW_OK;
1717a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1718a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1719e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic GstFlowReturn gst_avdtp_sink_render(GstBaseSink *basesink,
1720a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					GstBuffer *buffer)
1721a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1722e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GstAvdtpSink *self = GST_AVDTP_SINK(basesink);
17234aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	ssize_t ret;
17244aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	int fd;
1725a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
17264aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	fd = g_io_channel_unix_get_fd(self->stream);
1727a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
17284aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	ret = write(fd, GST_BUFFER_DATA(buffer), GST_BUFFER_SIZE(buffer));
17294aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	if (ret < 0) {
17304aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error while writting to socket: %s",
17314aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz							strerror(errno));
1732a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return GST_FLOW_ERROR;
1733a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
1734a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1735a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return GST_FLOW_OK;
1736a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1737a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1738e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic gboolean gst_avdtp_sink_unlock(GstBaseSink *basesink)
1739a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1740e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GstAvdtpSink *self = GST_AVDTP_SINK(basesink);
1741a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1742a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->stream != NULL)
1743cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg		g_io_channel_flush(self->stream, NULL);
1744a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1745a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return TRUE;
1746a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1747a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1748e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic GstFlowReturn gst_avdtp_sink_buffer_alloc(GstBaseSink *basesink,
1749b0f85afdba9d51cecc21ac04606a2f759f95df86Johan Hedberg				guint64 offset, guint size, GstCaps *caps,
1750a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				GstBuffer **buf)
1751a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1752e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GstAvdtpSink *self = GST_AVDTP_SINK(basesink);
1753a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1754a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	*buf = gst_buffer_new_and_alloc(size);
1755a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (!(*buf)) {
1756a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "buffer allocation failed");
1757a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return GST_FLOW_ERROR;
1758a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
1759a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1760a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gst_buffer_set_caps(*buf, caps);
1761a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1762a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_BUFFER_OFFSET(*buf) = offset;
1763a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1764a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return GST_FLOW_OK;
1765a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1766a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1767e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic void gst_avdtp_sink_class_init(GstAvdtpSinkClass *klass)
1768a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1769a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GObjectClass *object_class = G_OBJECT_CLASS(klass);
1770a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GstBaseSinkClass *basesink_class = GST_BASE_SINK_CLASS(klass);
1771a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1772a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	parent_class = g_type_class_peek_parent(klass);
1773a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1774a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	object_class->finalize = GST_DEBUG_FUNCPTR(
1775e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz					gst_avdtp_sink_finalize);
1776a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	object_class->set_property = GST_DEBUG_FUNCPTR(
1777e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz					gst_avdtp_sink_set_property);
1778a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	object_class->get_property = GST_DEBUG_FUNCPTR(
1779e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz					gst_avdtp_sink_get_property);
1780a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1781e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	basesink_class->start = GST_DEBUG_FUNCPTR(gst_avdtp_sink_start);
1782e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	basesink_class->stop = GST_DEBUG_FUNCPTR(gst_avdtp_sink_stop);
1783a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	basesink_class->render = GST_DEBUG_FUNCPTR(
1784e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz					gst_avdtp_sink_render);
1785a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	basesink_class->preroll = GST_DEBUG_FUNCPTR(
1786e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz					gst_avdtp_sink_preroll);
1787a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	basesink_class->unlock = GST_DEBUG_FUNCPTR(
1788e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz					gst_avdtp_sink_unlock);
1789de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	basesink_class->event = GST_DEBUG_FUNCPTR(
1790e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz					gst_avdtp_sink_event);
1791a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1792a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	basesink_class->buffer_alloc =
1793e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz		GST_DEBUG_FUNCPTR(gst_avdtp_sink_buffer_alloc);
1794a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1795a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	g_object_class_install_property(object_class, PROP_DEVICE,
1796a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					g_param_spec_string("device", "Device",
1797a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					"Bluetooth remote device address",
1798a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					NULL, G_PARAM_READWRITE));
1799a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
18006c4268df1dff13f3b1a7b778eb2e993648bff519Luiz Augusto von Dentz	g_object_class_install_property(object_class, PROP_AUTOCONNECT,
18016c4268df1dff13f3b1a7b778eb2e993648bff519Luiz Augusto von Dentz					g_param_spec_boolean("auto-connect",
18026c4268df1dff13f3b1a7b778eb2e993648bff519Luiz Augusto von Dentz					"Auto-connect",
18036c4268df1dff13f3b1a7b778eb2e993648bff519Luiz Augusto von Dentz					"Automatically attempt to connect "
18046c4268df1dff13f3b1a7b778eb2e993648bff519Luiz Augusto von Dentz					"to device", DEFAULT_AUTOCONNECT,
18056c4268df1dff13f3b1a7b778eb2e993648bff519Luiz Augusto von Dentz					G_PARAM_READWRITE));
18066c4268df1dff13f3b1a7b778eb2e993648bff519Luiz Augusto von Dentz
18073622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	g_object_class_install_property(object_class, PROP_TRANSPORT,
18083622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz					g_param_spec_string("transport",
18093622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz					"Transport",
18103622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz					"Use configured transport",
18113622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz					NULL, G_PARAM_READWRITE));
18123622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
18133ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz	GST_DEBUG_CATEGORY_INIT(avdtp_sink_debug, "avdtpsink", 0,
18143ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz				"A2DP headset sink element");
1815a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1816a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1817e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzstatic void gst_avdtp_sink_init(GstAvdtpSink *self,
1818e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz			GstAvdtpSinkClass *klass)
1819a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1820a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->device = NULL;
18213622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	self->transport = NULL;
1822a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->data = NULL;
1823a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1824a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->stream = NULL;
1825a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1826a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->dev_caps = NULL;
1827a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
18286c4268df1dff13f3b1a7b778eb2e993648bff519Luiz Augusto von Dentz	self->autoconnect = DEFAULT_AUTOCONNECT;
18296c4268df1dff13f3b1a7b778eb2e993648bff519Luiz Augusto von Dentz
1830a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->sink_lock = g_mutex_new();
18313ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz
18323ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz	/* FIXME this is for not synchronizing with clock, should be tested
18333ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz	 * with devices to see the behaviour
18343ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz	gst_base_sink_set_sync(GST_BASE_SINK(self), FALSE);
18353ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz	*/
1836a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1837a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
18384aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentzstatic int gst_avdtp_sink_audioservice_send(GstAvdtpSink *self,
1839a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz					const bt_audio_msg_header_t *msg)
1840a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
18414aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	ssize_t written;
1842b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	const char *type, *name;
18431c7291138ae3d25d7f34803e4f354a90d012f6a1Johan Hedberg	uint16_t length;
18444aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	int fd;
1845a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
18461c7291138ae3d25d7f34803e4f354a90d012f6a1Johan Hedberg	length = msg->length ? msg->length : BT_SUGGESTED_BUFFER_SIZE;
18471c7291138ae3d25d7f34803e4f354a90d012f6a1Johan Hedberg
18484aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	fd = g_io_channel_unix_get_fd(self->server);
18494aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz
18504aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	written = write(fd, msg, length);
18514aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	if (written < 0) {
1852a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error sending data to audio service:"
18534aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz			" %s", strerror(errno));
18544aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz		return -errno;
18554aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	}
1856a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1857b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	type = bt_audio_strtype(msg->type);
1858b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	name = bt_audio_strname(msg->name);
1859b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz
1860b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	GST_DEBUG_OBJECT(self, "sent: %s -> %s", type, name);
1861b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz
18624aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	return 0;
1863a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1864a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
18654aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentzstatic int gst_avdtp_sink_audioservice_recv(GstAvdtpSink *self,
18664aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz						bt_audio_msg_header_t *inmsg)
1867a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
18684aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	ssize_t bytes_read;
1869b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	const char *type, *name;
18701c7291138ae3d25d7f34803e4f354a90d012f6a1Johan Hedberg	uint16_t length;
1871d6ee6f16e6e7a6b63f34265d86a60ce50d63a2c9Szymon Janc	int fd, err = 0;
18721c7291138ae3d25d7f34803e4f354a90d012f6a1Johan Hedberg
18731c7291138ae3d25d7f34803e4f354a90d012f6a1Johan Hedberg	length = inmsg->length ? inmsg->length : BT_SUGGESTED_BUFFER_SIZE;
1874a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
18754aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	fd = g_io_channel_unix_get_fd(self->server);
18764aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz
18774aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	bytes_read = read(fd, inmsg, length);
18784aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	if (bytes_read < 0) {
1879a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Error receiving data from "
18804aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz				"audio service: %s", strerror(errno));
18814aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz		return -errno;
1882a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
1883a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1884b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	type = bt_audio_strtype(inmsg->type);
1885a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (!type) {
18864aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz		err = -EINVAL;
1887a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Bogus message type %d "
1888a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz				"received from audio service",
1889b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz				inmsg->type);
1890a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	}
1891a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1892b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	name = bt_audio_strname(inmsg->name);
1893b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	if (!name) {
18944aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz		err = -EINVAL;
1895b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "Bogus message name %d "
1896b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz				"received from audio service",
1897b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz				inmsg->name);
1898b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	}
1899b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz
1900b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	if (inmsg->type == BT_ERROR) {
19014aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz		bt_audio_error_t *msg = (void *) inmsg;
19024aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz		err = -EINVAL;
1903b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz		GST_ERROR_OBJECT(self, "%s failed : "
1904b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz					"%s(%d)",
1905b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz					name,
19064aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz					strerror(msg->posix_errno),
19074aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz					msg->posix_errno);
1908b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	}
1909b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz
1910b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	GST_DEBUG_OBJECT(self, "received: %s <- %s", type, name);
1911b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz
19124aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	return err;
1913a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1914a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
19154aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentzstatic int gst_avdtp_sink_audioservice_expect(GstAvdtpSink *self,
19164aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz						bt_audio_msg_header_t *outmsg,
19174aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz						guint8 expected_name)
1918a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
19194aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	int err;
1920a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
19214aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	err = gst_avdtp_sink_audioservice_recv(self, outmsg);
19224aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	if (err < 0)
19234aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz		return err;
1924a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1925b2b736c38f02704d225680fd0541936e36a73e82Luiz Augusto von Dentz	if (outmsg->name != expected_name)
19264aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz		return -EINVAL;
1927a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
19284aecf0a27cfdd08d84a1c61271f5c59da3ae370aLuiz Augusto von Dentz	return 0;
1929a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1930a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1931cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberggboolean gst_avdtp_sink_plugin_init(GstPlugin *plugin)
1932a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1933cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg	return gst_element_register(plugin, "avdtpsink", GST_RANK_NONE,
1934cc49c31ccedcd31dd09be2a9cc32e653573c7d4bJohan Hedberg							GST_TYPE_AVDTP_SINK);
1935a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1936a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1937a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1938a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz/* public functions */
1939e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von DentzGstCaps *gst_avdtp_sink_get_device_caps(GstAvdtpSink *sink)
1940a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1941a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (sink->dev_caps == NULL)
1942a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		return NULL;
1943a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1944a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return gst_caps_copy(sink->dev_caps);
1945a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1946a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1947e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzgboolean gst_avdtp_sink_set_device_caps(GstAvdtpSink *self,
1948a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz			GstCaps *caps)
1949a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1950a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	gboolean ret;
1951a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1952a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_DEBUG_OBJECT(self, "setting device caps");
1953e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GST_AVDTP_SINK_MUTEX_LOCK(self);
1954e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	ret = gst_avdtp_sink_configure(self, caps);
1955a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1956a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->stream_caps)
1957a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		gst_caps_unref(self->stream_caps);
1958a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->stream_caps = gst_caps_ref(caps);
1959a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1960e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	GST_AVDTP_SINK_MUTEX_UNLOCK(self);
1961a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1962a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return ret;
1963a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1964a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1965e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzguint gst_avdtp_sink_get_link_mtu(GstAvdtpSink *sink)
1966a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1967a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return sink->data->link_mtu;
1968a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1969a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1970b0f85afdba9d51cecc21ac04606a2f759f95df86Johan Hedbergvoid gst_avdtp_sink_set_device(GstAvdtpSink *self, const gchar *dev)
1971a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1972a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	if (self->device != NULL)
1973a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz		g_free(self->device);
1974a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
1975a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	GST_LOG_OBJECT(self, "Setting device: %s", dev);
1976a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	self->device = g_strdup(dev);
1977a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1978a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
19793622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentzvoid gst_avdtp_sink_set_transport(GstAvdtpSink *self, const gchar *trans)
19803622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz{
19813622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	if (self->transport != NULL)
19823622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz		g_free(self->transport);
19833622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
19843622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	GST_LOG_OBJECT(self, "Setting transport: %s", trans);
19853622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	self->transport = g_strdup(trans);
19863622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz}
19873622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
1988e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzgchar *gst_avdtp_sink_get_device(GstAvdtpSink *self)
1989a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz{
1990a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz	return g_strdup(self->device);
1991a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz}
1992a0af7ee44534dad8f35a4142c6a22177e54ffc57Luiz Augusto von Dentz
19933622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentzgchar *gst_avdtp_sink_get_transport(GstAvdtpSink *self)
19943622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz{
19953622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz	return g_strdup(self->transport);
19963622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz}
19973622790d166c2963e60be20b25157527773c1cd4Luiz Augusto von Dentz
1998e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzvoid gst_avdtp_sink_set_crc(GstAvdtpSink *self, gboolean crc)
1999de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz{
2000de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	gint new_crc;
2001de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
2002de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	new_crc = crc ? CRC_PROTECTED : CRC_UNPROTECTED;
2003de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
2004de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	/* test if we already received a different crc */
2005de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (self->mp3_using_crc != -1 && new_crc != self->mp3_using_crc) {
20063ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz		GST_WARNING_OBJECT(self, "crc changed during stream");
2007de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		return;
2008de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
2009de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	self->mp3_using_crc = new_crc;
2010de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
2011de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz}
2012de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
2013e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentzvoid gst_avdtp_sink_set_channel_mode(GstAvdtpSink *self,
2014de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz			const gchar *mode)
2015de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz{
2016de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	gint new_mode;
2017de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
2018e8e68d294cd662970de6082473e30ecd6ee8dd61Luiz Augusto von Dentz	new_mode = gst_avdtp_sink_get_channel_mode(mode);
2019de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
2020de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (self->channel_mode != -1 && new_mode != self->channel_mode) {
20213ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz		GST_WARNING_OBJECT(self, "channel mode changed during stream");
20223ad6867c8c7251c3192378a1a0e2ed937ee47d1bLuiz Augusto von Dentz		return;
2023de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	}
2024de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz
2025de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	self->channel_mode = new_mode;
2026de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz	if (self->channel_mode == -1)
2027de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz		GST_WARNING_OBJECT(self, "Received invalid channel "
2028de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz				"mode: %s", mode);
2029de8b4e7ab91bad2c1c6e796f53d4e69ecbadd0bdLuiz Augusto von Dentz}
2030