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
507926ce4dc656ecc494194aeac141695ab48f7b713Jaikumar Ganesh#ifdef ANDROID
508926ce4dc656ecc494194aeac141695ab48f7b713Jaikumar Ganesh	sbc_cap.frequency = SBC_SAMPLING_FREQ_44100;
509926ce4dc656ecc494194aeac141695ab48f7b713Jaikumar Ganesh#else
5109ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz	sbc_cap.frequency = ( SBC_SAMPLING_FREQ_48000 |
5119ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz				SBC_SAMPLING_FREQ_44100 |
5129ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz				SBC_SAMPLING_FREQ_32000 |
5139ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz				SBC_SAMPLING_FREQ_16000 );
514926ce4dc656ecc494194aeac141695ab48f7b713Jaikumar Ganesh#endif
5156763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
5169ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz	sbc_cap.channel_mode = ( SBC_CHANNEL_MODE_JOINT_STEREO |
5179ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_CHANNEL_MODE_STEREO |
5189ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_CHANNEL_MODE_DUAL_CHANNEL |
5199ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_CHANNEL_MODE_MONO );
5206763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
5219ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz	sbc_cap.block_length = ( SBC_BLOCK_LENGTH_16 |
5229ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_BLOCK_LENGTH_12 |
5239ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_BLOCK_LENGTH_8 |
5249ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_BLOCK_LENGTH_4 );
5256763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
5269ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz	sbc_cap.subbands = ( SBC_SUBBANDS_8 | SBC_SUBBANDS_4 );
5276763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
5289ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz	sbc_cap.allocation_method = ( SBC_ALLOCATION_LOUDNESS |
5299ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_ALLOCATION_SNR );
5306763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
531c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	sbc_cap.min_bitpool = MIN_BITPOOL;
532c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	sbc_cap.max_bitpool = MAX_BITPOOL;
5336763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
5346763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &sbc_cap,
5356763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg						sizeof(sbc_cap));
5366763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
5376763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	*caps = g_slist_append(*caps, media_codec);
5386763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
5395f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	if (get_all) {
5405f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		struct avdtp_service_capability *delay_reporting;
5415f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		delay_reporting = avdtp_service_cap_new(AVDTP_DELAY_REPORTING,
5425f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg								NULL, 0);
5435f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		*caps = g_slist_append(*caps, delay_reporting);
5445f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	}
5455f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg
5466763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
5476763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
5486763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
549489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentzstatic gboolean mpeg_setconf_ind(struct avdtp *session,
550928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					struct avdtp_local_sep *sep,
551928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					struct avdtp_stream *stream,
552928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					GSList *caps,
553928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					avdtp_set_configuration_cb cb,
554928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					void *user_data)
555489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz{
556489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct a2dp_sep *a2dp_sep = user_data;
557928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	struct a2dp_setup *setup;
558489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
559489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
5608e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Set_Configuration_Ind", sep);
561489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	else
5628e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Set_Configuration_Ind", sep);
563489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
56408b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	setup = a2dp_setup_get(session);
56508b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	if (!setup)
566489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		return FALSE;
567928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
568928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	a2dp_sep->stream = stream;
569928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	setup->sep = a2dp_sep;
570928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	setup->stream = stream;
571928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	setup->setconf_cb = cb;
572928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
5735f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	for (; caps != NULL; caps = g_slist_next(caps)) {
5745f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		struct avdtp_service_capability *cap = caps->data;
5755f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg
5765f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		if (cap->category == AVDTP_DELAY_REPORTING &&
5775f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg					!a2dp_sep->delay_reporting) {
578928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			setup->err = g_new(struct avdtp_error, 1);
579928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			avdtp_error_init(setup->err, AVDTP_DELAY_REPORTING,
580928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					AVDTP_UNSUPPORTED_CONFIGURATION);
581928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			goto done;
5825f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		}
5835f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	}
5845f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg
585928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentzdone:
586928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	g_idle_add(auto_config, setup);
587489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	return TRUE;
588489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz}
589489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
590ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentzstatic gboolean mpeg_getcap_ind(struct avdtp *session,
591ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz				struct avdtp_local_sep *sep,
5925f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg				gboolean get_all,
593489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				GSList **caps, uint8_t *err, void *user_data)
594489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz{
595489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct a2dp_sep *a2dp_sep = user_data;
596489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct avdtp_service_capability *media_transport, *media_codec;
597489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct mpeg_codec_cap mpeg_cap;
598489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
599489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
6008e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Get_Capability_Ind", sep);
601489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	else
6028e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Get_Capability_Ind", sep);
603489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
604489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	*caps = NULL;
605489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
606489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
607489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz						NULL, 0);
608489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
609489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	*caps = g_slist_append(*caps, media_transport);
610489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
611489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	memset(&mpeg_cap, 0, sizeof(struct mpeg_codec_cap));
612489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
613489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO;
614489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_cap.cap.media_codec_type = A2DP_CODEC_MPEG12;
615489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
616489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_cap.frequency = ( MPEG_SAMPLING_FREQ_48000 |
617489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				MPEG_SAMPLING_FREQ_44100 |
618489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				MPEG_SAMPLING_FREQ_32000 |
619489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				MPEG_SAMPLING_FREQ_24000 |
620489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				MPEG_SAMPLING_FREQ_22050 |
621489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				MPEG_SAMPLING_FREQ_16000 );
622489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
623489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_cap.channel_mode = ( MPEG_CHANNEL_MODE_JOINT_STEREO |
624489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz					MPEG_CHANNEL_MODE_STEREO |
625489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz					MPEG_CHANNEL_MODE_DUAL_CHANNEL |
626489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz					MPEG_CHANNEL_MODE_MONO );
627489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
628489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_cap.layer = ( MPEG_LAYER_MP3 | MPEG_LAYER_MP2 | MPEG_LAYER_MP1 );
629489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
630489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_cap.bitrate = 0xFFFF;
631489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
632489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &mpeg_cap,
633489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz						sizeof(mpeg_cap));
634489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
635489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	*caps = g_slist_append(*caps, media_codec);
636489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
6375f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	if (get_all) {
6385f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		struct avdtp_service_capability *delay_reporting;
6395f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		delay_reporting = avdtp_service_cap_new(AVDTP_DELAY_REPORTING,
6405f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg								NULL, 0);
6415f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		*caps = g_slist_append(*caps, delay_reporting);
6425f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	}
6435f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg
644489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	return TRUE;
645489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz}
646489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
647928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentzstatic void endpoint_setconf_cb(struct media_endpoint *endpoint, void *ret,
648928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz						int size, void *user_data)
649928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz{
650928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	struct a2dp_setup *setup = user_data;
651928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
652928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	if (ret == NULL) {
653928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz		setup->err = g_new(struct avdtp_error, 1);
654928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz		avdtp_error_init(setup->err, AVDTP_MEDIA_CODEC,
655928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					AVDTP_UNSUPPORTED_CONFIGURATION);
656928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	}
657928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
658928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	auto_config(setup);
659928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz}
660928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
661f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzstatic gboolean endpoint_setconf_ind(struct avdtp *session,
662928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz						struct avdtp_local_sep *sep,
663928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz						struct avdtp_stream *stream,
664928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz						GSList *caps,
665928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz						avdtp_set_configuration_cb cb,
666928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz						void *user_data)
667f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
668f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_sep *a2dp_sep = user_data;
669928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	struct a2dp_setup *setup;
670f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
671f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
672f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		DBG("Sink %p: Set_Configuration_Ind", sep);
673f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else
674f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		DBG("Source %p: Set_Configuration_Ind", sep);
675f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
67608b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	setup = a2dp_setup_get(session);
67708b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	if (!session)
678f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return FALSE;
679928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
680928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	a2dp_sep->stream = stream;
681928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	setup->sep = a2dp_sep;
682928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	setup->stream = stream;
683928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	setup->setconf_cb = cb;
684928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz
685f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	for (; caps != NULL; caps = g_slist_next(caps)) {
686f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		struct avdtp_service_capability *cap = caps->data;
687f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		struct avdtp_media_codec_capability *codec;
688f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		gboolean ret;
689f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
690f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		if (cap->category == AVDTP_DELAY_REPORTING &&
691f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz					!a2dp_sep->delay_reporting) {
692928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			setup->err = g_new(struct avdtp_error, 1);
693928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			avdtp_error_init(setup->err, AVDTP_DELAY_REPORTING,
694928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					AVDTP_UNSUPPORTED_CONFIGURATION);
695928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			goto done;
696f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		}
697f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
698f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		if (cap->category != AVDTP_MEDIA_CODEC)
699f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			continue;
700f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
701f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		codec = (struct avdtp_media_codec_capability *) cap->data;
702f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
703f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		if (codec->media_codec_type != a2dp_sep->codec) {
704928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			setup->err = g_new(struct avdtp_error, 1);
705928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			avdtp_error_init(setup->err, AVDTP_MEDIA_CODEC,
706928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					AVDTP_UNSUPPORTED_CONFIGURATION);
707928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			goto done;
708f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		}
709f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
71008b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz		ret = media_endpoint_set_configuration(a2dp_sep->endpoint,
71108b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz						setup->dev, codec->data,
71208b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz						cap->length - sizeof(*codec),
71308b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz						endpoint_setconf_cb, setup);
714f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		if (ret)
715928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz			return TRUE;
716f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
717928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz		avdtp_error_init(setup->err, AVDTP_MEDIA_CODEC,
718928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz					AVDTP_UNSUPPORTED_CONFIGURATION);
719928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz		break;
720f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
721f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
722928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentzdone:
723928b5dcda68c166b33638664a5f9f860f1c7c48aLuiz Augusto von Dentz	g_idle_add(auto_config, setup);
724f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	return TRUE;
725f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
726f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
727f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzstatic gboolean endpoint_getcap_ind(struct avdtp *session,
728d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz					struct avdtp_local_sep *sep,
729d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz					gboolean get_all, GSList **caps,
730d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz					uint8_t *err, void *user_data)
731f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
732f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_sep *a2dp_sep = user_data;
733f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct avdtp_service_capability *media_transport, *media_codec;
734f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct avdtp_media_codec_capability *codec_caps;
735f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	uint8_t *capabilities;
736f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	size_t length;
737f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
738f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
739f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		DBG("Sink %p: Get_Capability_Ind", sep);
740f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else
741f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		DBG("Source %p: Get_Capability_Ind", sep);
742f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
743f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	*caps = NULL;
744f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
745f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
746f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz						NULL, 0);
747f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
748f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	*caps = g_slist_append(*caps, media_transport);
749f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
750f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	length = media_endpoint_get_capabilities(a2dp_sep->endpoint,
751f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz						&capabilities);
752f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
753f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	codec_caps = g_malloc0(sizeof(*codec_caps) + length);
754f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	codec_caps->media_type = AVDTP_MEDIA_TYPE_AUDIO;
755f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	codec_caps->media_codec_type = a2dp_sep->codec;
756f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	memcpy(codec_caps->data, capabilities, length);
757f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
758f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, codec_caps,
759f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz						sizeof(*codec_caps) + length);
760f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
761f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	*caps = g_slist_append(*caps, media_codec);
762f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	g_free(codec_caps);
763f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
764f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (get_all) {
765f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		struct avdtp_service_capability *delay_reporting;
766f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		delay_reporting = avdtp_service_cap_new(AVDTP_DELAY_REPORTING,
767f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz								NULL, 0);
768f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		*caps = g_slist_append(*caps, delay_reporting);
769f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
770f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
771f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	return TRUE;
772f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
773f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
77448f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentzstatic void endpoint_open_cb(struct media_endpoint *endpoint, void *ret,
77548f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz						int size, void *user_data)
77648f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz{
77748f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz	struct a2dp_setup *setup = user_data;
77848f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz	int err;
77948f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz
78048f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz	if (ret == NULL) {
78148f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz		setup->stream = NULL;
78201a3858e8cfef34cde0e7af85602523bb45cf8f5Luiz Augusto von Dentz		finalize_setup_errno(setup, -EPERM, finalize_config, NULL);
78348f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz		return;
78448f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz	}
78548f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz
78648f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz	err = avdtp_open(setup->session, setup->stream);
78748f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz	if (err == 0)
78848f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz		return;
78948f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz
79048f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz	error("Error on avdtp_open %s (%d)", strerror(-err), -err);
79148f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz	setup->stream = NULL;
79201a3858e8cfef34cde0e7af85602523bb45cf8f5Luiz Augusto von Dentz	finalize_setup_errno(setup, err, finalize_config, NULL);
79348f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz}
79448f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz
795f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
7960f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg				struct avdtp_stream *stream,
797666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_error *err, void *user_data)
7986763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
799666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
8002934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
801caf9fdd6d0183afc3b21d1cd82eb637773c131deMarcel Holtmann	struct audio_device *dev;
8020f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	int ret;
803cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
804666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
8058e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Set_Configuration_Cfm", sep);
806666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
8078e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Set_Configuration_Cfm", sep);
808cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
80903490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
81003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
8110f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (err) {
8125309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		if (setup) {
8135309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz			setup->err = err;
8145309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz			finalize_config(setup);
8155309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		}
8160f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		return;
8170f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	}
8180f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg
8197a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep);
820c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	a2dp_sep->stream = stream;
821cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
822cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!setup)
823cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return;
824cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
825fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	dev = a2dp_get_dev(session);
826fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg
827f79bab5a11c34f46150544aa5742616fddeb0195João Paulo Rechi Vita	/* Notify D-Bus interface of the new stream */
828f79bab5a11c34f46150544aa5742616fddeb0195João Paulo Rechi Vita	if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE)
829f79bab5a11c34f46150544aa5742616fddeb0195João Paulo Rechi Vita		sink_new_stream(dev, session, setup->stream);
830f79bab5a11c34f46150544aa5742616fddeb0195João Paulo Rechi Vita	else
831f79bab5a11c34f46150544aa5742616fddeb0195João Paulo Rechi Vita		source_new_stream(dev, session, setup->stream);
83267d1e1774b3ff2d7a09fcf49484515bd85c02d14Johan Hedberg
833f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	/* Notify Endpoint */
834f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (a2dp_sep->endpoint) {
835f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		struct avdtp_service_capability *service;
836f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		struct avdtp_media_codec_capability *codec;
837f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
838f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		service = avdtp_stream_get_codec(stream);
839f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		codec = (struct avdtp_media_codec_capability *) service->data;
840f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
841f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		if (media_endpoint_set_configuration(a2dp_sep->endpoint, dev,
842f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz						codec->data, service->length -
84348f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz						sizeof(*codec),
84448f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz						endpoint_open_cb, setup) ==
84548f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz						TRUE)
84648f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz			return;
84748f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz
84848f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz		setup->stream = NULL;
84901a3858e8cfef34cde0e7af85602523bb45cf8f5Luiz Augusto von Dentz		finalize_setup_errno(setup, -EPERM, finalize_config, NULL);
85048f433e7e41fbdf4b12d31c75fd9d5deb36ce4bdLuiz Augusto von Dentz		return;
851f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
852f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
8530f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	ret = avdtp_open(session, stream);
8540f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (ret < 0) {
855924cbd78506f876296a47f63579977db4b2ffe9dJohan Hedberg		error("Error on avdtp_open %s (%d)", strerror(-ret), -ret);
8567a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		setup->stream = NULL;
85701a3858e8cfef34cde0e7af85602523bb45cf8f5Luiz Augusto von Dentz		finalize_setup_errno(setup, ret, finalize_config, NULL);
858cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
8596763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
8606763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
861f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean getconf_ind(struct avdtp *session, struct avdtp_local_sep *sep,
862666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				uint8_t *err, void *user_data)
8636763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
864666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
865666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
866666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
8678e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Get_Configuration_Ind", sep);
8686763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
8698e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Get_Configuration_Ind", sep);
8706763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
8716763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
8726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
873f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void getconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
874666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
875666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
8766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
877666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
878666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
879666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
8808e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Set_Configuration_Cfm", sep);
8816763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
8828e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Set_Configuration_Cfm", sep);
8836763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
8846763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
885f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean open_ind(struct avdtp *session, struct avdtp_local_sep *sep,
886666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
887666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
8886763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
889666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
890666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
891666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
8928e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Open_Ind", sep);
8936763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
8948e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Open_Ind", sep);
8956763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
8966763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
8976763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
898f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void open_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
899666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
900666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
9016763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
902666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
9032934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
904666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
905666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
9068e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Open_Cfm", sep);
9076763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
9088e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Open_Cfm", sep);
9091addff77624b54445c9b81779ddc78892a126a45Johan Hedberg
91003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
911cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!setup)
9121addff77624b54445c9b81779ddc78892a126a45Johan Hedberg		return;
9131addff77624b54445c9b81779ddc78892a126a45Johan Hedberg
9142934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (setup->reconfigure)
9152934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup->reconfigure = FALSE;
9162934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
9170f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (err) {
9180f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		setup->stream = NULL;
9195309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
9205402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
921d78f1f6ca28f2744af70bf189837e4c1b06b4eb8Johan Hedberg
922d78f1f6ca28f2744af70bf189837e4c1b06b4eb8Johan Hedberg	finalize_config(setup);
9236763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
9246763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
925c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedbergstatic gboolean suspend_timeout(struct a2dp_sep *sep)
926c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg{
927c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	if (avdtp_suspend(sep->session, sep->stream) == 0)
928c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg		sep->suspending = TRUE;
929c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
9307a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	sep->suspend_timer = 0;
931c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
932c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	avdtp_unref(sep->session);
933c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	sep->session = NULL;
934c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
935c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	return FALSE;
936c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg}
937c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
938f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean start_ind(struct avdtp *session, struct avdtp_local_sep *sep,
939666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
940666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
9416763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
942666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
943df8226b1584a200a81bea35e41d36f03fbafe408Johan Hedberg	struct a2dp_setup *setup;
944c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
945666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
9468e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Start_Ind", sep);
947666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
9488e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Start_Ind", sep);
9495b5cfaadb312600c58362617080e29fbf036712cJohan Hedberg
950df8226b1584a200a81bea35e41d36f03fbafe408Johan Hedberg	setup = find_setup_by_session(session);
951f8d790861cf7e02576b4b03455748567e05f942fLuiz Augusto von Dentz	if (setup)
952f8d790861cf7e02576b4b03455748567e05f942fLuiz Augusto von Dentz		finalize_resume(setup);
953df8226b1584a200a81bea35e41d36f03fbafe408Johan Hedberg
954f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg	if (!a2dp_sep->locked) {
955f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg		a2dp_sep->session = avdtp_ref(session);
9567ec871d37de442fd3731a0eef319851c61fb04ccLuiz Augusto von Dentz		a2dp_sep->suspend_timer = g_timeout_add_seconds(SUSPEND_TIMEOUT,
957c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg						(GSourceFunc) suspend_timeout,
958c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg						a2dp_sep);
959f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg	}
960f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg
961c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	return TRUE;
9626763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
9636763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
964f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void start_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
965666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
966666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
9676763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
968666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
9692934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
970666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
971666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
9728e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Start_Cfm", sep);
9736763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
9748e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Start_Cfm", sep);
975cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
97603490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
977cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!setup)
978cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return;
979cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
980847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	if (err) {
9810f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		setup->stream = NULL;
9825309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
983847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	}
984d78f1f6ca28f2744af70bf189837e4c1b06b4eb8Johan Hedberg
985d78f1f6ca28f2744af70bf189837e4c1b06b4eb8Johan Hedberg	finalize_resume(setup);
9866763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
9876763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
988f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean suspend_ind(struct avdtp *session, struct avdtp_local_sep *sep,
989666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
990666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
9916763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
992666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
993666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
994666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
9958e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Suspend_Ind", sep);
9966763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
9978e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Suspend_Ind", sep);
998d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg
999d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg	if (a2dp_sep->suspend_timer) {
1000d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg		g_source_remove(a2dp_sep->suspend_timer);
100186898be87d24991e48d783b3e20696ff1ce62abcJohan Hedberg		a2dp_sep->suspend_timer = 0;
1002f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg		avdtp_unref(a2dp_sep->session);
1003f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg		a2dp_sep->session = NULL;
1004d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg	}
1005d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg
10066763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
10076763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
10086763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1009f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void suspend_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
1010666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
1011666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
10126763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
1013666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
10142934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
10153f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	gboolean start;
1016d4bbb4b3baed2293f1ed71887910712843a70939Luiz Augusto von Dentz	int perr;
1017c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
1018666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
10198e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Suspend_Cfm", sep);
1020666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
10218e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Suspend_Cfm", sep);
1022cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1023c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	a2dp_sep->suspending = FALSE;
1024cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
102503490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
102603490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	if (!setup)
102703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg		return;
102803490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
10293f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	start = setup->start;
10303f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	setup->start = FALSE;
10313f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg
10320f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (err) {
10332934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup->stream = NULL;
10345309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
1035cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
1036d4bbb4b3baed2293f1ed71887910712843a70939Luiz Augusto von Dentz
1037d4bbb4b3baed2293f1ed71887910712843a70939Luiz Augusto von Dentz	finalize_suspend(setup);
10383f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg
10393f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	if (!start)
10403f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg		return;
10413f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg
10425309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	if (err) {
1043d4bbb4b3baed2293f1ed71887910712843a70939Luiz Augusto von Dentz		finalize_resume(setup);
1044d4bbb4b3baed2293f1ed71887910712843a70939Luiz Augusto von Dentz		return;
1045d4bbb4b3baed2293f1ed71887910712843a70939Luiz Augusto von Dentz	}
1046d4bbb4b3baed2293f1ed71887910712843a70939Luiz Augusto von Dentz
1047d4bbb4b3baed2293f1ed71887910712843a70939Luiz Augusto von Dentz	perr = avdtp_start(session, a2dp_sep->stream);
1048d4bbb4b3baed2293f1ed71887910712843a70939Luiz Augusto von Dentz	if (perr < 0) {
1049d4bbb4b3baed2293f1ed71887910712843a70939Luiz Augusto von Dentz		error("Error on avdtp_start %s (%d)", strerror(-perr), -perr);
105001a3858e8cfef34cde0e7af85602523bb45cf8f5Luiz Augusto von Dentz		finalize_setup_errno(setup, -EIO, finalize_suspend, NULL);
10513f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	}
10526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
10536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1054f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean close_ind(struct avdtp *session, struct avdtp_local_sep *sep,
1055666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
1056666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
10576763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
1058666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
10593e71cabf0edb511c452663710ed07d29b676933fLuiz Augusto von Dentz	struct a2dp_setup *setup;
1060c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
1061666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
10628e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Close_Ind", sep);
1063666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
10648e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Close_Ind", sep);
1065cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
10663e71cabf0edb511c452663710ed07d29b676933fLuiz Augusto von Dentz	setup = find_setup_by_session(session);
10673e71cabf0edb511c452663710ed07d29b676933fLuiz Augusto von Dentz	if (!setup)
10683e71cabf0edb511c452663710ed07d29b676933fLuiz Augusto von Dentz		return TRUE;
10693e71cabf0edb511c452663710ed07d29b676933fLuiz Augusto von Dentz
1070b3938c224f0baf5c09c63f9c55352fe61b241574Luiz Augusto von Dentz	finalize_setup_errno(setup, -ECONNRESET, finalize_suspend,
107101a3858e8cfef34cde0e7af85602523bb45cf8f5Luiz Augusto von Dentz							finalize_resume, NULL);
10723e71cabf0edb511c452663710ed07d29b676933fLuiz Augusto von Dentz
10736763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
10746763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
10756763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1076714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentzstatic gboolean a2dp_reconfigure(gpointer data)
10772934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
10782934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup = data;
1079f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_sep *sep = setup->sep;
10802934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	int posix_err;
1081e70fb63e463316ada715c1dbc03e2665c0009028Arun Raghavan	struct avdtp_media_codec_capability *rsep_codec;
1082e70fb63e463316ada715c1dbc03e2665c0009028Arun Raghavan	struct avdtp_service_capability *cap;
10832934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1084e70fb63e463316ada715c1dbc03e2665c0009028Arun Raghavan	if (setup->rsep) {
1085e70fb63e463316ada715c1dbc03e2665c0009028Arun Raghavan		cap = avdtp_get_codec(setup->rsep);
1086e70fb63e463316ada715c1dbc03e2665c0009028Arun Raghavan		rsep_codec = (struct avdtp_media_codec_capability *) cap->data;
1087e70fb63e463316ada715c1dbc03e2665c0009028Arun Raghavan	}
1088e70fb63e463316ada715c1dbc03e2665c0009028Arun Raghavan
1089e70fb63e463316ada715c1dbc03e2665c0009028Arun Raghavan	if (!setup->rsep || sep->codec != rsep_codec->media_codec_type)
10906b30e2e4d4e0c1b9b84ad0c3ad2f9bfd2da6e94dJohn Crosbie		setup->rsep = avdtp_find_remote_sep(setup->session, sep->lsep);
10916b30e2e4d4e0c1b9b84ad0c3ad2f9bfd2da6e94dJohn Crosbie
1092f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	posix_err = avdtp_set_configuration(setup->session, setup->rsep,
1093f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz						sep->lsep,
1094daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz						setup->caps,
10952934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz						&setup->stream);
10962934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (posix_err < 0) {
1097c2a07d4a29dba7b936744a9b5c42c886f478abfcLuiz Augusto von Dentz		error("avdtp_set_configuration: %s", strerror(-posix_err));
1098c2a07d4a29dba7b936744a9b5c42c886f478abfcLuiz Augusto von Dentz		goto failed;
10992934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
11002934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
11012934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return FALSE;
1102c2a07d4a29dba7b936744a9b5c42c886f478abfcLuiz Augusto von Dentz
1103c2a07d4a29dba7b936744a9b5c42c886f478abfcLuiz Augusto von Dentzfailed:
110401a3858e8cfef34cde0e7af85602523bb45cf8f5Luiz Augusto von Dentz	finalize_setup_errno(setup, posix_err, finalize_config, NULL);
1105c2a07d4a29dba7b936744a9b5c42c886f478abfcLuiz Augusto von Dentz	return FALSE;
11062934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
11072934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1108f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void close_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
1109666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
1110666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
11116763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
1112666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
11132934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
1114c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
1115666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
11168e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Close_Cfm", sep);
1117666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
11188e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Close_Cfm", sep);
11195402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
112003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
11215402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (!setup)
11225402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return;
11235402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
11245402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (err) {
11255402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		setup->stream = NULL;
11265309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
11275309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		finalize_config(setup);
1128847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg		return;
11295402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
11305402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
1131de96fcd89917168170a3b479c3bf094b6a5de67aJohan Hedberg	if (!setup->rsep)
1132de96fcd89917168170a3b479c3bf094b6a5de67aJohan Hedberg		setup->rsep = avdtp_stream_get_remote_sep(stream);
1133de96fcd89917168170a3b479c3bf094b6a5de67aJohan Hedberg
11342934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (setup->reconfigure)
1135fe5de84c0db9e7108000fe1b7a7136528b8f27d9Johan Hedberg		g_timeout_add(RECONFIGURE_TIMEOUT, a2dp_reconfigure, setup);
11366763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
11376763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1138f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean abort_ind(struct avdtp *session, struct avdtp_local_sep *sep,
1139666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
1140666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
11416763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
1142666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
1143c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
1144666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
11458e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Abort_Ind", sep);
1146666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
11478e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Abort_Ind", sep);
1148cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1149fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	a2dp_sep->stream = NULL;
115003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
11516763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
11526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
11536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1154f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void abort_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
1155666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
1156666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
11576763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
1158666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
11592934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
1160c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
1161666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
11628e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: Abort_Cfm", sep);
1163666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
11648e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: Abort_Cfm", sep);
11652934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
11662934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup = find_setup_by_session(session);
11672934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (!setup)
11682934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		return;
11692934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
11702934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_unref(setup);
11716763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
11726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1173f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean reconf_ind(struct avdtp *session, struct avdtp_local_sep *sep,
1174666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				uint8_t *err, void *user_data)
11756763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
1176666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
1177666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1178666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
11798e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: ReConfigure_Ind", sep);
11806763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
11818e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: ReConfigure_Ind", sep);
1182bac81ba536a0d77154e01a71b8bb1bd1712d42f6Johan Hedberg
11836763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
11846763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
11856763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
11865f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedbergstatic gboolean delayreport_ind(struct avdtp *session,
11875f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg				struct avdtp_local_sep *sep,
11885f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg				uint8_t rseid, uint16_t delay,
11895f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg				uint8_t *err, void *user_data)
11905f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg{
11915f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
11925f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	struct audio_device *dev = a2dp_get_dev(session);
11935f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg
11945f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
11958e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: DelayReport_Ind", sep);
11965f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	else
11978e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: DelayReport_Ind", sep);
11985f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg
11995f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	unix_delay_report(dev, rseid, delay);
12005f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg
12015f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	return TRUE;
12025f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg}
12035f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg
1204d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentzstatic gboolean endpoint_delayreport_ind(struct avdtp *session,
1205d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz						struct avdtp_local_sep *sep,
1206d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz						uint8_t rseid, uint16_t delay,
1207d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz						uint8_t *err, void *user_data)
1208d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz{
1209d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz	struct a2dp_sep *a2dp_sep = user_data;
1210d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz	struct media_transport *transport;
1211d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz
1212d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
1213d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz		DBG("Sink %p: DelayReport_Ind", sep);
1214d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz	else
1215d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz		DBG("Source %p: DelayReport_Ind", sep);
1216d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz
1217d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz	transport = media_endpoint_get_transport(a2dp_sep->endpoint);
1218d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz	if (transport == NULL)
1219d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz		return FALSE;
1220d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz
1221d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz	media_transport_update_delay(transport, delay);
1222d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz
1223d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz	return TRUE;
1224d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz}
1225d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz
12260f458da19471c933a4105cc450c48548b72edc8eJohan Hedbergstatic void reconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
1227666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
1228666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
12296763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
1230666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
12312934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
1232666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1233666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
12348e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: ReConfigure_Cfm", sep);
12356763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
12368e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: ReConfigure_Cfm", sep);
12375402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
123803490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
12395402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (!setup)
12405402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return;
12415402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
12425402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (err) {
12435402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		setup->stream = NULL;
12445309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
12455402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
1246d78f1f6ca28f2744af70bf189837e4c1b06b4eb8Johan Hedberg
1247d78f1f6ca28f2744af70bf189837e4c1b06b4eb8Johan Hedberg	finalize_config(setup);
12486763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
12496763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
12505f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedbergstatic void delay_report_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
12515f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg				struct avdtp_stream *stream,
12525f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg				struct avdtp_error *err, void *user_data)
12535f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg{
12545f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
12555f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg
12565f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
12578e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Sink %p: DelayReport_Cfm", sep);
12585f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	else
12598e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("Source %p: DelayReport_Cfm", sep);
12605f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg}
12615f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg
12626763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic struct avdtp_sep_cfm cfm = {
12636763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.set_configuration	= setconf_cfm,
12646763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.get_configuration	= getconf_cfm,
12656763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.open			= open_cfm,
12666763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.start			= start_cfm,
12676763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.suspend		= suspend_cfm,
12686763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.close			= close_cfm,
12696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.abort			= abort_cfm,
12705f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	.reconfigure		= reconf_cfm,
12715f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	.delay_report		= delay_report_cfm,
12726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg};
12736763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1274489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentzstatic struct avdtp_sep_ind sbc_ind = {
1275489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.get_capability		= sbc_getcap_ind,
1276489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.set_configuration	= sbc_setconf_ind,
1277489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.get_configuration	= getconf_ind,
1278489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.open			= open_ind,
1279489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.start			= start_ind,
1280489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.suspend		= suspend_ind,
1281489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.close			= close_ind,
1282489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.abort			= abort_ind,
12835f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	.reconfigure		= reconf_ind,
12845f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	.delayreport		= delayreport_ind,
1285489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz};
1286489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
1287489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentzstatic struct avdtp_sep_ind mpeg_ind = {
1288489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.get_capability		= mpeg_getcap_ind,
1289489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.set_configuration	= mpeg_setconf_ind,
12906763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.get_configuration	= getconf_ind,
12916763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.open			= open_ind,
12926763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.start			= start_ind,
12936763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.suspend		= suspend_ind,
12946763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.close			= close_ind,
12956763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.abort			= abort_ind,
12965f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	.reconfigure		= reconf_ind,
12975f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	.delayreport		= delayreport_ind,
12986763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg};
12996763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1300f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzstatic struct avdtp_sep_ind endpoint_ind = {
1301f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	.get_capability		= endpoint_getcap_ind,
1302f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	.set_configuration	= endpoint_setconf_ind,
1303f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	.get_configuration	= getconf_ind,
1304f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	.open			= open_ind,
1305f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	.start			= start_ind,
1306f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	.suspend		= suspend_ind,
1307f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	.close			= close_ind,
1308f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	.abort			= abort_ind,
1309f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	.reconfigure		= reconf_ind,
1310d19ec4d20c0d0498e54233aba1e7d200471eb088Luiz Augusto von Dentz	.delayreport		= endpoint_delayreport_ind,
1311f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz};
1312f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
13135f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedbergstatic sdp_record_t *a2dp_record(uint8_t type, uint16_t avdtp_ver)
13146763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
13156763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
13161340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	uuid_t root_uuid, l2cap_uuid, avdtp_uuid, a2dp_uuid;
13176763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_profile_desc_t profile[1];
13186763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_t *aproto, *proto[2];
13197299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_record_t *record;
13206763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_data_t *psm, *version, *features;
1321aec344ca67c386af667940545bb62946c092bfcfJohan Hedberg	uint16_t lp = AVDTP_UUID;
13225f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	uint16_t a2dp_ver = 0x0102, feat = 0x000f;
13236763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
13248e61c8e21bc24d9c50ff98c11bbbec49a7442bf1Jaikumar Ganesh#ifdef ANDROID
13258e61c8e21bc24d9c50ff98c11bbbec49a7442bf1Jaikumar Ganesh	feat = 0x0001;
13268e61c8e21bc24d9c50ff98c11bbbec49a7442bf1Jaikumar Ganesh#endif
13277299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	record = sdp_record_alloc();
13287299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	if (!record)
13297299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz		return NULL;
13306763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
13316763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
13326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	root = sdp_list_append(0, &root_uuid);
13337299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_set_browse_groups(record, root);
13346763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
13351340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	if (type == AVDTP_SEP_TYPE_SOURCE)
13361340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita		sdp_uuid16_create(&a2dp_uuid, AUDIO_SOURCE_SVCLASS_ID);
13371340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	else
13381340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita		sdp_uuid16_create(&a2dp_uuid, AUDIO_SINK_SVCLASS_ID);
13391340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	svclass_id = sdp_list_append(0, &a2dp_uuid);
13407299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_set_service_classes(record, svclass_id);
13416763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
13426763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID);
1343aec344ca67c386af667940545bb62946c092bfcfJohan Hedberg	profile[0].version = a2dp_ver;
13446763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	pfseq = sdp_list_append(0, &profile[0]);
13457299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_set_profile_descs(record, pfseq);
13466763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
13471340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	sdp_uuid16_create(&l2cap_uuid, L2CAP_UUID);
13481340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	proto[0] = sdp_list_append(0, &l2cap_uuid);
13496763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	psm = sdp_data_alloc(SDP_UINT16, &lp);
13506763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	proto[0] = sdp_list_append(proto[0], psm);
13516763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	apseq = sdp_list_append(0, proto[0]);
13526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
13531340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	sdp_uuid16_create(&avdtp_uuid, AVDTP_UUID);
13541340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	proto[1] = sdp_list_append(0, &avdtp_uuid);
1355aec344ca67c386af667940545bb62946c092bfcfJohan Hedberg	version = sdp_data_alloc(SDP_UINT16, &avdtp_ver);
13566763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	proto[1] = sdp_list_append(proto[1], version);
13576763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	apseq = sdp_list_append(apseq, proto[1]);
13586763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
13596763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	aproto = sdp_list_append(0, apseq);
13607299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_set_access_protos(record, aproto);
13616763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
13626763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	features = sdp_data_alloc(SDP_UINT16, &feat);
13637299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features);
13646763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
13651340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	if (type == AVDTP_SEP_TYPE_SOURCE)
13661340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita		sdp_set_info_attr(record, "Audio Source", 0, 0);
13671340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	else
13681340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita		sdp_set_info_attr(record, "Audio Sink", 0, 0);
13696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
13706763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	free(psm);
13716763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	free(version);
13726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(proto[0], 0);
13736763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(proto[1], 0);
13746763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(apseq, 0);
13756763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(pfseq, 0);
13766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(aproto, 0);
13776763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(root, 0);
13786763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(svclass_id, 0);
13796763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
13807299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	return record;
13816763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
13826763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1383957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentzstatic struct a2dp_server *find_server(GSList *list, const bdaddr_t *src)
1384957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz{
1385957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
138624c6dee3b307cbf9e99dfdb875895f410120ec41Szymon Janc	for (; list; list = list->next) {
138724c6dee3b307cbf9e99dfdb875895f410120ec41Szymon Janc		struct a2dp_server *server = list->data;
1388957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1389957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		if (bacmp(&server->src, src) == 0)
1390957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz			return server;
1391957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	}
1392957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1393957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	return NULL;
1394957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz}
1395957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1396957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentzint a2dp_register(DBusConnection *conn, const bdaddr_t *src, GKeyFile *config)
1397666938b54d631956826343ed278e2af4b982fc29Johan Hedberg{
139831f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita	int sbc_srcs = 1, sbc_sinks = 1;
13995b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	int mpeg12_srcs = 0, mpeg12_sinks = 0;
14008a7db32ff944cd51ac879d02bf9ec56c25800c66Johan Hedberg	gboolean source = TRUE, sink = FALSE, socket = TRUE;
14018a7db32ff944cd51ac879d02bf9ec56c25800c66Johan Hedberg	gboolean delay_reporting = FALSE;
14025b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	char *str;
14035b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	GError *err = NULL;
1404e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedberg	int i;
1405957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	struct a2dp_server *server;
1406e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedberg
14075b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (!config)
14085b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		goto proceed;
14095b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
141031f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita	str = g_key_file_get_string(config, "General", "Enable", &err);
141131f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita
141231f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita	if (err) {
14138e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("audio.conf: %s", err->message);
141431f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita		g_clear_error(&err);
141531f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita	} else {
141631f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita		if (strstr(str, "Sink"))
141731f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita			source = TRUE;
141831f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita		if (strstr(str, "Source"))
141931f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita			sink = TRUE;
142031f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita		g_free(str);
142131f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita	}
142231f80fc571a2e1ac0ffafa649bb90992839416a6João Paulo Rechi Vita
14235b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	str = g_key_file_get_string(config, "General", "Disable", &err);
14245b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
14255b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (err) {
14268e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("audio.conf: %s", err->message);
1427bd4494363230705c3efaa13f3c94a73fadab88e4Johan Hedberg		g_clear_error(&err);
14285b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	} else {
14295b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		if (strstr(str, "Sink"))
14307e64674f8b5c5be6b3cccb17ea05766763d50f94Johan Hedberg			source = FALSE;
14315b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		if (strstr(str, "Source"))
14327e64674f8b5c5be6b3cccb17ea05766763d50f94Johan Hedberg			sink = FALSE;
1433b5251802a1aa4c23286b7b54a58ea8ea8bd9ce51Luiz Augusto von Dentz		if (strstr(str, "Socket"))
1434b5251802a1aa4c23286b7b54a58ea8ea8bd9ce51Luiz Augusto von Dentz			socket = FALSE;
14355b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_free(str);
14365b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	}
14375b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
1438b5251802a1aa4c23286b7b54a58ea8ea8bd9ce51Luiz Augusto von Dentz	/* Don't register any local sep if Socket is disabled */
1439b5251802a1aa4c23286b7b54a58ea8ea8bd9ce51Luiz Augusto von Dentz	if (socket == FALSE) {
1440b5251802a1aa4c23286b7b54a58ea8ea8bd9ce51Luiz Augusto von Dentz		sbc_srcs = 0;
1441b5251802a1aa4c23286b7b54a58ea8ea8bd9ce51Luiz Augusto von Dentz		sbc_sinks = 0;
1442b5251802a1aa4c23286b7b54a58ea8ea8bd9ce51Luiz Augusto von Dentz		mpeg12_srcs = 0;
1443b5251802a1aa4c23286b7b54a58ea8ea8bd9ce51Luiz Augusto von Dentz		mpeg12_sinks = 0;
1444b5251802a1aa4c23286b7b54a58ea8ea8bd9ce51Luiz Augusto von Dentz		goto proceed;
1445b5251802a1aa4c23286b7b54a58ea8ea8bd9ce51Luiz Augusto von Dentz	}
1446b5251802a1aa4c23286b7b54a58ea8ea8bd9ce51Luiz Augusto von Dentz
14475b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	str = g_key_file_get_string(config, "A2DP", "SBCSources", &err);
14485b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (err) {
14498e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("audio.conf: %s", err->message);
1450bd4494363230705c3efaa13f3c94a73fadab88e4Johan Hedberg		g_clear_error(&err);
14515b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	} else {
14525b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		sbc_srcs = atoi(str);
14535b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_free(str);
14545b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	}
14555b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
14565b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	str = g_key_file_get_string(config, "A2DP", "MPEG12Sources", &err);
14575b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (err) {
14588e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("audio.conf: %s", err->message);
1459bd4494363230705c3efaa13f3c94a73fadab88e4Johan Hedberg		g_clear_error(&err);
14605b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	} else {
14615b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		mpeg12_srcs = atoi(str);
14625b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_free(str);
14635b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	}
14645b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
14655b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	str = g_key_file_get_string(config, "A2DP", "SBCSinks", &err);
14665b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (err) {
14678e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("audio.conf: %s", err->message);
1468bd4494363230705c3efaa13f3c94a73fadab88e4Johan Hedberg		g_clear_error(&err);
14695b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	} else {
14705b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		sbc_sinks = atoi(str);
14715b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_free(str);
14725b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	}
14735b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
14745b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	str = g_key_file_get_string(config, "A2DP", "MPEG12Sinks", &err);
14755b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (err) {
14768e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan		DBG("audio.conf: %s", err->message);
1477bd4494363230705c3efaa13f3c94a73fadab88e4Johan Hedberg		g_clear_error(&err);
14785b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	} else {
14795b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		mpeg12_sinks = atoi(str);
14805b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_free(str);
14815b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	}
14826763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
14835b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentzproceed:
1484957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (!connection)
1485957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		connection = dbus_connection_ref(conn);
1486957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1487957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	server = find_server(servers, src);
1488957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (!server) {
1489501b5d1a8afbaa56761dd5473e8d5169997b71ddLuiz Augusto von Dentz		int av_err;
1490501b5d1a8afbaa56761dd5473e8d5169997b71ddLuiz Augusto von Dentz
1491957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		server = g_new0(struct a2dp_server, 1);
1492957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		if (!server)
1493957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz			return -ENOMEM;
1494501b5d1a8afbaa56761dd5473e8d5169997b71ddLuiz Augusto von Dentz
14955f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		av_err = avdtp_init(src, config, &server->version);
14962e926fb0168ba0249dfbbcca71ff685e4235e1c7Steve Grubb		if (av_err < 0) {
14972e926fb0168ba0249dfbbcca71ff685e4235e1c7Steve Grubb			g_free(server);
1498501b5d1a8afbaa56761dd5473e8d5169997b71ddLuiz Augusto von Dentz			return av_err;
14992e926fb0168ba0249dfbbcca71ff685e4235e1c7Steve Grubb		}
1500501b5d1a8afbaa56761dd5473e8d5169997b71ddLuiz Augusto von Dentz
1501957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		bacpy(&server->src, src);
1502957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		servers = g_slist_append(servers, server);
1503957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	}
15046763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
15058a7db32ff944cd51ac879d02bf9ec56c25800c66Johan Hedberg	if (config)
15068a7db32ff944cd51ac879d02bf9ec56c25800c66Johan Hedberg		delay_reporting = g_key_file_get_boolean(config, "A2DP",
15075f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg						"DelayReporting", NULL);
15088a7db32ff944cd51ac879d02bf9ec56c25800c66Johan Hedberg
15095f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	if (delay_reporting)
15105f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		server->version = 0x0103;
15115f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg	else
15125f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg		server->version = 0x0102;
15135f8a274881a823ea51df7a62ca17948b1f4ebe63Johan Hedberg
15144c07eae01d5fc6f80f88d27bbcaa2effe73ef325Dmitriy Paliy	server->source_enabled = source;
15157e64674f8b5c5be6b3cccb17ea05766763d50f94Johan Hedberg	if (source) {
15165b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		for (i = 0; i < sbc_srcs; i++)
1517f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			a2dp_add_sep(src, AVDTP_SEP_TYPE_SOURCE,
15182da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy				A2DP_CODEC_SBC, delay_reporting, NULL, NULL);
15195b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
15205b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		for (i = 0; i < mpeg12_srcs; i++)
1521f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			a2dp_add_sep(src, AVDTP_SEP_TYPE_SOURCE,
15222da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy					A2DP_CODEC_MPEG12, delay_reporting,
15232da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy					NULL, NULL);
1524489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	}
15254c07eae01d5fc6f80f88d27bbcaa2effe73ef325Dmitriy Paliy	server->sink_enabled = sink;
15265b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (sink) {
15275b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		for (i = 0; i < sbc_sinks; i++)
1528f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			a2dp_add_sep(src, AVDTP_SEP_TYPE_SINK,
15292da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy				A2DP_CODEC_SBC, delay_reporting, NULL, NULL);
15305b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
15315b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		for (i = 0; i < mpeg12_sinks; i++)
1532f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			a2dp_add_sep(src, AVDTP_SEP_TYPE_SINK,
1533f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz					A2DP_CODEC_MPEG12, delay_reporting,
15342da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy					NULL, NULL);
1535489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	}
15366763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
15376763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return 0;
15386763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
15396763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1540666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic void a2dp_unregister_sep(struct a2dp_sep *sep)
1541666938b54d631956826343ed278e2af4b982fc29Johan Hedberg{
1542fe0f3fab1809cdc397b7d8dd41fb0ceed3e73a6cLuiz Augusto von Dentz	if (sep->endpoint) {
154380958057369d56d090b90929f85a0e89673a3d5cLuiz Augusto von Dentz		media_endpoint_release(sep->endpoint);
1544fe0f3fab1809cdc397b7d8dd41fb0ceed3e73a6cLuiz Augusto von Dentz		sep->endpoint = NULL;
1545fe0f3fab1809cdc397b7d8dd41fb0ceed3e73a6cLuiz Augusto von Dentz	}
154680958057369d56d090b90929f85a0e89673a3d5cLuiz Augusto von Dentz
1547f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	avdtp_unregister_sep(sep->lsep);
1548666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	g_free(sep);
1549666938b54d631956826343ed278e2af4b982fc29Johan Hedberg}
1550666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1551957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentzvoid a2dp_unregister(const bdaddr_t *src)
15526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
1553957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	struct a2dp_server *server;
15546763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1555957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	server = find_server(servers, src);
1556957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (!server)
1557957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		return;
15586763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1559f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	g_slist_foreach(server->sinks, (GFunc) a2dp_remove_sep, NULL);
1560957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	g_slist_free(server->sinks);
15616763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1562f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	g_slist_foreach(server->sources, (GFunc) a2dp_remove_sep, NULL);
1563957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	g_slist_free(server->sources);
1564957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1565f481e7faa9ced6b2c0fa089f768a9bd9613be640Luiz Augusto von Dentz	avdtp_exit(src);
1566f481e7faa9ced6b2c0fa089f768a9bd9613be640Luiz Augusto von Dentz
1567957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	servers = g_slist_remove(servers, server);
1568957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	g_free(server);
1569957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1570957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (servers)
1571957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		return;
15726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
15736763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	dbus_connection_unref(connection);
1574957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	connection = NULL;
15756763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
15766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1577f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzstruct a2dp_sep *a2dp_add_sep(const bdaddr_t *src, uint8_t type,
1578f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz				uint8_t codec, gboolean delay_reporting,
15792da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy				struct media_endpoint *endpoint, int *err)
1580f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
1581f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_server *server;
1582f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_sep *sep;
1583f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	GSList **l;
1584f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	uint32_t *record_id;
1585f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	sdp_record_t *record;
1586f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct avdtp_sep_ind *ind;
1587f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1588f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	server = find_server(servers, src);
15892da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy	if (server == NULL) {
15902da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy		if (err)
15912da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy			*err = -EINVAL;
1592f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return NULL;
15932da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy	}
1594f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
15952da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy	if (type == AVDTP_SEP_TYPE_SINK && !server->sink_enabled) {
15962da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy		if (err)
15972da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy			*err = -EPROTONOSUPPORT;
15984c07eae01d5fc6f80f88d27bbcaa2effe73ef325Dmitriy Paliy		return NULL;
15992da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy	}
16004c07eae01d5fc6f80f88d27bbcaa2effe73ef325Dmitriy Paliy
16012da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy	if (type == AVDTP_SEP_TYPE_SOURCE && !server->source_enabled) {
16022da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy		if (err)
16032da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy			*err = -EPROTONOSUPPORT;
16044c07eae01d5fc6f80f88d27bbcaa2effe73ef325Dmitriy Paliy		return NULL;
16052da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy	}
16064c07eae01d5fc6f80f88d27bbcaa2effe73ef325Dmitriy Paliy
1607f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	sep = g_new0(struct a2dp_sep, 1);
1608f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1609f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (endpoint) {
1610f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		ind = &endpoint_ind;
1611f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		goto proceed;
1612f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1613f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1614f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	ind = (codec == A2DP_CODEC_MPEG12) ? &mpeg_ind : &sbc_ind;
1615f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1616f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzproceed:
1617f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	sep->lsep = avdtp_register_sep(&server->src, type,
1618f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz					AVDTP_MEDIA_TYPE_AUDIO, codec,
1619f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz					delay_reporting, ind, &cfm, sep);
1620f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (sep->lsep == NULL) {
1621f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		g_free(sep);
16222da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy		if (err)
16232da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy			*err = -EINVAL;
1624f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return NULL;
1625f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1626f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1627f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	sep->server = server;
1628f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	sep->endpoint = endpoint;
1629f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	sep->codec = codec;
1630f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	sep->type = type;
1631f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	sep->delay_reporting = delay_reporting;
1632f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1633f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (type == AVDTP_SEP_TYPE_SOURCE) {
1634f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		l = &server->sources;
1635f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		record_id = &server->source_record_id;
1636f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	} else {
1637f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		l = &server->sinks;
1638f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		record_id = &server->sink_record_id;
1639f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1640f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1641f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (*record_id != 0)
1642f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		goto add;
1643f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1644f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	record = a2dp_record(type, server->version);
1645f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (!record) {
1646f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		error("Unable to allocate new service record");
1647f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		avdtp_unregister_sep(sep->lsep);
1648f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		g_free(sep);
16492da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy		if (err)
16502da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy			*err = -EINVAL;
1651f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return NULL;
1652f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1653f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1654f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (add_record_to_server(&server->src, record) < 0) {
1655f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		error("Unable to register A2DP service record");\
1656f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		sdp_record_free(record);
1657f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		avdtp_unregister_sep(sep->lsep);
1658f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		g_free(sep);
16592da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy		if (err)
16602da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy			*err = -EINVAL;
1661f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return NULL;
1662f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1663f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	*record_id = record->handle;
1664f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1665f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzadd:
1666f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	*l = g_slist_append(*l, sep);
1667f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
16682da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy	if (err)
16692da716f340e99d315a9c773ea95253d583ba2b74Dmitriy Paliy		*err = 0;
1670f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	return sep;
1671f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
1672f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1673f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzvoid a2dp_remove_sep(struct a2dp_sep *sep)
1674f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
1675f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_server *server = sep->server;
1676f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1677f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (sep->type == AVDTP_SEP_TYPE_SOURCE) {
167880958057369d56d090b90929f85a0e89673a3d5cLuiz Augusto von Dentz		if (g_slist_find(server->sources, sep) == NULL)
167980958057369d56d090b90929f85a0e89673a3d5cLuiz Augusto von Dentz			return;
1680f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		server->sources = g_slist_remove(server->sources, sep);
1681f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		if (server->sources == NULL && server->source_record_id) {
1682f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			remove_record_from_server(server->source_record_id);
1683f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			server->source_record_id = 0;
1684f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		}
1685f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	} else {
168680958057369d56d090b90929f85a0e89673a3d5cLuiz Augusto von Dentz		if (g_slist_find(server->sinks, sep) == NULL)
168780958057369d56d090b90929f85a0e89673a3d5cLuiz Augusto von Dentz			return;
1688f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		server->sinks = g_slist_remove(server->sinks, sep);
1689f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		if (server->sinks == NULL && server->sink_record_id) {
1690f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			remove_record_from_server(server->sink_record_id);
1691f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			server->sink_record_id = 0;
1692f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		}
1693f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1694f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
16951636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz	if (sep->locked)
16961636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz		return;
16971636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz
1698f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	a2dp_unregister_sep(sep);
1699f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
1700f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
17011340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vitastruct a2dp_sep *a2dp_get(struct avdtp *session,
1702bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz				struct avdtp_remote_sep *rsep)
1703bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz{
1704bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	GSList *l;
1705bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	struct a2dp_server *server;
1706bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	struct avdtp_service_capability *cap;
1707bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	struct avdtp_media_codec_capability *codec_cap = NULL;
1708bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	bdaddr_t src;
1709bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz
1710bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	avdtp_get_peers(session, &src, NULL);
1711bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	server = find_server(servers, &src);
1712bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	if (!server)
1713bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz		return NULL;
1714bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz
1715bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	cap = avdtp_get_codec(rsep);
1716bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	codec_cap = (void *) cap->data;
1717bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz
17181340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	if (avdtp_get_type(rsep) == AVDTP_SEP_TYPE_SINK)
17191340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita		l = server->sources;
17201340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	else
17211340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita		l = server->sinks;
17221340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita
17231340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	for (; l != NULL; l = l->next) {
1724bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz		struct a2dp_sep *sep = l->data;
1725bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz
1726bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz		if (sep->locked)
1727bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz			continue;
1728bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz
1729bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz		if (sep->codec != codec_cap->media_codec_type)
1730bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz			continue;
1731bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz
1732bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz		if (!sep->stream || avdtp_has_stream(session, sep->stream))
1733bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz			return sep;
1734bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	}
1735bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz
1736bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	return NULL;
1737bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz}
1738bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz
1739f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzstatic uint8_t default_bitpool(uint8_t freq, uint8_t mode)
1740f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
1741f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	switch (freq) {
1742f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	case SBC_SAMPLING_FREQ_16000:
1743f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	case SBC_SAMPLING_FREQ_32000:
1744f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return 53;
1745f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	case SBC_SAMPLING_FREQ_44100:
1746f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		switch (mode) {
1747f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		case SBC_CHANNEL_MODE_MONO:
1748f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		case SBC_CHANNEL_MODE_DUAL_CHANNEL:
1749f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			return 31;
1750f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		case SBC_CHANNEL_MODE_STEREO:
1751f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		case SBC_CHANNEL_MODE_JOINT_STEREO:
1752f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			return 53;
1753f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		default:
1754f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			error("Invalid channel mode %u", mode);
1755f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			return 53;
1756f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		}
1757f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	case SBC_SAMPLING_FREQ_48000:
1758f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		switch (mode) {
1759f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		case SBC_CHANNEL_MODE_MONO:
1760f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		case SBC_CHANNEL_MODE_DUAL_CHANNEL:
1761f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			return 29;
1762f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		case SBC_CHANNEL_MODE_STEREO:
1763f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		case SBC_CHANNEL_MODE_JOINT_STEREO:
1764f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			return 51;
1765f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		default:
1766f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			error("Invalid channel mode %u", mode);
1767f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			return 51;
1768f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		}
1769f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	default:
1770f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		error("Invalid sampling freq %u", freq);
1771f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return 53;
1772f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1773f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
1774f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1775f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzstatic gboolean select_sbc_params(struct sbc_codec_cap *cap,
1776f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz					struct sbc_codec_cap *supported)
1777f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
1778f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	unsigned int max_bitpool, min_bitpool;
1779f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1780f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	memset(cap, 0, sizeof(struct sbc_codec_cap));
1781f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1782f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	cap->cap.media_type = AVDTP_MEDIA_TYPE_AUDIO;
1783f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	cap->cap.media_codec_type = A2DP_CODEC_SBC;
1784f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1785f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (supported->frequency & SBC_SAMPLING_FREQ_44100)
1786f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->frequency = SBC_SAMPLING_FREQ_44100;
1787f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else if (supported->frequency & SBC_SAMPLING_FREQ_48000)
1788f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->frequency = SBC_SAMPLING_FREQ_48000;
1789f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else if (supported->frequency & SBC_SAMPLING_FREQ_32000)
1790f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->frequency = SBC_SAMPLING_FREQ_32000;
1791f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else if (supported->frequency & SBC_SAMPLING_FREQ_16000)
1792f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->frequency = SBC_SAMPLING_FREQ_16000;
1793f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else {
1794f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		error("No supported frequencies");
1795f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return FALSE;
1796f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1797f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1798f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (supported->channel_mode & SBC_CHANNEL_MODE_JOINT_STEREO)
1799f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->channel_mode = SBC_CHANNEL_MODE_JOINT_STEREO;
1800f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else if (supported->channel_mode & SBC_CHANNEL_MODE_STEREO)
1801f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->channel_mode = SBC_CHANNEL_MODE_STEREO;
1802f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else if (supported->channel_mode & SBC_CHANNEL_MODE_DUAL_CHANNEL)
1803f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->channel_mode = SBC_CHANNEL_MODE_DUAL_CHANNEL;
1804f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else if (supported->channel_mode & SBC_CHANNEL_MODE_MONO)
1805f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->channel_mode = SBC_CHANNEL_MODE_MONO;
1806f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else {
1807f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		error("No supported channel modes");
1808f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return FALSE;
1809f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1810f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1811f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (supported->block_length & SBC_BLOCK_LENGTH_16)
1812f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->block_length = SBC_BLOCK_LENGTH_16;
1813f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else if (supported->block_length & SBC_BLOCK_LENGTH_12)
1814f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->block_length = SBC_BLOCK_LENGTH_12;
1815f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else if (supported->block_length & SBC_BLOCK_LENGTH_8)
1816f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->block_length = SBC_BLOCK_LENGTH_8;
1817f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else if (supported->block_length & SBC_BLOCK_LENGTH_4)
1818f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->block_length = SBC_BLOCK_LENGTH_4;
1819f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else {
1820f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		error("No supported block lengths");
1821f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return FALSE;
1822f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1823f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1824f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (supported->subbands & SBC_SUBBANDS_8)
1825f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->subbands = SBC_SUBBANDS_8;
1826f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else if (supported->subbands & SBC_SUBBANDS_4)
1827f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->subbands = SBC_SUBBANDS_4;
1828f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else {
1829f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		error("No supported subbands");
1830f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return FALSE;
1831f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1832f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1833f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (supported->allocation_method & SBC_ALLOCATION_LOUDNESS)
1834f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->allocation_method = SBC_ALLOCATION_LOUDNESS;
1835f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	else if (supported->allocation_method & SBC_ALLOCATION_SNR)
1836f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		cap->allocation_method = SBC_ALLOCATION_SNR;
1837f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1838f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	min_bitpool = MAX(MIN_BITPOOL, supported->min_bitpool);
1839f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	max_bitpool = MIN(default_bitpool(cap->frequency, cap->channel_mode),
1840f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz							supported->max_bitpool);
1841f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1842f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	cap->min_bitpool = min_bitpool;
1843f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	cap->max_bitpool = max_bitpool;
1844f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1845f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	return TRUE;
1846f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
1847f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1848f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzstatic gboolean select_capabilities(struct avdtp *session,
1849f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz					struct avdtp_remote_sep *rsep,
1850f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz					GSList **caps)
1851f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
1852f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct avdtp_service_capability *media_transport, *media_codec;
1853f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct sbc_codec_cap sbc_cap;
1854f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1855f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	media_codec = avdtp_get_codec(rsep);
1856f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (!media_codec)
1857f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return FALSE;
1858f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1859f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	select_sbc_params(&sbc_cap, (struct sbc_codec_cap *) media_codec->data);
1860f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1861f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
1862f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz						NULL, 0);
1863f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1864f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	*caps = g_slist_append(*caps, media_transport);
1865f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1866f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &sbc_cap,
1867f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz						sizeof(sbc_cap));
1868f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1869f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	*caps = g_slist_append(*caps, media_codec);
1870f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1871f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (avdtp_get_delay_reporting(rsep)) {
1872f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		struct avdtp_service_capability *delay_reporting;
1873f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		delay_reporting = avdtp_service_cap_new(AVDTP_DELAY_REPORTING,
1874f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz								NULL, 0);
1875f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		*caps = g_slist_append(*caps, delay_reporting);
1876f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1877f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1878f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	return TRUE;
1879f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
1880f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1881f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzstatic void select_cb(struct media_endpoint *endpoint, void *ret, int size,
1882f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			void *user_data)
1883f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
1884f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_setup *setup = user_data;
1885f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct avdtp_service_capability *media_transport, *media_codec;
1886f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct avdtp_media_codec_capability *cap;
1887f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1888f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (size < 0) {
1889f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		DBG("Endpoint replied an invalid configuration");
1890f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		goto done;
1891f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1892f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1893f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
1894f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz						NULL, 0);
1895f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1896daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz	setup->caps = g_slist_append(setup->caps, media_transport);
1897f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1898f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	cap = g_malloc0(sizeof(*cap) + size);
1899f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	cap->media_type = AVDTP_MEDIA_TYPE_AUDIO;
1900f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	cap->media_codec_type = setup->sep->codec;
1901f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	memcpy(cap->data, ret, size);
1902f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1903f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, cap,
1904f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz						sizeof(*cap) + size);
1905f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1906daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz	setup->caps = g_slist_append(setup->caps, media_codec);
1907a26b71e72c9c511c511287eeb0fb32e7fb9717f7Luiz Augusto von Dentz	g_free(cap);
1908f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1909f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzdone:
1910daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz	finalize_select(setup);
1911f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
1912f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1913f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzstatic gboolean auto_select(gpointer data)
1914f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
1915f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_setup *setup = data;
1916f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1917daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz	finalize_select(setup);
1918f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1919f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	return FALSE;
1920f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
1921f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1922f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzstatic struct a2dp_sep *a2dp_find_sep(struct avdtp *session, GSList *list,
1923f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz					const char *sender)
1924f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
1925f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	for (; list; list = list->next) {
1926f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		struct a2dp_sep *sep = list->data;
1927f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1928f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		/* Use sender's endpoint if available */
1929f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		if (sender) {
1930f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			const char *name;
1931f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1932f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			if (sep->endpoint == NULL)
1933f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz				continue;
1934f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1935f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			name = media_endpoint_get_sender(sep->endpoint);
1936f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			if (g_strcmp0(sender, name) != 0)
1937f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz				continue;
1938f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		}
1939f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1940f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		if (avdtp_find_remote_sep(session, sep->lsep) == NULL)
1941f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			continue;
1942f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1943f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return sep;
1944f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1945f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1946f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	return NULL;
1947f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
1948f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1949f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzstatic struct a2dp_sep *a2dp_select_sep(struct avdtp *session, uint8_t type,
1950f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz					const char *sender)
1951f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
1952f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_server *server;
1953f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_sep *sep;
1954f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	GSList *l;
1955f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	bdaddr_t src;
1956f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1957f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	avdtp_get_peers(session, &src, NULL);
1958f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	server = find_server(servers, &src);
1959f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (!server)
1960f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return NULL;
1961f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1962f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	l = type == AVDTP_SEP_TYPE_SINK ? server->sources : server->sinks;
1963f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1964f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	/* Check sender's seps first */
1965f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	sep = a2dp_find_sep(session, l, sender);
1966f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (sep != NULL)
1967f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return sep;
1968f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1969f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	return a2dp_find_sep(session, l, NULL);
1970f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
1971f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1972f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzunsigned int a2dp_select_capabilities(struct avdtp *session,
1973f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz					uint8_t type, const char *sender,
1974f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz					a2dp_select_cb_t cb,
1975f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz					void *user_data)
1976f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
1977f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_setup *setup;
1978f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_setup_cb *cb_data;
1979f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct a2dp_sep *sep;
1980f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct avdtp_service_capability *service;
1981f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	struct avdtp_media_codec_capability *codec;
1982f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1983f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	sep = a2dp_select_sep(session, type, sender);
1984f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (!sep) {
1985f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		error("Unable to select SEP");
1986f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return 0;
1987f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
1988f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
198908b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	setup = a2dp_setup_get(session);
199008b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	if (!setup)
199108b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz		return 0;
199208b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz
19930889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	cb_data = setup_cb_new(setup);
1994f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	cb_data->select_cb = cb;
1995f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	cb_data->user_data = user_data;
1996f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
1997f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	setup->sep = sep;
1998f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	setup->rsep = avdtp_find_remote_sep(session, sep->lsep);
1999f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
2000f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (setup->rsep == NULL) {
2001f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		error("Could not find remote sep");
2002f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		goto fail;
2003f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
2004f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
2005f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	/* FIXME: Remove auto select when it is not longer possible to register
2006f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	endpoint in the configuration file */
2007f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (sep->endpoint == NULL) {
2008f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		if (!select_capabilities(session, setup->rsep,
2009daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz					&setup->caps)) {
2010f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			error("Unable to auto select remote SEP capabilities");
2011f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz			goto fail;
2012f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		}
2013f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
2014f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		g_idle_add(auto_select, setup);
2015f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
2016f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return cb_data->id;
2017f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	}
2018f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
2019f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	service = avdtp_get_codec(setup->rsep);
2020f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	codec = (struct avdtp_media_codec_capability *) service->data;
2021f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
2022f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	if (media_endpoint_select_configuration(sep->endpoint, codec->data,
2023f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz						service->length - sizeof(*codec),
2024f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz						select_cb, setup) ==
2025f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz						TRUE)
2026f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		return cb_data->id;
2027f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
2028f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzfail:
20290889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	setup_cb_free(cb_data);
2030f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	return 0;
2031f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
2032f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
2033f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
20341340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vitaunsigned int a2dp_config(struct avdtp *session, struct a2dp_sep *sep,
2035bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz				a2dp_config_cb_t cb, GSList *caps,
2036bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz				void *user_data)
2037cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
20382934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup_cb *cb_data;
2039666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	GSList *l;
2040957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	struct a2dp_server *server;
20412934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
2042bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	struct a2dp_sep *tmp;
2043489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct avdtp_service_capability *cap;
2044489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct avdtp_media_codec_capability *codec_cap = NULL;
20452934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	int posix_err;
2046957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	bdaddr_t src;
2047957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
2048957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	avdtp_get_peers(session, &src, NULL);
2049957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	server = find_server(servers, &src);
2050957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (!server)
2051957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		return 0;
2052cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
2053489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	for (l = caps; l != NULL; l = l->next) {
2054489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		cap = l->data;
2055489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
2056489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		if (cap->category != AVDTP_MEDIA_CODEC)
2057489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz			continue;
2058489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
2059489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		codec_cap = (void *) cap->data;
2060489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		break;
2061489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	}
2062489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
2063489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (!codec_cap)
2064489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		return 0;
2065489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
2066bd30e5535a6d713727f8f9433954dcb9dd4b7168Luiz Augusto von Dentz	if (sep->codec != codec_cap->media_codec_type)
2067730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg		return 0;
2068730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg
2069f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	DBG("a2dp_config: selected SEP %p", sep->lsep);
2070666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
207108b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	setup = a2dp_setup_get(session);
207208b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	if (!setup)
207308b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz		return 0;
207408b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz
20750889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	cb_data = setup_cb_new(setup);
20762934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->config_cb = cb;
2077cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	cb_data->user_data = user_data;
2078cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
20792934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->sep = sep;
2080666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	setup->stream = sep->stream;
2081daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz
2082daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz	/* Copy given caps if they are different than current caps */
2083daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz	if (setup->caps != caps) {
2084daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz		g_slist_foreach(setup->caps, (GFunc) g_free, NULL);
2085daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz		g_slist_free(setup->caps);
2086daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz		setup->caps = g_slist_copy(caps);
2087daba0e305b633dc2bb631fb370a7f9d33c733977Luiz Augusto von Dentz	}
2088cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
2089f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	switch (avdtp_sep_get_state(sep->lsep)) {
2090cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_IDLE:
2091984260d913eebddbd7b228704c071f0897640dceSzymon Janc		if (sep->type == AVDTP_SEP_TYPE_SOURCE)
20921340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita			l = server->sources;
2093984260d913eebddbd7b228704c071f0897640dceSzymon Janc		else
20941340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita			l = server->sinks;
2095714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz
20961340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita		for (; l != NULL; l = l->next) {
20971340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita			tmp = l->data;
2098714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz			if (avdtp_has_stream(session, tmp->stream))
2099714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz				break;
2100714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz		}
2101714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz
2102714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz		if (l != NULL) {
2103217b1bea41aad595022ce5a0078949472c27295bLuiz Augusto von Dentz			if (a2dp_sep_get_lock(tmp))
2104217b1bea41aad595022ce5a0078949472c27295bLuiz Augusto von Dentz				goto failed;
2105714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz			setup->reconfigure = TRUE;
2106ab816e6549b8e2ed661bd029e274102e8e04c075Luiz Augusto von Dentz			if (avdtp_close(session, tmp->stream, FALSE) < 0) {
2107714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz				error("avdtp_close failed");
2108714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz				goto failed;
2109714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz			}
2110714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz			break;
2111714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz		}
2112714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz
2113f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		setup->rsep = avdtp_find_remote_sep(session, sep->lsep);
2114f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		if (setup->rsep == NULL) {
21152934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			error("No matching ACP and INT SEPs found");
21162934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			goto failed;
21172934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		}
21182934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2119f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		posix_err = avdtp_set_configuration(session, setup->rsep,
2120f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz							sep->lsep, caps,
2121f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz							&setup->stream);
21222934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (posix_err < 0) {
21232934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			error("avdtp_set_configuration: %s",
21242934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				strerror(-posix_err));
2125cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			goto failed;
2126730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg		}
2127cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
2128cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_OPEN:
21292934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_STREAMING:
21300fcfb4bedc60fb5f632b4423518cb823f58348feLuiz Augusto von Dentz		if (avdtp_stream_has_capabilities(setup->stream, caps)) {
21318e58667ef0a4cda88ac64137728da28d8fdf3f0fGustavo F. Padovan			DBG("Configuration match: resuming");
2132d7f412e4197fbe26ebe1c30880e88295d2fbe17eLuiz Augusto von Dentz			cb_data->source_id = g_idle_add(finalize_config,
2133d7f412e4197fbe26ebe1c30880e88295d2fbe17eLuiz Augusto von Dentz								setup);
21340fcfb4bedc60fb5f632b4423518cb823f58348feLuiz Augusto von Dentz		} else if (!setup->reconfigure) {
21352934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			setup->reconfigure = TRUE;
2136ab816e6549b8e2ed661bd029e274102e8e04c075Luiz Augusto von Dentz			if (avdtp_close(session, sep->stream, FALSE) < 0) {
21372934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				error("avdtp_close failed");
21382934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				goto failed;
21395402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz			}
21405402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		}
21412934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
21422934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	default:
21432934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		error("SEP in bad state for requesting a new stream");
21442934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		goto failed;
21452934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
21462934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
21472934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return cb_data->id;
21482934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
21492934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzfailed:
21500889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	setup_cb_free(cb_data);
21512934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return 0;
21522934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
21532934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
21541340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vitaunsigned int a2dp_resume(struct avdtp *session, struct a2dp_sep *sep,
21552934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				a2dp_stream_cb_t cb, void *user_data)
21562934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
21572934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup_cb *cb_data;
21582934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
21592934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
216008b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	setup = a2dp_setup_get(session);
216108b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	if (!setup)
216208b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz		return 0;
216308b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz
21640889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	cb_data = setup_cb_new(setup);
21652934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->resume_cb = cb;
21662934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->user_data = user_data;
21672934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
21682934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->sep = sep;
21692934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->stream = sep->stream;
21702934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2171f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	switch (avdtp_sep_get_state(sep->lsep)) {
21722934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_IDLE:
21732934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		goto failed;
21742934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
21752934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_OPEN:
21762934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (avdtp_start(session, sep->stream) < 0) {
2177730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg			error("avdtp_start failed");
2178cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			goto failed;
2179730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg		}
2180cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
2181cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_STREAMING:
21822934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (!sep->suspending && sep->suspend_timer) {
21832934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			g_source_remove(sep->suspend_timer);
21842934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			sep->suspend_timer = 0;
21852934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			avdtp_unref(sep->session);
21862934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			sep->session = NULL;
2187cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		}
21883f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg		if (sep->suspending)
21893f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg			setup->start = TRUE;
21903f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg		else
2191d7f412e4197fbe26ebe1c30880e88295d2fbe17eLuiz Augusto von Dentz			cb_data->source_id = g_idle_add(finalize_resume,
2192d7f412e4197fbe26ebe1c30880e88295d2fbe17eLuiz Augusto von Dentz								setup);
2193cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
2194cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	default:
21956863b32bb003ead1a43228d685092b0173628750João Paulo Rechi Vita		error("SEP in bad state for resume");
2196cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		goto failed;
2197cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
21985402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
21992934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return cb_data->id;
22002934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
22012934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzfailed:
22020889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	setup_cb_free(cb_data);
22032934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return 0;
22042934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
22052934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
22061340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vitaunsigned int a2dp_suspend(struct avdtp *session, struct a2dp_sep *sep,
22072934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				a2dp_stream_cb_t cb, void *user_data)
22082934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
22092934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup_cb *cb_data;
22102934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
22112934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
221208b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	setup = a2dp_setup_get(session);
221308b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz	if (!setup)
221408b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz		return 0;
221508b6a53b6f1b7a2772da64c13957fec72f516345Luiz Augusto von Dentz
22160889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	cb_data = setup_cb_new(setup);
22172934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->suspend_cb = cb;
22182934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->user_data = user_data;
22192934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
22202934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->sep = sep;
22212934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->stream = sep->stream;
22222934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2223f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	switch (avdtp_sep_get_state(sep->lsep)) {
22242934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_IDLE:
22251340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita		error("a2dp_suspend: no stream to suspend");
22262934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		goto failed;
22272934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
22282934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_OPEN:
2229d7f412e4197fbe26ebe1c30880e88295d2fbe17eLuiz Augusto von Dentz		cb_data->source_id = g_idle_add(finalize_suspend, setup);
22302934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
22312934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_STREAMING:
2232c020b7240f8f6b72ffbb6c6f327a63f2da14e6a9Johan Hedberg		if (avdtp_suspend(session, sep->stream) < 0) {
2233c020b7240f8f6b72ffbb6c6f327a63f2da14e6a9Johan Hedberg			error("avdtp_suspend failed");
22342934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			goto failed;
22352934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		}
2236f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz		sep->suspending = TRUE;
22372934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
22382934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	default:
22396863b32bb003ead1a43228d685092b0173628750João Paulo Rechi Vita		error("SEP in bad state for suspend");
22402934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		goto failed;
22412934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
224203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
2243cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	return cb_data->id;
2244cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
2245cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergfailed:
22460889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	setup_cb_free(cb_data);
22470f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	return 0;
2248cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
2249cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
22501340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vitagboolean a2dp_cancel(struct audio_device *dev, unsigned int id)
22511340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita{
22521340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	struct a2dp_setup *setup;
22531340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	GSList *l;
22541340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita
22551340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	setup = find_setup_by_dev(dev);
22561340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita	if (!setup)
22571340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita		return FALSE;
22581340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita
22590889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	for (l = setup->cb; l != NULL; l = g_slist_next(l)) {
22601340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita		struct a2dp_setup_cb *cb = l->data;
22611340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita
22620889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz		if (cb->id != id)
22630889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz			continue;
22641340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita
22650889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz		setup_ref(setup);
22660889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz		setup_cb_free(cb);
22671340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita
22680889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz		if (!setup->cb) {
22690889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz			DBG("aborting setup %p", setup);
22700889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz			avdtp_abort(setup->session, setup->stream);
22710889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz			return TRUE;
22720889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz		}
22731340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita
22740889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz		setup_unref(setup);
2275f8d790861cf7e02576b4b03455748567e05f942fLuiz Augusto von Dentz		return TRUE;
22760889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	}
2277f8d790861cf7e02576b4b03455748567e05f942fLuiz Augusto von Dentz
22780889e245ef28056efdbb5647dd21245cccabb33dLuiz Augusto von Dentz	return FALSE;
22791340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita}
22801340fb6eb3ae71c6a7f57602a1b2a6405c3b577aJoão Paulo Rechi Vita
2281fc0d501d82773718d0f2d040f786136332c39813Johan Hedberggboolean a2dp_sep_lock(struct a2dp_sep *sep, struct avdtp *session)
2282cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
2283fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	if (sep->locked)
2284fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg		return FALSE;
2285f4211a3cd3442d54fa7877a6c421bee034d46e8eJohan Hedberg
2286f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	DBG("SEP %p locked", sep->lsep);
2287fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	sep->locked = TRUE;
2288666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
2289fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	return TRUE;
2290cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
2291cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
2292fc0d501d82773718d0f2d040f786136332c39813Johan Hedberggboolean a2dp_sep_unlock(struct a2dp_sep *sep, struct avdtp *session)
2293cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
22941636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz	struct a2dp_server *server = sep->server;
2295cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	avdtp_state_t state;
22961636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz	GSList *l;
2297cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
2298f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	state = avdtp_sep_get_state(sep->lsep);
2299cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
2300666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	sep->locked = FALSE;
2301cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
2302f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	DBG("SEP %p unlocked", sep->lsep);
2303730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg
23041636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz	if (sep->type == AVDTP_SEP_TYPE_SOURCE)
23051636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz		l = server->sources;
23061636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz	else
23071636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz		l = server->sinks;
23081636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz
23091636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz	/* Unregister sep if it was removed */
23101636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz	if (g_slist_find(l, sep) == NULL) {
23111636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz		a2dp_unregister_sep(sep);
23121636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz		return TRUE;
23131636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz	}
23141636fb014845743c0000c4030cbf75c55bd3983fLuiz Augusto von Dentz
2315666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (!sep->stream || state == AVDTP_STATE_IDLE)
2316cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return TRUE;
2317cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
2318cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	switch (state) {
2319cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_OPEN:
2320cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		/* Set timer here */
2321cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
2322cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_STREAMING:
2323666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		if (avdtp_suspend(session, sep->stream) == 0)
2324666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			sep->suspending = TRUE;
2325cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
2326cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	default:
2327cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
2328cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
2329cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
2330cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	return TRUE;
2331cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
2332cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
2333c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentzgboolean a2dp_sep_get_lock(struct a2dp_sep *sep)
2334c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz{
2335c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	return sep->locked;
2336c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz}
2337c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz
2338c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentzstatic int stream_cmp(gconstpointer data, gconstpointer user_data)
2339c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz{
2340c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	const struct a2dp_sep *sep = data;
2341c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	const struct avdtp_stream *stream = user_data;
2342c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz
2343c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	return (sep->stream != stream);
2344c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz}
2345c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz
2346c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentzstruct a2dp_sep *a2dp_get_sep(struct avdtp *session,
2347c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz				struct avdtp_stream *stream)
2348c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz{
2349c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	struct a2dp_server *server;
2350c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	bdaddr_t src, dst;
2351c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	GSList *l;
2352c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz
2353c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	avdtp_get_peers(session, &src, &dst);
2354c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz
2355c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	for (l = servers; l; l = l->next) {
2356c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz		server = l->data;
2357c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz
2358c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz		if (bacmp(&src, &server->src) == 0)
2359c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz			break;
2360c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	}
2361c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz
2362c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	if (!l)
2363c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz		return NULL;
2364c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz
2365c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	l = g_slist_find_custom(server->sources, stream, stream_cmp);
2366c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	if (l)
2367c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz		return l->data;
2368c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz
2369c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	l = g_slist_find_custom(server->sinks, stream, stream_cmp);
2370c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	if (l)
2371c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz		return l->data;
2372c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz
2373c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz	return NULL;
2374c5e75a5051967530f29f9fabfb8593ef2723d57eLuiz Augusto von Dentz}
2375f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz
2376f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentzstruct avdtp_stream *a2dp_sep_get_stream(struct a2dp_sep *sep)
2377f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz{
2378f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz	return sep->stream;
2379f87e1bed1320276e39cc5ccb250082fac90bdedeLuiz Augusto von Dentz}
2380