summaryrefslogtreecommitdiffstats
path: root/audio
diff options
context:
space:
mode:
Diffstat (limited to 'audio')
-rw-r--r--audio/avdtp.c24
1 files changed, 24 insertions, 0 deletions
diff --git a/audio/avdtp.c b/audio/avdtp.c
index 1ffabd94..8e2094bf 100644
--- a/audio/avdtp.c
+++ b/audio/avdtp.c
@@ -74,6 +74,7 @@
#define REQ_TIMEOUT 4000
#define DISCONNECT_TIMEOUT 5000
+#define STREAM_TIMEOUT 20000
typedef enum {
AVDTP_SESSION_STATE_DISCONNECTED,
@@ -317,6 +318,7 @@ struct avdtp_stream {
the transport channel */
gboolean open_acp; /* If we are in ACT role for Open */
gboolean close_int; /* If we are in INT role for Close */
+ guint idle_timer;
};
/* Structure describing an AVDTP connection between two devices */
@@ -569,6 +571,17 @@ static void stream_free(struct avdtp_stream *stream)
g_free(stream);
}
+static gboolean stream_timeout(struct avdtp_stream *stream)
+{
+ struct avdtp *session = stream->session;
+
+ avdtp_close(session, stream);
+
+ stream->idle_timer = 0;
+
+ return FALSE;
+}
+
static gboolean transport_cb(GIOChannel *chan, GIOCondition cond,
gpointer data)
{
@@ -660,8 +673,16 @@ static void avdtp_sep_set_state(struct avdtp *session,
case AVDTP_STATE_STREAMING:
case AVDTP_STATE_CLOSING:
case AVDTP_STATE_ABORTING:
+ if (stream->idle_timer) {
+ g_source_remove(stream->idle_timer);
+ stream->idle_timer = 0;
+ }
break;
case AVDTP_STATE_IDLE:
+ if (stream->idle_timer) {
+ g_source_remove(stream->idle_timer);
+ stream->idle_timer = 0;
+ }
session->streams = g_slist_remove(session->streams, stream);
if (session->pending_open == stream)
handle_transport_connect(session, -1, 0);
@@ -1933,6 +1954,9 @@ static gboolean avdtp_suspend_resp(struct avdtp *session,
avdtp_sep_set_state(session, sep, AVDTP_STATE_OPEN);
+ stream->idle_timer = g_timeout_add(STREAM_TIMEOUT,
+ (GSourceFunc) stream_timeout, stream);
+
if (sep->cfm && sep->cfm->suspend)
sep->cfm->suspend(session, sep, stream, NULL, sep->user_data);