a2dp.c revision 7ec871d37de442fd3731a0eef319851c61fb04cc
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. */
497ec871d37de442fd3731a0eef319851c61fb04ccLuiz Augusto von Dentz#define SUSPEND_TIMEOUT 5
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
1955309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentzstatic gboolean finalize_suspend(struct a2dp_setup *s)
1962934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
1972934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	GSList *l;
1982934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1992934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_ref(s);
2002934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	for (l = s->cb; l != NULL; l = l->next) {
2012934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		struct a2dp_setup_cb *cb = l->data;
2022934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2032934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (cb->suspend_cb) {
2045309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz			cb->suspend_cb(s->session, s->err, cb->user_data);
2052934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			cb->suspend_cb = NULL;
2062934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			setup_unref(s);
2072934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		}
2082934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
2092934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2102934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_unref(s);
2112934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return FALSE;
2122934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
2132934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2142934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic gboolean finalize_suspend_errno(struct a2dp_setup *s, int err)
2152934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
2162934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct avdtp_error avdtp_err;
2172934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2182934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	avdtp_error_init(&avdtp_err, AVDTP_ERROR_ERRNO, -err);
2195309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	s->err = err ? &avdtp_err : NULL;
2202934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2215309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	return finalize_suspend(s);
2222934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
2232934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2242934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic struct a2dp_setup *find_setup_by_session(struct avdtp *session)
22503490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg{
22603490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	GSList *l;
22703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
22803490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	for (l = setups; l != NULL; l = l->next) {
2292934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		struct a2dp_setup *setup = l->data;
23003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
23103490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg		if (setup->session == session)
23203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg			return setup;
23303490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	}
23403490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
23503490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	return NULL;
23603490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg}
23703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
238caf9fdd6d0183afc3b21d1cd82eb637773c131deMarcel Holtmannstatic struct a2dp_setup *find_setup_by_dev(struct audio_device *dev)
23903490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg{
24003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	GSList *l;
24103490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
24203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	for (l = setups; l != NULL; l = l->next) {
2432934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		struct a2dp_setup *setup = l->data;
244caf9fdd6d0183afc3b21d1cd82eb637773c131deMarcel Holtmann		struct audio_device *setup_dev = a2dp_get_dev(setup->session);
24503490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
246fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg		if (setup_dev == dev)
24703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg			return setup;
24803490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	}
24903490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
25003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	return NULL;
25103490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg}
25203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
2537a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedbergstatic void stream_state_changed(struct avdtp_stream *stream,
2547a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg					avdtp_state_t old_state,
2557a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg					avdtp_state_t new_state,
2567a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg					struct avdtp_error *err,
2577a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg					void *user_data)
2587a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg{
2597a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	struct a2dp_sep *sep = user_data;
2607a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg
2617a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	if (new_state != AVDTP_STATE_IDLE)
2627a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		return;
2637a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg
2647a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	if (sep->suspend_timer) {
2657a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		g_source_remove(sep->suspend_timer);
2667a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		sep->suspend_timer = 0;
2677a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	}
2687a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg
2697a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	if (sep->session) {
2707a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		avdtp_unref(sep->session);
2717a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		sep->session = NULL;
2727a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	}
2731ddd76afa25d775788e3762ab731cad80f8ffe56Johan Hedberg
2747a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	sep->stream = NULL;
2755402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
2765402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz}
2775402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
278489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentzstatic gboolean sbc_setconf_ind(struct avdtp *session,
279f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg				struct avdtp_local_sep *sep,
2806763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg				struct avdtp_stream *stream,
281f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg				GSList *caps, uint8_t *err,
282666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				uint8_t *category, void *user_data)
2836763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
284666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
285caf9fdd6d0183afc3b21d1cd82eb637773c131deMarcel Holtmann	struct audio_device *dev;
286c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	struct avdtp_service_capability *cap;
287c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	struct avdtp_media_codec_capability *codec_cap;
288c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	struct sbc_codec_cap *sbc_cap;
289f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg
290666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
291ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Set_Configuration_Ind", sep);
292666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
293ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Set_Configuration_Ind", sep);
294f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg
295fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	dev = a2dp_get_dev(session);
296f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg	if (!dev) {
297f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg		*err = AVDTP_UNSUPPORTED_CONFIGURATION;
298f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg		*category = 0x00;
299f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg		return FALSE;
300f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg	}
301f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg
302c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	/* Check bipool range */
303c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	for (codec_cap = NULL; caps; caps = g_slist_next(caps)) {
304c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz		cap = caps->data;
305c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz		if (cap->category == AVDTP_MEDIA_CODEC) {
306c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz			codec_cap = (void *) cap->data;
307c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz			if (codec_cap->media_codec_type == A2DP_CODEC_SBC) {
308c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz				sbc_cap = (void *) codec_cap;
309c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz				if (sbc_cap->min_bitpool < MIN_BITPOOL ||
310c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz					sbc_cap->max_bitpool > MAX_BITPOOL) {
311c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz					*err = AVDTP_UNSUPPORTED_CONFIGURATION;
312c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz					*category = AVDTP_MEDIA_CODEC;
313c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz					return FALSE;
314c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz				}
315c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz			}
316c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz			break;
317c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz		}
318c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	}
319c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz
3207a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep);
321c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	a2dp_sep->stream = stream;
322cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
323666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE)
324c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg		sink_new_stream(dev, session, stream);
3256763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3266763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
3276763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
3286763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
329489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentzstatic gboolean sbc_getcap_ind(struct avdtp *session, struct avdtp_local_sep *sep,
330666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				GSList **caps, uint8_t *err, void *user_data)
3316763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
332666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
3336763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	struct avdtp_service_capability *media_transport, *media_codec;
3346763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	struct sbc_codec_cap sbc_cap;
3356763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
336666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
337ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Get_Capability_Ind", sep);
3386763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
339ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Get_Capability_Ind", sep);
3406763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3416763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	*caps = NULL;
3426763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3436763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
3446763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg						NULL, 0);
3456763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3466763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	*caps = g_slist_append(*caps, media_transport);
3476763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3486763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	memset(&sbc_cap, 0, sizeof(struct sbc_codec_cap));
3496763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3506763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sbc_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO;
3516763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sbc_cap.cap.media_codec_type = A2DP_CODEC_SBC;
3526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3539ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz	sbc_cap.frequency = ( SBC_SAMPLING_FREQ_48000 |
3549ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz				SBC_SAMPLING_FREQ_44100 |
3559ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz				SBC_SAMPLING_FREQ_32000 |
3569ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz				SBC_SAMPLING_FREQ_16000 );
3576763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3589ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz	sbc_cap.channel_mode = ( SBC_CHANNEL_MODE_JOINT_STEREO |
3599ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_CHANNEL_MODE_STEREO |
3609ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_CHANNEL_MODE_DUAL_CHANNEL |
3619ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_CHANNEL_MODE_MONO );
3626763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3639ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz	sbc_cap.block_length = ( SBC_BLOCK_LENGTH_16 |
3649ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_BLOCK_LENGTH_12 |
3659ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_BLOCK_LENGTH_8 |
3669ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_BLOCK_LENGTH_4 );
3676763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3689ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz	sbc_cap.subbands = ( SBC_SUBBANDS_8 | SBC_SUBBANDS_4 );
3696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3709ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz	sbc_cap.allocation_method = ( SBC_ALLOCATION_LOUDNESS |
3719ae63b37bb909c66a931ee3934af1ad87047f326Luiz Augusto von Dentz					SBC_ALLOCATION_SNR );
3726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
373c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	sbc_cap.min_bitpool = MIN_BITPOOL;
374c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	sbc_cap.max_bitpool = MAX_BITPOOL;
3756763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &sbc_cap,
3776763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg						sizeof(sbc_cap));
3786763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3796763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	*caps = g_slist_append(*caps, media_codec);
3806763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3816763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
3826763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
3836763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
384489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentzstatic gboolean mpeg_setconf_ind(struct avdtp *session,
385489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				struct avdtp_local_sep *sep,
386489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				struct avdtp_stream *stream,
387489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				GSList *caps, uint8_t *err,
388489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				uint8_t *category, void *user_data)
389489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz{
390489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct a2dp_sep *a2dp_sep = user_data;
391caf9fdd6d0183afc3b21d1cd82eb637773c131deMarcel Holtmann	struct audio_device *dev;
392489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
393489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
394ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Set_Configuration_Ind", sep);
395489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	else
396ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Set_Configuration_Ind", sep);
397489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
398489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	dev = a2dp_get_dev(session);
399489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (!dev) {
400489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		*err = AVDTP_UNSUPPORTED_CONFIGURATION;
401489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		*category = 0x00;
402489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		return FALSE;
403489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	}
404489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
405489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep);
406489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	a2dp_sep->stream = stream;
407489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
408489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE)
409489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		sink_new_stream(dev, session, stream);
410489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
411489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	return TRUE;
412489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz}
413489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
414ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentzstatic gboolean mpeg_getcap_ind(struct avdtp *session,
415ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz				struct avdtp_local_sep *sep,
416489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				GSList **caps, uint8_t *err, void *user_data)
417489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz{
418489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct a2dp_sep *a2dp_sep = user_data;
419489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct avdtp_service_capability *media_transport, *media_codec;
420489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct mpeg_codec_cap mpeg_cap;
421489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
422489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
423ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Get_Capability_Ind", sep);
424489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	else
425ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Get_Capability_Ind", sep);
426489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
427489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	*caps = NULL;
428489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
429489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
430489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz						NULL, 0);
431489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
432489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	*caps = g_slist_append(*caps, media_transport);
433489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
434489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	memset(&mpeg_cap, 0, sizeof(struct mpeg_codec_cap));
435489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
436489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO;
437489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_cap.cap.media_codec_type = A2DP_CODEC_MPEG12;
438489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
439489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_cap.frequency = ( MPEG_SAMPLING_FREQ_48000 |
440489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				MPEG_SAMPLING_FREQ_44100 |
441489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				MPEG_SAMPLING_FREQ_32000 |
442489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				MPEG_SAMPLING_FREQ_24000 |
443489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				MPEG_SAMPLING_FREQ_22050 |
444489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				MPEG_SAMPLING_FREQ_16000 );
445489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
446489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_cap.channel_mode = ( MPEG_CHANNEL_MODE_JOINT_STEREO |
447489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz					MPEG_CHANNEL_MODE_STEREO |
448489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz					MPEG_CHANNEL_MODE_DUAL_CHANNEL |
449489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz					MPEG_CHANNEL_MODE_MONO );
450489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
451489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_cap.layer = ( MPEG_LAYER_MP3 | MPEG_LAYER_MP2 | MPEG_LAYER_MP1 );
452489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
453489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	mpeg_cap.bitrate = 0xFFFF;
454489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
455489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &mpeg_cap,
456489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz						sizeof(mpeg_cap));
457489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
458489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	*caps = g_slist_append(*caps, media_codec);
459489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
460489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	return TRUE;
461489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz}
462489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
463f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
4640f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg				struct avdtp_stream *stream,
465666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_error *err, void *user_data)
4666763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
467666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
4682934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
469caf9fdd6d0183afc3b21d1cd82eb637773c131deMarcel Holtmann	struct audio_device *dev;
4700f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	int ret;
471cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
472666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
473ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Set_Configuration_Cfm", sep);
474666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
475ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Set_Configuration_Cfm", sep);
476cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
47703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
47803490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
4790f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (err) {
4805309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		if (setup) {
4815309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz			setup->err = err;
4825309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz			finalize_config(setup);
4835309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		}
4840f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		return;
4850f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	}
4860f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg
4877a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep);
488c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	a2dp_sep->stream = stream;
489cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
490cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!setup)
491cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return;
492cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
493fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	dev = a2dp_get_dev(session);
494fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg
49567d1e1774b3ff2d7a09fcf49484515bd85c02d14Johan Hedberg	/* Notify sink.c of the new stream */
496fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	sink_new_stream(dev, session, setup->stream);
49767d1e1774b3ff2d7a09fcf49484515bd85c02d14Johan Hedberg
4980f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	ret = avdtp_open(session, stream);
4990f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (ret < 0) {
5000f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		error("Error on avdtp_open %s (%d)", strerror(-ret),
5010f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg				-ret);
5027a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		setup->stream = NULL;
5032934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		finalize_config_errno(setup, ret);
504cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
5056763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
5066763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
507f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean getconf_ind(struct avdtp *session, struct avdtp_local_sep *sep,
508666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				uint8_t *err, void *user_data)
5096763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
510666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
511666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
512666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
513ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Get_Configuration_Ind");
5146763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
515ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Get_Configuration_Ind");
5166763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
5176763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
5186763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
519f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void getconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
520666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
521666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
5226763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
523666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
524666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
525666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
526ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Set_Configuration_Cfm", sep);
5276763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
528ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Set_Configuration_Cfm", sep);
5296763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
5306763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
531f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean open_ind(struct avdtp *session, struct avdtp_local_sep *sep,
532666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
533666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
5346763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
535666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
536666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
537666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
538ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Open_Ind", sep);
5396763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
540ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Open_Ind", sep);
5416763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
5426763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
5436763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
544f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void open_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
545666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
546666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
5476763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
548666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
5492934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
550666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
551666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
552ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Open_Cfm", sep);
5536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
554ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Open_Cfm", sep);
5551addff77624b54445c9b81779ddc78892a126a45Johan Hedberg
55603490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
557cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!setup)
5581addff77624b54445c9b81779ddc78892a126a45Johan Hedberg		return;
5591addff77624b54445c9b81779ddc78892a126a45Johan Hedberg
560cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (setup->canceled) {
5610f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		if (!err)
5620f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg			avdtp_close(session, stream);
5632934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup_unref(setup);
564cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return;
565cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
566cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
5672934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (setup->reconfigure)
5682934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup->reconfigure = FALSE;
5692934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
5700f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (err) {
5710f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		setup->stream = NULL;
5725309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
5735402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
574d78f1f6ca28f2744af70bf189837e4c1b06b4eb8Johan Hedberg
575d78f1f6ca28f2744af70bf189837e4c1b06b4eb8Johan Hedberg	finalize_config(setup);
5766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
5776763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
578c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedbergstatic gboolean suspend_timeout(struct a2dp_sep *sep)
579c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg{
580c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	if (avdtp_suspend(sep->session, sep->stream) == 0)
581c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg		sep->suspending = TRUE;
582c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
5837a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	sep->suspend_timer = 0;
584c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
585c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	avdtp_unref(sep->session);
586c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	sep->session = NULL;
587c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
588c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	return FALSE;
589c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg}
590c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
591f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean start_ind(struct avdtp *session, struct avdtp_local_sep *sep,
592666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
593666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
5946763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
595666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
596df8226b1584a200a81bea35e41d36f03fbafe408Johan Hedberg	struct a2dp_setup *setup;
597c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
598666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
599ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Start_Ind", sep);
600666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
601ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Start_Ind", sep);
6025b5cfaadb312600c58362617080e29fbf036712cJohan Hedberg
603df8226b1584a200a81bea35e41d36f03fbafe408Johan Hedberg	setup = find_setup_by_session(session);
604df8226b1584a200a81bea35e41d36f03fbafe408Johan Hedberg	if (setup) {
605df8226b1584a200a81bea35e41d36f03fbafe408Johan Hedberg		if (setup->canceled)
606df8226b1584a200a81bea35e41d36f03fbafe408Johan Hedberg			setup_unref(setup);
607df8226b1584a200a81bea35e41d36f03fbafe408Johan Hedberg		else
608df8226b1584a200a81bea35e41d36f03fbafe408Johan Hedberg			finalize_resume(setup);
609df8226b1584a200a81bea35e41d36f03fbafe408Johan Hedberg	}
610df8226b1584a200a81bea35e41d36f03fbafe408Johan Hedberg
611f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg	if (!a2dp_sep->locked) {
612f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg		a2dp_sep->session = avdtp_ref(session);
6137ec871d37de442fd3731a0eef319851c61fb04ccLuiz Augusto von Dentz		a2dp_sep->suspend_timer = g_timeout_add_seconds(SUSPEND_TIMEOUT,
614c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg						(GSourceFunc) suspend_timeout,
615c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg						a2dp_sep);
616f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg	}
617f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg
618c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	return TRUE;
6196763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
6206763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
621f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void start_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
622666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
623666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
6246763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
625666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
6262934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
627666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
628666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
629ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Start_Cfm", sep);
6306763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
631ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Start_Cfm", sep);
632cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
63303490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
634cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!setup)
635cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return;
636cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
637cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (setup->canceled) {
6380f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		if (!err)
6390f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg			avdtp_close(session, stream);
6402934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup_unref(setup);
641cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return;
642cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
643cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
644847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	if (err) {
6450f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		setup->stream = NULL;
6465309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
647847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	}
648d78f1f6ca28f2744af70bf189837e4c1b06b4eb8Johan Hedberg
649d78f1f6ca28f2744af70bf189837e4c1b06b4eb8Johan Hedberg	finalize_resume(setup);
6506763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
6516763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
652f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean suspend_ind(struct avdtp *session, struct avdtp_local_sep *sep,
653666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
654666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
6556763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
656666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
657666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
658666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
659ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Suspend_Ind", sep);
6606763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
661ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Suspend_Ind", sep);
662d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg
663d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg	if (a2dp_sep->suspend_timer) {
664d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg		g_source_remove(a2dp_sep->suspend_timer);
66586898be87d24991e48d783b3e20696ff1ce62abcJohan Hedberg		a2dp_sep->suspend_timer = 0;
666f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg		avdtp_unref(a2dp_sep->session);
667f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg		a2dp_sep->session = NULL;
668d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg	}
669d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg
6706763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
6716763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
6726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
673f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void suspend_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
674666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
675666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
6766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
677666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
6782934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
6793f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	gboolean start;
680c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
681666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
682ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Suspend_Cfm", sep);
683666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
684ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Suspend_Cfm", sep);
685cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
686c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	a2dp_sep->suspending = FALSE;
687cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
68803490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
68903490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	if (!setup)
69003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg		return;
69103490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
6923f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	start = setup->start;
6933f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	setup->start = FALSE;
6943f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg
6950f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (err) {
6962934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup->stream = NULL;
6975309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
6985309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		finalize_suspend(setup);
699cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
7002934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	else
7012934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		finalize_suspend_errno(setup, 0);
7023f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg
7033f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	if (!start)
7043f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg		return;
7053f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg
7065309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	if (err) {
7075309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
7085309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		finalize_suspend(setup);
7095309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	} else if (avdtp_start(session, a2dp_sep->stream) < 0) {
7103f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg		struct avdtp_error start_err;
7113f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg		error("avdtp_start failed");
7123f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg		avdtp_error_init(&start_err, AVDTP_ERROR_ERRNO, EIO);
7135309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
7145309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		finalize_suspend(setup);
7153f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	}
7166763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
7176763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
718f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean close_ind(struct avdtp *session, struct avdtp_local_sep *sep,
719666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
720666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
7216763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
722666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
723c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
724666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
725ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Close_Ind", sep);
726666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
727ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Close_Ind", sep);
728cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
7296763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
7306763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
7316763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
732714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentzstatic gboolean a2dp_reconfigure(gpointer data)
7332934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
7342934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup = data;
7352934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct avdtp_local_sep *lsep;
7362934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct avdtp_remote_sep *rsep;
737714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz	struct avdtp_service_capability *cap;
738714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz	struct avdtp_media_codec_capability *codec_cap = NULL;
739714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz	GSList *l;
7402934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	int posix_err;
7412934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
742714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz	for (l = setup->client_caps; l != NULL; l = l->next) {
743714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz		cap = l->data;
744714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz
745714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz		if (cap->category != AVDTP_MEDIA_CODEC)
746714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz			continue;
747714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz
748714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz		codec_cap = (void *) cap->data;
749714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz		break;
750714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz	}
751714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz
7522934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	posix_err = avdtp_get_seps(setup->session, AVDTP_SEP_TYPE_SINK,
753714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz					codec_cap->media_type,
754714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz					codec_cap->media_codec_type,
7552934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz					&lsep, &rsep);
7562934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (posix_err < 0) {
7572934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		error("No matching ACP and INT SEPs found");
7582934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		finalize_config_errno(setup, posix_err);
7592934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
7602934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
7612934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	posix_err = avdtp_set_configuration(setup->session, rsep, lsep,
7622934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz						setup->client_caps,
7632934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz						&setup->stream);
7642934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (posix_err < 0) {
7652934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		error("avdtp_set_configuration: %s",
7662934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			strerror(-posix_err));
7672934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		finalize_config_errno(setup, posix_err);
7682934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
7692934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
7702934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return FALSE;
7712934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
7722934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
773f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void close_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
774666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
775666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
7766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
777666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
7782934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
779c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
780666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
781ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Close_Cfm", sep);
782666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
783ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Close_Cfm", sep);
7845402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
78503490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
7865402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (!setup)
7875402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return;
7885402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
7895402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (setup->canceled) {
7902934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup_unref(setup);
7915402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return;
7925402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
7935402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
7945402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (err) {
7955402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		setup->stream = NULL;
7965309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
7975309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		finalize_config(setup);
798847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg		return;
7995402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
8005402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
8012934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (setup->reconfigure)
802714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz		g_timeout_add(RECONFIGURE_TIMEOUT, a2dp_reconfigure, setup);
8036763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
8046763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
805f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean abort_ind(struct avdtp *session, struct avdtp_local_sep *sep,
806666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
807666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
8086763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
809666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
810c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
811666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
812ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Abort_Ind", sep);
813666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
814ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Abort_Ind", sep);
815cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
816fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	a2dp_sep->stream = NULL;
81703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
8186763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
8196763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
8206763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
821f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void abort_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
822666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
823666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
8246763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
825666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
8262934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
827c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
828666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
829ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: Abort_Cfm", sep);
830666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
831ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: Abort_Cfm", sep);
8322934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
8332934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup = find_setup_by_session(session);
8342934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (!setup)
8352934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		return;
8362934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
8372934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_unref(setup);
8386763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
8396763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
840f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean reconf_ind(struct avdtp *session, struct avdtp_local_sep *sep,
841666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				uint8_t *err, void *user_data)
8426763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
843666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
844666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
845666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
846ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: ReConfigure_Ind", sep);
8476763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
848ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: ReConfigure_Ind", sep);
8496763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
8506763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
8516763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8520f458da19471c933a4105cc450c48548b72edc8eJohan Hedbergstatic void reconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
853666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
854666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
8556763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
856666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
8572934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
858666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
859666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
860ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Sink %p: ReConfigure_Cfm", sep);
8616763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
862ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz		debug("Source %p: ReConfigure_Cfm", sep);
8635402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
86403490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
8655402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (!setup)
8665402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return;
8675402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
8685402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (setup->canceled) {
8695402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		if (!err)
8705402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz			avdtp_close(session, stream);
8712934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup_unref(setup);
8725402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return;
8735402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
8745402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
8755402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (err) {
8765402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		setup->stream = NULL;
8775309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
8785402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
879d78f1f6ca28f2744af70bf189837e4c1b06b4eb8Johan Hedberg
880d78f1f6ca28f2744af70bf189837e4c1b06b4eb8Johan Hedberg	finalize_config(setup);
8816763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
8826763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8836763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic struct avdtp_sep_cfm cfm = {
8846763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.set_configuration	= setconf_cfm,
8856763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.get_configuration	= getconf_cfm,
8866763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.open			= open_cfm,
8876763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.start			= start_cfm,
8886763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.suspend		= suspend_cfm,
8896763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.close			= close_cfm,
8906763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.abort			= abort_cfm,
8916763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.reconfigure		= reconf_cfm
8926763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg};
8936763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
894489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentzstatic struct avdtp_sep_ind sbc_ind = {
895489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.get_capability		= sbc_getcap_ind,
896489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.set_configuration	= sbc_setconf_ind,
897489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.get_configuration	= getconf_ind,
898489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.open			= open_ind,
899489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.start			= start_ind,
900489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.suspend		= suspend_ind,
901489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.close			= close_ind,
902489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.abort			= abort_ind,
903489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.reconfigure		= reconf_ind
904489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz};
905489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
906489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentzstatic struct avdtp_sep_ind mpeg_ind = {
907489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.get_capability		= mpeg_getcap_ind,
908489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	.set_configuration	= mpeg_setconf_ind,
9096763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.get_configuration	= getconf_ind,
9106763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.open			= open_ind,
9116763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.start			= start_ind,
9126763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.suspend		= suspend_ind,
9136763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.close			= close_ind,
9146763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.abort			= abort_ind,
9156763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.reconfigure		= reconf_ind
9166763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg};
9176763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9187299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentzstatic sdp_record_t *a2dp_source_record()
9196763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
9206763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
9216763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	uuid_t root_uuid, l2cap, avdtp, a2src;
9226763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_profile_desc_t profile[1];
9236763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_t *aproto, *proto[2];
9247299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_record_t *record;
9256763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_data_t *psm, *version, *features;
9266763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	uint16_t lp = AVDTP_UUID, ver = 0x0100, feat = 0x000F;
9276763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9287299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	record = sdp_record_alloc();
9297299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	if (!record)
9307299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz		return NULL;
9316763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
9336763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	root = sdp_list_append(0, &root_uuid);
9347299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_set_browse_groups(record, root);
9356763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9366763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_uuid16_create(&a2src, AUDIO_SOURCE_SVCLASS_ID);
9376763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	svclass_id = sdp_list_append(0, &a2src);
9387299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_set_service_classes(record, svclass_id);
9396763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9406763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID);
9416763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	profile[0].version = 0x0100;
9426763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	pfseq = sdp_list_append(0, &profile[0]);
9437299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_set_profile_descs(record, pfseq);
9446763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9456763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_uuid16_create(&l2cap, L2CAP_UUID);
9466763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	proto[0] = sdp_list_append(0, &l2cap);
9476763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	psm = sdp_data_alloc(SDP_UINT16, &lp);
9486763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	proto[0] = sdp_list_append(proto[0], psm);
9496763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	apseq = sdp_list_append(0, proto[0]);
9506763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9516763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_uuid16_create(&avdtp, AVDTP_UUID);
9526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	proto[1] = sdp_list_append(0, &avdtp);
9536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	version = sdp_data_alloc(SDP_UINT16, &ver);
9546763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	proto[1] = sdp_list_append(proto[1], version);
9556763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	apseq = sdp_list_append(apseq, proto[1]);
9566763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9576763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	aproto = sdp_list_append(0, apseq);
9587299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_set_access_protos(record, aproto);
9596763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9606763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	features = sdp_data_alloc(SDP_UINT16, &feat);
9617299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_attr_add(record, SDP_ATTR_SUPPORTED_FEATURES, features);
9626763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9637299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_set_info_attr(record, "Audio Source", 0, 0);
9646763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9656763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	free(psm);
9666763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	free(version);
9676763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(proto[0], 0);
9686763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(proto[1], 0);
9696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(apseq, 0);
9706763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(pfseq, 0);
9716763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(aproto, 0);
9726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(root, 0);
9736763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(svclass_id, 0);
9746763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9757299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	return record;
9766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
9776763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9787299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentzstatic sdp_record_t *a2dp_sink_record()
9796763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
9807299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	return NULL;
9816763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
9826763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
983957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentzstatic struct a2dp_sep *a2dp_add_sep(struct a2dp_server *server, uint8_t type,
984489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz					uint8_t codec)
9856763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
986666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *sep;
987666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	GSList **l;
9887299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_record_t *(*create_record)(void);
989666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	uint32_t *record_id;
9907299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	sdp_record_t *record;
991489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct avdtp_sep_ind *ind;
9926763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
993666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	sep = g_new0(struct a2dp_sep, 1);
994666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
995489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	ind = (codec == A2DP_CODEC_MPEG12) ? &mpeg_ind : &sbc_ind;
996957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	sep->sep = avdtp_register_sep(&server->src, type,
997957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz					AVDTP_MEDIA_TYPE_AUDIO, codec, ind,
998957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz					&cfm, sep);
999666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (sep->sep == NULL) {
1000666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		g_free(sep);
1001666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		return NULL;
1002666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	}
1003666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1004489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	sep->codec = codec;
1005666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	sep->type = type;
1006666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1007666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (type == AVDTP_SEP_TYPE_SOURCE) {
1008957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		l = &server->sources;
1009666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		create_record = a2dp_source_record;
1010957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		record_id = &server->source_record_id;
1011666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	} else {
1012957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		l = &server->sinks;
1013666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		create_record = a2dp_sink_record;
1014957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		record_id = &server->sink_record_id;
1015666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	}
1016666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1017666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (*record_id != 0)
1018666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		goto add;
1019666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
10207299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	record = create_record();
10217299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	if (!record) {
1022666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		error("Unable to allocate new service record");
1023666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		avdtp_unregister_sep(sep->sep);
1024666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		g_free(sep);
1025666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		return NULL;
1026666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	}
1027666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1028957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (add_record_to_server(&server->src, record) < 0) {
10297299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz		error("Unable to register A2DP service record");\
10307299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz		sdp_record_free(record);
1031666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		avdtp_unregister_sep(sep->sep);
1032666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		g_free(sep);
1033666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		return NULL;
1034666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	}
10357299869ac79b76564cd68411acb18f4233ddbbb7Luiz Augusto von Dentz	*record_id = record->handle;
1036666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1037666938b54d631956826343ed278e2af4b982fc29Johan Hedbergadd:
1038666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	*l = g_slist_append(*l, sep);
1039666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1040666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	return sep;
1041666938b54d631956826343ed278e2af4b982fc29Johan Hedberg}
1042666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1043957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentzstatic struct a2dp_server *find_server(GSList *list, const bdaddr_t *src)
1044957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz{
1045957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	GSList *l;
1046957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1047957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	for (l = list; l; l = l->next) {
1048957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		struct a2dp_server *server = l->data;
1049957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1050957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		if (bacmp(&server->src, src) == 0)
1051957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz			return server;
1052957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	}
1053957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1054957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	return NULL;
1055957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz}
1056957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1057957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentzint a2dp_register(DBusConnection *conn, const bdaddr_t *src, GKeyFile *config)
1058666938b54d631956826343ed278e2af4b982fc29Johan Hedberg{
10595b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	int sbc_srcs = 1, sbc_sinks = 0;
10605b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	int mpeg12_srcs = 0, mpeg12_sinks = 0;
10617e64674f8b5c5be6b3cccb17ea05766763d50f94Johan Hedberg	gboolean source = TRUE, sink = TRUE;
10625b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	char *str;
10635b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	GError *err = NULL;
1064e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedberg	int i;
1065957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	struct a2dp_server *server;
1066e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedberg
10675b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (!config)
10685b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		goto proceed;
10695b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
10705b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	str = g_key_file_get_string(config, "General", "Disable", &err);
10715b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
10725b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (err) {
10735b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		debug("audio.conf: %s", err->message);
1074bd4494363230705c3efaa13f3c94a73fadab88e4Johan Hedberg		g_clear_error(&err);
10755b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	} else {
10765b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		if (strstr(str, "Sink"))
10777e64674f8b5c5be6b3cccb17ea05766763d50f94Johan Hedberg			source = FALSE;
10785b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		if (strstr(str, "Source"))
10797e64674f8b5c5be6b3cccb17ea05766763d50f94Johan Hedberg			sink = FALSE;
10805b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_free(str);
10815b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	}
10825b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
10835b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	str = g_key_file_get_string(config, "A2DP", "SBCSources", &err);
10845b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (err) {
10855b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		debug("audio.conf: %s", err->message);
1086bd4494363230705c3efaa13f3c94a73fadab88e4Johan Hedberg		g_clear_error(&err);
10875b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	} else {
10885b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		sbc_srcs = atoi(str);
10895b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_free(str);
10905b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	}
10915b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
10925b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	str = g_key_file_get_string(config, "A2DP", "MPEG12Sources", &err);
10935b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (err) {
10945b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		debug("audio.conf: %s", err->message);
1095bd4494363230705c3efaa13f3c94a73fadab88e4Johan Hedberg		g_clear_error(&err);
10965b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	} else {
10975b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		mpeg12_srcs = atoi(str);
10985b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_free(str);
10995b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	}
11005b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
11015b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	str = g_key_file_get_string(config, "A2DP", "SBCSinks", &err);
11025b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (err) {
11035b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		debug("audio.conf: %s", err->message);
1104bd4494363230705c3efaa13f3c94a73fadab88e4Johan Hedberg		g_clear_error(&err);
11055b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	} else {
11065b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		sbc_sinks = atoi(str);
11075b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_free(str);
11085b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	}
11095b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
11105b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	str = g_key_file_get_string(config, "A2DP", "MPEG12Sinks", &err);
11115b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (err) {
11125b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		debug("audio.conf: %s", err->message);
1113bd4494363230705c3efaa13f3c94a73fadab88e4Johan Hedberg		g_clear_error(&err);
11145b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	} else {
11155b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		mpeg12_sinks = atoi(str);
11165b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		g_free(str);
11175b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	}
11186763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
11195b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentzproceed:
1120957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (!connection)
1121957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		connection = dbus_connection_ref(conn);
1122957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1123957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	server = find_server(servers, src);
1124957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (!server) {
1125957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		server = g_new0(struct a2dp_server, 1);
1126957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		if (!server)
1127957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz			return -ENOMEM;
1128957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		avdtp_init(src, config);
1129957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		bacpy(&server->src, src);
1130957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		servers = g_slist_append(servers, server);
1131957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	}
11326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
11337e64674f8b5c5be6b3cccb17ea05766763d50f94Johan Hedberg	if (source) {
11345b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		for (i = 0; i < sbc_srcs; i++)
1135957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz			a2dp_add_sep(server, AVDTP_SEP_TYPE_SOURCE,
11365b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz					A2DP_CODEC_SBC);
11375b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
11385b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		for (i = 0; i < mpeg12_srcs; i++)
1139957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz			a2dp_add_sep(server, AVDTP_SEP_TYPE_SOURCE,
11405b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz					A2DP_CODEC_MPEG12);
1141489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	}
11426763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
11435b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz	if (sink) {
11445b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		for (i = 0; i < sbc_sinks; i++)
1145957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz			a2dp_add_sep(server, AVDTP_SEP_TYPE_SINK,
11465b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz					A2DP_CODEC_SBC);
11475b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz
11485b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz		for (i = 0; i < mpeg12_sinks; i++)
1149957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz			a2dp_add_sep(server, AVDTP_SEP_TYPE_SINK,
11505b601136563565049e0dc726b67860bc636e03bdLuiz Augusto von Dentz					A2DP_CODEC_MPEG12);
1151489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	}
11526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
11536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return 0;
11546763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
11556763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1156666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic void a2dp_unregister_sep(struct a2dp_sep *sep)
1157666938b54d631956826343ed278e2af4b982fc29Johan Hedberg{
1158666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	avdtp_unregister_sep(sep->sep);
1159666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	g_free(sep);
1160666938b54d631956826343ed278e2af4b982fc29Johan Hedberg}
1161666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1162957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentzvoid a2dp_unregister(const bdaddr_t *src)
11636763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
1164957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	struct a2dp_server *server;
11656763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1166957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	server = find_server(servers, src);
1167957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (!server)
1168957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		return;
11696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1170957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	g_slist_foreach(server->sinks, (GFunc) a2dp_unregister_sep, NULL);
1171957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	g_slist_free(server->sinks);
11726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1173957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	g_slist_foreach(server->sources, (GFunc) a2dp_unregister_sep, NULL);
1174957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	g_slist_free(server->sources);
1175957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1176957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (server->source_record_id)
1177957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		remove_record_from_server(server->source_record_id);
1178957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1179957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (server->sink_record_id)
1180957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		remove_record_from_server(server->sink_record_id);
1181957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1182957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	servers = g_slist_remove(servers, server);
1183957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	g_free(server);
1184957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1185957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (servers)
1186957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		return;
11876763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
11886763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	dbus_connection_unref(connection);
1189957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	connection = NULL;
11906763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
11916763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1192caf9fdd6d0183afc3b21d1cd82eb637773c131deMarcel Holtmanngboolean a2dp_source_cancel(struct audio_device *dev, unsigned int id)
1193cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
11942934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup_cb *cb_data;
11952934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
1196cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	GSList *l;
1197cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
119803490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_dev(dev);
1199cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!setup)
1200cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return FALSE;
1201cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1202cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	for (cb_data = NULL, l = setup->cb; l != NULL; l = g_slist_next(l)) {
12032934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		struct a2dp_setup_cb *cb = l->data;
1204cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1205cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		if (cb->id == id) {
1206cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			cb_data = cb;
1207cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			break;
1208cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		}
1209cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
1210cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1211cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!cb_data)
1212cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return FALSE;
1213cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1214cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	setup->cb = g_slist_remove(setup->cb, cb_data);
12159ce01693dd0aa7407b7d8eb37c8524dd05abe15cJohan Hedberg	g_free(cb_data);
1216cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1217828133c3180a090a06ace6637d9f84ae5f57ae33Johan Hedberg	if (!setup->cb) {
1218cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		setup->canceled = TRUE;
121903490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg		setup->sep = NULL;
1220828133c3180a090a06ace6637d9f84ae5f57ae33Johan Hedberg	}
1221cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1222cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	return TRUE;
1223cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
1224cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
12252934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzunsigned int a2dp_source_config(struct avdtp *session, a2dp_config_cb_t cb,
12262934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				GSList *caps, void *user_data)
1227cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
12282934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup_cb *cb_data;
1229666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	GSList *l;
1230957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	struct a2dp_server *server;
12312934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
1232714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz	struct a2dp_sep *sep = NULL, *tmp;
12332934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct avdtp_local_sep *lsep;
12342934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct avdtp_remote_sep *rsep;
1235489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct avdtp_service_capability *cap;
1236489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	struct avdtp_media_codec_capability *codec_cap = NULL;
12372934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	int posix_err;
1238957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	bdaddr_t src;
1239957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz
1240957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	avdtp_get_peers(session, &src, NULL);
1241957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	server = find_server(servers, &src);
1242957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	if (!server)
1243957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		return 0;
1244cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1245489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	for (l = caps; l != NULL; l = l->next) {
1246489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		cap = l->data;
1247489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
1248489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		if (cap->category != AVDTP_MEDIA_CODEC)
1249489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz			continue;
1250489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
1251489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		codec_cap = (void *) cap->data;
1252489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		break;
1253489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	}
1254489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
1255489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz	if (!codec_cap)
1256489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		return 0;
1257489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
1258957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz	for (l = server->sources; l != NULL; l = l->next) {
1259714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz		tmp = l->data;
1260666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1261666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		if (tmp->locked)
1262666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			continue;
1263666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1264489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz		if (tmp->codec != codec_cap->media_codec_type)
1265489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz			continue;
1266489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz
1267fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg		if (!tmp->stream || avdtp_has_stream(session, tmp->stream)) {
1268666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			sep = tmp;
1269666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			break;
1270666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		}
1271666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	}
1272666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1273666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (!sep) {
12742934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		error("a2dp_source_cfg: no available SEP found");
1275730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg		return 0;
1276730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg	}
1277730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg
1278ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz	debug("a2dp_source_config: selected SEP %p", sep->sep);
1279666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1280bcc1d569bcfb0cd026930eb6a8ee607a8002f523Johan Hedberg	cb_data = g_new0(struct a2dp_setup_cb, 1);
12812934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->config_cb = cb;
1282cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	cb_data->user_data = user_data;
12830f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	cb_data->id = ++cb_id;
1284cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
12852934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup = find_setup_by_session(session);
12862934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (!setup) {
12872934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup = g_new0(struct a2dp_setup, 1);
12882934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup->session = avdtp_ref(session);
12892934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setups = g_slist_append(setups, setup);
1290cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
1291cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
12922934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_ref(setup);
1293cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	setup->cb = g_slist_append(setup->cb, cb_data);
12942934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->sep = sep;
1295666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	setup->stream = sep->stream;
12962934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->client_caps = caps;
1297cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1298666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	switch (avdtp_sep_get_state(sep->sep)) {
1299cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_IDLE:
1300957d01bac7a4c448bbe0a15de613af7927d1c7d0Luiz Augusto von Dentz		for (l = server->sources; l != NULL; l = l->next) {
1301714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz			tmp = l->data;
1302714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz
1303714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz			if (avdtp_has_stream(session, tmp->stream))
1304714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz				break;
1305714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz		}
1306714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz
1307714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz		if (l != NULL) {
1308714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz			setup->reconfigure = TRUE;
1309714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz			if (avdtp_close(session, tmp->stream) < 0) {
1310714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz				error("avdtp_close failed");
1311714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz				goto failed;
1312714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz			}
1313714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz			break;
1314714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz		}
1315714eda55e1af76786f134620b9c4291dee3350e2Luiz Augusto von Dentz
13162934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (avdtp_get_seps(session, AVDTP_SEP_TYPE_SINK,
1317489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				codec_cap->media_type,
1318489c2e0dbd76d9cecec62d19fafd9e7baddb72e7Luiz Augusto von Dentz				codec_cap->media_codec_type,
13192934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				&lsep, &rsep) < 0) {
13202934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			error("No matching ACP and INT SEPs found");
13212934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			goto failed;
13222934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		}
13232934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
13242934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		posix_err = avdtp_set_configuration(session, rsep, lsep,
13252934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz							caps, &setup->stream);
13262934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (posix_err < 0) {
13272934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			error("avdtp_set_configuration: %s",
13282934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				strerror(-posix_err));
1329cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			goto failed;
1330730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg		}
1331cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
1332cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_OPEN:
13332934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_STREAMING:
13342934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (avdtp_stream_has_capabilities(setup->stream, caps))
13352934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			g_idle_add((GSourceFunc) finalize_config, setup);
13362934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		else if (!setup->reconfigure) {
13372934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			setup->reconfigure = TRUE;
13382934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			if (avdtp_close(session, sep->stream) < 0) {
13392934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				error("avdtp_close failed");
13402934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				goto failed;
13415402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz			}
13425402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		}
13432934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
13442934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	default:
13452934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		error("SEP in bad state for requesting a new stream");
13462934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		goto failed;
13472934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
13482934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
13492934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return cb_data->id;
13502934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
13512934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzfailed:
13522934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_unref(setup);
13532934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_id--;
13542934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return 0;
13552934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
13562934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
13572934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzunsigned int a2dp_source_resume(struct avdtp *session, struct a2dp_sep *sep,
13582934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				a2dp_stream_cb_t cb, void *user_data)
13592934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
13602934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup_cb *cb_data;
13612934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
13622934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
136370f4ad8b4bf7d477bcfc7efdec7f25b1f9517cd3Johan Hedberg	cb_data = g_new0(struct a2dp_setup_cb, 1);
13642934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->resume_cb = cb;
13652934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->user_data = user_data;
13662934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->id = ++cb_id;
13672934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
13682934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup = find_setup_by_session(session);
13692934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (!setup) {
13702934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup = g_new0(struct a2dp_setup, 1);
13712934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup->session = avdtp_ref(session);
13722934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setups = g_slist_append(setups, setup);
13732934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
13742934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
13752934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_ref(setup);
13762934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->cb = g_slist_append(setup->cb, cb_data);
13772934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->sep = sep;
13782934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->stream = sep->stream;
13792934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
13802934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	switch (avdtp_sep_get_state(sep->sep)) {
13812934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_IDLE:
13822934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		goto failed;
13832934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
13842934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_OPEN:
13852934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (avdtp_start(session, sep->stream) < 0) {
1386730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg			error("avdtp_start failed");
1387cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			goto failed;
1388730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg		}
1389cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
1390cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_STREAMING:
13912934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (!sep->suspending && sep->suspend_timer) {
13922934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			g_source_remove(sep->suspend_timer);
13932934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			sep->suspend_timer = 0;
13942934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			avdtp_unref(sep->session);
13952934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			sep->session = NULL;
1396cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		}
13973f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg		if (sep->suspending)
13983f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg			setup->start = TRUE;
13993f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg		else
14003f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg			g_idle_add((GSourceFunc) finalize_resume, setup);
1401cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
1402cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	default:
14032934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		error("SEP in bad state");
1404cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		goto failed;
1405cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
14065402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
14072934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return cb_data->id;
14082934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
14092934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzfailed:
14102934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_unref(setup);
14112934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_id--;
14122934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return 0;
14132934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
14142934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
14152934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzunsigned int a2dp_source_suspend(struct avdtp *session, struct a2dp_sep *sep,
14162934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				a2dp_stream_cb_t cb, void *user_data)
14172934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
14182934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup_cb *cb_data;
14192934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
14202934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1421bcc1d569bcfb0cd026930eb6a8ee607a8002f523Johan Hedberg	cb_data = g_new0(struct a2dp_setup_cb, 1);
14222934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->suspend_cb = cb;
14232934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->user_data = user_data;
14242934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->id = ++cb_id;
14252934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
14262934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup = find_setup_by_session(session);
14272934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (!setup) {
14282934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup = g_new0(struct a2dp_setup, 1);
14292934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup->session = avdtp_ref(session);
14302934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setups = g_slist_append(setups, setup);
14312934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
14322934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
14332934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_ref(setup);
14342934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->cb = g_slist_append(setup->cb, cb_data);
14352934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->sep = sep;
14362934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->stream = sep->stream;
14372934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
14382934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	switch (avdtp_sep_get_state(sep->sep)) {
14392934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_IDLE:
14402934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		error("a2dp_source_suspend: no stream to suspend");
14412934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		goto failed;
14422934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
14432934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_OPEN:
14442934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		g_idle_add((GSourceFunc) finalize_suspend, setup);
14452934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
14462934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_STREAMING:
1447c020b7240f8f6b72ffbb6c6f327a63f2da14e6a9Johan Hedberg		if (avdtp_suspend(session, sep->stream) < 0) {
1448c020b7240f8f6b72ffbb6c6f327a63f2da14e6a9Johan Hedberg			error("avdtp_suspend failed");
14492934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			goto failed;
14502934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		}
14512934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
14522934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	default:
14532934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		error("SEP in bad state for resume");
14542934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		goto failed;
14552934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
145603490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
1457cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	return cb_data->id;
1458cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1459cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergfailed:
14602934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_unref(setup);
1461cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	cb_id--;
14620f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	return 0;
1463cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
1464cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1465fc0d501d82773718d0f2d040f786136332c39813Johan Hedberggboolean a2dp_sep_lock(struct a2dp_sep *sep, struct avdtp *session)
1466cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
1467fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	if (sep->locked)
1468fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg		return FALSE;
1469f4211a3cd3442d54fa7877a6c421bee034d46e8eJohan Hedberg
1470ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz	debug("SEP %p locked", sep->sep);
1471fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	sep->locked = TRUE;
1472666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1473fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	return TRUE;
1474cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
1475cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1476fc0d501d82773718d0f2d040f786136332c39813Johan Hedberggboolean a2dp_sep_unlock(struct a2dp_sep *sep, struct avdtp *session)
1477cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
1478cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	avdtp_state_t state;
1479cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1480666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	state = avdtp_sep_get_state(sep->sep);
1481cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1482666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	sep->locked = FALSE;
1483cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1484ad834a766f5fa52cb08280fe9a297a6f46359a70Luiz Augusto von Dentz	debug("SEP %p unlocked", sep->sep);
1485730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg
1486666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (!sep->stream || state == AVDTP_STATE_IDLE)
1487cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return TRUE;
1488cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1489cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	switch (state) {
1490cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_OPEN:
1491cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		/* Set timer here */
1492cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
1493cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_STREAMING:
1494666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		if (avdtp_suspend(session, sep->stream) == 0)
1495666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			sep->suspending = TRUE;
1496cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
1497cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	default:
1498cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
1499cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
1500cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1501cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	return TRUE;
1502cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
1503cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1504