public inbox for linux-bluetooth@vger.kernel.org
 help / color / mirror / Atom feed
* [PATCH] AVDTP start/stop handling during disconnection
@ 2009-08-27 15:24 Daniel Örstadius
  2009-08-27 17:08 ` Luiz Augusto von Dentz
  0 siblings, 1 reply; 5+ messages in thread
From: Daniel Örstadius @ 2009-08-27 15:24 UTC (permalink / raw)
  To: linux-bluetooth

A suggested patch for rejecting AVDTP CLOSE and START requests when a
CLOSE request has been initiated. The check is done by testing the
close_int flag in the avdtp_stream struct. The flag is reset when
receiving a timeout or rejection from the remote.

Changes in unix.c were made to call avdtp_unref() in case an AVDTP
session was marked by avdtp_ref(), but no SEP was found. This could
happen if START is called on a session being disconnected.

We found that these changes help to improve behavior both in case the
audio streaming application tries to start the stream during a
disconnection procedure, and if avdtp_close() is called twice.

Br,
Daniel Örstadius

------------------------

 audio/avdtp.c |   19 +++++++++++++++++--
 audio/unix.c  |   11 ++++++++++-
 2 files changed, 27 insertions(+), 3 deletions(-)

diff --git a/audio/avdtp.c b/audio/avdtp.c
index 8046dda..839f035 100644
--- a/audio/avdtp.c
+++ b/audio/avdtp.c
@@ -2223,9 +2223,12 @@ static gboolean request_timeout(gpointer user_data)
 		break;
 	case AVDTP_CLOSE:
 		error("Close request timed out");
-		if (lsep && lsep->cfm && lsep->cfm->close)
+		if (lsep && lsep->cfm && lsep->cfm->close) {
 			lsep->cfm->close(session, lsep, stream, &err,
 						lsep->user_data);
+			if (stream)
+				stream->close_int = FALSE;
+		}
 		break;
 	case AVDTP_SET_CONFIGURATION:
 		error("SetConfiguration request timed out");
@@ -2675,9 +2678,11 @@ static gboolean avdtp_parse_rej(struct avdtp *session,
 			return FALSE;
 		error("CLOSE request rejected: %s (%d)",
 				avdtp_strerror(&err), err.err.error_code);
-		if (sep && sep->cfm && sep->cfm->close)
+		if (sep && sep->cfm && sep->cfm->close) {
 			sep->cfm->close(session, sep, stream, &err,
 					sep->user_data);
+			stream->close_int = FALSE;
+		}
 		return TRUE;
 	case AVDTP_ABORT:
 		if (!stream_rej_to_err(buf, size, &err, &acp_seid))
@@ -3138,6 +3143,11 @@ int avdtp_start(struct avdtp *session, struct
avdtp_stream *stream)
 	if (stream->lsep->state != AVDTP_STATE_OPEN)
 		return -EINVAL;

+	if (stream->close_int == TRUE) {
+		error("avdtp_start: rejecting start since close is initiated");
+		return -EINVAL;
+	}
+
 	memset(&req, 0, sizeof(req));
 	req.first_seid.seid = stream->rseid;

@@ -3156,6 +3166,11 @@ int avdtp_close(struct avdtp *session, struct
avdtp_stream *stream)
 	if (stream->lsep->state < AVDTP_STATE_OPEN)
 		return -EINVAL;

+	if (stream->close_int == TRUE) {
+		error("avdtp_close: rejecting close since it is already inititated");
+		return -EINVAL;
+	}
+
 	memset(&req, 0, sizeof(req));
 	req.acp_seid = stream->rseid;

diff --git a/audio/unix.c b/audio/unix.c
index 0829630..61cc369 100644
--- a/audio/unix.c
+++ b/audio/unix.c
@@ -1051,14 +1051,17 @@ static void start_resume(struct audio_device
*dev, struct unix_client *client)
 	struct a2dp_data *a2dp;
 	struct headset_data *hs;
 	unsigned int id;
+	gboolean ref_session = FALSE;

 	switch (client->type) {
 	case TYPE_SINK:
 	case TYPE_SOURCE:
 		a2dp = &client->d.a2dp;

-		if (!a2dp->session)
+		if (!a2dp->session) {
 			a2dp->session = avdtp_get(&dev->src, &dev->dst);
+			ref_session = TRUE;
+		}			

 		if (!a2dp->session) {
 			error("Unable to get a session");
@@ -1067,6 +1070,12 @@ static void start_resume(struct audio_device
*dev, struct unix_client *client)

 		if (!a2dp->sep) {
 			error("seid not opened");
+
+			if (ref_session) {
+				avdtp_unref(a2dp->session);
+				a2dp->session = NULL;
+			}
+
 			goto failed;
 		}

^ permalink raw reply related	[flat|nested] 5+ messages in thread

end of thread, other threads:[~2009-09-02 10:06 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2009-08-27 15:24 [PATCH] AVDTP start/stop handling during disconnection Daniel Örstadius
2009-08-27 17:08 ` Luiz Augusto von Dentz
2009-09-01  7:02   ` Johan Hedberg
2009-09-01 11:09     ` Daniel Örstadius
2009-09-02 10:06       ` Johan Hedberg

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox