a2dp.c revision 847dad179fe16ec395373e4b55d46dcd400c623a
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> 29847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg#include <errno.h> 306763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 316763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include <dbus/dbus.h> 326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include <glib.h> 336763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 34c2833e263d6cfc4cf82f4bfdcc59640a4071aeaeJohan Hedberg#include <bluetooth/bluetooth.h> 356763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include <bluetooth/sdp.h> 366763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include <bluetooth/sdp_lib.h> 376763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 386763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include "logging.h" 39d013a1eaa7beebbb49c1fe0015c70ad81566d97cJohan Hedberg#include "device.h" 40296dcf42cf8a4f4d6f0192cac58a28887be38552Johan Hedberg#include "manager.h" 416763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include "avdtp.h" 42f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg#include "sink.h" 43e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg#include "a2dp.h" 446763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 45c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz#define MAX_BITPOOL 64 46c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz#define MIN_BITPOOL 2 47c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz 48c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg/* The duration that streams without users are allowed to stay in 49c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg * STREAMING state. */ 50c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg#define SUSPEND_TIMEOUT 5000 51c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg 52cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg#ifndef MIN 53cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg# define MIN(x, y) ((x) < (y) ? (x) : (y)) 54cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg#endif 55cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 56cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg#ifndef MAX 57cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg# define MAX(x, y) ((x) > (y) ? (x) : (y)) 58cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg#endif 59cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 60cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergstruct a2dp_sep { 61666938b54d631956826343ed278e2af4b982fc29Johan Hedberg uint8_t type; 62cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg struct avdtp_local_sep *sep; 63c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg struct avdtp *session; 64cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg struct avdtp_stream *stream; 65c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg guint suspend_timer; 66666938b54d631956826343ed278e2af4b982fc29Johan Hedberg gboolean locked; 67cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg gboolean suspending; 68cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg gboolean starting; 69cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}; 70cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 71cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergstruct a2dp_stream_cb { 72cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg a2dp_stream_cb_t cb; 73cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg void *user_data; 74cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg int id; 75cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}; 76cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 77cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergstruct a2dp_stream_setup { 78cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg struct avdtp *session; 79828133c3180a090a06ace6637d9f84ae5f57ae33Johan Hedberg struct a2dp_sep *sep; 80cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg struct avdtp_stream *stream; 815402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz struct avdtp_service_capability *media_codec; 82cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg gboolean start; 83cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg gboolean canceled; 84cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg GSList *cb; 85cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}; 86cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 876763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic DBusConnection *connection = NULL; 886763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 89666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic GSList *sinks = NULL; 90666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic GSList *sources = NULL; 91666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 92666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic uint32_t source_record_id = 0; 93666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic uint32_t sink_record_id = 0; 946763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 9503490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedbergstatic GSList *setups = NULL; 966763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 97cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergstatic void stream_setup_free(struct a2dp_stream_setup *s) 98cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{ 9903490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg setups = g_slist_remove(setups, s); 100cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (s->session) 101cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg avdtp_unref(s->session); 102cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg g_slist_foreach(s->cb, (GFunc) g_free, NULL); 103cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg g_slist_free(s->cb); 104cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg g_free(s); 105cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg} 106cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 107fc0d501d82773718d0f2d040f786136332c39813Johan Hedbergstatic struct device *a2dp_get_dev(struct avdtp *session) 108fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg{ 109fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg bdaddr_t addr; 110fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg 111fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg avdtp_get_peers(session, NULL, &addr); 112fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg 113fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg return manager_device_connected(&addr, A2DP_SOURCE_UUID); 114fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg} 115fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg 116847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedbergstatic gboolean finalize_stream_setup(struct a2dp_stream_setup *s, struct avdtp_error *err) 117cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{ 118847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg GSList *l; 119847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg 120847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg for (l = s->cb; l != NULL; l = l->next) { 121847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg struct a2dp_stream_cb *cb = l->data; 122847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg 123847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg cb->cb(s->session, s->sep, s->stream, cb->user_data, err); 124847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg } 125cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 12603490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg stream_setup_free(s); 12778a94059160d7478624cad315022255f7ebbbe80Johan Hedberg return FALSE; 128cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg} 1291addff77624b54445c9b81779ddc78892a126a45Johan Hedberg 130847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedbergstatic gboolean finalize_stream_setup_errno(struct a2dp_stream_setup *s, int err) 131847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg{ 132847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg struct avdtp_error avdtp_err; 133847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg 134847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg avdtp_error_init(&avdtp_err, AVDTP_ERROR_ERRNO, -err); 135847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg 136847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg return finalize_stream_setup(s, err ? &avdtp_err : NULL); 137847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg} 138847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg 13903490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedbergstatic struct a2dp_stream_setup *find_setup_by_session(struct avdtp *session) 14003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg{ 14103490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg GSList *l; 14203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg 14303490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg for (l = setups; l != NULL; l = l->next) { 14403490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg struct a2dp_stream_setup *setup = l->data; 14503490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg 14603490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg if (setup->session == session) 14703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg return setup; 14803490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg } 14903490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg 15003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg return NULL; 15103490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg} 15203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg 15303490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedbergstatic struct a2dp_stream_setup *find_setup_by_dev(struct device *dev) 15403490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg{ 15503490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg GSList *l; 15603490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg 15703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg for (l = setups; l != NULL; l = l->next) { 15803490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg struct a2dp_stream_setup *setup = l->data; 159fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg struct device *setup_dev = a2dp_get_dev(setup->session); 16003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg 161fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg if (setup_dev == dev) 16203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg return setup; 16303490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg } 16403490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg 16503490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg return NULL; 16603490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg} 16703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg 1687a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedbergstatic void stream_state_changed(struct avdtp_stream *stream, 1697a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg avdtp_state_t old_state, 1707a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg avdtp_state_t new_state, 1717a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg struct avdtp_error *err, 1727a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg void *user_data) 1737a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg{ 1747a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg struct a2dp_sep *sep = user_data; 1757a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg 1767a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg if (new_state != AVDTP_STATE_IDLE) 1777a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg return; 1787a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg 1797a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg if (sep->suspend_timer) { 1807a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg g_source_remove(sep->suspend_timer); 1817a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg sep->suspend_timer = 0; 1827a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg } 1837a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg 1847a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg if (sep->session) { 1857a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg avdtp_unref(sep->session); 1867a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg sep->session = NULL; 1877a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg } 1887a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg 1897a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg sep->stream = NULL; 1907a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg} 1917a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg 1925402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentzstatic uint8_t default_bitpool(uint8_t freq, uint8_t mode) 1935402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz{ 1945402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz switch (freq) { 1955402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz case A2DP_SAMPLING_FREQ_16000: 1965402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz case A2DP_SAMPLING_FREQ_32000: 1975402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return 53; 1985402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz case A2DP_SAMPLING_FREQ_44100: 1995402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz switch (mode) { 2005402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz case A2DP_CHANNEL_MODE_MONO: 2015402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz case A2DP_CHANNEL_MODE_DUAL_CHANNEL: 2025402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return 31; 2035402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz case A2DP_CHANNEL_MODE_STEREO: 2045402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz case A2DP_CHANNEL_MODE_JOINT_STEREO: 2055402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return 53; 2065402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz default: 2075402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz error("Invalid channel mode %u", mode); 2085402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return 53; 2095402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz } 2105402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz case A2DP_SAMPLING_FREQ_48000: 2115402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz switch (mode) { 2125402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz case A2DP_CHANNEL_MODE_MONO: 2135402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz case A2DP_CHANNEL_MODE_DUAL_CHANNEL: 2145402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return 29; 2155402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz case A2DP_CHANNEL_MODE_STEREO: 2165402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz case A2DP_CHANNEL_MODE_JOINT_STEREO: 2175402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return 51; 2185402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz default: 2195402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz error("Invalid channel mode %u", mode); 2205402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return 51; 2215402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz } 2225402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz default: 2235402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz error("Invalid sampling freq %u", freq); 2245402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return 53; 2255402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz } 2265402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz} 2275402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 2285402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentzstatic gboolean select_sbc_params(struct sbc_codec_cap *cap, 2295402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz struct sbc_codec_cap *supported) 2305402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz{ 2315402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz uint max_bitpool, min_bitpool; 2325402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 2335402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz memset(cap, 0, sizeof(struct sbc_codec_cap)); 2345402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 2355402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz cap->cap.media_type = AVDTP_MEDIA_TYPE_AUDIO; 2365402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz cap->cap.media_codec_type = A2DP_CODEC_SBC; 2375402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 238734b3f84c1e48f241bf1004e57a86fa898d083a5Marcel Holtmann if (supported->frequency & A2DP_SAMPLING_FREQ_44100) 2395402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz cap->frequency = A2DP_SAMPLING_FREQ_44100; 240734b3f84c1e48f241bf1004e57a86fa898d083a5Marcel Holtmann else if (supported->frequency & A2DP_SAMPLING_FREQ_48000) 241734b3f84c1e48f241bf1004e57a86fa898d083a5Marcel Holtmann cap->frequency = A2DP_SAMPLING_FREQ_48000; 2425402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz else if (supported->frequency & A2DP_SAMPLING_FREQ_32000) 2435402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz cap->frequency = A2DP_SAMPLING_FREQ_32000; 2445402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz else if (supported->frequency & A2DP_SAMPLING_FREQ_16000) 2455402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz cap->frequency = A2DP_SAMPLING_FREQ_16000; 2465402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz else { 2475402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz error("No supported frequencies"); 2485402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return FALSE; 2495402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz } 2505402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 2515402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz if (supported->channel_mode & A2DP_CHANNEL_MODE_JOINT_STEREO) 2525402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz cap->channel_mode = A2DP_CHANNEL_MODE_JOINT_STEREO; 2535402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz else if (supported->channel_mode & A2DP_CHANNEL_MODE_STEREO) 2545402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz cap->channel_mode = A2DP_CHANNEL_MODE_STEREO; 2555402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz else if (supported->channel_mode & A2DP_CHANNEL_MODE_DUAL_CHANNEL) 2565402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz cap->channel_mode = A2DP_CHANNEL_MODE_DUAL_CHANNEL; 2575402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz else if (supported->channel_mode & A2DP_CHANNEL_MODE_MONO) 2585402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz cap->channel_mode = A2DP_CHANNEL_MODE_MONO; 2595402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz else { 2605402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz error("No supported channel modes"); 2615402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return FALSE; 2625402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz } 2635402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 2645402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz if (supported->block_length & A2DP_BLOCK_LENGTH_16) 2655402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz cap->block_length = A2DP_BLOCK_LENGTH_16; 2665402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz else if (supported->block_length & A2DP_BLOCK_LENGTH_12) 2675402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz cap->block_length = A2DP_BLOCK_LENGTH_12; 2685402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz else if (supported->block_length & A2DP_BLOCK_LENGTH_8) 2695402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz cap->block_length = A2DP_BLOCK_LENGTH_8; 2705402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz else if (supported->block_length & A2DP_BLOCK_LENGTH_4) 2715402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz cap->block_length = A2DP_BLOCK_LENGTH_4; 2725402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz else { 2735402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz error("No supported block lengths"); 2745402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return FALSE; 2755402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz } 2765402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 2775402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz if (supported->subbands & A2DP_SUBBANDS_8) 2785402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz cap->subbands = A2DP_SUBBANDS_8; 2795402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz else if (supported->subbands & A2DP_SUBBANDS_4) 2805402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz cap->subbands = A2DP_SUBBANDS_4; 2815402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz else { 2825402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz error("No supported subbands"); 2835402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return FALSE; 2845402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz } 2855402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 2865402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz if (supported->allocation_method & A2DP_ALLOCATION_LOUDNESS) 2875402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz cap->allocation_method = A2DP_ALLOCATION_LOUDNESS; 2885402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz else if (supported->allocation_method & A2DP_ALLOCATION_SNR) 2895402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz cap->allocation_method = A2DP_ALLOCATION_SNR; 2905402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 291c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz min_bitpool = MAX(MIN_BITPOOL, supported->min_bitpool); 2925402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz max_bitpool = MIN(default_bitpool(cap->frequency, cap->channel_mode), 2934183300934043b1038c84652848c271a235bc5dfMarcel Holtmann supported->max_bitpool); 2945402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 2955402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz cap->min_bitpool = min_bitpool; 2965402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz cap->max_bitpool = max_bitpool; 2975402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 2985402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return TRUE; 2995402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz} 3005402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 30103490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedbergstatic gboolean a2dp_select_capabilities(struct avdtp *session, 30203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg struct avdtp_remote_sep *rsep, 3035402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz GSList **caps) 3045402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz{ 3055402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz struct avdtp_service_capability *media_transport, *media_codec; 30669e07f5a7b3934fac5bcf4c554e14e0d0b3cec47Luiz Augusto von Dentz struct sbc_codec_cap sbc_cap; 30703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg struct a2dp_stream_setup *setup; 3085402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 30903490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg setup = find_setup_by_session(session); 3105402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz if (!setup) 3115402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return FALSE; 3125402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 3134183300934043b1038c84652848c271a235bc5dfMarcel Holtmann if (setup->media_codec) { 31469e07f5a7b3934fac5bcf4c554e14e0d0b3cec47Luiz Augusto von Dentz memcpy(&sbc_cap, setup->media_codec->data, sizeof(sbc_cap)); 3154183300934043b1038c84652848c271a235bc5dfMarcel Holtmann } else { 3165402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz media_codec = avdtp_get_codec(rsep); 3175402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz if (!media_codec) 3185402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return FALSE; 3195402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 3205402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz select_sbc_params(&sbc_cap, 32141b71b230e0aa4b495c091e7d17c6b939ddbce79Luiz Augusto von Dentz (struct sbc_codec_cap *) media_codec->data); 3225402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz } 3235402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 3245402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT, 3255402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz NULL, 0); 3265402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 3275402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz *caps = g_slist_append(*caps, media_transport); 3285402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 3295402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &sbc_cap, 3305402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz sizeof(sbc_cap)); 3315402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 3325402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz *caps = g_slist_append(*caps, media_codec); 3335402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 33469e07f5a7b3934fac5bcf4c554e14e0d0b3cec47Luiz Augusto von Dentz 3355402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return TRUE; 3365402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz} 3375402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 338847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedbergstatic void discovery_complete(struct avdtp *session, GSList *seps, struct avdtp_error *err, 3395402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz void *user_data) 3405402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz{ 3415402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz struct avdtp_local_sep *lsep; 3425402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz struct avdtp_remote_sep *rsep; 34303490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg struct a2dp_stream_setup *setup; 3445402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz GSList *caps = NULL; 345847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg int posix_err; 3465402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 34703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg setup = find_setup_by_session(session); 34803490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg 34903490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg if (!setup) 35003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg return; 35103490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg 352847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg if (err || setup->canceled) { 3535402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz setup->stream = NULL; 354847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg finalize_stream_setup(setup, err); 3555402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return; 3565402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz } 3575402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 3585402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz debug("Discovery complete"); 3595402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 3605402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz if (avdtp_get_seps(session, AVDTP_SEP_TYPE_SINK, AVDTP_MEDIA_TYPE_AUDIO, 3615402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz A2DP_CODEC_SBC, &lsep, &rsep) < 0) { 3625402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz error("No matching ACP and INT SEPs found"); 363847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg finalize_stream_setup_errno(setup, -EINVAL); 3645402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return; 3655402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz } 3665402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 36703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg if (!a2dp_select_capabilities(session, rsep, &caps)) { 3685402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz error("Unable to select remote SEP capabilities"); 369847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg finalize_stream_setup_errno(setup, -EINVAL); 3705402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return; 3715402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz } 3725402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 373847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg posix_err = avdtp_set_configuration(session, rsep, lsep, caps, 3744183300934043b1038c84652848c271a235bc5dfMarcel Holtmann &setup->stream); 375847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg if (posix_err < 0) { 376847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg error("avdtp_set_configuration: %s", strerror(-posix_err)); 377847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg finalize_stream_setup_errno(setup, posix_err); 3785402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz } 3795402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz} 3805402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 381f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedbergstatic gboolean setconf_ind(struct avdtp *session, 382f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg struct avdtp_local_sep *sep, 3836763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg struct avdtp_stream *stream, 384f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg GSList *caps, uint8_t *err, 385666938b54d631956826343ed278e2af4b982fc29Johan Hedberg uint8_t *category, void *user_data) 3866763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 387666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 388f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg struct device *dev; 389c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz struct avdtp_service_capability *cap; 390c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz struct avdtp_media_codec_capability *codec_cap; 391c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz struct sbc_codec_cap *sbc_cap; 392f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg 393666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 3946763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Set_Configuration_Ind"); 395666938b54d631956826343ed278e2af4b982fc29Johan Hedberg else 396c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg debug("SBC Source: Set_Configuration_Ind"); 397f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg 398fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg dev = a2dp_get_dev(session); 399f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg if (!dev) { 400f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg *err = AVDTP_UNSUPPORTED_CONFIGURATION; 401f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg *category = 0x00; 402f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg return FALSE; 403f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg } 404f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg 405c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz /* Check bipool range */ 406c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz for (codec_cap = NULL; caps; caps = g_slist_next(caps)) { 407c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz cap = caps->data; 408c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz if (cap->category == AVDTP_MEDIA_CODEC) { 409c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz codec_cap = (void *) cap->data; 410c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz if (codec_cap->media_codec_type == A2DP_CODEC_SBC) { 411c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz sbc_cap = (void *) codec_cap; 412c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz if (sbc_cap->min_bitpool < MIN_BITPOOL || 413c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz sbc_cap->max_bitpool > MAX_BITPOOL) { 414c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz *err = AVDTP_UNSUPPORTED_CONFIGURATION; 415c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz *category = AVDTP_MEDIA_CODEC; 416c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz return FALSE; 417c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz } 418c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz } 419c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz break; 420c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz } 421c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz } 422c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz 4237a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep); 424c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg a2dp_sep->stream = stream; 425cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 426666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE) 427c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg sink_new_stream(dev, session, stream); 4286763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 4296763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return TRUE; 4306763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 4316763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 432f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean getcap_ind(struct avdtp *session, struct avdtp_local_sep *sep, 433666938b54d631956826343ed278e2af4b982fc29Johan Hedberg GSList **caps, uint8_t *err, void *user_data) 4346763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 435666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 4366763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg struct avdtp_service_capability *media_transport, *media_codec; 4376763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg struct sbc_codec_cap sbc_cap; 4386763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 439666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 4406763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Get_Capability_Ind"); 4416763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else 4426763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Source: Get_Capability_Ind"); 4436763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 4446763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg *caps = NULL; 4456763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 4466763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT, 4476763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg NULL, 0); 4486763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 4496763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg *caps = g_slist_append(*caps, media_transport); 4506763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 4516763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg memset(&sbc_cap, 0, sizeof(struct sbc_codec_cap)); 4526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 4536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sbc_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO; 4546763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sbc_cap.cap.media_codec_type = A2DP_CODEC_SBC; 4556763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 4566763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sbc_cap.frequency = ( A2DP_SAMPLING_FREQ_48000 | 4576763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg A2DP_SAMPLING_FREQ_44100 | 4586763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg A2DP_SAMPLING_FREQ_32000 | 4596763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg A2DP_SAMPLING_FREQ_16000 ); 4606763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 4616763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sbc_cap.channel_mode = ( A2DP_CHANNEL_MODE_JOINT_STEREO | 4626763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg A2DP_CHANNEL_MODE_STEREO | 4636763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg A2DP_CHANNEL_MODE_DUAL_CHANNEL | 4646763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg A2DP_CHANNEL_MODE_MONO ); 4656763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 4666763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sbc_cap.block_length = ( A2DP_BLOCK_LENGTH_16 | 4676763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg A2DP_BLOCK_LENGTH_12 | 4686763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg A2DP_BLOCK_LENGTH_8 | 4696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg A2DP_BLOCK_LENGTH_4 ); 4706763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 4716763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sbc_cap.subbands = ( A2DP_SUBBANDS_8 | A2DP_SUBBANDS_4 ); 4726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 4736763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sbc_cap.allocation_method = ( A2DP_ALLOCATION_LOUDNESS | 4746763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg A2DP_ALLOCATION_SNR ); 4756763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 476c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz sbc_cap.min_bitpool = MIN_BITPOOL; 477c4be6b437310018f154f7a01e6a3ddc2c9d1e175Luiz Augusto von Dentz sbc_cap.max_bitpool = MAX_BITPOOL; 4786763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 4796763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &sbc_cap, 4806763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sizeof(sbc_cap)); 4816763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 4826763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg *caps = g_slist_append(*caps, media_codec); 4836763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 4846763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return TRUE; 4856763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 4866763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 487f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 4880f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg struct avdtp_stream *stream, 489666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_error *err, void *user_data) 4906763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 491666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 49203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg struct a2dp_stream_setup *setup; 493fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg struct device *dev; 4940f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg int ret; 495cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 496666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 4976763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Set_Configuration_Cfm"); 498666938b54d631956826343ed278e2af4b982fc29Johan Hedberg else 499c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg debug("SBC Source: Set_Configuration_Cfm"); 500cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 50103490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg setup = find_setup_by_session(session); 50203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg 5030f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg if (err) { 5040f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg if (setup) 505847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg finalize_stream_setup(setup, err); 5060f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg return; 5070f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg } 5080f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg 5097a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep); 510c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg a2dp_sep->stream = stream; 511cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 512cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (!setup) 513cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return; 514cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 515fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg dev = a2dp_get_dev(session); 516fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg 51767d1e1774b3ff2d7a09fcf49484515bd85c02d14Johan Hedberg /* Notify sink.c of the new stream */ 518fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg sink_new_stream(dev, session, setup->stream); 51967d1e1774b3ff2d7a09fcf49484515bd85c02d14Johan Hedberg 5200f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg ret = avdtp_open(session, stream); 5210f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg if (ret < 0) { 5220f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg error("Error on avdtp_open %s (%d)", strerror(-ret), 5230f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg -ret); 5247a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg setup->stream = NULL; 525847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg finalize_stream_setup_errno(setup, ret); 526cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 5276763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 5286763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 529f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean getconf_ind(struct avdtp *session, struct avdtp_local_sep *sep, 530666938b54d631956826343ed278e2af4b982fc29Johan Hedberg uint8_t *err, void *user_data) 5316763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 532666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 533666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 534666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 5356763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Get_Configuration_Ind"); 5366763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else 5376763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Source: Get_Configuration_Ind"); 5386763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return TRUE; 5396763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 5406763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 541f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void getconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 542666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_stream *stream, struct avdtp_error *err, 543666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data) 5446763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 545666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 546666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 547666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 5486763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Set_Configuration_Cfm"); 5496763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else 5506763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Source: Set_Configuration_Cfm"); 5516763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 5526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 553f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean open_ind(struct avdtp *session, struct avdtp_local_sep *sep, 554666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_stream *stream, uint8_t *err, 555666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data) 5566763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 557666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 558666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 559666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 5606763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Open_Ind"); 5616763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else 5626763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Source: Open_Ind"); 5636763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return TRUE; 5646763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 5656763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 566f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void open_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 567666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_stream *stream, struct avdtp_error *err, 568666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data) 5696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 570666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 57103490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg struct a2dp_stream_setup *setup; 572847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg int posix_err; 573666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 574666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 5756763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Open_Cfm"); 5766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else 5776763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Source: Open_Cfm"); 5781addff77624b54445c9b81779ddc78892a126a45Johan Hedberg 57903490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg setup = find_setup_by_session(session); 580cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (!setup) 5811addff77624b54445c9b81779ddc78892a126a45Johan Hedberg return; 5821addff77624b54445c9b81779ddc78892a126a45Johan Hedberg 583cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (setup->canceled) { 5840f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg if (!err) 5850f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg avdtp_close(session, stream); 586cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg stream_setup_free(setup); 587cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return; 588cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 589cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 5900f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg if (err) { 5910f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg setup->stream = NULL; 592847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg finalize_stream_setup(setup, err); 593847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg return; 5940f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg } 5950f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg 596cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (setup->start) { 597847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg posix_err = avdtp_start(session, stream); 598847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg if (posix_err == 0) 599cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return; 6001addff77624b54445c9b81779ddc78892a126a45Johan Hedberg 601cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg error("avdtp_start failed"); 602847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg setup->stream = NULL; 6035402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz } 604847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg else 605847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg posix_err = 0; 606cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 607847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg finalize_stream_setup_errno(setup, -posix_err); 6086763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 6096763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 610c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedbergstatic gboolean suspend_timeout(struct a2dp_sep *sep) 611c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg{ 612c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg if (avdtp_suspend(sep->session, sep->stream) == 0) 613c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg sep->suspending = TRUE; 614c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg 6157a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg sep->suspend_timer = 0; 616c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg 617c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg avdtp_unref(sep->session); 618c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg sep->session = NULL; 619c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg 620c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg return FALSE; 621c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg} 622c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg 623f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean start_ind(struct avdtp *session, struct avdtp_local_sep *sep, 624666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_stream *stream, uint8_t *err, 625666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data) 6266763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 627666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 628c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg 629666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 6306763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Start_Ind"); 631666938b54d631956826343ed278e2af4b982fc29Johan Hedberg else 6326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Source: Start_Ind"); 6335b5cfaadb312600c58362617080e29fbf036712cJohan Hedberg 634c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg a2dp_sep->session = avdtp_ref(session); 635c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg 636c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg a2dp_sep->suspend_timer = g_timeout_add(SUSPEND_TIMEOUT, 637c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg (GSourceFunc) suspend_timeout, 638c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg a2dp_sep); 639c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg return TRUE; 6406763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 6416763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 642f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void start_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 643666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_stream *stream, struct avdtp_error *err, 644666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data) 6456763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 646666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 64703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg struct a2dp_stream_setup *setup; 648666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 649666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 6506763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Start_Cfm"); 6516763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else 6526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Source: Start_Cfm"); 653cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 65403490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg setup = find_setup_by_session(session); 655cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (!setup) 656cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return; 657cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 658cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (setup->canceled) { 6590f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg if (!err) 6600f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg avdtp_close(session, stream); 661cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg stream_setup_free(setup); 662cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return; 663cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 664cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 665847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg if (err) { 6660f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg setup->stream = NULL; 667847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg finalize_stream_setup(setup, err); 668847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg } 669847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg else 670847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg finalize_stream_setup_errno(setup, 0); 6716763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 6726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 673f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean suspend_ind(struct avdtp *session, struct avdtp_local_sep *sep, 674666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_stream *stream, uint8_t *err, 675666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data) 6766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 677666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 678666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 679666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 6806763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Suspend_Ind"); 6816763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else 6826763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Source: Suspend_Ind"); 6836763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return TRUE; 6846763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 6856763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 686f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void suspend_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 687666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_stream *stream, struct avdtp_error *err, 688666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data) 6896763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 690666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 69103490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg struct a2dp_stream_setup *setup; 692847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg int posix_err; 693c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg 694666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 6956763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Suspend_Cfm"); 696666938b54d631956826343ed278e2af4b982fc29Johan Hedberg else 697c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg debug("SBC Source: Suspend_Cfm"); 698cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 699c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg a2dp_sep->suspending = FALSE; 700cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 70103490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg setup = find_setup_by_session(session); 70203490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg if (!setup) 70303490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg return; 70403490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg 7050f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg if (err) { 706847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg finalize_stream_setup(setup, err); 7070f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg return; 7080f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg } 7090f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg 71003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg if (setup->start) { 711847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg posix_err = avdtp_start(session, stream); 712847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg if (posix_err < 0) 713847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg finalize_stream_setup_errno(setup, posix_err); 714cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 7156763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 7166763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 717f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean close_ind(struct avdtp *session, struct avdtp_local_sep *sep, 718666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_stream *stream, uint8_t *err, 719666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data) 7206763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 721666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 722c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg 723666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 7246763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Close_Ind"); 725666938b54d631956826343ed278e2af4b982fc29Johan Hedberg else 726c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg debug("SBC Source: Close_Ind"); 727cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 7286763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return TRUE; 7296763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 7306763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 731f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void close_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 732666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_stream *stream, struct avdtp_error *err, 733666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data) 7346763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 735666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 73603490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg struct a2dp_stream_setup *setup; 737847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg int posix_err; 738c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg 739666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 7406763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Close_Cfm"); 741666938b54d631956826343ed278e2af4b982fc29Johan Hedberg else 742c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg debug("SBC Source: Close_Cfm"); 7435402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 74403490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg setup = find_setup_by_session(session); 7455402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz if (!setup) 7465402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return; 7475402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 7485402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz if (setup->canceled) { 7495402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz stream_setup_free(setup); 7505402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return; 7515402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz } 7525402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 7535402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz if (err) { 7545402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz setup->stream = NULL; 755847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg finalize_stream_setup(setup, err); 756847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg return; 7575402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz } 7585402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 7595402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz if (setup->start) { 760847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg posix_err = avdtp_discover(session, discovery_complete, setup); 761847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg if (posix_err == 0) 7625402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return; 7635402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 7645402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz error("avdtp_discover failed"); 7655402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz setup->stream = NULL; 7665402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz } 767847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg else 768847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg posix_err = 0; 7695402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 770847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg finalize_stream_setup_errno(setup, -posix_err); 7716763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 7726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 773f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean abort_ind(struct avdtp *session, struct avdtp_local_sep *sep, 774666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_stream *stream, uint8_t *err, 775666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data) 7766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 777666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 778c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg 779666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 7806763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Abort_Ind"); 781666938b54d631956826343ed278e2af4b982fc29Johan Hedberg else 782c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg debug("SBC Source: Abort_Ind"); 783cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 784fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg a2dp_sep->stream = NULL; 78503490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg 7866763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return TRUE; 7876763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 7886763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 789f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void abort_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 790666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_stream *stream, struct avdtp_error *err, 791666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data) 7926763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 793666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 794c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg 795666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 7966763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Abort_Cfm"); 797666938b54d631956826343ed278e2af4b982fc29Johan Hedberg else 7986763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Source: Abort_Cfm"); 7996763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 8006763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 801f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean reconf_ind(struct avdtp *session, struct avdtp_local_sep *sep, 802666938b54d631956826343ed278e2af4b982fc29Johan Hedberg uint8_t *err, void *user_data) 8036763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 804666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 805666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 806666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 8076763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: ReConfigure_Ind"); 8086763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else 8096763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Source: ReConfigure_Ind"); 8106763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return TRUE; 8116763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 8126763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 8130f458da19471c933a4105cc450c48548b72edc8eJohan Hedbergstatic void reconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 814666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_stream *stream, struct avdtp_error *err, 815666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data) 8166763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 817666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 81803490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg struct a2dp_stream_setup *setup; 819847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg int posix_err; 820666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 821666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 8226763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: ReConfigure_Cfm"); 8236763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else 8246763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Source: ReConfigure_Cfm"); 8255402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 82603490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg setup = find_setup_by_session(session); 8275402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz if (!setup) 8285402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return; 8295402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 8305402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz if (setup->canceled) { 8315402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz if (!err) 8325402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz avdtp_close(session, stream); 8335402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz stream_setup_free(setup); 8345402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return; 8355402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz } 8365402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 8375402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz if (err) { 8385402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz setup->stream = NULL; 839847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg finalize_stream_setup(setup, err); 840847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg return; 8415402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz } 8425402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 8435402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz if (setup->start) { 844847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg posix_err = avdtp_start(session, stream); 845847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg if (posix_err == 0) 8465402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz return; 8475402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 8485402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz error("avdtp_start failed"); 8495402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz setup->stream = NULL; 8505402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz } 851847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg else 852847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg posix_err = 0; 8535402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 854847dad179fe16ec395373e4b55d46dcd400c623aJohan Hedberg finalize_stream_setup_errno(setup, -posix_err); 8556763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 8566763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 8576763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic struct avdtp_sep_cfm cfm = { 8586763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .set_configuration = setconf_cfm, 8596763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .get_configuration = getconf_cfm, 8606763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .open = open_cfm, 8616763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .start = start_cfm, 8626763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .suspend = suspend_cfm, 8636763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .close = close_cfm, 8646763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .abort = abort_cfm, 8656763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .reconfigure = reconf_cfm 8666763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}; 8676763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 8686763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic struct avdtp_sep_ind ind = { 8696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .get_capability = getcap_ind, 8706763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .set_configuration = setconf_ind, 8716763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .get_configuration = getconf_ind, 8726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .open = open_ind, 8736763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .start = start_ind, 8746763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .suspend = suspend_ind, 8756763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .close = close_ind, 8766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .abort = abort_ind, 8776763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .reconfigure = reconf_ind 8786763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}; 8796763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 8806763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic int a2dp_source_record(sdp_buf_t *buf) 8816763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 8826763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_list_t *svclass_id, *pfseq, *apseq, *root; 8836763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg uuid_t root_uuid, l2cap, avdtp, a2src; 8846763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_profile_desc_t profile[1]; 8856763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_list_t *aproto, *proto[2]; 8866763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_record_t record; 8876763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_data_t *psm, *version, *features; 8886763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg uint16_t lp = AVDTP_UUID, ver = 0x0100, feat = 0x000F; 8896763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg int ret = 0; 8906763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 8916763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg memset(&record, 0, sizeof(sdp_record_t)); 8926763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 8936763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); 8946763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg root = sdp_list_append(0, &root_uuid); 8956763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_set_browse_groups(&record, root); 8966763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 8976763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_uuid16_create(&a2src, AUDIO_SOURCE_SVCLASS_ID); 8986763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg svclass_id = sdp_list_append(0, &a2src); 8996763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_set_service_classes(&record, svclass_id); 9006763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 9016763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID); 9026763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg profile[0].version = 0x0100; 9036763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg pfseq = sdp_list_append(0, &profile[0]); 9046763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_set_profile_descs(&record, pfseq); 9056763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 9066763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_uuid16_create(&l2cap, L2CAP_UUID); 9076763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg proto[0] = sdp_list_append(0, &l2cap); 9086763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg psm = sdp_data_alloc(SDP_UINT16, &lp); 9096763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg proto[0] = sdp_list_append(proto[0], psm); 9106763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg apseq = sdp_list_append(0, proto[0]); 9116763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 9126763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_uuid16_create(&avdtp, AVDTP_UUID); 9136763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg proto[1] = sdp_list_append(0, &avdtp); 9146763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg version = sdp_data_alloc(SDP_UINT16, &ver); 9156763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg proto[1] = sdp_list_append(proto[1], version); 9166763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg apseq = sdp_list_append(apseq, proto[1]); 9176763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 9186763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg aproto = sdp_list_append(0, apseq); 9196763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_set_access_protos(&record, aproto); 9206763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 9216763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg features = sdp_data_alloc(SDP_UINT16, &feat); 9226763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features); 9236763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 9246763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_set_info_attr(&record, "Audio Source", 0, 0); 9256763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 9266763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg if (sdp_gen_record_pdu(&record, buf) < 0) 9276763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg ret = -1; 9286763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else 9296763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg ret = 0; 9306763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 9316763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg free(psm); 9326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg free(version); 9336763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_list_free(proto[0], 0); 9346763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_list_free(proto[1], 0); 9356763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_list_free(apseq, 0); 9366763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_list_free(pfseq, 0); 9376763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_list_free(aproto, 0); 9386763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_list_free(root, 0); 9396763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_list_free(svclass_id, 0); 9406763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_list_free(record.attrlist, (sdp_free_func_t) sdp_data_free); 9416763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_list_free(record.pattern, free); 9426763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 9436763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return ret; 9446763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 9456763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 9466763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic int a2dp_sink_record(sdp_buf_t *buf) 9476763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 9486763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return 0; 9496763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 9506763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 951666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic struct a2dp_sep *a2dp_add_sep(DBusConnection *conn, uint8_t type) 9526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 953666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *sep; 954666938b54d631956826343ed278e2af4b982fc29Johan Hedberg GSList **l; 955666938b54d631956826343ed278e2af4b982fc29Johan Hedberg int (*create_record)(sdp_buf_t *buf); 956666938b54d631956826343ed278e2af4b982fc29Johan Hedberg uint32_t *record_id; 9576763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_buf_t buf; 9586763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 959666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep = g_new0(struct a2dp_sep, 1); 960666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 961666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep->sep = avdtp_register_sep(type, AVDTP_MEDIA_TYPE_AUDIO, 962666938b54d631956826343ed278e2af4b982fc29Johan Hedberg &ind, &cfm, sep); 963666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (sep->sep == NULL) { 964666938b54d631956826343ed278e2af4b982fc29Johan Hedberg g_free(sep); 965666938b54d631956826343ed278e2af4b982fc29Johan Hedberg return NULL; 966666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } 967666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 968666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep->type = type; 969666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 970666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (type == AVDTP_SEP_TYPE_SOURCE) { 971666938b54d631956826343ed278e2af4b982fc29Johan Hedberg l = &sources; 972666938b54d631956826343ed278e2af4b982fc29Johan Hedberg create_record = a2dp_source_record; 973666938b54d631956826343ed278e2af4b982fc29Johan Hedberg record_id = &source_record_id; 974666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } else { 975666938b54d631956826343ed278e2af4b982fc29Johan Hedberg l = &sinks; 976666938b54d631956826343ed278e2af4b982fc29Johan Hedberg create_record = a2dp_sink_record; 977666938b54d631956826343ed278e2af4b982fc29Johan Hedberg record_id = &sink_record_id; 978666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } 979666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 980666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (*record_id != 0) 981666938b54d631956826343ed278e2af4b982fc29Johan Hedberg goto add; 982666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 983666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (create_record(&buf) < 0) { 984666938b54d631956826343ed278e2af4b982fc29Johan Hedberg error("Unable to allocate new service record"); 985666938b54d631956826343ed278e2af4b982fc29Johan Hedberg avdtp_unregister_sep(sep->sep); 986666938b54d631956826343ed278e2af4b982fc29Johan Hedberg g_free(sep); 987666938b54d631956826343ed278e2af4b982fc29Johan Hedberg return NULL; 988666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } 989666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 990666938b54d631956826343ed278e2af4b982fc29Johan Hedberg *record_id = add_service_record(conn, &buf); 991666938b54d631956826343ed278e2af4b982fc29Johan Hedberg free(buf.data); 992666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (!*record_id) { 993666938b54d631956826343ed278e2af4b982fc29Johan Hedberg error("Unable to register A2DP service record"); 994666938b54d631956826343ed278e2af4b982fc29Johan Hedberg avdtp_unregister_sep(sep->sep); 995666938b54d631956826343ed278e2af4b982fc29Johan Hedberg g_free(sep); 996666938b54d631956826343ed278e2af4b982fc29Johan Hedberg return NULL; 997666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } 998666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 999666938b54d631956826343ed278e2af4b982fc29Johan Hedbergadd: 1000666938b54d631956826343ed278e2af4b982fc29Johan Hedberg *l = g_slist_append(*l, sep); 1001666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 1002666938b54d631956826343ed278e2af4b982fc29Johan Hedberg return sep; 1003666938b54d631956826343ed278e2af4b982fc29Johan Hedberg} 1004666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 1005e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedbergint a2dp_init(DBusConnection *conn, int sources, int sinks) 1006666938b54d631956826343ed278e2af4b982fc29Johan Hedberg{ 1007e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedberg int i; 1008e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedberg 1009e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedberg if (!sources && !sinks) 10106763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return 0; 10116763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 10126763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg connection = dbus_connection_ref(conn); 10136763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 10146763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg avdtp_init(); 10156763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 1016e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedberg for (i = 0; i < sources; i++) 1017666938b54d631956826343ed278e2af4b982fc29Johan Hedberg a2dp_add_sep(conn, AVDTP_SEP_TYPE_SOURCE); 10186763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 1019e2827b35575bab20a99a170805a0a59a32fb2c48Johan Hedberg for (i = 0; i < sinks; i++) 1020666938b54d631956826343ed278e2af4b982fc29Johan Hedberg a2dp_add_sep(conn, AVDTP_SEP_TYPE_SINK); 10216763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 10226763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return 0; 10236763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 10246763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 1025666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic void a2dp_unregister_sep(struct a2dp_sep *sep) 1026666938b54d631956826343ed278e2af4b982fc29Johan Hedberg{ 1027666938b54d631956826343ed278e2af4b982fc29Johan Hedberg avdtp_unregister_sep(sep->sep); 1028666938b54d631956826343ed278e2af4b982fc29Johan Hedberg g_free(sep); 1029666938b54d631956826343ed278e2af4b982fc29Johan Hedberg} 1030666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 10316763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergvoid a2dp_exit() 10326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 1033666938b54d631956826343ed278e2af4b982fc29Johan Hedberg g_slist_foreach(sinks, (GFunc) a2dp_unregister_sep, NULL); 1034666938b54d631956826343ed278e2af4b982fc29Johan Hedberg g_slist_free(sinks); 1035666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sinks = NULL; 10366763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 1037666938b54d631956826343ed278e2af4b982fc29Johan Hedberg g_slist_foreach(sources, (GFunc) a2dp_unregister_sep, NULL); 1038666938b54d631956826343ed278e2af4b982fc29Johan Hedberg g_slist_free(sources); 1039666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sources = NULL; 10406763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 1041666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (source_record_id) { 1042666938b54d631956826343ed278e2af4b982fc29Johan Hedberg remove_service_record(connection, source_record_id); 1043666938b54d631956826343ed278e2af4b982fc29Johan Hedberg source_record_id = 0; 10446763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg } 10456763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 1046666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (sink_record_id) { 1047666938b54d631956826343ed278e2af4b982fc29Johan Hedberg remove_service_record(connection, sink_record_id); 1048666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sink_record_id = 0; 10496763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg } 10506763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 10516763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg dbus_connection_unref(connection); 10526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 10536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 1054d1fb0b25a9882016de70f102408f10101b348e57Johan Hedberggboolean a2dp_source_cancel_stream(struct device *dev, unsigned int id) 1055cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{ 1056cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg struct a2dp_stream_cb *cb_data; 105703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg struct a2dp_stream_setup *setup; 1058cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg GSList *l; 1059cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 106003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg setup = find_setup_by_dev(dev); 1061cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (!setup) 1062cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return FALSE; 1063cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1064cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg for (cb_data = NULL, l = setup->cb; l != NULL; l = g_slist_next(l)) { 1065cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg struct a2dp_stream_cb *cb = l->data; 1066cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1067cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (cb->id == id) { 1068cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg cb_data = cb; 1069cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg break; 1070cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 1071cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 1072cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1073cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (!cb_data) 1074cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return FALSE; 1075cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1076cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg setup->cb = g_slist_remove(setup->cb, cb_data); 10779ce01693dd0aa7407b7d8eb37c8524dd05abe15cJohan Hedberg g_free(cb_data); 1078cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1079828133c3180a090a06ace6637d9f84ae5f57ae33Johan Hedberg if (!setup->cb) { 1080cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg setup->canceled = TRUE; 108103490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg setup->sep = NULL; 1082828133c3180a090a06ace6637d9f84ae5f57ae33Johan Hedberg } 1083cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1084cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return TRUE; 1085cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg} 1086cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 10870f458da19471c933a4105cc450c48548b72edc8eJohan Hedbergunsigned int a2dp_source_request_stream(struct avdtp *session, 1088666938b54d631956826343ed278e2af4b982fc29Johan Hedberg gboolean start, 1089666938b54d631956826343ed278e2af4b982fc29Johan Hedberg a2dp_stream_cb_t cb, 1090666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data, 10915402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz struct avdtp_service_capability *media_codec) 1092cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{ 1093cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg struct a2dp_stream_cb *cb_data; 1094cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg static unsigned int cb_id = 0; 1095666938b54d631956826343ed278e2af4b982fc29Johan Hedberg GSList *l; 109603490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg struct a2dp_stream_setup *setup; 1097666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *sep = NULL; 1098cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1099666938b54d631956826343ed278e2af4b982fc29Johan Hedberg for (l = sources; l != NULL; l = l->next) { 1100666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *tmp = l->data; 1101666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 1102666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (tmp->locked) 1103666938b54d631956826343ed278e2af4b982fc29Johan Hedberg continue; 1104666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 1105fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg if (!tmp->stream || avdtp_has_stream(session, tmp->stream)) { 1106666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep = tmp; 1107666938b54d631956826343ed278e2af4b982fc29Johan Hedberg break; 1108666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } 1109666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } 1110666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 1111666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (!sep) { 1112666938b54d631956826343ed278e2af4b982fc29Johan Hedberg error("a2dp_source_request_stream: no available SEP found"); 1113730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg return 0; 1114730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg } 1115730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg 111603490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg setup = find_setup_by_session(session); 1117730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg 1118666938b54d631956826343ed278e2af4b982fc29Johan Hedberg debug("a2dp_source_request_stream: selected SEP %p", sep); 1119666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 1120cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg cb_data = g_new(struct a2dp_stream_cb, 1); 1121cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg cb_data->cb = cb; 1122cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg cb_data->user_data = user_data; 11230f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg cb_data->id = ++cb_id; 1124cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1125cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (setup) { 1126cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg setup->canceled = FALSE; 112703490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg setup->sep = sep; 1128cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg setup->cb = g_slist_append(setup->cb, cb_data); 1129cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (start) 1130cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg setup->start = TRUE; 1131cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return cb_data->id; 1132cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 1133cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1134cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg setup = g_new0(struct a2dp_stream_setup, 1); 1135cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg setup->session = avdtp_ref(session); 1136828133c3180a090a06ace6637d9f84ae5f57ae33Johan Hedberg setup->sep = sep; 1137cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg setup->cb = g_slist_append(setup->cb, cb_data); 1138cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg setup->start = start; 1139666938b54d631956826343ed278e2af4b982fc29Johan Hedberg setup->stream = sep->stream; 11405402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz setup->media_codec = media_codec; 1141cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1142666938b54d631956826343ed278e2af4b982fc29Johan Hedberg switch (avdtp_sep_get_state(sep->sep)) { 1143cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg case AVDTP_STATE_IDLE: 1144730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg if (avdtp_discover(session, discovery_complete, setup) < 0) { 1145730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg error("avdtp_discover failed"); 1146cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg goto failed; 1147730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg } 1148cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg break; 1149cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg case AVDTP_STATE_OPEN: 1150cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (!start) { 1151cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg g_idle_add((GSourceFunc) finalize_stream_setup, setup); 1152cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg break; 1153cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 1154666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (sep->starting) 1155cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg break; 11565402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz if (setup->media_codec) { 11575402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz if (avdtp_stream_has_capability(setup->stream, 11584183300934043b1038c84652848c271a235bc5dfMarcel Holtmann setup->media_codec)) { 11595402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz if (avdtp_start(session, sep->stream) < 0) { 11605402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz error("avdtp_start failed"); 11615402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz goto failed; 11625402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz } 11635402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz } else { 11645402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz if (avdtp_close(session, sep->stream) < 0) { 11655402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz error("avdtp_close failed"); 11665402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz goto failed; 11675402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz } 11685402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz } 11695402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz } 11705402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz else if (avdtp_start(session, sep->stream) < 0) { 1171730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg error("avdtp_start failed"); 1172cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg goto failed; 1173730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg } 1174cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg break; 1175cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg case AVDTP_STATE_STREAMING: 1176666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (!start || !sep->suspending) { 1177666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (sep->suspend_timer) { 1178666938b54d631956826343ed278e2af4b982fc29Johan Hedberg g_source_remove(sep->suspend_timer); 1179666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep->suspend_timer = 0; 118058b173171f61373c7eb8ed00d0635fb06fa741ccJohan Hedberg } 1181edce261bbbcaa3bca4d68289e4f244c1f709c0c9Johan Hedberg g_idle_add((GSourceFunc) finalize_stream_setup, setup); 1182cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 1183cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg break; 1184cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg default: 1185730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg error("SEP in bad state for requesting a new stream"); 1186cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg goto failed; 1187cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 11885402a5058f463efd3bc84d43b1af10ff253b9a1eLuiz Augusto von Dentz 118903490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg setups = g_slist_append(setups, setup); 119003490d81bbe11641c47cd8e7e0c64a45db4f80f4Johan Hedberg 1191cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return cb_data->id; 1192cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1193cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergfailed: 1194cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg stream_setup_free(setup); 1195cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg cb_id--; 11960f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg return 0; 1197cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg} 1198cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1199fc0d501d82773718d0f2d040f786136332c39813Johan Hedberggboolean a2dp_sep_lock(struct a2dp_sep *sep, struct avdtp *session) 1200cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{ 1201fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg if (sep->locked) 1202fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg return FALSE; 1203f4211a3cd3442d54fa7877a6c421bee034d46e8eJohan Hedberg 1204fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg debug("SBC Source SEP %p locked", sep); 1205fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg sep->locked = TRUE; 1206666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 1207fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg return TRUE; 1208cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg} 1209cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1210fc0d501d82773718d0f2d040f786136332c39813Johan Hedberggboolean a2dp_sep_unlock(struct a2dp_sep *sep, struct avdtp *session) 1211cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{ 1212cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg avdtp_state_t state; 1213cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1214666938b54d631956826343ed278e2af4b982fc29Johan Hedberg state = avdtp_sep_get_state(sep->sep); 1215cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1216666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep->locked = FALSE; 1217cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1218666938b54d631956826343ed278e2af4b982fc29Johan Hedberg debug("SBC Source SEP %p unlocked", sep); 1219730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg 1220666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (!sep->stream || state == AVDTP_STATE_IDLE) 1221cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return TRUE; 1222cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1223cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg switch (state) { 1224cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg case AVDTP_STATE_OPEN: 1225cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg /* Set timer here */ 1226cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg break; 1227cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg case AVDTP_STATE_STREAMING: 1228666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (avdtp_suspend(session, sep->stream) == 0) 1229666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep->suspending = TRUE; 1230cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg break; 1231cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg default: 1232cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg break; 1233cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 1234cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1235cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return TRUE; 1236cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg} 1237cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1238cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberggboolean a2dp_source_suspend(struct device *dev, struct avdtp *session) 1239cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{ 1240cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg avdtp_state_t state; 1241666938b54d631956826343ed278e2af4b982fc29Johan Hedberg GSList *l; 1242666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *sep = NULL; 1243cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1244666938b54d631956826343ed278e2af4b982fc29Johan Hedberg for (l = sources; l != NULL; l = l->next) { 1245666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *tmp = l->data; 1246cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1247fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg if (tmp->session && tmp->session == session) { 1248666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep = tmp; 1249666938b54d631956826343ed278e2af4b982fc29Johan Hedberg break; 1250666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } 1251666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } 1252666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 1253666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (!sep) 1254cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return FALSE; 1255cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1256666938b54d631956826343ed278e2af4b982fc29Johan Hedberg state = avdtp_sep_get_state(sep->sep); 1257cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1258666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (!sep->stream || state != AVDTP_STATE_STREAMING) 1259cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return TRUE; 1260cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1261666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (avdtp_suspend(session, sep->stream) == 0) { 1262666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep->suspending = TRUE; 1263cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return TRUE; 1264cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 1265cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1266cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return FALSE; 1267cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg} 1268cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1269cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberggboolean a2dp_source_start_stream(struct device *dev, struct avdtp *session) 1270cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{ 1271cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg avdtp_state_t state; 1272666938b54d631956826343ed278e2af4b982fc29Johan Hedberg GSList *l; 1273666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *sep = NULL; 1274cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1275666938b54d631956826343ed278e2af4b982fc29Johan Hedberg for (l = sources; l != NULL; l = l->next) { 1276666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *tmp = l->data; 1277666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 1278fc0d501d82773718d0f2d040f786136332c39813Johan Hedberg if (tmp->session && tmp->session == session) { 1279666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep = tmp; 1280666938b54d631956826343ed278e2af4b982fc29Johan Hedberg break; 1281666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } 1282666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } 1283cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1284666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (!sep) 1285cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return FALSE; 1286cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1287666938b54d631956826343ed278e2af4b982fc29Johan Hedberg state = avdtp_sep_get_state(sep->sep); 1288cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1289cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (state < AVDTP_STATE_OPEN) { 1290cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg error("a2dp_source_start_stream: no stream open"); 1291cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return FALSE; 1292cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 1293cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1294cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (state == AVDTP_STATE_STREAMING) 1295cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return TRUE; 1296cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1297666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (avdtp_start(session, sep->stream) < 0) 1298cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return FALSE; 1299cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1300cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return TRUE; 13011addff77624b54445c9b81779ddc78892a126a45Johan Hedberg} 1302