diff options
| -rw-r--r-- | audio/a2dp.c | 3 | ||||
| -rw-r--r-- | audio/avdtp.c | 41 | ||||
| -rw-r--r-- | audio/avdtp.h | 2 | ||||
| -rw-r--r-- | audio/sink.c | 10 | ||||
| -rw-r--r-- | audio/unix.c | 28 | 
5 files changed, 65 insertions, 19 deletions
diff --git a/audio/a2dp.c b/audio/a2dp.c index d1f90fd1..bc9c4013 100644 --- a/audio/a2dp.c +++ b/audio/a2dp.c @@ -675,8 +675,7 @@ static gboolean select_sbc_params(struct sbc_codec_cap *cap,  	else if (supported->allocation_method & A2DP_ALLOCATION_SNR)  		cap->allocation_method = A2DP_ALLOCATION_SNR; -	min_bitpool = MAX(default_bitpool(cap->frequency, cap->channel_mode), -				supported->min_bitpool); +	min_bitpool = MAX(2, supported->min_bitpool);  	max_bitpool = MIN(default_bitpool(cap->frequency, cap->channel_mode),  				supported->max_bitpool); diff --git a/audio/avdtp.c b/audio/avdtp.c index 7194177f..d2733d6e 100644 --- a/audio/avdtp.c +++ b/audio/avdtp.c @@ -218,6 +218,11 @@ struct avdtp_local_sep {  	void *data;  }; +struct stream_callback { +	avdtp_stream_state_cb cb; +	void *user_data; +}; +  struct avdtp_stream {  	int sock;  	uint16_t mtu; @@ -225,9 +230,8 @@ struct avdtp_stream {  	struct avdtp_local_sep *lsep;  	uint8_t rseid;  	GSList *caps; +	GSList *callbacks;  	struct avdtp_service_capability *codec; -	avdtp_stream_state_cb cb; -	void *user_data;  	guint io;		/* Transport GSource ID */  	guint timer;		/* Waiting for other side to close or open  				   the transport channel */ @@ -456,10 +460,13 @@ static void stream_free(struct avdtp_stream *stream)  	if (stream->timer)  		g_source_remove(stream->timer); -	if (stream->caps) { -		g_slist_foreach(stream->caps, (GFunc) g_free, NULL); -		g_slist_free(stream->caps); -	} + +	g_slist_foreach(stream->callbacks, (GFunc) g_free, NULL); +	g_slist_free(stream->callbacks); + +	g_slist_foreach(stream->caps, (GFunc) g_free, NULL); +	g_slist_free(stream->caps); +  	g_free(stream);  } @@ -485,9 +492,14 @@ static void avdtp_sep_set_state(struct avdtp *session,  	old_state = sep->state;  	sep->state = state; -	if (stream && stream->cb) -		stream->cb(stream, old_state, state, err_ptr, -				stream->user_data); +	if (stream) { +		GSList *l; +		for (l = stream->callbacks; l != NULL; l = g_slist_next(l)) { +			struct stream_callback *cb = l->data; +			cb->cb(stream, old_state, state, err_ptr, +					cb->user_data); +		} +	}  	if (state == AVDTP_STATE_IDLE) {  		session->streams = g_slist_remove(session->streams, stream); @@ -2085,11 +2097,16 @@ int avdtp_get_seps(struct avdtp *session, uint8_t acp_type, uint8_t media_type,  	return -EINVAL;  } -void avdtp_stream_set_cb(struct avdtp *session, struct avdtp_stream *stream, +void avdtp_stream_add_cb(struct avdtp *session, struct avdtp_stream *stream,  				avdtp_stream_state_cb cb, void *data)  { -	stream->cb = cb; -	stream->user_data = data; +	struct stream_callback *stream_cb; + +	stream_cb = g_new(struct stream_callback, 1); +	stream_cb->cb = cb; +	stream_cb->user_data = data; + +	stream->callbacks = g_slist_append(stream->callbacks, stream_cb);;  }  int avdtp_get_configuration(struct avdtp *session, struct avdtp_stream *stream) diff --git a/audio/avdtp.h b/audio/avdtp.h index 0043c480..aa835131 100644 --- a/audio/avdtp.h +++ b/audio/avdtp.h @@ -165,7 +165,7 @@ struct avdtp_service_capability *avdtp_get_codec(struct avdtp_remote_sep *sep);  int avdtp_discover(struct avdtp *session, avdtp_discover_cb_t cb,  			void *user_data); -void avdtp_stream_set_cb(struct avdtp *session, struct avdtp_stream *stream, +void avdtp_stream_add_cb(struct avdtp *session, struct avdtp_stream *stream,  				avdtp_stream_state_cb cb, void *data);  gboolean avdtp_stream_get_transport(struct avdtp_stream *stream, int *sock, diff --git a/audio/sink.c b/audio/sink.c index 0f69bbf6..fd6e9db2 100644 --- a/audio/sink.c +++ b/audio/sink.c @@ -71,9 +71,11 @@ static void pending_request_free(struct pending_request *pending)  	g_free(pending);  } -void stream_state_changed(struct avdtp_stream *stream, avdtp_state_t old_state, -				avdtp_state_t new_state, -				struct avdtp_error *err, void *user_data) +static void stream_state_changed(struct avdtp_stream *stream, +					avdtp_state_t old_state, +					avdtp_state_t new_state, +					struct avdtp_error *err, +					void *user_data)  {  	struct device *dev = user_data;  	struct sink *sink = dev->sink; @@ -315,7 +317,7 @@ gboolean sink_new_stream(struct device *dev, struct avdtp *session,  	sink->stream = stream;  	sink->initiator = FALSE; -	avdtp_stream_set_cb(session, stream, stream_state_changed, dev); +	avdtp_stream_add_cb(session, stream, stream_state_changed, dev);  	return TRUE;  } diff --git a/audio/unix.c b/audio/unix.c index 10856b93..0e5fd5c1 100644 --- a/audio/unix.c +++ b/audio/unix.c @@ -140,6 +140,30 @@ static service_type_t select_service(struct device *dev)  		return TYPE_NONE;  } + +static void stream_state_changed(struct avdtp_stream *stream, +					avdtp_state_t old_state, +					avdtp_state_t new_state, +					struct avdtp_error *err, +					void *user_data) +{ +	struct unix_client *client = user_data; + +	if (err) +		return; +	 +	switch (new_state) { +	case AVDTP_STATE_IDLE: +		if (client->data.session) { +			avdtp_unref(client->data.session); +			client->data.session = NULL; +		} +		break; +	default: +		break; +	} +} +  static void a2dp_setup_complete(struct avdtp *session, struct device *dev,  					struct avdtp_stream *stream,  					void *user_data) @@ -223,11 +247,15 @@ static void a2dp_setup_complete(struct avdtp *session, struct device *dev,  	unix_send_cfg(client->sock, cfg, fd); +	avdtp_stream_add_cb(session, stream, stream_state_changed, dev); +  	return;  failed:  	unix_send_cfg(client->sock, NULL, -1);  	a2dp_source_unlock(dev, session); +	avdtp_unref(client->data.session); +	client->data.session = NULL;  }  static void cfg_event(struct unix_client *client, struct ipc_packet *pkt,  | 
