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