summaryrefslogtreecommitdiffstats
path: root/audio/a2dp.c
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2007-08-24 12:15:20 +0000
committerJohan Hedberg <johan.hedberg@nokia.com>2007-08-24 12:15:20 +0000
commit666938b54d631956826343ed278e2af4b982fc29 (patch)
tree90828ce9054d431a304bda457ac392cd3798bd9e /audio/a2dp.c
parentc3cd59ae39ebb53e27ddd99ee48f1875bd480c1d (diff)
Support up to two simultaneous streams
Diffstat (limited to 'audio/a2dp.c')
-rw-r--r--audio/a2dp.c435
1 files changed, 262 insertions, 173 deletions
diff --git a/audio/a2dp.c b/audio/a2dp.c
index febc112c..daeda70c 100644
--- a/audio/a2dp.c
+++ b/audio/a2dp.c
@@ -54,12 +54,13 @@
#endif
struct a2dp_sep {
+ uint8_t type;
struct avdtp_local_sep *sep;
struct avdtp *session;
struct avdtp_stream *stream;
struct device *used_by;
- uint32_t record_id;
guint suspend_timer;
+ gboolean locked;
gboolean start_requested;
gboolean suspending;
gboolean starting;
@@ -82,8 +83,11 @@ struct a2dp_stream_setup {
static DBusConnection *connection = NULL;
-static struct a2dp_sep sink = { NULL };
-static struct a2dp_sep source = { NULL };
+static GSList *sinks = NULL;
+static GSList *sources = NULL;
+
+static uint32_t source_record_id = 0;
+static uint32_t sink_record_id = 0;
static struct a2dp_stream_setup *setup = NULL;
@@ -138,19 +142,16 @@ static gboolean setconf_ind(struct avdtp *session,
struct avdtp_local_sep *sep,
struct avdtp_stream *stream,
GSList *caps, uint8_t *err,
- uint8_t *category)
+ uint8_t *category, void *user_data)
{
- struct a2dp_sep *a2dp_sep;
+ struct a2dp_sep *a2dp_sep = user_data;
struct device *dev;
bdaddr_t addr;
- if (sep == sink.sep) {
+ if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
debug("SBC Sink: Set_Configuration_Ind");
- a2dp_sep = &sink;
- } else {
+ else
debug("SBC Source: Set_Configuration_Ind");
- a2dp_sep = &source;
- }
avdtp_get_peers(session, NULL, &addr);
@@ -164,19 +165,20 @@ static gboolean setconf_ind(struct avdtp *session,
avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep);
a2dp_sep->stream = stream;
- if (a2dp_sep == &source)
+ if (a2dp_sep->type == AVDTP_SEP_TYPE_SOURCE)
sink_new_stream(dev, session, stream);
return TRUE;
}
static gboolean getcap_ind(struct avdtp *session, struct avdtp_local_sep *sep,
- GSList **caps, uint8_t *err)
+ GSList **caps, uint8_t *err, void *user_data)
{
+ struct a2dp_sep *a2dp_sep = user_data;
struct avdtp_service_capability *media_transport, *media_codec;
struct sbc_codec_cap sbc_cap;
- if (sep == sink.sep)
+ if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
debug("SBC Sink: Get_Capability_Ind");
else
debug("SBC Source: Get_Capability_Ind");
@@ -226,18 +228,15 @@ static gboolean getcap_ind(struct avdtp *session, struct avdtp_local_sep *sep,
static void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
struct avdtp_stream *stream,
- struct avdtp_error *err)
+ struct avdtp_error *err, void *user_data)
{
- struct a2dp_sep *a2dp_sep;
+ struct a2dp_sep *a2dp_sep = user_data;
int ret;
- if (sep == sink.sep) {
+ if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
debug("SBC Sink: Set_Configuration_Cfm");
- a2dp_sep = &sink;
- } else {
+ else
debug("SBC Source: Set_Configuration_Cfm");
- a2dp_sep = &source;
- }
if (err) {
if (setup)
@@ -261,9 +260,11 @@ static void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
}
static gboolean getconf_ind(struct avdtp *session, struct avdtp_local_sep *sep,
- uint8_t *err)
+ uint8_t *err, void *user_data)
{
- if (sep == sink.sep)
+ struct a2dp_sep *a2dp_sep = user_data;
+
+ if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
debug("SBC Sink: Get_Configuration_Ind");
else
debug("SBC Source: Get_Configuration_Ind");
@@ -271,18 +272,24 @@ static gboolean getconf_ind(struct avdtp *session, struct avdtp_local_sep *sep,
}
static void getconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
- struct avdtp_stream *stream, struct avdtp_error *err)
+ struct avdtp_stream *stream, struct avdtp_error *err,
+ void *user_data)
{
- if (sep == sink.sep)
+ struct a2dp_sep *a2dp_sep = user_data;
+
+ if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
debug("SBC Sink: Set_Configuration_Cfm");
else
debug("SBC Source: Set_Configuration_Cfm");
}
static gboolean open_ind(struct avdtp *session, struct avdtp_local_sep *sep,
- struct avdtp_stream *stream, uint8_t *err)
+ struct avdtp_stream *stream, uint8_t *err,
+ void *user_data)
{
- if (sep == sink.sep)
+ struct a2dp_sep *a2dp_sep = user_data;
+
+ if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
debug("SBC Sink: Open_Ind");
else
debug("SBC Source: Open_Ind");
@@ -290,9 +297,12 @@ static gboolean open_ind(struct avdtp *session, struct avdtp_local_sep *sep,
}
static void open_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
- struct avdtp_stream *stream, struct avdtp_error *err)
+ struct avdtp_stream *stream, struct avdtp_error *err,
+ void *user_data)
{
- if (sep == sink.sep)
+ struct a2dp_sep *a2dp_sep = user_data;
+
+ if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
debug("SBC Sink: Open_Cfm");
else
debug("SBC Source: Open_Cfm");
@@ -338,18 +348,15 @@ static gboolean suspend_timeout(struct a2dp_sep *sep)
}
static gboolean start_ind(struct avdtp *session, struct avdtp_local_sep *sep,
- struct avdtp_stream *stream, uint8_t *err)
+ struct avdtp_stream *stream, uint8_t *err,
+ void *user_data)
{
- struct a2dp_sep *a2dp_sep;
+ struct a2dp_sep *a2dp_sep = user_data;
- if (sep == sink.sep) {
+ if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
debug("SBC Sink: Start_Ind");
- a2dp_sep = &sink;
- }
- else {
+ else
debug("SBC Source: Start_Ind");
- a2dp_sep = &source;
- }
a2dp_sep->session = avdtp_ref(session);
@@ -360,9 +367,12 @@ static gboolean start_ind(struct avdtp *session, struct avdtp_local_sep *sep,
}
static void start_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
- struct avdtp_stream *stream, struct avdtp_error *err)
+ struct avdtp_stream *stream, struct avdtp_error *err,
+ void *user_data)
{
- if (sep == sink.sep)
+ struct a2dp_sep *a2dp_sep = user_data;
+
+ if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
debug("SBC Sink: Start_Cfm");
else
debug("SBC Source: Start_Cfm");
@@ -384,9 +394,12 @@ static void start_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
}
static gboolean suspend_ind(struct avdtp *session, struct avdtp_local_sep *sep,
- struct avdtp_stream *stream, uint8_t *err)
+ struct avdtp_stream *stream, uint8_t *err,
+ void *user_data)
{
- if (sep == sink.sep)
+ struct a2dp_sep *a2dp_sep = user_data;
+
+ if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
debug("SBC Sink: Suspend_Ind");
else
debug("SBC Source: Suspend_Ind");
@@ -394,17 +407,15 @@ static gboolean suspend_ind(struct avdtp *session, struct avdtp_local_sep *sep,
}
static void suspend_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
- struct avdtp_stream *stream, struct avdtp_error *err)
+ struct avdtp_stream *stream, struct avdtp_error *err,
+ void *user_data)
{
- struct a2dp_sep *a2dp_sep;
+ struct a2dp_sep *a2dp_sep = user_data;
- if (sep == sink.sep) {
+ if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
debug("SBC Sink: Suspend_Cfm");
- a2dp_sep = &sink;
- } else {
+ else
debug("SBC Source: Suspend_Cfm");
- a2dp_sep = &source;
- }
a2dp_sep->suspending = FALSE;
@@ -422,69 +433,63 @@ static void suspend_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
}
static gboolean close_ind(struct avdtp *session, struct avdtp_local_sep *sep,
- struct avdtp_stream *stream, uint8_t *err)
+ struct avdtp_stream *stream, uint8_t *err,
+ void *user_data)
{
- struct a2dp_sep *a2dp_sep;
+ struct a2dp_sep *a2dp_sep = user_data;
- if (sep == sink.sep) {
+ if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
debug("SBC Sink: Close_Ind");
- a2dp_sep = &sink;
- } else {
+ else
debug("SBC Source: Close_Ind");
- a2dp_sep = &source;
- }
return TRUE;
}
static void close_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
- struct avdtp_stream *stream, struct avdtp_error *err)
+ struct avdtp_stream *stream, struct avdtp_error *err,
+ void *user_data)
{
- struct a2dp_sep *a2dp_sep;
+ struct a2dp_sep *a2dp_sep = user_data;
- if (sep == sink.sep) {
+ if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
debug("SBC Sink: Close_Cfm");
- a2dp_sep = &sink;
- } else {
+ else
debug("SBC Source: Close_Cfm");
- a2dp_sep = &source;
- }
}
static gboolean abort_ind(struct avdtp *session, struct avdtp_local_sep *sep,
- struct avdtp_stream *stream, uint8_t *err)
+ struct avdtp_stream *stream, uint8_t *err,
+ void *user_data)
{
- struct a2dp_sep *a2dp_sep;
+ struct a2dp_sep *a2dp_sep = user_data;
- if (sep == sink.sep) {
+ if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
debug("SBC Sink: Abort_Ind");
- a2dp_sep = &sink;
- } else {
+ else
debug("SBC Source: Abort_Ind");
- a2dp_sep = &source;
- }
return TRUE;
}
static void abort_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
- struct avdtp_stream *stream, struct avdtp_error *err)
+ struct avdtp_stream *stream, struct avdtp_error *err,
+ void *user_data)
{
- struct a2dp_sep *a2dp_sep;
+ struct a2dp_sep *a2dp_sep = user_data;
- if (sep == sink.sep) {
+ if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
debug("SBC Sink: Abort_Cfm");
- a2dp_sep = &sink;
- } else {
+ else
debug("SBC Source: Abort_Cfm");
- a2dp_sep = &source;
- }
}
static gboolean reconf_ind(struct avdtp *session, struct avdtp_local_sep *sep,
- uint8_t *err)
+ uint8_t *err, void *user_data)
{
- if (sep == sink.sep)
+ struct a2dp_sep *a2dp_sep = user_data;
+
+ if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
debug("SBC Sink: ReConfigure_Ind");
else
debug("SBC Source: ReConfigure_Ind");
@@ -492,9 +497,12 @@ static gboolean reconf_ind(struct avdtp *session, struct avdtp_local_sep *sep,
}
static void reconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,
- struct avdtp_stream *stream, struct avdtp_error *err)
+ struct avdtp_stream *stream, struct avdtp_error *err,
+ void *user_data)
{
- if (sep == sink.sep)
+ struct a2dp_sep *a2dp_sep = user_data;
+
+ if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)
debug("SBC Sink: ReConfigure_Cfm");
else
debug("SBC Source: ReConfigure_Cfm");
@@ -594,10 +602,62 @@ static int a2dp_sink_record(sdp_buf_t *buf)
return 0;
}
-int a2dp_init(DBusConnection *conn, gboolean enable_sink, gboolean enable_source)
+static struct a2dp_sep *a2dp_add_sep(DBusConnection *conn, uint8_t type)
{
+ struct a2dp_sep *sep;
+ GSList **l;
+ int (*create_record)(sdp_buf_t *buf);
+ uint32_t *record_id;
sdp_buf_t buf;
+ sep = g_new0(struct a2dp_sep, 1);
+
+ sep->sep = avdtp_register_sep(type, AVDTP_MEDIA_TYPE_AUDIO,
+ &ind, &cfm, sep);
+ if (sep->sep == NULL) {
+ g_free(sep);
+ return NULL;
+ }
+
+ sep->type = type;
+
+ if (type == AVDTP_SEP_TYPE_SOURCE) {
+ l = &sources;
+ create_record = a2dp_source_record;
+ record_id = &source_record_id;
+ } else {
+ l = &sinks;
+ create_record = a2dp_sink_record;
+ record_id = &sink_record_id;
+ }
+
+ if (*record_id != 0)
+ goto add;
+
+ if (create_record(&buf) < 0) {
+ error("Unable to allocate new service record");
+ avdtp_unregister_sep(sep->sep);
+ g_free(sep);
+ return NULL;
+ }
+
+ *record_id = add_service_record(conn, &buf);
+ free(buf.data);
+ if (!*record_id) {
+ error("Unable to register A2DP service record");
+ avdtp_unregister_sep(sep->sep);
+ g_free(sep);
+ return NULL;
+ }
+
+add:
+ *l = g_slist_append(*l, sep);
+
+ return sep;
+}
+
+int a2dp_init(DBusConnection *conn, gboolean enable_sink, gboolean enable_source)
+{
if (!enable_sink && !enable_source)
return 0;
@@ -606,68 +666,40 @@ int a2dp_init(DBusConnection *conn, gboolean enable_sink, gboolean enable_source
avdtp_init();
if (enable_sink) {
- source.sep = avdtp_register_sep(AVDTP_SEP_TYPE_SOURCE,
- AVDTP_MEDIA_TYPE_AUDIO,
- &ind, &cfm);
- if (source.sep == NULL)
- return -1;
-
- if (a2dp_source_record(&buf) < 0) {
- error("Unable to allocate new service record");
- return -1;
- }
-
- source.record_id = add_service_record(conn, &buf);
- free(buf.data);
- if (!source.record_id) {
- error("Unable to register A2DP Source service record");
- return -1;
- }
+ a2dp_add_sep(conn, AVDTP_SEP_TYPE_SOURCE);
+ a2dp_add_sep(conn, AVDTP_SEP_TYPE_SOURCE);
}
- if (enable_source) {
- sink.sep = avdtp_register_sep(AVDTP_SEP_TYPE_SINK,
- AVDTP_MEDIA_TYPE_AUDIO,
- &ind, &cfm);
- if (sink.sep == NULL)
- return -1;
-
- if (a2dp_sink_record(&buf) < 0) {
- error("Unable to allocate new service record");
- return -1;
- }
-
- sink.record_id = add_service_record(conn, &buf);
- free(buf.data);
- if (!sink.record_id) {
- error("Unable to register A2DP Sink service record");
- return -1;
- }
- }
+ if (enable_source)
+ a2dp_add_sep(conn, AVDTP_SEP_TYPE_SINK);
return 0;
}
+static void a2dp_unregister_sep(struct a2dp_sep *sep)
+{
+ avdtp_unregister_sep(sep->sep);
+ g_free(sep);
+}
+
void a2dp_exit()
{
- if (sink.sep) {
- avdtp_unregister_sep(sink.sep);
- sink.sep = NULL;
- }
+ g_slist_foreach(sinks, (GFunc) a2dp_unregister_sep, NULL);
+ g_slist_free(sinks);
+ sinks = NULL;
- if (source.sep) {
- avdtp_unregister_sep(source.sep);
- source.sep = NULL;
- }
+ g_slist_foreach(sources, (GFunc) a2dp_unregister_sep, NULL);
+ g_slist_free(sources);
+ sources = NULL;
- if (source.record_id) {
- remove_service_record(connection, source.record_id);
- source.record_id = 0;
+ if (source_record_id) {
+ remove_service_record(connection, source_record_id);
+ source_record_id = 0;
}
- if (sink.record_id) {
- remove_service_record(connection, sink.record_id);
- sink.record_id = 0;
+ if (sink_record_id) {
+ remove_service_record(connection, sink_record_id);
+ sink_record_id = 0;
}
dbus_connection_unref(connection);
@@ -878,15 +910,31 @@ gboolean a2dp_source_cancel_stream(int id)
}
unsigned int a2dp_source_request_stream(struct avdtp *session,
- struct device *dev,
- gboolean start, a2dp_stream_cb_t cb,
- void *user_data)
+ struct device *dev,
+ gboolean start,
+ a2dp_stream_cb_t cb,
+ void *user_data,
+ struct a2dp_sep **ret)
{
struct a2dp_stream_cb *cb_data;
static unsigned int cb_id = 0;
+ GSList *l;
+ struct a2dp_sep *sep = NULL;
- if (source.used_by != NULL && source.used_by != dev) {
- error("a2dp_source_request_stream: SEP is locked");
+ for (l = sources; l != NULL; l = l->next) {
+ struct a2dp_sep *tmp = l->data;
+
+ if (tmp->locked)
+ continue;
+
+ if (tmp->used_by == NULL || tmp->used_by == dev) {
+ sep = tmp;
+ break;
+ }
+ }
+
+ if (!sep) {
+ error("a2dp_source_request_stream: no available SEP found");
return 0;
}
@@ -896,6 +944,10 @@ unsigned int a2dp_source_request_stream(struct avdtp *session,
return 0;
}
+ sep->used_by = dev;
+
+ debug("a2dp_source_request_stream: selected SEP %p", sep);
+
cb_data = g_new(struct a2dp_stream_cb, 1);
cb_data->cb = cb;
cb_data->user_data = user_data;
@@ -914,9 +966,9 @@ unsigned int a2dp_source_request_stream(struct avdtp *session,
setup->dev = dev;
setup->cb = g_slist_append(setup->cb, cb_data);
setup->start = start;
- setup->stream = source.stream;
+ setup->stream = sep->stream;
- switch (avdtp_sep_get_state(source.sep)) {
+ switch (avdtp_sep_get_state(sep->sep)) {
case AVDTP_STATE_IDLE:
if (avdtp_discover(session, discovery_complete, setup) < 0) {
error("avdtp_discover failed");
@@ -928,32 +980,35 @@ unsigned int a2dp_source_request_stream(struct avdtp *session,
g_idle_add((GSourceFunc) finalize_stream_setup, setup);
break;
}
- if (source.starting)
+ if (sep->starting)
break;
- if (avdtp_start(session, source.stream) < 0) {
+ if (avdtp_start(session, sep->stream) < 0) {
error("avdtp_start failed");
goto failed;
}
break;
case AVDTP_STATE_STREAMING:
- if (!start || !source.suspending) {
- if (source.suspend_timer) {
- g_source_remove(source.suspend_timer);
- source.suspend_timer = 0;
+ if (!start || !sep->suspending) {
+ if (sep->suspend_timer) {
+ g_source_remove(sep->suspend_timer);
+ sep->suspend_timer = 0;
}
- if (source.session) {
- avdtp_unref(source.session);
- source.session = NULL;
+ if (sep->session) {
+ avdtp_unref(sep->session);
+ sep->session = NULL;
}
g_idle_add((GSourceFunc) finalize_stream_setup, setup);
return cb_data->id;
}
- source.start_requested = TRUE;
+ sep->start_requested = TRUE;
break;
default:
error("SEP in bad state for requesting a new stream");
goto failed;
}
+
+ if (ret)
+ *ret = sep;
return cb_data->id;
@@ -965,33 +1020,51 @@ failed:
gboolean a2dp_source_lock(struct device *dev, struct avdtp *session)
{
- if (source.used_by)
- return FALSE;
+ GSList *l;
- debug("SBC Source locked");
+ for (l = sources; l != NULL; l = l->next) {
+ struct a2dp_sep *sep = l->data;
- source.used_by = dev;
+ if (sep->locked)
+ continue;
- return TRUE;
+ debug("SBC Source SEP %p locked", sep);
+ sep->locked = TRUE;
+ return TRUE;
+ }
+
+ return FALSE;
}
gboolean a2dp_source_unlock(struct device *dev, struct avdtp *session)
{
avdtp_state_t state;
+ GSList *l;
+ struct a2dp_sep *sep = NULL;
- if (!source.sep)
- return FALSE;
+ for (l = sources; l != NULL; l = l->next) {
+ struct a2dp_sep *tmp = l->data;
+
+ if (!sep->locked)
+ continue;
+
+ if (tmp->sep && tmp->used_by == dev) {
+ sep = tmp;
+ break;
+ }
+ }
- if (source.used_by != dev)
+ if (!sep)
return FALSE;
- state = avdtp_sep_get_state(source.sep);
+ state = avdtp_sep_get_state(sep->sep);
- source.used_by = NULL;
+ sep->locked = FALSE;
+ sep->used_by = NULL;
- debug("SBC Source unlocked");
+ debug("SBC Source SEP %p unlocked", sep);
- if (!source.stream || state == AVDTP_STATE_IDLE)
+ if (!sep->stream || state == AVDTP_STATE_IDLE)
return TRUE;
switch (state) {
@@ -999,8 +1072,8 @@ gboolean a2dp_source_unlock(struct device *dev, struct avdtp *session)
/* Set timer here */
break;
case AVDTP_STATE_STREAMING:
- if (avdtp_suspend(session, source.stream) == 0)
- source.suspending = TRUE;
+ if (avdtp_suspend(session, sep->stream) == 0)
+ sep->suspending = TRUE;
break;
default:
break;
@@ -1012,20 +1085,28 @@ gboolean a2dp_source_unlock(struct device *dev, struct avdtp *session)
gboolean a2dp_source_suspend(struct device *dev, struct avdtp *session)
{
avdtp_state_t state;
+ GSList *l;
+ struct a2dp_sep *sep = NULL;
- if (!source.sep)
- return FALSE;
+ for (l = sources; l != NULL; l = l->next) {
+ struct a2dp_sep *tmp = l->data;
- if (source.used_by != dev)
+ if (tmp->sep && tmp->used_by == dev) {
+ sep = tmp;
+ break;
+ }
+ }
+
+ if (!sep)
return FALSE;
- state = avdtp_sep_get_state(source.sep);
+ state = avdtp_sep_get_state(sep->sep);
- if (!source.stream || state != AVDTP_STATE_STREAMING)
+ if (!sep->stream || state != AVDTP_STATE_STREAMING)
return TRUE;
- if (avdtp_suspend(session, source.stream) == 0) {
- source.suspending = TRUE;
+ if (avdtp_suspend(session, sep->stream) == 0) {
+ sep->suspending = TRUE;
return TRUE;
}
@@ -1035,14 +1116,22 @@ gboolean a2dp_source_suspend(struct device *dev, struct avdtp *session)
gboolean a2dp_source_start_stream(struct device *dev, struct avdtp *session)
{
avdtp_state_t state;
+ GSList *l;
+ struct a2dp_sep *sep = NULL;
- if (!source.sep)
- return FALSE;
+ for (l = sources; l != NULL; l = l->next) {
+ struct a2dp_sep *tmp = l->data;
+
+ if (tmp->sep && tmp->used_by == dev) {
+ sep = tmp;
+ break;
+ }
+ }
- if (source.used_by != dev)
+ if (!sep)
return FALSE;
- state = avdtp_sep_get_state(source.sep);
+ state = avdtp_sep_get_state(sep->sep);
if (state < AVDTP_STATE_OPEN) {
error("a2dp_source_start_stream: no stream open");
@@ -1052,7 +1141,7 @@ gboolean a2dp_source_start_stream(struct device *dev, struct avdtp *session)
if (state == AVDTP_STATE_STREAMING)
return TRUE;
- if (avdtp_start(session, source.stream) < 0)
+ if (avdtp_start(session, sep->stream) < 0)
return FALSE;
return TRUE;