Re: [PATCH BlueZ 1/2] android/hidhost: Rework uHID code to use bt_uhid

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



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




[Index of Archives]     [Bluez Devel]     [Linux Wireless Networking]     [Linux Wireless Personal Area Networking]     [Linux ATH6KL]     [Linux USB Devel]     [Linux Media Drivers]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Big List of Linux Books]

  Powered by Linux