a2dp.c revision 828133c3180a090a06ace6637d9f84ae5f57ae33
1e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg/*
2e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *
3e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  BlueZ - Bluetooth protocol stack for Linux
4e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *
5e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  Copyright (C) 2004-2007  Marcel Holtmann <marcel@holtmann.org>
6e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *
7e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *
8e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  This program is free software; you can redistribute it and/or modify
9e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  it under the terms of the GNU General Public License as published by
10e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  the Free Software Foundation; either version 2 of the License, or
11e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  (at your option) any later version.
12e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *
13e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  This program is distributed in the hope that it will be useful,
14e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  but WITHOUT ANY WARRANTY; without even the implied warranty of
15e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
16e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  GNU General Public License for more details.
17e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *
18e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  You should have received a copy of the GNU General Public License
19e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  along with this program; if not, write to the Free Software
20e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
21e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg *
22e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg */
23e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg
24e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg#ifdef HAVE_CONFIG_H
25e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg#include <config.h>
26e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg#endif
27e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg
286763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include <stdlib.h>
296763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
306763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include <dbus/dbus.h>
316763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include <glib.h>
326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
33c2833e263d6cfc4cf82f4bfdcc59640a4071aeaeJohan Hedberg#include <bluetooth/bluetooth.h>
346763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include <bluetooth/sdp.h>
356763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include <bluetooth/sdp_lib.h>
366763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
376763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include "logging.h"
38d013a1eaa7beebbb49c1fe0015c70ad81566d97cJohan Hedberg#include "device.h"
39296dcf42cf8a4f4d6f0192cac58a28887be38552Johan Hedberg#include "manager.h"
406763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include "avdtp.h"
41f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg#include "sink.h"
42e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg#include "a2dp.h"
436763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
44c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg/* The duration that streams without users are allowed to stay in
45c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg * STREAMING state. */
46c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg#define SUSPEND_TIMEOUT 5000
47c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
48cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg#ifndef MIN
49cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg# define MIN(x, y) ((x) < (y) ? (x) : (y))
50cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg#endif
51cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
52cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg#ifndef MAX
53cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg# define MAX(x, y) ((x) > (y) ? (x) : (y))
54cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg#endif
55cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
56cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergstruct a2dp_sep {
57666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	uint8_t type;
58cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	struct avdtp_local_sep *sep;
59c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	struct avdtp *session;
60cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	struct avdtp_stream *stream;
61cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	struct device *used_by;
62c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	guint suspend_timer;
63666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	gboolean locked;
64cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	gboolean start_requested;
65cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	gboolean suspending;
66cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	gboolean starting;
67cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg};
68cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
69cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergstruct a2dp_stream_cb {
70cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	a2dp_stream_cb_t cb;
71cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	void *user_data;
72cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	int id;
73cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg};
74cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
75cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergstruct a2dp_stream_setup {
76cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	struct avdtp *session;
77cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	struct device *dev;
78828133c3180a090a06ace6637d9f84ae5f57ae33Johan Hedberg	struct a2dp_sep *sep;
79cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	struct avdtp_stream *stream;
805402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	struct avdtp_service_capability *media_codec;
81cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	gboolean start;
82cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	gboolean canceled;
83cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	GSList *cb;
84cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg};
85cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
866763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic DBusConnection *connection = NULL;
876763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
88666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic GSList *sinks = NULL;
89666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic GSList *sources = NULL;
90666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
91666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic uint32_t source_record_id = 0;
92666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic uint32_t sink_record_id = 0;
936763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
94cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergstatic struct a2dp_stream_setup *setup = NULL;
956763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
96cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergstatic void stream_setup_free(struct a2dp_stream_setup *s)
97cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
98cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (s->session)
99cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		avdtp_unref(s->session);
100cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	g_slist_foreach(s->cb, (GFunc) g_free, NULL);
101cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	g_slist_free(s->cb);
102cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	g_free(s);
103cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	setup = NULL;
104cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
105cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
106cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergstatic void setup_callback(struct a2dp_stream_cb *cb,
107cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg				struct a2dp_stream_setup *s)
108cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
109cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	cb->cb(s->session, s->dev, s->stream, cb->user_data);
110cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
111cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
11278a94059160d7478624cad315022255f7ebbbe80Johan Hedbergstatic gboolean finalize_stream_setup(struct a2dp_stream_setup *s)
113cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
114828133c3180a090a06ace6637d9f84ae5f57ae33Johan Hedberg	if (!s->stream)
115828133c3180a090a06ace6637d9f84ae5f57ae33Johan Hedberg		s->sep->used_by = NULL;
116cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	g_slist_foreach(setup->cb, (GFunc) setup_callback, setup);
117cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	stream_setup_free(setup);
11878a94059160d7478624cad315022255f7ebbbe80Johan Hedberg	return FALSE;
119cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
1201addff77624b54445c9b81779ddc78892a126a45Johan Hedberg
1217a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedbergstatic void stream_state_changed(struct avdtp_stream *stream,
1227a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg					avdtp_state_t old_state,
1237a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg					avdtp_state_t new_state,
1247a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg					struct avdtp_error *err,
1257a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg					void *user_data)
1267a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg{
1277a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	struct a2dp_sep *sep = user_data;
1287a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg
1297a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	if (new_state != AVDTP_STATE_IDLE)
1307a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		return;
1317a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg
1327a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	if (sep->suspend_timer) {
1337a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		g_source_remove(sep->suspend_timer);
1347a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		sep->suspend_timer = 0;
1357a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	}
1367a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg
1377a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	if (sep->session) {
1387a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		avdtp_unref(sep->session);
1397a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		sep->session = NULL;
1407a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	}
1417a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg
1427a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	sep->stream = NULL;
1437a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg}
1447a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg
1455402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentzstatic uint8_t default_bitpool(uint8_t freq, uint8_t mode)
1465402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz{
1475402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	switch (freq) {
1485402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	case A2DP_SAMPLING_FREQ_16000:
1495402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	case A2DP_SAMPLING_FREQ_32000:
1505402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return 53;
1515402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	case A2DP_SAMPLING_FREQ_44100:
1525402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		switch (mode) {
1535402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		case A2DP_CHANNEL_MODE_MONO:
1545402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		case A2DP_CHANNEL_MODE_DUAL_CHANNEL:
1555402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz			return 31;
1565402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		case A2DP_CHANNEL_MODE_STEREO:
1575402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		case A2DP_CHANNEL_MODE_JOINT_STEREO:
1585402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz			return 53;
1595402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		default:
1605402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz			error("Invalid channel mode %u", mode);
1615402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz			return 53;
1625402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		}
1635402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	case A2DP_SAMPLING_FREQ_48000:
1645402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		switch (mode) {
1655402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		case A2DP_CHANNEL_MODE_MONO:
1665402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		case A2DP_CHANNEL_MODE_DUAL_CHANNEL:
1675402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz			return 29;
1685402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		case A2DP_CHANNEL_MODE_STEREO:
1695402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		case A2DP_CHANNEL_MODE_JOINT_STEREO:
1705402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz			return 51;
1715402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		default:
1725402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz			error("Invalid channel mode %u", mode);
1735402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz			return 51;
1745402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		}
1755402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	default:
1765402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		error("Invalid sampling freq %u", freq);
1775402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return 53;
1785402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
1795402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz}
1805402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
1815402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentzstatic gboolean select_sbc_params(struct sbc_codec_cap *cap,
1825402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz					struct sbc_codec_cap *supported)
1835402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz{
1845402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	uint max_bitpool, min_bitpool;
1855402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
1865402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	memset(cap, 0, sizeof(struct sbc_codec_cap));
1875402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
1885402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	cap->cap.media_type = AVDTP_MEDIA_TYPE_AUDIO;
1895402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	cap->cap.media_codec_type = A2DP_CODEC_SBC;
1905402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
191734b3f84c1e48f241bf1004e57a86fa898d083a5Marcel Holtmann	if (supported->frequency & A2DP_SAMPLING_FREQ_44100)
1925402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		cap->frequency = A2DP_SAMPLING_FREQ_44100;
193734b3f84c1e48f241bf1004e57a86fa898d083a5Marcel Holtmann	else if (supported->frequency & A2DP_SAMPLING_FREQ_48000)
194734b3f84c1e48f241bf1004e57a86fa898d083a5Marcel Holtmann		cap->frequency = A2DP_SAMPLING_FREQ_48000;
1955402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	else if (supported->frequency & A2DP_SAMPLING_FREQ_32000)
1965402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		cap->frequency = A2DP_SAMPLING_FREQ_32000;
1975402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	else if (supported->frequency & A2DP_SAMPLING_FREQ_16000)
1985402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		cap->frequency = A2DP_SAMPLING_FREQ_16000;
1995402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	else {
2005402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		error("No supported frequencies");
2015402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return FALSE;
2025402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
2035402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
2045402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (supported->channel_mode & A2DP_CHANNEL_MODE_JOINT_STEREO)
2055402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		cap->channel_mode = A2DP_CHANNEL_MODE_JOINT_STEREO;
2065402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	else if (supported->channel_mode & A2DP_CHANNEL_MODE_STEREO)
2075402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		cap->channel_mode = A2DP_CHANNEL_MODE_STEREO;
2085402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	else if (supported->channel_mode & A2DP_CHANNEL_MODE_DUAL_CHANNEL)
2095402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		cap->channel_mode = A2DP_CHANNEL_MODE_DUAL_CHANNEL;
2105402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	else if (supported->channel_mode & A2DP_CHANNEL_MODE_MONO)
2115402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		cap->channel_mode = A2DP_CHANNEL_MODE_MONO;
2125402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	else {
2135402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		error("No supported channel modes");
2145402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return FALSE;
2155402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
2165402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
2175402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (supported->block_length & A2DP_BLOCK_LENGTH_16)
2185402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		cap->block_length = A2DP_BLOCK_LENGTH_16;
2195402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	else if (supported->block_length & A2DP_BLOCK_LENGTH_12)
2205402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		cap->block_length = A2DP_BLOCK_LENGTH_12;
2215402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	else if (supported->block_length & A2DP_BLOCK_LENGTH_8)
2225402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		cap->block_length = A2DP_BLOCK_LENGTH_8;
2235402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	else if (supported->block_length & A2DP_BLOCK_LENGTH_4)
2245402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		cap->block_length = A2DP_BLOCK_LENGTH_4;
2255402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	else {
2265402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		error("No supported block lengths");
2275402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return FALSE;
2285402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
2295402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
2305402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (supported->subbands & A2DP_SUBBANDS_8)
2315402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		cap->subbands = A2DP_SUBBANDS_8;
2325402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	else if (supported->subbands & A2DP_SUBBANDS_4)
2335402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		cap->subbands = A2DP_SUBBANDS_4;
2345402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	else {
2355402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		error("No supported subbands");
2365402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return FALSE;
2375402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
2385402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
2395402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (supported->allocation_method & A2DP_ALLOCATION_LOUDNESS)
2405402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		cap->allocation_method = A2DP_ALLOCATION_LOUDNESS;
2415402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	else if (supported->allocation_method & A2DP_ALLOCATION_SNR)
2425402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		cap->allocation_method = A2DP_ALLOCATION_SNR;
2435402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
2445402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	min_bitpool = MAX(2, supported->min_bitpool);
2455402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	max_bitpool = MIN(default_bitpool(cap->frequency, cap->channel_mode),
2464183300934043b1038c84652848c271a235bc5dfMarcel Holtmann							supported->max_bitpool);
2475402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
2485402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	cap->min_bitpool = min_bitpool;
2495402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	cap->max_bitpool = max_bitpool;
2505402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
2515402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	return TRUE;
2525402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz}
2535402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
2545402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentzstatic gboolean a2dp_select_capabilities(struct avdtp_remote_sep *rsep,
2555402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz						GSList **caps)
2565402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz{
2575402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	struct avdtp_service_capability *media_transport, *media_codec;
25869e07f5a7b3934fac5bcf4c554e14e0d0b3cec47Luiz Augusto von Dentz	struct sbc_codec_cap sbc_cap;
2595402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
2605402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (!setup)
2615402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return FALSE;
2625402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
2634183300934043b1038c84652848c271a235bc5dfMarcel Holtmann	if (setup->media_codec) {
26469e07f5a7b3934fac5bcf4c554e14e0d0b3cec47Luiz Augusto von Dentz		memcpy(&sbc_cap, setup->media_codec->data, sizeof(sbc_cap));
2654183300934043b1038c84652848c271a235bc5dfMarcel Holtmann	} else {
2665402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		media_codec = avdtp_get_codec(rsep);
2675402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		if (!media_codec)
2685402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz			return FALSE;
2695402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
2705402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		select_sbc_params(&sbc_cap,
27141b71b230e0aa4b495c091e7d17c6b939ddbce79Luiz Augusto von Dentz			(struct sbc_codec_cap *) media_codec->data);
2725402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
2735402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
2745402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
2755402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz						NULL, 0);
2765402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
2775402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	*caps = g_slist_append(*caps, media_transport);
2785402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
2795402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &sbc_cap,
2805402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz						sizeof(sbc_cap));
2815402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
2825402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	*caps = g_slist_append(*caps, media_codec);
2835402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
28469e07f5a7b3934fac5bcf4c554e14e0d0b3cec47Luiz Augusto von Dentz
2855402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	return TRUE;
2865402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz}
2875402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
2885402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentzstatic void discovery_complete(struct avdtp *session, GSList *seps, int err,
2895402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz				void *user_data)
2905402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz{
2915402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	struct avdtp_local_sep *lsep;
2925402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	struct avdtp_remote_sep *rsep;
2935402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	GSList *caps = NULL;
2945402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
295828133c3180a090a06ace6637d9f84ae5f57ae33Johan Hedberg	if (err < 0 || setup->canceled) {
2965402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		setup->stream = NULL;
2975402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		finalize_stream_setup(setup);
2985402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return;
2995402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
3005402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
3015402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	debug("Discovery complete");
3025402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
3035402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (avdtp_get_seps(session, AVDTP_SEP_TYPE_SINK, AVDTP_MEDIA_TYPE_AUDIO,
3045402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz				A2DP_CODEC_SBC, &lsep, &rsep) < 0) {
3055402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		error("No matching ACP and INT SEPs found");
3065402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		finalize_stream_setup(setup);
3075402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return;
3085402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
3095402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
3105402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (!a2dp_select_capabilities(rsep, &caps)) {
3115402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		error("Unable to select remote SEP capabilities");
3125402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		finalize_stream_setup(setup);
3135402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return;
3145402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
3155402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
3165402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	err = avdtp_set_configuration(session, rsep, lsep, caps,
3174183300934043b1038c84652848c271a235bc5dfMarcel Holtmann							&setup->stream);
3185402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (err < 0) {
3195402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		error("avdtp_set_configuration: %s", strerror(-err));
3205402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		finalize_stream_setup(setup);
3215402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
3225402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz}
3235402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
324f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedbergstatic gboolean setconf_ind(struct avdtp *session,
325f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg				struct avdtp_local_sep *sep,
3266763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg				struct avdtp_stream *stream,
327f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg				GSList *caps, uint8_t *err,
328666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				uint8_t *category, void *user_data)
3296763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
330666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
331f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg	struct device *dev;
332f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg	bdaddr_t addr;
333f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg
334666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
3356763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Set_Configuration_Ind");
336666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
337c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg		debug("SBC Source: Set_Configuration_Ind");
338f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg
339f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg	avdtp_get_peers(session, NULL, &addr);
340f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg
341f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg	dev = manager_device_connected(&addr, A2DP_SOURCE_UUID);
342f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg	if (!dev) {
343f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg		*err = AVDTP_UNSUPPORTED_CONFIGURATION;
344f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg		*category = 0x00;
345f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg		return FALSE;
346f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg	}
347f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg
3487a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep);
349c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	a2dp_sep->stream = stream;
350cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
351666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE)
352c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg		sink_new_stream(dev, session, stream);
3536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3546763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
3556763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
3566763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
357f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean getcap_ind(struct avdtp *session, struct avdtp_local_sep *sep,
358666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				GSList **caps, uint8_t *err, void *user_data)
3596763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
360666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
3616763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	struct avdtp_service_capability *media_transport, *media_codec;
3626763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	struct sbc_codec_cap sbc_cap;
3636763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
364666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
3656763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Get_Capability_Ind");
3666763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
3676763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Source: Get_Capability_Ind");
3686763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	*caps = NULL;
3706763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3716763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT,
3726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg						NULL, 0);
3736763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3746763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	*caps = g_slist_append(*caps, media_transport);
3756763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	memset(&sbc_cap, 0, sizeof(struct sbc_codec_cap));
3776763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3786763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sbc_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO;
3796763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sbc_cap.cap.media_codec_type = A2DP_CODEC_SBC;
3806763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3816763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sbc_cap.frequency = ( A2DP_SAMPLING_FREQ_48000 |
3826763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg				A2DP_SAMPLING_FREQ_44100 |
3836763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg				A2DP_SAMPLING_FREQ_32000 |
3846763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg				A2DP_SAMPLING_FREQ_16000 );
3856763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3866763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sbc_cap.channel_mode = ( A2DP_CHANNEL_MODE_JOINT_STEREO |
3876763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg					A2DP_CHANNEL_MODE_STEREO |
3886763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg					A2DP_CHANNEL_MODE_DUAL_CHANNEL |
3896763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg					A2DP_CHANNEL_MODE_MONO );
3906763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3916763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sbc_cap.block_length = ( A2DP_BLOCK_LENGTH_16 |
3926763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg					A2DP_BLOCK_LENGTH_12 |
3936763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg					A2DP_BLOCK_LENGTH_8 |
3946763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg					A2DP_BLOCK_LENGTH_4 );
3956763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3966763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sbc_cap.subbands = ( A2DP_SUBBANDS_8 | A2DP_SUBBANDS_4 );
3976763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
3986763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sbc_cap.allocation_method = ( A2DP_ALLOCATION_LOUDNESS |
3996763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg					A2DP_ALLOCATION_SNR );
4006763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
4016763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sbc_cap.min_bitpool = 2;
4026763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sbc_cap.max_bitpool = 250;
4036763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
4046763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &sbc_cap,
4056763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg						sizeof(sbc_cap));
4066763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
4076763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	*caps = g_slist_append(*caps, media_codec);
4086763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
4096763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
4106763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
4116763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
412f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
4130f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg				struct avdtp_stream *stream,
414666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_error *err, void *user_data)
4156763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
416666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
4170f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	int ret;
418cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
419666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
4206763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Set_Configuration_Cfm");
421666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
422c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg		debug("SBC Source: Set_Configuration_Cfm");
423cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
4240f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (err) {
4250f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		if (setup)
4260f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg			finalize_stream_setup(setup);
4270f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		return;
4280f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	}
4290f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg
4307a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep);
431c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	a2dp_sep->stream = stream;
432cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
433cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!setup)
434cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return;
435cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
43667d1e1774b3ff2d7a09fcf49484515bd85c02d14Johan Hedberg	/* Notify sink.c of the new stream */
43767d1e1774b3ff2d7a09fcf49484515bd85c02d14Johan Hedberg	sink_new_stream(setup->dev, session, setup->stream);
43867d1e1774b3ff2d7a09fcf49484515bd85c02d14Johan Hedberg
4390f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	ret = avdtp_open(session, stream);
4400f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (ret < 0) {
4410f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		error("Error on avdtp_open %s (%d)", strerror(-ret),
4420f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg				-ret);
4437a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg		setup->stream = NULL;
444cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		finalize_stream_setup(setup);
445cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
4466763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
4476763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
448f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean getconf_ind(struct avdtp *session, struct avdtp_local_sep *sep,
449666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				uint8_t *err, void *user_data)
4506763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
451666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
452666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
453666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
4546763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Get_Configuration_Ind");
4556763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
4566763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Source: Get_Configuration_Ind");
4576763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
4586763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
4596763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
460f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void getconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
461666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
462666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
4636763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
464666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
465666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
466666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
4676763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Set_Configuration_Cfm");
4686763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
4696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Source: Set_Configuration_Cfm");
4706763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
4716763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
472f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean open_ind(struct avdtp *session, struct avdtp_local_sep *sep,
473666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
474666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
4756763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
476666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
477666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
478666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
4796763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Open_Ind");
4806763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
4816763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Source: Open_Ind");
4826763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
4836763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
4846763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
485f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void open_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
486666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
487666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
4886763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
489666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
490666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
491666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
4926763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Open_Cfm");
4936763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
4946763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Source: Open_Cfm");
4951addff77624b54445c9b81779ddc78892a126a45Johan Hedberg
496cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!setup)
4971addff77624b54445c9b81779ddc78892a126a45Johan Hedberg		return;
4981addff77624b54445c9b81779ddc78892a126a45Johan Hedberg
499cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (setup->canceled) {
5000f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		if (!err)
5010f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg			avdtp_close(session, stream);
502cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		stream_setup_free(setup);
503cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return;
504cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
505cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
5060f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (err) {
5070f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		setup->stream = NULL;
5080f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		goto finalize;
5090f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	}
5100f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg
511cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (setup->start) {
512cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		if (avdtp_start(session, stream) == 0)
513cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			return;
5141addff77624b54445c9b81779ddc78892a126a45Johan Hedberg
515cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		error("avdtp_start failed");
516cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		setup->stream = NULL;
5175402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
518cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
5190f458da19471c933a4105cc450c48548b72edc8eJohan Hedbergfinalize:
520cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	finalize_stream_setup(setup);
5216763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
5226763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
523c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedbergstatic gboolean suspend_timeout(struct a2dp_sep *sep)
524c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg{
525c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	if (avdtp_suspend(sep->session, sep->stream) == 0)
526c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg		sep->suspending = TRUE;
527c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
5287a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg	sep->suspend_timer = 0;
529c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
530c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	avdtp_unref(sep->session);
531c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	sep->session = NULL;
532c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
533c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	return FALSE;
534c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg}
535c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
536f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean start_ind(struct avdtp *session, struct avdtp_local_sep *sep,
537666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
538666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
5396763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
540666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
541c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
542666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
5436763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Start_Ind");
544666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
5456763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Source: Start_Ind");
5465b5cfaadb312600c58362617080e29fbf036712cJohan Hedberg
547c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	a2dp_sep->session = avdtp_ref(session);
548c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
549c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	a2dp_sep->suspend_timer = g_timeout_add(SUSPEND_TIMEOUT,
550c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg						(GSourceFunc) suspend_timeout,
551c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg						a2dp_sep);
552c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	return TRUE;
5536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
5546763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
555f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void start_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
556666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
557666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
5586763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
559666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
560666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
561666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
5626763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Start_Cfm");
5636763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
5646763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Source: Start_Cfm");
565cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
566cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!setup)
567cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return;
568cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
569cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (setup->canceled) {
5700f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		if (!err)
5710f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg			avdtp_close(session, stream);
572cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		stream_setup_free(setup);
573cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return;
574cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
575cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
5760f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (err)
5770f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		setup->stream = NULL;
5780f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg
579cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	finalize_stream_setup(setup);
5806763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
5816763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
582f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean suspend_ind(struct avdtp *session, struct avdtp_local_sep *sep,
583666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
584666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
5856763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
586666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
587666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
588666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
5896763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Suspend_Ind");
5906763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
5916763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Source: Suspend_Ind");
5926763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
5936763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
5946763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
595f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void suspend_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
596666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
597666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
5986763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
599666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
600c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
601666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
6026763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Suspend_Cfm");
603666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
604c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg		debug("SBC Source: Suspend_Cfm");
605cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
606c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	a2dp_sep->suspending = FALSE;
607cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
6080f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	if (err) {
609c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg		a2dp_sep->start_requested = FALSE;
6100f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		if (setup)
6110f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg			finalize_stream_setup(setup);
6120f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg		return;
6130f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	}
6140f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg
615c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg	if (a2dp_sep->start_requested) {
616cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		avdtp_start(session, stream);
617c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg		a2dp_sep->start_requested = FALSE;
618cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
6196763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
6206763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
621f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean close_ind(struct avdtp *session, struct avdtp_local_sep *sep,
622666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
623666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
6246763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
625666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
626c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
627666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
6286763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Close_Ind");
629666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
630c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg		debug("SBC Source: Close_Ind");
631cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
6326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
6336763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
6346763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
635f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void close_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
636666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
637666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
6386763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
639666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
640c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
641666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
6426763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Close_Cfm");
643666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
644c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg		debug("SBC Source: Close_Cfm");
6455402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
6465402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (!setup)
6475402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return;
6485402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
6495402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (setup->canceled) {
6505402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		stream_setup_free(setup);
6515402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return;
6525402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
6535402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
6545402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (err) {
6555402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		setup->stream = NULL;
6565402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		goto finalize;
6575402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
6585402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
6595402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (setup->start) {
6605402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		if (avdtp_discover(session, discovery_complete, setup) == 0)
6615402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz			return;
6625402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
6635402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		error("avdtp_discover failed");
6645402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		setup->stream = NULL;
6655402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
6665402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
6675402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentzfinalize:
6685402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	finalize_stream_setup(setup);
6696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
6706763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
671f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean abort_ind(struct avdtp *session, struct avdtp_local_sep *sep,
672666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				struct avdtp_stream *stream, uint8_t *err,
673666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				void *user_data)
6746763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
675666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
676c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
677666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
6786763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Abort_Ind");
679666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
680c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg		debug("SBC Source: Abort_Ind");
681cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
6826763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
6836763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
6846763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
685f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void abort_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
686666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
687666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
6886763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
689666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
690c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg
691666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
6926763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: Abort_Cfm");
693666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	else
6946763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Source: Abort_Cfm");
6956763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
6966763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
697f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean reconf_ind(struct avdtp *session, struct avdtp_local_sep *sep,
698666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				uint8_t *err, void *user_data)
6996763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
700666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
701666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
702666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
7036763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: ReConfigure_Ind");
7046763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
7056763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Source: ReConfigure_Ind");
7066763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return TRUE;
7076763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
7086763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
7090f458da19471c933a4105cc450c48548b72edc8eJohan Hedbergstatic void reconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
710666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			struct avdtp_stream *stream, struct avdtp_error *err,
711666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			void *user_data)
7126763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
713666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *a2dp_sep = user_data;
714666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
715666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
7166763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Sink: ReConfigure_Cfm");
7176763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
7186763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		debug("SBC Source: ReConfigure_Cfm");
7195402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
7205402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (!setup)
7215402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return;
7225402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
7235402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (setup->canceled) {
7245402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		if (!err)
7255402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz			avdtp_close(session, stream);
7265402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		stream_setup_free(setup);
7275402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		return;
7285402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
7295402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
7305402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (err) {
7315402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		setup->stream = NULL;
7325402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		goto finalize;
7335402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
7345402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
7355402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	if (setup->start) {
7365402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		if (avdtp_start(session, stream) == 0)
7375402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz			return;
7385402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
7395402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		error("avdtp_start failed");
7405402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		setup->stream = NULL;
7415402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	}
7425402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
7435402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentzfinalize:
7445402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	finalize_stream_setup(setup);
7456763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
7466763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
7476763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic struct avdtp_sep_cfm cfm = {
7486763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.set_configuration	= setconf_cfm,
7496763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.get_configuration	= getconf_cfm,
7506763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.open			= open_cfm,
7516763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.start			= start_cfm,
7526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.suspend		= suspend_cfm,
7536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.close			= close_cfm,
7546763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.abort			= abort_cfm,
7556763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.reconfigure		= reconf_cfm
7566763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg};
7576763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
7586763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic struct avdtp_sep_ind ind = {
7596763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.get_capability		= getcap_ind,
7606763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.set_configuration	= setconf_ind,
7616763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.get_configuration	= getconf_ind,
7626763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.open			= open_ind,
7636763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.start			= start_ind,
7646763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.suspend		= suspend_ind,
7656763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.close			= close_ind,
7666763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.abort			= abort_ind,
7676763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	.reconfigure		= reconf_ind
7686763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg};
7696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
7706763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic int a2dp_source_record(sdp_buf_t *buf)
7716763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
7726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_t *svclass_id, *pfseq, *apseq, *root;
7736763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	uuid_t root_uuid, l2cap, avdtp, a2src;
7746763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_profile_desc_t profile[1];
7756763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_t *aproto, *proto[2];
7766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_record_t record;
7776763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_data_t *psm, *version, *features;
7786763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	uint16_t lp = AVDTP_UUID, ver = 0x0100, feat = 0x000F;
7796763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	int ret = 0;
7806763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
7816763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	memset(&record, 0, sizeof(sdp_record_t));
7826763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
7836763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP);
7846763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	root = sdp_list_append(0, &root_uuid);
7856763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_set_browse_groups(&record, root);
7866763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
7876763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_uuid16_create(&a2src, AUDIO_SOURCE_SVCLASS_ID);
7886763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	svclass_id = sdp_list_append(0, &a2src);
7896763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_set_service_classes(&record, svclass_id);
7906763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
7916763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID);
7926763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	profile[0].version = 0x0100;
7936763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	pfseq = sdp_list_append(0, &profile[0]);
7946763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_set_profile_descs(&record, pfseq);
7956763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
7966763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_uuid16_create(&l2cap, L2CAP_UUID);
7976763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	proto[0] = sdp_list_append(0, &l2cap);
7986763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	psm = sdp_data_alloc(SDP_UINT16, &lp);
7996763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	proto[0] = sdp_list_append(proto[0], psm);
8006763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	apseq = sdp_list_append(0, proto[0]);
8016763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8026763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_uuid16_create(&avdtp, AVDTP_UUID);
8036763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	proto[1] = sdp_list_append(0, &avdtp);
8046763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	version = sdp_data_alloc(SDP_UINT16, &ver);
8056763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	proto[1] = sdp_list_append(proto[1], version);
8066763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	apseq = sdp_list_append(apseq, proto[1]);
8076763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8086763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	aproto = sdp_list_append(0, apseq);
8096763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_set_access_protos(&record, aproto);
8106763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8116763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	features = sdp_data_alloc(SDP_UINT16, &feat);
8126763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features);
8136763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8146763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_set_info_attr(&record, "Audio Source", 0, 0);
8156763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8166763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	if (sdp_gen_record_pdu(&record, buf) < 0)
8176763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		ret = -1;
8186763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	else
8196763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		ret = 0;
8206763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8216763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	free(psm);
8226763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	free(version);
8236763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(proto[0], 0);
8246763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(proto[1], 0);
8256763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(apseq, 0);
8266763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(pfseq, 0);
8276763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(aproto, 0);
8286763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(root, 0);
8296763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(svclass_id, 0);
8306763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(record.attrlist, (sdp_free_func_t) sdp_data_free);
8316763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_list_free(record.pattern, free);
8326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8336763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return ret;
8346763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
8356763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
8366763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic int a2dp_sink_record(sdp_buf_t *buf)
8376763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
8386763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return 0;
8396763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
8406763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
841666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic struct a2dp_sep *a2dp_add_sep(DBusConnection *conn, uint8_t type)
8426763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
843666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *sep;
844666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	GSList **l;
845666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	int (*create_record)(sdp_buf_t *buf);
846666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	uint32_t *record_id;
8476763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	sdp_buf_t buf;
8486763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
849666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	sep = g_new0(struct a2dp_sep, 1);
850666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
851666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	sep->sep = avdtp_register_sep(type, AVDTP_MEDIA_TYPE_AUDIO,
852666938b54d631956826343ed278e2af4b982fc29Johan Hedberg					&ind, &cfm, sep);
853666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (sep->sep == NULL) {
854666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		g_free(sep);
855666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		return NULL;
856666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	}
857666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
858666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	sep->type = type;
859666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
860666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (type == AVDTP_SEP_TYPE_SOURCE) {
861666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		l = &sources;
862666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		create_record = a2dp_source_record;
863666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		record_id = &source_record_id;
864666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	} else {
865666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		l = &sinks;
866666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		create_record = a2dp_sink_record;
867666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		record_id = &sink_record_id;
868666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	}
869666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
870666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (*record_id != 0)
871666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		goto add;
872666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
873666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (create_record(&buf) < 0) {
874666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		error("Unable to allocate new service record");
875666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		avdtp_unregister_sep(sep->sep);
876666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		g_free(sep);
877666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		return NULL;
878666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	}
879666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
880666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	*record_id = add_service_record(conn, &buf);
881666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	free(buf.data);
882666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (!*record_id) {
883666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		error("Unable to register A2DP service record");
884666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		avdtp_unregister_sep(sep->sep);
885666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		g_free(sep);
886666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		return NULL;
887666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	}
888666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
889666938b54d631956826343ed278e2af4b982fc29Johan Hedbergadd:
890666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	*l = g_slist_append(*l, sep);
891666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
892666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	return sep;
893666938b54d631956826343ed278e2af4b982fc29Johan Hedberg}
894666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
895e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedbergint a2dp_init(DBusConnection *conn, int sources, int sinks)
896666938b54d631956826343ed278e2af4b982fc29Johan Hedberg{
897e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedberg	int i;
898e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedberg
899e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedberg	if (!sources && !sinks)
9006763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg		return 0;
9016763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9026763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	connection = dbus_connection_ref(conn);
9036763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9046763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	avdtp_init();
9056763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
906e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedberg	for (i = 0; i < sources; i++)
907666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		a2dp_add_sep(conn, AVDTP_SEP_TYPE_SOURCE);
9086763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
909e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedberg	for (i = 0; i < sinks; i++)
910666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		a2dp_add_sep(conn, AVDTP_SEP_TYPE_SINK);
9116763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9126763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	return 0;
9136763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
9146763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
915666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic void a2dp_unregister_sep(struct a2dp_sep *sep)
916666938b54d631956826343ed278e2af4b982fc29Johan Hedberg{
917666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	avdtp_unregister_sep(sep->sep);
918666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	g_free(sep);
919666938b54d631956826343ed278e2af4b982fc29Johan Hedberg}
920666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
9216763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergvoid a2dp_exit()
9226763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{
923666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	g_slist_foreach(sinks, (GFunc) a2dp_unregister_sep, NULL);
924666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	g_slist_free(sinks);
925666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	sinks = NULL;
9266763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
927666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	g_slist_foreach(sources, (GFunc) a2dp_unregister_sep, NULL);
928666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	g_slist_free(sources);
929666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	sources = NULL;
9306763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
931666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (source_record_id) {
932666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		remove_service_record(connection, source_record_id);
933666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		source_record_id = 0;
9346763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	}
9356763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
936666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (sink_record_id) {
937666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		remove_service_record(connection, sink_record_id);
938666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		sink_record_id = 0;
9396763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	}
9406763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
9416763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg	dbus_connection_unref(connection);
9426763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}
9436763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg
944d1fb0b25a9882016de70f102408f10101b348e57Johan Hedberggboolean a2dp_source_cancel_stream(struct device *dev, unsigned int id)
945cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
946cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	struct a2dp_stream_cb *cb_data;
947cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	GSList *l;
948cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
949cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!setup)
950cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return FALSE;
951cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
952cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	for (cb_data = NULL, l = setup->cb; l != NULL; l = g_slist_next(l)) {
953cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		struct a2dp_stream_cb *cb = l->data;
954cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
955cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		if (cb->id == id) {
956cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			cb_data = cb;
957cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			break;
958cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		}
959cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
960cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
961cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (!cb_data)
962cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return FALSE;
963cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
964cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	setup->cb = g_slist_remove(setup->cb, cb_data);
9659ce01693dd0aa7407b7d8eb37c8524dd05abe15cJohan Hedberg	g_free(cb_data);
966cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
967828133c3180a090a06ace6637d9f84ae5f57ae33Johan Hedberg	if (!setup->cb) {
968cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		setup->canceled = TRUE;
969828133c3180a090a06ace6637d9f84ae5f57ae33Johan Hedberg		setup->sep->used_by = NULL;
970828133c3180a090a06ace6637d9f84ae5f57ae33Johan Hedberg	}
971cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
972cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	return TRUE;
973cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
974cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
9750f458da19471c933a4105cc450c48548b72edc8eJohan Hedbergunsigned int a2dp_source_request_stream(struct avdtp *session,
976666938b54d631956826343ed278e2af4b982fc29Johan Hedberg						struct device *dev,
977666938b54d631956826343ed278e2af4b982fc29Johan Hedberg						gboolean start,
978666938b54d631956826343ed278e2af4b982fc29Johan Hedberg						a2dp_stream_cb_t cb,
979666938b54d631956826343ed278e2af4b982fc29Johan Hedberg						void *user_data,
9805402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz						struct a2dp_sep **ret,
9815402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz						struct avdtp_service_capability *media_codec)
982cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
983cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	struct a2dp_stream_cb *cb_data;
984cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	static unsigned int cb_id = 0;
985666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	GSList *l;
986666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *sep = NULL;
987cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
988666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	for (l = sources; l != NULL; l = l->next) {
989666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		struct a2dp_sep *tmp = l->data;
990666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
991666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		if (tmp->locked)
992666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			continue;
993666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
994666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		if (tmp->used_by == NULL || tmp->used_by == dev) {
995666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			sep = tmp;
996666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			break;
997666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		}
998666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	}
999666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1000666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (!sep) {
1001666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		error("a2dp_source_request_stream: no available SEP found");
1002730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg		return 0;
1003730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg	}
1004730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg
1005730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg	if (setup && setup->dev != dev) {
1006730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg		error("a2dp_source_request_stream: stream setup in progress "
1007730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg				"already for another device");
1008730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg		return 0;
1009730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg	}
1010730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg
1011666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	sep->used_by = dev;
1012666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1013666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	debug("a2dp_source_request_stream: selected SEP %p", sep);
1014666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1015cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	cb_data = g_new(struct a2dp_stream_cb, 1);
1016cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	cb_data->cb = cb;
1017cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	cb_data->user_data = user_data;
10180f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	cb_data->id = ++cb_id;
1019cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1020cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (setup) {
1021cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		setup->canceled = FALSE;
1022cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		setup->cb = g_slist_append(setup->cb, cb_data);
1023cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		if (start)
1024cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			setup->start = TRUE;
1025cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return cb_data->id;
1026cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
1027cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1028cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	setup = g_new0(struct a2dp_stream_setup, 1);
1029cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	setup->session = avdtp_ref(session);
1030828133c3180a090a06ace6637d9f84ae5f57ae33Johan Hedberg	setup->sep = sep;
1031cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	setup->dev = dev;
1032cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	setup->cb = g_slist_append(setup->cb, cb_data);
1033cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	setup->start = start;
1034666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	setup->stream = sep->stream;
10355402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz	setup->media_codec = media_codec;
1036cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1037666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	switch (avdtp_sep_get_state(sep->sep)) {
1038cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_IDLE:
1039730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg		if (avdtp_discover(session, discovery_complete, setup) < 0) {
1040730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg			error("avdtp_discover failed");
1041cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			goto failed;
1042730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg		}
1043cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
1044cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_OPEN:
1045cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		if (!start) {
1046cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			g_idle_add((GSourceFunc) finalize_stream_setup, setup);
1047cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			break;
1048cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		}
1049666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		if (sep->starting)
1050cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			break;
10515402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		if (setup->media_codec) {
10525402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz			if (avdtp_stream_has_capability(setup->stream,
10534183300934043b1038c84652848c271a235bc5dfMarcel Holtmann							setup->media_codec)) {
10545402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz				if (avdtp_start(session, sep->stream) < 0) {
10555402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz					error("avdtp_start failed");
10565402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz					goto failed;
10575402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz				}
10585402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz			} else {
10595402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz				if (avdtp_close(session, sep->stream) < 0) {
10605402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz					error("avdtp_close failed");
10615402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz					goto failed;
10625402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz				}
10635402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz			}
10645402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		}
10655402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz		else if (avdtp_start(session, sep->stream) < 0) {
1066730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg			error("avdtp_start failed");
1067cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			goto failed;
1068730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg		}
1069cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
1070cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_STREAMING:
1071666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		if (!start || !sep->suspending) {
1072666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			if (sep->suspend_timer) {
1073666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				g_source_remove(sep->suspend_timer);
1074666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				sep->suspend_timer = 0;
107558b173171f61373c7eb8ed00d0635fb06fa741ccJohan Hedberg			}
1076666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			if (sep->session) {
1077666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				avdtp_unref(sep->session);
1078666938b54d631956826343ed278e2af4b982fc29Johan Hedberg				sep->session = NULL;
10797a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg			}
1080cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			g_idle_add((GSourceFunc) finalize_stream_setup, setup);
1081cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg			return cb_data->id;
1082cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		}
1083666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		sep->start_requested = TRUE;
1084cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
1085cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	default:
1086730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg		error("SEP in bad state for requesting a new stream");
1087cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		goto failed;
1088cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
10895402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz
1090666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (ret)
1091666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		*ret = sep;
1092cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1093cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	return cb_data->id;
1094cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1095cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergfailed:
1096cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	stream_setup_free(setup);
1097cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	cb_id--;
10980f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg	return 0;
1099cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
1100cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1101cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberggboolean a2dp_source_lock(struct device *dev, struct avdtp *session)
1102cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
1103666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	GSList *l;
1104cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1105666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	for (l = sources; l != NULL; l = l->next) {
1106666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		struct a2dp_sep *sep = l->data;
1107730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg
1108666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		if (sep->locked)
1109666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			continue;
1110cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1111f4211a3cd3442d54fa7877a6c421bee034d46e8eJohan Hedberg		if (sep->used_by != dev)
1112f4211a3cd3442d54fa7877a6c421bee034d46e8eJohan Hedberg			continue;
1113f4211a3cd3442d54fa7877a6c421bee034d46e8eJohan Hedberg
1114666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		debug("SBC Source SEP %p locked", sep);
1115666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		sep->locked = TRUE;
1116666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		return TRUE;
1117666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	}
1118666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1119666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	return FALSE;
1120cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
1121cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1122cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberggboolean a2dp_source_unlock(struct device *dev, struct avdtp *session)
1123cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
1124cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	avdtp_state_t state;
1125666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	GSList *l;
1126666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *sep = NULL;
1127cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1128666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	for (l = sources; l != NULL; l = l->next) {
1129666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		struct a2dp_sep *tmp = l->data;
1130666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1131f4211a3cd3442d54fa7877a6c421bee034d46e8eJohan Hedberg		if (!tmp->locked)
1132666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			continue;
1133666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1134666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		if (tmp->sep && tmp->used_by == dev) {
1135666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			sep = tmp;
1136666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			break;
1137666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		}
1138666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	}
1139cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1140666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (!sep)
1141cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return FALSE;
1142cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1143666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	state = avdtp_sep_get_state(sep->sep);
1144cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1145666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	sep->locked = FALSE;
1146666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	sep->used_by = NULL;
1147cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1148666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	debug("SBC Source SEP %p unlocked", sep);
1149730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg
1150666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (!sep->stream || state == AVDTP_STATE_IDLE)
1151cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return TRUE;
1152cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1153cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	switch (state) {
1154cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_OPEN:
1155cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		/* Set timer here */
1156cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
1157cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	case AVDTP_STATE_STREAMING:
1158666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		if (avdtp_suspend(session, sep->stream) == 0)
1159666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			sep->suspending = TRUE;
1160cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
1161cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	default:
1162cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		break;
1163cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
1164cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1165cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	return TRUE;
1166cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
1167cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1168cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberggboolean a2dp_source_suspend(struct device *dev, struct avdtp *session)
1169cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
1170cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	avdtp_state_t state;
1171666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	GSList *l;
1172666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *sep = NULL;
1173cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1174666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	for (l = sources; l != NULL; l = l->next) {
1175666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		struct a2dp_sep *tmp = l->data;
1176cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1177666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		if (tmp->sep && tmp->used_by == dev) {
1178666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			sep = tmp;
1179666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			break;
1180666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		}
1181666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	}
1182666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1183666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (!sep)
1184cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return FALSE;
1185cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1186666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	state = avdtp_sep_get_state(sep->sep);
1187cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1188666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (!sep->stream || state != AVDTP_STATE_STREAMING)
1189cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return TRUE;
1190cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1191666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (avdtp_suspend(session, sep->stream) == 0) {
1192666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		sep->suspending = TRUE;
1193cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return TRUE;
1194cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
1195cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1196cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	return FALSE;
1197cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}
1198cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1199cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberggboolean a2dp_source_start_stream(struct device *dev, struct avdtp *session)
1200cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{
1201cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	avdtp_state_t state;
1202666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	GSList *l;
1203666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	struct a2dp_sep *sep = NULL;
1204cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1205666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	for (l = sources; l != NULL; l = l->next) {
1206666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		struct a2dp_sep *tmp = l->data;
1207666938b54d631956826343ed278e2af4b982fc29Johan Hedberg
1208666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		if (tmp->sep && tmp->used_by == dev) {
1209666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			sep = tmp;
1210666938b54d631956826343ed278e2af4b982fc29Johan Hedberg			break;
1211666938b54d631956826343ed278e2af4b982fc29Johan Hedberg		}
1212666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	}
1213cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1214666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (!sep)
1215cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return FALSE;
1216cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1217666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	state = avdtp_sep_get_state(sep->sep);
1218cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1219cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (state < AVDTP_STATE_OPEN) {
1220cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		error("a2dp_source_start_stream: no stream open");
1221cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return FALSE;
1222cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	}
1223cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1224cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	if (state == AVDTP_STATE_STREAMING)
1225cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return TRUE;
1226cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1227666938b54d631956826343ed278e2af4b982fc29Johan Hedberg	if (avdtp_start(session, sep->stream) < 0)
1228cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg		return FALSE;
1229cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg
1230cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg	return TRUE;
12311addff77624b54445c9b81779ddc78892a126a45Johan Hedberg}
1232