a2dp.c revision 984260d913eebddbd7b228704c071f0897640dce
1e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg/*
2e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *
3e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  BlueZ - Bluetooth protocol stack for Linux
4e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *
55592142cb9383df0556b27ac59e96547b380310bJohan Hedberg *  Copyright (C) 2006-2010  Nokia Corporation
69184e2eeb7b97371c6b83b747c8984e2340d2b47Marcel Holtmann *  Copyright (C) 2004-2010  Marcel Holtmann <marcel@holtmann.org>
7e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *
8e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *
9e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  This program is free software; you can redistribute it and/or modify
10e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  it under the terms of the GNU General Public License as published by
11e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  the Free Software Foundation; either version 2 of the License, or
12e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  (at your option) any later version.
13e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *
14e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  This program is distributed in the hope that it will be useful,
15e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  but WITHOUT ANY WARRANTY; without even the implied warranty of
16e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  GNU General Public License for more details.
18e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *
19e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  You should have received a copy of the GNU General Public License
20e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  along with this program; if not, write to the Free Software
21e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
22e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *
23e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg */
24e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg
25e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg#ifdef HAVE_CONFIG_H
26e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg#include <config.h>
27e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg#endif
28e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg
296763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include <stdlib.h>
30847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg#include <errno.h>
316763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include <dbus/dbus.h>
336763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include <glib.h>
346763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
35c2833e263d6cfc4cf82f4bfdcc59640a4071aeaeJohan Hedberg#include <bluetooth/bluetooth.h>
366763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include <bluetooth/sdp.h>
376763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include <bluetooth/sdp_lib.h>
386763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
39e891f7df6225c758da0d95f7554c6cc67f72f31eGustavo F. Padovan#include "log.h"
40d013a1eaa7beebbb49c1fe0015c70ad81566d97cJohan Hedberg#include "device.h"
41296dcf42cf8a4f4d6f0192cac58a28887be38552Johan Hedberg#include "manager.h"
426763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include "avdtp.h"
43f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg#include "sink.h"
441340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita#include "source.h"
455f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg#include "unix.h"
46f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz#include "media.h"
47d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz#include "transport.h"
48e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg#include "a2dp.h"
497299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz#include "sdpd.h"
506763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
51c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg/* The duration that streams without users are allowed to stay in
52c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg * STREAMING state. */
537ec871d37de442fd3731a0eef319851c61fb04ccLuiz Augusto von Dentz#define SUSPEND_TIMEOUT 5
542934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz#define RECONFIGURE_TIMEOUT 500
55c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
56cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg#ifndef MIN
57cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg# define MIN(x, y) ((x) < (y) ? (x) : (y))
58cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg#endif
59cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
60cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg#ifndef MAX
61cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg# define MAX(x, y) ((x) > (y) ? (x) : (y))
62cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg#endif
63cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
64cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergstruct a2dp_sep {
65f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_server *server;
66f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct media_endpoint *endpoint;
67666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	uint8_t type;
68489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	uint8_t codec;
69f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct avdtp_local_sep *lsep;
70c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	struct avdtp *session;
71cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	struct avdtp_stream *stream;
72c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	guint suspend_timer;
735f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	gboolean delay_reporting;
74666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	gboolean locked;
75cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	gboolean suspending;
76cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	gboolean starting;
77cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg};
78cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
792934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstruct a2dp_setup_cb {
800889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	struct a2dp_setup *setup;
81f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	a2dp_select_cb_t select_cb;
822934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	a2dp_config_cb_t config_cb;
832934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	a2dp_stream_cb_t resume_cb;
842934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	a2dp_stream_cb_t suspend_cb;
85d7f412e4197fbe26ebe1c30880e88295d2fbe17eLuiz Augusto von Dentz	guint source_id;
86cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	void *user_data;
87b41ba1eb2b6b7a775536f803eda6fe42d8742745Marcel Holtmann	unsigned int id;
88cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg};
89cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
902934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstruct a2dp_setup {
919fe662df2a0d8950cc0cbd7fc87d47fa2f1fc6bcJohan Hedberg	struct audio_device *dev;
92cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	struct avdtp *session;
93828133c3180a090a06ace6637d9f84ae5f57ae33Johan Hedberg	struct a2dp_sep *sep;
94f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct avdtp_remote_sep *rsep;
95cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	struct avdtp_stream *stream;
965309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	struct avdtp_error *err;
97928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	avdtp_set_configuration_cb setconf_cb;
98daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz	GSList *caps;
992934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	gboolean reconfigure;
1003f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	gboolean start;
101cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	GSList *cb;
1022934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	int ref;
103cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg};
104cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1056763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic DBusConnection *connection = NULL;
1066763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
107957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentzstruct a2dp_server {
108957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	bdaddr_t src;
109957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	GSList *sinks;
110957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	GSList *sources;
111957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	uint32_t source_record_id;
112957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	uint32_t sink_record_id;
1135f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	uint16_t version;
1144c07eae01d5fc6f80f88d27bbcaa2effe73ef325Dmitriy Paliy	gboolean sink_enabled;
1154c07eae01d5fc6f80f88d27bbcaa2effe73ef325Dmitriy Paliy	gboolean source_enabled;
116957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz};
1176763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
118957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentzstatic GSList *servers = NULL;
11903490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedbergstatic GSList *setups = NULL;
1202934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic unsigned int cb_id = 0;
1212934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1222934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic struct a2dp_setup *setup_ref(struct a2dp_setup *setup)
1232934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
1242934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->ref++;
1252934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1260f775bfff64dc5e073b3bd098c296da4660aa072Luiz Augusto von Dentz	DBG("%p: ref=%d", setup, setup->ref);
1272934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1282934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return setup;
1292934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
1306763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
13108b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentzstatic struct audio_device *a2dp_get_dev(struct avdtp *session)
13208b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz{
13308b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	bdaddr_t src, dst;
13408b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz
13508b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	avdtp_get_peers(session, &src, &dst);
13608b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz
13708b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	return manager_find_device(NULL, &src, &dst, NULL, FALSE);
13808b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz}
13908b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz
14008b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentzstatic struct a2dp_setup *setup_new(struct avdtp *session)
14108b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz{
14208b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	struct audio_device *dev;
14308b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	struct a2dp_setup *setup;
14408b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz
14508b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	dev = a2dp_get_dev(session);
14608b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	if (!dev) {
14708b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz		error("Unable to create setup");
14808b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz		return NULL;
14908b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	}
15008b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz
15108b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	setup = g_new0(struct a2dp_setup, 1);
15208b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	setup->session = avdtp_ref(session);
15308b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	setup->dev = a2dp_get_dev(session);
15408b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	setups = g_slist_append(setups, setup);
15508b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz
15608b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	return setup;
15708b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz}
15808b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz
1592934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic void setup_free(struct a2dp_setup *s)
160cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
1610f775bfff64dc5e073b3bd098c296da4660aa072Luiz Augusto von Dentz	DBG("%p", s);
1620889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz
16303490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setups = g_slist_remove(setups, s);
164cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (s->session)
165cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		avdtp_unref(s->session);
166cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	g_slist_foreach(s->cb, (GFunc) g_free, NULL);
167cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	g_slist_free(s->cb);
168daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz	g_slist_foreach(s->caps, (GFunc) g_free, NULL);
169daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz	g_slist_free(s->caps);
170cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	g_free(s);
171cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
172cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1732934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic void setup_unref(struct a2dp_setup *setup)
1742934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
1752934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->ref--;
1762934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1770f775bfff64dc5e073b3bd098c296da4660aa072Luiz Augusto von Dentz	DBG("%p: ref=%d", setup, setup->ref);
1782934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1790889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	if (setup->ref > 0)
1800889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz		return;
1810889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz
1820889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	setup_free(setup);
1830889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz}
1840889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz
1850889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentzstatic struct a2dp_setup_cb *setup_cb_new(struct a2dp_setup *setup)
1860889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz{
1870889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	struct a2dp_setup_cb *cb;
1880889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz
1890889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	cb = g_new0(struct a2dp_setup_cb, 1);
1900889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	cb->setup = setup;
1910889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	cb->id = ++cb_id;
1920889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz
1930889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	setup->cb = g_slist_append(setup->cb, cb);
1940889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	return cb;
1950889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz}
1960889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz
1970889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentzstatic void setup_cb_free(struct a2dp_setup_cb *cb)
1980889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz{
1990889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	struct a2dp_setup *setup = cb->setup;
2000889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz
201d7f412e4197fbe26ebe1c30880e88295d2fbe17eLuiz Augusto von Dentz	if (cb->source_id)
202d7f412e4197fbe26ebe1c30880e88295d2fbe17eLuiz Augusto von Dentz		g_source_remove(cb->source_id);
203d7f412e4197fbe26ebe1c30880e88295d2fbe17eLuiz Augusto von Dentz
2040889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	setup->cb = g_slist_remove(setup->cb, cb);
2050889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	setup_unref(cb->setup);
2060889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	g_free(cb);
2072934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
2082934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
209b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentzstatic void finalize_setup_errno(struct a2dp_setup *s, int err,
210b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz					GSourceFunc cb1, ...)
211cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
212b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz	GSourceFunc finalize;
213b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz	va_list args;
214b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz	struct avdtp_error avdtp_err;
215b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz
216b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz	if (err < 0) {
217b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz		avdtp_error_init(&avdtp_err, AVDTP_ERRNO, -err);
218b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz		s->err = &avdtp_err;
219b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz	}
220b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz
221b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz	va_start(args, cb1);
222b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz	finalize = cb1;
223b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz	setup_ref(s);
224b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz	while (finalize != NULL) {
225b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz		finalize(s);
226b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz		finalize = va_arg(args, GSourceFunc);
227b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz	}
228b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz	setup_unref(s);
229b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz	va_end(args);
230b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz}
231b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz
232b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentzstatic gboolean finalize_config(gpointer data)
233b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz{
234b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz	struct a2dp_setup *s = data;
235847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	GSList *l;
236f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct avdtp_stream *stream = s->err ? NULL : s->stream;
237847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg
238bffa2d625c369fe0f0dceb0abb44c00a964da333Johan Hedberg	for (l = s->cb; l != NULL; ) {
2392934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		struct a2dp_setup_cb *cb = l->data;
2402934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
241ed5c9a308e1dfe289c93391977bd2ff23fabc1faLuiz Augusto von Dentz		l = l->next;
242ed5c9a308e1dfe289c93391977bd2ff23fabc1faLuiz Augusto von Dentz
2438f619dd6228f1cfa750e562d4e2ea89396e8b4fdJohan Hedberg		if (!cb->config_cb)
2448f619dd6228f1cfa750e562d4e2ea89396e8b4fdJohan Hedberg			continue;
2458f619dd6228f1cfa750e562d4e2ea89396e8b4fdJohan Hedberg
2468f619dd6228f1cfa750e562d4e2ea89396e8b4fdJohan Hedberg		cb->config_cb(s->session, s->sep, stream, s->err,
2478f619dd6228f1cfa750e562d4e2ea89396e8b4fdJohan Hedberg							cb->user_data);
2480889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz		setup_cb_free(cb);
249847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	}
250cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
25178a94059160d7478624cad315022255f7ebbbe80Johan Hedberg	return FALSE;
252cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
2531addff77624b54445c9b81779ddc78892a126a45Johan Hedberg
254b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentzstatic gboolean finalize_resume(gpointer data)
2552934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
256b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz	struct a2dp_setup *s = data;
2572934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	GSList *l;
2582934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
259ed5c9a308e1dfe289c93391977bd2ff23fabc1faLuiz Augusto von Dentz	for (l = s->cb; l != NULL; ) {
2602934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		struct a2dp_setup_cb *cb = l->data;
2612934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
262ed5c9a308e1dfe289c93391977bd2ff23fabc1faLuiz Augusto von Dentz		l = l->next;
263ed5c9a308e1dfe289c93391977bd2ff23fabc1faLuiz Augusto von Dentz
264ed5c9a308e1dfe289c93391977bd2ff23fabc1faLuiz Augusto von Dentz		if (!cb->resume_cb)
265ed5c9a308e1dfe289c93391977bd2ff23fabc1faLuiz Augusto von Dentz			continue;
266ed5c9a308e1dfe289c93391977bd2ff23fabc1faLuiz Augusto von Dentz
267ed5c9a308e1dfe289c93391977bd2ff23fabc1faLuiz Augusto von Dentz		cb->resume_cb(s->session, s->err, cb->user_data);
2680889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz		setup_cb_free(cb);
2692934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
2702934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2712934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return FALSE;
2722934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
2732934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
274b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentzstatic gboolean finalize_suspend(gpointer data)
2752934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
276b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz	struct a2dp_setup *s = data;
2772934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	GSList *l;
2782934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
279ed5c9a308e1dfe289c93391977bd2ff23fabc1faLuiz Augusto von Dentz	for (l = s->cb; l != NULL; ) {
2802934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		struct a2dp_setup_cb *cb = l->data;
2812934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
282ed5c9a308e1dfe289c93391977bd2ff23fabc1faLuiz Augusto von Dentz		l = l->next;
283ed5c9a308e1dfe289c93391977bd2ff23fabc1faLuiz Augusto von Dentz
284ed5c9a308e1dfe289c93391977bd2ff23fabc1faLuiz Augusto von Dentz		if (!cb->suspend_cb)
285ed5c9a308e1dfe289c93391977bd2ff23fabc1faLuiz Augusto von Dentz			continue;
286ed5c9a308e1dfe289c93391977bd2ff23fabc1faLuiz Augusto von Dentz
287ed5c9a308e1dfe289c93391977bd2ff23fabc1faLuiz Augusto von Dentz		cb->suspend_cb(s->session, s->err, cb->user_data);
2880889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz		setup_cb_free(cb);
2892934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
2902934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2912934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return FALSE;
2922934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
2932934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
294b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentzstatic void finalize_select(struct a2dp_setup *s)
295f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
296f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	GSList *l;
297f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
298ed5c9a308e1dfe289c93391977bd2ff23fabc1faLuiz Augusto von Dentz	for (l = s->cb; l != NULL; ) {
299f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		struct a2dp_setup_cb *cb = l->data;
300f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
301ed5c9a308e1dfe289c93391977bd2ff23fabc1faLuiz Augusto von Dentz		l = l->next;
302ed5c9a308e1dfe289c93391977bd2ff23fabc1faLuiz Augusto von Dentz
303ed5c9a308e1dfe289c93391977bd2ff23fabc1faLuiz Augusto von Dentz		if (!cb->select_cb)
304ed5c9a308e1dfe289c93391977bd2ff23fabc1faLuiz Augusto von Dentz			continue;
305ed5c9a308e1dfe289c93391977bd2ff23fabc1faLuiz Augusto von Dentz
306daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz		cb->select_cb(s->session, s->sep, s->caps, cb->user_data);
3070889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz		setup_cb_free(cb);
308f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
309f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
310f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
3112934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic struct a2dp_setup *find_setup_by_session(struct avdtp *session)
31203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg{
31303490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	GSList *l;
31403490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
31503490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	for (l = setups; l != NULL; l = l->next) {
3162934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		struct a2dp_setup *setup = l->data;
31703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
31803490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg		if (setup->session == session)
31903490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg			return setup;
32003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	}
32103490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
32203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	return NULL;
32303490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg}
32403490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
32508b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentzstatic struct a2dp_setup *a2dp_setup_get(struct avdtp *session)
32608b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz{
32708b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	struct a2dp_setup *setup;
32808b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz
32908b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	setup = find_setup_by_session(session);
33008b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	if (!setup) {
33108b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz		setup = setup_new(session);
33208b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz		if (!setup)
33308b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz			return NULL;
33408b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	}
33508b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz
33608b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	return setup_ref(setup);
33708b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz}
33808b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz
339caf9fdd6d0183afc3b21d1cd82eb637773c131deMarcel Holtmannstatic struct a2dp_setup *find_setup_by_dev(struct audio_device *dev)
34003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg{
34103490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	GSList *l;
34203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
34303490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	for (l = setups; l != NULL; l = l->next) {
3442934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		struct a2dp_setup *setup = l->data;
34503490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
3469fe662df2a0d8950cc0cbd7fc87d47fa2f1fc6bcJohan Hedberg		if (setup->dev == dev)
34703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg			return setup;
34803490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	}
34903490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
35003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	return NULL;
35103490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg}
35203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
3537a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedbergstatic void stream_state_changed(struct avdtp_stream *stream,
3547a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg					avdtp_state_t old_state,
3557a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg					avdtp_state_t new_state,
3567a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg					struct avdtp_error *err,
3577a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg					void *user_data)
3587a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg{
3597a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	struct a2dp_sep *sep = user_data;
3607a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg
3617a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	if (new_state != AVDTP_STATE_IDLE)
3627a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		return;
3637a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg
3647a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	if (sep->suspend_timer) {
3657a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		g_source_remove(sep->suspend_timer);
3667a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		sep->suspend_timer = 0;
3677a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	}
3687a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg
3697a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	if (sep->session) {
3707a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		avdtp_unref(sep->session);
3717a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		sep->session = NULL;
3727a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	}
3731ddd76afa25d775788e3762ab731cad80f8ffe56Johan Hedberg
374f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (sep->endpoint)
375f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		media_endpoint_clear_configuration(sep->endpoint);
376f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
3777a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	sep->stream = NULL;
3785402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
3795402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz}
3805402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
381928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentzstatic gboolean auto_config(gpointer data)
382928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz{
383928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	struct a2dp_setup *setup = data;
384928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	struct avdtp_error *err = NULL;
385928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
386928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	/* Check if configuration was aborted */
387928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	if (setup->sep->stream == NULL)
388928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz		return FALSE;
389928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
390928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	if (setup->err != NULL) {
391928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz		err = setup->err;
392928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz		goto done;
393928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	}
394928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
395928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	avdtp_stream_add_cb(setup->session, setup->stream,
396928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz				stream_state_changed, setup->sep);
397928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
398928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	if (setup->sep->type == AVDTP_SEP_TYPE_SOURCE)
399928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz		sink_new_stream(setup->dev, setup->session, setup->stream);
400928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	else
401928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz		source_new_stream(setup->dev, setup->session, setup->stream);
402928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
403928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentzdone:
404928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	if (setup->setconf_cb)
405928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz		setup->setconf_cb(setup->session, setup->stream, setup->err);
406928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
407928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	finalize_config(setup);
408928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
409928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	if (err)
410928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz		g_free(err);
411928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
4120889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	setup_unref(setup);
4130889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz
414928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	return FALSE;
415928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz}
416928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
417489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentzstatic gboolean sbc_setconf_ind(struct avdtp *session,
418928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					struct avdtp_local_sep *sep,
419928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					struct avdtp_stream *stream,
420928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					GSList *caps,
421928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					avdtp_set_configuration_cb cb,
422928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					void *user_data)
4236763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
424666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
425928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	struct a2dp_setup *setup;
426f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg
427666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
4288e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Set_Configuration_Ind", sep);
429666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
4308e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Set_Configuration_Ind", sep);
431f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg
43208b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	setup = a2dp_setup_get(session);
43308b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	if (!setup)
434f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg		return FALSE;
435928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
436928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	a2dp_sep->stream = stream;
437928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	setup->sep = a2dp_sep;
438928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	setup->stream = stream;
439928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	setup->setconf_cb = cb;
440928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
4415f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	/* Check valid settings */
4425f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	for (; caps != NULL; caps = g_slist_next(caps)) {
4435f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		struct avdtp_service_capability *cap = caps->data;
4445f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		struct avdtp_media_codec_capability *codec_cap;
4455f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		struct sbc_codec_cap *sbc_cap;
4465f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg
4475f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		if (cap->category == AVDTP_DELAY_REPORTING &&
4485f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg					!a2dp_sep->delay_reporting) {
449928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			setup->err = g_new(struct avdtp_error, 1);
450928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			avdtp_error_init(setup->err, AVDTP_DELAY_REPORTING,
451928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz						AVDTP_UNSUPPORTED_CONFIGURATION);
452928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			goto done;
4535f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		}
4545f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg
455f48c24c3d758934fa5d3edfd49c9a2bced272e5bJohan Hedberg		if (cap->category != AVDTP_MEDIA_CODEC)
456f48c24c3d758934fa5d3edfd49c9a2bced272e5bJohan Hedberg			continue;
457f48c24c3d758934fa5d3edfd49c9a2bced272e5bJohan Hedberg
458f48c24c3d758934fa5d3edfd49c9a2bced272e5bJohan Hedberg		if (cap->length < sizeof(struct sbc_codec_cap))
459f48c24c3d758934fa5d3edfd49c9a2bced272e5bJohan Hedberg			continue;
460f48c24c3d758934fa5d3edfd49c9a2bced272e5bJohan Hedberg
461f48c24c3d758934fa5d3edfd49c9a2bced272e5bJohan Hedberg		codec_cap = (void *) cap->data;
462f48c24c3d758934fa5d3edfd49c9a2bced272e5bJohan Hedberg
463f48c24c3d758934fa5d3edfd49c9a2bced272e5bJohan Hedberg		if (codec_cap->media_codec_type != A2DP_CODEC_SBC)
464f48c24c3d758934fa5d3edfd49c9a2bced272e5bJohan Hedberg			continue;
465f48c24c3d758934fa5d3edfd49c9a2bced272e5bJohan Hedberg
466f48c24c3d758934fa5d3edfd49c9a2bced272e5bJohan Hedberg		sbc_cap = (void *) codec_cap;
467f48c24c3d758934fa5d3edfd49c9a2bced272e5bJohan Hedberg
468f48c24c3d758934fa5d3edfd49c9a2bced272e5bJohan Hedberg		if (sbc_cap->min_bitpool < MIN_BITPOOL ||
469c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz					sbc_cap->max_bitpool > MAX_BITPOOL) {
470928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			setup->err = g_new(struct avdtp_error, 1);
471928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			avdtp_error_init(setup->err, AVDTP_MEDIA_CODEC,
472928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					AVDTP_UNSUPPORTED_CONFIGURATION);
473928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			goto done;
474c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz		}
475c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	}
476c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz
477928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentzdone:
478928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	g_idle_add(auto_config, setup);
4796763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
4806763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
4816763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
482489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentzstatic gboolean sbc_getcap_ind(struct avdtp *session, struct avdtp_local_sep *sep,
4835f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg				gboolean get_all, GSList **caps, uint8_t *err,
4845f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg				void *user_data)
4856763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
486666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
4876763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	struct avdtp_service_capability *media_transport, *media_codec;
4886763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	struct sbc_codec_cap sbc_cap;
4896763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
490666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
4918e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Get_Capability_Ind", sep);
4926763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
4938e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Get_Capability_Ind", sep);
4946763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
4956763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	*caps = NULL;
4966763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
4976763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
4986763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg						NULL, 0);
4996763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
5006763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	*caps = g_slist_append(*caps, media_transport);
5016763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
5026763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	memset(&sbc_cap, 0, sizeof(struct sbc_codec_cap));
5036763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
5046763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sbc_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO;
5056763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sbc_cap.cap.media_codec_type = A2DP_CODEC_SBC;
5066763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
5079ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz	sbc_cap.frequency = ( SBC_SAMPLING_FREQ_48000 |
5089ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz				SBC_SAMPLING_FREQ_44100 |
5099ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz				SBC_SAMPLING_FREQ_32000 |
5109ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz				SBC_SAMPLING_FREQ_16000 );
5116763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
5129ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz	sbc_cap.channel_mode = ( SBC_CHANNEL_MODE_JOINT_STEREO |
5139ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_CHANNEL_MODE_STEREO |
5149ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_CHANNEL_MODE_DUAL_CHANNEL |
5159ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_CHANNEL_MODE_MONO );
5166763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
5179ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz	sbc_cap.block_length = ( SBC_BLOCK_LENGTH_16 |
5189ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_BLOCK_LENGTH_12 |
5199ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_BLOCK_LENGTH_8 |
5209ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_BLOCK_LENGTH_4 );
5216763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
5229ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz	sbc_cap.subbands = ( SBC_SUBBANDS_8 | SBC_SUBBANDS_4 );
5236763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
5249ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz	sbc_cap.allocation_method = ( SBC_ALLOCATION_LOUDNESS |
5259ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_ALLOCATION_SNR );
5266763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
527c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	sbc_cap.min_bitpool = MIN_BITPOOL;
528c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	sbc_cap.max_bitpool = MAX_BITPOOL;
5296763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
5306763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &sbc_cap,
5316763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg						sizeof(sbc_cap));
5326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
5336763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	*caps = g_slist_append(*caps, media_codec);
5346763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
5355f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	if (get_all) {
5365f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		struct avdtp_service_capability *delay_reporting;
5375f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		delay_reporting = avdtp_service_cap_new(AVDTP_DELAY_REPORTING,
5385f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg								NULL, 0);
5395f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		*caps = g_slist_append(*caps, delay_reporting);
5405f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	}
5415f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg
5426763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
5436763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
5446763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
545489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentzstatic gboolean mpeg_setconf_ind(struct avdtp *session,
546928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					struct avdtp_local_sep *sep,
547928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					struct avdtp_stream *stream,
548928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					GSList *caps,
549928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					avdtp_set_configuration_cb cb,
550928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					void *user_data)
551489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz{
552489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct a2dp_sep *a2dp_sep = user_data;
553928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	struct a2dp_setup *setup;
554489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
555489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
5568e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Set_Configuration_Ind", sep);
557489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	else
5588e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Set_Configuration_Ind", sep);
559489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
56008b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	setup = a2dp_setup_get(session);
56108b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	if (!setup)
562489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		return FALSE;
563928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
564928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	a2dp_sep->stream = stream;
565928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	setup->sep = a2dp_sep;
566928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	setup->stream = stream;
567928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	setup->setconf_cb = cb;
568928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
5695f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	for (; caps != NULL; caps = g_slist_next(caps)) {
5705f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		struct avdtp_service_capability *cap = caps->data;
5715f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg
5725f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		if (cap->category == AVDTP_DELAY_REPORTING &&
5735f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg					!a2dp_sep->delay_reporting) {
574928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			setup->err = g_new(struct avdtp_error, 1);
575928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			avdtp_error_init(setup->err, AVDTP_DELAY_REPORTING,
576928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					AVDTP_UNSUPPORTED_CONFIGURATION);
577928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			goto done;
5785f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		}
5795f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	}
5805f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg
581928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentzdone:
582928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	g_idle_add(auto_config, setup);
583489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	return TRUE;
584489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz}
585489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
586ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentzstatic gboolean mpeg_getcap_ind(struct avdtp *session,
587ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz				struct avdtp_local_sep *sep,
5885f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg				gboolean get_all,
589489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				GSList **caps, uint8_t *err, void *user_data)
590489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz{
591489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct a2dp_sep *a2dp_sep = user_data;
592489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct avdtp_service_capability *media_transport, *media_codec;
593489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct mpeg_codec_cap mpeg_cap;
594489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
595489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
5968e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Get_Capability_Ind", sep);
597489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	else
5988e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Get_Capability_Ind", sep);
599489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
600489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	*caps = NULL;
601489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
602489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
603489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz						NULL, 0);
604489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
605489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	*caps = g_slist_append(*caps, media_transport);
606489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
607489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	memset(&mpeg_cap, 0, sizeof(struct mpeg_codec_cap));
608489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
609489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO;
610489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_cap.cap.media_codec_type = A2DP_CODEC_MPEG12;
611489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
612489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_cap.frequency = ( MPEG_SAMPLING_FREQ_48000 |
613489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				MPEG_SAMPLING_FREQ_44100 |
614489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				MPEG_SAMPLING_FREQ_32000 |
615489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				MPEG_SAMPLING_FREQ_24000 |
616489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				MPEG_SAMPLING_FREQ_22050 |
617489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				MPEG_SAMPLING_FREQ_16000 );
618489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
619489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_cap.channel_mode = ( MPEG_CHANNEL_MODE_JOINT_STEREO |
620489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz					MPEG_CHANNEL_MODE_STEREO |
621489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz					MPEG_CHANNEL_MODE_DUAL_CHANNEL |
622489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz					MPEG_CHANNEL_MODE_MONO );
623489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
624489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_cap.layer = ( MPEG_LAYER_MP3 | MPEG_LAYER_MP2 | MPEG_LAYER_MP1 );
625489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
626489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_cap.bitrate = 0xFFFF;
627489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
628489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &mpeg_cap,
629489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz						sizeof(mpeg_cap));
630489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
631489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	*caps = g_slist_append(*caps, media_codec);
632489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
6335f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	if (get_all) {
6345f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		struct avdtp_service_capability *delay_reporting;
6355f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		delay_reporting = avdtp_service_cap_new(AVDTP_DELAY_REPORTING,
6365f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg								NULL, 0);
6375f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		*caps = g_slist_append(*caps, delay_reporting);
6385f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	}
6395f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg
640489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	return TRUE;
641489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz}
642489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
643928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentzstatic void endpoint_setconf_cb(struct media_endpoint *endpoint, void *ret,
644928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz						int size, void *user_data)
645928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz{
646928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	struct a2dp_setup *setup = user_data;
647928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
648928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	if (ret == NULL) {
649928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz		setup->err = g_new(struct avdtp_error, 1);
650928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz		avdtp_error_init(setup->err, AVDTP_MEDIA_CODEC,
651928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					AVDTP_UNSUPPORTED_CONFIGURATION);
652928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	}
653928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
654928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	auto_config(setup);
655928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz}
656928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
657f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzstatic gboolean endpoint_setconf_ind(struct avdtp *session,
658928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz						struct avdtp_local_sep *sep,
659928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz						struct avdtp_stream *stream,
660928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz						GSList *caps,
661928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz						avdtp_set_configuration_cb cb,
662928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz						void *user_data)
663f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
664f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_sep *a2dp_sep = user_data;
665928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	struct a2dp_setup *setup;
666f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
667f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
668f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		DBG("Sink %p: Set_Configuration_Ind", sep);
669f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else
670f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		DBG("Source %p: Set_Configuration_Ind", sep);
671f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
67208b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	setup = a2dp_setup_get(session);
67308b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	if (!session)
674f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return FALSE;
675928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
676928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	a2dp_sep->stream = stream;
677928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	setup->sep = a2dp_sep;
678928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	setup->stream = stream;
679928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	setup->setconf_cb = cb;
680928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
681f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	for (; caps != NULL; caps = g_slist_next(caps)) {
682f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		struct avdtp_service_capability *cap = caps->data;
683f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		struct avdtp_media_codec_capability *codec;
684f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		gboolean ret;
685f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
686f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		if (cap->category == AVDTP_DELAY_REPORTING &&
687f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz					!a2dp_sep->delay_reporting) {
688928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			setup->err = g_new(struct avdtp_error, 1);
689928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			avdtp_error_init(setup->err, AVDTP_DELAY_REPORTING,
690928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					AVDTP_UNSUPPORTED_CONFIGURATION);
691928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			goto done;
692f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		}
693f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
694f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		if (cap->category != AVDTP_MEDIA_CODEC)
695f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			continue;
696f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
697f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		codec = (struct avdtp_media_codec_capability *) cap->data;
698f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
699f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		if (codec->media_codec_type != a2dp_sep->codec) {
700928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			setup->err = g_new(struct avdtp_error, 1);
701928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			avdtp_error_init(setup->err, AVDTP_MEDIA_CODEC,
702928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					AVDTP_UNSUPPORTED_CONFIGURATION);
703928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			goto done;
704f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		}
705f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
70608b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz		ret = media_endpoint_set_configuration(a2dp_sep->endpoint,
70708b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz						setup->dev, codec->data,
70808b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz						cap->length - sizeof(*codec),
70908b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz						endpoint_setconf_cb, setup);
710f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		if (ret)
711928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			return TRUE;
712f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
713928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz		avdtp_error_init(setup->err, AVDTP_MEDIA_CODEC,
714928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					AVDTP_UNSUPPORTED_CONFIGURATION);
715928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz		break;
716f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
717f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
718928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentzdone:
719928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	g_idle_add(auto_config, setup);
720f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	return TRUE;
721f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
722f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
723f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzstatic gboolean endpoint_getcap_ind(struct avdtp *session,
724d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz					struct avdtp_local_sep *sep,
725d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz					gboolean get_all, GSList **caps,
726d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz					uint8_t *err, void *user_data)
727f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
728f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_sep *a2dp_sep = user_data;
729f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct avdtp_service_capability *media_transport, *media_codec;
730f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct avdtp_media_codec_capability *codec_caps;
731f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	uint8_t *capabilities;
732f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	size_t length;
733f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
734f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
735f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		DBG("Sink %p: Get_Capability_Ind", sep);
736f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else
737f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		DBG("Source %p: Get_Capability_Ind", sep);
738f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
739f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	*caps = NULL;
740f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
741f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
742f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz						NULL, 0);
743f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
744f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	*caps = g_slist_append(*caps, media_transport);
745f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
746f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	length = media_endpoint_get_capabilities(a2dp_sep->endpoint,
747f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz						&capabilities);
748f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
749f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	codec_caps = g_malloc0(sizeof(*codec_caps) + length);
750f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	codec_caps->media_type = AVDTP_MEDIA_TYPE_AUDIO;
751f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	codec_caps->media_codec_type = a2dp_sep->codec;
752f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	memcpy(codec_caps->data, capabilities, length);
753f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
754f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, codec_caps,
755f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz						sizeof(*codec_caps) + length);
756f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
757f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	*caps = g_slist_append(*caps, media_codec);
758f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	g_free(codec_caps);
759f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
760f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (get_all) {
761f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		struct avdtp_service_capability *delay_reporting;
762f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		delay_reporting = avdtp_service_cap_new(AVDTP_DELAY_REPORTING,
763f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz								NULL, 0);
764f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		*caps = g_slist_append(*caps, delay_reporting);
765f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
766f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
767f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	return TRUE;
768f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
769f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
77048f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentzstatic void endpoint_open_cb(struct media_endpoint *endpoint, void *ret,
77148f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz						int size, void *user_data)
77248f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz{
77348f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz	struct a2dp_setup *setup = user_data;
77448f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz	int err;
77548f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz
77648f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz	if (ret == NULL) {
77748f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz		setup->stream = NULL;
77801a3858e8cfef34cde0e7af85602523bb45cf8f5Luiz Augusto von Dentz		finalize_setup_errno(setup, -EPERM, finalize_config, NULL);
77948f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz		return;
78048f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz	}
78148f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz
78248f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz	err = avdtp_open(setup->session, setup->stream);
78348f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz	if (err == 0)
78448f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz		return;
78548f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz
78648f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz	error("Error on avdtp_open %s (%d)", strerror(-err), -err);
78748f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz	setup->stream = NULL;
78801a3858e8cfef34cde0e7af85602523bb45cf8f5Luiz Augusto von Dentz	finalize_setup_errno(setup, err, finalize_config, NULL);
78948f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz}
79048f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz
791f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
7920f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg				struct avdtp_stream *stream,
793666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_error *err, void *user_data)
7946763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
795666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
7962934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
797caf9fdd6d0183afc3b21d1cd82eb637773c131deMarcel Holtmann	struct audio_device *dev;
7980f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	int ret;
799cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
800666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
8018e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Set_Configuration_Cfm", sep);
802666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
8038e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Set_Configuration_Cfm", sep);
804cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
80503490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
80603490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
8070f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (err) {
8085309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		if (setup) {
8095309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz			setup->err = err;
8105309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz			finalize_config(setup);
8115309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		}
8120f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		return;
8130f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	}
8140f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg
8157a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep);
816c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	a2dp_sep->stream = stream;
817cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
818cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!setup)
819cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return;
820cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
821fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	dev = a2dp_get_dev(session);
822fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg
823f79bab5a11c34f46150544aa5742616fddeb0195João Paulo Rechi Vita	/* Notify D-Bus interface of the new stream */
824f79bab5a11c34f46150544aa5742616fddeb0195João Paulo Rechi Vita	if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE)
825f79bab5a11c34f46150544aa5742616fddeb0195João Paulo Rechi Vita		sink_new_stream(dev, session, setup->stream);
826f79bab5a11c34f46150544aa5742616fddeb0195João Paulo Rechi Vita	else
827f79bab5a11c34f46150544aa5742616fddeb0195João Paulo Rechi Vita		source_new_stream(dev, session, setup->stream);
82867d1e1774b3ff2d7a09fcf49484515bd85c02d14Johan Hedberg
829f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	/* Notify Endpoint */
830f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (a2dp_sep->endpoint) {
831f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		struct avdtp_service_capability *service;
832f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		struct avdtp_media_codec_capability *codec;
833f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
834f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		service = avdtp_stream_get_codec(stream);
835f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		codec = (struct avdtp_media_codec_capability *) service->data;
836f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
837f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		if (media_endpoint_set_configuration(a2dp_sep->endpoint, dev,
838f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz						codec->data, service->length -
83948f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz						sizeof(*codec),
84048f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz						endpoint_open_cb, setup) ==
84148f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz						TRUE)
84248f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz			return;
84348f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz
84448f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz		setup->stream = NULL;
84501a3858e8cfef34cde0e7af85602523bb45cf8f5Luiz Augusto von Dentz		finalize_setup_errno(setup, -EPERM, finalize_config, NULL);
84648f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz		return;
847f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
848f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
8490f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	ret = avdtp_open(session, stream);
8500f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (ret < 0) {
851924cbd78506f876296a47f63579977db4b2ffe9dJohan Hedberg		error("Error on avdtp_open %s (%d)", strerror(-ret), -ret);
8527a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		setup->stream = NULL;
85301a3858e8cfef34cde0e7af85602523bb45cf8f5Luiz Augusto von Dentz		finalize_setup_errno(setup, ret, finalize_config, NULL);
854cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
8556763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
8566763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
857f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean getconf_ind(struct avdtp *session, struct avdtp_local_sep *sep,
858666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				uint8_t *err, void *user_data)
8596763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
860666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
861666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
862666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
8638e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Get_Configuration_Ind", sep);
8646763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
8658e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Get_Configuration_Ind", sep);
8666763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
8676763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
8686763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
869f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void getconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
870666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
871666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
8726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
873666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
874666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
875666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
8768e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Set_Configuration_Cfm", sep);
8776763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
8788e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Set_Configuration_Cfm", sep);
8796763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
8806763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
881f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean open_ind(struct avdtp *session, struct avdtp_local_sep *sep,
882666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
883666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
8846763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
885666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
886666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
887666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
8888e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Open_Ind", sep);
8896763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
8908e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Open_Ind", sep);
8916763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
8926763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
8936763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
894f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void open_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
895666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
896666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
8976763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
898666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
8992934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
900666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
901666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
9028e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Open_Cfm", sep);
9036763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
9048e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Open_Cfm", sep);
9051addff77624b54445c9b81779ddc78892a126a45Johan Hedberg
90603490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
907cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!setup)
9081addff77624b54445c9b81779ddc78892a126a45Johan Hedberg		return;
9091addff77624b54445c9b81779ddc78892a126a45Johan Hedberg
9102934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (setup->reconfigure)
9112934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup->reconfigure = FALSE;
9122934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
9130f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (err) {
9140f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		setup->stream = NULL;
9155309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
9165402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
917d78f1f6ca28f2744af70bf189837e4c1b06b4eb8Johan Hedberg
918d78f1f6ca28f2744af70bf189837e4c1b06b4eb8Johan Hedberg	finalize_config(setup);
9196763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
9206763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
921c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedbergstatic gboolean suspend_timeout(struct a2dp_sep *sep)
922c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg{
923c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	if (avdtp_suspend(sep->session, sep->stream) == 0)
924c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg		sep->suspending = TRUE;
925c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
9267a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	sep->suspend_timer = 0;
927c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
928c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	avdtp_unref(sep->session);
929c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	sep->session = NULL;
930c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
931c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	return FALSE;
932c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg}
933c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
934f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean start_ind(struct avdtp *session, struct avdtp_local_sep *sep,
935666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
936666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
9376763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
938666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
939df8226b1584a200a81bea35e41d36f03fbafe408Johan Hedberg	struct a2dp_setup *setup;
940c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
941666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
9428e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Start_Ind", sep);
943666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
9448e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Start_Ind", sep);
9455b5cfaadb312600c58362617080e29fbf036712cJohan Hedberg
946df8226b1584a200a81bea35e41d36f03fbafe408Johan Hedberg	setup = find_setup_by_session(session);
947f8d790861cf7e02576b4b03455748567e05f942fLuiz Augusto von Dentz	if (setup)
948f8d790861cf7e02576b4b03455748567e05f942fLuiz Augusto von Dentz		finalize_resume(setup);
949df8226b1584a200a81bea35e41d36f03fbafe408Johan Hedberg
950f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg	if (!a2dp_sep->locked) {
951f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg		a2dp_sep->session = avdtp_ref(session);
9527ec871d37de442fd3731a0eef319851c61fb04ccLuiz Augusto von Dentz		a2dp_sep->suspend_timer = g_timeout_add_seconds(SUSPEND_TIMEOUT,
953c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg						(GSourceFunc) suspend_timeout,
954c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg						a2dp_sep);
955f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg	}
956f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg
957c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	return TRUE;
9586763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
9596763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
960f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void start_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
961666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
962666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
9636763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
964666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
9652934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
966666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
967666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
9688e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Start_Cfm", sep);
9696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
9708e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Start_Cfm", sep);
971cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
97203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
973cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!setup)
974cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return;
975cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
976847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	if (err) {
9770f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		setup->stream = NULL;
9785309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
979847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	}
980d78f1f6ca28f2744af70bf189837e4c1b06b4eb8Johan Hedberg
981d78f1f6ca28f2744af70bf189837e4c1b06b4eb8Johan Hedberg	finalize_resume(setup);
9826763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
9836763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
984f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean suspend_ind(struct avdtp *session, struct avdtp_local_sep *sep,
985666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
986666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
9876763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
988666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
989666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
990666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
9918e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Suspend_Ind", sep);
9926763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
9938e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Suspend_Ind", sep);
994d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg
995d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg	if (a2dp_sep->suspend_timer) {
996d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg		g_source_remove(a2dp_sep->suspend_timer);
99786898be87d24991e48d783b3e20696ff1ce62abcJohan Hedberg		a2dp_sep->suspend_timer = 0;
998f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg		avdtp_unref(a2dp_sep->session);
999f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg		a2dp_sep->session = NULL;
1000d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg	}
1001d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg
10026763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
10036763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
10046763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1005f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void suspend_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
1006666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
1007666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
10086763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
1009666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
10102934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
10113f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	gboolean start;
1012d4bbb4b3baed2293f1ed71887910712843a70939Luiz Augusto von Dentz	int perr;
1013c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
1014666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
10158e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Suspend_Cfm", sep);
1016666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
10178e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Suspend_Cfm", sep);
1018cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1019c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	a2dp_sep->suspending = FALSE;
1020cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
102103490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
102203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	if (!setup)
102303490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg		return;
102403490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
10253f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	start = setup->start;
10263f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	setup->start = FALSE;
10273f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg
10280f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (err) {
10292934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup->stream = NULL;
10305309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
1031cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
1032d4bbb4b3baed2293f1ed71887910712843a70939Luiz Augusto von Dentz
1033d4bbb4b3baed2293f1ed71887910712843a70939Luiz Augusto von Dentz	finalize_suspend(setup);
10343f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg
10353f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	if (!start)
10363f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg		return;
10373f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg
10385309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	if (err) {
1039d4bbb4b3baed2293f1ed71887910712843a70939Luiz Augusto von Dentz		finalize_resume(setup);
1040d4bbb4b3baed2293f1ed71887910712843a70939Luiz Augusto von Dentz		return;
1041d4bbb4b3baed2293f1ed71887910712843a70939Luiz Augusto von Dentz	}
1042d4bbb4b3baed2293f1ed71887910712843a70939Luiz Augusto von Dentz
1043d4bbb4b3baed2293f1ed71887910712843a70939Luiz Augusto von Dentz	perr = avdtp_start(session, a2dp_sep->stream);
1044d4bbb4b3baed2293f1ed71887910712843a70939Luiz Augusto von Dentz	if (perr < 0) {
1045d4bbb4b3baed2293f1ed71887910712843a70939Luiz Augusto von Dentz		error("Error on avdtp_start %s (%d)", strerror(-perr), -perr);
104601a3858e8cfef34cde0e7af85602523bb45cf8f5Luiz Augusto von Dentz		finalize_setup_errno(setup, -EIO, finalize_suspend, NULL);
10473f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	}
10486763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
10496763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1050f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean close_ind(struct avdtp *session, struct avdtp_local_sep *sep,
1051666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
1052666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
10536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
1054666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
10553e71cabf0edb511c452663710ed07d29b676933fLuiz Augusto von Dentz	struct a2dp_setup *setup;
1056c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
1057666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
10588e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Close_Ind", sep);
1059666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
10608e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Close_Ind", sep);
1061cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
10623e71cabf0edb511c452663710ed07d29b676933fLuiz Augusto von Dentz	setup = find_setup_by_session(session);
10633e71cabf0edb511c452663710ed07d29b676933fLuiz Augusto von Dentz	if (!setup)
10643e71cabf0edb511c452663710ed07d29b676933fLuiz Augusto von Dentz		return TRUE;
10653e71cabf0edb511c452663710ed07d29b676933fLuiz Augusto von Dentz
1066b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz	finalize_setup_errno(setup, -ECONNRESET, finalize_suspend,
106701a3858e8cfef34cde0e7af85602523bb45cf8f5Luiz Augusto von Dentz							finalize_resume, NULL);
10683e71cabf0edb511c452663710ed07d29b676933fLuiz Augusto von Dentz
10696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
10706763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
10716763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1072714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentzstatic gboolean a2dp_reconfigure(gpointer data)
10732934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
10742934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup = data;
1075f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_sep *sep = setup->sep;
10762934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	int posix_err;
1077e70fb63e463316ada715c1dbc03e2665c0009028Arun Raghavan	struct avdtp_media_codec_capability *rsep_codec;
1078e70fb63e463316ada715c1dbc03e2665c0009028Arun Raghavan	struct avdtp_service_capability *cap;
10792934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1080e70fb63e463316ada715c1dbc03e2665c0009028Arun Raghavan	if (setup->rsep) {
1081e70fb63e463316ada715c1dbc03e2665c0009028Arun Raghavan		cap = avdtp_get_codec(setup->rsep);
1082e70fb63e463316ada715c1dbc03e2665c0009028Arun Raghavan		rsep_codec = (struct avdtp_media_codec_capability *) cap->data;
1083e70fb63e463316ada715c1dbc03e2665c0009028Arun Raghavan	}
1084e70fb63e463316ada715c1dbc03e2665c0009028Arun Raghavan
1085e70fb63e463316ada715c1dbc03e2665c0009028Arun Raghavan	if (!setup->rsep || sep->codec != rsep_codec->media_codec_type)
10866b30e2e4d4e0c1b9b84ad0c3ad2f9bfd2da6e94dJohn Crosbie		setup->rsep = avdtp_find_remote_sep(setup->session, sep->lsep);
10876b30e2e4d4e0c1b9b84ad0c3ad2f9bfd2da6e94dJohn Crosbie
1088f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	posix_err = avdtp_set_configuration(setup->session, setup->rsep,
1089f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz						sep->lsep,
1090daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz						setup->caps,
10912934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz						&setup->stream);
10922934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (posix_err < 0) {
1093c2a07d4a29dba7b936744a9b5c42c886f478abfcLuiz Augusto von Dentz		error("avdtp_set_configuration: %s", strerror(-posix_err));
1094c2a07d4a29dba7b936744a9b5c42c886f478abfcLuiz Augusto von Dentz		goto failed;
10952934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
10962934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
10972934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return FALSE;
1098c2a07d4a29dba7b936744a9b5c42c886f478abfcLuiz Augusto von Dentz
1099c2a07d4a29dba7b936744a9b5c42c886f478abfcLuiz Augusto von Dentzfailed:
110001a3858e8cfef34cde0e7af85602523bb45cf8f5Luiz Augusto von Dentz	finalize_setup_errno(setup, posix_err, finalize_config, NULL);
1101c2a07d4a29dba7b936744a9b5c42c886f478abfcLuiz Augusto von Dentz	return FALSE;
11022934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
11032934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1104f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void close_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
1105666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
1106666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
11076763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
1108666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
11092934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
1110c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
1111666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
11128e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Close_Cfm", sep);
1113666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
11148e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Close_Cfm", sep);
11155402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
111603490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
11175402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (!setup)
11185402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return;
11195402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
11205402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (err) {
11215402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		setup->stream = NULL;
11225309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
11235309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		finalize_config(setup);
1124847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg		return;
11255402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
11265402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
1127de96fcd89917168170a3b479c3bf094b6a5de67aJohan Hedberg	if (!setup->rsep)
1128de96fcd89917168170a3b479c3bf094b6a5de67aJohan Hedberg		setup->rsep = avdtp_stream_get_remote_sep(stream);
1129de96fcd89917168170a3b479c3bf094b6a5de67aJohan Hedberg
11302934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (setup->reconfigure)
1131fe5de84c0db9e7108000fe1b7a7136528b8f27d9Johan Hedberg		g_timeout_add(RECONFIGURE_TIMEOUT, a2dp_reconfigure, setup);
11326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
11336763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1134f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean abort_ind(struct avdtp *session, struct avdtp_local_sep *sep,
1135666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
1136666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
11376763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
1138666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
1139c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
1140666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
11418e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Abort_Ind", sep);
1142666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
11438e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Abort_Ind", sep);
1144cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1145fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	a2dp_sep->stream = NULL;
114603490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
11476763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
11486763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
11496763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1150f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void abort_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
1151666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
1152666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
11536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
1154666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
11552934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
1156c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
1157666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
11588e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Abort_Cfm", sep);
1159666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
11608e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Abort_Cfm", sep);
11612934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
11622934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup = find_setup_by_session(session);
11632934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (!setup)
11642934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		return;
11652934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
11662934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_unref(setup);
11676763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
11686763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1169f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean reconf_ind(struct avdtp *session, struct avdtp_local_sep *sep,
1170666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				uint8_t *err, void *user_data)
11716763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
1172666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
1173666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1174666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
11758e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: ReConfigure_Ind", sep);
11766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
11778e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: ReConfigure_Ind", sep);
1178bac81ba536a0d77154e01a71b8bb1bd1712d42f6Johan Hedberg
11796763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
11806763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
11816763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
11825f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedbergstatic gboolean delayreport_ind(struct avdtp *session,
11835f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg				struct avdtp_local_sep *sep,
11845f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg				uint8_t rseid, uint16_t delay,
11855f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg				uint8_t *err, void *user_data)
11865f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg{
11875f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
11885f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	struct audio_device *dev = a2dp_get_dev(session);
11895f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg
11905f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
11918e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: DelayReport_Ind", sep);
11925f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	else
11938e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: DelayReport_Ind", sep);
11945f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg
11955f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	unix_delay_report(dev, rseid, delay);
11965f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg
11975f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	return TRUE;
11985f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg}
11995f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg
1200d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentzstatic gboolean endpoint_delayreport_ind(struct avdtp *session,
1201d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz						struct avdtp_local_sep *sep,
1202d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz						uint8_t rseid, uint16_t delay,
1203d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz						uint8_t *err, void *user_data)
1204d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz{
1205d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz	struct a2dp_sep *a2dp_sep = user_data;
1206d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz	struct media_transport *transport;
1207d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz
1208d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
1209d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz		DBG("Sink %p: DelayReport_Ind", sep);
1210d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz	else
1211d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz		DBG("Source %p: DelayReport_Ind", sep);
1212d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz
1213d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz	transport = media_endpoint_get_transport(a2dp_sep->endpoint);
1214d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz	if (transport == NULL)
1215d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz		return FALSE;
1216d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz
1217d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz	media_transport_update_delay(transport, delay);
1218d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz
1219d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz	return TRUE;
1220d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz}
1221d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz
12220f458da19471c933a4105cc450c48548b72edc8eJohan Hedbergstatic void reconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
1223666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
1224666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
12256763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
1226666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
12272934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
1228666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1229666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
12308e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: ReConfigure_Cfm", sep);
12316763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
12328e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: ReConfigure_Cfm", sep);
12335402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
123403490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
12355402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (!setup)
12365402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return;
12375402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
12385402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (err) {
12395402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		setup->stream = NULL;
12405309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
12415402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
1242d78f1f6ca28f2744af70bf189837e4c1b06b4eb8Johan Hedberg
1243d78f1f6ca28f2744af70bf189837e4c1b06b4eb8Johan Hedberg	finalize_config(setup);
12446763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
12456763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
12465f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedbergstatic void delay_report_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
12475f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg				struct avdtp_stream *stream,
12485f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg				struct avdtp_error *err, void *user_data)
12495f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg{
12505f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
12515f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg
12525f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
12538e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: DelayReport_Cfm", sep);
12545f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	else
12558e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: DelayReport_Cfm", sep);
12565f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg}
12575f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg
12586763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic struct avdtp_sep_cfm cfm = {
12596763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.set_configuration	= setconf_cfm,
12606763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.get_configuration	= getconf_cfm,
12616763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.open			= open_cfm,
12626763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.start			= start_cfm,
12636763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.suspend		= suspend_cfm,
12646763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.close			= close_cfm,
12656763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.abort			= abort_cfm,
12665f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	.reconfigure		= reconf_cfm,
12675f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	.delay_report		= delay_report_cfm,
12686763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg};
12696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1270489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentzstatic struct avdtp_sep_ind sbc_ind = {
1271489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.get_capability		= sbc_getcap_ind,
1272489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.set_configuration	= sbc_setconf_ind,
1273489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.get_configuration	= getconf_ind,
1274489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.open			= open_ind,
1275489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.start			= start_ind,
1276489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.suspend		= suspend_ind,
1277489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.close			= close_ind,
1278489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.abort			= abort_ind,
12795f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	.reconfigure		= reconf_ind,
12805f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	.delayreport		= delayreport_ind,
1281489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz};
1282489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
1283489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentzstatic struct avdtp_sep_ind mpeg_ind = {
1284489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.get_capability		= mpeg_getcap_ind,
1285489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.set_configuration	= mpeg_setconf_ind,
12866763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.get_configuration	= getconf_ind,
12876763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.open			= open_ind,
12886763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.start			= start_ind,
12896763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.suspend		= suspend_ind,
12906763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.close			= close_ind,
12916763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.abort			= abort_ind,
12925f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	.reconfigure		= reconf_ind,
12935f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	.delayreport		= delayreport_ind,
12946763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg};
12956763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1296f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzstatic struct avdtp_sep_ind endpoint_ind = {
1297f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	.get_capability		= endpoint_getcap_ind,
1298f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	.set_configuration	= endpoint_setconf_ind,
1299f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	.get_configuration	= getconf_ind,
1300f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	.open			= open_ind,
1301f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	.start			= start_ind,
1302f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	.suspend		= suspend_ind,
1303f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	.close			= close_ind,
1304f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	.abort			= abort_ind,
1305f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	.reconfigure		= reconf_ind,
1306d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz	.delayreport		= endpoint_delayreport_ind,
1307f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz};
1308f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
13095f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedbergstatic sdp_record_t *a2dp_record(uint8_t type, uint16_t avdtp_ver)
13106763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
13116763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
13121340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	uuid_t root_uuid, l2cap_uuid, avdtp_uuid, a2dp_uuid;
13136763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_profile_desc_t profile[1];
13146763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_t *aproto, *proto[2];
13157299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_record_t *record;
13166763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_data_t *psm, *version, *features;
1317aec344ca67c386af667940545bb62946c092bfcfJohan Hedberg	uint16_t lp = AVDTP_UUID;
13185f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	uint16_t a2dp_ver = 0x0102, feat = 0x000f;
13196763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
13207299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	record = sdp_record_alloc();
13217299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	if (!record)
13227299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz		return NULL;
13236763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
13246763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
13256763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	root = sdp_list_append(0, &root_uuid);
13267299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_set_browse_groups(record, root);
13276763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
13281340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	if (type == AVDTP_SEP_TYPE_SOURCE)
13291340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita		sdp_uuid16_create(&a2dp_uuid, AUDIO_SOURCE_SVCLASS_ID);
13301340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	else
13311340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita		sdp_uuid16_create(&a2dp_uuid, AUDIO_SINK_SVCLASS_ID);
13321340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	svclass_id = sdp_list_append(0, &a2dp_uuid);
13337299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_set_service_classes(record, svclass_id);
13346763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
13356763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID);
1336aec344ca67c386af667940545bb62946c092bfcfJohan Hedberg	profile[0].version = a2dp_ver;
13376763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	pfseq = sdp_list_append(0, &profile[0]);
13387299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_set_profile_descs(record, pfseq);
13396763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
13401340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
13411340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	proto[0] = sdp_list_append(0, &l2cap_uuid);
13426763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	psm = sdp_data_alloc(SDP_UINT16, &lp);
13436763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	proto[0] = sdp_list_append(proto[0], psm);
13446763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	apseq = sdp_list_append(0, proto[0]);
13456763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
13461340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	sdp_uuid16_create(&avdtp_uuid, AVDTP_UUID);
13471340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	proto[1] = sdp_list_append(0, &avdtp_uuid);
1348aec344ca67c386af667940545bb62946c092bfcfJohan Hedberg	version = sdp_data_alloc(SDP_UINT16, &avdtp_ver);
13496763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	proto[1] = sdp_list_append(proto[1], version);
13506763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	apseq = sdp_list_append(apseq, proto[1]);
13516763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
13526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	aproto = sdp_list_append(0, apseq);
13537299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_set_access_protos(record, aproto);
13546763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
13556763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	features = sdp_data_alloc(SDP_UINT16, &feat);
13567299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features);
13576763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
13581340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	if (type == AVDTP_SEP_TYPE_SOURCE)
13591340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita		sdp_set_info_attr(record, "Audio Source", 0, 0);
13601340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	else
13611340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita		sdp_set_info_attr(record, "Audio Sink", 0, 0);
13626763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
13636763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	free(psm);
13646763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	free(version);
13656763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(proto[0], 0);
13666763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(proto[1], 0);
13676763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(apseq, 0);
13686763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(pfseq, 0);
13696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(aproto, 0);
13706763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(root, 0);
13716763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(svclass_id, 0);
13726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
13737299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	return record;
13746763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
13756763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1376957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentzstatic struct a2dp_server *find_server(GSList *list, const bdaddr_t *src)
1377957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz{
1378957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
137924c6dee3b307cbf9e99dfdb875895f410120ec41Szymon Janc	for (; list; list = list->next) {
138024c6dee3b307cbf9e99dfdb875895f410120ec41Szymon Janc		struct a2dp_server *server = list->data;
1381957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1382957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		if (bacmp(&server->src, src) == 0)
1383957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz			return server;
1384957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	}
1385957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1386957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	return NULL;
1387957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz}
1388957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1389957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentzint a2dp_register(DBusConnection *conn, const bdaddr_t *src, GKeyFile *config)
1390666938b54d631956826343ed278e2af4b982fc29Johan Hedberg{
139131f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita	int sbc_srcs = 1, sbc_sinks = 1;
13925b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	int mpeg12_srcs = 0, mpeg12_sinks = 0;
13938a7db32ff944cd51ac879d02bf9ec56c25800c66Johan Hedberg	gboolean source = TRUE, sink = FALSE, socket = TRUE;
13948a7db32ff944cd51ac879d02bf9ec56c25800c66Johan Hedberg	gboolean delay_reporting = FALSE;
13955b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	char *str;
13965b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	GError *err = NULL;
1397e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedberg	int i;
1398957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	struct a2dp_server *server;
1399e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedberg
14005b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (!config)
14015b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		goto proceed;
14025b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
140331f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita	str = g_key_file_get_string(config, "General", "Enable", &err);
140431f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita
140531f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita	if (err) {
14068e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("audio.conf: %s", err->message);
140731f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita		g_clear_error(&err);
140831f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita	} else {
140931f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita		if (strstr(str, "Sink"))
141031f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita			source = TRUE;
141131f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita		if (strstr(str, "Source"))
141231f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita			sink = TRUE;
141331f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita		g_free(str);
141431f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita	}
141531f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita
14165b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	str = g_key_file_get_string(config, "General", "Disable", &err);
14175b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
14185b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (err) {
14198e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("audio.conf: %s", err->message);
1420bd4494363230705c3efaa13f3c94a73fadab88e4Johan Hedberg		g_clear_error(&err);
14215b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	} else {
14225b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		if (strstr(str, "Sink"))
14237e64674f8b5c5be6b3cccb17ea05766763d50f94Johan Hedberg			source = FALSE;
14245b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		if (strstr(str, "Source"))
14257e64674f8b5c5be6b3cccb17ea05766763d50f94Johan Hedberg			sink = FALSE;
1426b5251802a1aa4c23286b7b54a58ea8ea8bd9ce51Luiz Augusto von Dentz		if (strstr(str, "Socket"))
1427b5251802a1aa4c23286b7b54a58ea8ea8bd9ce51Luiz Augusto von Dentz			socket = FALSE;
14285b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_free(str);
14295b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	}
14305b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
1431b5251802a1aa4c23286b7b54a58ea8ea8bd9ce51Luiz Augusto von Dentz	/* Don't register any local sep if Socket is disabled */
1432b5251802a1aa4c23286b7b54a58ea8ea8bd9ce51Luiz Augusto von Dentz	if (socket == FALSE) {
1433b5251802a1aa4c23286b7b54a58ea8ea8bd9ce51Luiz Augusto von Dentz		sbc_srcs = 0;
1434b5251802a1aa4c23286b7b54a58ea8ea8bd9ce51Luiz Augusto von Dentz		sbc_sinks = 0;
1435b5251802a1aa4c23286b7b54a58ea8ea8bd9ce51Luiz Augusto von Dentz		mpeg12_srcs = 0;
1436b5251802a1aa4c23286b7b54a58ea8ea8bd9ce51Luiz Augusto von Dentz		mpeg12_sinks = 0;
1437b5251802a1aa4c23286b7b54a58ea8ea8bd9ce51Luiz Augusto von Dentz		goto proceed;
1438b5251802a1aa4c23286b7b54a58ea8ea8bd9ce51Luiz Augusto von Dentz	}
1439b5251802a1aa4c23286b7b54a58ea8ea8bd9ce51Luiz Augusto von Dentz
14405b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	str = g_key_file_get_string(config, "A2DP", "SBCSources", &err);
14415b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (err) {
14428e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("audio.conf: %s", err->message);
1443bd4494363230705c3efaa13f3c94a73fadab88e4Johan Hedberg		g_clear_error(&err);
14445b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	} else {
14455b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		sbc_srcs = atoi(str);
14465b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_free(str);
14475b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	}
14485b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
14495b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	str = g_key_file_get_string(config, "A2DP", "MPEG12Sources", &err);
14505b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (err) {
14518e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("audio.conf: %s", err->message);
1452bd4494363230705c3efaa13f3c94a73fadab88e4Johan Hedberg		g_clear_error(&err);
14535b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	} else {
14545b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		mpeg12_srcs = atoi(str);
14555b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_free(str);
14565b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	}
14575b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
14585b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	str = g_key_file_get_string(config, "A2DP", "SBCSinks", &err);
14595b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (err) {
14608e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("audio.conf: %s", err->message);
1461bd4494363230705c3efaa13f3c94a73fadab88e4Johan Hedberg		g_clear_error(&err);
14625b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	} else {
14635b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		sbc_sinks = atoi(str);
14645b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_free(str);
14655b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	}
14665b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
14675b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	str = g_key_file_get_string(config, "A2DP", "MPEG12Sinks", &err);
14685b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (err) {
14698e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("audio.conf: %s", err->message);
1470bd4494363230705c3efaa13f3c94a73fadab88e4Johan Hedberg		g_clear_error(&err);
14715b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	} else {
14725b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		mpeg12_sinks = atoi(str);
14735b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_free(str);
14745b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	}
14756763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
14765b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentzproceed:
1477957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (!connection)
1478957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		connection = dbus_connection_ref(conn);
1479957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1480957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	server = find_server(servers, src);
1481957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (!server) {
1482501b5d1a8afbaa56761dd5473e8d5169997b71ddLuiz Augusto von Dentz		int av_err;
1483501b5d1a8afbaa56761dd5473e8d5169997b71ddLuiz Augusto von Dentz
1484957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		server = g_new0(struct a2dp_server, 1);
1485957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		if (!server)
1486957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz			return -ENOMEM;
1487501b5d1a8afbaa56761dd5473e8d5169997b71ddLuiz Augusto von Dentz
14885f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		av_err = avdtp_init(src, config, &server->version);
14892e926fb0168ba0249dfbbcca71ff685e4235e1c7Steve Grubb		if (av_err < 0) {
14902e926fb0168ba0249dfbbcca71ff685e4235e1c7Steve Grubb			g_free(server);
1491501b5d1a8afbaa56761dd5473e8d5169997b71ddLuiz Augusto von Dentz			return av_err;
14922e926fb0168ba0249dfbbcca71ff685e4235e1c7Steve Grubb		}
1493501b5d1a8afbaa56761dd5473e8d5169997b71ddLuiz Augusto von Dentz
1494957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		bacpy(&server->src, src);
1495957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		servers = g_slist_append(servers, server);
1496957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	}
14976763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
14988a7db32ff944cd51ac879d02bf9ec56c25800c66Johan Hedberg	if (config)
14998a7db32ff944cd51ac879d02bf9ec56c25800c66Johan Hedberg		delay_reporting = g_key_file_get_boolean(config, "A2DP",
15005f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg						"DelayReporting", NULL);
15018a7db32ff944cd51ac879d02bf9ec56c25800c66Johan Hedberg
15025f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	if (delay_reporting)
15035f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		server->version = 0x0103;
15045f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	else
15055f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		server->version = 0x0102;
15065f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg
15074c07eae01d5fc6f80f88d27bbcaa2effe73ef325Dmitriy Paliy	server->source_enabled = source;
15087e64674f8b5c5be6b3cccb17ea05766763d50f94Johan Hedberg	if (source) {
15095b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		for (i = 0; i < sbc_srcs; i++)
1510f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			a2dp_add_sep(src, AVDTP_SEP_TYPE_SOURCE,
15112da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy				A2DP_CODEC_SBC, delay_reporting, NULL, NULL);
15125b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
15135b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		for (i = 0; i < mpeg12_srcs; i++)
1514f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			a2dp_add_sep(src, AVDTP_SEP_TYPE_SOURCE,
15152da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy					A2DP_CODEC_MPEG12, delay_reporting,
15162da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy					NULL, NULL);
1517489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	}
15184c07eae01d5fc6f80f88d27bbcaa2effe73ef325Dmitriy Paliy	server->sink_enabled = sink;
15195b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (sink) {
15205b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		for (i = 0; i < sbc_sinks; i++)
1521f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			a2dp_add_sep(src, AVDTP_SEP_TYPE_SINK,
15222da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy				A2DP_CODEC_SBC, delay_reporting, NULL, NULL);
15235b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
15245b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		for (i = 0; i < mpeg12_sinks; i++)
1525f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			a2dp_add_sep(src, AVDTP_SEP_TYPE_SINK,
1526f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz					A2DP_CODEC_MPEG12, delay_reporting,
15272da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy					NULL, NULL);
1528489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	}
15296763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
15306763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return 0;
15316763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
15326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1533666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic void a2dp_unregister_sep(struct a2dp_sep *sep)
1534666938b54d631956826343ed278e2af4b982fc29Johan Hedberg{
1535fe0f3fab1809cdc397b7d8dd41fb0ceed3e73a6cLuiz Augusto von Dentz	if (sep->endpoint) {
153680958057369d56d090b90929f85a0e89673a3d5cLuiz Augusto von Dentz		media_endpoint_release(sep->endpoint);
1537fe0f3fab1809cdc397b7d8dd41fb0ceed3e73a6cLuiz Augusto von Dentz		sep->endpoint = NULL;
1538fe0f3fab1809cdc397b7d8dd41fb0ceed3e73a6cLuiz Augusto von Dentz	}
153980958057369d56d090b90929f85a0e89673a3d5cLuiz Augusto von Dentz
1540f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	avdtp_unregister_sep(sep->lsep);
1541666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	g_free(sep);
1542666938b54d631956826343ed278e2af4b982fc29Johan Hedberg}
1543666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1544957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentzvoid a2dp_unregister(const bdaddr_t *src)
15456763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
1546957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	struct a2dp_server *server;
15476763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1548957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	server = find_server(servers, src);
1549957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (!server)
1550957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		return;
15516763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1552f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	g_slist_foreach(server->sinks, (GFunc) a2dp_remove_sep, NULL);
1553957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	g_slist_free(server->sinks);
15546763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1555f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	g_slist_foreach(server->sources, (GFunc) a2dp_remove_sep, NULL);
1556957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	g_slist_free(server->sources);
1557957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1558f481e7faa9ced6b2c0fa089f768a9bd9613be640Luiz Augusto von Dentz	avdtp_exit(src);
1559f481e7faa9ced6b2c0fa089f768a9bd9613be640Luiz Augusto von Dentz
1560957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	servers = g_slist_remove(servers, server);
1561957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	g_free(server);
1562957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1563957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (servers)
1564957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		return;
15656763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
15666763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	dbus_connection_unref(connection);
1567957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	connection = NULL;
15686763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
15696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1570f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzstruct a2dp_sep *a2dp_add_sep(const bdaddr_t *src, uint8_t type,
1571f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz				uint8_t codec, gboolean delay_reporting,
15722da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy				struct media_endpoint *endpoint, int *err)
1573f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
1574f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_server *server;
1575f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_sep *sep;
1576f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	GSList **l;
1577f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	uint32_t *record_id;
1578f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	sdp_record_t *record;
1579f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct avdtp_sep_ind *ind;
1580f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1581f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	server = find_server(servers, src);
15822da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy	if (server == NULL) {
15832da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy		if (err)
15842da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy			*err = -EINVAL;
1585f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return NULL;
15862da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy	}
1587f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
15882da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy	if (type == AVDTP_SEP_TYPE_SINK && !server->sink_enabled) {
15892da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy		if (err)
15902da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy			*err = -EPROTONOSUPPORT;
15914c07eae01d5fc6f80f88d27bbcaa2effe73ef325Dmitriy Paliy		return NULL;
15922da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy	}
15934c07eae01d5fc6f80f88d27bbcaa2effe73ef325Dmitriy Paliy
15942da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy	if (type == AVDTP_SEP_TYPE_SOURCE && !server->source_enabled) {
15952da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy		if (err)
15962da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy			*err = -EPROTONOSUPPORT;
15974c07eae01d5fc6f80f88d27bbcaa2effe73ef325Dmitriy Paliy		return NULL;
15982da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy	}
15994c07eae01d5fc6f80f88d27bbcaa2effe73ef325Dmitriy Paliy
1600f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	sep = g_new0(struct a2dp_sep, 1);
1601f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1602f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (endpoint) {
1603f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		ind = &endpoint_ind;
1604f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		goto proceed;
1605f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1606f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1607f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	ind = (codec == A2DP_CODEC_MPEG12) ? &mpeg_ind : &sbc_ind;
1608f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1609f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzproceed:
1610f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	sep->lsep = avdtp_register_sep(&server->src, type,
1611f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz					AVDTP_MEDIA_TYPE_AUDIO, codec,
1612f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz					delay_reporting, ind, &cfm, sep);
1613f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (sep->lsep == NULL) {
1614f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		g_free(sep);
16152da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy		if (err)
16162da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy			*err = -EINVAL;
1617f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return NULL;
1618f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1619f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1620f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	sep->server = server;
1621f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	sep->endpoint = endpoint;
1622f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	sep->codec = codec;
1623f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	sep->type = type;
1624f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	sep->delay_reporting = delay_reporting;
1625f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1626f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (type == AVDTP_SEP_TYPE_SOURCE) {
1627f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		l = &server->sources;
1628f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		record_id = &server->source_record_id;
1629f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	} else {
1630f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		l = &server->sinks;
1631f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		record_id = &server->sink_record_id;
1632f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1633f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1634f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (*record_id != 0)
1635f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		goto add;
1636f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1637f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	record = a2dp_record(type, server->version);
1638f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (!record) {
1639f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		error("Unable to allocate new service record");
1640f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		avdtp_unregister_sep(sep->lsep);
1641f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		g_free(sep);
16422da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy		if (err)
16432da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy			*err = -EINVAL;
1644f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return NULL;
1645f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1646f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1647f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (add_record_to_server(&server->src, record) < 0) {
1648f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		error("Unable to register A2DP service record");\
1649f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		sdp_record_free(record);
1650f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		avdtp_unregister_sep(sep->lsep);
1651f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		g_free(sep);
16522da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy		if (err)
16532da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy			*err = -EINVAL;
1654f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return NULL;
1655f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1656f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	*record_id = record->handle;
1657f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1658f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzadd:
1659f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	*l = g_slist_append(*l, sep);
1660f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
16612da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy	if (err)
16622da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy		*err = 0;
1663f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	return sep;
1664f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
1665f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1666f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzvoid a2dp_remove_sep(struct a2dp_sep *sep)
1667f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
1668f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_server *server = sep->server;
1669f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1670f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (sep->type == AVDTP_SEP_TYPE_SOURCE) {
167180958057369d56d090b90929f85a0e89673a3d5cLuiz Augusto von Dentz		if (g_slist_find(server->sources, sep) == NULL)
167280958057369d56d090b90929f85a0e89673a3d5cLuiz Augusto von Dentz			return;
1673f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		server->sources = g_slist_remove(server->sources, sep);
1674f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		if (server->sources == NULL && server->source_record_id) {
1675f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			remove_record_from_server(server->source_record_id);
1676f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			server->source_record_id = 0;
1677f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		}
1678f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	} else {
167980958057369d56d090b90929f85a0e89673a3d5cLuiz Augusto von Dentz		if (g_slist_find(server->sinks, sep) == NULL)
168080958057369d56d090b90929f85a0e89673a3d5cLuiz Augusto von Dentz			return;
1681f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		server->sinks = g_slist_remove(server->sinks, sep);
1682f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		if (server->sinks == NULL && server->sink_record_id) {
1683f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			remove_record_from_server(server->sink_record_id);
1684f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			server->sink_record_id = 0;
1685f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		}
1686f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1687f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
16881636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz	if (sep->locked)
16891636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz		return;
16901636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz
1691f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	a2dp_unregister_sep(sep);
1692f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
1693f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
16941340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vitastruct a2dp_sep *a2dp_get(struct avdtp *session,
1695bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz				struct avdtp_remote_sep *rsep)
1696bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz{
1697bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	GSList *l;
1698bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	struct a2dp_server *server;
1699bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	struct avdtp_service_capability *cap;
1700bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	struct avdtp_media_codec_capability *codec_cap = NULL;
1701bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	bdaddr_t src;
1702bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz
1703bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	avdtp_get_peers(session, &src, NULL);
1704bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	server = find_server(servers, &src);
1705bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	if (!server)
1706bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz		return NULL;
1707bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz
1708bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	cap = avdtp_get_codec(rsep);
1709bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	codec_cap = (void *) cap->data;
1710bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz
17111340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	if (avdtp_get_type(rsep) == AVDTP_SEP_TYPE_SINK)
17121340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita		l = server->sources;
17131340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	else
17141340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita		l = server->sinks;
17151340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita
17161340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	for (; l != NULL; l = l->next) {
1717bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz		struct a2dp_sep *sep = l->data;
1718bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz
1719bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz		if (sep->locked)
1720bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz			continue;
1721bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz
1722bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz		if (sep->codec != codec_cap->media_codec_type)
1723bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz			continue;
1724bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz
1725bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz		if (!sep->stream || avdtp_has_stream(session, sep->stream))
1726bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz			return sep;
1727bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	}
1728bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz
1729bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	return NULL;
1730bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz}
1731bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz
1732f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzstatic uint8_t default_bitpool(uint8_t freq, uint8_t mode)
1733f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
1734f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	switch (freq) {
1735f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	case SBC_SAMPLING_FREQ_16000:
1736f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	case SBC_SAMPLING_FREQ_32000:
1737f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return 53;
1738f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	case SBC_SAMPLING_FREQ_44100:
1739f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		switch (mode) {
1740f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		case SBC_CHANNEL_MODE_MONO:
1741f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		case SBC_CHANNEL_MODE_DUAL_CHANNEL:
1742f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			return 31;
1743f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		case SBC_CHANNEL_MODE_STEREO:
1744f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		case SBC_CHANNEL_MODE_JOINT_STEREO:
1745f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			return 53;
1746f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		default:
1747f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			error("Invalid channel mode %u", mode);
1748f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			return 53;
1749f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		}
1750f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	case SBC_SAMPLING_FREQ_48000:
1751f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		switch (mode) {
1752f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		case SBC_CHANNEL_MODE_MONO:
1753f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		case SBC_CHANNEL_MODE_DUAL_CHANNEL:
1754f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			return 29;
1755f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		case SBC_CHANNEL_MODE_STEREO:
1756f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		case SBC_CHANNEL_MODE_JOINT_STEREO:
1757f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			return 51;
1758f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		default:
1759f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			error("Invalid channel mode %u", mode);
1760f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			return 51;
1761f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		}
1762f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	default:
1763f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		error("Invalid sampling freq %u", freq);
1764f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return 53;
1765f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1766f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
1767f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1768f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzstatic gboolean select_sbc_params(struct sbc_codec_cap *cap,
1769f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz					struct sbc_codec_cap *supported)
1770f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
1771f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	unsigned int max_bitpool, min_bitpool;
1772f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1773f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	memset(cap, 0, sizeof(struct sbc_codec_cap));
1774f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1775f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	cap->cap.media_type = AVDTP_MEDIA_TYPE_AUDIO;
1776f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	cap->cap.media_codec_type = A2DP_CODEC_SBC;
1777f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1778f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (supported->frequency & SBC_SAMPLING_FREQ_44100)
1779f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->frequency = SBC_SAMPLING_FREQ_44100;
1780f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else if (supported->frequency & SBC_SAMPLING_FREQ_48000)
1781f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->frequency = SBC_SAMPLING_FREQ_48000;
1782f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else if (supported->frequency & SBC_SAMPLING_FREQ_32000)
1783f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->frequency = SBC_SAMPLING_FREQ_32000;
1784f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else if (supported->frequency & SBC_SAMPLING_FREQ_16000)
1785f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->frequency = SBC_SAMPLING_FREQ_16000;
1786f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else {
1787f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		error("No supported frequencies");
1788f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return FALSE;
1789f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1790f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1791f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (supported->channel_mode & SBC_CHANNEL_MODE_JOINT_STEREO)
1792f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->channel_mode = SBC_CHANNEL_MODE_JOINT_STEREO;
1793f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else if (supported->channel_mode & SBC_CHANNEL_MODE_STEREO)
1794f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->channel_mode = SBC_CHANNEL_MODE_STEREO;
1795f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else if (supported->channel_mode & SBC_CHANNEL_MODE_DUAL_CHANNEL)
1796f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL;
1797f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else if (supported->channel_mode & SBC_CHANNEL_MODE_MONO)
1798f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->channel_mode = SBC_CHANNEL_MODE_MONO;
1799f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else {
1800f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		error("No supported channel modes");
1801f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return FALSE;
1802f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1803f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1804f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (supported->block_length & SBC_BLOCK_LENGTH_16)
1805f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->block_length = SBC_BLOCK_LENGTH_16;
1806f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else if (supported->block_length & SBC_BLOCK_LENGTH_12)
1807f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->block_length = SBC_BLOCK_LENGTH_12;
1808f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else if (supported->block_length & SBC_BLOCK_LENGTH_8)
1809f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->block_length = SBC_BLOCK_LENGTH_8;
1810f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else if (supported->block_length & SBC_BLOCK_LENGTH_4)
1811f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->block_length = SBC_BLOCK_LENGTH_4;
1812f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else {
1813f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		error("No supported block lengths");
1814f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return FALSE;
1815f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1816f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1817f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (supported->subbands & SBC_SUBBANDS_8)
1818f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->subbands = SBC_SUBBANDS_8;
1819f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else if (supported->subbands & SBC_SUBBANDS_4)
1820f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->subbands = SBC_SUBBANDS_4;
1821f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else {
1822f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		error("No supported subbands");
1823f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return FALSE;
1824f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1825f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1826f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (supported->allocation_method & SBC_ALLOCATION_LOUDNESS)
1827f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->allocation_method = SBC_ALLOCATION_LOUDNESS;
1828f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else if (supported->allocation_method & SBC_ALLOCATION_SNR)
1829f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->allocation_method = SBC_ALLOCATION_SNR;
1830f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1831f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	min_bitpool = MAX(MIN_BITPOOL, supported->min_bitpool);
1832f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	max_bitpool = MIN(default_bitpool(cap->frequency, cap->channel_mode),
1833f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz							supported->max_bitpool);
1834f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1835f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	cap->min_bitpool = min_bitpool;
1836f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	cap->max_bitpool = max_bitpool;
1837f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1838f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	return TRUE;
1839f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
1840f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1841f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzstatic gboolean select_capabilities(struct avdtp *session,
1842f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz					struct avdtp_remote_sep *rsep,
1843f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz					GSList **caps)
1844f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
1845f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct avdtp_service_capability *media_transport, *media_codec;
1846f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct sbc_codec_cap sbc_cap;
1847f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1848f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	media_codec = avdtp_get_codec(rsep);
1849f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (!media_codec)
1850f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return FALSE;
1851f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1852f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	select_sbc_params(&sbc_cap, (struct sbc_codec_cap *) media_codec->data);
1853f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1854f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
1855f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz						NULL, 0);
1856f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1857f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	*caps = g_slist_append(*caps, media_transport);
1858f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1859f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &sbc_cap,
1860f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz						sizeof(sbc_cap));
1861f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1862f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	*caps = g_slist_append(*caps, media_codec);
1863f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1864f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (avdtp_get_delay_reporting(rsep)) {
1865f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		struct avdtp_service_capability *delay_reporting;
1866f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		delay_reporting = avdtp_service_cap_new(AVDTP_DELAY_REPORTING,
1867f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz								NULL, 0);
1868f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		*caps = g_slist_append(*caps, delay_reporting);
1869f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1870f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1871f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	return TRUE;
1872f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
1873f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1874f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzstatic void select_cb(struct media_endpoint *endpoint, void *ret, int size,
1875f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			void *user_data)
1876f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
1877f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_setup *setup = user_data;
1878f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct avdtp_service_capability *media_transport, *media_codec;
1879f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct avdtp_media_codec_capability *cap;
1880f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1881f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (size < 0) {
1882f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		DBG("Endpoint replied an invalid configuration");
1883f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		goto done;
1884f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1885f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1886f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
1887f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz						NULL, 0);
1888f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1889daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz	setup->caps = g_slist_append(setup->caps, media_transport);
1890f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1891f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	cap = g_malloc0(sizeof(*cap) + size);
1892f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	cap->media_type = AVDTP_MEDIA_TYPE_AUDIO;
1893f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	cap->media_codec_type = setup->sep->codec;
1894f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	memcpy(cap->data, ret, size);
1895f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1896f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, cap,
1897f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz						sizeof(*cap) + size);
1898f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1899daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz	setup->caps = g_slist_append(setup->caps, media_codec);
1900a26b71e72c9c511c511287eeb0fb32e7fb9717f7Luiz Augusto von Dentz	g_free(cap);
1901f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1902f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzdone:
1903daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz	finalize_select(setup);
1904f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
1905f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1906f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzstatic gboolean auto_select(gpointer data)
1907f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
1908f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_setup *setup = data;
1909f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1910daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz	finalize_select(setup);
1911f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1912f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	return FALSE;
1913f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
1914f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1915f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzstatic struct a2dp_sep *a2dp_find_sep(struct avdtp *session, GSList *list,
1916f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz					const char *sender)
1917f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
1918f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	for (; list; list = list->next) {
1919f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		struct a2dp_sep *sep = list->data;
1920f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1921f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		/* Use sender's endpoint if available */
1922f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		if (sender) {
1923f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			const char *name;
1924f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1925f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			if (sep->endpoint == NULL)
1926f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz				continue;
1927f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1928f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			name = media_endpoint_get_sender(sep->endpoint);
1929f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			if (g_strcmp0(sender, name) != 0)
1930f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz				continue;
1931f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		}
1932f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1933f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		if (avdtp_find_remote_sep(session, sep->lsep) == NULL)
1934f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			continue;
1935f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1936f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return sep;
1937f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1938f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1939f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	return NULL;
1940f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
1941f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1942f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzstatic struct a2dp_sep *a2dp_select_sep(struct avdtp *session, uint8_t type,
1943f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz					const char *sender)
1944f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
1945f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_server *server;
1946f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_sep *sep;
1947f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	GSList *l;
1948f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	bdaddr_t src;
1949f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1950f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	avdtp_get_peers(session, &src, NULL);
1951f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	server = find_server(servers, &src);
1952f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (!server)
1953f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return NULL;
1954f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1955f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	l = type == AVDTP_SEP_TYPE_SINK ? server->sources : server->sinks;
1956f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1957f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	/* Check sender's seps first */
1958f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	sep = a2dp_find_sep(session, l, sender);
1959f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (sep != NULL)
1960f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return sep;
1961f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1962f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	return a2dp_find_sep(session, l, NULL);
1963f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
1964f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1965f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzunsigned int a2dp_select_capabilities(struct avdtp *session,
1966f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz					uint8_t type, const char *sender,
1967f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz					a2dp_select_cb_t cb,
1968f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz					void *user_data)
1969f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
1970f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_setup *setup;
1971f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_setup_cb *cb_data;
1972f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_sep *sep;
1973f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct avdtp_service_capability *service;
1974f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct avdtp_media_codec_capability *codec;
1975f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1976f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	sep = a2dp_select_sep(session, type, sender);
1977f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (!sep) {
1978f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		error("Unable to select SEP");
1979f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return 0;
1980f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1981f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
198208b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	setup = a2dp_setup_get(session);
198308b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	if (!setup)
198408b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz		return 0;
198508b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz
19860889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	cb_data = setup_cb_new(setup);
1987f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	cb_data->select_cb = cb;
1988f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	cb_data->user_data = user_data;
1989f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1990f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	setup->sep = sep;
1991f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	setup->rsep = avdtp_find_remote_sep(session, sep->lsep);
1992f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1993f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (setup->rsep == NULL) {
1994f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		error("Could not find remote sep");
1995f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		goto fail;
1996f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1997f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1998f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	/* FIXME: Remove auto select when it is not longer possible to register
1999f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	endpoint in the configuration file */
2000f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (sep->endpoint == NULL) {
2001f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		if (!select_capabilities(session, setup->rsep,
2002daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz					&setup->caps)) {
2003f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			error("Unable to auto select remote SEP capabilities");
2004f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			goto fail;
2005f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		}
2006f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
2007f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		g_idle_add(auto_select, setup);
2008f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
2009f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return cb_data->id;
2010f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
2011f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
2012f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	service = avdtp_get_codec(setup->rsep);
2013f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	codec = (struct avdtp_media_codec_capability *) service->data;
2014f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
2015f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (media_endpoint_select_configuration(sep->endpoint, codec->data,
2016f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz						service->length - sizeof(*codec),
2017f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz						select_cb, setup) ==
2018f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz						TRUE)
2019f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return cb_data->id;
2020f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
2021f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzfail:
20220889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	setup_cb_free(cb_data);
2023f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	return 0;
2024f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
2025f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
2026f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
20271340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vitaunsigned int a2dp_config(struct avdtp *session, struct a2dp_sep *sep,
2028bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz				a2dp_config_cb_t cb, GSList *caps,
2029bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz				void *user_data)
2030cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
20312934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup_cb *cb_data;
2032666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	GSList *l;
2033957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	struct a2dp_server *server;
20342934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
2035bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	struct a2dp_sep *tmp;
2036489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct avdtp_service_capability *cap;
2037489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct avdtp_media_codec_capability *codec_cap = NULL;
20382934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	int posix_err;
2039957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	bdaddr_t src;
2040957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
2041957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	avdtp_get_peers(session, &src, NULL);
2042957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	server = find_server(servers, &src);
2043957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (!server)
2044957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		return 0;
2045cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
2046489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	for (l = caps; l != NULL; l = l->next) {
2047489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		cap = l->data;
2048489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
2049489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		if (cap->category != AVDTP_MEDIA_CODEC)
2050489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz			continue;
2051489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
2052489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		codec_cap = (void *) cap->data;
2053489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		break;
2054489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	}
2055489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
2056489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (!codec_cap)
2057489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		return 0;
2058489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
2059bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	if (sep->codec != codec_cap->media_codec_type)
2060730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg		return 0;
2061730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg
2062f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	DBG("a2dp_config: selected SEP %p", sep->lsep);
2063666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
206408b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	setup = a2dp_setup_get(session);
206508b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	if (!setup)
206608b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz		return 0;
206708b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz
20680889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	cb_data = setup_cb_new(setup);
20692934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->config_cb = cb;
2070cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	cb_data->user_data = user_data;
2071cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
20722934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->sep = sep;
2073666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	setup->stream = sep->stream;
2074daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz
2075daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz	/* Copy given caps if they are different than current caps */
2076daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz	if (setup->caps != caps) {
2077daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz		g_slist_foreach(setup->caps, (GFunc) g_free, NULL);
2078daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz		g_slist_free(setup->caps);
2079daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz		setup->caps = g_slist_copy(caps);
2080daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz	}
2081cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
2082f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	switch (avdtp_sep_get_state(sep->lsep)) {
2083cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_IDLE:
2084984260d913eebddbd7b228704c071f0897640dceSzymon Janc		if (sep->type == AVDTP_SEP_TYPE_SOURCE)
20851340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita			l = server->sources;
2086984260d913eebddbd7b228704c071f0897640dceSzymon Janc		else
20871340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita			l = server->sinks;
2088714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz
20891340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita		for (; l != NULL; l = l->next) {
20901340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita			tmp = l->data;
2091714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz			if (avdtp_has_stream(session, tmp->stream))
2092714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz				break;
2093714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz		}
2094714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz
2095714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz		if (l != NULL) {
2096217b1bea41aad595022ce5a0078949472c27295bLuiz Augusto von Dentz			if (a2dp_sep_get_lock(tmp))
2097217b1bea41aad595022ce5a0078949472c27295bLuiz Augusto von Dentz				goto failed;
2098714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz			setup->reconfigure = TRUE;
2099ab816e6549b8e2ed661bd029e274102e8e04c075Luiz Augusto von Dentz			if (avdtp_close(session, tmp->stream, FALSE) < 0) {
2100714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz				error("avdtp_close failed");
2101714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz				goto failed;
2102714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz			}
2103714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz			break;
2104714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz		}
2105714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz
2106f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		setup->rsep = avdtp_find_remote_sep(session, sep->lsep);
2107f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		if (setup->rsep == NULL) {
21082934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			error("No matching ACP and INT SEPs found");
21092934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			goto failed;
21102934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		}
21112934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2112f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		posix_err = avdtp_set_configuration(session, setup->rsep,
2113f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz							sep->lsep, caps,
2114f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz							&setup->stream);
21152934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (posix_err < 0) {
21162934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			error("avdtp_set_configuration: %s",
21172934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				strerror(-posix_err));
2118cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			goto failed;
2119730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg		}
2120cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
2121cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_OPEN:
21222934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_STREAMING:
21230fcfb4bedc60fb5f632b4423518cb823f58348feLuiz Augusto von Dentz		if (avdtp_stream_has_capabilities(setup->stream, caps)) {
21248e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan			DBG("Configuration match: resuming");
2125d7f412e4197fbe26ebe1c30880e88295d2fbe17eLuiz Augusto von Dentz			cb_data->source_id = g_idle_add(finalize_config,
2126d7f412e4197fbe26ebe1c30880e88295d2fbe17eLuiz Augusto von Dentz								setup);
21270fcfb4bedc60fb5f632b4423518cb823f58348feLuiz Augusto von Dentz		} else if (!setup->reconfigure) {
21282934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			setup->reconfigure = TRUE;
2129ab816e6549b8e2ed661bd029e274102e8e04c075Luiz Augusto von Dentz			if (avdtp_close(session, sep->stream, FALSE) < 0) {
21302934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				error("avdtp_close failed");
21312934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				goto failed;
21325402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz			}
21335402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		}
21342934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
21352934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	default:
21362934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		error("SEP in bad state for requesting a new stream");
21372934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		goto failed;
21382934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
21392934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
21402934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return cb_data->id;
21412934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
21422934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzfailed:
21430889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	setup_cb_free(cb_data);
21442934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return 0;
21452934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
21462934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
21471340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vitaunsigned int a2dp_resume(struct avdtp *session, struct a2dp_sep *sep,
21482934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				a2dp_stream_cb_t cb, void *user_data)
21492934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
21502934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup_cb *cb_data;
21512934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
21522934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
215308b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	setup = a2dp_setup_get(session);
215408b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	if (!setup)
215508b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz		return 0;
215608b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz
21570889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	cb_data = setup_cb_new(setup);
21582934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->resume_cb = cb;
21592934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->user_data = user_data;
21602934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
21612934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->sep = sep;
21622934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->stream = sep->stream;
21632934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2164f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	switch (avdtp_sep_get_state(sep->lsep)) {
21652934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_IDLE:
21662934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		goto failed;
21672934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
21682934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_OPEN:
21692934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (avdtp_start(session, sep->stream) < 0) {
2170730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg			error("avdtp_start failed");
2171cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			goto failed;
2172730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg		}
2173cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
2174cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_STREAMING:
21752934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (!sep->suspending && sep->suspend_timer) {
21762934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			g_source_remove(sep->suspend_timer);
21772934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			sep->suspend_timer = 0;
21782934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			avdtp_unref(sep->session);
21792934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			sep->session = NULL;
2180cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		}
21813f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg		if (sep->suspending)
21823f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg			setup->start = TRUE;
21833f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg		else
2184d7f412e4197fbe26ebe1c30880e88295d2fbe17eLuiz Augusto von Dentz			cb_data->source_id = g_idle_add(finalize_resume,
2185d7f412e4197fbe26ebe1c30880e88295d2fbe17eLuiz Augusto von Dentz								setup);
2186cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
2187cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	default:
21886863b32bb003ead1a43228d685092b0173628750João Paulo Rechi Vita		error("SEP in bad state for resume");
2189cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		goto failed;
2190cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
21915402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
21922934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return cb_data->id;
21932934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
21942934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzfailed:
21950889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	setup_cb_free(cb_data);
21962934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return 0;
21972934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
21982934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
21991340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vitaunsigned int a2dp_suspend(struct avdtp *session, struct a2dp_sep *sep,
22002934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				a2dp_stream_cb_t cb, void *user_data)
22012934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
22022934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup_cb *cb_data;
22032934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
22042934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
220508b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	setup = a2dp_setup_get(session);
220608b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	if (!setup)
220708b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz		return 0;
220808b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz
22090889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	cb_data = setup_cb_new(setup);
22102934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->suspend_cb = cb;
22112934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->user_data = user_data;
22122934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
22132934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->sep = sep;
22142934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->stream = sep->stream;
22152934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2216f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	switch (avdtp_sep_get_state(sep->lsep)) {
22172934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_IDLE:
22181340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita		error("a2dp_suspend: no stream to suspend");
22192934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		goto failed;
22202934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
22212934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_OPEN:
2222d7f412e4197fbe26ebe1c30880e88295d2fbe17eLuiz Augusto von Dentz		cb_data->source_id = g_idle_add(finalize_suspend, setup);
22232934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
22242934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_STREAMING:
2225c020b7240f8f6b72ffbb6c6f327a63f2da14e6a9Johan Hedberg		if (avdtp_suspend(session, sep->stream) < 0) {
2226c020b7240f8f6b72ffbb6c6f327a63f2da14e6a9Johan Hedberg			error("avdtp_suspend failed");
22272934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			goto failed;
22282934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		}
2229f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		sep->suspending = TRUE;
22302934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
22312934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	default:
22326863b32bb003ead1a43228d685092b0173628750João Paulo Rechi Vita		error("SEP in bad state for suspend");
22332934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		goto failed;
22342934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
223503490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
2236cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	return cb_data->id;
2237cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
2238cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergfailed:
22390889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	setup_cb_free(cb_data);
22400f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	return 0;
2241cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
2242cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
22431340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vitagboolean a2dp_cancel(struct audio_device *dev, unsigned int id)
22441340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita{
22451340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	struct a2dp_setup *setup;
22461340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	GSList *l;
22471340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita
22481340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	setup = find_setup_by_dev(dev);
22491340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	if (!setup)
22501340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita		return FALSE;
22511340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita
22520889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	for (l = setup->cb; l != NULL; l = g_slist_next(l)) {
22531340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita		struct a2dp_setup_cb *cb = l->data;
22541340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita
22550889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz		if (cb->id != id)
22560889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz			continue;
22571340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita
22580889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz		setup_ref(setup);
22590889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz		setup_cb_free(cb);
22601340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita
22610889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz		if (!setup->cb) {
22620889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz			DBG("aborting setup %p", setup);
22630889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz			avdtp_abort(setup->session, setup->stream);
22640889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz			return TRUE;
22650889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz		}
22661340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita
22670889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz		setup_unref(setup);
2268f8d790861cf7e02576b4b03455748567e05f942fLuiz Augusto von Dentz		return TRUE;
22690889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	}
2270f8d790861cf7e02576b4b03455748567e05f942fLuiz Augusto von Dentz
22710889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	return FALSE;
22721340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita}
22731340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita
2274fc0d501d82773718d0f2d040f786136332c39813Johan Hedberggboolean a2dp_sep_lock(struct a2dp_sep *sep, struct avdtp *session)
2275cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
2276fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	if (sep->locked)
2277fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg		return FALSE;
2278f4211a3cd3442d54fa7877a6c421bee034d46e8eJohan Hedberg
2279f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	DBG("SEP %p locked", sep->lsep);
2280fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	sep->locked = TRUE;
2281666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
2282fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	return TRUE;
2283cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
2284cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
2285fc0d501d82773718d0f2d040f786136332c39813Johan Hedberggboolean a2dp_sep_unlock(struct a2dp_sep *sep, struct avdtp *session)
2286cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
22871636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz	struct a2dp_server *server = sep->server;
2288cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	avdtp_state_t state;
22891636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz	GSList *l;
2290cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
2291f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	state = avdtp_sep_get_state(sep->lsep);
2292cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
2293666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	sep->locked = FALSE;
2294cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
2295f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	DBG("SEP %p unlocked", sep->lsep);
2296730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg
22971636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz	if (sep->type == AVDTP_SEP_TYPE_SOURCE)
22981636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz		l = server->sources;
22991636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz	else
23001636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz		l = server->sinks;
23011636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz
23021636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz	/* Unregister sep if it was removed */
23031636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz	if (g_slist_find(l, sep) == NULL) {
23041636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz		a2dp_unregister_sep(sep);
23051636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz		return TRUE;
23061636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz	}
23071636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz
2308666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (!sep->stream || state == AVDTP_STATE_IDLE)
2309cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return TRUE;
2310cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
2311cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	switch (state) {
2312cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_OPEN:
2313cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		/* Set timer here */
2314cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
2315cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_STREAMING:
2316666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		if (avdtp_suspend(session, sep->stream) == 0)
2317666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			sep->suspending = TRUE;
2318cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
2319cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	default:
2320cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
2321cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
2322cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
2323cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	return TRUE;
2324cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
2325cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
2326c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentzgboolean a2dp_sep_get_lock(struct a2dp_sep *sep)
2327c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz{
2328c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	return sep->locked;
2329c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz}
2330c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz
2331c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentzstatic int stream_cmp(gconstpointer data, gconstpointer user_data)
2332c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz{
2333c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	const struct a2dp_sep *sep = data;
2334c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	const struct avdtp_stream *stream = user_data;
2335c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz
2336c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	return (sep->stream != stream);
2337c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz}
2338c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz
2339c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentzstruct a2dp_sep *a2dp_get_sep(struct avdtp *session,
2340c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz				struct avdtp_stream *stream)
2341c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz{
2342c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	struct a2dp_server *server;
2343c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	bdaddr_t src, dst;
2344c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	GSList *l;
2345c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz
2346c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	avdtp_get_peers(session, &src, &dst);
2347c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz
2348c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	for (l = servers; l; l = l->next) {
2349c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz		server = l->data;
2350c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz
2351c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz		if (bacmp(&src, &server->src) == 0)
2352c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz			break;
2353c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	}
2354c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz
2355c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	if (!l)
2356c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz		return NULL;
2357c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz
2358c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	l = g_slist_find_custom(server->sources, stream, stream_cmp);
2359c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	if (l)
2360c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz		return l->data;
2361c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz
2362c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	l = g_slist_find_custom(server->sinks, stream, stream_cmp);
2363c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	if (l)
2364c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz		return l->data;
2365c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz
2366c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	return NULL;
2367c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz}
2368f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
2369f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzstruct avdtp_stream *a2dp_sep_get_stream(struct a2dp_sep *sep)
2370f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
2371f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	return sep->stream;
2372f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
2373