diff options
| author | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2007-06-18 21:08:35 +0000 | 
|---|---|---|
| committer | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2007-06-18 21:08:35 +0000 | 
| commit | eb0899c1c7137ece8c0e5e5ec031cb2b9b4262e3 (patch) | |
| tree | c18bfb08d8d4ab57e6b61427c4c30c80361f8170 | |
| parent | 8b82bd82b15db30f805c755aa783f6c98f0be73e (diff) | |
Make deprecated headset methods to rely on new device methods.
| -rw-r--r-- | audio/audio-api.txt | 8 | ||||
| -rw-r--r-- | audio/headset.c | 145 | ||||
| -rw-r--r-- | audio/headset.h | 4 | ||||
| -rw-r--r-- | audio/main.c | 2 | ||||
| -rw-r--r-- | audio/manager.c | 321 | ||||
| -rw-r--r-- | audio/manager.h | 2 | ||||
| -rw-r--r-- | audio/unix.c | 60 | ||||
| -rw-r--r-- | audio/unix.h | 3 | 
8 files changed, 289 insertions, 256 deletions
| diff --git a/audio/audio-api.txt b/audio/audio-api.txt index 17baedc1..cd736802 100644 --- a/audio/audio-api.txt +++ b/audio/audio-api.txt @@ -35,6 +35,14 @@ Methods  			of available devices which implement as a minimum the  			interfaces given through the parameter. +		string DefaultDevice() + +			Returns the object path for the default device. + +		void ChangeDefaultDevice(string path) + +			Changes the default device. +  		array{string} ListHeadsets()  			Returns list of headset objects that are configured. diff --git a/audio/headset.c b/audio/headset.c index 5c087312..723bc1ab 100644 --- a/audio/headset.c +++ b/audio/headset.c @@ -89,6 +89,8 @@ struct pending_connect {  	DBusMessage *msg;  	GIOChannel *io;  	guint io_id; +	int sock; +	struct ipc_data_cfg *cfg;  };  struct headset { @@ -325,7 +327,7 @@ static void send_cancel_auth(audio_device_t *device)  	DBusMessage *cancel;  	char addr[18], *address = addr;  	const char *uuid; -        +  	if (device->headset->type == SVC_HEADSET)  		uuid = HSP_AG_UUID;  	else @@ -475,9 +477,11 @@ static gboolean sco_connect_cb(GIOChannel *chan, GIOCondition cond,  	g_io_add_watch(hs->sco, flags, (GIOFunc) sco_cb, device); -	reply = dbus_message_new_method_return(hs->pending_connect->msg); -	if (reply) -		send_message_and_unref(connection, reply); +	if (hs->pending_connect->msg) { +		reply = dbus_message_new_method_return(hs->pending_connect->msg); +		if (reply) +			send_message_and_unref(connection, reply); +	}  	pending_connect_free(hs->pending_connect);  	hs->pending_connect = NULL; @@ -514,6 +518,70 @@ failed:  	return FALSE;  } +static int sco_connect(audio_device_t *device, struct pending_connect *c) +{ +	struct headset *hs = device->headset; +	struct sockaddr_sco addr; +	gboolean do_callback = FALSE; +	int sk, err; + +	sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO); +	if (sk < 0) { +		err = errno; +		error("socket(BTPROTO_SCO): %s (%d)", strerror(err), err); +		return -err; +	} + +	c->io = g_io_channel_unix_new(sk); +	if (!c->io) { +		close(sk); +		return -EINVAL; +	} + +	memset(&addr, 0, sizeof(addr)); +	addr.sco_family = AF_BLUETOOTH; +	bacpy(&addr.sco_bdaddr, BDADDR_ANY); + +	if (bind(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0) { +		err = errno; +		error("socket(BTPROTO_SCO): %s (%d)", strerror(err), err); +		return -err; +	} + +	if (set_nonblocking(sk) < 0) { +		err = errno; +		return -err; +	} + +	memset(&addr, 0, sizeof(addr)); +	addr.sco_family = AF_BLUETOOTH; +	bacpy(&addr.sco_bdaddr, &device->bda); + +	if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { +		if (!(errno == EAGAIN || errno == EINPROGRESS)) { +			err = errno; +			error("connect: %s (%d)", strerror(errno), errno); +			return -err; +		} + +		debug("SCO connect in progress"); +		c->io_id = g_io_add_watch(c->io, +					G_IO_OUT | G_IO_NVAL | G_IO_ERR | G_IO_HUP, +					(GIOFunc) sco_connect_cb, device); +	} else { +		debug("SCO connect succeeded with first try"); +		do_callback = TRUE; +	} + +	hs->state = HEADSET_STATE_PLAY_IN_PROGRESS; +	hs->pending_connect = c; + +	if (do_callback) +		sco_connect_cb(c->io, G_IO_OUT, device); + +	return 0; +} +  static gboolean rfcomm_connect_cb(GIOChannel *chan, GIOCondition cond,  					audio_device_t *device)  { @@ -521,14 +589,14 @@ static gboolean rfcomm_connect_cb(GIOChannel *chan, GIOCondition cond,  	char hs_address[18];  	int sk, ret, err;  	socklen_t len; -	 +  	if (cond & G_IO_NVAL)  		return FALSE;  	hs = device->headset;  	assert(hs != NULL); -       	assert(hs->pending_connect != NULL); +	assert(hs->pending_connect != NULL);  	assert(hs->rfcomm == NULL);  	assert(hs->state == HEADSET_STATE_CONNECT_IN_PROGRESS); @@ -1406,10 +1474,7 @@ static DBusHandlerResult hs_play(DBusConnection *conn, DBusMessage *msg,  {  	audio_device_t *device = data;  	struct headset *hs = device->headset; -	struct sockaddr_sco addr;  	struct pending_connect *c; -	gboolean do_callback = FALSE; -	int sk, err;  	if (hs->state < HEADSET_STATE_CONNECTED)  		return err_not_connected(connection, msg); @@ -1426,66 +1491,10 @@ static DBusHandlerResult hs_play(DBusConnection *conn, DBusMessage *msg,  	c->msg = msg ? dbus_message_ref(msg) : NULL; -	sk = socket(PF_BLUETOOTH, SOCK_SEQPACKET, BTPROTO_SCO); -	if (sk < 0) { -		err = errno; -		error("socket(BTPROTO_SCO): %s (%d)", strerror(err), err); -		err_connect_failed(connection, msg, err); -		goto failed; -	} - -	c->io = g_io_channel_unix_new(sk); -	if (!c->io) { -		close(sk); -		pending_connect_free(c); -		return DBUS_HANDLER_RESULT_NEED_MEMORY; -	} - -	memset(&addr, 0, sizeof(addr)); -	addr.sco_family = AF_BLUETOOTH; -	bacpy(&addr.sco_bdaddr, BDADDR_ANY); - -	if (bind(sk, (struct sockaddr *)&addr, sizeof(addr)) < 0) { -		err = errno; -		error("socket(BTPROTO_SCO): %s (%d)", strerror(err), err); -		err_connect_failed(connection, msg, err); +	if (sco_connect(device, c) < 0)  		goto failed; -	} - -	if (set_nonblocking(sk) < 0) { -		err = errno; -		err_connect_failed(connection, msg, err); -		goto failed; -	} - -	memset(&addr, 0, sizeof(addr)); -	addr.sco_family = AF_BLUETOOTH; -	bacpy(&addr.sco_bdaddr, &device->bda); - -	if (connect(sk, (struct sockaddr *) &addr, sizeof(addr)) < 0) { -		if (!(errno == EAGAIN || errno == EINPROGRESS)) { -			err = errno; -			error("connect: %s (%d)", strerror(errno), errno); -			goto failed; -		} - -		debug("SCO connect in progress"); -		c->io_id = g_io_add_watch(c->io, -					G_IO_OUT | G_IO_NVAL | G_IO_ERR | G_IO_HUP, -					(GIOFunc) sco_connect_cb, device); -	} else { -		debug("SCO connect succeeded with first try"); -		do_callback = TRUE; -	} - -	hs->state = HEADSET_STATE_PLAY_IN_PROGRESS; -	hs->pending_connect = c; - -	if (do_callback) -		sco_connect_cb(c->io, G_IO_OUT, device);  	return 0; -  failed:  	if (c)  		pending_connect_free(c); @@ -1772,7 +1781,7 @@ register_iface:  }  void headset_free(const char *object_path) -{  +{  	audio_device_t *device;  	if (!dbus_connection_get_object_user_data(connection, object_path, @@ -2028,7 +2037,7 @@ void headset_exit(void)  	connection = NULL;  } -int headset_get_config(headset_t *headset, struct ipc_data_cfg *cfg) +int headset_get_config(headset_t *headset, int sock, struct ipc_data_cfg *cfg)  {  	if (!sco_over_hci)  		return -1; diff --git a/audio/headset.h b/audio/headset.h index 6780e7a9..b420860e 100644 --- a/audio/headset.h +++ b/audio/headset.h @@ -29,7 +29,7 @@  #include <dbus/dbus.h> -#include "ipc.h" +#include "unix.h"  #define AUDIO_HEADSET_INTERFACE "org.bluez.audio.Headset" @@ -49,6 +49,6 @@ int headset_server_init(DBusConnection *conn, gboolean disable_hfp,  void headset_exit(void); -int headset_get_config(headset_t *headset, struct ipc_data_cfg *cfg); +int headset_get_config(headset_t *headset, int sock, struct ipc_data_cfg *cfg);  #endif /* __AUDIO_HEADSET_H_ */ diff --git a/audio/main.c b/audio/main.c index 3a170b1a..0ca8ce87 100644 --- a/audio/main.c +++ b/audio/main.c @@ -36,9 +36,7 @@  #include "dbus.h"  #include "logging.h" -#include "unix.h"  #include "manager.h" -#include "headset.h"  /* Configuration settings */  static gboolean disable_hfp = TRUE; diff --git a/audio/manager.c b/audio/manager.c index e166fdca..7faa0490 100644 --- a/audio/manager.c +++ b/audio/manager.c @@ -79,7 +79,7 @@ struct audio_sdp_data {  static DBusConnection *connection = NULL; -static audio_device_t *default_hs = NULL; +static audio_device_t *default_dev = NULL;  static GSList *devices = NULL; @@ -275,6 +275,10 @@ static gboolean add_device(audio_device_t *device)  		return FALSE;  	} +	/* First device became default */ +	if (g_slist_length(devices) == 0) +		default_dev = device; +  	devices = g_slist_append(devices, device);  	return TRUE; @@ -370,6 +374,11 @@ static void handle_record(sdp_record_t *record, audio_device_t *device)  		break;  	case HANDSFREE_SVCLASS_ID:  		debug("Found Hansfree record"); +		if (device->headset) +			headset_update(device->headset, record, uuid16); +		else +			device->headset = headset_init(device->object_path, +							record, uuid16);  		break;  	case HANDSFREE_AGW_SVCLASS_ID:  		debug("Found Handsfree AG record"); @@ -429,6 +438,7 @@ static void finish_sdp(struct audio_sdp_data *data, gboolean success)  	char **required;  	int required_len, i;  	DBusMessage *reply = NULL; +	DBusError derr;  	debug("Audio service discovery completed with %s",  			success ? "success" : "failure"); @@ -441,13 +451,43 @@ static void finish_sdp(struct audio_sdp_data *data, gboolean success)  	if (!data->msg)  		goto update; -	if (!dbus_message_get_args(data->msg, NULL, +	dbus_error_init(&derr); +	if (dbus_message_is_method_call(data->msg, AUDIO_MANAGER_INTERFACE, +		"CreateHeadset")) { +		dbus_message_get_args(data->msg, &derr, +					DBUS_TYPE_STRING, &addr, +					DBUS_TYPE_INVALID); +		required = dbus_new0(char *, 2); +		if (required == NULL) { +			success = FALSE; +			err_failed(connection, data->msg, "Out of memory"); +			goto done; +		} + +		required[0] = dbus_new0(char, +			strlen(AUDIO_HEADSET_INTERFACE) + 1); +		if (required[0] == NULL) { +			success = FALSE; +			err_failed(connection, data->msg, "Out of memory"); +			goto done; +		} + +		memcpy(required[0], AUDIO_HEADSET_INTERFACE, +			strlen(AUDIO_HEADSET_INTERFACE) + 1); +		required[1] = NULL; +		required_len = 1; +	} +	else +		dbus_message_get_args(data->msg, &derr,  					DBUS_TYPE_STRING, &addr,  					DBUS_TYPE_ARRAY, DBUS_TYPE_STRING,  					&required, &required_len, -					DBUS_TYPE_INVALID)) { +					DBUS_TYPE_INVALID); + +	if (dbus_error_is_set(&derr)) {  		error("Unable to get message args");  		success = FALSE; +		dbus_error_free(&derr);  		goto done;  	} @@ -494,13 +534,20 @@ update:  						"DeviceCreated",  						DBUS_TYPE_STRING, &path,  						DBUS_TYPE_INVALID); - +		if (data->device->headset) +			dbus_connection_emit_signal(connection, AUDIO_MANAGER_PATH, +							AUDIO_MANAGER_INTERFACE, +							"HeadsetCreated", +							DBUS_TYPE_STRING, &path, +							DBUS_TYPE_INVALID);  		dbus_message_append_args(reply, DBUS_TYPE_STRING, &path,  				DBUS_TYPE_INVALID);  		send_message_and_unref(connection, reply);  	}  done: +	if (required) +		dbus_free_string_array(required);  	if (!success)  		free_device(data->device);  	if (data->msg) @@ -651,7 +698,6 @@ static void get_handles_reply(DBusPendingCall *call,  				DBUS_TYPE_ARRAY, DBUS_TYPE_UINT32,  				&array, &array_len,  				DBUS_TYPE_INVALID)) { -	    		err_failed(connection, data->msg,  				"Unable to get args from reply");  		goto failed; @@ -679,7 +725,7 @@ static void get_handles_reply(DBusPendingCall *call,  			get_next_record(data);  		else  			finish_sdp(data, TRUE); -	}	 +	}  	dbus_message_unref(reply); @@ -789,8 +835,8 @@ audio_device_t *manager_headset_connected(bdaddr_t *bda)  					DBUS_TYPE_STRING, &path,  					DBUS_TYPE_INVALID); -	if (!default_hs) { -		default_hs = device; +	if (!default_dev) { +		default_dev = device;  		dbus_connection_emit_signal(connection, AUDIO_MANAGER_PATH,  						AUDIO_MANAGER_INTERFACE,  						"DefaultHeadsetChanged", @@ -805,13 +851,13 @@ static gboolean device_supports_interface(audio_device_t *device,  						const char *iface)  {  		if (strcmp(iface, AUDIO_HEADSET_INTERFACE) == 0) -		       	return device->headset ? TRUE : FALSE; +			return device->headset ? TRUE : FALSE;  		if (strcmp(iface, AUDIO_GATEWAY_INTERFACE) == 0)  			return device->gateway ? TRUE : FALSE;  		if (strcmp(iface, AUDIO_SOURCE_INTERFACE) == 0) -			return device->gateway ? TRUE : FALSE; +			return device->source ? TRUE : FALSE;  		if (strcmp(iface, AUDIO_SINK_INTERFACE) == 0)  			return device->sink ? TRUE : FALSE; @@ -854,11 +900,34 @@ static DBusHandlerResult am_create_device(DBusConnection *conn,  	DBusError derr;  	dbus_error_init(&derr); -	dbus_message_get_args(msg, &derr, -				DBUS_TYPE_STRING, &address, -				DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, -				&required, &required_len, -				DBUS_TYPE_INVALID); +	if (dbus_message_is_method_call(msg, AUDIO_MANAGER_INTERFACE, +		"CreateHeadset")) { +		dbus_message_get_args(msg, &derr, +					DBUS_TYPE_STRING, &address, +					DBUS_TYPE_INVALID); +		required = dbus_new0(char *, 2); +		if (required == NULL) +			return DBUS_HANDLER_RESULT_NEED_MEMORY; + +		required[0] = dbus_new0(char, +			strlen(AUDIO_HEADSET_INTERFACE) + 1); +		if (required[0] == NULL) { +			dbus_free(required); +			return DBUS_HANDLER_RESULT_NEED_MEMORY; +		} + +		memcpy(required[0], AUDIO_HEADSET_INTERFACE, +			strlen(AUDIO_HEADSET_INTERFACE) + 1); +		required[1] = NULL; +		required_len = 1; +	} +	else +		dbus_message_get_args(msg, &derr, +					DBUS_TYPE_STRING, &address, +					DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, +					&required, &required_len, +					DBUS_TYPE_INVALID); +  	if (dbus_error_is_set(&derr)) {  		err_invalid_args(connection, msg, derr.message);  		dbus_error_free(&derr); @@ -905,10 +974,31 @@ static DBusHandlerResult am_list_devices(DBusConnection *conn,  	int required_len;  	dbus_error_init(&derr); -	dbus_message_get_args(msg, &derr, -				DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, -				&required, &required_len, -				DBUS_TYPE_INVALID); + +	if (dbus_message_is_method_call(msg, AUDIO_MANAGER_INTERFACE, +		"ListHeadsets")) { +		required = dbus_new0(char *, 2); +		if (required == NULL) +			return DBUS_HANDLER_RESULT_NEED_MEMORY; + +		required[0] = dbus_new0(char, +			strlen(AUDIO_HEADSET_INTERFACE) + 1); +		if (required[0] == NULL) { +			dbus_free(required); +			return DBUS_HANDLER_RESULT_NEED_MEMORY; +		} + +		memcpy(required[0], AUDIO_HEADSET_INTERFACE, +			strlen(AUDIO_HEADSET_INTERFACE) + 1); +		required[1] = NULL; +		required_len = 1; +	} +	else +		dbus_message_get_args(msg, &derr, +					DBUS_TYPE_ARRAY, DBUS_TYPE_STRING, +					&required, &required_len, +					DBUS_TYPE_INVALID); +  	if (dbus_error_is_set(&derr)) {  		err_invalid_args(connection, msg, derr.message);  		dbus_error_free(&derr); @@ -944,72 +1034,6 @@ static DBusHandlerResult am_list_devices(DBusConnection *conn,  	return send_message_and_unref(connection, reply);  } -static DBusHandlerResult am_create_headset(DBusConnection *conn, DBusMessage *msg, -						void *data) -{ -	const char *path, *address; -	bdaddr_t bda; -	DBusMessage *reply; -	DBusError derr; -	audio_device_t *device; -	gboolean created = FALSE; - -	dbus_error_init(&derr); -	dbus_message_get_args(msg, &derr, -				DBUS_TYPE_STRING, &address, -				DBUS_TYPE_INVALID); -	if (dbus_error_is_set(&derr)) { -		err_invalid_args(connection, msg, derr.message); -		dbus_error_free(&derr); -		return DBUS_HANDLER_RESULT_HANDLED; -	} - -	str2ba(address, &bda); - -	device = find_device(&bda); -	if (device) -		goto done; - -	device = create_device(&bda); -	if (!add_device(device)) { -		free_device(device); -		return error_reply(connection, msg, -				"org.bluez.audio.Error.Failed", -				"Unable to create new audio device"); -	} - -	if (!device->headset) { -		device->headset = headset_init(device->object_path, NULL, 0); -		created = TRUE; -	} - -	if (!device->headset) { -		remove_device(device); -		return error_reply(connection, msg, -				"org.bluez.audio.Error.Failed", -				"Unable to init Headset interface"); -	} - -done: -	path = device->object_path; - -	reply = dbus_message_new_method_return(msg); -	if (!reply) -		return DBUS_HANDLER_RESULT_NEED_MEMORY; - -	if (created) -		dbus_connection_emit_signal(connection, AUDIO_MANAGER_PATH, -						AUDIO_MANAGER_INTERFACE, -						"HeadsetCreated", -						DBUS_TYPE_STRING, &path, -						DBUS_TYPE_INVALID); - -	dbus_message_append_args(reply, DBUS_TYPE_STRING, &path, -					DBUS_TYPE_INVALID); - -	return send_message_and_unref(connection, reply); -} -  static gint device_path_cmp(gconstpointer a, gconstpointer b)  {  	const audio_device_t *device = a; @@ -1045,7 +1069,7 @@ static DBusHandlerResult am_remove_device(DBusConnection *conn,  	if (!match)  		return error_reply(connection, msg,  					"org.bluez.audio.Error.DoesNotExist", -					"The headset does not exist"); +					"The device does not exist");  	reply = dbus_message_new_method_return(msg);  	if (!reply) @@ -1055,20 +1079,20 @@ static DBusHandlerResult am_remove_device(DBusConnection *conn,  	remove_device(device); -	if (default_hs == device) { +	if (default_dev == device) {  		const char *param;  		GSList *l; -		default_hs = NULL; +		default_dev = NULL;  		for (l = devices; l != NULL; l = l->next) {  			device = l->data;  			if (device->headset) -				default_hs = device; +				default_dev = device;  		} -		param = default_hs ? default_hs->object_path : ""; +		param = default_dev ? default_dev->object_path : "";  		dbus_connection_emit_signal(conn, AUDIO_MANAGER_PATH,  						AUDIO_MANAGER_INTERFACE, @@ -1092,49 +1116,6 @@ static DBusHandlerResult am_remove_device(DBusConnection *conn,  	return send_message_and_unref(connection, reply);  } -static DBusHandlerResult am_remove_headset(DBusConnection *conn, -						DBusMessage *msg, -						void *data) -{ -	return am_remove_device(conn, msg, data); -} - -static DBusHandlerResult am_list_headsets(DBusConnection *conn, -						DBusMessage *msg, -						void *data) -{ -	DBusMessageIter iter; -	DBusMessageIter array_iter; -	DBusMessage *reply; -	GSList *l; - -	reply = dbus_message_new_method_return(msg); -	if (!reply) -		return DBUS_HANDLER_RESULT_NEED_MEMORY; - -	dbus_message_iter_init_append(reply, &iter); - -	dbus_message_iter_open_container(&iter, DBUS_TYPE_ARRAY, -				DBUS_TYPE_STRING_AS_STRING, &array_iter); - -	for (l = devices; l != NULL; l = l->next) { -		audio_device_t *device = l->data; -		const char *path; - -		if (!device->headset) -			continue; - -		path = device->object_path; - -		dbus_message_iter_append_basic(&array_iter, -						DBUS_TYPE_STRING, &path); -	} - -	dbus_message_iter_close_container(&iter, &array_iter); - -	return send_message_and_unref(connection, reply); -} -  static DBusHandlerResult am_find_by_addr(DBusConnection *conn,  						DBusMessage *msg,  						void *data) @@ -1174,14 +1155,21 @@ static DBusHandlerResult am_find_by_addr(DBusConnection *conn,  	return send_message_and_unref(conn, reply);  } -static DBusHandlerResult am_get_default_headset(DBusConnection *conn, +static DBusHandlerResult am_default_device(DBusConnection *conn,  						DBusMessage *msg,  						void *data)  {  	DBusMessage *reply;  	const char *path; -	if (!default_hs) +	if (!default_dev) +		return error_reply(connection, msg, +					"org.bluez.audio.Error.DoesNotExist", +					"There is no default device"); + +	if (default_dev->headset == NULL && +		dbus_message_is_method_call(msg, AUDIO_MANAGER_INTERFACE, +		"DefaultHeadset"))  		return error_reply(connection, msg,  					"org.bluez.audio.Error.DoesNotExist",  					"There is no default headset"); @@ -1190,7 +1178,7 @@ static DBusHandlerResult am_get_default_headset(DBusConnection *conn,  	if (!reply)  		return DBUS_HANDLER_RESULT_NEED_MEMORY; -	path = default_hs->object_path; +	path = default_dev->object_path;  	dbus_message_append_args(reply, DBUS_TYPE_STRING, &path,  					DBUS_TYPE_INVALID); @@ -1198,7 +1186,7 @@ static DBusHandlerResult am_get_default_headset(DBusConnection *conn,  	return send_message_and_unref(connection, reply);  } -static DBusHandlerResult am_change_default_headset(DBusConnection *conn, +static DBusHandlerResult am_change_default_device(DBusConnection *conn,  							DBusMessage *msg,  							void *data)  { @@ -1206,6 +1194,7 @@ static DBusHandlerResult am_change_default_headset(DBusConnection *conn,  	DBusMessage *reply;  	GSList *match;  	const char *path; +	audio_device_t *device;  	dbus_error_init(&derr);  	if (!dbus_message_get_args(msg, &derr, @@ -1224,22 +1213,35 @@ static DBusHandlerResult am_change_default_headset(DBusConnection *conn,  	if (!match)  		return error_reply(connection, msg,  					"org.bluez.audio.Error.DoesNotExist", -					"The headset does not exist"); +					"The device does not exist");  	reply = dbus_message_new_method_return(msg);  	if (!reply)  		return DBUS_HANDLER_RESULT_NEED_MEMORY; -	default_hs = match->data; +	device = match->data; -	path = default_hs->object_path; +	path = device->object_path; -	dbus_connection_emit_signal(conn, AUDIO_MANAGER_PATH, -					AUDIO_MANAGER_INTERFACE, -					"DefaultHeadsetChanged", -					DBUS_TYPE_STRING, &path, -					DBUS_TYPE_INVALID); +	if (!dbus_message_is_method_call(msg, AUDIO_MANAGER_INTERFACE, +		"ChangeDefaultHeadset")) +		dbus_connection_emit_signal(conn, AUDIO_MANAGER_PATH, +						AUDIO_MANAGER_INTERFACE, +						"DefaultDeviceChanged", +						DBUS_TYPE_STRING, &path, +						DBUS_TYPE_INVALID); +	else if (device->headset) +		dbus_connection_emit_signal(conn, AUDIO_MANAGER_PATH, +						AUDIO_MANAGER_INTERFACE, +						"DefaultHeadsetChanged", +						DBUS_TYPE_STRING, &path, +						DBUS_TYPE_INVALID); +	else +		return error_reply(connection, msg, +					"org.bluez.audio.Error.DoesNotExist", +					"The headset does not exist"); +	default_dev = device;  	return send_message_and_unref(connection, reply);  } @@ -1249,19 +1251,23 @@ static DBusMethodVTable manager_methods[] = {  	{ "RemoveDevice",		am_remove_device,  		"s",	""		},  	{ "ListDevices",		am_list_devices, -		"as",	"as"	}, -	{ "CreateHeadset",		am_create_headset, +		"as",	"as"		}, +	{ "DefaultDevice",		am_default_device, +		"",	"s"		}, +	{ "ChangeDefaultDevice",	am_change_default_device, +		"s",	""		}, +	{ "CreateHeadset",		am_create_device,  		"s",	"s"		}, -	{ "RemoveHeadset",		am_remove_headset, +	{ "RemoveHeadset",		am_remove_device,  		"s",	""		}, -	{ "ListHeadsets",		am_list_headsets, +	{ "ListHeadsets",		am_list_devices,  		"",	"as"		},  	{ "FindDeviceByAddress",	am_find_by_addr,  		"s",	"s"		}, -	{ "DefaultHeadset",		am_get_default_headset, +	{ "DefaultHeadset",		am_default_device,  		"",	"s"		}, -	{ "ChangeDefaultHeadset",	am_change_default_headset, -		"s",	""	}, +	{ "ChangeDefaultHeadset",	am_change_default_device, +		"s",	""		},  	{ NULL, NULL, NULL, NULL },  }; @@ -1270,6 +1276,7 @@ static DBusSignalVTable manager_signals[] = {  	{ "DeviceRemoved",		"s"	},  	{ "HeadsetCreated",		"s"	},  	{ "HeadsetRemoved",		"s"	}, +	{ "DefaultDeviceChanged",	"s"	},  	{ "DefaultHeadsetChanged",	"s"	},  	{ NULL, NULL }  }; @@ -1309,19 +1316,19 @@ void audio_exit(void)  	connection = NULL;  } -int manager_get_device(uint8_t role, struct ipc_data_cfg *cfg) +int manager_get_device(int sock, uint8_t role, struct ipc_data_cfg *cfg)  {  	GSList *l; -	if (default_hs && default_hs->headset && -			headset_is_connected(default_hs->headset)) -		return headset_get_config(default_hs->headset, cfg); +	if (default_dev && default_dev->headset && +			headset_is_connected(default_dev->headset)) +		return headset_get_config(default_dev->headset, sock, cfg);  	for (l = devices; l != NULL; l = l->next) {  		audio_device_t *dev = l->data;  		if (dev->headset && headset_is_connected(dev->headset)) -			return headset_get_config(dev->headset, cfg); +			return headset_get_config(dev->headset, sock, cfg);  	}  	return -1; diff --git a/audio/manager.h b/audio/manager.h index 1ec5247b..5cdf2b23 100644 --- a/audio/manager.h +++ b/audio/manager.h @@ -95,4 +95,4 @@ DBusHandlerResult err_not_available(DBusConnection *conn, DBusMessage *msg);  DBusHandlerResult err_failed(DBusConnection *conn, DBusMessage *msg,  				const char *dsc); -int manager_get_device(uint8_t role, struct ipc_data_cfg *cfg); +int manager_get_device(int sock, uint8_t role, struct ipc_data_cfg *cfg); diff --git a/audio/unix.c b/audio/unix.c index 163f4f98..2dad00df 100644 --- a/audio/unix.c +++ b/audio/unix.c @@ -39,7 +39,6 @@  #include "logging.h"  #include "dbus.h" -#include "unix.h"  #include "manager.h"  static int unix_sock = -1; @@ -119,29 +118,8 @@ static gboolean unix_event(GIOChannel *chan, GIOCondition cond, gpointer data)  		cfg = (struct ipc_data_cfg *) pkt->data;  		memset(cfg, 0, sizeof(struct ipc_data_cfg)); -		if (manager_get_device(pkt->role, cfg) < 0) -			cfg->fd = -1; - -		info("fd=%d, fd_opt=%u, channels=%u, pkt_len=%u, sample_size=%u," -			"rate=%u", cfg->fd, cfg->fd_opt, cfg->channels, -			cfg->pkt_len, cfg->sample_size, cfg->rate); - -		pkt->type = PKT_TYPE_CFG_RSP; -		pkt->length = sizeof(struct ipc_data_cfg); -		pkt->error = PKT_ERROR_NONE; - -		len = send(clisk, pkt, len, 0); -		if (len < 0) -			info("Error %s(%d)", strerror(errno), errno); - -		info("%d bytes sent", len); - -		if (cfg->fd != -1) { -			len = unix_sendmsg_fd(clisk, cfg->fd, pkt); -			if (len < 0) -				info("Error %s(%d)", strerror(errno), errno); -			info("%d bytes sent", len); -		} +		if (manager_get_device(clisk, pkt->role, cfg) == 0) +			unix_send_cfg(clisk, pkt);  		break;  	case PKT_TYPE_STATUS_REQ: @@ -152,8 +130,6 @@ static gboolean unix_event(GIOChannel *chan, GIOCondition cond, gpointer data)  		break;  	} -	g_free(pkt); -	close(clisk);  	return TRUE;  } @@ -202,3 +178,35 @@ void unix_exit(void)  	close(unix_sock);  	unix_sock = -1;  } + +int unix_send_cfg(int sock, struct ipc_packet *pkt) +{ +	struct ipc_data_cfg *cfg = (struct ipc_data_cfg *) pkt->data; +	int len; + +	info("fd=%d, fd_opt=%u, channels=%u, pkt_len=%u, sample_size=%u," +		"rate=%u", cfg->fd, cfg->fd_opt, cfg->channels, +		cfg->pkt_len, cfg->sample_size, cfg->rate); + +	pkt->type = PKT_TYPE_CFG_RSP; +	pkt->length = sizeof(struct ipc_data_cfg); +	pkt->error = PKT_ERROR_NONE; + +	len = sizeof(struct ipc_packet) + sizeof(struct ipc_data_cfg); +	len = send(sock, pkt, len, 0); +	if (len < 0) +		info("Error %s(%d)", strerror(errno), errno); + +	info("%d bytes sent", len); + +	if (cfg->fd != -1) { +		len = unix_sendmsg_fd(sock, cfg->fd, pkt); +		if (len < 0) +			info("Error %s(%d)", strerror(errno), errno); +		info("%d bytes sent", len); +	} + +	g_free(pkt); +	close(sock); +	return 0; +} diff --git a/audio/unix.h b/audio/unix.h index 4f3fc994..15da23ab 100644 --- a/audio/unix.h +++ b/audio/unix.h @@ -21,6 +21,9 @@   *   */ +#include "ipc.h" +  int unix_init(void);  void unix_exit(void); +int unix_send_cfg(int sock, struct ipc_packet *pkt); | 
