a2dp.c revision 957d01bac7a4c448bbe0a15de613af7927d1c7d0
1e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg/*
2e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *
3e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  BlueZ - Bluetooth protocol stack for Linux
4e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *
5de72271829f6bfd21aa6550a2ac6d81e35b53cadMarcel Holtmann *  Copyright (C) 2006-2007  Nokia Corporation
6e823c15e43a6f924779e466d434c51157002d9eeMarcel Holtmann *  Copyright (C) 2004-2008  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
396763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include "logging.h"
40d013a1eaa7beebbb49c1fe0015c70ad81566d97cJohan Hedberg#include "device.h"
41296dcf42cf8a4f4d6f0192cac58a28887be38552Johan Hedberg#include "manager.h"
426763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include "avdtp.h"
43f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg#include "sink.h"
44e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg#include "a2dp.h"
457299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz#include "sdpd.h"
466763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
47c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg/* The duration that streams without users are allowed to stay in
48c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg * STREAMING state. */
49c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg#define SUSPEND_TIMEOUT 5000
502934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz#define RECONFIGURE_TIMEOUT 500
51c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
52cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg#ifndef MIN
53cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg# define MIN(x, y) ((x) < (y) ? (x) : (y))
54cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg#endif
55cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
56cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg#ifndef MAX
57cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg# define MAX(x, y) ((x) > (y) ? (x) : (y))
58cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg#endif
59cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
60cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergstruct a2dp_sep {
61666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	uint8_t type;
62489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	uint8_t codec;
63cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	struct avdtp_local_sep *sep;
64c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	struct avdtp *session;
65cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	struct avdtp_stream *stream;
66c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	guint suspend_timer;
67666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	gboolean locked;
68cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	gboolean suspending;
69cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	gboolean starting;
70cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg};
71cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
722934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstruct a2dp_setup_cb {
732934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	a2dp_config_cb_t config_cb;
742934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	a2dp_stream_cb_t resume_cb;
752934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	a2dp_stream_cb_t suspend_cb;
76cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	void *user_data;
77cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	int id;
78cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg};
79cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
802934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstruct a2dp_setup {
81cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	struct avdtp *session;
82828133c3180a090a06ace6637d9f84ae5f57ae33Johan Hedberg	struct a2dp_sep *sep;
83cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	struct avdtp_stream *stream;
845309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	struct avdtp_error *err;
852934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	GSList *client_caps;
862934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	gboolean reconfigure;
87cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	gboolean canceled;
883f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	gboolean start;
89cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	GSList *cb;
902934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	int ref;
91cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg};
92cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
936763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic DBusConnection *connection = NULL;
946763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
95957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentzstruct a2dp_server {
96957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	bdaddr_t src;
97957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	GSList *sinks;
98957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	GSList *sources;
99957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	uint32_t source_record_id;
100957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	uint32_t sink_record_id;
101957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz};
1026763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
103957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentzstatic GSList *servers = NULL;
10403490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedbergstatic GSList *setups = NULL;
1052934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic unsigned int cb_id = 0;
1062934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1072934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic struct a2dp_setup *setup_ref(struct a2dp_setup *setup)
1082934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
1092934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->ref++;
1102934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1112934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	debug("setup_ref(%p): ref=%d", setup, setup->ref);
1122934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1132934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return setup;
1142934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
1156763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1162934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic void setup_free(struct a2dp_setup *s)
117cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
1182934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	debug("setup_free(%p)", s);
11903490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setups = g_slist_remove(setups, s);
120cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (s->session)
121cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		avdtp_unref(s->session);
122cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	g_slist_foreach(s->cb, (GFunc) g_free, NULL);
123cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	g_slist_free(s->cb);
124cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	g_free(s);
125cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
126cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1272934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic void setup_unref(struct a2dp_setup *setup)
1282934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
1292934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->ref--;
1302934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1312934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	debug("setup_unref(%p): ref=%d", setup, setup->ref);
1322934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1332934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (setup->ref <= 0)
1342934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup_free(setup);
1352934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
1362934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
137caf9fdd6d0183afc3b21d1cd82eb637773c131deMarcel Holtmannstatic struct audio_device *a2dp_get_dev(struct avdtp *session)
138fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg{
139fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	bdaddr_t addr;
140fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg
141fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	avdtp_get_peers(session, NULL, &addr);
142fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg
14312d81a98fe65d109c0b1caa242e96b005bcc8209Luiz Augusto von Dentz	return manager_find_device(&addr, NULL, FALSE);
144fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg}
145fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg
1465309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentzstatic gboolean finalize_config(struct a2dp_setup *s)
147cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
148847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	GSList *l;
149847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg
1502934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_ref(s);
151847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	for (l = s->cb; l != NULL; l = l->next) {
1522934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		struct a2dp_setup_cb *cb = l->data;
1532934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1542934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (cb->config_cb) {
1555309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz			cb->config_cb(s->session, s->sep, s->stream, s->err,
1562934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz					cb->user_data);
1572934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			cb->config_cb = NULL;
1582934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			setup_unref(s);
1592934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		}
160847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	}
161cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1622934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_unref(s);
16378a94059160d7478624cad315022255f7ebbbe80Johan Hedberg	return FALSE;
164cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
1651addff77624b54445c9b81779ddc78892a126a45Johan Hedberg
1662934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic gboolean finalize_config_errno(struct a2dp_setup *s, int err)
167847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg{
168847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	struct avdtp_error avdtp_err;
169847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg
170847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	avdtp_error_init(&avdtp_err, AVDTP_ERROR_ERRNO, -err);
1715309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	s->err = err ? &avdtp_err : NULL;
172847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg
1735309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	return finalize_config(s);
174847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg}
175847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg
1765309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentzstatic gboolean finalize_resume(struct a2dp_setup *s)
1772934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
1782934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	GSList *l;
1792934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1802934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_ref(s);
1812934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	for (l = s->cb; l != NULL; l = l->next) {
1822934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		struct a2dp_setup_cb *cb = l->data;
1832934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1842934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (cb->resume_cb) {
1855309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz			cb->resume_cb(s->session, s->err, cb->user_data);
1862934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			cb->resume_cb = NULL;
1872934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			setup_unref(s);
1882934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		}
1892934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
1902934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1912934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_unref(s);
1922934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return FALSE;
1932934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
1942934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1952934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic gboolean finalize_resume_errno(struct a2dp_setup *s, int err)
1962934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
1972934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct avdtp_error avdtp_err;
1982934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1992934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	avdtp_error_init(&avdtp_err, AVDTP_ERROR_ERRNO, -err);
2005309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	s->err = err ? &avdtp_err : NULL;
2012934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2025309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	return finalize_resume(s);
2032934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
2042934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2055309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentzstatic gboolean finalize_suspend(struct a2dp_setup *s)
2062934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
2072934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	GSList *l;
2082934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2092934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_ref(s);
2102934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	for (l = s->cb; l != NULL; l = l->next) {
2112934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		struct a2dp_setup_cb *cb = l->data;
2122934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2132934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (cb->suspend_cb) {
2145309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz			cb->suspend_cb(s->session, s->err, cb->user_data);
2152934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			cb->suspend_cb = NULL;
2162934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			setup_unref(s);
2172934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		}
2182934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
2192934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2202934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_unref(s);
2212934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return FALSE;
2222934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
2232934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2242934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic gboolean finalize_suspend_errno(struct a2dp_setup *s, int err)
2252934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
2262934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct avdtp_error avdtp_err;
2272934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2282934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	avdtp_error_init(&avdtp_err, AVDTP_ERROR_ERRNO, -err);
2295309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	s->err = err ? &avdtp_err : NULL;
2302934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2315309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	return finalize_suspend(s);
2322934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
2332934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2342934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic struct a2dp_setup *find_setup_by_session(struct avdtp *session)
23503490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg{
23603490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	GSList *l;
23703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
23803490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	for (l = setups; l != NULL; l = l->next) {
2392934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		struct a2dp_setup *setup = l->data;
24003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
24103490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg		if (setup->session == session)
24203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg			return setup;
24303490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	}
24403490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
24503490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	return NULL;
24603490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg}
24703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
248caf9fdd6d0183afc3b21d1cd82eb637773c131deMarcel Holtmannstatic struct a2dp_setup *find_setup_by_dev(struct audio_device *dev)
24903490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg{
25003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	GSList *l;
25103490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
25203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	for (l = setups; l != NULL; l = l->next) {
2532934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		struct a2dp_setup *setup = l->data;
254caf9fdd6d0183afc3b21d1cd82eb637773c131deMarcel Holtmann		struct audio_device *setup_dev = a2dp_get_dev(setup->session);
25503490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
256fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg		if (setup_dev == dev)
25703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg			return setup;
25803490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	}
25903490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
26003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	return NULL;
26103490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg}
26203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
2637a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedbergstatic void stream_state_changed(struct avdtp_stream *stream,
2647a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg					avdtp_state_t old_state,
2657a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg					avdtp_state_t new_state,
2667a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg					struct avdtp_error *err,
2677a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg					void *user_data)
2687a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg{
2697a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	struct a2dp_sep *sep = user_data;
2707a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg
2717a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	if (new_state != AVDTP_STATE_IDLE)
2727a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		return;
2737a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg
2747a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	if (sep->suspend_timer) {
2757a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		g_source_remove(sep->suspend_timer);
2767a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		sep->suspend_timer = 0;
2777a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	}
2787a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg
2797a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	if (sep->session) {
2807a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		avdtp_unref(sep->session);
2817a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		sep->session = NULL;
2827a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	}
2831ddd76afa25d775788e3762ab731cad80f8ffe56Johan Hedberg
2847a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	sep->stream = NULL;
2855402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
2865402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz}
2875402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
288489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentzstatic gboolean sbc_setconf_ind(struct avdtp *session,
289f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg				struct avdtp_local_sep *sep,
2906763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg				struct avdtp_stream *stream,
291f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg				GSList *caps, uint8_t *err,
292666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				uint8_t *category, void *user_data)
2936763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
294666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
295caf9fdd6d0183afc3b21d1cd82eb637773c131deMarcel Holtmann	struct audio_device *dev;
296c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	struct avdtp_service_capability *cap;
297c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	struct avdtp_media_codec_capability *codec_cap;
298c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	struct sbc_codec_cap *sbc_cap;
299f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg
300666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
301ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Set_Configuration_Ind", sep);
302666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
303ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Set_Configuration_Ind", sep);
304f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg
305fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	dev = a2dp_get_dev(session);
306f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg	if (!dev) {
307f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg		*err = AVDTP_UNSUPPORTED_CONFIGURATION;
308f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg		*category = 0x00;
309f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg		return FALSE;
310f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg	}
311f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg
312c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	/* Check bipool range */
313c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	for (codec_cap = NULL; caps; caps = g_slist_next(caps)) {
314c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz		cap = caps->data;
315c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz		if (cap->category == AVDTP_MEDIA_CODEC) {
316c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz			codec_cap = (void *) cap->data;
317c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz			if (codec_cap->media_codec_type == A2DP_CODEC_SBC) {
318c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz				sbc_cap = (void *) codec_cap;
319c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz				if (sbc_cap->min_bitpool < MIN_BITPOOL ||
320c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz					sbc_cap->max_bitpool > MAX_BITPOOL) {
321c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz					*err = AVDTP_UNSUPPORTED_CONFIGURATION;
322c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz					*category = AVDTP_MEDIA_CODEC;
323c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz					return FALSE;
324c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz				}
325c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz			}
326c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz			break;
327c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz		}
328c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	}
329c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz
3307a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep);
331c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	a2dp_sep->stream = stream;
332cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
333666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE)
334c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg		sink_new_stream(dev, session, stream);
3356763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3366763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
3376763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
3386763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
339489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentzstatic gboolean sbc_getcap_ind(struct avdtp *session, struct avdtp_local_sep *sep,
340666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				GSList **caps, uint8_t *err, void *user_data)
3416763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
342666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
3436763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	struct avdtp_service_capability *media_transport, *media_codec;
3446763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	struct sbc_codec_cap sbc_cap;
3456763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
346666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
347ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Get_Capability_Ind", sep);
3486763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
349ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Get_Capability_Ind", sep);
3506763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3516763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	*caps = NULL;
3526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
3546763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg						NULL, 0);
3556763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3566763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	*caps = g_slist_append(*caps, media_transport);
3576763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3586763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	memset(&sbc_cap, 0, sizeof(struct sbc_codec_cap));
3596763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3606763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sbc_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO;
3616763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sbc_cap.cap.media_codec_type = A2DP_CODEC_SBC;
3626763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3639ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz	sbc_cap.frequency = ( SBC_SAMPLING_FREQ_48000 |
3649ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz				SBC_SAMPLING_FREQ_44100 |
3659ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz				SBC_SAMPLING_FREQ_32000 |
3669ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz				SBC_SAMPLING_FREQ_16000 );
3676763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3689ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz	sbc_cap.channel_mode = ( SBC_CHANNEL_MODE_JOINT_STEREO |
3699ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_CHANNEL_MODE_STEREO |
3709ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_CHANNEL_MODE_DUAL_CHANNEL |
3719ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_CHANNEL_MODE_MONO );
3726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3739ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz	sbc_cap.block_length = ( SBC_BLOCK_LENGTH_16 |
3749ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_BLOCK_LENGTH_12 |
3759ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_BLOCK_LENGTH_8 |
3769ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_BLOCK_LENGTH_4 );
3776763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3789ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz	sbc_cap.subbands = ( SBC_SUBBANDS_8 | SBC_SUBBANDS_4 );
3796763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3809ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz	sbc_cap.allocation_method = ( SBC_ALLOCATION_LOUDNESS |
3819ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_ALLOCATION_SNR );
3826763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
383c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	sbc_cap.min_bitpool = MIN_BITPOOL;
384c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	sbc_cap.max_bitpool = MAX_BITPOOL;
3856763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3866763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &sbc_cap,
3876763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg						sizeof(sbc_cap));
3886763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3896763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	*caps = g_slist_append(*caps, media_codec);
3906763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3916763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
3926763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
3936763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
394489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentzstatic gboolean mpeg_setconf_ind(struct avdtp *session,
395489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				struct avdtp_local_sep *sep,
396489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				struct avdtp_stream *stream,
397489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				GSList *caps, uint8_t *err,
398489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				uint8_t *category, void *user_data)
399489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz{
400489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct a2dp_sep *a2dp_sep = user_data;
401caf9fdd6d0183afc3b21d1cd82eb637773c131deMarcel Holtmann	struct audio_device *dev;
402489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
403489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
404ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Set_Configuration_Ind", sep);
405489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	else
406ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Set_Configuration_Ind", sep);
407489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
408489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	dev = a2dp_get_dev(session);
409489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (!dev) {
410489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		*err = AVDTP_UNSUPPORTED_CONFIGURATION;
411489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		*category = 0x00;
412489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		return FALSE;
413489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	}
414489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
415489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep);
416489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	a2dp_sep->stream = stream;
417489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
418489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE)
419489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		sink_new_stream(dev, session, stream);
420489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
421489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	return TRUE;
422489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz}
423489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
424ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentzstatic gboolean mpeg_getcap_ind(struct avdtp *session,
425ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz				struct avdtp_local_sep *sep,
426489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				GSList **caps, uint8_t *err, void *user_data)
427489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz{
428489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct a2dp_sep *a2dp_sep = user_data;
429489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct avdtp_service_capability *media_transport, *media_codec;
430489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct mpeg_codec_cap mpeg_cap;
431489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
432489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
433ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Get_Capability_Ind", sep);
434489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	else
435ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Get_Capability_Ind", sep);
436489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
437489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	*caps = NULL;
438489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
439489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
440489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz						NULL, 0);
441489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
442489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	*caps = g_slist_append(*caps, media_transport);
443489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
444489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	memset(&mpeg_cap, 0, sizeof(struct mpeg_codec_cap));
445489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
446489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO;
447489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_cap.cap.media_codec_type = A2DP_CODEC_MPEG12;
448489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
449489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_cap.frequency = ( MPEG_SAMPLING_FREQ_48000 |
450489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				MPEG_SAMPLING_FREQ_44100 |
451489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				MPEG_SAMPLING_FREQ_32000 |
452489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				MPEG_SAMPLING_FREQ_24000 |
453489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				MPEG_SAMPLING_FREQ_22050 |
454489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				MPEG_SAMPLING_FREQ_16000 );
455489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
456489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_cap.channel_mode = ( MPEG_CHANNEL_MODE_JOINT_STEREO |
457489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz					MPEG_CHANNEL_MODE_STEREO |
458489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz					MPEG_CHANNEL_MODE_DUAL_CHANNEL |
459489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz					MPEG_CHANNEL_MODE_MONO );
460489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
461489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_cap.layer = ( MPEG_LAYER_MP3 | MPEG_LAYER_MP2 | MPEG_LAYER_MP1 );
462489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
463489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_cap.bitrate = 0xFFFF;
464489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
465489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &mpeg_cap,
466489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz						sizeof(mpeg_cap));
467489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
468489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	*caps = g_slist_append(*caps, media_codec);
469489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
470489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	return TRUE;
471489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz}
472489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
473f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
4740f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg				struct avdtp_stream *stream,
475666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_error *err, void *user_data)
4766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
477666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
4782934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
479caf9fdd6d0183afc3b21d1cd82eb637773c131deMarcel Holtmann	struct audio_device *dev;
4800f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	int ret;
481cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
482666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
483ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Set_Configuration_Cfm", sep);
484666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
485ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Set_Configuration_Cfm", sep);
486cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
48703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
48803490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
4890f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (err) {
4905309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		if (setup) {
4915309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz			setup->err = err;
4925309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz			finalize_config(setup);
4935309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		}
4940f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		return;
4950f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	}
4960f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg
4977a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep);
498c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	a2dp_sep->stream = stream;
499cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
500cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!setup)
501cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return;
502cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
503fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	dev = a2dp_get_dev(session);
504fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg
50567d1e1774b3ff2d7a09fcf49484515bd85c02d14Johan Hedberg	/* Notify sink.c of the new stream */
506fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	sink_new_stream(dev, session, setup->stream);
50767d1e1774b3ff2d7a09fcf49484515bd85c02d14Johan Hedberg
5080f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	ret = avdtp_open(session, stream);
5090f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (ret < 0) {
5100f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		error("Error on avdtp_open %s (%d)", strerror(-ret),
5110f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg				-ret);
5127a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		setup->stream = NULL;
5132934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		finalize_config_errno(setup, ret);
514cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
5156763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
5166763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
517f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean getconf_ind(struct avdtp *session, struct avdtp_local_sep *sep,
518666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				uint8_t *err, void *user_data)
5196763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
520666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
521666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
522666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
523ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Get_Configuration_Ind");
5246763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
525ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Get_Configuration_Ind");
5266763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
5276763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
5286763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
529f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void getconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
530666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
531666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
5326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
533666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
534666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
535666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
536ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Set_Configuration_Cfm", sep);
5376763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
538ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Set_Configuration_Cfm", sep);
5396763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
5406763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
541f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean open_ind(struct avdtp *session, struct avdtp_local_sep *sep,
542666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
543666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
5446763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
545666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
546666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
547666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
548ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Open_Ind", sep);
5496763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
550ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Open_Ind", sep);
5516763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
5526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
5536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
554f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void open_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
555666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
556666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
5576763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
558666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
5592934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
560666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
561666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
562ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Open_Cfm", sep);
5636763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
564ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Open_Cfm", sep);
5651addff77624b54445c9b81779ddc78892a126a45Johan Hedberg
56603490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
567cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!setup)
5681addff77624b54445c9b81779ddc78892a126a45Johan Hedberg		return;
5691addff77624b54445c9b81779ddc78892a126a45Johan Hedberg
570cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (setup->canceled) {
5710f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		if (!err)
5720f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg			avdtp_close(session, stream);
5732934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup_unref(setup);
574cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return;
575cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
576cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
5772934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (setup->reconfigure)
5782934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup->reconfigure = FALSE;
5792934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
5800f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (err) {
5810f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		setup->stream = NULL;
5825309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
5835309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		finalize_config(setup);
5845402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
585847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	else
5865309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		finalize_config_errno(setup, 0);
5876763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
5886763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
589c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedbergstatic gboolean suspend_timeout(struct a2dp_sep *sep)
590c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg{
591c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	if (avdtp_suspend(sep->session, sep->stream) == 0)
592c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg		sep->suspending = TRUE;
593c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
5947a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	sep->suspend_timer = 0;
595c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
596c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	avdtp_unref(sep->session);
597c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	sep->session = NULL;
598c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
599c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	return FALSE;
600c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg}
601c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
602f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean start_ind(struct avdtp *session, struct avdtp_local_sep *sep,
603666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
604666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
6056763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
606666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
607c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
608666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
609ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Start_Ind", sep);
610666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
611ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Start_Ind", sep);
6125b5cfaadb312600c58362617080e29fbf036712cJohan Hedberg
613f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg	if (!a2dp_sep->locked) {
614f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg		a2dp_sep->session = avdtp_ref(session);
615f6d1f79b0382b03dc01d3bb823c8c3eb70f82457Johan Hedberg		a2dp_sep->suspend_timer = g_timeout_add(SUSPEND_TIMEOUT,
616c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg						(GSourceFunc) suspend_timeout,
617c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg						a2dp_sep);
618f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg	}
619f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg
620c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	return TRUE;
6216763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
6226763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
623f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void start_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
624666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
625666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
6266763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
627666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
6282934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
629666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
630666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
631ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Start_Cfm", sep);
6326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
633ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Start_Cfm", sep);
634cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
63503490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
636cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!setup)
637cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return;
638cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
639cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (setup->canceled) {
6400f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		if (!err)
6410f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg			avdtp_close(session, stream);
6422934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup_unref(setup);
643cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return;
644cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
645cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
646847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	if (err) {
6470f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		setup->stream = NULL;
6485309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
6495309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		finalize_resume(setup);
650847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	}
651847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	else
6522934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		finalize_resume_errno(setup, 0);
6536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
6546763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
655f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean suspend_ind(struct avdtp *session, struct avdtp_local_sep *sep,
656666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
657666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
6586763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
659666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
660666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
661666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
662ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Suspend_Ind", sep);
6636763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
664ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Suspend_Ind", sep);
665d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg
666d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg	if (a2dp_sep->suspend_timer) {
667d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg		g_source_remove(a2dp_sep->suspend_timer);
66886898be87d24991e48d783b3e20696ff1ce62abcJohan Hedberg		a2dp_sep->suspend_timer = 0;
669f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg		avdtp_unref(a2dp_sep->session);
670f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg		a2dp_sep->session = NULL;
671d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg	}
672d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg
6736763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
6746763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
6756763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
676f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void suspend_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
677666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
678666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
6796763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
680666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
6812934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
6823f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	gboolean start;
683c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
684666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
685ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Suspend_Cfm", sep);
686666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
687ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Suspend_Cfm", sep);
688cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
689c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	a2dp_sep->suspending = FALSE;
690cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
69103490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
69203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	if (!setup)
69303490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg		return;
69403490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
6953f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	start = setup->start;
6963f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	setup->start = FALSE;
6973f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg
6980f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (err) {
6992934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup->stream = NULL;
7005309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
7015309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		finalize_suspend(setup);
702cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
7032934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	else
7042934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		finalize_suspend_errno(setup, 0);
7053f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg
7063f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	if (!start)
7073f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg		return;
7083f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg
7095309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	if (err) {
7105309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
7115309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		finalize_suspend(setup);
7125309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	} else if (avdtp_start(session, a2dp_sep->stream) < 0) {
7133f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg		struct avdtp_error start_err;
7143f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg		error("avdtp_start failed");
7153f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg		avdtp_error_init(&start_err, AVDTP_ERROR_ERRNO, EIO);
7165309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
7175309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		finalize_suspend(setup);
7183f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	}
7196763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
7206763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
721f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean close_ind(struct avdtp *session, struct avdtp_local_sep *sep,
722666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
723666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
7246763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
725666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
726c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
727666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
728ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Close_Ind", sep);
729666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
730ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Close_Ind", sep);
731cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
7326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
7336763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
7346763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
735714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentzstatic gboolean a2dp_reconfigure(gpointer data)
7362934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
7372934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup = data;
7382934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct avdtp_local_sep *lsep;
7392934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct avdtp_remote_sep *rsep;
740714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz	struct avdtp_service_capability *cap;
741714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz	struct avdtp_media_codec_capability *codec_cap = NULL;
742714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz	GSList *l;
7432934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	int posix_err;
7442934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
745714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz	for (l = setup->client_caps; l != NULL; l = l->next) {
746714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz		cap = l->data;
747714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz
748714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz		if (cap->category != AVDTP_MEDIA_CODEC)
749714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz			continue;
750714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz
751714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz		codec_cap = (void *) cap->data;
752714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz		break;
753714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz	}
754714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz
7552934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	posix_err = avdtp_get_seps(setup->session, AVDTP_SEP_TYPE_SINK,
756714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz					codec_cap->media_type,
757714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz					codec_cap->media_codec_type,
7582934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz					&lsep, &rsep);
7592934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (posix_err < 0) {
7602934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		error("No matching ACP and INT SEPs found");
7612934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		finalize_config_errno(setup, posix_err);
7622934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
7632934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
7642934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	posix_err = avdtp_set_configuration(setup->session, rsep, lsep,
7652934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz						setup->client_caps,
7662934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz						&setup->stream);
7672934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (posix_err < 0) {
7682934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		error("avdtp_set_configuration: %s",
7692934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			strerror(-posix_err));
7702934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		finalize_config_errno(setup, posix_err);
7712934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
7722934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
7732934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return FALSE;
7742934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
7752934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
776f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void close_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
777666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
778666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
7796763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
780666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
7812934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
782c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
783666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
784ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Close_Cfm", sep);
785666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
786ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Close_Cfm", sep);
7875402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
78803490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
7895402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (!setup)
7905402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return;
7915402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
7925402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (setup->canceled) {
7932934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup_unref(setup);
7945402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return;
7955402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
7965402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
7975402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (err) {
7985402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		setup->stream = NULL;
7995309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
8005309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		finalize_config(setup);
801847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg		return;
8025402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
8035402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
8042934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (setup->reconfigure)
805714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz		g_timeout_add(RECONFIGURE_TIMEOUT, a2dp_reconfigure, setup);
8066763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
8076763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
808f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean abort_ind(struct avdtp *session, struct avdtp_local_sep *sep,
809666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
810666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
8116763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
812666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
813c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
814666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
815ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Abort_Ind", sep);
816666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
817ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Abort_Ind", sep);
818cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
819fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	a2dp_sep->stream = NULL;
82003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
8216763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
8226763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
8236763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
824f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void abort_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
825666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
826666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
8276763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
828666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
8292934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
830c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
831666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
832ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Abort_Cfm", sep);
833666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
834ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Abort_Cfm", sep);
8352934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
8362934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup = find_setup_by_session(session);
8372934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (!setup)
8382934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		return;
8392934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
8402934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_unref(setup);
8416763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
8426763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
843f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean reconf_ind(struct avdtp *session, struct avdtp_local_sep *sep,
844666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				uint8_t *err, void *user_data)
8456763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
846666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
847666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
848666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
849ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: ReConfigure_Ind", sep);
8506763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
851ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: ReConfigure_Ind", sep);
8526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
8536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
8546763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8550f458da19471c933a4105cc450c48548b72edc8eJohan Hedbergstatic void reconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
856666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
857666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
8586763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
859666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
8602934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
861666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
862666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
863ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: ReConfigure_Cfm", sep);
8646763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
865ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: ReConfigure_Cfm", sep);
8665402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
86703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
8685402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (!setup)
8695402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return;
8705402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
8715402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (setup->canceled) {
8725402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		if (!err)
8735402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz			avdtp_close(session, stream);
8742934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup_unref(setup);
8755402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return;
8765402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
8775402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
8785402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (err) {
8795402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		setup->stream = NULL;
8805309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
8815309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		finalize_config(setup);
8825402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
883847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	else
8845309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		finalize_config_errno(setup, 0);
8856763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
8866763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8876763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic struct avdtp_sep_cfm cfm = {
8886763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.set_configuration	= setconf_cfm,
8896763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.get_configuration	= getconf_cfm,
8906763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.open			= open_cfm,
8916763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.start			= start_cfm,
8926763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.suspend		= suspend_cfm,
8936763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.close			= close_cfm,
8946763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.abort			= abort_cfm,
8956763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.reconfigure		= reconf_cfm
8966763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg};
8976763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
898489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentzstatic struct avdtp_sep_ind sbc_ind = {
899489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.get_capability		= sbc_getcap_ind,
900489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.set_configuration	= sbc_setconf_ind,
901489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.get_configuration	= getconf_ind,
902489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.open			= open_ind,
903489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.start			= start_ind,
904489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.suspend		= suspend_ind,
905489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.close			= close_ind,
906489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.abort			= abort_ind,
907489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.reconfigure		= reconf_ind
908489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz};
909489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
910489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentzstatic struct avdtp_sep_ind mpeg_ind = {
911489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.get_capability		= mpeg_getcap_ind,
912489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.set_configuration	= mpeg_setconf_ind,
9136763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.get_configuration	= getconf_ind,
9146763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.open			= open_ind,
9156763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.start			= start_ind,
9166763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.suspend		= suspend_ind,
9176763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.close			= close_ind,
9186763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.abort			= abort_ind,
9196763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.reconfigure		= reconf_ind
9206763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg};
9216763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9227299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentzstatic sdp_record_t *a2dp_source_record()
9236763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
9246763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
9256763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	uuid_t root_uuid, l2cap, avdtp, a2src;
9266763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_profile_desc_t profile[1];
9276763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_t *aproto, *proto[2];
9287299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_record_t *record;
9296763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_data_t *psm, *version, *features;
9306763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	uint16_t lp = AVDTP_UUID, ver = 0x0100, feat = 0x000F;
9316763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9327299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	record = sdp_record_alloc();
9337299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	if (!record)
9347299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz		return NULL;
9356763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9366763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
9376763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	root = sdp_list_append(0, &root_uuid);
9387299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_set_browse_groups(record, root);
9396763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9406763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_uuid16_create(&a2src, AUDIO_SOURCE_SVCLASS_ID);
9416763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	svclass_id = sdp_list_append(0, &a2src);
9427299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_set_service_classes(record, svclass_id);
9436763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9446763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID);
9456763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	profile[0].version = 0x0100;
9466763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	pfseq = sdp_list_append(0, &profile[0]);
9477299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_set_profile_descs(record, pfseq);
9486763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9496763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_uuid16_create(&l2cap, L2CAP_UUID);
9506763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	proto[0] = sdp_list_append(0, &l2cap);
9516763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	psm = sdp_data_alloc(SDP_UINT16, &lp);
9526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	proto[0] = sdp_list_append(proto[0], psm);
9536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	apseq = sdp_list_append(0, proto[0]);
9546763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9556763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_uuid16_create(&avdtp, AVDTP_UUID);
9566763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	proto[1] = sdp_list_append(0, &avdtp);
9576763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	version = sdp_data_alloc(SDP_UINT16, &ver);
9586763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	proto[1] = sdp_list_append(proto[1], version);
9596763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	apseq = sdp_list_append(apseq, proto[1]);
9606763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9616763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	aproto = sdp_list_append(0, apseq);
9627299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_set_access_protos(record, aproto);
9636763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9646763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	features = sdp_data_alloc(SDP_UINT16, &feat);
9657299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features);
9666763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9677299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_set_info_attr(record, "Audio Source", 0, 0);
9686763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	free(psm);
9706763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	free(version);
9716763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(proto[0], 0);
9726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(proto[1], 0);
9736763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(apseq, 0);
9746763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(pfseq, 0);
9756763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(aproto, 0);
9766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(root, 0);
9776763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(svclass_id, 0);
9786763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9797299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	return record;
9806763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
9816763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9827299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentzstatic sdp_record_t *a2dp_sink_record()
9836763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
9847299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	return NULL;
9856763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
9866763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
987957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentzstatic struct a2dp_sep *a2dp_add_sep(struct a2dp_server *server, uint8_t type,
988489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz					uint8_t codec)
9896763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
990666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *sep;
991666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	GSList **l;
9927299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_record_t *(*create_record)(void);
993666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	uint32_t *record_id;
9947299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_record_t *record;
995489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct avdtp_sep_ind *ind;
9966763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
997666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	sep = g_new0(struct a2dp_sep, 1);
998666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
999489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	ind = (codec == A2DP_CODEC_MPEG12) ? &mpeg_ind : &sbc_ind;
1000957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	sep->sep = avdtp_register_sep(&server->src, type,
1001957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz					AVDTP_MEDIA_TYPE_AUDIO, codec, ind,
1002957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz					&cfm, sep);
1003666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (sep->sep == NULL) {
1004666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		g_free(sep);
1005666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		return NULL;
1006666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	}
1007666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1008489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	sep->codec = codec;
1009666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	sep->type = type;
1010666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1011666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (type == AVDTP_SEP_TYPE_SOURCE) {
1012957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		l = &server->sources;
1013666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		create_record = a2dp_source_record;
1014957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		record_id = &server->source_record_id;
1015666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	} else {
1016957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		l = &server->sinks;
1017666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		create_record = a2dp_sink_record;
1018957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		record_id = &server->sink_record_id;
1019666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	}
1020666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1021666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (*record_id != 0)
1022666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		goto add;
1023666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
10247299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	record = create_record();
10257299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	if (!record) {
1026666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		error("Unable to allocate new service record");
1027666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		avdtp_unregister_sep(sep->sep);
1028666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		g_free(sep);
1029666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		return NULL;
1030666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	}
1031666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1032957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (add_record_to_server(&server->src, record) < 0) {
10337299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz		error("Unable to register A2DP service record");\
10347299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz		sdp_record_free(record);
1035666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		avdtp_unregister_sep(sep->sep);
1036666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		g_free(sep);
1037666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		return NULL;
1038666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	}
10397299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	*record_id = record->handle;
1040666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1041666938b54d631956826343ed278e2af4b982fc29Johan Hedbergadd:
1042666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	*l = g_slist_append(*l, sep);
1043666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1044666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	return sep;
1045666938b54d631956826343ed278e2af4b982fc29Johan Hedberg}
1046666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1047957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentzstatic struct a2dp_server *find_server(GSList *list, const bdaddr_t *src)
1048957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz{
1049957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	GSList *l;
1050957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1051957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	for (l = list; l; l = l->next) {
1052957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		struct a2dp_server *server = l->data;
1053957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1054957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		if (bacmp(&server->src, src) == 0)
1055957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz			return server;
1056957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	}
1057957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1058957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	return NULL;
1059957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz}
1060957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1061957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentzint a2dp_register(DBusConnection *conn, const bdaddr_t *src, GKeyFile *config)
1062666938b54d631956826343ed278e2af4b982fc29Johan Hedberg{
10635b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	int sbc_srcs = 1, sbc_sinks = 0;
10645b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	int mpeg12_srcs = 0, mpeg12_sinks = 0;
10657e64674f8b5c5be6b3cccb17ea05766763d50f94Johan Hedberg	gboolean source = TRUE, sink = TRUE;
10665b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	char *str;
10675b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	GError *err = NULL;
1068e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedberg	int i;
1069957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	struct a2dp_server *server;
1070e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedberg
10715b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (!config)
10725b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		goto proceed;
10735b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
10745b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	str = g_key_file_get_string(config, "General", "Disable", &err);
10755b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
10765b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (err) {
10775b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		debug("audio.conf: %s", err->message);
10785b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_error_free(err);
10795b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		err = NULL;
10805b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	} else {
10815b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		if (strstr(str, "Sink"))
10827e64674f8b5c5be6b3cccb17ea05766763d50f94Johan Hedberg			source = FALSE;
10835b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		if (strstr(str, "Source"))
10847e64674f8b5c5be6b3cccb17ea05766763d50f94Johan Hedberg			sink = FALSE;
10855b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_free(str);
10865b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	}
10875b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
10885b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	str = g_key_file_get_string(config, "A2DP", "SBCSources", &err);
10895b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (err) {
10905b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		debug("audio.conf: %s", err->message);
10915b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_error_free(err);
10925b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		err = NULL;
10935b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	} else {
10945b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		sbc_srcs = atoi(str);
10955b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_free(str);
10965b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	}
10975b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
10985b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	str = g_key_file_get_string(config, "A2DP", "MPEG12Sources", &err);
10995b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (err) {
11005b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		debug("audio.conf: %s", err->message);
11015b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_error_free(err);
11025b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		err = NULL;
11035b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	} else {
11045b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		mpeg12_srcs = atoi(str);
11055b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_free(str);
11065b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	}
11075b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
11085b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	str = g_key_file_get_string(config, "A2DP", "SBCSinks", &err);
11095b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (err) {
11105b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		debug("audio.conf: %s", err->message);
11115b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_error_free(err);
11125b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		err = NULL;
11135b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	} else {
11145b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		sbc_sinks = atoi(str);
11155b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_free(str);
11165b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	}
11175b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
11185b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	str = g_key_file_get_string(config, "A2DP", "MPEG12Sinks", &err);
11195b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (err) {
11205b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		debug("audio.conf: %s", err->message);
11215b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_error_free(err);
11225b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		err = NULL;
11235b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	} else {
11245b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		mpeg12_sinks = atoi(str);
11255b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_free(str);
11265b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	}
11276763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
11285b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentzproceed:
1129957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (!connection)
1130957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		connection = dbus_connection_ref(conn);
1131957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1132957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	server = find_server(servers, src);
1133957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (!server) {
1134957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		server = g_new0(struct a2dp_server, 1);
1135957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		if (!server)
1136957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz			return -ENOMEM;
1137957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		avdtp_init(src, config);
1138957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		bacpy(&server->src, src);
1139957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		servers = g_slist_append(servers, server);
1140957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	}
11416763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
11427e64674f8b5c5be6b3cccb17ea05766763d50f94Johan Hedberg	if (source) {
11435b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		for (i = 0; i < sbc_srcs; i++)
1144957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz			a2dp_add_sep(server, AVDTP_SEP_TYPE_SOURCE,
11455b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz					A2DP_CODEC_SBC);
11465b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
11475b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		for (i = 0; i < mpeg12_srcs; i++)
1148957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz			a2dp_add_sep(server, AVDTP_SEP_TYPE_SOURCE,
11495b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz					A2DP_CODEC_MPEG12);
1150489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	}
11516763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
11525b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (sink) {
11535b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		for (i = 0; i < sbc_sinks; i++)
1154957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz			a2dp_add_sep(server, AVDTP_SEP_TYPE_SINK,
11555b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz					A2DP_CODEC_SBC);
11565b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
11575b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		for (i = 0; i < mpeg12_sinks; i++)
1158957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz			a2dp_add_sep(server, AVDTP_SEP_TYPE_SINK,
11595b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz					A2DP_CODEC_MPEG12);
1160489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	}
11616763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
11626763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return 0;
11636763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
11646763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1165666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic void a2dp_unregister_sep(struct a2dp_sep *sep)
1166666938b54d631956826343ed278e2af4b982fc29Johan Hedberg{
1167666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	avdtp_unregister_sep(sep->sep);
1168666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	g_free(sep);
1169666938b54d631956826343ed278e2af4b982fc29Johan Hedberg}
1170666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1171957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentzvoid a2dp_unregister(const bdaddr_t *src)
11726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
1173957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	struct a2dp_server *server;
11746763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1175957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	server = find_server(servers, src);
1176957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (!server)
1177957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		return;
11786763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1179957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	g_slist_foreach(server->sinks, (GFunc) a2dp_unregister_sep, NULL);
1180957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	g_slist_free(server->sinks);
11816763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1182957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	g_slist_foreach(server->sources, (GFunc) a2dp_unregister_sep, NULL);
1183957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	g_slist_free(server->sources);
1184957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1185957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (server->source_record_id)
1186957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		remove_record_from_server(server->source_record_id);
1187957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1188957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (server->sink_record_id)
1189957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		remove_record_from_server(server->sink_record_id);
1190957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1191957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	servers = g_slist_remove(servers, server);
1192957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	g_free(server);
1193957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1194957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (servers)
1195957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		return;
11966763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
11976763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	dbus_connection_unref(connection);
1198957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	connection = NULL;
11996763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
12006763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1201caf9fdd6d0183afc3b21d1cd82eb637773c131deMarcel Holtmanngboolean a2dp_source_cancel(struct audio_device *dev, unsigned int id)
1202cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
12032934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup_cb *cb_data;
12042934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
1205cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	GSList *l;
1206cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
120703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_dev(dev);
1208cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!setup)
1209cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return FALSE;
1210cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1211cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	for (cb_data = NULL, l = setup->cb; l != NULL; l = g_slist_next(l)) {
12122934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		struct a2dp_setup_cb *cb = l->data;
1213cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1214cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		if (cb->id == id) {
1215cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			cb_data = cb;
1216cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			break;
1217cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		}
1218cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
1219cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1220cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!cb_data)
1221cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return FALSE;
1222cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1223cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	setup->cb = g_slist_remove(setup->cb, cb_data);
12249ce01693dd0aa7407b7d8eb37c8524dd05abe15cJohan Hedberg	g_free(cb_data);
1225cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1226828133c3180a090a06ace6637d9f84ae5f57ae33Johan Hedberg	if (!setup->cb) {
1227cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		setup->canceled = TRUE;
122803490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg		setup->sep = NULL;
1229828133c3180a090a06ace6637d9f84ae5f57ae33Johan Hedberg	}
1230cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1231cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	return TRUE;
1232cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
1233cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
12342934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzunsigned int a2dp_source_config(struct avdtp *session, a2dp_config_cb_t cb,
12352934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				GSList *caps, void *user_data)
1236cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
12372934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup_cb *cb_data;
1238666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	GSList *l;
1239957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	struct a2dp_server *server;
12402934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
1241714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz	struct a2dp_sep *sep = NULL, *tmp;
12422934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct avdtp_local_sep *lsep;
12432934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct avdtp_remote_sep *rsep;
1244489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct avdtp_service_capability *cap;
1245489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct avdtp_media_codec_capability *codec_cap = NULL;
12462934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	int posix_err;
1247957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	bdaddr_t src;
1248957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1249957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	avdtp_get_peers(session, &src, NULL);
1250957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	server = find_server(servers, &src);
1251957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (!server)
1252957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		return 0;
1253cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1254489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	for (l = caps; l != NULL; l = l->next) {
1255489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		cap = l->data;
1256489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
1257489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		if (cap->category != AVDTP_MEDIA_CODEC)
1258489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz			continue;
1259489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
1260489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		codec_cap = (void *) cap->data;
1261489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		break;
1262489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	}
1263489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
1264489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (!codec_cap)
1265489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		return 0;
1266489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
1267957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	for (l = server->sources; l != NULL; l = l->next) {
1268714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz		tmp = l->data;
1269666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1270666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		if (tmp->locked)
1271666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			continue;
1272666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1273489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		if (tmp->codec != codec_cap->media_codec_type)
1274489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz			continue;
1275489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
1276fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg		if (!tmp->stream || avdtp_has_stream(session, tmp->stream)) {
1277666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			sep = tmp;
1278666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			break;
1279666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		}
1280666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	}
1281666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1282666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (!sep) {
12832934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		error("a2dp_source_cfg: no available SEP found");
1284730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg		return 0;
1285730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg	}
1286730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg
1287ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz	debug("a2dp_source_config: selected SEP %p", sep->sep);
1288666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1289bcc1d569bcfb0cd026930eb6a8ee607a8002f523Johan Hedberg	cb_data = g_new0(struct a2dp_setup_cb, 1);
12902934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->config_cb = cb;
1291cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	cb_data->user_data = user_data;
12920f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	cb_data->id = ++cb_id;
1293cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
12942934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup = find_setup_by_session(session);
12952934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (!setup) {
12962934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup = g_new0(struct a2dp_setup, 1);
12972934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup->session = avdtp_ref(session);
12982934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setups = g_slist_append(setups, setup);
1299cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
1300cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
13012934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_ref(setup);
1302cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	setup->cb = g_slist_append(setup->cb, cb_data);
13032934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->sep = sep;
1304666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	setup->stream = sep->stream;
13052934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->client_caps = caps;
1306cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1307666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	switch (avdtp_sep_get_state(sep->sep)) {
1308cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_IDLE:
1309957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		for (l = server->sources; l != NULL; l = l->next) {
1310714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz			tmp = l->data;
1311714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz
1312714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz			if (avdtp_has_stream(session, tmp->stream))
1313714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz				break;
1314714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz		}
1315714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz
1316714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz		if (l != NULL) {
1317714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz			setup->reconfigure = TRUE;
1318714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz			if (avdtp_close(session, tmp->stream) < 0) {
1319714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz				error("avdtp_close failed");
1320714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz				goto failed;
1321714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz			}
1322714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz			break;
1323714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz		}
1324714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz
13252934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (avdtp_get_seps(session, AVDTP_SEP_TYPE_SINK,
1326489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				codec_cap->media_type,
1327489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				codec_cap->media_codec_type,
13282934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				&lsep, &rsep) < 0) {
13292934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			error("No matching ACP and INT SEPs found");
13302934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			goto failed;
13312934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		}
13322934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
13332934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		posix_err = avdtp_set_configuration(session, rsep, lsep,
13342934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz							caps, &setup->stream);
13352934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (posix_err < 0) {
13362934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			error("avdtp_set_configuration: %s",
13372934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				strerror(-posix_err));
1338cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			goto failed;
1339730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg		}
1340cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
1341cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_OPEN:
13422934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_STREAMING:
13432934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (avdtp_stream_has_capabilities(setup->stream, caps))
13442934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			g_idle_add((GSourceFunc) finalize_config, setup);
13452934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		else if (!setup->reconfigure) {
13462934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			setup->reconfigure = TRUE;
13472934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			if (avdtp_close(session, sep->stream) < 0) {
13482934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				error("avdtp_close failed");
13492934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				goto failed;
13505402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz			}
13515402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		}
13522934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
13532934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	default:
13542934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		error("SEP in bad state for requesting a new stream");
13552934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		goto failed;
13562934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
13572934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
13582934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return cb_data->id;
13592934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
13602934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzfailed:
13612934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_unref(setup);
13622934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_id--;
13632934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return 0;
13642934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
13652934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
13662934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzunsigned int a2dp_source_resume(struct avdtp *session, struct a2dp_sep *sep,
13672934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				a2dp_stream_cb_t cb, void *user_data)
13682934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
13692934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup_cb *cb_data;
13702934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
13712934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
137270f4ad8b4bf7d477bcfc7efdec7f25b1f9517cd3Johan Hedberg	cb_data = g_new0(struct a2dp_setup_cb, 1);
13732934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->resume_cb = cb;
13742934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->user_data = user_data;
13752934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->id = ++cb_id;
13762934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
13772934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup = find_setup_by_session(session);
13782934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (!setup) {
13792934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup = g_new0(struct a2dp_setup, 1);
13802934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup->session = avdtp_ref(session);
13812934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setups = g_slist_append(setups, setup);
13822934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
13832934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
13842934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_ref(setup);
13852934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->cb = g_slist_append(setup->cb, cb_data);
13862934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->sep = sep;
13872934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->stream = sep->stream;
13882934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
13892934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	switch (avdtp_sep_get_state(sep->sep)) {
13902934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_IDLE:
13912934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		goto failed;
13922934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
13932934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_OPEN:
13942934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (avdtp_start(session, sep->stream) < 0) {
1395730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg			error("avdtp_start failed");
1396cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			goto failed;
1397730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg		}
1398cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
1399cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_STREAMING:
14002934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (!sep->suspending && sep->suspend_timer) {
14012934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			g_source_remove(sep->suspend_timer);
14022934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			sep->suspend_timer = 0;
14032934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			avdtp_unref(sep->session);
14042934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			sep->session = NULL;
1405cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		}
14063f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg		if (sep->suspending)
14073f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg			setup->start = TRUE;
14083f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg		else
14093f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg			g_idle_add((GSourceFunc) finalize_resume, setup);
1410cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
1411cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	default:
14122934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		error("SEP in bad state");
1413cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		goto failed;
1414cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
14155402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
14162934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return cb_data->id;
14172934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
14182934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzfailed:
14192934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_unref(setup);
14202934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_id--;
14212934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return 0;
14222934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
14232934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
14242934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzunsigned int a2dp_source_suspend(struct avdtp *session, struct a2dp_sep *sep,
14252934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				a2dp_stream_cb_t cb, void *user_data)
14262934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
14272934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup_cb *cb_data;
14282934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
14292934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1430bcc1d569bcfb0cd026930eb6a8ee607a8002f523Johan Hedberg	cb_data = g_new0(struct a2dp_setup_cb, 1);
14312934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->suspend_cb = cb;
14322934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->user_data = user_data;
14332934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->id = ++cb_id;
14342934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
14352934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup = find_setup_by_session(session);
14362934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (!setup) {
14372934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup = g_new0(struct a2dp_setup, 1);
14382934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup->session = avdtp_ref(session);
14392934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setups = g_slist_append(setups, setup);
14402934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
14412934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
14422934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_ref(setup);
14432934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->cb = g_slist_append(setup->cb, cb_data);
14442934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->sep = sep;
14452934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->stream = sep->stream;
14462934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
14472934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	switch (avdtp_sep_get_state(sep->sep)) {
14482934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_IDLE:
14492934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		error("a2dp_source_suspend: no stream to suspend");
14502934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		goto failed;
14512934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
14522934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_OPEN:
14532934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		g_idle_add((GSourceFunc) finalize_suspend, setup);
14542934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
14552934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_STREAMING:
1456c020b7240f8f6b72ffbb6c6f327a63f2da14e6a9Johan Hedberg		if (avdtp_suspend(session, sep->stream) < 0) {
1457c020b7240f8f6b72ffbb6c6f327a63f2da14e6a9Johan Hedberg			error("avdtp_suspend failed");
14582934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			goto failed;
14592934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		}
14602934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
14612934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	default:
14622934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		error("SEP in bad state for resume");
14632934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		goto failed;
14642934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
146503490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
1466cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	return cb_data->id;
1467cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1468cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergfailed:
14692934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_unref(setup);
1470cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	cb_id--;
14710f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	return 0;
1472cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
1473cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1474fc0d501d82773718d0f2d040f786136332c39813Johan Hedberggboolean a2dp_sep_lock(struct a2dp_sep *sep, struct avdtp *session)
1475cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
1476fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	if (sep->locked)
1477fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg		return FALSE;
1478f4211a3cd3442d54fa7877a6c421bee034d46e8eJohan Hedberg
1479ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz	debug("SEP %p locked", sep->sep);
1480fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	sep->locked = TRUE;
1481666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1482fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	return TRUE;
1483cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
1484cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1485fc0d501d82773718d0f2d040f786136332c39813Johan Hedberggboolean a2dp_sep_unlock(struct a2dp_sep *sep, struct avdtp *session)
1486cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
1487cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	avdtp_state_t state;
1488cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1489666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	state = avdtp_sep_get_state(sep->sep);
1490cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1491666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	sep->locked = FALSE;
1492cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1493ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz	debug("SEP %p unlocked", sep->sep);
1494730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg
1495666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (!sep->stream || state == AVDTP_STATE_IDLE)
1496cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return TRUE;
1497cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1498cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	switch (state) {
1499cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_OPEN:
1500cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		/* Set timer here */
1501cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
1502cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_STREAMING:
1503666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		if (avdtp_suspend(session, sep->stream) == 0)
1504666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			sep->suspending = TRUE;
1505cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
1506cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	default:
1507cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
1508cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
1509cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1510cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	return TRUE;
1511cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
1512cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1513