diff options
| author | Johan Hedberg <johan.hedberg@nokia.com> | 2007-09-28 13:46:55 +0000 | 
|---|---|---|
| committer | Johan Hedberg <johan.hedberg@nokia.com> | 2007-09-28 13:46:55 +0000 | 
| commit | 847dad179fe16ec395373e4b55d46dcd400c623a (patch) | |
| tree | 139f0bdc92e1d7ea3be3f787ace5a7064f8e29b3 | |
| parent | 11275793e04e21cb7e26d6a7d289f98005a3c478 (diff) | |
Expose stream setup errors higher up in the call stack
| -rw-r--r-- | audio/a2dp.c | 102 | ||||
| -rw-r--r-- | audio/a2dp.h | 3 | ||||
| -rw-r--r-- | audio/avdtp.c | 22 | ||||
| -rw-r--r-- | audio/avdtp.h | 17 | ||||
| -rw-r--r-- | audio/sink.c | 4 | 
5 files changed, 91 insertions, 57 deletions
| diff --git a/audio/a2dp.c b/audio/a2dp.c index 5dd85a5e..cb43dce2 100644 --- a/audio/a2dp.c +++ b/audio/a2dp.c @@ -26,6 +26,7 @@  #endif  #include <stdlib.h> +#include <errno.h>  #include <dbus/dbus.h>  #include <glib.h> @@ -112,19 +113,29 @@ static struct device *a2dp_get_dev(struct avdtp *session)  	return manager_device_connected(&addr, A2DP_SOURCE_UUID);  } -static void setup_callback(struct a2dp_stream_cb *cb, -				struct a2dp_stream_setup *s) +static gboolean finalize_stream_setup(struct a2dp_stream_setup *s, struct avdtp_error *err)  { -	cb->cb(s->session, s->sep, s->stream, cb->user_data); -} +	GSList *l; + +	for (l = s->cb; l != NULL; l = l->next) { +		struct a2dp_stream_cb *cb = l->data; +		 +		cb->cb(s->session, s->sep, s->stream, cb->user_data, err); +	} -static gboolean finalize_stream_setup(struct a2dp_stream_setup *s) -{ -	g_slist_foreach(s->cb, (GFunc) setup_callback, s);  	stream_setup_free(s);  	return FALSE;  } +static gboolean finalize_stream_setup_errno(struct a2dp_stream_setup *s, int err) +{ +	struct avdtp_error avdtp_err; + +	avdtp_error_init(&avdtp_err, AVDTP_ERROR_ERRNO, -err); + +	return finalize_stream_setup(s, err ? &avdtp_err : NULL); +} +  static struct a2dp_stream_setup *find_setup_by_session(struct avdtp *session)  {  	GSList *l; @@ -324,22 +335,23 @@ static gboolean a2dp_select_capabilities(struct avdtp *session,  	return TRUE;  } -static void discovery_complete(struct avdtp *session, GSList *seps, int err, +static void discovery_complete(struct avdtp *session, GSList *seps, struct avdtp_error *err,  				void *user_data)  {  	struct avdtp_local_sep *lsep;  	struct avdtp_remote_sep *rsep;  	struct a2dp_stream_setup *setup;  	GSList *caps = NULL; +	int posix_err;  	setup = find_setup_by_session(session);  	if (!setup)  		return; -	if (err < 0 || setup->canceled) { +	if (err || setup->canceled) {  		setup->stream = NULL; -		finalize_stream_setup(setup); +		finalize_stream_setup(setup, err);  		return;  	} @@ -348,21 +360,21 @@ static void discovery_complete(struct avdtp *session, GSList *seps, int err,  	if (avdtp_get_seps(session, AVDTP_SEP_TYPE_SINK, AVDTP_MEDIA_TYPE_AUDIO,  				A2DP_CODEC_SBC, &lsep, &rsep) < 0) {  		error("No matching ACP and INT SEPs found"); -		finalize_stream_setup(setup); +		finalize_stream_setup_errno(setup, -EINVAL);  		return;  	}  	if (!a2dp_select_capabilities(session, rsep, &caps)) {  		error("Unable to select remote SEP capabilities"); -		finalize_stream_setup(setup); +		finalize_stream_setup_errno(setup, -EINVAL);  		return;  	} -	err = avdtp_set_configuration(session, rsep, lsep, caps, +	posix_err = avdtp_set_configuration(session, rsep, lsep, caps,  							&setup->stream); -	if (err < 0) { -		error("avdtp_set_configuration: %s", strerror(-err)); -		finalize_stream_setup(setup); +	if (posix_err < 0) { +		error("avdtp_set_configuration: %s", strerror(-posix_err)); +		finalize_stream_setup_errno(setup, posix_err);  	}  } @@ -490,7 +502,7 @@ static void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,  	if (err) {  		if (setup) -			finalize_stream_setup(setup); +			finalize_stream_setup(setup, err);  		return;  	} @@ -510,7 +522,7 @@ static void setconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,  		error("Error on avdtp_open %s (%d)", strerror(-ret),  				-ret);  		setup->stream = NULL; -		finalize_stream_setup(setup); +		finalize_stream_setup_errno(setup, ret);  	}  } @@ -557,6 +569,7 @@ static void open_cfm(struct avdtp *session, struct avdtp_local_sep *sep,  {  	struct a2dp_sep *a2dp_sep = user_data;  	struct a2dp_stream_setup *setup; +	int posix_err;  	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)  		debug("SBC Sink: Open_Cfm"); @@ -576,19 +589,22 @@ static void open_cfm(struct avdtp *session, struct avdtp_local_sep *sep,  	if (err) {  		setup->stream = NULL; -		goto finalize; +		finalize_stream_setup(setup, err); +		return;  	}  	if (setup->start) { -		if (avdtp_start(session, stream) == 0) +		posix_err = avdtp_start(session, stream);		 +		if (posix_err == 0)  			return;  		error("avdtp_start failed"); -		setup->stream = NULL; +		setup->stream = NULL;		  	} +	else +		posix_err = 0; -finalize: -	finalize_stream_setup(setup); +	finalize_stream_setup_errno(setup, -posix_err);  }  static gboolean suspend_timeout(struct a2dp_sep *sep) @@ -646,10 +662,12 @@ static void start_cfm(struct avdtp *session, struct avdtp_local_sep *sep,  		return;  	} -	if (err) +	if (err) {  		setup->stream = NULL; - -	finalize_stream_setup(setup); +		finalize_stream_setup(setup, err); +	} +	else +		finalize_stream_setup_errno(setup, 0);  }  static gboolean suspend_ind(struct avdtp *session, struct avdtp_local_sep *sep, @@ -671,6 +689,7 @@ static void suspend_cfm(struct avdtp *session, struct avdtp_local_sep *sep,  {  	struct a2dp_sep *a2dp_sep = user_data;  	struct a2dp_stream_setup *setup; +	int posix_err;  	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)  		debug("SBC Sink: Suspend_Cfm"); @@ -684,13 +703,14 @@ static void suspend_cfm(struct avdtp *session, struct avdtp_local_sep *sep,  		return;  	if (err) { -		finalize_stream_setup(setup); +		finalize_stream_setup(setup, err);  		return;  	}  	if (setup->start) { -		if (avdtp_start(session, stream) < 0) -			finalize_stream_setup(setup); +		posix_err = avdtp_start(session, stream); +		if (posix_err < 0) +			finalize_stream_setup_errno(setup, posix_err);  	}  } @@ -714,6 +734,7 @@ static void close_cfm(struct avdtp *session, struct avdtp_local_sep *sep,  {  	struct a2dp_sep *a2dp_sep = user_data;  	struct a2dp_stream_setup *setup; +	int posix_err;  	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)  		debug("SBC Sink: Close_Cfm"); @@ -731,19 +752,22 @@ static void close_cfm(struct avdtp *session, struct avdtp_local_sep *sep,  	if (err) {  		setup->stream = NULL; -		goto finalize; +		finalize_stream_setup(setup, err); +		return;  	}  	if (setup->start) { -		if (avdtp_discover(session, discovery_complete, setup) == 0) +		posix_err = avdtp_discover(session, discovery_complete, setup); +		if (posix_err == 0)  			return;  		error("avdtp_discover failed");  		setup->stream = NULL;  	} +	else +		posix_err = 0; -finalize: -	finalize_stream_setup(setup); +	finalize_stream_setup_errno(setup, -posix_err);  }  static gboolean abort_ind(struct avdtp *session, struct avdtp_local_sep *sep, @@ -792,6 +816,7 @@ static void reconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,  {  	struct a2dp_sep *a2dp_sep = user_data;  	struct a2dp_stream_setup *setup; +	int posix_err;  	if (a2dp_sep->type == AVDTP_SEP_TYPE_SINK)  		debug("SBC Sink: ReConfigure_Cfm"); @@ -811,19 +836,22 @@ static void reconf_cfm(struct avdtp *session, struct avdtp_local_sep *sep,  	if (err) {  		setup->stream = NULL; -		goto finalize; +		finalize_stream_setup(setup, err); +		return;  	}  	if (setup->start) { -		if (avdtp_start(session, stream) == 0) +		posix_err = avdtp_start(session, stream);		 +		if (posix_err == 0)  			return;  		error("avdtp_start failed");  		setup->stream = NULL;  	} +	else +		posix_err = 0; -finalize: -	finalize_stream_setup(setup); +	finalize_stream_setup_errno(setup, -posix_err);  }  static struct avdtp_sep_cfm cfm = { diff --git a/audio/a2dp.h b/audio/a2dp.h index e0d1c2f6..dffdf259 100644 --- a/audio/a2dp.h +++ b/audio/a2dp.h @@ -81,7 +81,8 @@ struct a2dp_sep;  typedef void (*a2dp_stream_cb_t) (struct avdtp *session, struct a2dp_sep *sep,  					struct avdtp_stream *stream, -					void *user_data); +					void *user_data, +					struct avdtp_error *err);  int a2dp_init(DBusConnection *conn, int sources, int sinks);  void a2dp_exit(void); diff --git a/audio/avdtp.c b/audio/avdtp.c index 7907763a..ee1bd06d 100644 --- a/audio/avdtp.c +++ b/audio/avdtp.c @@ -77,11 +77,6 @@  #define STREAM_TIMEOUT 20000  typedef enum { -	AVDTP_ERROR_ERRNO, -	AVDTP_ERROR_ERROR_CODE -} avdtp_error_type_t; - -typedef enum {  	AVDTP_SESSION_STATE_DISCONNECTED,  	AVDTP_SESSION_STATE_CONNECTING,  	AVDTP_SESSION_STATE_CONNECTED @@ -362,14 +357,6 @@ struct avdtp {  	DBusPendingCall *pending_auth;  }; -struct avdtp_error { -	avdtp_error_type_t type; -	union { -		uint8_t error_code; -		int posix_errno; -	} err; -}; -  static uint8_t free_seid = 1;  static GSList *local_seps = NULL; @@ -499,7 +486,7 @@ static void set_disconnect_timer(struct avdtp *session)  						disconnect_timeout, session);  } -static void avdtp_error_init(struct avdtp_error *err, uint8_t type, int id) +void avdtp_error_init(struct avdtp_error *err, uint8_t type, int id)  {  	err->type = type;  	switch (type) { @@ -698,10 +685,15 @@ static void avdtp_sep_set_state(struct avdtp *session,  static void finalize_discovery(struct avdtp *session, int err)  { +	struct avdtp_error avdtp_err; + +	avdtp_error_init(&avdtp_err, AVDTP_ERROR_ERRNO, -err); +  	if (!session->discov_cb)  		return; -	session->discov_cb(session, session->seps, err, +	session->discov_cb(session, session->seps, +				err ? &avdtp_err : NULL,  				session->user_data);  	session->discov_cb = NULL; diff --git a/audio/avdtp.h b/audio/avdtp.h index e81bf496..6af47e57 100644 --- a/audio/avdtp.h +++ b/audio/avdtp.h @@ -21,11 +21,22 @@   *   */ +typedef enum { +	AVDTP_ERROR_ERRNO, +	AVDTP_ERROR_ERROR_CODE +} avdtp_error_type_t; +  struct avdtp;  struct avdtp_stream;  struct avdtp_local_sep;  struct avdtp_remote_sep; -struct avdtp_error; +struct avdtp_error { +	avdtp_error_type_t type; +	union { +		uint8_t error_code; +		int posix_errno; +	} err; +};  /* SEP capability categories */  #define AVDTP_MEDIA_TRANSPORT			0x01 @@ -177,7 +188,7 @@ struct avdtp_sep_ind {  };  typedef void (*avdtp_discover_cb_t) (struct avdtp *session, GSList *seps, -					int err, void *user_data); +					struct avdtp_error *err, void *user_data);  struct avdtp *avdtp_get(bdaddr_t *src, bdaddr_t *dst); @@ -240,7 +251,9 @@ int avdtp_unregister_sep(struct avdtp_local_sep *sep);  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);  void avdtp_get_peers(struct avdtp *session, bdaddr_t *src, bdaddr_t *dst); diff --git a/audio/sink.c b/audio/sink.c index ea95bcf7..e249af18 100644 --- a/audio/sink.c +++ b/audio/sink.c @@ -135,7 +135,7 @@ static void stream_state_changed(struct avdtp_stream *stream,  static void stream_setup_complete(struct avdtp *session, struct a2dp_sep *sep,  					struct avdtp_stream *stream, -					void *user_data) +					void *user_data, struct avdtp_error *err)  {  	struct sink *sink = user_data;  	struct pending_request *pending; @@ -153,7 +153,7 @@ static void stream_setup_complete(struct avdtp *session, struct a2dp_sep *sep,  		err_failed(pending->conn, pending->msg, "Stream setup failed");  		avdtp_unref(sink->session);  		sink->session = NULL; -		debug("Stream setup failed"); +		debug("Stream setup failed : %s", avdtp_strerror(err));  	}  	pending_request_free(pending); | 
