summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohan Hedberg <johan.hedberg@nokia.com>2007-08-20 08:50:22 +0000
committerJohan Hedberg <johan.hedberg@nokia.com>2007-08-20 08:50:22 +0000
commit730a4ceb9e7e986e2a327fa7e023c3dd2102a50d (patch)
treea19fc7a8d901abd7b8429673fec69d1d37dd7d56
parent78a94059160d7478624cad315022255f7ebbbe80 (diff)
Improve handling of simultaneous connect attempts to different devices
-rw-r--r--audio/a2dp.c24
-rw-r--r--audio/unix.c14
2 files changed, 29 insertions, 9 deletions
diff --git a/audio/a2dp.c b/audio/a2dp.c
index ebf6b472..0e5f1473 100644
--- a/audio/a2dp.c
+++ b/audio/a2dp.c
@@ -884,6 +884,17 @@ unsigned int a2dp_source_request_stream(struct avdtp *session,
struct a2dp_stream_cb *cb_data;
static unsigned int cb_id = 0;
+ if (source.used_by != NULL && source.used_by != dev) {
+ error("a2dp_source_request_stream: SEP is locked");
+ return 0;
+ }
+
+ if (setup && setup->dev != dev) {
+ error("a2dp_source_request_stream: stream setup in progress "
+ "already for another device");
+ return 0;
+ }
+
cb_data = g_new(struct a2dp_stream_cb, 1);
cb_data->cb = cb;
cb_data->user_data = user_data;
@@ -906,8 +917,10 @@ unsigned int a2dp_source_request_stream(struct avdtp *session,
switch (avdtp_sep_get_state(source.sep)) {
case AVDTP_STATE_IDLE:
- if (avdtp_discover(session, discovery_complete, setup) < 0)
+ if (avdtp_discover(session, discovery_complete, setup) < 0) {
+ error("avdtp_discover failed");
goto failed;
+ }
break;
case AVDTP_STATE_OPEN:
if (!start) {
@@ -916,8 +929,10 @@ unsigned int a2dp_source_request_stream(struct avdtp *session,
}
if (source.starting)
break;
- if (avdtp_start(session, source.stream) < 0)
+ if (avdtp_start(session, source.stream) < 0) {
+ error("avdtp_start failed");
goto failed;
+ }
break;
case AVDTP_STATE_STREAMING:
if (!start || !source.suspending) {
@@ -931,6 +946,7 @@ unsigned int a2dp_source_request_stream(struct avdtp *session,
source.start_requested = TRUE;
break;
default:
+ error("SEP in bad state for requesting a new stream");
goto failed;
}
@@ -947,6 +963,8 @@ gboolean a2dp_source_lock(struct device *dev, struct avdtp *session)
if (source.used_by)
return FALSE;
+ debug("SBC Source locked");
+
source.used_by = dev;
return TRUE;
@@ -966,6 +984,8 @@ gboolean a2dp_source_unlock(struct device *dev, struct avdtp *session)
source.used_by = NULL;
+ debug("SBC Source unlocked");
+
if (!source.stream || state == AVDTP_STATE_IDLE)
return TRUE;
diff --git a/audio/unix.c b/audio/unix.c
index f8832c91..9bf1a9ca 100644
--- a/audio/unix.c
+++ b/audio/unix.c
@@ -198,6 +198,11 @@ static void a2dp_setup_complete(struct avdtp *session, struct device *dev,
if (!stream)
goto failed;
+ if (!a2dp_source_lock(dev, session)) {
+ error("Unable to lock A2DP source SEP");
+ goto failed;
+ }
+
a2dp->stream = stream;
if (!avdtp_stream_get_transport(stream, &fd, &cfg->pkt_len, &caps)) {
@@ -273,8 +278,9 @@ static void a2dp_setup_complete(struct avdtp *session, struct device *dev,
failed:
error("stream setup failed");
+ if (a2dp->stream)
+ a2dp_source_unlock(dev, session);
unix_send_cfg(client->sock, NULL, -1);
- a2dp_source_unlock(dev, session);
avdtp_unref(a2dp->session);
a2dp->session = NULL;
a2dp->stream = NULL;
@@ -307,17 +313,11 @@ proceed:
if (!a2dp->session)
a2dp->session = avdtp_get(&dev->src, &dev->dst);
- if (!a2dp_source_lock(dev, a2dp->session)) {
- error("Unable to lock A2DP source SEP");
- goto failed;
- }
-
id = a2dp_source_request_stream(a2dp->session, dev,
TRUE, a2dp_setup_complete,
client);
if (id == 0) {
error("request_stream failed");
- a2dp_source_unlock(dev, a2dp->session);
goto failed;
}