a2dp.c revision 5309e42d65942fb971c0748676939398e6e513f4
1e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg/*
2e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *
3e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  BlueZ - Bluetooth protocol stack for Linux
4e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *
5de72271829f6bfd21aa6550a2ac6d81e35b53cadMarcel Holtmann *  Copyright (C) 2006-2007  Nokia Corporation
6e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  Copyright (C) 2004-2007  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"
456763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
46c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg/* The duration that streams without users are allowed to stay in
47c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg * STREAMING state. */
48c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg#define SUSPEND_TIMEOUT 5000
492934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz#define RECONFIGURE_TIMEOUT 500
50c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
51cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg#ifndef MIN
52cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg# define MIN(x, y) ((x) < (y) ? (x) : (y))
53cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg#endif
54cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
55cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg#ifndef MAX
56cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg# define MAX(x, y) ((x) > (y) ? (x) : (y))
57cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg#endif
58cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
59cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergstruct a2dp_sep {
60666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	uint8_t type;
61cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	struct avdtp_local_sep *sep;
62c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	struct avdtp *session;
63cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	struct avdtp_stream *stream;
64c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	guint suspend_timer;
65666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	gboolean locked;
66cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	gboolean suspending;
67cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	gboolean starting;
68cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg};
69cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
702934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstruct a2dp_setup_cb {
712934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	a2dp_config_cb_t config_cb;
722934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	a2dp_stream_cb_t resume_cb;
732934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	a2dp_stream_cb_t suspend_cb;
74cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	void *user_data;
75cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	int id;
76cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg};
77cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
782934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstruct a2dp_setup {
79cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	struct avdtp *session;
80828133c3180a090a06ace6637d9f84ae5f57ae33Johan Hedberg	struct a2dp_sep *sep;
81cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	struct avdtp_stream *stream;
825309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	struct avdtp_error *err;
832934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	GSList *client_caps;
842934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	gboolean reconfigure;
85cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	gboolean canceled;
863f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	gboolean start;
87cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	GSList *cb;
882934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	int ref;
89cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg};
90cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
916763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic DBusConnection *connection = NULL;
926763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
93666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic GSList *sinks = NULL;
94666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic GSList *sources = NULL;
95666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
96666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic uint32_t source_record_id = 0;
97666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic uint32_t sink_record_id = 0;
986763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9903490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedbergstatic GSList *setups = NULL;
1002934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic unsigned int cb_id = 0;
1012934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1022934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic struct a2dp_setup *setup_ref(struct a2dp_setup *setup)
1032934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
1042934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->ref++;
1052934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1062934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	debug("setup_ref(%p): ref=%d", setup, setup->ref);
1072934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1082934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return setup;
1092934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
1106763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
1112934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic void setup_free(struct a2dp_setup *s)
112cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
1132934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	debug("setup_free(%p)", s);
11403490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setups = g_slist_remove(setups, s);
115cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (s->session)
116cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		avdtp_unref(s->session);
117cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	g_slist_foreach(s->cb, (GFunc) g_free, NULL);
118cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	g_slist_free(s->cb);
119cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	g_free(s);
120cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
121cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1222934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic void setup_unref(struct a2dp_setup *setup)
1232934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
1242934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->ref--;
1252934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1262934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	debug("setup_unref(%p): ref=%d", setup, setup->ref);
1272934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1282934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (setup->ref <= 0)
1292934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup_free(setup);
1302934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
1312934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
132fc0d501d82773718d0f2d040f786136332c39813Johan Hedbergstatic struct device *a2dp_get_dev(struct avdtp *session)
133fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg{
134fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	bdaddr_t addr;
135fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg
136fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	avdtp_get_peers(session, NULL, &addr);
137fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg
138fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	return manager_device_connected(&addr, A2DP_SOURCE_UUID);
139fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg}
140fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg
1415309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentzstatic gboolean finalize_config(struct a2dp_setup *s)
142cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
143847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	GSList *l;
144847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg
1452934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_ref(s);
146847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	for (l = s->cb; l != NULL; l = l->next) {
1472934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		struct a2dp_setup_cb *cb = l->data;
1482934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1492934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (cb->config_cb) {
1505309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz			cb->config_cb(s->session, s->sep, s->stream, s->err,
1512934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz					cb->user_data);
1522934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			cb->config_cb = NULL;
1532934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			setup_unref(s);
1542934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		}
155847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	}
156cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1572934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_unref(s);
15878a94059160d7478624cad315022255f7ebbbe80Johan Hedberg	return FALSE;
159cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
1601addff77624b54445c9b81779ddc78892a126a45Johan Hedberg
1612934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic gboolean finalize_config_errno(struct a2dp_setup *s, int err)
162847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg{
163847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	struct avdtp_error avdtp_err;
164847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg
165847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	avdtp_error_init(&avdtp_err, AVDTP_ERROR_ERRNO, -err);
1665309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	s->err = err ? &avdtp_err : NULL;
167847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg
1685309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	return finalize_config(s);
169847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg}
170847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg
1715309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentzstatic gboolean finalize_resume(struct a2dp_setup *s)
1722934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
1732934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	GSList *l;
1742934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1752934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_ref(s);
1762934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	for (l = s->cb; l != NULL; l = l->next) {
1772934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		struct a2dp_setup_cb *cb = l->data;
1782934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1792934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (cb->resume_cb) {
1805309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz			cb->resume_cb(s->session, s->err, cb->user_data);
1812934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			cb->resume_cb = NULL;
1822934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			setup_unref(s);
1832934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		}
1842934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
1852934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1862934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_unref(s);
1872934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return FALSE;
1882934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
1892934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1902934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic gboolean finalize_resume_errno(struct a2dp_setup *s, int err)
1912934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
1922934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct avdtp_error avdtp_err;
1932934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1942934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	avdtp_error_init(&avdtp_err, AVDTP_ERROR_ERRNO, -err);
1955309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	s->err = err ? &avdtp_err : NULL;
1962934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1975309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	return finalize_resume(s);
1982934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
1992934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2005309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentzstatic gboolean finalize_suspend(struct a2dp_setup *s)
2012934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
2022934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	GSList *l;
2032934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2042934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_ref(s);
2052934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	for (l = s->cb; l != NULL; l = l->next) {
2062934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		struct a2dp_setup_cb *cb = l->data;
2072934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2082934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (cb->suspend_cb) {
2095309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz			cb->suspend_cb(s->session, s->err, cb->user_data);
2102934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			cb->suspend_cb = NULL;
2112934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			setup_unref(s);
2122934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		}
2132934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
2142934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2152934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_unref(s);
2162934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return FALSE;
2172934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
2182934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2192934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic gboolean finalize_suspend_errno(struct a2dp_setup *s, int err)
2202934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
2212934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct avdtp_error avdtp_err;
2222934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2232934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	avdtp_error_init(&avdtp_err, AVDTP_ERROR_ERRNO, -err);
2245309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	s->err = err ? &avdtp_err : NULL;
2252934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2265309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	return finalize_suspend(s);
2272934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
2282934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
2292934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic struct a2dp_setup *find_setup_by_session(struct avdtp *session)
23003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg{
23103490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	GSList *l;
23203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
23303490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	for (l = setups; l != NULL; l = l->next) {
2342934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		struct a2dp_setup *setup = l->data;
23503490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
23603490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg		if (setup->session == session)
23703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg			return setup;
23803490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	}
23903490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
24003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	return NULL;
24103490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg}
24203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
2432934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic struct a2dp_setup *find_setup_by_dev(struct device *dev)
24403490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg{
24503490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	GSList *l;
24603490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
24703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	for (l = setups; l != NULL; l = l->next) {
2482934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		struct a2dp_setup *setup = l->data;
249fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg		struct device *setup_dev = a2dp_get_dev(setup->session);
25003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
251fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg		if (setup_dev == dev)
25203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg			return setup;
25303490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	}
25403490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
25503490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	return NULL;
25603490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg}
25703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
2587a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedbergstatic void stream_state_changed(struct avdtp_stream *stream,
2597a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg					avdtp_state_t old_state,
2607a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg					avdtp_state_t new_state,
2617a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg					struct avdtp_error *err,
2627a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg					void *user_data)
2637a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg{
2647a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	struct a2dp_sep *sep = user_data;
2657a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg
2667a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	if (new_state != AVDTP_STATE_IDLE)
2677a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		return;
2687a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg
2697a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	if (sep->suspend_timer) {
2707a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		g_source_remove(sep->suspend_timer);
2717a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		sep->suspend_timer = 0;
2727a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	}
2737a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg
2747a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	if (sep->session) {
2757a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		avdtp_unref(sep->session);
2767a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		sep->session = NULL;
2777a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	}
2781ddd76afa25d775788e3762ab731cad80f8ffe56Johan Hedberg
2797a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	sep->stream = NULL;
2805402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
2815402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz}
2825402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
283f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedbergstatic gboolean setconf_ind(struct avdtp *session,
284f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg				struct avdtp_local_sep *sep,
2856763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg				struct avdtp_stream *stream,
286f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg				GSList *caps, uint8_t *err,
287666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				uint8_t *category, void *user_data)
2886763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
289666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
290f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg	struct device *dev;
291c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	struct avdtp_service_capability *cap;
292c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	struct avdtp_media_codec_capability *codec_cap;
293c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	struct sbc_codec_cap *sbc_cap;
294f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg
295666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
2966763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Set_Configuration_Ind");
297666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
298c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg		debug("SBC Source: Set_Configuration_Ind");
299f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg
300fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	dev = a2dp_get_dev(session);
301f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg	if (!dev) {
302f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg		*err = AVDTP_UNSUPPORTED_CONFIGURATION;
303f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg		*category = 0x00;
304f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg		return FALSE;
305f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg	}
306f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg
307c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	/* Check bipool range */
308c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	for (codec_cap = NULL; caps; caps = g_slist_next(caps)) {
309c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz		cap = caps->data;
310c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz		if (cap->category == AVDTP_MEDIA_CODEC) {
311c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz			codec_cap = (void *) cap->data;
312c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz			if (codec_cap->media_codec_type == A2DP_CODEC_SBC) {
313c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz				sbc_cap = (void *) codec_cap;
314c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz				if (sbc_cap->min_bitpool < MIN_BITPOOL ||
315c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz					sbc_cap->max_bitpool > MAX_BITPOOL) {
316c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz					*err = AVDTP_UNSUPPORTED_CONFIGURATION;
317c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz					*category = AVDTP_MEDIA_CODEC;
318c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz					return FALSE;
319c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz				}
320c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz			}
321c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz			break;
322c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz		}
323c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	}
324c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz
3257a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep);
326c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	a2dp_sep->stream = stream;
327cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
328666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE)
329c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg		sink_new_stream(dev, session, stream);
3306763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3316763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
3326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
3336763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
334f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean getcap_ind(struct avdtp *session, struct avdtp_local_sep *sep,
335666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				GSList **caps, uint8_t *err, void *user_data)
3366763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
337666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
3386763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	struct avdtp_service_capability *media_transport, *media_codec;
3396763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	struct sbc_codec_cap sbc_cap;
3406763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
341666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
3426763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Get_Capability_Ind");
3436763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
3446763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Source: Get_Capability_Ind");
3456763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3466763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	*caps = NULL;
3476763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3486763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
3496763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg						NULL, 0);
3506763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3516763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	*caps = g_slist_append(*caps, media_transport);
3526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	memset(&sbc_cap, 0, sizeof(struct sbc_codec_cap));
3546763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3556763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sbc_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO;
3566763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sbc_cap.cap.media_codec_type = A2DP_CODEC_SBC;
3576763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3586763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sbc_cap.frequency = ( A2DP_SAMPLING_FREQ_48000 |
3596763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg				A2DP_SAMPLING_FREQ_44100 |
3606763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg				A2DP_SAMPLING_FREQ_32000 |
3616763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg				A2DP_SAMPLING_FREQ_16000 );
3626763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3636763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sbc_cap.channel_mode = ( A2DP_CHANNEL_MODE_JOINT_STEREO |
3646763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg					A2DP_CHANNEL_MODE_STEREO |
3656763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg					A2DP_CHANNEL_MODE_DUAL_CHANNEL |
3666763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg					A2DP_CHANNEL_MODE_MONO );
3676763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3686763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sbc_cap.block_length = ( A2DP_BLOCK_LENGTH_16 |
3696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg					A2DP_BLOCK_LENGTH_12 |
3706763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg					A2DP_BLOCK_LENGTH_8 |
3716763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg					A2DP_BLOCK_LENGTH_4 );
3726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3736763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sbc_cap.subbands = ( A2DP_SUBBANDS_8 | A2DP_SUBBANDS_4 );
3746763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3756763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sbc_cap.allocation_method = ( A2DP_ALLOCATION_LOUDNESS |
3766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg					A2DP_ALLOCATION_SNR );
3776763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
378c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	sbc_cap.min_bitpool = MIN_BITPOOL;
379c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz	sbc_cap.max_bitpool = MAX_BITPOOL;
3806763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3816763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &sbc_cap,
3826763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg						sizeof(sbc_cap));
3836763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3846763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	*caps = g_slist_append(*caps, media_codec);
3856763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3866763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
3876763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
3886763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
389f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
3900f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg				struct avdtp_stream *stream,
391666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_error *err, void *user_data)
3926763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
393666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
3942934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
395fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	struct device *dev;
3960f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	int ret;
397cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
398666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
3996763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Set_Configuration_Cfm");
400666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
401c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg		debug("SBC Source: Set_Configuration_Cfm");
402cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
40303490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
40403490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
4050f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (err) {
4065309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		if (setup) {
4075309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz			setup->err = err;
4085309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz			finalize_config(setup);
4095309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		}
4100f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		return;
4110f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	}
4120f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg
4137a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep);
414c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	a2dp_sep->stream = stream;
415cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
416cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!setup)
417cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return;
418cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
419fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	dev = a2dp_get_dev(session);
420fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg
42167d1e1774b3ff2d7a09fcf49484515bd85c02d14Johan Hedberg	/* Notify sink.c of the new stream */
422fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	sink_new_stream(dev, session, setup->stream);
42367d1e1774b3ff2d7a09fcf49484515bd85c02d14Johan Hedberg
4240f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	ret = avdtp_open(session, stream);
4250f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (ret < 0) {
4260f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		error("Error on avdtp_open %s (%d)", strerror(-ret),
4270f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg				-ret);
4287a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		setup->stream = NULL;
4292934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		finalize_config_errno(setup, ret);
430cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
4316763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
4326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
433f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean getconf_ind(struct avdtp *session, struct avdtp_local_sep *sep,
434666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				uint8_t *err, void *user_data)
4356763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
436666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
437666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
438666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
4396763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Get_Configuration_Ind");
4406763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
4416763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Source: Get_Configuration_Ind");
4426763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
4436763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
4446763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
445f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void getconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
446666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
447666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
4486763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
449666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
450666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
451666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
4526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Set_Configuration_Cfm");
4536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
4546763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Source: Set_Configuration_Cfm");
4556763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
4566763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
457f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean open_ind(struct avdtp *session, struct avdtp_local_sep *sep,
458666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
459666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
4606763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
461666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
462666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
463666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
4646763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Open_Ind");
4656763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
4666763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Source: Open_Ind");
4676763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
4686763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
4696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
470f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void open_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
471666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
472666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
4736763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
474666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
4752934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
476666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
477666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
4786763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Open_Cfm");
4796763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
4806763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Source: Open_Cfm");
4811addff77624b54445c9b81779ddc78892a126a45Johan Hedberg
48203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
483cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!setup)
4841addff77624b54445c9b81779ddc78892a126a45Johan Hedberg		return;
4851addff77624b54445c9b81779ddc78892a126a45Johan Hedberg
486cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (setup->canceled) {
4870f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		if (!err)
4880f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg			avdtp_close(session, stream);
4892934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup_unref(setup);
490cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return;
491cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
492cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
4932934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (setup->reconfigure)
4942934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup->reconfigure = FALSE;
4952934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
4960f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (err) {
4970f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		setup->stream = NULL;
4985309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
4995309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		finalize_config(setup);
5005402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
501847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	else
5025309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		finalize_config_errno(setup, 0);
5036763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
5046763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
505c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedbergstatic gboolean suspend_timeout(struct a2dp_sep *sep)
506c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg{
507c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	if (avdtp_suspend(sep->session, sep->stream) == 0)
508c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg		sep->suspending = TRUE;
509c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
5107a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	sep->suspend_timer = 0;
511c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
512c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	avdtp_unref(sep->session);
513c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	sep->session = NULL;
514c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
515c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	return FALSE;
516c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg}
517c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
518f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean start_ind(struct avdtp *session, struct avdtp_local_sep *sep,
519666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
520666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
5216763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
522666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
523c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
524666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
5256763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Start_Ind");
526666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
5276763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Source: Start_Ind");
5285b5cfaadb312600c58362617080e29fbf036712cJohan Hedberg
529f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg	if (!a2dp_sep->locked) {
530f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg		a2dp_sep->session = avdtp_ref(session);
531f6d1f79b0382b03dc01d3bb823c8c3eb70f82457Johan Hedberg		a2dp_sep->suspend_timer = g_timeout_add(SUSPEND_TIMEOUT,
532c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg						(GSourceFunc) suspend_timeout,
533c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg						a2dp_sep);
534f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg	}
535f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg
536c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	return TRUE;
5376763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
5386763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
539f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void start_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
540666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
541666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
5426763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
543666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
5442934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
545666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
546666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
5476763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Start_Cfm");
5486763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
5496763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Source: Start_Cfm");
550cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
55103490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
552cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!setup)
553cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return;
554cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
555cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (setup->canceled) {
5560f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		if (!err)
5570f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg			avdtp_close(session, stream);
5582934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup_unref(setup);
559cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return;
560cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
561cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
562847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	if (err) {
5630f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		setup->stream = NULL;
5645309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
5655309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		finalize_resume(setup);
566847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	}
567847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	else
5682934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		finalize_resume_errno(setup, 0);
5696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
5706763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
571f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean suspend_ind(struct avdtp *session, struct avdtp_local_sep *sep,
572666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
573666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
5746763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
575666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
576666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
577666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
5786763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Suspend_Ind");
5796763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
5806763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Source: Suspend_Ind");
581d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg
582d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg	if (a2dp_sep->suspend_timer) {
583d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg		g_source_remove(a2dp_sep->suspend_timer);
58486898be87d24991e48d783b3e20696ff1ce62abcJohan Hedberg		a2dp_sep->suspend_timer = 0;
585f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg		avdtp_unref(a2dp_sep->session);
586f3ebb007ac66682bbba7926eac0c12258a945490Johan Hedberg		a2dp_sep->session = NULL;
587d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg	}
588d0f7d2f3742cbd962a4e8ca7f982185fd07a424eJohan Hedberg
5896763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
5906763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
5916763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
592f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void suspend_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
593666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
594666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
5956763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
596666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
5972934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
5983f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	gboolean start;
599c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
600666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
6016763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Suspend_Cfm");
602666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
603c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg		debug("SBC Source: Suspend_Cfm");
604cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
605c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	a2dp_sep->suspending = FALSE;
606cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
60703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
60803490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	if (!setup)
60903490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg		return;
61003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
6113f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	start = setup->start;
6123f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	setup->start = FALSE;
6133f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg
6140f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (err) {
6152934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup->stream = NULL;
6165309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
6175309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		finalize_suspend(setup);
618cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
6192934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	else
6202934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		finalize_suspend_errno(setup, 0);
6213f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg
6223f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	if (!start)
6233f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg		return;
6243f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg
6255309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	if (err) {
6265309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
6275309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		finalize_suspend(setup);
6285309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz	} else if (avdtp_start(session, a2dp_sep->stream) < 0) {
6293f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg		struct avdtp_error start_err;
6303f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg		error("avdtp_start failed");
6313f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg		avdtp_error_init(&start_err, AVDTP_ERROR_ERRNO, EIO);
6325309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
6335309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		finalize_suspend(setup);
6343f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg	}
6356763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
6366763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
637f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean close_ind(struct avdtp *session, struct avdtp_local_sep *sep,
638666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
639666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
6406763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
641666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
642c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
643666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
6446763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Close_Ind");
645666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
646c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg		debug("SBC Source: Close_Ind");
647cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
6486763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
6496763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
6506763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
6512934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzstatic gboolean reconfigure(gpointer data)
6522934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
6532934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup = data;
6542934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct avdtp_local_sep *lsep;
6552934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct avdtp_remote_sep *rsep;
6562934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	int posix_err;
6572934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
6582934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	posix_err = avdtp_get_seps(setup->session, AVDTP_SEP_TYPE_SINK,
6592934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz					AVDTP_MEDIA_TYPE_AUDIO, A2DP_CODEC_SBC,
6602934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz					&lsep, &rsep);
6612934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (posix_err < 0) {
6622934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		error("No matching ACP and INT SEPs found");
6632934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		finalize_config_errno(setup, posix_err);
6642934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
6652934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
6662934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	posix_err = avdtp_set_configuration(setup->session, rsep, lsep,
6672934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz						setup->client_caps,
6682934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz						&setup->stream);
6692934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (posix_err < 0) {
6702934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		error("avdtp_set_configuration: %s",
6712934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			strerror(-posix_err));
6722934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		finalize_config_errno(setup, posix_err);
6732934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
6742934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
6752934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return FALSE;
6762934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
6772934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
678f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void close_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
679666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
680666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
6816763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
682666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
6832934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
684c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
685666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
6866763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Close_Cfm");
687666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
688c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg		debug("SBC Source: Close_Cfm");
6895402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
69003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
6915402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (!setup)
6925402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return;
6935402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
6945402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (setup->canceled) {
6952934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup_unref(setup);
6965402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return;
6975402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
6985402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
6995402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (err) {
7005402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		setup->stream = NULL;
7015309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
7025309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		finalize_config(setup);
703847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg		return;
7045402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
7055402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
7062934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (setup->reconfigure)
7072934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		g_timeout_add(RECONFIGURE_TIMEOUT, reconfigure, setup);
7086763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
7096763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
710f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean abort_ind(struct avdtp *session, struct avdtp_local_sep *sep,
711666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
712666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
7136763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
714666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
715c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
716666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
7176763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Abort_Ind");
718666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
719c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg		debug("SBC Source: Abort_Ind");
720cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
721fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	a2dp_sep->stream = NULL;
72203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
7236763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
7246763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
7256763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
726f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void abort_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
727666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
728666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
7296763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
730666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
7312934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
732c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
733666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
7346763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Abort_Cfm");
735666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
7366763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Source: Abort_Cfm");
7372934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
7382934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup = find_setup_by_session(session);
7392934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (!setup)
7402934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		return;
7412934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
7422934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_unref(setup);
7436763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
7446763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
745f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean reconf_ind(struct avdtp *session, struct avdtp_local_sep *sep,
746666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				uint8_t *err, void *user_data)
7476763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
748666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
749666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
750666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
7516763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: ReConfigure_Ind");
7526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
7536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Source: ReConfigure_Ind");
7546763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
7556763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
7566763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
7570f458da19471c933a4105cc450c48548b72edc8eJohan Hedbergstatic void reconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
758666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
759666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
7606763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
761666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
7622934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
763666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
764666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
7656763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: ReConfigure_Cfm");
7666763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
7676763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Source: ReConfigure_Cfm");
7685402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
76903490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_session(session);
7705402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (!setup)
7715402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return;
7725402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
7735402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (setup->canceled) {
7745402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		if (!err)
7755402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz			avdtp_close(session, stream);
7762934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup_unref(setup);
7775402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return;
7785402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
7795402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
7805402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (err) {
7815402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		setup->stream = NULL;
7825309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		setup->err = err;
7835309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		finalize_config(setup);
7845402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
785847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg	else
7865309e42d65942fb971c0748676939398e6e513f4Luiz Augusto von Dentz		finalize_config_errno(setup, 0);
7876763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
7886763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
7896763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic struct avdtp_sep_cfm cfm = {
7906763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.set_configuration	= setconf_cfm,
7916763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.get_configuration	= getconf_cfm,
7926763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.open			= open_cfm,
7936763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.start			= start_cfm,
7946763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.suspend		= suspend_cfm,
7956763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.close			= close_cfm,
7966763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.abort			= abort_cfm,
7976763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.reconfigure		= reconf_cfm
7986763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg};
7996763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8006763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic struct avdtp_sep_ind ind = {
8016763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.get_capability		= getcap_ind,
8026763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.set_configuration	= setconf_ind,
8036763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.get_configuration	= getconf_ind,
8046763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.open			= open_ind,
8056763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.start			= start_ind,
8066763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.suspend		= suspend_ind,
8076763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.close			= close_ind,
8086763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.abort			= abort_ind,
8096763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.reconfigure		= reconf_ind
8106763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg};
8116763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8126763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic int a2dp_source_record(sdp_buf_t *buf)
8136763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
8146763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
8156763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	uuid_t root_uuid, l2cap, avdtp, a2src;
8166763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_profile_desc_t profile[1];
8176763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_t *aproto, *proto[2];
8186763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_record_t record;
8196763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_data_t *psm, *version, *features;
8206763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	uint16_t lp = AVDTP_UUID, ver = 0x0100, feat = 0x000F;
8216763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	int ret = 0;
8226763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8236763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	memset(&record, 0, sizeof(sdp_record_t));
8246763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8256763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
8266763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	root = sdp_list_append(0, &root_uuid);
8276763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_set_browse_groups(&record, root);
8286763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8296763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_uuid16_create(&a2src, AUDIO_SOURCE_SVCLASS_ID);
8306763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	svclass_id = sdp_list_append(0, &a2src);
8316763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_set_service_classes(&record, svclass_id);
8326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8336763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID);
8346763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	profile[0].version = 0x0100;
8356763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	pfseq = sdp_list_append(0, &profile[0]);
8366763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_set_profile_descs(&record, pfseq);
8376763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8386763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_uuid16_create(&l2cap, L2CAP_UUID);
8396763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	proto[0] = sdp_list_append(0, &l2cap);
8406763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	psm = sdp_data_alloc(SDP_UINT16, &lp);
8416763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	proto[0] = sdp_list_append(proto[0], psm);
8426763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	apseq = sdp_list_append(0, proto[0]);
8436763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8446763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_uuid16_create(&avdtp, AVDTP_UUID);
8456763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	proto[1] = sdp_list_append(0, &avdtp);
8466763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	version = sdp_data_alloc(SDP_UINT16, &ver);
8476763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	proto[1] = sdp_list_append(proto[1], version);
8486763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	apseq = sdp_list_append(apseq, proto[1]);
8496763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8506763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	aproto = sdp_list_append(0, apseq);
8516763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_set_access_protos(&record, aproto);
8526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	features = sdp_data_alloc(SDP_UINT16, &feat);
8546763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features);
8556763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8566763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_set_info_attr(&record, "Audio Source", 0, 0);
8576763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8586763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	if (sdp_gen_record_pdu(&record, buf) < 0)
8596763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		ret = -1;
8606763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
8616763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		ret = 0;
8626763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8636763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	free(psm);
8646763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	free(version);
8656763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(proto[0], 0);
8666763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(proto[1], 0);
8676763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(apseq, 0);
8686763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(pfseq, 0);
8696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(aproto, 0);
8706763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(root, 0);
8716763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(svclass_id, 0);
8726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(record.attrlist, (sdp_free_func_t) sdp_data_free);
8736763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(record.pattern, free);
8746763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8756763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return ret;
8766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
8776763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8786763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic int a2dp_sink_record(sdp_buf_t *buf)
8796763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
8806763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return 0;
8816763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
8826763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
883666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic struct a2dp_sep *a2dp_add_sep(DBusConnection *conn, uint8_t type)
8846763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
885666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *sep;
886666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	GSList **l;
887666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	int (*create_record)(sdp_buf_t *buf);
888666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	uint32_t *record_id;
8896763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_buf_t buf;
8906763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
891666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	sep = g_new0(struct a2dp_sep, 1);
892666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
893666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	sep->sep = avdtp_register_sep(type, AVDTP_MEDIA_TYPE_AUDIO,
894666938b54d631956826343ed278e2af4b982fc29Johan Hedberg					&ind, &cfm, sep);
895666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (sep->sep == NULL) {
896666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		g_free(sep);
897666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		return NULL;
898666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	}
899666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
900666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	sep->type = type;
901666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
902666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (type == AVDTP_SEP_TYPE_SOURCE) {
903666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		l = &sources;
904666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		create_record = a2dp_source_record;
905666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		record_id = &source_record_id;
906666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	} else {
907666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		l = &sinks;
908666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		create_record = a2dp_sink_record;
909666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		record_id = &sink_record_id;
910666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	}
911666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
912666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (*record_id != 0)
913666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		goto add;
914666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
915666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (create_record(&buf) < 0) {
916666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		error("Unable to allocate new service record");
917666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		avdtp_unregister_sep(sep->sep);
918666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		g_free(sep);
919666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		return NULL;
920666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	}
921666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
922666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	*record_id = add_service_record(conn, &buf);
923666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	free(buf.data);
924666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (!*record_id) {
925666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		error("Unable to register A2DP service record");
926666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		avdtp_unregister_sep(sep->sep);
927666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		g_free(sep);
928666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		return NULL;
929666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	}
930666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
931666938b54d631956826343ed278e2af4b982fc29Johan Hedbergadd:
932666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	*l = g_slist_append(*l, sep);
933666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
934666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	return sep;
935666938b54d631956826343ed278e2af4b982fc29Johan Hedberg}
936666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
937e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedbergint a2dp_init(DBusConnection *conn, int sources, int sinks)
938666938b54d631956826343ed278e2af4b982fc29Johan Hedberg{
939e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedberg	int i;
940e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedberg
941e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedberg	if (!sources && !sinks)
9426763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		return 0;
9436763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9446763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	connection = dbus_connection_ref(conn);
9456763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9466763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	avdtp_init();
9476763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
948e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedberg	for (i = 0; i < sources; i++)
949666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		a2dp_add_sep(conn, AVDTP_SEP_TYPE_SOURCE);
9506763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
951e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedberg	for (i = 0; i < sinks; i++)
952666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		a2dp_add_sep(conn, AVDTP_SEP_TYPE_SINK);
9536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9546763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return 0;
9556763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
9566763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
957666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic void a2dp_unregister_sep(struct a2dp_sep *sep)
958666938b54d631956826343ed278e2af4b982fc29Johan Hedberg{
959666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	avdtp_unregister_sep(sep->sep);
960666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	g_free(sep);
961666938b54d631956826343ed278e2af4b982fc29Johan Hedberg}
962666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
9636763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergvoid a2dp_exit()
9646763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
965666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	g_slist_foreach(sinks, (GFunc) a2dp_unregister_sep, NULL);
966666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	g_slist_free(sinks);
967666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	sinks = NULL;
9686763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
969666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	g_slist_foreach(sources, (GFunc) a2dp_unregister_sep, NULL);
970666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	g_slist_free(sources);
971666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	sources = NULL;
9726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
973666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (source_record_id) {
974666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		remove_service_record(connection, source_record_id);
975666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		source_record_id = 0;
9766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	}
9776763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
978666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (sink_record_id) {
979666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		remove_service_record(connection, sink_record_id);
980666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		sink_record_id = 0;
9816763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	}
9826763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9836763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	dbus_connection_unref(connection);
9846763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
9856763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9862934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzgboolean a2dp_source_cancel(struct device *dev, unsigned int id)
987cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
9882934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup_cb *cb_data;
9892934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
990cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	GSList *l;
991cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
99203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg	setup = find_setup_by_dev(dev);
993cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!setup)
994cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return FALSE;
995cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
996cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	for (cb_data = NULL, l = setup->cb; l != NULL; l = g_slist_next(l)) {
9972934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		struct a2dp_setup_cb *cb = l->data;
998cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
999cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		if (cb->id == id) {
1000cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			cb_data = cb;
1001cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			break;
1002cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		}
1003cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
1004cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1005cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!cb_data)
1006cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return FALSE;
1007cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1008cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	setup->cb = g_slist_remove(setup->cb, cb_data);
10099ce01693dd0aa7407b7d8eb37c8524dd05abe15cJohan Hedberg	g_free(cb_data);
1010cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1011828133c3180a090a06ace6637d9f84ae5f57ae33Johan Hedberg	if (!setup->cb) {
1012cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		setup->canceled = TRUE;
101303490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg		setup->sep = NULL;
1014828133c3180a090a06ace6637d9f84ae5f57ae33Johan Hedberg	}
1015cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1016cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	return TRUE;
1017cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
1018cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
10192934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzunsigned int a2dp_source_config(struct avdtp *session, a2dp_config_cb_t cb,
10202934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				GSList *caps, void *user_data)
1021cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
10222934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup_cb *cb_data;
1023666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	GSList *l;
10242934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
1025666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *sep = NULL;
10262934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct avdtp_local_sep *lsep;
10272934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct avdtp_remote_sep *rsep;
10282934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	int posix_err;
1029cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1030666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	for (l = sources; l != NULL; l = l->next) {
1031666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		struct a2dp_sep *tmp = l->data;
1032666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1033666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		if (tmp->locked)
1034666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			continue;
1035666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1036fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg		if (!tmp->stream || avdtp_has_stream(session, tmp->stream)) {
1037666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			sep = tmp;
1038666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			break;
1039666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		}
1040666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	}
1041666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1042666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (!sep) {
10432934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		error("a2dp_source_cfg: no available SEP found");
1044730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg		return 0;
1045730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg	}
1046730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg
10472934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	debug("a2dp_source_config: selected SEP %p", sep);
1048666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1049bcc1d569bcfb0cd026930eb6a8ee607a8002f523Johan Hedberg	cb_data = g_new0(struct a2dp_setup_cb, 1);
10502934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->config_cb = cb;
1051cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	cb_data->user_data = user_data;
10520f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	cb_data->id = ++cb_id;
1053cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
10542934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup = find_setup_by_session(session);
10552934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (!setup) {
10562934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup = g_new0(struct a2dp_setup, 1);
10572934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup->session = avdtp_ref(session);
10582934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setups = g_slist_append(setups, setup);
1059cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
1060cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
10612934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_ref(setup);
1062cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	setup->cb = g_slist_append(setup->cb, cb_data);
10632934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->sep = sep;
1064666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	setup->stream = sep->stream;
10652934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->client_caps = caps;
1066cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1067666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	switch (avdtp_sep_get_state(sep->sep)) {
1068cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_IDLE:
10692934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (avdtp_get_seps(session, AVDTP_SEP_TYPE_SINK,
10702934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				AVDTP_MEDIA_TYPE_AUDIO, A2DP_CODEC_SBC,
10712934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				&lsep, &rsep) < 0) {
10722934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			error("No matching ACP and INT SEPs found");
10732934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			goto failed;
10742934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		}
10752934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
10762934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		posix_err = avdtp_set_configuration(session, rsep, lsep,
10772934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz							caps, &setup->stream);
10782934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (posix_err < 0) {
10792934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			error("avdtp_set_configuration: %s",
10802934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				strerror(-posix_err));
1081cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			goto failed;
1082730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg		}
1083cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
1084cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_OPEN:
10852934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_STREAMING:
10862934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (avdtp_stream_has_capabilities(setup->stream, caps))
10872934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			g_idle_add((GSourceFunc) finalize_config, setup);
10882934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		else if (!setup->reconfigure) {
10892934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			setup->reconfigure = TRUE;
10902934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			if (avdtp_close(session, sep->stream) < 0) {
10912934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				error("avdtp_close failed");
10922934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				goto failed;
10935402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz			}
10945402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		}
10952934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
10962934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	default:
10972934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		error("SEP in bad state for requesting a new stream");
10982934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		goto failed;
10992934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
11002934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
11012934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return cb_data->id;
11022934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
11032934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzfailed:
11042934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_unref(setup);
11052934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_id--;
11062934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return 0;
11072934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
11082934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
11092934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzunsigned int a2dp_source_resume(struct avdtp *session, struct a2dp_sep *sep,
11102934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				a2dp_stream_cb_t cb, void *user_data)
11112934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
11122934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup_cb *cb_data;
11132934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
11142934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
111570f4ad8b4bf7d477bcfc7efdec7f25b1f9517cd3Johan Hedberg	cb_data = g_new0(struct a2dp_setup_cb, 1);
11162934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->resume_cb = cb;
11172934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->user_data = user_data;
11182934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->id = ++cb_id;
11192934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
11202934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup = find_setup_by_session(session);
11212934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (!setup) {
11222934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup = g_new0(struct a2dp_setup, 1);
11232934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup->session = avdtp_ref(session);
11242934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setups = g_slist_append(setups, setup);
11252934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
11262934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
11272934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_ref(setup);
11282934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->cb = g_slist_append(setup->cb, cb_data);
11292934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->sep = sep;
11302934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->stream = sep->stream;
11312934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
11322934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	switch (avdtp_sep_get_state(sep->sep)) {
11332934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_IDLE:
11342934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		goto failed;
11352934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
11362934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_OPEN:
11372934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (avdtp_start(session, sep->stream) < 0) {
1138730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg			error("avdtp_start failed");
1139cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			goto failed;
1140730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg		}
1141cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
1142cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_STREAMING:
11432934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		if (!sep->suspending && sep->suspend_timer) {
11442934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			g_source_remove(sep->suspend_timer);
11452934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			sep->suspend_timer = 0;
11462934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			avdtp_unref(sep->session);
11472934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			sep->session = NULL;
1148cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		}
11493f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg		if (sep->suspending)
11503f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg			setup->start = TRUE;
11513f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg		else
11523f4eef5217c126cf27afb32c5fbb10cb08726658Johan Hedberg			g_idle_add((GSourceFunc) finalize_resume, setup);
1153cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
1154cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	default:
11552934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		error("SEP in bad state");
1156cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		goto failed;
1157cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
11585402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
11592934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return cb_data->id;
11602934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
11612934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzfailed:
11622934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_unref(setup);
11632934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_id--;
11642934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	return 0;
11652934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz}
11662934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
11672934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentzunsigned int a2dp_source_suspend(struct avdtp *session, struct a2dp_sep *sep,
11682934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz				a2dp_stream_cb_t cb, void *user_data)
11692934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz{
11702934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup_cb *cb_data;
11712934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	struct a2dp_setup *setup;
11722934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
1173bcc1d569bcfb0cd026930eb6a8ee607a8002f523Johan Hedberg	cb_data = g_new0(struct a2dp_setup_cb, 1);
11742934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->suspend_cb = cb;
11752934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->user_data = user_data;
11762934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	cb_data->id = ++cb_id;
11772934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
11782934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup = find_setup_by_session(session);
11792934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	if (!setup) {
11802934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup = g_new0(struct a2dp_setup, 1);
11812934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setup->session = avdtp_ref(session);
11822934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		setups = g_slist_append(setups, setup);
11832934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
11842934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
11852934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_ref(setup);
11862934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->cb = g_slist_append(setup->cb, cb_data);
11872934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->sep = sep;
11882934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup->stream = sep->stream;
11892934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz
11902934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	switch (avdtp_sep_get_state(sep->sep)) {
11912934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_IDLE:
11922934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		error("a2dp_source_suspend: no stream to suspend");
11932934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		goto failed;
11942934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
11952934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_OPEN:
11962934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		g_idle_add((GSourceFunc) finalize_suspend, setup);
11972934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
11982934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	case AVDTP_STATE_STREAMING:
1199c020b7240f8f6b72ffbb6c6f327a63f2da14e6a9Johan Hedberg		if (avdtp_suspend(session, sep->stream) < 0) {
1200c020b7240f8f6b72ffbb6c6f327a63f2da14e6a9Johan Hedberg			error("avdtp_suspend failed");
12012934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz			goto failed;
12022934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		}
12032934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		break;
12042934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	default:
12052934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		error("SEP in bad state for resume");
12062934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz		goto failed;
12072934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	}
120803490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg
1209cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	return cb_data->id;
1210cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1211cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergfailed:
12122934e194f3ffe754e18477113c870a7b98f88454Luiz Augusto von Dentz	setup_unref(setup);
1213cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	cb_id--;
12140f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	return 0;
1215cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
1216cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1217fc0d501d82773718d0f2d040f786136332c39813Johan Hedberggboolean a2dp_sep_lock(struct a2dp_sep *sep, struct avdtp *session)
1218cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
1219fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	if (sep->locked)
1220fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg		return FALSE;
1221f4211a3cd3442d54fa7877a6c421bee034d46e8eJohan Hedberg
1222fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	debug("SBC Source SEP %p locked", sep);
1223fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	sep->locked = TRUE;
1224666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1225fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg	return TRUE;
1226cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
1227cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1228fc0d501d82773718d0f2d040f786136332c39813Johan Hedberggboolean a2dp_sep_unlock(struct a2dp_sep *sep, struct avdtp *session)
1229cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
1230cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	avdtp_state_t state;
1231cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1232666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	state = avdtp_sep_get_state(sep->sep);
1233cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1234666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	sep->locked = FALSE;
1235cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1236666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	debug("SBC Source SEP %p unlocked", sep);
1237730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg
1238666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (!sep->stream || state == AVDTP_STATE_IDLE)
1239cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return TRUE;
1240cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1241cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	switch (state) {
1242cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_OPEN:
1243cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		/* Set timer here */
1244cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
1245cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_STREAMING:
1246666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		if (avdtp_suspend(session, sep->stream) == 0)
1247666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			sep->suspending = TRUE;
1248cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
1249cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	default:
1250cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
1251cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
1252cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1253cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	return TRUE;
1254cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
1255cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1256