diff options
author | mav <mav@FreeBSD.org> | 2011-09-28 14:52:25 +0000 |
---|---|---|
committer | mav <mav@FreeBSD.org> | 2011-09-28 14:52:25 +0000 |
commit | 3a1a19715027c5c03af47ff8d3ce06461e3b4d65 (patch) | |
tree | ed5b81a92c39c4c34a4ab0631b21d7f1764a740f /lib/libusbhid | |
parent | 3383aff65a84084093f4575d6098fac891dcbab9 (diff) | |
download | FreeBSD-src-3a1a19715027c5c03af47ff8d3ce06461e3b4d65.zip FreeBSD-src-3a1a19715027c5c03af47ff8d3ce06461e3b4d65.tar.gz |
MFprojects/hid:
Import the rest of HID improvements from the branch:
- improve report descriptor parser in libusbhid to handle several kinds of
reports same time;
- add to the libusbhid API two functions wrapping respective kernel IOCTLs
for reading and writing reports;
- tune uhid IOCTL interface to allow reading and writing arbitrary report,
when multiple supported by the device;
- teach usbhidctl to set output and feature reports;
- make usbhidaction support all the same item names as bhidctl.
Sponsored by: iXsystems, inc.
Diffstat (limited to 'lib/libusbhid')
-rw-r--r-- | lib/libusbhid/data.c | 27 | ||||
-rw-r--r-- | lib/libusbhid/parse.c | 26 | ||||
-rw-r--r-- | lib/libusbhid/usbhid.3 | 16 | ||||
-rw-r--r-- | lib/libusbhid/usbhid.h | 5 |
4 files changed, 61 insertions, 13 deletions
diff --git a/lib/libusbhid/data.c b/lib/libusbhid/data.c index 3b90ac6..f607737 100644 --- a/lib/libusbhid/data.c +++ b/lib/libusbhid/data.c @@ -32,7 +32,10 @@ __FBSDID("$FreeBSD$"); #include <sys/param.h> #include <assert.h> #include <stdlib.h> +#include <string.h> +#include <dev/usb/usb_ioctl.h> #include "usbhid.h" +#include "usbvar.h" int32_t hid_get_data(const void *p, const hid_item_t *h) @@ -114,3 +117,27 @@ hid_set_data(void *p, const hid_item_t *h, int32_t data) buf[offs + i] = (buf[offs + i] & (mask >> (i*8))) | ((data >> (i*8)) & 0xff); } + +int +hid_get_report(int fd, enum hid_kind k, unsigned char *data, unsigned int size) +{ + struct usb_gen_descriptor ugd; + + memset(&ugd, 0, sizeof(ugd)); + ugd.ugd_data = hid_pass_ptr(data); + ugd.ugd_maxlen = size; + ugd.ugd_report_type = k + 1; + return (ioctl(fd, USB_GET_REPORT, &ugd)); +} + +int +hid_set_report(int fd, enum hid_kind k, unsigned char *data, unsigned int size) +{ + struct usb_gen_descriptor ugd; + + memset(&ugd, 0, sizeof(ugd)); + ugd.ugd_data = hid_pass_ptr(data); + ugd.ugd_maxlen = size; + ugd.ugd_report_type = k + 1; + return (ioctl(fd, USB_SET_REPORT, &ugd)); +} diff --git a/lib/libusbhid/parse.c b/lib/libusbhid/parse.c index d2b49d4..f7c2cb1 100644 --- a/lib/libusbhid/parse.c +++ b/lib/libusbhid/parse.c @@ -43,10 +43,11 @@ __FBSDID("$FreeBSD$"); #define MAXUSAGE 100 #define MAXPUSH 4 #define MAXID 64 +#define ITEMTYPES 3 struct hid_pos_data { int32_t rid; - uint32_t pos; + uint32_t pos[ITEMTYPES]; }; struct hid_data { @@ -55,6 +56,7 @@ struct hid_data { const uint8_t *p; struct hid_item cur[MAXPUSH]; struct hid_pos_data last_pos[MAXID]; + uint32_t pos[ITEMTYPES]; int32_t usages_min[MAXUSAGE]; int32_t usages_max[MAXUSAGE]; int32_t usage_last; /* last seen usage */ @@ -92,7 +94,7 @@ hid_clear_local(hid_item_t *c) static void hid_switch_rid(struct hid_data *s, struct hid_item *c, int32_t next_rID) { - uint8_t i; + uint8_t i, j; /* check for same report ID - optimise */ @@ -113,7 +115,8 @@ hid_switch_rid(struct hid_data *s, struct hid_item *c, int32_t next_rID) } if (i != MAXID) { s->last_pos[i].rid = c->report_ID; - s->last_pos[i].pos = c->pos; + for (j = 0; j < ITEMTYPES; j++) + s->last_pos[i].pos[j] = s->pos[j]; } /* store next report ID */ @@ -134,9 +137,12 @@ hid_switch_rid(struct hid_data *s, struct hid_item *c, int32_t next_rID) } if (i != MAXID) { s->last_pos[i].rid = next_rID; - c->pos = s->last_pos[i].pos; - } else - c->pos = 0; /* Out of RID entries. */ + for (j = 0; j < ITEMTYPES; j++) + s->pos[j] = s->last_pos[i].pos[j]; + } else { + for (j = 0; j < ITEMTYPES; j++) + s->pos[j] = 0; /* Out of RID entries. */ + } } /*------------------------------------------------------------------------* @@ -206,7 +212,6 @@ hid_get_item(hid_data_t s, hid_item_t *h) { hid_item_t *c; unsigned int bTag, bType, bSize; - uint32_t oldpos; int32_t mask; int32_t dval; @@ -240,7 +245,8 @@ hid_get_item(hid_data_t s, hid_item_t *h) */ if (s->kindset & (1 << c->kind)) { *h = *c; - c->pos += c->report_size * c->report_count; + h->pos = s->pos[c->kind]; + s->pos[c->kind] += c->report_size * c->report_count; return (1); } } @@ -406,14 +412,10 @@ hid_get_item(hid_data_t s, hid_item_t *h) case 11: /* Pop */ s->pushlevel --; if (s->pushlevel < MAXPUSH) { - /* preserve position */ - oldpos = c->pos; c = &s->cur[s->pushlevel]; /* restore size and count */ s->loc_size = c->report_size; s->loc_count = c->report_count; - /* set default item location */ - c->pos = oldpos; c->report_size = 0; c->report_count = 0; } diff --git a/lib/libusbhid/usbhid.3 b/lib/libusbhid/usbhid.3 index b4951f2..c34a109 100644 --- a/lib/libusbhid/usbhid.3 +++ b/lib/libusbhid/usbhid.3 @@ -44,7 +44,9 @@ .Nm hid_usage_in_page , .Nm hid_init , .Nm hid_get_data , -.Nm hid_set_data +.Nm hid_set_data , +.Nm hid_get_report , +.Nm hid_set_report .Nd USB HID access routines .Sh LIBRARY .Lb libusbhid @@ -84,6 +86,10 @@ .Fn hid_get_data "const void *data" "const hid_item_t *h" .Ft void .Fn hid_set_data "void *buf" "const hid_item_t *h" "int data" +.Ft int +.Fn hid_get_report "int fd" "enum hid_kind k" "unsigned char *data" "unsigned int size" +.Ft int +.Fn hid_set_report "int fd" "enum hid_kind k" "unsigned char *data" "unsigned int size" .Sh DESCRIPTION The .Nm @@ -105,6 +111,14 @@ Synchronous HID operation can be enabled or disabled by a call to If the second argument is zero synchronous HID operation is disabled. Else synchronous HID operation is enabled. The function returns a negative value on failure. +.Pp +.Fn hid_get_report +and +.Fn hid_set_report +functions allow to synchronously get and set specific report if device +supports it. +For devices with multiple report IDs, wanted ID should be provided in the +first byte of the buffer for both get and set. .Ss Descriptor Functions The report descriptor ID can be obtained by calling .Fn hid_get_report_id . diff --git a/lib/libusbhid/usbhid.h b/lib/libusbhid/usbhid.h index 5e098ea..231ee1f 100644 --- a/lib/libusbhid/usbhid.h +++ b/lib/libusbhid/usbhid.h @@ -76,6 +76,7 @@ typedef struct hid_item { #define HID_PAGE(u) (((u) >> 16) & 0xffff) #define HID_USAGE(u) ((u) & 0xffff) +#define HID_HAS_GET_SET_REPORT 1 __BEGIN_DECLS @@ -104,5 +105,9 @@ int hid_parse_usage_page(const char *name); /* Extracting/insertion of data, data.c: */ int32_t hid_get_data(const void *p, const hid_item_t *h); void hid_set_data(void *p, const hid_item_t *h, int32_t data); +int hid_get_report(int fd, enum hid_kind k, + unsigned char *data, unsigned int size); +int hid_set_report(int fd, enum hid_kind k, + unsigned char *data, unsigned int size); __END_DECLS |