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,  | 
