diff options
author | Johan Hedberg <johan.hedberg@nokia.com> | 2007-10-09 13:36:33 +0000 |
---|---|---|
committer | Johan Hedberg <johan.hedberg@nokia.com> | 2007-10-09 13:36:33 +0000 |
commit | d328981381cec52309a57b991bad0b832b4b9373 (patch) | |
tree | e20e62df02339001bede8c3a2f2c0876b5f9b057 | |
parent | af44f3cafbe4a2a2f2c4bb5879d803f766cf775a (diff) |
Handle cross-connect case for AVDTP
-rw-r--r-- | audio/avdtp.c | 17 | ||||
-rw-r--r-- | audio/avdtp.h | 4 | ||||
-rw-r--r-- | audio/sink.c | 41 |
3 files changed, 56 insertions, 6 deletions
diff --git a/audio/avdtp.c b/audio/avdtp.c index ee1bd06d..0fb64bb0 100644 --- a/audio/avdtp.c +++ b/audio/avdtp.c @@ -499,6 +499,23 @@ void avdtp_error_init(struct avdtp_error *err, uint8_t type, int id) } } +avdtp_error_type_t avdtp_error_type(struct avdtp_error *err) +{ + return err->type; +} + +int avdtp_error_error_code(struct avdtp_error *err) +{ + assert(err->type == AVDTP_ERROR_ERROR_CODE); + return err->err.error_code; +} + +int avdtp_error_posix_errno(struct avdtp_error *err) +{ + assert(err->type == AVDTP_ERROR_ERRNO); + return err->err.posix_errno; +} + static struct avdtp_stream *find_stream_by_rseid(struct avdtp *session, uint8_t rseid) { diff --git a/audio/avdtp.h b/audio/avdtp.h index 6af47e57..a14355b9 100644 --- a/audio/avdtp.h +++ b/audio/avdtp.h @@ -253,7 +253,9 @@ avdtp_state_t avdtp_sep_get_state(struct avdtp_local_sep *sep); void avdtp_error_init(struct avdtp_error *err, uint8_t type, int id); const char *avdtp_strerror(struct avdtp_error *err); -int avdtp_error_code(struct avdtp_error *err); +avdtp_error_type_t avdtp_error_type(struct avdtp_error *err); +int avdtp_error_error_code(struct avdtp_error *err); +int avdtp_error_posix_errno(struct avdtp_error *err); void avdtp_get_peers(struct avdtp *session, bdaddr_t *src, bdaddr_t *dst); diff --git a/audio/sink.c b/audio/sink.c index 18bf7e37..0c5391f3 100644 --- a/audio/sink.c +++ b/audio/sink.c @@ -43,6 +43,8 @@ #include "error.h" #include "sink.h" +#define STREAM_SETUP_RETRY_TIMER 2000 + struct pending_request { DBusConnection *conn; DBusMessage *msg; @@ -133,6 +135,27 @@ static void stream_state_changed(struct avdtp_stream *stream, sink->state = new_state; } +static gboolean stream_setup_retry(gpointer user_data) +{ + struct sink *sink = user_data; + struct pending_request *pending = sink->connect; + + if (sink->state >= AVDTP_STATE_OPEN) { + DBusMessage *reply; + debug("Stream successfully created, after XCASE connect:connect"); + reply = dbus_message_new_method_return(pending->msg); + send_message_and_unref(pending->conn, reply); + } else { + debug("Stream setup failed, after XCASE connect:connect"); + err_failed(pending->conn, pending->msg, "Stream setup failed"); + } + + sink->connect = NULL; + pending_request_free(pending); + + return FALSE; +} + static void stream_setup_complete(struct avdtp *session, struct a2dp_sep *sep, struct avdtp_stream *stream, void *user_data, struct avdtp_error *err) @@ -141,21 +164,29 @@ static void stream_setup_complete(struct avdtp *session, struct a2dp_sep *sep, struct pending_request *pending; pending = sink->connect; - sink->connect = NULL; if (stream) { DBusMessage *reply; + sink->connect = NULL; reply = dbus_message_new_method_return(pending->msg); send_message_and_unref(pending->conn, reply); + pending_request_free(pending); debug("Stream successfully created"); } else { - err_failed(pending->conn, pending->msg, "Stream setup failed"); avdtp_unref(sink->session); sink->session = NULL; - debug("Stream setup failed : %s", avdtp_strerror(err)); + if (avdtp_error_type(err) == AVDTP_ERROR_ERRNO + && avdtp_error_posix_errno(err) != EHOSTDOWN) { + debug("connect:connect XCASE detected"); + g_timeout_add(STREAM_SETUP_RETRY_TIMER, + stream_setup_retry, sink); + } else { + sink->connect = NULL; + err_failed(pending->conn, pending->msg, "Stream setup failed"); + pending_request_free(pending); + debug("Stream setup failed : %s", avdtp_strerror(err)); + } } - - pending_request_free(pending); } static DBusHandlerResult sink_connect(DBusConnection *conn, |