diff options
author | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2007-01-23 17:29:52 +0000 |
---|---|---|
committer | Claudio Takahasi <claudio.takahasi@openbossa.org> | 2007-01-23 17:29:52 +0000 |
commit | 706b8b6df5e924d72caac5d477ca1fa4a6b1d794 (patch) | |
tree | 5abc393703303a1dad479d850044acc724056694 /input/input-service.c | |
parent | 03ebdf91be3d0652e27c2813ee37b43bb29f9411 (diff) |
Added L2CAP HID interrupt channel connect callback
Diffstat (limited to 'input/input-service.c')
-rw-r--r-- | input/input-service.c | 60 |
1 files changed, 58 insertions, 2 deletions
diff --git a/input/input-service.c b/input/input-service.c index cc6a05c5..11572c03 100644 --- a/input/input-service.c +++ b/input/input-service.c @@ -29,7 +29,10 @@ #include <errno.h> #include <unistd.h> #include <fcntl.h> - +#include <sys/stat.h> +#include <sys/ioctl.h> +#include <sys/socket.h> + #include <bluetooth/bluetooth.h> #include <bluetooth/hci.h> #include <bluetooth/hci_lib.h> @@ -505,7 +508,60 @@ failed: static gboolean interrupt_connect_cb(GIOChannel *chan, GIOCondition cond, struct pending_connect *pc) { - info("FIXME: interrupt connect callback"); + struct input_device *idev; + int ctl, ret, err = EHOSTDOWN, isk = -1; + socklen_t len; + const char *path; + + path = dbus_message_get_path(pc->msg); + dbus_connection_get_object_path_data(pc->conn, path, (void *) &idev); + + if (cond & G_IO_NVAL) + goto failed; + + isk = g_io_channel_unix_get_fd(chan); + idev->hidp.intr_sock = isk; + + len = sizeof(ret); + if (getsockopt(isk, SOL_SOCKET, SO_ERROR, &ret, &len) < 0) { + err = errno; + error("getsockopt(SO_ERROR): %s (%d)", strerror(err), err); + goto failed; + } + + if (ret != 0) { + err = ret; + error("connect(): %s (%d)", strerror(ret), ret); + goto failed; + } + + ctl = socket(AF_BLUETOOTH, SOCK_RAW, BTPROTO_HIDP); + if (ctl < 0) { + err = errno; + error("Can't open HIDP control socket"); + goto failed; + } + if (ioctl(ctl, HIDPCONNADD, &idev->hidp) < 0) { + err = errno; + close(ctl); + goto failed; + } + close(ctl); + + send_message_and_unref(pc->conn, + dbus_message_new_method_return(pc->msg)); + + pending_connect_free(pc); + + return FALSE; +failed: + if (isk > 0) + close(isk); + + idev->hidp.intr_sock = -1; + err_connection_failed(pc->conn, pc->msg, strerror(err)); + pending_connect_free(pc); + return FALSE; } |