diff options
author | Andrzej Kaczmarek <andrzej.kaczmarek@tieto.com> | 2014-02-10 11:45:40 +0100 |
---|---|---|
committer | Luiz Augusto von Dentz <luiz.von.dentz@intel.com> | 2014-02-10 13:22:56 +0200 |
commit | 4e50a5f7ff2938870919e8250898237cfe777e5a (patch) | |
tree | d5448d5a93adf5126a6067fe394038c3375e8063 /android/avdtp.c | |
parent | a7032c97ef6c399eacc63bf0e18ac67da2d1356b (diff) | |
download | bluez-4e50a5f7ff2938870919e8250898237cfe777e5a.tar.gz |
android/a2dp: Shutdown AVDTP gracefully
When shutting down AVDTP connection we first abort and wait for stream
to go to idle state before disconnecting signalling channel.
Diffstat (limited to 'android/avdtp.c')
-rw-r--r-- | android/avdtp.c | 21 |
1 files changed, 17 insertions, 4 deletions
diff --git a/android/avdtp.c b/android/avdtp.c index e26d6eccf..2629e6729 100644 --- a/android/avdtp.c +++ b/android/avdtp.c @@ -398,6 +398,8 @@ struct avdtp { struct pending_req *req; GSList *disconnect; + + bool shutdown; }; static GSList *lseps = NULL; @@ -913,6 +915,11 @@ static void avdtp_sep_set_state(struct avdtp *session, session->streams = g_slist_remove(session->streams, stream); stream_free(stream); } + + if (session->io && session->shutdown && session->streams == NULL) { + int sock = g_io_channel_unix_get_fd(session->io); + shutdown(sock, SHUT_RDWR); + } } static void finalize_discovery(struct avdtp *session, int err) @@ -2141,7 +2148,7 @@ gboolean avdtp_remove_disconnect_cb(struct avdtp *session, unsigned int id) void avdtp_shutdown(struct avdtp *session) { GSList *l; - int sock; + bool aborting = false; if (!session->io) return; @@ -2149,12 +2156,18 @@ void avdtp_shutdown(struct avdtp *session) for (l = session->streams; l; l = g_slist_next(l)) { struct avdtp_stream *stream = l->data; - avdtp_close(session, stream, TRUE); + if (stream->abort_int || avdtp_abort(session, stream) == 0) + aborting = true; } - sock = g_io_channel_unix_get_fd(session->io); + if (aborting) { + /* defer shutdown until all streams are aborted properly */ + session->shutdown = true; + } else { + int sock = g_io_channel_unix_get_fd(session->io); - shutdown(sock, SHUT_RDWR); + shutdown(sock, SHUT_RDWR); + } } static void queue_request(struct avdtp *session, struct pending_req *req, |