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/device.c | |
parent | 56fe087dfc68f56d84ac41ca390c8a0dc7438e2d (diff) |
Make input plugin to use BtIO API.
Diffstat (limited to 'input/device.c')
-rw-r--r-- | input/device.c | 158 |
1 files changed, 93 insertions, 65 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) |