diff options
| author | Luiz Augusto von Dentz <luiz.dentz@openbossa.org> | 2009-02-18 19:17:50 -0300 | 
|---|---|---|
| committer | Johan Hedberg <johan.hedberg@nokia.com> | 2009-02-19 11:05:10 +0200 | 
| commit | c95494ee508a9f36096af5ddb1c2ac1579a32b1d (patch) | |
| tree | f04c45cc65a372d8ae5d953a72ab6156e8215bf1 /input | |
| parent | 56fe087dfc68f56d84ac41ca390c8a0dc7438e2d (diff) | |
Make input plugin to use BtIO API.
Diffstat (limited to 'input')
| -rw-r--r-- | input/device.c | 158 | ||||
| -rw-r--r-- | input/device.h | 2 | ||||
| -rw-r--r-- | input/fakehid.c | 2 | ||||
| -rw-r--r-- | input/fakehid.h | 2 | ||||
| -rw-r--r-- | input/server.c | 60 | 
5 files changed, 136 insertions, 88 deletions
| diff --git a/input/device.c b/input/device.c index a2a3c38d..eb089093 100644 --- a/input/device.c +++ b/input/device.c @@ -59,6 +59,7 @@  #include "error.h"  #include "fakehid.h"  #include "glib-helper.h" +#include "btio.h"  #define INPUT_DEVICE_INTERFACE "org.bluez.Input" @@ -324,22 +325,26 @@ static inline DBusMessage *already_connected(DBusMessage *msg)  					"Already connected to a device");  } -static inline DBusMessage *connection_attempt_failed(DBusMessage *msg, int err) +static inline DBusMessage *connection_attempt_failed(DBusMessage *msg, +							const char *err)  { -	return g_dbus_create_error(msg, ERROR_INTERFACE ".ConnectionAttemptFailed", -				err ? strerror(err) : "Connection attempt failed"); +	return g_dbus_create_error(msg, +				ERROR_INTERFACE ".ConnectionAttemptFailed", +				err ? err : "Connection attempt failed");  } -static void rfcomm_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src, -			const bdaddr_t *dst, gpointer user_data) +static void rfcomm_connect_cb(GIOChannel *chan, GError *err, gpointer user_data)  {  	struct input_conn *iconn = user_data;  	struct input_device *idev = iconn->idev;  	struct fake_input *fake = iconn->fake;  	DBusMessage *reply; -	if (err < 0) +	if (err) { +		reply = connection_attempt_failed(iconn->pending_connect, +								err->message);  		goto failed; +	}  	fake->rfcomm = g_io_channel_unix_get_fd(chan); @@ -349,7 +354,9 @@ static void rfcomm_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,  	 */  	fake->uinput = uinput_create(idev->name);  	if (fake->uinput < 0) { -		err = errno; +		g_io_channel_close(chan); +		reply = connection_attempt_failed(iconn->pending_connect, +							strerror(errno));  		goto failed;  	} @@ -368,26 +375,27 @@ static void rfcomm_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,  	return;  failed: -	reply = connection_attempt_failed(iconn->pending_connect, err);  	g_dbus_send_message(idev->conn, reply); -  	dbus_message_unref(iconn->pending_connect);  	iconn->pending_connect = NULL;  } -static int rfcomm_connect(struct input_conn *iconn) +static gboolean rfcomm_connect(struct input_conn *iconn, GError **err)  {  	struct input_device *idev = iconn->idev; -	int err; +	GIOChannel *io; -	err = bt_rfcomm_connect(&idev->src, &idev->dst, iconn->fake->ch, -			rfcomm_connect_cb, iconn); -	if (err < 0) { -		error("connect() failed: %s (%d)", strerror(-err), -err); -		return err; -	} +	io = bt_io_connect(BT_IO_RFCOMM, rfcomm_connect_cb, iconn, +				NULL, err, +				BT_IO_OPT_SOURCE_BDADDR, &idev->src, +				BT_IO_OPT_DEST_BDADDR, &idev->dst, +				BT_IO_OPT_INVALID); +	if (!io) +		return FALSE; -	return 0; +	g_io_channel_unref(io); + +	return TRUE;  }  static gboolean intr_watch_cb(GIOChannel *chan, GIOCondition cond, gpointer data) @@ -448,11 +456,11 @@ static guint create_watch(int sk, GIOFunc cb, struct input_conn *iconn)  	return id;  } -static gboolean fake_hid_connect(struct input_conn *iconn) +static gboolean fake_hid_connect(struct input_conn *iconn, GError **err)  {  	struct fake_hid *fhid = iconn->fake->priv; -	return fhid->connect(iconn->fake); +	return fhid->connect(iconn->fake, err);  }  static int fake_hid_disconnect(struct input_conn *iconn) @@ -588,8 +596,7 @@ cleanup:  }  static int hidp_add_connection(const struct input_device *idev, -			       const struct input_conn *iconn) -			        +				const struct input_conn *iconn)  {  	struct hidp_connadd_req *req;  	struct fake_hid *fake_hid; @@ -663,23 +670,28 @@ cleanup:  	return err;  } -static void interrupt_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src, -			const bdaddr_t *dst, gpointer user_data) +static void interrupt_connect_cb(GIOChannel *chan, GError *conn_err, +							gpointer user_data)  {  	struct input_conn *iconn = user_data;  	struct input_device *idev = iconn->idev;  	DBusMessage *reply; +	int err; +	const char *err_msg; -	if (err < 0) { -		error("connect(): %s (%d)", strerror(-err), -err); +	if (conn_err) { +		err_msg = conn_err->message;  		goto failed;  	} -	iconn->intr_sk = g_io_channel_unix_get_fd(chan);  	err = hidp_add_connection(idev, iconn); - -	if (err < 0) +	if (err < 0) { +		err_msg = strerror(-err); +		g_io_channel_close(chan);  		goto failed; +	} + +	iconn->intr_sk = g_io_channel_unix_get_fd(chan);  	iconn->intr_watch = create_watch(iconn->intr_sk, intr_watch_cb, iconn);  	iconn->ctrl_watch = create_watch(iconn->ctrl_sk, ctrl_watch_cb, iconn); @@ -690,7 +702,8 @@ static void interrupt_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src,  	goto cleanup;  failed: -	reply = connection_attempt_failed(iconn->pending_connect, -err); +	error("%s", err_msg); +	reply = connection_attempt_failed(iconn->pending_connect, err_msg);  	g_dbus_send_message(idev->conn, reply);  	iconn->intr_sk = -1; @@ -701,34 +714,46 @@ cleanup:  	iconn->pending_connect = NULL;  } -static void control_connect_cb(GIOChannel *chan, int err, const bdaddr_t *src, -			const bdaddr_t *dst, gpointer user_data) +static void control_connect_cb(GIOChannel *chan, GError *conn_err, +							gpointer user_data)  {  	struct input_conn *iconn = user_data;  	struct input_device *idev = iconn->idev;  	DBusMessage *reply; +	GIOChannel *io; +	GError *err = NULL; -	if (err < 0) { -		error("connect(): %s (%d)", strerror(-err), -err); +	if (conn_err) { +		error("%s", conn_err->message); +		reply = connection_attempt_failed(iconn->pending_connect, +							conn_err->message);  		goto failed;  	} -	/* Set HID control channel */ -	iconn->ctrl_sk = g_io_channel_unix_get_fd(chan); -  	/* Connect to the HID interrupt channel */ -	err = bt_l2cap_connect(&idev->src, &idev->dst, L2CAP_PSM_HIDP_INTR, 0, -			interrupt_connect_cb, iconn); -	if (err < 0) { -		error("L2CAP connect failed:%s (%d)", strerror(-err), -err); +	io = bt_io_connect(BT_IO_L2CAP, interrupt_connect_cb, iconn, +				NULL, &err, +				BT_IO_OPT_SOURCE_BDADDR, &idev->src, +				BT_IO_OPT_DEST_BDADDR, &idev->dst, +				BT_IO_OPT_PSM, L2CAP_PSM_HIDP_INTR, +				BT_IO_OPT_INVALID); +	if (!io) { +		error("%s", err->message); +		reply = connection_attempt_failed(iconn->pending_connect, +							err->message); +		g_clear_error(&err); +		g_io_channel_close(chan);  		goto failed;  	} +	g_io_channel_unref(io); + +	/* Set HID control channel */ +	iconn->ctrl_sk = g_io_channel_unix_get_fd(chan); +  	return;  failed: -	iconn->ctrl_sk = -1; -	reply = connection_attempt_failed(iconn->pending_connect, -err);  	g_dbus_send_message(idev->conn, reply);  	dbus_message_unref(iconn->pending_connect);  	iconn->pending_connect = NULL; @@ -873,7 +898,8 @@ static DBusMessage *device_connect(DBusConnection *conn,  	struct input_device *idev = data;  	struct input_conn *iconn;  	struct fake_input *fake; -	int err; +	DBusMessage *reply; +	GError *err = NULL;  	iconn = find_connection(idev->connections, "HID");  	if (!iconn) @@ -888,31 +914,33 @@ static DBusMessage *device_connect(DBusConnection *conn,  	iconn->pending_connect = dbus_message_ref(msg);  	fake = iconn->fake; -	/* Fake input device */  	if (fake) { -		if (fake->connect(iconn) < 0) { -			int err = errno; -			const char *str = strerror(err); -			error("Connect failed: %s(%d)", str, err); -			dbus_message_unref(iconn->pending_connect); -			iconn->pending_connect = NULL; -			return connection_attempt_failed(msg, err); -		} -		fake->flags |= FI_FLAG_CONNECTED; -		return NULL; +		/* Fake input device */ +		if (fake->connect(iconn, &err)) +			fake->flags |= FI_FLAG_CONNECTED; +	} else { +		/* HID devices */ +		GIOChannel *io; + +		io = bt_io_connect(BT_IO_L2CAP, control_connect_cb, iconn, +					NULL, &err, +					BT_IO_OPT_SOURCE_BDADDR, &idev->src, +					BT_IO_OPT_DEST_BDADDR, &idev->dst, +					BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL, +					NULL); +		if (io) +			g_io_channel_unref(io);  	} -	/* HID devices */ -	err = bt_l2cap_connect(&idev->src, &idev->dst, L2CAP_PSM_HIDP_CTRL, -						0, control_connect_cb, iconn); -	if (err < 0) { -		error("L2CAP connect failed: %s(%d)", strerror(-err), -err); -		dbus_message_unref(iconn->pending_connect); -		iconn->pending_connect = NULL; -		return connection_attempt_failed(msg, -err); -	} +	if (err == NULL) +		return NULL; -	return NULL; +	error("%s", err->message); +	dbus_message_unref(iconn->pending_connect); +	iconn->pending_connect = NULL; +	reply = connection_attempt_failed(msg, err->message); +	g_clear_error(&err); +	return reply;  }  static DBusMessage *create_errno_message(DBusMessage *msg, int err) diff --git a/input/device.h b/input/device.h index c65a5d20..cb305d62 100644 --- a/input/device.h +++ b/input/device.h @@ -36,7 +36,7 @@ struct fake_input {  	int		uinput;		/* uinput socket */  	int		rfcomm;		/* RFCOMM socket */  	uint8_t		ch;		/* RFCOMM channel number */ -	gboolean 	(*connect) (struct input_conn *iconn); +	gboolean	(*connect) (struct input_conn *iconn, GError **err);  	int		(*disconnect) (struct input_conn *iconn);  	void		*priv;  }; diff --git a/input/fakehid.c b/input/fakehid.c index 900399d2..077dc21f 100644 --- a/input/fakehid.c +++ b/input/fakehid.c @@ -325,7 +325,7 @@ err:  	return 1;  } -static gboolean fake_hid_common_connect(struct fake_input *fake) +static gboolean fake_hid_common_connect(struct fake_input *fake, GError **err)  {  	return TRUE;  } diff --git a/input/fakehid.h b/input/fakehid.h index ced9ed43..e61a7275 100644 --- a/input/fakehid.h +++ b/input/fakehid.h @@ -27,7 +27,7 @@ struct fake_input;  struct fake_hid {  	uint16_t vendor;  	uint16_t product; -	gboolean (*connect) (struct fake_input *fake_input); +	gboolean (*connect) (struct fake_input *fake_input, GError **err);  	int (*disconnect) (struct fake_input *fake_input);  	gboolean (*event) (GIOChannel *chan, GIOCondition cond, gpointer data);  	int (*setup_uinput) (struct fake_input *fake, struct fake_hid *fake_hid); diff --git a/input/server.c b/input/server.c index 6e9639f0..fdeac6d5 100644 --- a/input/server.c +++ b/input/server.c @@ -36,6 +36,7 @@  #include "logging.h"  #include "glib-helper.h" +#include "btio.h"  #include "adapter.h"  #include "device.h"  #include "server.h" @@ -86,60 +87,76 @@ static int authorize_device(const bdaddr_t *src, const bdaddr_t *dst)  				auth_callback, auth);  } -static void connect_event_cb(GIOChannel *chan, int err, const bdaddr_t *src, -				const bdaddr_t *dst, gpointer data) +static void connect_event_cb(GIOChannel *chan, GError *err, gpointer data)  { -	int sk, psm = GPOINTER_TO_UINT(data); +	int sk, psm; +	bdaddr_t src, dst; +	GError *gerr = NULL; -	if (err < 0) { -		error("accept: %s (%d)", strerror(-err), -err); +	if (err) { +		error("%s", err->message);  		return;  	} -	sk = g_io_channel_unix_get_fd(chan); +	bt_io_get(chan, BT_IO_L2CAP, &gerr, +			BT_IO_OPT_SOURCE_BDADDR, &src, +			BT_IO_OPT_DEST_BDADDR, &dst, +			BT_IO_OPT_PSM, &psm, +			NULL); +	if (gerr) { +		error("%s", gerr->message); +		g_error_free(gerr); +		g_io_channel_close(chan); +		return; +	}  	debug("Incoming connection on PSM %d", psm); -	if (input_device_set_channel(src, dst, psm, sk) < 0) { +	sk = g_io_channel_unix_get_fd(chan); + +	if (input_device_set_channel(&src, &dst, psm, sk) < 0) {  		/* Send unplug virtual cable to unknown devices */  		if (psm == L2CAP_PSM_HIDP_CTRL) {  			unsigned char unplug[] = { 0x15 };  			int err;  			err = write(sk, unplug, sizeof(unplug));  		} -		close(sk); +		g_io_channel_close(chan);  		return;  	} -	if ((psm == L2CAP_PSM_HIDP_INTR) && (authorize_device(src, dst) < 0)) -		input_device_close_channels(src, dst); - -	return; +	if ((psm == L2CAP_PSM_HIDP_INTR) && (authorize_device(&src, &dst) < 0)) +		input_device_close_channels(&src, &dst);  }  int server_start(const bdaddr_t *src)  {  	struct server *server;  	GIOChannel *ctrl_io, *intr_io; +	GError *err = NULL; -	ctrl_io = bt_l2cap_listen(src, L2CAP_PSM_HIDP_CTRL, 0, 0, -				connect_event_cb, -				GUINT_TO_POINTER(L2CAP_PSM_HIDP_CTRL)); +	ctrl_io = bt_io_listen(BT_IO_L2CAP, connect_event_cb, NULL, +				NULL, NULL, &err, +				BT_IO_OPT_SOURCE_BDADDR, src, +				BT_IO_OPT_PSM, L2CAP_PSM_HIDP_CTRL, +				BT_IO_OPT_INVALID);  	if (!ctrl_io) {  		error("Failed to listen on control channel"); +		g_clear_error(&err);  		return -1;  	} -	g_io_channel_set_close_on_unref(ctrl_io, TRUE); -	intr_io = bt_l2cap_listen(src, L2CAP_PSM_HIDP_INTR, 0, 0, -				connect_event_cb, -				GUINT_TO_POINTER(L2CAP_PSM_HIDP_INTR)); +	intr_io = bt_io_listen(BT_IO_L2CAP, connect_event_cb, NULL, +				NULL, NULL, &err, +				BT_IO_OPT_SOURCE_BDADDR, src, +				BT_IO_OPT_PSM, L2CAP_PSM_HIDP_INTR, +				BT_IO_OPT_INVALID);  	if (!intr_io) {  		error("Failed to listen on interrupt channel");  		g_io_channel_unref(ctrl_io); +		g_clear_error(&err);  		return -1;  	} -	g_io_channel_set_close_on_unref(intr_io, TRUE);  	server = g_new0(struct server, 1);  	bacpy(&server->src, src); @@ -162,7 +179,10 @@ void server_stop(const bdaddr_t *src)  	server = l->data; +	g_io_channel_close(server->intr);  	g_io_channel_unref(server->intr); + +	g_io_channel_close(server->ctrl);  	g_io_channel_unref(server->ctrl);  	servers = g_slist_remove(servers, server); | 
