a2dp.c revision f4211a3cd3442d54fa7877a6c421bee034d46e8e
1e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg/* 2e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg * 3e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg * BlueZ - Bluetooth protocol stack for Linux 4e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg * 5e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg * Copyright (C) 2004-2007 Marcel Holtmann <marcel@holtmann.org> 6e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg * 7e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg * 8e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg * This program is free software; you can redistribute it and/or modify 9e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg * it under the terms of the GNU General Public License as published by 10e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg * the Free Software Foundation; either version 2 of the License, or 11e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg * (at your option) any later version. 12e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg * 13e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg * This program is distributed in the hope that it will be useful, 14e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg * but WITHOUT ANY WARRANTY; without even the implied warranty of 15e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg * GNU General Public License for more details. 17e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg * 18e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg * You should have received a copy of the GNU General Public License 19e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg * along with this program; if not, write to the Free Software 20e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 21e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg * 22e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg */ 23e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg 24e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg#ifdef HAVE_CONFIG_H 25e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg#include <config.h> 26e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg#endif 27e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg 286763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include <stdlib.h> 296763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 306763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include <dbus/dbus.h> 316763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include <glib.h> 326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 33c2833e263d6cfc4cf82f4bfdcc59640a4071aeaeJohan Hedberg#include <bluetooth/bluetooth.h> 346763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include <bluetooth/sdp.h> 356763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include <bluetooth/sdp_lib.h> 366763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 376763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include "logging.h" 386763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include "manager.h" 39d013a1eaa7beebbb49c1fe0015c70ad81566d97cJohan Hedberg#include "device.h" 406763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg#include "avdtp.h" 41f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg#include "sink.h" 42e929f72c17c104ed4eb6c15bda8f5d2be58c8084Johan Hedberg#include "a2dp.h" 436763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 44c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg/* The duration that streams without users are allowed to stay in 45c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg * STREAMING state. */ 46c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg#define SUSPEND_TIMEOUT 5000 47c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg 48cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg#ifndef MIN 49cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg# define MIN(x, y) ((x) < (y) ? (x) : (y)) 50cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg#endif 51cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 52cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg#ifndef MAX 53cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg# define MAX(x, y) ((x) > (y) ? (x) : (y)) 54cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg#endif 55cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 56cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergstruct a2dp_sep { 57666938b54d631956826343ed278e2af4b982fc29Johan Hedberg uint8_t type; 58cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg struct avdtp_local_sep *sep; 59c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg struct avdtp *session; 60cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg struct avdtp_stream *stream; 61cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg struct device *used_by; 62c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg guint suspend_timer; 63666938b54d631956826343ed278e2af4b982fc29Johan Hedberg gboolean locked; 64cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg gboolean start_requested; 65cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg gboolean suspending; 66cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg gboolean starting; 67cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}; 68cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 69cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergstruct a2dp_stream_cb { 70cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg a2dp_stream_cb_t cb; 71cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg void *user_data; 72cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg int id; 73cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}; 74cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 75cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergstruct a2dp_stream_setup { 76cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg struct avdtp *session; 77cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg struct device *dev; 78cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg struct avdtp_stream *stream; 79cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg gboolean start; 80cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg gboolean canceled; 81cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg GSList *cb; 82cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg}; 83cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 846763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic DBusConnection *connection = NULL; 856763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 86666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic GSList *sinks = NULL; 87666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic GSList *sources = NULL; 88666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 89666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic uint32_t source_record_id = 0; 90666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic uint32_t sink_record_id = 0; 916763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 92cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergstatic struct a2dp_stream_setup *setup = NULL; 936763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 94cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergstatic void stream_setup_free(struct a2dp_stream_setup *s) 95cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{ 96cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (s->session) 97cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg avdtp_unref(s->session); 98cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg g_slist_foreach(s->cb, (GFunc) g_free, NULL); 99cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg g_slist_free(s->cb); 100cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg g_free(s); 101cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg setup = NULL; 102cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg} 103cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 104cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergstatic void setup_callback(struct a2dp_stream_cb *cb, 105cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg struct a2dp_stream_setup *s) 106cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{ 107cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg cb->cb(s->session, s->dev, s->stream, cb->user_data); 108cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg} 109cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 11078a94059160d7478624cad315022255f7ebbbe80Johan Hedbergstatic gboolean finalize_stream_setup(struct a2dp_stream_setup *s) 111cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{ 112cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg g_slist_foreach(setup->cb, (GFunc) setup_callback, setup); 113cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg stream_setup_free(setup); 11478a94059160d7478624cad315022255f7ebbbe80Johan Hedberg return FALSE; 115cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg} 1161addff77624b54445c9b81779ddc78892a126a45Johan Hedberg 1177a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedbergstatic void stream_state_changed(struct avdtp_stream *stream, 1187a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg avdtp_state_t old_state, 1197a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg avdtp_state_t new_state, 1207a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg struct avdtp_error *err, 1217a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg void *user_data) 1227a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg{ 1237a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg struct a2dp_sep *sep = user_data; 1247a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg 1257a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg if (new_state != AVDTP_STATE_IDLE) 1267a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg return; 1277a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg 1287a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg if (sep->suspend_timer) { 1297a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg g_source_remove(sep->suspend_timer); 1307a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg sep->suspend_timer = 0; 1317a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg } 1327a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg 1337a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg if (sep->session) { 1347a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg avdtp_unref(sep->session); 1357a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg sep->session = NULL; 1367a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg } 1377a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg 1387a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg sep->stream = NULL; 1397a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg} 1407a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg 141f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedbergstatic gboolean setconf_ind(struct avdtp *session, 142f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg struct avdtp_local_sep *sep, 1436763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg struct avdtp_stream *stream, 144f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg GSList *caps, uint8_t *err, 145666938b54d631956826343ed278e2af4b982fc29Johan Hedberg uint8_t *category, void *user_data) 1466763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 147666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 148f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg struct device *dev; 149f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg bdaddr_t addr; 150f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg 151666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 1526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Set_Configuration_Ind"); 153666938b54d631956826343ed278e2af4b982fc29Johan Hedberg else 154c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg debug("SBC Source: Set_Configuration_Ind"); 155f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg 156f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg avdtp_get_peers(session, NULL, &addr); 157f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg 158f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg dev = manager_device_connected(&addr, A2DP_SOURCE_UUID); 159f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg if (!dev) { 160f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg *err = AVDTP_UNSUPPORTED_CONFIGURATION; 161f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg *category = 0x00; 162f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg return FALSE; 163f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg } 164f817fefff69cc44d5a2e1ba7d8ed9976fe3b4235Johan Hedberg 1657a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep); 166c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg a2dp_sep->stream = stream; 167cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 168666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE) 169c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg sink_new_stream(dev, session, stream); 1706763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 1716763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return TRUE; 1726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 1736763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 174f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean getcap_ind(struct avdtp *session, struct avdtp_local_sep *sep, 175666938b54d631956826343ed278e2af4b982fc29Johan Hedberg GSList **caps, uint8_t *err, void *user_data) 1766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 177666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 1786763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg struct avdtp_service_capability *media_transport, *media_codec; 1796763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg struct sbc_codec_cap sbc_cap; 1806763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 181666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 1826763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Get_Capability_Ind"); 1836763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else 1846763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Source: Get_Capability_Ind"); 1856763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 1866763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg *caps = NULL; 1876763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 1886763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT, 1896763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg NULL, 0); 1906763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 1916763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg *caps = g_slist_append(*caps, media_transport); 1926763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 1936763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg memset(&sbc_cap, 0, sizeof(struct sbc_codec_cap)); 1946763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 1956763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sbc_cap.cap.media_type = AVDTP_MEDIA_TYPE_AUDIO; 1966763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sbc_cap.cap.media_codec_type = A2DP_CODEC_SBC; 1976763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 1986763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sbc_cap.frequency = ( A2DP_SAMPLING_FREQ_48000 | 1996763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg A2DP_SAMPLING_FREQ_44100 | 2006763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg A2DP_SAMPLING_FREQ_32000 | 2016763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg A2DP_SAMPLING_FREQ_16000 ); 2026763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 2036763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sbc_cap.channel_mode = ( A2DP_CHANNEL_MODE_JOINT_STEREO | 2046763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg A2DP_CHANNEL_MODE_STEREO | 2056763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg A2DP_CHANNEL_MODE_DUAL_CHANNEL | 2066763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg A2DP_CHANNEL_MODE_MONO ); 2076763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 2086763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sbc_cap.block_length = ( A2DP_BLOCK_LENGTH_16 | 2096763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg A2DP_BLOCK_LENGTH_12 | 2106763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg A2DP_BLOCK_LENGTH_8 | 2116763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg A2DP_BLOCK_LENGTH_4 ); 2126763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 2136763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sbc_cap.subbands = ( A2DP_SUBBANDS_8 | A2DP_SUBBANDS_4 ); 2146763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 2156763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sbc_cap.allocation_method = ( A2DP_ALLOCATION_LOUDNESS | 2166763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg A2DP_ALLOCATION_SNR ); 2176763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 2186763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sbc_cap.min_bitpool = 2; 2196763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sbc_cap.max_bitpool = 250; 2206763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 2216763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &sbc_cap, 2226763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sizeof(sbc_cap)); 2236763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 2246763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg *caps = g_slist_append(*caps, media_codec); 2256763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 2266763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return TRUE; 2276763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 2286763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 229f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 2300f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg struct avdtp_stream *stream, 231666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_error *err, void *user_data) 2326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 233666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 2340f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg int ret; 235cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 236666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 2376763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Set_Configuration_Cfm"); 238666938b54d631956826343ed278e2af4b982fc29Johan Hedberg else 239c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg debug("SBC Source: Set_Configuration_Cfm"); 240cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 2410f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg if (err) { 2420f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg if (setup) 2430f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg finalize_stream_setup(setup); 2440f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg return; 2450f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg } 2460f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg 2477a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep); 248c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg a2dp_sep->stream = stream; 249cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 250cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (!setup) 251cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return; 252cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 2530f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg ret = avdtp_open(session, stream); 2540f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg if (ret < 0) { 2550f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg error("Error on avdtp_open %s (%d)", strerror(-ret), 2560f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg -ret); 2577a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg setup->stream = NULL; 258cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg finalize_stream_setup(setup); 259cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 2606763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 2616763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 262f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean getconf_ind(struct avdtp *session, struct avdtp_local_sep *sep, 263666938b54d631956826343ed278e2af4b982fc29Johan Hedberg uint8_t *err, void *user_data) 2646763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 265666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 266666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 267666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 2686763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Get_Configuration_Ind"); 2696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else 2706763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Source: Get_Configuration_Ind"); 2716763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return TRUE; 2726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 2736763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 274f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void getconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 275666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_stream *stream, struct avdtp_error *err, 276666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data) 2776763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 278666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 279666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 280666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 2816763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Set_Configuration_Cfm"); 2826763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else 2836763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Source: Set_Configuration_Cfm"); 2846763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 2856763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 286f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean open_ind(struct avdtp *session, struct avdtp_local_sep *sep, 287666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_stream *stream, uint8_t *err, 288666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data) 2896763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 290666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 291666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 292666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 2936763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Open_Ind"); 2946763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else 2956763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Source: Open_Ind"); 2966763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return TRUE; 2976763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 2986763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 299f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void open_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 300666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_stream *stream, struct avdtp_error *err, 301666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data) 3026763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 303666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 304666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 305666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 3066763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Open_Cfm"); 3076763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else 3086763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Source: Open_Cfm"); 3091addff77624b54445c9b81779ddc78892a126a45Johan Hedberg 310cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (!setup) 3111addff77624b54445c9b81779ddc78892a126a45Johan Hedberg return; 3121addff77624b54445c9b81779ddc78892a126a45Johan Hedberg 313cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (setup->canceled) { 3140f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg if (!err) 3150f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg avdtp_close(session, stream); 316cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg stream_setup_free(setup); 317cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return; 318cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 319cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 3200f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg if (err) { 3210f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg setup->stream = NULL; 3220f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg goto finalize; 3230f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg } 3240f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg 325cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (setup->start) { 326cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (avdtp_start(session, stream) == 0) 327cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return; 3281addff77624b54445c9b81779ddc78892a126a45Johan Hedberg 329cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg error("avdtp_start failed"); 330cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg setup->stream = NULL; 331cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 332cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 3330f458da19471c933a4105cc450c48548b72edc8eJohan Hedbergfinalize: 334cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg finalize_stream_setup(setup); 3356763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 3366763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 337c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedbergstatic gboolean suspend_timeout(struct a2dp_sep *sep) 338c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg{ 339c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg if (avdtp_suspend(sep->session, sep->stream) == 0) 340c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg sep->suspending = TRUE; 341c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg 3427a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg sep->suspend_timer = 0; 343c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg 344c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg avdtp_unref(sep->session); 345c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg sep->session = NULL; 346c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg 347c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg return FALSE; 348c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg} 349c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg 350f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean start_ind(struct avdtp *session, struct avdtp_local_sep *sep, 351666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_stream *stream, uint8_t *err, 352666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data) 3536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 354666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 355c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg 356666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 3576763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Start_Ind"); 358666938b54d631956826343ed278e2af4b982fc29Johan Hedberg else 3596763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Source: Start_Ind"); 3605b5cfaadb312600c58362617080e29fbf036712cJohan Hedberg 361c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg a2dp_sep->session = avdtp_ref(session); 362c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg 363c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg a2dp_sep->suspend_timer = g_timeout_add(SUSPEND_TIMEOUT, 364c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg (GSourceFunc) suspend_timeout, 365c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg a2dp_sep); 366c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg return TRUE; 3676763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 3686763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 369f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void start_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 370666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_stream *stream, struct avdtp_error *err, 371666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data) 3726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 373666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 374666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 375666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 3766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Start_Cfm"); 3776763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else 3786763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Source: Start_Cfm"); 379cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 380cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (!setup) 381cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return; 382cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 383cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (setup->canceled) { 3840f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg if (!err) 3850f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg avdtp_close(session, stream); 386cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg stream_setup_free(setup); 387cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return; 388cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 389cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 3900f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg if (err) 3910f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg setup->stream = NULL; 3920f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg 393cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg finalize_stream_setup(setup); 3946763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 3956763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 396f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean suspend_ind(struct avdtp *session, struct avdtp_local_sep *sep, 397666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_stream *stream, uint8_t *err, 398666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data) 3996763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 400666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 401666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 402666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 4036763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Suspend_Ind"); 4046763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else 4056763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Source: Suspend_Ind"); 4066763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return TRUE; 4076763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 4086763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 409f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void suspend_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 410666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_stream *stream, struct avdtp_error *err, 411666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data) 4126763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 413666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 414c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg 415666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 4166763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Suspend_Cfm"); 417666938b54d631956826343ed278e2af4b982fc29Johan Hedberg else 418c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg debug("SBC Source: Suspend_Cfm"); 419cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 420c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg a2dp_sep->suspending = FALSE; 421cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 4220f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg if (err) { 423c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg a2dp_sep->start_requested = FALSE; 4240f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg if (setup) 4250f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg finalize_stream_setup(setup); 4260f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg return; 4270f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg } 4280f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg 429c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg if (a2dp_sep->start_requested) { 430cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg avdtp_start(session, stream); 431c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg a2dp_sep->start_requested = FALSE; 432cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 4336763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 4346763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 435f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean close_ind(struct avdtp *session, struct avdtp_local_sep *sep, 436666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_stream *stream, uint8_t *err, 437666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data) 4386763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 439666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 440c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg 441666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 4426763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Close_Ind"); 443666938b54d631956826343ed278e2af4b982fc29Johan Hedberg else 444c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg debug("SBC Source: Close_Ind"); 445cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 4466763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return TRUE; 4476763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 4486763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 449f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void close_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 450666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_stream *stream, struct avdtp_error *err, 451666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data) 4526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 453666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 454c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg 455666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 4566763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Close_Cfm"); 457666938b54d631956826343ed278e2af4b982fc29Johan Hedberg else 458c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg debug("SBC Source: Close_Cfm"); 4596763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 4606763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 461f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean abort_ind(struct avdtp *session, struct avdtp_local_sep *sep, 462666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_stream *stream, uint8_t *err, 463666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data) 4646763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 465666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 466c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg 467666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 4686763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Abort_Ind"); 469666938b54d631956826343ed278e2af4b982fc29Johan Hedberg else 470c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg debug("SBC Source: Abort_Ind"); 471cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 4726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return TRUE; 4736763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 4746763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 475f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic void abort_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 476666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_stream *stream, struct avdtp_error *err, 477666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data) 4786763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 479666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 480c0e0aa5745b38505b180ffdd7d5df44612597e75Johan Hedberg 481666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 4826763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: Abort_Cfm"); 483666938b54d631956826343ed278e2af4b982fc29Johan Hedberg else 4846763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Source: Abort_Cfm"); 4856763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 4866763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 487f9d8837abad3b67b70425157ac854deb892b2b91Johan Hedbergstatic gboolean reconf_ind(struct avdtp *session, struct avdtp_local_sep *sep, 488666938b54d631956826343ed278e2af4b982fc29Johan Hedberg uint8_t *err, void *user_data) 4896763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 490666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 491666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 492666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 4936763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: ReConfigure_Ind"); 4946763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else 4956763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Source: ReConfigure_Ind"); 4966763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return TRUE; 4976763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 4986763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 4990f458da19471c933a4105cc450c48548b72edc8eJohan Hedbergstatic void reconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep, 500666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct avdtp_stream *stream, struct avdtp_error *err, 501666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data) 5026763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 503666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *a2dp_sep = user_data; 504666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 505666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK) 5066763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Sink: ReConfigure_Cfm"); 5076763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else 5086763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg debug("SBC Source: ReConfigure_Cfm"); 5096763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 5106763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 5116763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic struct avdtp_sep_cfm cfm = { 5126763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .set_configuration = setconf_cfm, 5136763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .get_configuration = getconf_cfm, 5146763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .open = open_cfm, 5156763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .start = start_cfm, 5166763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .suspend = suspend_cfm, 5176763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .close = close_cfm, 5186763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .abort = abort_cfm, 5196763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .reconfigure = reconf_cfm 5206763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}; 5216763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 5226763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic struct avdtp_sep_ind ind = { 5236763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .get_capability = getcap_ind, 5246763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .set_configuration = setconf_ind, 5256763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .get_configuration = getconf_ind, 5266763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .open = open_ind, 5276763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .start = start_ind, 5286763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .suspend = suspend_ind, 5296763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .close = close_ind, 5306763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .abort = abort_ind, 5316763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg .reconfigure = reconf_ind 5326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg}; 5336763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 5346763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic int a2dp_source_record(sdp_buf_t *buf) 5356763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 5366763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_list_t *svclass_id, *pfseq, *apseq, *root; 5376763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg uuid_t root_uuid, l2cap, avdtp, a2src; 5386763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_profile_desc_t profile[1]; 5396763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_list_t *aproto, *proto[2]; 5406763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_record_t record; 5416763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_data_t *psm, *version, *features; 5426763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg uint16_t lp = AVDTP_UUID, ver = 0x0100, feat = 0x000F; 5436763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg int ret = 0; 5446763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 5456763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg memset(&record, 0, sizeof(sdp_record_t)); 5466763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 5476763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_uuid16_create(&root_uuid, PUBLIC_BROWSE_GROUP); 5486763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg root = sdp_list_append(0, &root_uuid); 5496763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_set_browse_groups(&record, root); 5506763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 5516763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_uuid16_create(&a2src, AUDIO_SOURCE_SVCLASS_ID); 5526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg svclass_id = sdp_list_append(0, &a2src); 5536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_set_service_classes(&record, svclass_id); 5546763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 5556763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_uuid16_create(&profile[0].uuid, ADVANCED_AUDIO_PROFILE_ID); 5566763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg profile[0].version = 0x0100; 5576763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg pfseq = sdp_list_append(0, &profile[0]); 5586763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_set_profile_descs(&record, pfseq); 5596763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 5606763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_uuid16_create(&l2cap, L2CAP_UUID); 5616763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg proto[0] = sdp_list_append(0, &l2cap); 5626763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg psm = sdp_data_alloc(SDP_UINT16, &lp); 5636763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg proto[0] = sdp_list_append(proto[0], psm); 5646763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg apseq = sdp_list_append(0, proto[0]); 5656763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 5666763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_uuid16_create(&avdtp, AVDTP_UUID); 5676763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg proto[1] = sdp_list_append(0, &avdtp); 5686763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg version = sdp_data_alloc(SDP_UINT16, &ver); 5696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg proto[1] = sdp_list_append(proto[1], version); 5706763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg apseq = sdp_list_append(apseq, proto[1]); 5716763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 5726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg aproto = sdp_list_append(0, apseq); 5736763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_set_access_protos(&record, aproto); 5746763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 5756763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg features = sdp_data_alloc(SDP_UINT16, &feat); 5766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_attr_add(&record, SDP_ATTR_SUPPORTED_FEATURES, features); 5776763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 5786763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_set_info_attr(&record, "Audio Source", 0, 0); 5796763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 5806763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg if (sdp_gen_record_pdu(&record, buf) < 0) 5816763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg ret = -1; 5826763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else 5836763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg ret = 0; 5846763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 5856763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg free(psm); 5866763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg free(version); 5876763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_list_free(proto[0], 0); 5886763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_list_free(proto[1], 0); 5896763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_list_free(apseq, 0); 5906763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_list_free(pfseq, 0); 5916763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_list_free(aproto, 0); 5926763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_list_free(root, 0); 5936763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_list_free(svclass_id, 0); 5946763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_list_free(record.attrlist, (sdp_free_func_t) sdp_data_free); 5956763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_list_free(record.pattern, free); 5966763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 5976763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return ret; 5986763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 5996763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 6006763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic int a2dp_sink_record(sdp_buf_t *buf) 6016763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 6026763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return 0; 6036763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 6046763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 605666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic struct a2dp_sep *a2dp_add_sep(DBusConnection *conn, uint8_t type) 6066763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 607666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *sep; 608666938b54d631956826343ed278e2af4b982fc29Johan Hedberg GSList **l; 609666938b54d631956826343ed278e2af4b982fc29Johan Hedberg int (*create_record)(sdp_buf_t *buf); 610666938b54d631956826343ed278e2af4b982fc29Johan Hedberg uint32_t *record_id; 6116763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sdp_buf_t buf; 6126763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 613666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep = g_new0(struct a2dp_sep, 1); 614666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 615666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep->sep = avdtp_register_sep(type, AVDTP_MEDIA_TYPE_AUDIO, 616666938b54d631956826343ed278e2af4b982fc29Johan Hedberg &ind, &cfm, sep); 617666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (sep->sep == NULL) { 618666938b54d631956826343ed278e2af4b982fc29Johan Hedberg g_free(sep); 619666938b54d631956826343ed278e2af4b982fc29Johan Hedberg return NULL; 620666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } 621666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 622666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep->type = type; 623666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 624666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (type == AVDTP_SEP_TYPE_SOURCE) { 625666938b54d631956826343ed278e2af4b982fc29Johan Hedberg l = &sources; 626666938b54d631956826343ed278e2af4b982fc29Johan Hedberg create_record = a2dp_source_record; 627666938b54d631956826343ed278e2af4b982fc29Johan Hedberg record_id = &source_record_id; 628666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } else { 629666938b54d631956826343ed278e2af4b982fc29Johan Hedberg l = &sinks; 630666938b54d631956826343ed278e2af4b982fc29Johan Hedberg create_record = a2dp_sink_record; 631666938b54d631956826343ed278e2af4b982fc29Johan Hedberg record_id = &sink_record_id; 632666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } 633666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 634666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (*record_id != 0) 635666938b54d631956826343ed278e2af4b982fc29Johan Hedberg goto add; 636666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 637666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (create_record(&buf) < 0) { 638666938b54d631956826343ed278e2af4b982fc29Johan Hedberg error("Unable to allocate new service record"); 639666938b54d631956826343ed278e2af4b982fc29Johan Hedberg avdtp_unregister_sep(sep->sep); 640666938b54d631956826343ed278e2af4b982fc29Johan Hedberg g_free(sep); 641666938b54d631956826343ed278e2af4b982fc29Johan Hedberg return NULL; 642666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } 643666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 644666938b54d631956826343ed278e2af4b982fc29Johan Hedberg *record_id = add_service_record(conn, &buf); 645666938b54d631956826343ed278e2af4b982fc29Johan Hedberg free(buf.data); 646666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (!*record_id) { 647666938b54d631956826343ed278e2af4b982fc29Johan Hedberg error("Unable to register A2DP service record"); 648666938b54d631956826343ed278e2af4b982fc29Johan Hedberg avdtp_unregister_sep(sep->sep); 649666938b54d631956826343ed278e2af4b982fc29Johan Hedberg g_free(sep); 650666938b54d631956826343ed278e2af4b982fc29Johan Hedberg return NULL; 651666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } 652666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 653666938b54d631956826343ed278e2af4b982fc29Johan Hedbergadd: 654666938b54d631956826343ed278e2af4b982fc29Johan Hedberg *l = g_slist_append(*l, sep); 655666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 656666938b54d631956826343ed278e2af4b982fc29Johan Hedberg return sep; 657666938b54d631956826343ed278e2af4b982fc29Johan Hedberg} 658666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 659666938b54d631956826343ed278e2af4b982fc29Johan Hedbergint a2dp_init(DBusConnection *conn, gboolean enable_sink, gboolean enable_source) 660666938b54d631956826343ed278e2af4b982fc29Johan Hedberg{ 6616763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg if (!enable_sink && !enable_source) 6626763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return 0; 6636763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 6646763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg connection = dbus_connection_ref(conn); 6656763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 6666763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg avdtp_init(); 6676763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 6686763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg if (enable_sink) { 669666938b54d631956826343ed278e2af4b982fc29Johan Hedberg a2dp_add_sep(conn, AVDTP_SEP_TYPE_SOURCE); 670666938b54d631956826343ed278e2af4b982fc29Johan Hedberg a2dp_add_sep(conn, AVDTP_SEP_TYPE_SOURCE); 6716763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg } 6726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 673666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (enable_source) 674666938b54d631956826343ed278e2af4b982fc29Johan Hedberg a2dp_add_sep(conn, AVDTP_SEP_TYPE_SINK); 6756763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 6766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return 0; 6776763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 6786763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 679666938b54d631956826343ed278e2af4b982fc29Johan Hedbergstatic void a2dp_unregister_sep(struct a2dp_sep *sep) 680666938b54d631956826343ed278e2af4b982fc29Johan Hedberg{ 681666938b54d631956826343ed278e2af4b982fc29Johan Hedberg avdtp_unregister_sep(sep->sep); 682666938b54d631956826343ed278e2af4b982fc29Johan Hedberg g_free(sep); 683666938b54d631956826343ed278e2af4b982fc29Johan Hedberg} 684666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 6856763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergvoid a2dp_exit() 6866763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 687666938b54d631956826343ed278e2af4b982fc29Johan Hedberg g_slist_foreach(sinks, (GFunc) a2dp_unregister_sep, NULL); 688666938b54d631956826343ed278e2af4b982fc29Johan Hedberg g_slist_free(sinks); 689666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sinks = NULL; 6906763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 691666938b54d631956826343ed278e2af4b982fc29Johan Hedberg g_slist_foreach(sources, (GFunc) a2dp_unregister_sep, NULL); 692666938b54d631956826343ed278e2af4b982fc29Johan Hedberg g_slist_free(sources); 693666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sources = NULL; 6946763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 695666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (source_record_id) { 696666938b54d631956826343ed278e2af4b982fc29Johan Hedberg remove_service_record(connection, source_record_id); 697666938b54d631956826343ed278e2af4b982fc29Johan Hedberg source_record_id = 0; 6986763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg } 6996763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 700666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (sink_record_id) { 701666938b54d631956826343ed278e2af4b982fc29Johan Hedberg remove_service_record(connection, sink_record_id); 702666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sink_record_id = 0; 7036763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg } 7046763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 7056763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg dbus_connection_unref(connection); 7066763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 7076763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 7086763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic uint8_t default_bitpool(uint8_t freq, uint8_t mode) { 7096763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg switch (freq) { 7106763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg case A2DP_SAMPLING_FREQ_16000: 7116763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg case A2DP_SAMPLING_FREQ_32000: 7126763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return 53; 7136763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg case A2DP_SAMPLING_FREQ_44100: 7146763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg switch (mode) { 7156763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg case A2DP_CHANNEL_MODE_MONO: 7166763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg case A2DP_CHANNEL_MODE_DUAL_CHANNEL: 7176763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return 31; 7186763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg case A2DP_CHANNEL_MODE_STEREO: 7196763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg case A2DP_CHANNEL_MODE_JOINT_STEREO: 7206763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return 53; 7216763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg default: 7226763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg error("Invalid channel mode %u", mode); 7236763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return 53; 7246763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg } 7256763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg case A2DP_SAMPLING_FREQ_48000: 7266763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg switch (mode) { 7276763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg case A2DP_CHANNEL_MODE_MONO: 7286763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg case A2DP_CHANNEL_MODE_DUAL_CHANNEL: 7296763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return 29; 7306763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg case A2DP_CHANNEL_MODE_STEREO: 7316763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg case A2DP_CHANNEL_MODE_JOINT_STEREO: 7326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return 51; 7336763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg default: 7346763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg error("Invalid channel mode %u", mode); 7356763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return 51; 7366763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg } 7376763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg default: 7386763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg error("Invalid sampling freq %u", freq); 7396763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return 53; 7406763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg } 7416763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 7426763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 7436763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedbergstatic gboolean select_sbc_params(struct sbc_codec_cap *cap, 7446763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg struct sbc_codec_cap *supported) 7456763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 7466763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg uint max_bitpool, min_bitpool; 7476763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 7486763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg memset(cap, 0, sizeof(struct sbc_codec_cap)); 7496763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 7506763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg cap->cap.media_type = AVDTP_MEDIA_TYPE_AUDIO; 7516763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg cap->cap.media_codec_type = A2DP_CODEC_SBC; 7526763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 7536763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg if (supported->frequency & A2DP_SAMPLING_FREQ_48000) 7546763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg cap->frequency = A2DP_SAMPLING_FREQ_48000; 7556763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else if (supported->frequency & A2DP_SAMPLING_FREQ_44100) 7566763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg cap->frequency = A2DP_SAMPLING_FREQ_44100; 7576763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else if (supported->frequency & A2DP_SAMPLING_FREQ_32000) 7586763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg cap->frequency = A2DP_SAMPLING_FREQ_32000; 7596763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else if (supported->frequency & A2DP_SAMPLING_FREQ_16000) 7606763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg cap->frequency = A2DP_SAMPLING_FREQ_16000; 7616763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else { 7626763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg error("No supported frequencies"); 7636763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return FALSE; 7646763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg } 7656763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 7666763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg if (supported->channel_mode & A2DP_CHANNEL_MODE_JOINT_STEREO) 7676763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg cap->channel_mode = A2DP_CHANNEL_MODE_JOINT_STEREO; 7686763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else if (supported->channel_mode & A2DP_CHANNEL_MODE_STEREO) 7696763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg cap->channel_mode = A2DP_CHANNEL_MODE_STEREO; 7706763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else if (supported->channel_mode & A2DP_CHANNEL_MODE_DUAL_CHANNEL) 7716763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg cap->channel_mode = A2DP_CHANNEL_MODE_DUAL_CHANNEL; 7726763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else if (supported->channel_mode & A2DP_CHANNEL_MODE_MONO) 7736763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg cap->channel_mode = A2DP_CHANNEL_MODE_MONO; 7746763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else { 7756763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg error("No supported channel modes"); 7766763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return FALSE; 7776763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg } 7786763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 7796763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg if (supported->block_length & A2DP_BLOCK_LENGTH_16) 7806763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg cap->block_length = A2DP_BLOCK_LENGTH_16; 7816763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else if (supported->block_length & A2DP_BLOCK_LENGTH_12) 7826763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg cap->block_length = A2DP_BLOCK_LENGTH_12; 7836763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else if (supported->block_length & A2DP_BLOCK_LENGTH_8) 7846763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg cap->block_length = A2DP_BLOCK_LENGTH_8; 7856763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else if (supported->block_length & A2DP_BLOCK_LENGTH_4) 7866763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg cap->block_length = A2DP_BLOCK_LENGTH_4; 7876763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else { 7886763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg error("No supported block lengths"); 7896763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return FALSE; 7906763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg } 7916763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 7926763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg if (supported->subbands & A2DP_SUBBANDS_8) 7936763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg cap->subbands = A2DP_SUBBANDS_8; 7946763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else if (supported->subbands & A2DP_SUBBANDS_4) 7956763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg cap->subbands = A2DP_SUBBANDS_4; 7966763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else { 7976763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg error("No supported subbands"); 7986763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return FALSE; 7996763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg } 8006763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 8016763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg if (supported->allocation_method & A2DP_ALLOCATION_LOUDNESS) 8026763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg cap->allocation_method = A2DP_ALLOCATION_LOUDNESS; 8036763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg else if (supported->allocation_method & A2DP_ALLOCATION_SNR) 8046763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg cap->allocation_method = A2DP_ALLOCATION_SNR; 8056763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 8068ae40e0b0046a011bbc15771f248d7950a606ae4Johan Hedberg min_bitpool = MAX(2, supported->min_bitpool); 8076763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg max_bitpool = MIN(default_bitpool(cap->frequency, cap->channel_mode), 8086763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg supported->max_bitpool); 8096763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 8106763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg cap->min_bitpool = min_bitpool; 8116763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg cap->max_bitpool = max_bitpool; 8126763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 8136763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return TRUE; 8146763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 8156763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 8165d5f4d99e9176da5f01b7195e6132b5796d026d8Johan Hedbergstatic gboolean a2dp_select_capabilities(struct avdtp_remote_sep *rsep, GSList **caps) 8176763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg{ 8186763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg struct avdtp_service_capability *media_transport, *media_codec; 8196763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg struct sbc_codec_cap sbc_cap, *acp_sbc; 8206763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 8216763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg media_codec = avdtp_get_codec(rsep); 8226763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg if (!media_codec) 8236763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return FALSE; 8246763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 8256763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg acp_sbc = (void *) media_codec->data; 8266763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 8276763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg media_transport = avdtp_service_cap_new(AVDTP_MEDIA_TRANSPORT, 8286763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg NULL, 0); 8296763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 8306763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg *caps = g_slist_append(*caps, media_transport); 8316763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 8326763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg select_sbc_params(&sbc_cap, acp_sbc); 8336763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 8346763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg media_codec = avdtp_service_cap_new(AVDTP_MEDIA_CODEC, &sbc_cap, 8356763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg sizeof(sbc_cap)); 8366763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 8376763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg *caps = g_slist_append(*caps, media_codec); 8386763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 8396763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg return TRUE; 8406763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg} 8416763ebb3c231740c66a235f94d56e8d8cc213d90Johan Hedberg 842cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergstatic void discovery_complete(struct avdtp *session, GSList *seps, int err, 843cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg void *user_data) 8441addff77624b54445c9b81779ddc78892a126a45Johan Hedberg{ 845cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg struct avdtp_local_sep *lsep; 846cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg struct avdtp_remote_sep *rsep; 847cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg GSList *caps = NULL; 848cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 849cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (err < 0) { 850cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg error("Discovery failed: %s (%d)", strerror(-err), -err); 851cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg setup->stream = NULL; 852cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg finalize_stream_setup(setup); 853cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return; 854cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 8551addff77624b54445c9b81779ddc78892a126a45Johan Hedberg 856cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg debug("Discovery complete"); 857cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 858cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (avdtp_get_seps(session, AVDTP_SEP_TYPE_SINK, AVDTP_MEDIA_TYPE_AUDIO, 859cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg A2DP_CODEC_SBC, &lsep, &rsep) < 0) { 860cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg error("No matching ACP and INT SEPs found"); 861cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg finalize_stream_setup(setup); 862cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return; 863cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 864cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 865cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (!a2dp_select_capabilities(rsep, &caps)) { 866cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg error("Unable to select remote SEP capabilities"); 867cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg finalize_stream_setup(setup); 868cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return; 869cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 870cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 871cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg err = avdtp_set_configuration(session, rsep, lsep, caps, 872cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg &setup->stream); 873cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (err < 0) { 874cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg error("avdtp_set_configuration: %s", strerror(-err)); 875cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg finalize_stream_setup(setup); 876cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return; 877cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 878cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 879cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg /* Notify sink.c of the new stream */ 880cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg sink_new_stream(setup->dev, session, setup->stream); 881cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg} 882cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 883cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberggboolean a2dp_source_cancel_stream(int id) 884cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{ 885cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg struct a2dp_stream_cb *cb_data; 886cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg GSList *l; 887cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 888cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (!setup) 889cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return FALSE; 890cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 891cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg for (cb_data = NULL, l = setup->cb; l != NULL; l = g_slist_next(l)) { 892cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg struct a2dp_stream_cb *cb = l->data; 893cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 894cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (cb->id == id) { 895cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg cb_data = cb; 896cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg break; 897cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 898cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 899cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 900cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (!cb_data) 901cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return FALSE; 902cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 903cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg setup->cb = g_slist_remove(setup->cb, cb_data); 9049ce01693dd0aa7407b7d8eb37c8524dd05abe15cJohan Hedberg g_free(cb_data); 905cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 906cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (!setup->cb) 907cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg setup->canceled = TRUE; 908cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 909cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return TRUE; 910cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg} 911cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 9120f458da19471c933a4105cc450c48548b72edc8eJohan Hedbergunsigned int a2dp_source_request_stream(struct avdtp *session, 913666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct device *dev, 914666938b54d631956826343ed278e2af4b982fc29Johan Hedberg gboolean start, 915666938b54d631956826343ed278e2af4b982fc29Johan Hedberg a2dp_stream_cb_t cb, 916666938b54d631956826343ed278e2af4b982fc29Johan Hedberg void *user_data, 917666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep **ret) 918cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{ 919cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg struct a2dp_stream_cb *cb_data; 920cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg static unsigned int cb_id = 0; 921666938b54d631956826343ed278e2af4b982fc29Johan Hedberg GSList *l; 922666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *sep = NULL; 923cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 924666938b54d631956826343ed278e2af4b982fc29Johan Hedberg for (l = sources; l != NULL; l = l->next) { 925666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *tmp = l->data; 926666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 927666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (tmp->locked) 928666938b54d631956826343ed278e2af4b982fc29Johan Hedberg continue; 929666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 930666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (tmp->used_by == NULL || tmp->used_by == dev) { 931666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep = tmp; 932666938b54d631956826343ed278e2af4b982fc29Johan Hedberg break; 933666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } 934666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } 935666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 936666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (!sep) { 937666938b54d631956826343ed278e2af4b982fc29Johan Hedberg error("a2dp_source_request_stream: no available SEP found"); 938730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg return 0; 939730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg } 940730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg 941730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg if (setup && setup->dev != dev) { 942730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg error("a2dp_source_request_stream: stream setup in progress " 943730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg "already for another device"); 944730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg return 0; 945730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg } 946730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg 947666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep->used_by = dev; 948666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 949666938b54d631956826343ed278e2af4b982fc29Johan Hedberg debug("a2dp_source_request_stream: selected SEP %p", sep); 950666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 951cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg cb_data = g_new(struct a2dp_stream_cb, 1); 952cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg cb_data->cb = cb; 953cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg cb_data->user_data = user_data; 9540f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg cb_data->id = ++cb_id; 955cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 956cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (setup) { 957cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg setup->canceled = FALSE; 958cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg setup->cb = g_slist_append(setup->cb, cb_data); 959cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (start) 960cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg setup->start = TRUE; 961cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return cb_data->id; 962cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 963cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 964cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg setup = g_new0(struct a2dp_stream_setup, 1); 965cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg setup->session = avdtp_ref(session); 966cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg setup->dev = dev; 967cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg setup->cb = g_slist_append(setup->cb, cb_data); 968cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg setup->start = start; 969666938b54d631956826343ed278e2af4b982fc29Johan Hedberg setup->stream = sep->stream; 970cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 971666938b54d631956826343ed278e2af4b982fc29Johan Hedberg switch (avdtp_sep_get_state(sep->sep)) { 972cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg case AVDTP_STATE_IDLE: 973730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg if (avdtp_discover(session, discovery_complete, setup) < 0) { 974730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg error("avdtp_discover failed"); 975cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg goto failed; 976730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg } 977cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg break; 978cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg case AVDTP_STATE_OPEN: 979cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (!start) { 980cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg g_idle_add((GSourceFunc) finalize_stream_setup, setup); 981cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg break; 982cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 983666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (sep->starting) 984cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg break; 985666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (avdtp_start(session, sep->stream) < 0) { 986730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg error("avdtp_start failed"); 987cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg goto failed; 988730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg } 989cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg break; 990cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg case AVDTP_STATE_STREAMING: 991666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (!start || !sep->suspending) { 992666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (sep->suspend_timer) { 993666938b54d631956826343ed278e2af4b982fc29Johan Hedberg g_source_remove(sep->suspend_timer); 994666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep->suspend_timer = 0; 99558b173171f61373c7eb8ed00d0635fb06fa741ccJohan Hedberg } 996666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (sep->session) { 997666938b54d631956826343ed278e2af4b982fc29Johan Hedberg avdtp_unref(sep->session); 998666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep->session = NULL; 9997a29d3596b6680c421aa28051ec6baeea1bbfa6bJohan Hedberg } 1000cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg g_idle_add((GSourceFunc) finalize_stream_setup, setup); 1001cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return cb_data->id; 1002cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 1003666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep->start_requested = TRUE; 1004cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg break; 1005cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg default: 1006730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg error("SEP in bad state for requesting a new stream"); 1007cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg goto failed; 1008cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 1009666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 1010666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (ret) 1011666938b54d631956826343ed278e2af4b982fc29Johan Hedberg *ret = sep; 1012cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1013cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return cb_data->id; 1014cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1015cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedbergfailed: 1016cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg stream_setup_free(setup); 1017cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg cb_id--; 10180f458da19471c933a4105cc450c48548b72edc8eJohan Hedberg return 0; 1019cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg} 1020cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1021cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberggboolean a2dp_source_lock(struct device *dev, struct avdtp *session) 1022cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{ 1023666938b54d631956826343ed278e2af4b982fc29Johan Hedberg GSList *l; 1024cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1025666938b54d631956826343ed278e2af4b982fc29Johan Hedberg for (l = sources; l != NULL; l = l->next) { 1026666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *sep = l->data; 1027730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg 1028666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (sep->locked) 1029666938b54d631956826343ed278e2af4b982fc29Johan Hedberg continue; 1030cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1031f4211a3cd3442d54fa7877a6c421bee034d46e8eJohan Hedberg if (sep->used_by != dev) 1032f4211a3cd3442d54fa7877a6c421bee034d46e8eJohan Hedberg continue; 1033f4211a3cd3442d54fa7877a6c421bee034d46e8eJohan Hedberg 1034666938b54d631956826343ed278e2af4b982fc29Johan Hedberg debug("SBC Source SEP %p locked", sep); 1035666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep->locked = TRUE; 1036666938b54d631956826343ed278e2af4b982fc29Johan Hedberg return TRUE; 1037666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } 1038666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 1039666938b54d631956826343ed278e2af4b982fc29Johan Hedberg return FALSE; 1040cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg} 1041cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1042cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberggboolean a2dp_source_unlock(struct device *dev, struct avdtp *session) 1043cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{ 1044cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg avdtp_state_t state; 1045666938b54d631956826343ed278e2af4b982fc29Johan Hedberg GSList *l; 1046666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *sep = NULL; 1047cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1048666938b54d631956826343ed278e2af4b982fc29Johan Hedberg for (l = sources; l != NULL; l = l->next) { 1049666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *tmp = l->data; 1050666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 1051f4211a3cd3442d54fa7877a6c421bee034d46e8eJohan Hedberg if (!tmp->locked) 1052666938b54d631956826343ed278e2af4b982fc29Johan Hedberg continue; 1053666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 1054666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (tmp->sep && tmp->used_by == dev) { 1055666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep = tmp; 1056666938b54d631956826343ed278e2af4b982fc29Johan Hedberg break; 1057666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } 1058666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } 1059cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1060666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (!sep) 1061cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return FALSE; 1062cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1063666938b54d631956826343ed278e2af4b982fc29Johan Hedberg state = avdtp_sep_get_state(sep->sep); 1064cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1065666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep->locked = FALSE; 1066666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep->used_by = NULL; 1067cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1068666938b54d631956826343ed278e2af4b982fc29Johan Hedberg debug("SBC Source SEP %p unlocked", sep); 1069730a4ceb9e7e986e2a327fa7e023c3dd2102a50dJohan Hedberg 1070666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (!sep->stream || state == AVDTP_STATE_IDLE) 1071cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return TRUE; 1072cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1073cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg switch (state) { 1074cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg case AVDTP_STATE_OPEN: 1075cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg /* Set timer here */ 1076cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg break; 1077cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg case AVDTP_STATE_STREAMING: 1078666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (avdtp_suspend(session, sep->stream) == 0) 1079666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep->suspending = TRUE; 1080cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg break; 1081cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg default: 1082cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg break; 1083cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 1084cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1085cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return TRUE; 1086cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg} 1087cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1088cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberggboolean a2dp_source_suspend(struct device *dev, struct avdtp *session) 1089cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{ 1090cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg avdtp_state_t state; 1091666938b54d631956826343ed278e2af4b982fc29Johan Hedberg GSList *l; 1092666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *sep = NULL; 1093cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1094666938b54d631956826343ed278e2af4b982fc29Johan Hedberg for (l = sources; l != NULL; l = l->next) { 1095666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *tmp = l->data; 1096cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1097666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (tmp->sep && tmp->used_by == dev) { 1098666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep = tmp; 1099666938b54d631956826343ed278e2af4b982fc29Johan Hedberg break; 1100666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } 1101666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } 1102666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 1103666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (!sep) 1104cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return FALSE; 1105cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1106666938b54d631956826343ed278e2af4b982fc29Johan Hedberg state = avdtp_sep_get_state(sep->sep); 1107cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1108666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (!sep->stream || state != AVDTP_STATE_STREAMING) 1109cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return TRUE; 1110cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1111666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (avdtp_suspend(session, sep->stream) == 0) { 1112666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep->suspending = TRUE; 1113cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return TRUE; 1114cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 1115cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1116cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return FALSE; 1117cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg} 1118cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1119cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberggboolean a2dp_source_start_stream(struct device *dev, struct avdtp *session) 1120cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg{ 1121cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg avdtp_state_t state; 1122666938b54d631956826343ed278e2af4b982fc29Johan Hedberg GSList *l; 1123666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *sep = NULL; 1124cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1125666938b54d631956826343ed278e2af4b982fc29Johan Hedberg for (l = sources; l != NULL; l = l->next) { 1126666938b54d631956826343ed278e2af4b982fc29Johan Hedberg struct a2dp_sep *tmp = l->data; 1127666938b54d631956826343ed278e2af4b982fc29Johan Hedberg 1128666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (tmp->sep && tmp->used_by == dev) { 1129666938b54d631956826343ed278e2af4b982fc29Johan Hedberg sep = tmp; 1130666938b54d631956826343ed278e2af4b982fc29Johan Hedberg break; 1131666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } 1132666938b54d631956826343ed278e2af4b982fc29Johan Hedberg } 1133cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1134666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (!sep) 1135cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return FALSE; 1136cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1137666938b54d631956826343ed278e2af4b982fc29Johan Hedberg state = avdtp_sep_get_state(sep->sep); 1138cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1139cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (state < AVDTP_STATE_OPEN) { 1140cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg error("a2dp_source_start_stream: no stream open"); 1141cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return FALSE; 1142cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg } 1143cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1144cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg if (state == AVDTP_STATE_STREAMING) 1145cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return TRUE; 1146cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1147666938b54d631956826343ed278e2af4b982fc29Johan Hedberg if (avdtp_start(session, sep->stream) < 0) 1148cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return FALSE; 1149cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg 1150cdd9e2e17ad674e5fc1a5ed19643880ef61d28c7Johan Hedberg return TRUE; 11511addff77624b54445c9b81779ddc78892a126a45Johan Hedberg} 1152