diff options
| author | Johan Hedberg <johan.hedberg@nokia.com> | 2007-08-20 08:50:22 +0000 | 
|---|---|---|
| committer | Johan Hedberg <johan.hedberg@nokia.com> | 2007-08-20 08:50:22 +0000 | 
| commit | 730a4ceb9e7e986e2a327fa7e023c3dd2102a50d (patch) | |
| tree | a19fc7a8d901abd7b8429673fec69d1d37dd7d56 | |
| parent | 78a94059160d7478624cad315022255f7ebbbe80 (diff) | |
Improve handling of simultaneous connect attempts to different devices
| -rw-r--r-- | audio/a2dp.c | 24 | ||||
| -rw-r--r-- | audio/unix.c | 14 | 
2 files changed, 29 insertions, 9 deletions
diff --git a/audio/a2dp.c b/audio/a2dp.c index ebf6b472..0e5f1473 100644 --- a/audio/a2dp.c +++ b/audio/a2dp.c @@ -884,6 +884,17 @@ unsigned int a2dp_source_request_stream(struct avdtp *session,  	struct a2dp_stream_cb *cb_data;  	static unsigned int cb_id = 0; +	if (source.used_by != NULL && source.used_by != dev) { +		error("a2dp_source_request_stream: SEP is locked"); +		return 0; +	} + +	if (setup && setup->dev != dev) { +		error("a2dp_source_request_stream: stream setup in progress " +				"already for another device"); +		return 0; +	} +  	cb_data = g_new(struct a2dp_stream_cb, 1);  	cb_data->cb = cb;  	cb_data->user_data = user_data; @@ -906,8 +917,10 @@ unsigned int a2dp_source_request_stream(struct avdtp *session,  	switch (avdtp_sep_get_state(source.sep)) {  	case AVDTP_STATE_IDLE: -		if (avdtp_discover(session, discovery_complete, setup) < 0) +		if (avdtp_discover(session, discovery_complete, setup) < 0) { +			error("avdtp_discover failed");  			goto failed; +		}  		break;  	case AVDTP_STATE_OPEN:  		if (!start) { @@ -916,8 +929,10 @@ unsigned int a2dp_source_request_stream(struct avdtp *session,  		}  		if (source.starting)  			break; -		if (avdtp_start(session, source.stream) < 0) +		if (avdtp_start(session, source.stream) < 0) { +			error("avdtp_start failed");  			goto failed; +		}  		break;  	case AVDTP_STATE_STREAMING:  		if (!start || !source.suspending) { @@ -931,6 +946,7 @@ unsigned int a2dp_source_request_stream(struct avdtp *session,  		source.start_requested = TRUE;  		break;  	default: +		error("SEP in bad state for requesting a new stream");  		goto failed;  	} @@ -947,6 +963,8 @@ gboolean a2dp_source_lock(struct device *dev, struct avdtp *session)  	if (source.used_by)  		return FALSE; +	debug("SBC Source locked"); +  	source.used_by = dev;  	return TRUE; @@ -966,6 +984,8 @@ gboolean a2dp_source_unlock(struct device *dev, struct avdtp *session)  	source.used_by = NULL; +	debug("SBC Source unlocked"); +  	if (!source.stream || state == AVDTP_STATE_IDLE)  		return TRUE; diff --git a/audio/unix.c b/audio/unix.c index f8832c91..9bf1a9ca 100644 --- a/audio/unix.c +++ b/audio/unix.c @@ -198,6 +198,11 @@ static void a2dp_setup_complete(struct avdtp *session, struct device *dev,  	if (!stream)  		goto failed; +	if (!a2dp_source_lock(dev, session)) { +		error("Unable to lock A2DP source SEP"); +		goto failed; +	} +  	a2dp->stream = stream;  	if (!avdtp_stream_get_transport(stream, &fd, &cfg->pkt_len, &caps)) { @@ -273,8 +278,9 @@ static void a2dp_setup_complete(struct avdtp *session, struct device *dev,  failed:  	error("stream setup failed"); +	if (a2dp->stream) +		a2dp_source_unlock(dev, session);  	unix_send_cfg(client->sock, NULL, -1); -	a2dp_source_unlock(dev, session);  	avdtp_unref(a2dp->session);  	a2dp->session = NULL;  	a2dp->stream = NULL; @@ -307,17 +313,11 @@ proceed:  		if (!a2dp->session)  			a2dp->session = avdtp_get(&dev->src, &dev->dst); -		if (!a2dp_source_lock(dev, a2dp->session)) { -			error("Unable to lock A2DP source SEP"); -			goto failed; -		} -  		id = a2dp_source_request_stream(a2dp->session, dev,  						TRUE, a2dp_setup_complete,  						client);  		if (id == 0) {  			error("request_stream failed"); -			a2dp_source_unlock(dev, a2dp->session);  			goto failed;  		}  | 
