diff options
| author | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2008-09-08 18:20:29 -0300 | 
|---|---|---|
| committer | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2008-09-08 18:20:29 -0300 | 
| commit | 957d01bac7a4c448bbe0a15de613af7927d1c7d0 (patch) | |
| tree | 4c279a27c3284d9434a08cc5802b97bf846c6479 /audio/a2dp.c | |
| parent | 75b61c0a4f415fdb6518b9cf99f9b5d4b8072c5f (diff) | |
Fix a2dp and avrcp drivers to not rely on BDADDR_ANY.
Diffstat (limited to 'audio/a2dp.c')
| -rw-r--r-- | audio/a2dp.c | 118 | 
1 files changed, 80 insertions, 38 deletions
| diff --git a/audio/a2dp.c b/audio/a2dp.c index 5e8cfd85..de15a42a 100644 --- a/audio/a2dp.c +++ b/audio/a2dp.c @@ -92,12 +92,15 @@ struct a2dp_setup {  static DBusConnection *connection = NULL; -static GSList *sinks = NULL; -static GSList *sources = NULL; - -static uint32_t source_record_id = 0; -static uint32_t sink_record_id = 0; +struct a2dp_server { +	bdaddr_t src; +	GSList *sinks; +	GSList *sources; +	uint32_t source_record_id; +	uint32_t sink_record_id; +}; +static GSList *servers = NULL;  static GSList *setups = NULL;  static unsigned int cb_id = 0; @@ -981,7 +984,7 @@ static sdp_record_t *a2dp_sink_record()  	return NULL;  } -static struct a2dp_sep *a2dp_add_sep(DBusConnection *conn, uint8_t type, +static struct a2dp_sep *a2dp_add_sep(struct a2dp_server *server, uint8_t type,  					uint8_t codec)  {  	struct a2dp_sep *sep; @@ -994,8 +997,9 @@ static struct a2dp_sep *a2dp_add_sep(DBusConnection *conn, uint8_t type,  	sep = g_new0(struct a2dp_sep, 1);  	ind = (codec == A2DP_CODEC_MPEG12) ? &mpeg_ind : &sbc_ind; -	sep->sep = avdtp_register_sep(type, AVDTP_MEDIA_TYPE_AUDIO, codec, -					ind, &cfm, sep); +	sep->sep = avdtp_register_sep(&server->src, type, +					AVDTP_MEDIA_TYPE_AUDIO, codec, ind, +					&cfm, sep);  	if (sep->sep == NULL) {  		g_free(sep);  		return NULL; @@ -1005,13 +1009,13 @@ static struct a2dp_sep *a2dp_add_sep(DBusConnection *conn, uint8_t type,  	sep->type = type;  	if (type == AVDTP_SEP_TYPE_SOURCE) { -		l = &sources; +		l = &server->sources;  		create_record = a2dp_source_record; -		record_id = &source_record_id; +		record_id = &server->source_record_id;  	} else { -		l = &sinks; +		l = &server->sinks;  		create_record = a2dp_sink_record; -		record_id = &sink_record_id; +		record_id = &server->sink_record_id;  	}  	if (*record_id != 0) @@ -1025,7 +1029,7 @@ static struct a2dp_sep *a2dp_add_sep(DBusConnection *conn, uint8_t type,  		return NULL;  	} -	if (add_record_to_server(BDADDR_ANY, record) < 0) { +	if (add_record_to_server(&server->src, record) < 0) {  		error("Unable to register A2DP service record");\  		sdp_record_free(record);  		avdtp_unregister_sep(sep->sep); @@ -1040,7 +1044,21 @@ add:  	return sep;  } -int a2dp_init(DBusConnection *conn, GKeyFile *config) +static struct a2dp_server *find_server(GSList *list, const bdaddr_t *src) +{ +	GSList *l; + +	for (l = list; l; l = l->next) { +		struct a2dp_server *server = l->data; + +		if (bacmp(&server->src, src) == 0) +			return server; +	} + +	return NULL; +} + +int a2dp_register(DBusConnection *conn, const bdaddr_t *src, GKeyFile *config)  {  	int sbc_srcs = 1, sbc_sinks = 0;  	int mpeg12_srcs = 0, mpeg12_sinks = 0; @@ -1048,6 +1066,7 @@ int a2dp_init(DBusConnection *conn, GKeyFile *config)  	char *str;  	GError *err = NULL;  	int i; +	struct a2dp_server *server;  	if (!config)  		goto proceed; @@ -1107,27 +1126,36 @@ int a2dp_init(DBusConnection *conn, GKeyFile *config)  	}  proceed: -	connection = dbus_connection_ref(conn); - -	avdtp_init(config); +	if (!connection) +		connection = dbus_connection_ref(conn); + +	server = find_server(servers, src); +	if (!server) { +		server = g_new0(struct a2dp_server, 1); +		if (!server) +			return -ENOMEM; +		avdtp_init(src, config); +		bacpy(&server->src, src); +		servers = g_slist_append(servers, server); +	}  	if (source) {  		for (i = 0; i < sbc_srcs; i++) -			a2dp_add_sep(conn, AVDTP_SEP_TYPE_SOURCE, +			a2dp_add_sep(server, AVDTP_SEP_TYPE_SOURCE,  					A2DP_CODEC_SBC);  		for (i = 0; i < mpeg12_srcs; i++) -			a2dp_add_sep(conn, AVDTP_SEP_TYPE_SOURCE, +			a2dp_add_sep(server, AVDTP_SEP_TYPE_SOURCE,  					A2DP_CODEC_MPEG12);  	}  	if (sink) {  		for (i = 0; i < sbc_sinks; i++) -			a2dp_add_sep(conn, AVDTP_SEP_TYPE_SINK, +			a2dp_add_sep(server, AVDTP_SEP_TYPE_SINK,  					A2DP_CODEC_SBC);  		for (i = 0; i < mpeg12_sinks; i++) -			a2dp_add_sep(conn, AVDTP_SEP_TYPE_SINK, +			a2dp_add_sep(server, AVDTP_SEP_TYPE_SINK,  					A2DP_CODEC_MPEG12);  	} @@ -1140,27 +1168,34 @@ static void a2dp_unregister_sep(struct a2dp_sep *sep)  	g_free(sep);  } -void a2dp_exit() +void a2dp_unregister(const bdaddr_t *src)  { -	g_slist_foreach(sinks, (GFunc) a2dp_unregister_sep, NULL); -	g_slist_free(sinks); -	sinks = NULL; +	struct a2dp_server *server; -	g_slist_foreach(sources, (GFunc) a2dp_unregister_sep, NULL); -	g_slist_free(sources); -	sources = NULL; +	server = find_server(servers, src); +	if (!server) +		return; -	if (source_record_id) { -		remove_record_from_server(source_record_id); -		source_record_id = 0; -	} +	g_slist_foreach(server->sinks, (GFunc) a2dp_unregister_sep, NULL); +	g_slist_free(server->sinks); -	if (sink_record_id) { -		remove_record_from_server(sink_record_id); -		sink_record_id = 0; -	} +	g_slist_foreach(server->sources, (GFunc) a2dp_unregister_sep, NULL); +	g_slist_free(server->sources); + +	if (server->source_record_id) +		remove_record_from_server(server->source_record_id); + +	if (server->sink_record_id) +		remove_record_from_server(server->sink_record_id); + +	servers = g_slist_remove(servers, server); +	g_free(server); + +	if (servers) +		return;  	dbus_connection_unref(connection); +	connection = NULL;  }  gboolean a2dp_source_cancel(struct audio_device *dev, unsigned int id) @@ -1201,6 +1236,7 @@ unsigned int a2dp_source_config(struct avdtp *session, a2dp_config_cb_t cb,  {  	struct a2dp_setup_cb *cb_data;  	GSList *l; +	struct a2dp_server *server;  	struct a2dp_setup *setup;  	struct a2dp_sep *sep = NULL, *tmp;  	struct avdtp_local_sep *lsep; @@ -1208,6 +1244,12 @@ unsigned int a2dp_source_config(struct avdtp *session, a2dp_config_cb_t cb,  	struct avdtp_service_capability *cap;  	struct avdtp_media_codec_capability *codec_cap = NULL;  	int posix_err; +	bdaddr_t src; + +	avdtp_get_peers(session, &src, NULL); +	server = find_server(servers, &src); +	if (!server) +		return 0;  	for (l = caps; l != NULL; l = l->next) {  		cap = l->data; @@ -1222,7 +1264,7 @@ unsigned int a2dp_source_config(struct avdtp *session, a2dp_config_cb_t cb,  	if (!codec_cap)  		return 0; -	for (l = sources; l != NULL; l = l->next) { +	for (l = server->sources; l != NULL; l = l->next) {  		tmp = l->data;  		if (tmp->locked) @@ -1264,7 +1306,7 @@ unsigned int a2dp_source_config(struct avdtp *session, a2dp_config_cb_t cb,  	switch (avdtp_sep_get_state(sep->sep)) {  	case AVDTP_STATE_IDLE: -		for (l = sources; l != NULL; l = l->next) { +		for (l = server->sources; l != NULL; l = l->next) {  			tmp = l->data;  			if (avdtp_has_stream(session, tmp->stream)) | 
