Hi, On Wed, May 28, 2014 at 2:27 PM, Luiz Augusto von Dentz <luiz.dentz@xxxxxxxxx> wrote: > From: Luiz Augusto von Dentz <luiz.von.dentz@xxxxxxxxx> > > --- > android/Android.mk | 1 + > android/Makefile.am | 1 + > android/hidhost.c | 143 ++++++++-------------------------------------------- > 3 files changed, 23 insertions(+), 122 deletions(-) > > diff --git a/android/Android.mk b/android/Android.mk > index afd6e9c..de909d6 100644 > --- a/android/Android.mk > +++ b/android/Android.mk > @@ -54,6 +54,7 @@ LOCAL_SRC_FILES := \ > bluez/src/shared/gatt-db.c \ > bluez/src/shared/io-glib.c \ > bluez/src/shared/crypto.c \ > + bluez/src/shared/uhid.c \ > bluez/src/sdpd-database.c \ > bluez/src/sdpd-service.c \ > bluez/src/sdpd-request.c \ > diff --git a/android/Makefile.am b/android/Makefile.am > index 2d74505..bcaec4c 100644 > --- a/android/Makefile.am > +++ b/android/Makefile.am > @@ -32,6 +32,7 @@ android_bluetoothd_SOURCES = android/main.c \ > src/shared/hfp.h src/shared/hfp.c \ > src/shared/gatt-db.h src/shared/gatt-db.c \ > src/shared/crypto.h src/shared/crypto.c \ > + src/shared/uhid.h src/shared/uhid.c \ > android/bluetooth.h android/bluetooth.c \ > android/hidhost.h android/hidhost.c \ > android/ipc-common.h \ > diff --git a/android/hidhost.c b/android/hidhost.c > index 1758020..4a158c6 100644 > --- a/android/hidhost.c > +++ b/android/hidhost.c > @@ -40,9 +40,9 @@ > #include "lib/sdp_lib.h" > #include "src/shared/mgmt.h" > #include "src/shared/util.h" > +#include "src/shared/uhid.h" > #include "src/sdp-client.h" > #include "src/uuid-helper.h" > -#include "profiles/input/uhid_copy.h" > #include "src/log.h" > > #include "hal-msg.h" > @@ -53,7 +53,6 @@ > > #define L2CAP_PSM_HIDP_CTRL 0x11 > #define L2CAP_PSM_HIDP_INTR 0x13 > -#define UHID_DEVICE_FILE "/dev/uhid" > > /* HID message types */ > #define HID_MSG_CONTROL 0x10 > @@ -101,8 +100,7 @@ struct hid_device { > GIOChannel *intr_io; > guint ctrl_watch; > guint intr_watch; > - int uhid_fd; > - guint uhid_watch_id; > + struct bt_uhid *uhid; > uint8_t last_hid_msg; > }; > > @@ -114,21 +112,6 @@ static int device_cmp(gconstpointer s, gconstpointer user_data) > return bacmp(&dev->dst, dst); > } > > -static void uhid_destroy(int fd) > -{ > - struct uhid_event ev; > - > - /* destroy uHID device */ > - memset(&ev, 0, sizeof(ev)); > - ev.type = UHID_DESTROY; > - > - if (write(fd, &ev, sizeof(ev)) < 0) > - error("hidhost: Failed to destroy uHID device: %s (%d)", > - strerror(errno), errno); > - > - close(fd); > -} > - > static void hid_device_free(void *data) > { > struct hid_device *dev = data; > @@ -145,13 +128,8 @@ static void hid_device_free(void *data) > if (dev->ctrl_io) > g_io_channel_unref(dev->ctrl_io); > > - if (dev->uhid_watch_id) { > - g_source_remove(dev->uhid_watch_id); > - dev->uhid_watch_id = 0; > - } > - > - if (dev->uhid_fd > 0) > - uhid_destroy(dev->uhid_fd); > + if (dev->uhid) > + bt_uhid_unref(dev->uhid); > > g_free(dev->rd_data); > g_free(dev); > @@ -196,9 +174,10 @@ static bool hex2buf(const uint8_t *hex, uint8_t *buf, int buf_size) > return true; > } > > -static void handle_uhid_output(struct hid_device *dev, > - struct uhid_output_req *output) > +static void handle_uhid_output(struct uhid_event *event, void *user_data) > { > + struct uhid_output_req *output = &event->u.output; > + struct hid_device *dev = user_data; > int fd, req_size; > uint8_t *req; > > @@ -222,87 +201,15 @@ static void handle_uhid_output(struct hid_device *dev, > free(req); > } > > -static gboolean uhid_event_cb(GIOChannel *io, GIOCondition cond, > - gpointer user_data) > -{ > - struct hid_device *dev = user_data; > - struct uhid_event ev; > - ssize_t bread; > - int fd; > - > - DBG(""); > - > - if (cond & (G_IO_ERR | G_IO_NVAL)) > - goto failed; > - > - fd = g_io_channel_unix_get_fd(io); > - memset(&ev, 0, sizeof(ev)); > - > - bread = read(fd, &ev, sizeof(ev)); > - if (bread < 0) { > - DBG("read: %s (%d)", strerror(errno), errno); > - goto failed; > - } > - > - DBG("uHID event type %d received", ev.type); > - > - switch (ev.type) { > - case UHID_START: > - case UHID_STOP: > - /* > - * These are called to start and stop the underlying hardware. > - * We open the channels before creating the device so the > - * hardware is always ready. No need to handle these. > - * The kernel never destroys a device itself! Only an explicit > - * UHID_DESTROY request can remove a device. > - */ > - break; > - case UHID_OPEN: > - case UHID_CLOSE: > - /* > - * OPEN/CLOSE are sent whenever user-space opens any interface > - * provided by the kernel HID device. Whenever the open-count > - * is non-zero we must be ready for I/O. As long as it is zero, > - * we can decide to drop all I/O and put the device > - * asleep This is optional, though. > - */ > - break; > - case UHID_OUTPUT: > - handle_uhid_output(dev, &ev.u.output); > - break; > - case UHID_FEATURE: > - /* TODO */ > - break; > - case UHID_OUTPUT_EV: > - /* > - * This is only sent by kernels prior to linux-3.11. It > - * requires us to parse HID-descriptors in user-space to > - * properly handle it. This is redundant as the kernel > - * does it already. That's why newer kernels assemble > - * the output-reports and send it to us via UHID_OUTPUT. > - */ > - DBG("UHID_OUTPUT_EV unsupported"); > - break; > - default: > - warn("unexpected uHID event"); > - } > - > - return TRUE; > - > -failed: > - dev->uhid_watch_id = 0; > - return FALSE; > -} > - > static gboolean intr_io_watch_cb(GIOChannel *chan, gpointer data) > { > struct hid_device *dev = data; > uint8_t buf[UHID_DATA_MAX]; > struct uhid_event ev; > - int fd, bread; > + int fd, bread, err; > > /* Wait uHID if not ready */ > - if (dev->uhid_fd < 0) > + if (!dev->uhid) > return TRUE; > > fd = g_io_channel_unix_get_fd(chan); > @@ -323,8 +230,9 @@ static gboolean intr_io_watch_cb(GIOChannel *chan, gpointer data) > ev.u.input.size = bread - 1; > memcpy(ev.u.input.data, &buf[1], ev.u.input.size); > > - if (write(dev->uhid_fd, &ev, sizeof(ev)) < 0) > - DBG("uhid write: %s (%d)", strerror(errno), errno); > + err = bt_uhid_send(dev->uhid, &ev); > + if (err < 0) > + DBG("bt_uhid_send: %s (%d)", strerror(-err), -err); > > return TRUE; > } > @@ -571,16 +479,13 @@ static void bt_hid_set_info(struct hid_device *dev) > > static int uhid_create(struct hid_device *dev) > { > - GIOCondition cond = G_IO_IN | G_IO_ERR | G_IO_NVAL; > struct uhid_event ev; > - GIOChannel *io; > int err; > > - dev->uhid_fd = open(UHID_DEVICE_FILE, O_RDWR | O_CLOEXEC); > - if (dev->uhid_fd < 0) { > + dev->uhid = bt_uhid_new_default(); > + if (!dev->uhid) { > err = -errno; > - error("hidhost: Failed to open uHID device: %s", > - strerror(errno)); > + error("hidhost: Failed to create bt_uhid instance"); > return err; > } > > @@ -595,20 +500,16 @@ static int uhid_create(struct hid_device *dev) > ev.u.create.rd_size = dev->rd_size; > ev.u.create.rd_data = dev->rd_data; > > - if (write(dev->uhid_fd, &ev, sizeof(ev)) < 0) { > - err = -errno; > + err = bt_uhid_send(dev->uhid, &ev); > + if (err < 0) { > error("hidhost: Failed to create uHID device: %s", > - strerror(errno)); > - close(dev->uhid_fd); > - dev->uhid_fd = -1; > + strerror(-err)); > + bt_uhid_unref(dev->uhid); > + dev->uhid = NULL; > return err; > } > > - io = g_io_channel_unix_new(dev->uhid_fd); > - g_io_channel_set_encoding(io, NULL, NULL); > - dev->uhid_watch_id = g_io_add_watch(io, cond, uhid_event_cb, dev); > - g_io_channel_unref(io); > - > + bt_uhid_register(dev->uhid, UHID_OUTPUT, handle_uhid_output, dev); > bt_hid_set_info(dev); > > return 0; > @@ -843,7 +744,6 @@ static void bt_hid_connect(const void *buf, uint16_t len) > > dev = g_new0(struct hid_device, 1); > bacpy(&dev->dst, &dst); > - dev->uhid_fd = -1; > > ba2str(&dev->dst, addr); > DBG("connecting to %s", addr); > @@ -1361,7 +1261,6 @@ static void connect_cb(GIOChannel *chan, GError *err, gpointer user_data) > dev = g_new0(struct hid_device, 1); > bacpy(&dev->dst, &dst); > dev->ctrl_io = g_io_channel_ref(chan); > - dev->uhid_fd = -1; > > sdp_uuid16_create(&uuid, PNP_INFO_SVCLASS_ID); > if (bt_search_service(&adapter_addr, &dev->dst, &uuid, > -- > 1.9.0 Pushed. -- Luiz Augusto von Dentz -- To unsubscribe from this list: send the line "unsubscribe linux-bluetooth" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html