diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2007-08-20 15:12:33 +0000 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2007-08-20 15:12:33 +0000 |
commit | 7a29d3596b6680c421aa28051ec6baeea1bbfa6b (patch) | |
tree | 6243dcafbe04c1ca02c3bd1c2268aea243c39281 /audio/a2dp.c | |
parent | 8905b2bad9aebd0911d452b53b9cbe975ad5bdcc (diff) |
Improve robustness of A2DP SEP active stream state by using a stream state callback instead of the SEP callbacks
Diffstat (limited to 'audio/a2dp.c')
-rw-r--r-- | audio/a2dp.c | 59 |
1 files changed, 32 insertions, 27 deletions
diff --git a/audio/a2dp.c b/audio/a2dp.c index 0e5f14732..1e22e7c85 100644 --- a/audio/a2dp.c +++ b/audio/a2dp.c @@ -87,21 +87,6 @@ static struct a2dp_sep source = { NULL }; static struct a2dp_stream_setup *setup = NULL; -static void stream_cleanup(struct a2dp_sep *sep) -{ - if (sep->suspend_timer) { - g_source_remove(sep->suspend_timer); - sep->suspend_timer = 0; - } - - if (sep->session) { - avdtp_unref(sep->session); - sep->session = NULL; - } - - sep->stream = NULL; -} - static void stream_setup_free(struct a2dp_stream_setup *s) { if (s->session) @@ -125,6 +110,30 @@ static gboolean finalize_stream_setup(struct a2dp_stream_setup *s) return FALSE; } +static void stream_state_changed(struct avdtp_stream *stream, + avdtp_state_t old_state, + avdtp_state_t new_state, + struct avdtp_error *err, + void *user_data) +{ + struct a2dp_sep *sep = user_data; + + if (new_state != AVDTP_STATE_IDLE) + return; + + if (sep->suspend_timer) { + g_source_remove(sep->suspend_timer); + sep->suspend_timer = 0; + } + + if (sep->session) { + avdtp_unref(sep->session); + sep->session = NULL; + } + + sep->stream = NULL; +} + static gboolean setconf_ind(struct avdtp *session, struct avdtp_local_sep *sep, struct avdtp_stream *stream, @@ -152,6 +161,7 @@ static gboolean setconf_ind(struct avdtp *session, return FALSE; } + avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep); a2dp_sep->stream = stream; if (a2dp_sep == &source) @@ -230,12 +240,12 @@ static void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep, } if (err) { - a2dp_sep->stream = NULL; if (setup) finalize_stream_setup(setup); return; } + avdtp_stream_add_cb(session, stream, stream_state_changed, a2dp_sep); a2dp_sep->stream = stream; if (!setup) @@ -245,7 +255,7 @@ static void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep, if (ret < 0) { error("Error on avdtp_open %s (%d)", strerror(-ret), -ret); - setup->stream = FALSE; + setup->stream = NULL; finalize_stream_setup(setup); } } @@ -319,7 +329,7 @@ static gboolean suspend_timeout(struct a2dp_sep *sep) if (avdtp_suspend(sep->session, sep->stream) == 0) sep->suspending = TRUE; - sep->suspend_timer = FALSE; + sep->suspend_timer = 0; avdtp_unref(sep->session); sep->session = NULL; @@ -346,7 +356,6 @@ static gboolean start_ind(struct avdtp *session, struct avdtp_local_sep *sep, a2dp_sep->suspend_timer = g_timeout_add(SUSPEND_TIMEOUT, (GSourceFunc) suspend_timeout, a2dp_sep); - return TRUE; } @@ -425,8 +434,6 @@ static gboolean close_ind(struct avdtp *session, struct avdtp_local_sep *sep, a2dp_sep = &source; } - stream_cleanup(a2dp_sep); - return TRUE; } @@ -442,8 +449,6 @@ static void close_cfm(struct avdtp *session, struct avdtp_local_sep *sep, debug("SBC Source: Close_Cfm"); a2dp_sep = &source; } - - stream_cleanup(a2dp_sep); } static gboolean abort_ind(struct avdtp *session, struct avdtp_local_sep *sep, @@ -459,8 +464,6 @@ static gboolean abort_ind(struct avdtp *session, struct avdtp_local_sep *sep, a2dp_sep = &source; } - stream_cleanup(a2dp_sep); - return TRUE; } @@ -476,8 +479,6 @@ static void abort_cfm(struct avdtp *session, struct avdtp_local_sep *sep, debug("SBC Source: Abort_Cfm"); a2dp_sep = &source; } - - stream_cleanup(a2dp_sep); } static gboolean reconf_ind(struct avdtp *session, struct avdtp_local_sep *sep, @@ -940,6 +941,10 @@ unsigned int a2dp_source_request_stream(struct avdtp *session, g_source_remove(source.suspend_timer); source.suspend_timer = 0; } + if (source.session) { + avdtp_unref(source.session); + source.session = NULL; + } g_idle_add((GSourceFunc) finalize_stream_setup, setup); return cb_data->id; } |