diff --git a/lib/libusb/Makefile b/lib/libusb/Makefile new file mode 100644 index 000000000000..fddc4aad1d3b --- /dev/null +++ b/lib/libusb/Makefile @@ -0,0 +1,24 @@ +# $NetBSD: Makefile,v 1.5 1999/07/23 09:44:38 mrg Exp $ +# $FreeBSD$ + +MAINTAINER= n_hibma@FreeBSD.ORG + +LIB= usb +MAN3= usb.3 + +SHLIB_MAJOR= 0 +SHLIB_MINOR= 0 + +MLINKS= usb.3 libusb.3 usb.3 hid_get_report_desc.3 \ + usb.3 hid_dispose_report_desc.3 \ + usb.3 hid_start_parse.3 usb.3 hid_end_parse.3 \ + usb.3 hid_get_item.3 usb.3 hid_report_size.3 usb.3 hid_locate.3 \ + usb.3 hid_usage_page.3 usb.3 hid_usage_in_page.3 usb.3 hid_init.3 \ + usb.3 hid_get_data.3 usb.3 hid_set_data.3 + +SRCS= descr.c parse.c usage.c data.c + +INCS= libusb.h + +.include + diff --git a/lib/libusb/data.c b/lib/libusb/data.c new file mode 100644 index 000000000000..26b33b39b9cc --- /dev/null +++ b/lib/libusb/data.c @@ -0,0 +1,99 @@ +/* $NetBSD: data.c,v 1.8 2000/04/02 11:10:53 augustss Exp $ */ + +/* + * Copyright (c) 1999 Lennart Augustsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include +#include "libusb.h" + +int +hid_get_data(const void *p, const hid_item_t *h) +{ + const unsigned char *buf; + unsigned int hpos; + unsigned int hsize; + int data; + int i, end, offs; + + _DIAGASSERT(p != NULL); + _DIAGASSERT(h != NULL); + + buf = p; + hpos = h->pos; /* bit position of data */ + hsize = h->report_size; /* bit length of data */ + + if (hsize == 0) + return (0); + offs = hpos / 8; + end = (hpos + hsize) / 8 - offs; + data = 0; + for (i = 0; i <= end; i++) + data |= buf[offs + i] << (i*8); + data >>= hpos % 8; + data &= (1 << hsize) - 1; + if (h->logical_minimum < 0) { + /* Need to sign extend */ + hsize = sizeof data * 8 - hsize; + data = (data << hsize) >> hsize; + } + return (data); +} + +void +hid_set_data(void *p, const hid_item_t *h, int data) +{ + unsigned char *buf; + unsigned int hpos; + unsigned int hsize; + int i, end, offs, mask; + + _DIAGASSERT(p != NULL); + _DIAGASSERT(h != NULL); + + buf = p; + hpos = h->pos; /* bit position of data */ + hsize = h->report_size; /* bit length of data */ + + if (hsize != 32) { + mask = (1 << hsize) - 1; + data &= mask; + } else + mask = ~0; + + data <<= (hpos % 8); + mask <<= (hpos % 8); + mask = ~mask; + + offs = hpos / 8; + end = (hpos + hsize) / 8 - offs; + + for (i = 0; i <= end; i++) + buf[offs + i] = (buf[offs + i] & (mask >> (i*8))) | + ((data >> (i*8)) & 0xff); +} diff --git a/lib/libusb/descr.c b/lib/libusb/descr.c new file mode 100644 index 000000000000..17b607e60c16 --- /dev/null +++ b/lib/libusb/descr.c @@ -0,0 +1,75 @@ +/* $NetBSD: descr.c,v 1.7 1999/10/13 17:48:04 drochner Exp $ */ + +/* + * Copyright (c) 1999 Lennart Augustsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "libusb.h" +#include "usbvar.h" + +report_desc_t +hid_get_report_desc(fd) + int fd; +{ + struct usb_ctl_report_desc rep; + report_desc_t r; + + _DIAGASSERT(fd != -1); + + rep.size = 0; + if (ioctl(fd, USB_GET_REPORT_DESC, &rep) < 0) + return (0); + r = malloc(sizeof *r + rep.size); + if (r == 0) { + errno = ENOMEM; + return (0); + } + r->size = rep.size; + memcpy(r->data, rep.data, (unsigned int)rep.size); + return (r); +} + +void +hid_dispose_report_desc(r) + report_desc_t r; +{ + + free(r); +} diff --git a/lib/libusb/libusb.h b/lib/libusb/libusb.h new file mode 100644 index 000000000000..65b996fc7fde --- /dev/null +++ b/lib/libusb/libusb.h @@ -0,0 +1,96 @@ +/* $NetBSD: usb.h,v 1.7 2000/04/02 11:10:53 augustss Exp $ */ + +/* + * Copyright (c) 1999 Lennart Augustsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * + */ + +typedef struct report_desc *report_desc_t; + +typedef struct hid_data *hid_data_t; + +typedef enum hid_kind { + hid_input, hid_output, hid_feature, hid_collection, hid_endcollection +}hid_kind_t; + +typedef struct hid_item { + /* Global */ + int _usage_page; + int logical_minimum; + int logical_maximum; + int physical_minimum; + int physical_maximum; + int unit_exponent; + int unit; + int report_size; + int report_ID; +#define NO_REPORT_ID 0 + int report_count; + /* Local */ + unsigned int usage; + int usage_minimum; + int usage_maximum; + int designator_index; + int designator_minimum; + int designator_maximum; + int string_index; + int string_minimum; + int string_maximum; + int set_delimiter; + /* Misc */ + int collection; + int collevel; + enum hid_kind kind; + unsigned int flags; + /* Absolute data position (bits) */ + unsigned int pos; + /* */ + struct hid_item *next; +} hid_item_t; + +#define HID_PAGE(u) ((u) >> 16) +#define HID_USAGE(u) ((u) & 0xffff) + +/* Obtaining a report descriptor, descr.c: */ +report_desc_t hid_get_report_desc __P((int file)); +void hid_dispose_report_desc __P((report_desc_t)); + +/* Parsing of a HID report descriptor, parse.c: */ +hid_data_t hid_start_parse __P((report_desc_t d, int kindset)); +void hid_end_parse __P((hid_data_t s)); +int hid_get_item __P((hid_data_t s, hid_item_t *h)); +int hid_report_size __P((report_desc_t d, enum hid_kind k, int *idp)); +int hid_locate __P((report_desc_t d, unsigned int usage, enum hid_kind k, hid_item_t *h)); + +/* Conversion to/from usage names, usage.c: */ +const char *hid_usage_page __P((int i)); +const char *hid_usage_in_page __P((unsigned int u)); +void hid_init __P((const char *file)); + +/* Extracting/insertion of data, data.c: */ +int hid_get_data __P((const void *p, const hid_item_t *h)); +void hid_set_data __P((void *p, const hid_item_t *h, int data)); diff --git a/lib/libusb/parse.c b/lib/libusb/parse.c new file mode 100644 index 000000000000..79af687d7434 --- /dev/null +++ b/lib/libusb/parse.c @@ -0,0 +1,405 @@ +/* $NetBSD: parse.c,v 1.9 2000/03/17 18:09:17 augustss Exp $ */ + +/* + * Copyright (c) 1999 Lennart Augustsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * + */ + +#include +#include +#include +#include + +#include +#include + +#include "libusb.h" +#include "usbvar.h" + +#define MAXUSAGE 100 +struct hid_data { + u_char *start; + u_char *end; + u_char *p; + hid_item_t cur; + unsigned int usages[MAXUSAGE]; + int nusage; + int minset; + int multi; + int multimax; + int kindset; +}; + +static int min(int x, int y) { return x < y ? x : y; } + +static void +hid_clear_local(hid_item_t *c) +{ + + _DIAGASSERT(c != NULL); + + c->usage = 0; + c->usage_minimum = 0; + c->usage_maximum = 0; + c->designator_index = 0; + c->designator_minimum = 0; + c->designator_maximum = 0; + c->string_index = 0; + c->string_minimum = 0; + c->string_maximum = 0; + c->set_delimiter = 0; +} + +hid_data_t +hid_start_parse(report_desc_t d, int kindset) +{ + struct hid_data *s; + + _DIAGASSERT(d != NULL); + + s = malloc(sizeof *s); + memset(s, 0, sizeof *s); + s->start = s->p = d->data; + s->end = d->data + d->size; + s->kindset = kindset; + return (s); +} + +void +hid_end_parse(hid_data_t s) +{ + + _DIAGASSERT(s != NULL); + + while (s->cur.next) { + hid_item_t *hi = s->cur.next->next; + free(s->cur.next); + s->cur.next = hi; + } + free(s); +} + +int +hid_get_item(hid_data_t s, hid_item_t *h) +{ + hid_item_t *c; + unsigned int bTag = 0, bType = 0, bSize, oldpos; + unsigned char *data; + int dval; + unsigned char *p; + hid_item_t *hi; + int i; + + _DIAGASSERT(s != NULL); + _DIAGASSERT(h != NULL); + + c = &s->cur; + + top: + if (s->multimax) { + if (s->multi < s->multimax) { + c->usage = s->usages[min(s->multi, s->nusage-1)]; + s->multi++; + *h = *c; + c->pos += c->report_size; + h->next = 0; + return (1); + } else { + c->report_count = s->multimax; + s->multimax = 0; + s->nusage = 0; + hid_clear_local(c); + } + } + for (;;) { + p = s->p; + if (p >= s->end) + return (0); + + bSize = *p++; + if (bSize == 0xfe) { + /* long item */ + bSize = *p++; + bSize |= *p++ << 8; + bTag = *p++; + data = p; + p += bSize; + } else { + /* short item */ + bTag = bSize >> 4; + bType = (bSize >> 2) & 3; + bSize &= 3; + if (bSize == 3) bSize = 4; + data = p; + p += bSize; + } + s->p = p; + /* + * The spec is unclear if the data is signed or unsigned. + */ + switch(bSize) { + case 0: + dval = 0; + break; + case 1: + dval = (int8_t)*data++; + break; + case 2: + dval = *data++; + dval |= *data++ << 8; + dval = (int16_t)dval; + break; + case 4: + dval = *data++; + dval |= *data++ << 8; + dval |= *data++ << 16; + dval |= *data++ << 24; + break; + default: + return (-1); + } + + switch (bType) { + case 0: /* Main */ + switch (bTag) { + case 8: /* Input */ + if (!(s->kindset & (1 << hid_input))) + continue; + c->kind = hid_input; + c->flags = dval; + ret: + if (c->flags & HIO_VARIABLE) { + s->multimax = c->report_count; + s->multi = 0; + c->report_count = 1; + if (s->minset) { + for (i = c->usage_minimum; + i <= c->usage_maximum; + i++) { + s->usages[s->nusage] = i; + if (s->nusage < MAXUSAGE-1) + s->nusage++; + } + s->minset = 0; + } + goto top; + } else { + if (s->minset) + c->usage = c->usage_minimum; + *h = *c; + h->next = 0; + c->pos += c->report_size * c->report_count; + hid_clear_local(c); + s->minset = 0; + return (1); + } + case 9: /* Output */ + if (!(s->kindset & (1 << hid_output))) + continue; + c->kind = hid_output; + c->flags = dval; + goto ret; + case 10: /* Collection */ + c->kind = hid_collection; + c->collection = dval; + c->collevel++; + *h = *c; + hid_clear_local(c); + c->report_ID = NO_REPORT_ID; + s->nusage = 0; + return (1); + case 11: /* Feature */ + if (!(s->kindset & (1 << hid_feature))) + continue; + c->kind = hid_feature; + c->flags = dval; + goto ret; + case 12: /* End collection */ + c->kind = hid_endcollection; + c->collevel--; + *h = *c; + /*hid_clear_local(c);*/ + s->nusage = 0; + return (1); + default: + return (-2); + } + + case 1: /* Global */ + switch (bTag) { + case 0: + c->_usage_page = dval << 16; + break; + case 1: + c->logical_minimum = dval; + break; + case 2: + c->logical_maximum = dval; + break; + case 3: + c->physical_maximum = dval; + break; + case 4: + c->physical_maximum = dval; + break; + case 5: + c->unit_exponent = dval; + break; + case 6: + c->unit = dval; + break; + case 7: + c->report_size = dval; + break; + case 8: + c->report_ID = dval; + break; + case 9: + c->report_count = dval; + break; + case 10: /* Push */ + hi = malloc(sizeof *hi); + *hi = s->cur; + c->next = hi; + break; + case 11: /* Pop */ + hi = c->next; + oldpos = c->pos; + s->cur = *hi; + c->pos = oldpos; + free(hi); + break; + default: + return (-3); + } + break; + case 2: /* Local */ + switch (bTag) { + case 0: + if (bSize == 1) + dval = c->_usage_page | (dval&0xff); + else if (bSize == 2) + dval = c->_usage_page | (dval&0xffff); + c->usage = dval; + if (s->nusage < MAXUSAGE) + s->usages[s->nusage++] = dval; + /* else XXX */ + break; + case 1: + s->minset = 1; + if (bSize == 1) + dval = c->_usage_page | (dval&0xff); + else if (bSize == 2) + dval = c->_usage_page | (dval&0xffff); + c->usage_minimum = dval; + break; + case 2: + if (bSize == 1) + dval = c->_usage_page | (dval&0xff); + else if (bSize == 2) + dval = c->_usage_page | (dval&0xffff); + c->usage_maximum = dval; + break; + case 3: + c->designator_index = dval; + break; + case 4: + c->designator_minimum = dval; + break; + case 5: + c->designator_maximum = dval; + break; + case 7: + c->string_index = dval; + break; + case 8: + c->string_minimum = dval; + break; + case 9: + c->string_maximum = dval; + break; + case 10: + c->set_delimiter = dval; + break; + default: + return (-4); + } + break; + default: + return (-5); + } + } +} + +int +hid_report_size(report_desc_t r, enum hid_kind k, int *idp) +{ + struct hid_data *d; + hid_item_t h; + int size, id; + + _DIAGASSERT(r != NULL); + /* idp may be NULL */ + + id = 0; + if (idp) + *idp = 0; + memset(&h, 0, sizeof h); + for (d = hid_start_parse(r, 1<kind == k && !(h->flags & HIO_CONST) && h->usage == u) { + hid_end_parse(d); + return (1); + } + } + hid_end_parse(d); + h->report_size = 0; + return (0); +} diff --git a/lib/libusb/usage.c b/lib/libusb/usage.c new file mode 100644 index 000000000000..afb990a93ccd --- /dev/null +++ b/lib/libusb/usage.c @@ -0,0 +1,197 @@ +/* $NetBSD: usage.c,v 1.5 2000/04/02 11:10:53 augustss Exp $ */ + +/* + * Copyright (c) 1999 Lennart Augustsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * + */ + +#include +#include +#include +#include +#include + +#include "libusb.h" + +#define _PATH_HIDTABLE "/usr/share/misc/usb_hid_usages" + +struct usage_in_page { + const char *name; + int usage; +}; + +static struct usage_page { + const char *name; + int usage; + struct usage_in_page *page_contents; + int pagesize, pagesizemax; +} *pages; +static int npages, npagesmax; + +#ifdef DEBUG +void +dump_hid_table(void) +{ + int i, j; + + for (i = 0; i < npages; i++) { + printf("%d\t%s\n", pages[i].usage, pages[i].name); + for (j = 0; j < pages[i].pagesize; j++) { + printf("\t%d\t%s\n", pages[i].page_contents[j].usage, + pages[i].page_contents[j].name); + } + } +} +#endif + +void +hid_init(const char *hidname) +{ + FILE *f; + char line[100], name[100], *p, *n; + int no; + int lineno; + struct usage_page *curpage = 0; + + if (hidname == 0) + hidname = _PATH_HIDTABLE; + + f = fopen(hidname, "r"); + if (f == NULL) + err(1, "%s", hidname); + for (lineno = 1; ; lineno++) { + if (fgets(line, sizeof line, f) == NULL) + break; + if (line[0] == '#') + continue; + for (p = line; *p && isspace(*p); p++) + ; + if (!*p) + continue; + if (sscanf(line, " * %[^\n]", name) == 1) + no = -1; + else if (sscanf(line, " 0x%x %[^\n]", &no, name) != 2 && + sscanf(line, " %d %[^\n]", &no, name) != 2) + errx(1, "file %s, line %d, syntax error\n", + hidname, lineno); + for (p = name; *p; p++) + if (isspace(*p) || *p == '.') + *p = '_'; + n = strdup(name); + if (!n) + err(1, "strdup"); + if (isspace(line[0])) { + if (!curpage) + errx(1, "file %s, line %d, syntax error\n", + hidname, lineno); + if (curpage->pagesize >= curpage->pagesizemax) { + curpage->pagesizemax += 10; + curpage->page_contents = + realloc(curpage->page_contents, + curpage->pagesizemax * + sizeof (struct usage_in_page)); + if (!curpage->page_contents) + err(1, "realloc"); + } + curpage->page_contents[curpage->pagesize].name = n; + curpage->page_contents[curpage->pagesize].usage = no; + curpage->pagesize++; + } else { + if (npages >= npagesmax) { + if (pages == 0) { + npagesmax = 5; + pages = malloc(npagesmax * + sizeof (struct usage_page)); + } else { + npagesmax += 5; + pages = realloc(pages, + npagesmax * + sizeof (struct usage_page)); + } + if (!pages) + err(1, "alloc"); + } + curpage = &pages[npages++]; + curpage->name = n; + curpage->usage = no; + curpage->pagesize = 0; + curpage->pagesizemax = 10; + curpage->page_contents = + malloc(curpage->pagesizemax * + sizeof (struct usage_in_page)); + if (!curpage->page_contents) + err(1, "malloc"); + } + } + fclose(f); +#ifdef DEBUG + dump_hid_table(); +#endif +} + +const char * +hid_usage_page(int i) +{ + static char b[10]; + int k; + + if (!pages) + errx(1, "no hid table\n"); + + for (k = 0; k < npages; k++) + if (pages[k].usage == i) + return pages[k].name; + sprintf(b, "0x%02x", i); + return b; +} + +const char * +hid_usage_in_page(unsigned int u) +{ + int page = HID_PAGE(u); + int i = HID_USAGE(u); + static char b[100]; + int j, k, us; + + for (k = 0; k < npages; k++) + if (pages[k].usage == page) + break; + if (k >= npages) + goto bad; + for (j = 0; j < pages[k].pagesize; j++) { + us = pages[k].page_contents[j].usage; + if (us == -1) { + sprintf(b, pages[k].page_contents[j].name, i); + return b; + } + if (us == i) + return pages[k].page_contents[j].name; + } + bad: + sprintf(b, "0x%02x", i); + return b; +} diff --git a/lib/libusb/usb.3 b/lib/libusb/usb.3 new file mode 100644 index 000000000000..a8a87534914b --- /dev/null +++ b/lib/libusb/usb.3 @@ -0,0 +1,190 @@ +.\" $NetBSD: usb.3,v 1.10 2000/02/22 12:39:22 augustss Exp $ +.\" $FreeBSD$ +.\" +.\" Copyright (c) 1999 Lennart Augustsson +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd May 11, 1999 +.Dt USB 3 +.Os +.Sh NAME +.Nm usb , +.Nm hid_get_report_desc , +.Nm hid_dispose_report_desc , +.Nm hid_start_parse , +.Nm hid_end_parse , +.Nm hid_get_item , +.Nm hid_report_size , +.Nm hid_locate , +.Nm hid_usage_page , +.Nm hid_usage_in_page , +.Nm hid_init , +.Nm hid_get_data , +.Nm hid_set_data +.Nd USB HID access routines +.Sh LIBRARY +.Lb libusb +.Sh SYNOPSIS +.Fd #include +.Ft report_desc_t +.Fn hid_get_report_desc "int file" +.Ft void +.Fn hid_dispose_report_desc "report_desc_t d" +.Ft hid_data_t +.Fn hid_start_parse "report_desc_t d" "int kindset" +.Ft void +.Fn hid_end_parse "hid_data_t s" +.Ft int +.Fn hid_get_item "hid_data_t s" "hid_item_t *h" +.Ft int +.Fn hid_report_size "report_desc_t d" "hid_kind_t k" "int *idp" +.Ft int +.Fn hid_locate "report_desc_t d" "u_int usage" "hid_kind_t k" "hid_item_t *h" +.Ft char * +.Fn hid_usage_page "int i" +.Ft char * +.Fn hid_usage_in_page "u_int u" +.Ft void +.Fn hid_init "char *file" +.Ft int +.Fn hid_get_data "void *data" "hid_item_t *h" +.Ft void +.Fn hid_set_data "void *data" "hid_item_t *h" "u_int data" +.Sh DESCRIPTION +The +.Nm +library provides routines to extract data from USB Human Interface Devices. +.Ss INTRODUCTION +USB HID devices send and receive data layed out in a device dependent +way. The +.Nm +library contains routines to extract the +.Em report descriptor +which contains the data layout information and then use this information. +.Pp +The routines can be divided into four parts: extraction of the descriptor, +parsing of the descriptor, translating to/from symbolic names, and +data manipulation. +.Ss DESCRIPTOR FUNCTIONS +A report descriptor can be obtained by calling +.Fn hid_get_report_desc +with a file descriptor obtained by opening a +.Xr uhid 4 +device. +When the report descriptor is no longer needed it should be freed +by calling +.Fn hid_dispose_report_desc . +The type +.Fa report_desc_t +is opaque and should be used when calling the parsing functions. +.Ss DESCRIPTOR PARSING FUNCTIONS +To parse the report descriptor the +.Fn hid_start_parse +function should be called with a report descriptor and a set that +describes which items that are interesting. The set is obtained +by or-ing together values +.Fa "(1 << k)" +where +.Fa k +is an item of type +.Fa hid_kind_t . +The function returns +.Fa NULL +if the initialization fails, otherwise an opaque value to be used +in subsequent calls. +After parsing the +.Fn hid_end_parse +function should be called to free internal data structures. +.Pp +To iterate through all the items in the report descriptor +.Fn hid_get_item +should be called while it returns a value greater than 0. +When the report descriptor ends it will returns 0; a syntax +error within the report descriptor will cause a return value less +than 0. +The struct pointed to by +.Fa h +will be filled with the relevant data for the item. +The definition of +.Fa hid_item_t +can be found in +.Pa +and the meaning of the components in the USB HID documentation. +.Pp +Data should be read/written to the device in the size of +the report. The size of a report (of a certain kind) can be +computed by the +.Fn hid_report_size +function. If the report is prefixed by an ID byte it is +stored at +.Fa idp , +otherwise it will contain 0. +.Pp +To locate a single item the +.Fn hid_locate +function can be used. It should be given the usage code of +the item and its kind and it will fill the item and return +non-zero if the item was found. +.Pp +.Ss NAME TRANSLATION FUNCTIONS +The function +.Fn hid_usage_page +will return the symbolic name of a usage page, and the function +.Fn hid_usage_in_page +will return the symbolic name of the usage within the page. +Both these functions may return a pointer to static data. +Before either of these functions can be called the usage table +must be parsed, this is done by calling +.Fn hid_init +with the name of the table. Passing +.Fa NULL +to this function will cause it to use the default table. +.Ss DATA EXTRACTION FUNCTIONS +Given the data obtained from a HID device and an item in the +report descriptor the +.Fn hid_get_data +function extracts the value of the item. +Conversely +.Fn hid_set_data +can be used to put data into a report (which must be zeroed first). +.Sh EXAMPLE +Not yet. +.Sh FILES +.Pa /usr/share/misc/usb_hid_usages +The default HID usage table. +.Sh BUGS +This man page is woefully incomplete. +.Sh SEE ALSO +The +.Tn USB +specifications can be found at +.Dv http://www.usb.org/developers/docs.htm . +.Pp +.Xr hid 4 , +.Xr usb 4 . +.Sh HISTORY +The +.Nm +library first appeared in +.Nx 1.5 . diff --git a/lib/libusb/usbvar.h b/lib/libusb/usbvar.h new file mode 100644 index 000000000000..7ed04e5edea1 --- /dev/null +++ b/lib/libusb/usbvar.h @@ -0,0 +1,36 @@ +/* $NetBSD: usbvar.h,v 1.2 1999/05/11 21:15:46 augustss Exp $ */ + +/* + * Copyright (c) 1999 Lennart Augustsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * + */ + +struct report_desc { + unsigned int size; + unsigned char data[1]; +}; + diff --git a/lib/libusbhid/Makefile b/lib/libusbhid/Makefile new file mode 100644 index 000000000000..fddc4aad1d3b --- /dev/null +++ b/lib/libusbhid/Makefile @@ -0,0 +1,24 @@ +# $NetBSD: Makefile,v 1.5 1999/07/23 09:44:38 mrg Exp $ +# $FreeBSD$ + +MAINTAINER= n_hibma@FreeBSD.ORG + +LIB= usb +MAN3= usb.3 + +SHLIB_MAJOR= 0 +SHLIB_MINOR= 0 + +MLINKS= usb.3 libusb.3 usb.3 hid_get_report_desc.3 \ + usb.3 hid_dispose_report_desc.3 \ + usb.3 hid_start_parse.3 usb.3 hid_end_parse.3 \ + usb.3 hid_get_item.3 usb.3 hid_report_size.3 usb.3 hid_locate.3 \ + usb.3 hid_usage_page.3 usb.3 hid_usage_in_page.3 usb.3 hid_init.3 \ + usb.3 hid_get_data.3 usb.3 hid_set_data.3 + +SRCS= descr.c parse.c usage.c data.c + +INCS= libusb.h + +.include + diff --git a/lib/libusbhid/data.c b/lib/libusbhid/data.c new file mode 100644 index 000000000000..26b33b39b9cc --- /dev/null +++ b/lib/libusbhid/data.c @@ -0,0 +1,99 @@ +/* $NetBSD: data.c,v 1.8 2000/04/02 11:10:53 augustss Exp $ */ + +/* + * Copyright (c) 1999 Lennart Augustsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + */ + +#include +#include +#include "libusb.h" + +int +hid_get_data(const void *p, const hid_item_t *h) +{ + const unsigned char *buf; + unsigned int hpos; + unsigned int hsize; + int data; + int i, end, offs; + + _DIAGASSERT(p != NULL); + _DIAGASSERT(h != NULL); + + buf = p; + hpos = h->pos; /* bit position of data */ + hsize = h->report_size; /* bit length of data */ + + if (hsize == 0) + return (0); + offs = hpos / 8; + end = (hpos + hsize) / 8 - offs; + data = 0; + for (i = 0; i <= end; i++) + data |= buf[offs + i] << (i*8); + data >>= hpos % 8; + data &= (1 << hsize) - 1; + if (h->logical_minimum < 0) { + /* Need to sign extend */ + hsize = sizeof data * 8 - hsize; + data = (data << hsize) >> hsize; + } + return (data); +} + +void +hid_set_data(void *p, const hid_item_t *h, int data) +{ + unsigned char *buf; + unsigned int hpos; + unsigned int hsize; + int i, end, offs, mask; + + _DIAGASSERT(p != NULL); + _DIAGASSERT(h != NULL); + + buf = p; + hpos = h->pos; /* bit position of data */ + hsize = h->report_size; /* bit length of data */ + + if (hsize != 32) { + mask = (1 << hsize) - 1; + data &= mask; + } else + mask = ~0; + + data <<= (hpos % 8); + mask <<= (hpos % 8); + mask = ~mask; + + offs = hpos / 8; + end = (hpos + hsize) / 8 - offs; + + for (i = 0; i <= end; i++) + buf[offs + i] = (buf[offs + i] & (mask >> (i*8))) | + ((data >> (i*8)) & 0xff); +} diff --git a/lib/libusbhid/descr.c b/lib/libusbhid/descr.c new file mode 100644 index 000000000000..17b607e60c16 --- /dev/null +++ b/lib/libusbhid/descr.c @@ -0,0 +1,75 @@ +/* $NetBSD: descr.c,v 1.7 1999/10/13 17:48:04 drochner Exp $ */ + +/* + * Copyright (c) 1999 Lennart Augustsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * + */ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "libusb.h" +#include "usbvar.h" + +report_desc_t +hid_get_report_desc(fd) + int fd; +{ + struct usb_ctl_report_desc rep; + report_desc_t r; + + _DIAGASSERT(fd != -1); + + rep.size = 0; + if (ioctl(fd, USB_GET_REPORT_DESC, &rep) < 0) + return (0); + r = malloc(sizeof *r + rep.size); + if (r == 0) { + errno = ENOMEM; + return (0); + } + r->size = rep.size; + memcpy(r->data, rep.data, (unsigned int)rep.size); + return (r); +} + +void +hid_dispose_report_desc(r) + report_desc_t r; +{ + + free(r); +} diff --git a/lib/libusbhid/libusb.h b/lib/libusbhid/libusb.h new file mode 100644 index 000000000000..65b996fc7fde --- /dev/null +++ b/lib/libusbhid/libusb.h @@ -0,0 +1,96 @@ +/* $NetBSD: usb.h,v 1.7 2000/04/02 11:10:53 augustss Exp $ */ + +/* + * Copyright (c) 1999 Lennart Augustsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * + */ + +typedef struct report_desc *report_desc_t; + +typedef struct hid_data *hid_data_t; + +typedef enum hid_kind { + hid_input, hid_output, hid_feature, hid_collection, hid_endcollection +}hid_kind_t; + +typedef struct hid_item { + /* Global */ + int _usage_page; + int logical_minimum; + int logical_maximum; + int physical_minimum; + int physical_maximum; + int unit_exponent; + int unit; + int report_size; + int report_ID; +#define NO_REPORT_ID 0 + int report_count; + /* Local */ + unsigned int usage; + int usage_minimum; + int usage_maximum; + int designator_index; + int designator_minimum; + int designator_maximum; + int string_index; + int string_minimum; + int string_maximum; + int set_delimiter; + /* Misc */ + int collection; + int collevel; + enum hid_kind kind; + unsigned int flags; + /* Absolute data position (bits) */ + unsigned int pos; + /* */ + struct hid_item *next; +} hid_item_t; + +#define HID_PAGE(u) ((u) >> 16) +#define HID_USAGE(u) ((u) & 0xffff) + +/* Obtaining a report descriptor, descr.c: */ +report_desc_t hid_get_report_desc __P((int file)); +void hid_dispose_report_desc __P((report_desc_t)); + +/* Parsing of a HID report descriptor, parse.c: */ +hid_data_t hid_start_parse __P((report_desc_t d, int kindset)); +void hid_end_parse __P((hid_data_t s)); +int hid_get_item __P((hid_data_t s, hid_item_t *h)); +int hid_report_size __P((report_desc_t d, enum hid_kind k, int *idp)); +int hid_locate __P((report_desc_t d, unsigned int usage, enum hid_kind k, hid_item_t *h)); + +/* Conversion to/from usage names, usage.c: */ +const char *hid_usage_page __P((int i)); +const char *hid_usage_in_page __P((unsigned int u)); +void hid_init __P((const char *file)); + +/* Extracting/insertion of data, data.c: */ +int hid_get_data __P((const void *p, const hid_item_t *h)); +void hid_set_data __P((void *p, const hid_item_t *h, int data)); diff --git a/lib/libusbhid/libusbhid.h b/lib/libusbhid/libusbhid.h new file mode 100644 index 000000000000..65b996fc7fde --- /dev/null +++ b/lib/libusbhid/libusbhid.h @@ -0,0 +1,96 @@ +/* $NetBSD: usb.h,v 1.7 2000/04/02 11:10:53 augustss Exp $ */ + +/* + * Copyright (c) 1999 Lennart Augustsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * + */ + +typedef struct report_desc *report_desc_t; + +typedef struct hid_data *hid_data_t; + +typedef enum hid_kind { + hid_input, hid_output, hid_feature, hid_collection, hid_endcollection +}hid_kind_t; + +typedef struct hid_item { + /* Global */ + int _usage_page; + int logical_minimum; + int logical_maximum; + int physical_minimum; + int physical_maximum; + int unit_exponent; + int unit; + int report_size; + int report_ID; +#define NO_REPORT_ID 0 + int report_count; + /* Local */ + unsigned int usage; + int usage_minimum; + int usage_maximum; + int designator_index; + int designator_minimum; + int designator_maximum; + int string_index; + int string_minimum; + int string_maximum; + int set_delimiter; + /* Misc */ + int collection; + int collevel; + enum hid_kind kind; + unsigned int flags; + /* Absolute data position (bits) */ + unsigned int pos; + /* */ + struct hid_item *next; +} hid_item_t; + +#define HID_PAGE(u) ((u) >> 16) +#define HID_USAGE(u) ((u) & 0xffff) + +/* Obtaining a report descriptor, descr.c: */ +report_desc_t hid_get_report_desc __P((int file)); +void hid_dispose_report_desc __P((report_desc_t)); + +/* Parsing of a HID report descriptor, parse.c: */ +hid_data_t hid_start_parse __P((report_desc_t d, int kindset)); +void hid_end_parse __P((hid_data_t s)); +int hid_get_item __P((hid_data_t s, hid_item_t *h)); +int hid_report_size __P((report_desc_t d, enum hid_kind k, int *idp)); +int hid_locate __P((report_desc_t d, unsigned int usage, enum hid_kind k, hid_item_t *h)); + +/* Conversion to/from usage names, usage.c: */ +const char *hid_usage_page __P((int i)); +const char *hid_usage_in_page __P((unsigned int u)); +void hid_init __P((const char *file)); + +/* Extracting/insertion of data, data.c: */ +int hid_get_data __P((const void *p, const hid_item_t *h)); +void hid_set_data __P((void *p, const hid_item_t *h, int data)); diff --git a/lib/libusbhid/parse.c b/lib/libusbhid/parse.c new file mode 100644 index 000000000000..79af687d7434 --- /dev/null +++ b/lib/libusbhid/parse.c @@ -0,0 +1,405 @@ +/* $NetBSD: parse.c,v 1.9 2000/03/17 18:09:17 augustss Exp $ */ + +/* + * Copyright (c) 1999 Lennart Augustsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * + */ + +#include +#include +#include +#include + +#include +#include + +#include "libusb.h" +#include "usbvar.h" + +#define MAXUSAGE 100 +struct hid_data { + u_char *start; + u_char *end; + u_char *p; + hid_item_t cur; + unsigned int usages[MAXUSAGE]; + int nusage; + int minset; + int multi; + int multimax; + int kindset; +}; + +static int min(int x, int y) { return x < y ? x : y; } + +static void +hid_clear_local(hid_item_t *c) +{ + + _DIAGASSERT(c != NULL); + + c->usage = 0; + c->usage_minimum = 0; + c->usage_maximum = 0; + c->designator_index = 0; + c->designator_minimum = 0; + c->designator_maximum = 0; + c->string_index = 0; + c->string_minimum = 0; + c->string_maximum = 0; + c->set_delimiter = 0; +} + +hid_data_t +hid_start_parse(report_desc_t d, int kindset) +{ + struct hid_data *s; + + _DIAGASSERT(d != NULL); + + s = malloc(sizeof *s); + memset(s, 0, sizeof *s); + s->start = s->p = d->data; + s->end = d->data + d->size; + s->kindset = kindset; + return (s); +} + +void +hid_end_parse(hid_data_t s) +{ + + _DIAGASSERT(s != NULL); + + while (s->cur.next) { + hid_item_t *hi = s->cur.next->next; + free(s->cur.next); + s->cur.next = hi; + } + free(s); +} + +int +hid_get_item(hid_data_t s, hid_item_t *h) +{ + hid_item_t *c; + unsigned int bTag = 0, bType = 0, bSize, oldpos; + unsigned char *data; + int dval; + unsigned char *p; + hid_item_t *hi; + int i; + + _DIAGASSERT(s != NULL); + _DIAGASSERT(h != NULL); + + c = &s->cur; + + top: + if (s->multimax) { + if (s->multi < s->multimax) { + c->usage = s->usages[min(s->multi, s->nusage-1)]; + s->multi++; + *h = *c; + c->pos += c->report_size; + h->next = 0; + return (1); + } else { + c->report_count = s->multimax; + s->multimax = 0; + s->nusage = 0; + hid_clear_local(c); + } + } + for (;;) { + p = s->p; + if (p >= s->end) + return (0); + + bSize = *p++; + if (bSize == 0xfe) { + /* long item */ + bSize = *p++; + bSize |= *p++ << 8; + bTag = *p++; + data = p; + p += bSize; + } else { + /* short item */ + bTag = bSize >> 4; + bType = (bSize >> 2) & 3; + bSize &= 3; + if (bSize == 3) bSize = 4; + data = p; + p += bSize; + } + s->p = p; + /* + * The spec is unclear if the data is signed or unsigned. + */ + switch(bSize) { + case 0: + dval = 0; + break; + case 1: + dval = (int8_t)*data++; + break; + case 2: + dval = *data++; + dval |= *data++ << 8; + dval = (int16_t)dval; + break; + case 4: + dval = *data++; + dval |= *data++ << 8; + dval |= *data++ << 16; + dval |= *data++ << 24; + break; + default: + return (-1); + } + + switch (bType) { + case 0: /* Main */ + switch (bTag) { + case 8: /* Input */ + if (!(s->kindset & (1 << hid_input))) + continue; + c->kind = hid_input; + c->flags = dval; + ret: + if (c->flags & HIO_VARIABLE) { + s->multimax = c->report_count; + s->multi = 0; + c->report_count = 1; + if (s->minset) { + for (i = c->usage_minimum; + i <= c->usage_maximum; + i++) { + s->usages[s->nusage] = i; + if (s->nusage < MAXUSAGE-1) + s->nusage++; + } + s->minset = 0; + } + goto top; + } else { + if (s->minset) + c->usage = c->usage_minimum; + *h = *c; + h->next = 0; + c->pos += c->report_size * c->report_count; + hid_clear_local(c); + s->minset = 0; + return (1); + } + case 9: /* Output */ + if (!(s->kindset & (1 << hid_output))) + continue; + c->kind = hid_output; + c->flags = dval; + goto ret; + case 10: /* Collection */ + c->kind = hid_collection; + c->collection = dval; + c->collevel++; + *h = *c; + hid_clear_local(c); + c->report_ID = NO_REPORT_ID; + s->nusage = 0; + return (1); + case 11: /* Feature */ + if (!(s->kindset & (1 << hid_feature))) + continue; + c->kind = hid_feature; + c->flags = dval; + goto ret; + case 12: /* End collection */ + c->kind = hid_endcollection; + c->collevel--; + *h = *c; + /*hid_clear_local(c);*/ + s->nusage = 0; + return (1); + default: + return (-2); + } + + case 1: /* Global */ + switch (bTag) { + case 0: + c->_usage_page = dval << 16; + break; + case 1: + c->logical_minimum = dval; + break; + case 2: + c->logical_maximum = dval; + break; + case 3: + c->physical_maximum = dval; + break; + case 4: + c->physical_maximum = dval; + break; + case 5: + c->unit_exponent = dval; + break; + case 6: + c->unit = dval; + break; + case 7: + c->report_size = dval; + break; + case 8: + c->report_ID = dval; + break; + case 9: + c->report_count = dval; + break; + case 10: /* Push */ + hi = malloc(sizeof *hi); + *hi = s->cur; + c->next = hi; + break; + case 11: /* Pop */ + hi = c->next; + oldpos = c->pos; + s->cur = *hi; + c->pos = oldpos; + free(hi); + break; + default: + return (-3); + } + break; + case 2: /* Local */ + switch (bTag) { + case 0: + if (bSize == 1) + dval = c->_usage_page | (dval&0xff); + else if (bSize == 2) + dval = c->_usage_page | (dval&0xffff); + c->usage = dval; + if (s->nusage < MAXUSAGE) + s->usages[s->nusage++] = dval; + /* else XXX */ + break; + case 1: + s->minset = 1; + if (bSize == 1) + dval = c->_usage_page | (dval&0xff); + else if (bSize == 2) + dval = c->_usage_page | (dval&0xffff); + c->usage_minimum = dval; + break; + case 2: + if (bSize == 1) + dval = c->_usage_page | (dval&0xff); + else if (bSize == 2) + dval = c->_usage_page | (dval&0xffff); + c->usage_maximum = dval; + break; + case 3: + c->designator_index = dval; + break; + case 4: + c->designator_minimum = dval; + break; + case 5: + c->designator_maximum = dval; + break; + case 7: + c->string_index = dval; + break; + case 8: + c->string_minimum = dval; + break; + case 9: + c->string_maximum = dval; + break; + case 10: + c->set_delimiter = dval; + break; + default: + return (-4); + } + break; + default: + return (-5); + } + } +} + +int +hid_report_size(report_desc_t r, enum hid_kind k, int *idp) +{ + struct hid_data *d; + hid_item_t h; + int size, id; + + _DIAGASSERT(r != NULL); + /* idp may be NULL */ + + id = 0; + if (idp) + *idp = 0; + memset(&h, 0, sizeof h); + for (d = hid_start_parse(r, 1<kind == k && !(h->flags & HIO_CONST) && h->usage == u) { + hid_end_parse(d); + return (1); + } + } + hid_end_parse(d); + h->report_size = 0; + return (0); +} diff --git a/lib/libusbhid/usage.c b/lib/libusbhid/usage.c new file mode 100644 index 000000000000..afb990a93ccd --- /dev/null +++ b/lib/libusbhid/usage.c @@ -0,0 +1,197 @@ +/* $NetBSD: usage.c,v 1.5 2000/04/02 11:10:53 augustss Exp $ */ + +/* + * Copyright (c) 1999 Lennart Augustsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * + */ + +#include +#include +#include +#include +#include + +#include "libusb.h" + +#define _PATH_HIDTABLE "/usr/share/misc/usb_hid_usages" + +struct usage_in_page { + const char *name; + int usage; +}; + +static struct usage_page { + const char *name; + int usage; + struct usage_in_page *page_contents; + int pagesize, pagesizemax; +} *pages; +static int npages, npagesmax; + +#ifdef DEBUG +void +dump_hid_table(void) +{ + int i, j; + + for (i = 0; i < npages; i++) { + printf("%d\t%s\n", pages[i].usage, pages[i].name); + for (j = 0; j < pages[i].pagesize; j++) { + printf("\t%d\t%s\n", pages[i].page_contents[j].usage, + pages[i].page_contents[j].name); + } + } +} +#endif + +void +hid_init(const char *hidname) +{ + FILE *f; + char line[100], name[100], *p, *n; + int no; + int lineno; + struct usage_page *curpage = 0; + + if (hidname == 0) + hidname = _PATH_HIDTABLE; + + f = fopen(hidname, "r"); + if (f == NULL) + err(1, "%s", hidname); + for (lineno = 1; ; lineno++) { + if (fgets(line, sizeof line, f) == NULL) + break; + if (line[0] == '#') + continue; + for (p = line; *p && isspace(*p); p++) + ; + if (!*p) + continue; + if (sscanf(line, " * %[^\n]", name) == 1) + no = -1; + else if (sscanf(line, " 0x%x %[^\n]", &no, name) != 2 && + sscanf(line, " %d %[^\n]", &no, name) != 2) + errx(1, "file %s, line %d, syntax error\n", + hidname, lineno); + for (p = name; *p; p++) + if (isspace(*p) || *p == '.') + *p = '_'; + n = strdup(name); + if (!n) + err(1, "strdup"); + if (isspace(line[0])) { + if (!curpage) + errx(1, "file %s, line %d, syntax error\n", + hidname, lineno); + if (curpage->pagesize >= curpage->pagesizemax) { + curpage->pagesizemax += 10; + curpage->page_contents = + realloc(curpage->page_contents, + curpage->pagesizemax * + sizeof (struct usage_in_page)); + if (!curpage->page_contents) + err(1, "realloc"); + } + curpage->page_contents[curpage->pagesize].name = n; + curpage->page_contents[curpage->pagesize].usage = no; + curpage->pagesize++; + } else { + if (npages >= npagesmax) { + if (pages == 0) { + npagesmax = 5; + pages = malloc(npagesmax * + sizeof (struct usage_page)); + } else { + npagesmax += 5; + pages = realloc(pages, + npagesmax * + sizeof (struct usage_page)); + } + if (!pages) + err(1, "alloc"); + } + curpage = &pages[npages++]; + curpage->name = n; + curpage->usage = no; + curpage->pagesize = 0; + curpage->pagesizemax = 10; + curpage->page_contents = + malloc(curpage->pagesizemax * + sizeof (struct usage_in_page)); + if (!curpage->page_contents) + err(1, "malloc"); + } + } + fclose(f); +#ifdef DEBUG + dump_hid_table(); +#endif +} + +const char * +hid_usage_page(int i) +{ + static char b[10]; + int k; + + if (!pages) + errx(1, "no hid table\n"); + + for (k = 0; k < npages; k++) + if (pages[k].usage == i) + return pages[k].name; + sprintf(b, "0x%02x", i); + return b; +} + +const char * +hid_usage_in_page(unsigned int u) +{ + int page = HID_PAGE(u); + int i = HID_USAGE(u); + static char b[100]; + int j, k, us; + + for (k = 0; k < npages; k++) + if (pages[k].usage == page) + break; + if (k >= npages) + goto bad; + for (j = 0; j < pages[k].pagesize; j++) { + us = pages[k].page_contents[j].usage; + if (us == -1) { + sprintf(b, pages[k].page_contents[j].name, i); + return b; + } + if (us == i) + return pages[k].page_contents[j].name; + } + bad: + sprintf(b, "0x%02x", i); + return b; +} diff --git a/lib/libusbhid/usb.3 b/lib/libusbhid/usb.3 new file mode 100644 index 000000000000..a8a87534914b --- /dev/null +++ b/lib/libusbhid/usb.3 @@ -0,0 +1,190 @@ +.\" $NetBSD: usb.3,v 1.10 2000/02/22 12:39:22 augustss Exp $ +.\" $FreeBSD$ +.\" +.\" Copyright (c) 1999 Lennart Augustsson +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd May 11, 1999 +.Dt USB 3 +.Os +.Sh NAME +.Nm usb , +.Nm hid_get_report_desc , +.Nm hid_dispose_report_desc , +.Nm hid_start_parse , +.Nm hid_end_parse , +.Nm hid_get_item , +.Nm hid_report_size , +.Nm hid_locate , +.Nm hid_usage_page , +.Nm hid_usage_in_page , +.Nm hid_init , +.Nm hid_get_data , +.Nm hid_set_data +.Nd USB HID access routines +.Sh LIBRARY +.Lb libusb +.Sh SYNOPSIS +.Fd #include +.Ft report_desc_t +.Fn hid_get_report_desc "int file" +.Ft void +.Fn hid_dispose_report_desc "report_desc_t d" +.Ft hid_data_t +.Fn hid_start_parse "report_desc_t d" "int kindset" +.Ft void +.Fn hid_end_parse "hid_data_t s" +.Ft int +.Fn hid_get_item "hid_data_t s" "hid_item_t *h" +.Ft int +.Fn hid_report_size "report_desc_t d" "hid_kind_t k" "int *idp" +.Ft int +.Fn hid_locate "report_desc_t d" "u_int usage" "hid_kind_t k" "hid_item_t *h" +.Ft char * +.Fn hid_usage_page "int i" +.Ft char * +.Fn hid_usage_in_page "u_int u" +.Ft void +.Fn hid_init "char *file" +.Ft int +.Fn hid_get_data "void *data" "hid_item_t *h" +.Ft void +.Fn hid_set_data "void *data" "hid_item_t *h" "u_int data" +.Sh DESCRIPTION +The +.Nm +library provides routines to extract data from USB Human Interface Devices. +.Ss INTRODUCTION +USB HID devices send and receive data layed out in a device dependent +way. The +.Nm +library contains routines to extract the +.Em report descriptor +which contains the data layout information and then use this information. +.Pp +The routines can be divided into four parts: extraction of the descriptor, +parsing of the descriptor, translating to/from symbolic names, and +data manipulation. +.Ss DESCRIPTOR FUNCTIONS +A report descriptor can be obtained by calling +.Fn hid_get_report_desc +with a file descriptor obtained by opening a +.Xr uhid 4 +device. +When the report descriptor is no longer needed it should be freed +by calling +.Fn hid_dispose_report_desc . +The type +.Fa report_desc_t +is opaque and should be used when calling the parsing functions. +.Ss DESCRIPTOR PARSING FUNCTIONS +To parse the report descriptor the +.Fn hid_start_parse +function should be called with a report descriptor and a set that +describes which items that are interesting. The set is obtained +by or-ing together values +.Fa "(1 << k)" +where +.Fa k +is an item of type +.Fa hid_kind_t . +The function returns +.Fa NULL +if the initialization fails, otherwise an opaque value to be used +in subsequent calls. +After parsing the +.Fn hid_end_parse +function should be called to free internal data structures. +.Pp +To iterate through all the items in the report descriptor +.Fn hid_get_item +should be called while it returns a value greater than 0. +When the report descriptor ends it will returns 0; a syntax +error within the report descriptor will cause a return value less +than 0. +The struct pointed to by +.Fa h +will be filled with the relevant data for the item. +The definition of +.Fa hid_item_t +can be found in +.Pa +and the meaning of the components in the USB HID documentation. +.Pp +Data should be read/written to the device in the size of +the report. The size of a report (of a certain kind) can be +computed by the +.Fn hid_report_size +function. If the report is prefixed by an ID byte it is +stored at +.Fa idp , +otherwise it will contain 0. +.Pp +To locate a single item the +.Fn hid_locate +function can be used. It should be given the usage code of +the item and its kind and it will fill the item and return +non-zero if the item was found. +.Pp +.Ss NAME TRANSLATION FUNCTIONS +The function +.Fn hid_usage_page +will return the symbolic name of a usage page, and the function +.Fn hid_usage_in_page +will return the symbolic name of the usage within the page. +Both these functions may return a pointer to static data. +Before either of these functions can be called the usage table +must be parsed, this is done by calling +.Fn hid_init +with the name of the table. Passing +.Fa NULL +to this function will cause it to use the default table. +.Ss DATA EXTRACTION FUNCTIONS +Given the data obtained from a HID device and an item in the +report descriptor the +.Fn hid_get_data +function extracts the value of the item. +Conversely +.Fn hid_set_data +can be used to put data into a report (which must be zeroed first). +.Sh EXAMPLE +Not yet. +.Sh FILES +.Pa /usr/share/misc/usb_hid_usages +The default HID usage table. +.Sh BUGS +This man page is woefully incomplete. +.Sh SEE ALSO +The +.Tn USB +specifications can be found at +.Dv http://www.usb.org/developers/docs.htm . +.Pp +.Xr hid 4 , +.Xr usb 4 . +.Sh HISTORY +The +.Nm +library first appeared in +.Nx 1.5 . diff --git a/lib/libusbhid/usbhid.3 b/lib/libusbhid/usbhid.3 new file mode 100644 index 000000000000..a8a87534914b --- /dev/null +++ b/lib/libusbhid/usbhid.3 @@ -0,0 +1,190 @@ +.\" $NetBSD: usb.3,v 1.10 2000/02/22 12:39:22 augustss Exp $ +.\" $FreeBSD$ +.\" +.\" Copyright (c) 1999 Lennart Augustsson +.\" All rights reserved. +.\" +.\" Redistribution and use in source and binary forms, with or without +.\" modification, are permitted provided that the following conditions +.\" are met: +.\" 1. Redistributions of source code must retain the above copyright +.\" notice, this list of conditions and the following disclaimer. +.\" 2. Redistributions in binary form must reproduce the above copyright +.\" notice, this list of conditions and the following disclaimer in the +.\" documentation and/or other materials provided with the distribution. +.\" +.\" THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND +.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +.\" ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE +.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS +.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) +.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT +.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY +.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF +.\" SUCH DAMAGE. +.\" +.Dd May 11, 1999 +.Dt USB 3 +.Os +.Sh NAME +.Nm usb , +.Nm hid_get_report_desc , +.Nm hid_dispose_report_desc , +.Nm hid_start_parse , +.Nm hid_end_parse , +.Nm hid_get_item , +.Nm hid_report_size , +.Nm hid_locate , +.Nm hid_usage_page , +.Nm hid_usage_in_page , +.Nm hid_init , +.Nm hid_get_data , +.Nm hid_set_data +.Nd USB HID access routines +.Sh LIBRARY +.Lb libusb +.Sh SYNOPSIS +.Fd #include +.Ft report_desc_t +.Fn hid_get_report_desc "int file" +.Ft void +.Fn hid_dispose_report_desc "report_desc_t d" +.Ft hid_data_t +.Fn hid_start_parse "report_desc_t d" "int kindset" +.Ft void +.Fn hid_end_parse "hid_data_t s" +.Ft int +.Fn hid_get_item "hid_data_t s" "hid_item_t *h" +.Ft int +.Fn hid_report_size "report_desc_t d" "hid_kind_t k" "int *idp" +.Ft int +.Fn hid_locate "report_desc_t d" "u_int usage" "hid_kind_t k" "hid_item_t *h" +.Ft char * +.Fn hid_usage_page "int i" +.Ft char * +.Fn hid_usage_in_page "u_int u" +.Ft void +.Fn hid_init "char *file" +.Ft int +.Fn hid_get_data "void *data" "hid_item_t *h" +.Ft void +.Fn hid_set_data "void *data" "hid_item_t *h" "u_int data" +.Sh DESCRIPTION +The +.Nm +library provides routines to extract data from USB Human Interface Devices. +.Ss INTRODUCTION +USB HID devices send and receive data layed out in a device dependent +way. The +.Nm +library contains routines to extract the +.Em report descriptor +which contains the data layout information and then use this information. +.Pp +The routines can be divided into four parts: extraction of the descriptor, +parsing of the descriptor, translating to/from symbolic names, and +data manipulation. +.Ss DESCRIPTOR FUNCTIONS +A report descriptor can be obtained by calling +.Fn hid_get_report_desc +with a file descriptor obtained by opening a +.Xr uhid 4 +device. +When the report descriptor is no longer needed it should be freed +by calling +.Fn hid_dispose_report_desc . +The type +.Fa report_desc_t +is opaque and should be used when calling the parsing functions. +.Ss DESCRIPTOR PARSING FUNCTIONS +To parse the report descriptor the +.Fn hid_start_parse +function should be called with a report descriptor and a set that +describes which items that are interesting. The set is obtained +by or-ing together values +.Fa "(1 << k)" +where +.Fa k +is an item of type +.Fa hid_kind_t . +The function returns +.Fa NULL +if the initialization fails, otherwise an opaque value to be used +in subsequent calls. +After parsing the +.Fn hid_end_parse +function should be called to free internal data structures. +.Pp +To iterate through all the items in the report descriptor +.Fn hid_get_item +should be called while it returns a value greater than 0. +When the report descriptor ends it will returns 0; a syntax +error within the report descriptor will cause a return value less +than 0. +The struct pointed to by +.Fa h +will be filled with the relevant data for the item. +The definition of +.Fa hid_item_t +can be found in +.Pa +and the meaning of the components in the USB HID documentation. +.Pp +Data should be read/written to the device in the size of +the report. The size of a report (of a certain kind) can be +computed by the +.Fn hid_report_size +function. If the report is prefixed by an ID byte it is +stored at +.Fa idp , +otherwise it will contain 0. +.Pp +To locate a single item the +.Fn hid_locate +function can be used. It should be given the usage code of +the item and its kind and it will fill the item and return +non-zero if the item was found. +.Pp +.Ss NAME TRANSLATION FUNCTIONS +The function +.Fn hid_usage_page +will return the symbolic name of a usage page, and the function +.Fn hid_usage_in_page +will return the symbolic name of the usage within the page. +Both these functions may return a pointer to static data. +Before either of these functions can be called the usage table +must be parsed, this is done by calling +.Fn hid_init +with the name of the table. Passing +.Fa NULL +to this function will cause it to use the default table. +.Ss DATA EXTRACTION FUNCTIONS +Given the data obtained from a HID device and an item in the +report descriptor the +.Fn hid_get_data +function extracts the value of the item. +Conversely +.Fn hid_set_data +can be used to put data into a report (which must be zeroed first). +.Sh EXAMPLE +Not yet. +.Sh FILES +.Pa /usr/share/misc/usb_hid_usages +The default HID usage table. +.Sh BUGS +This man page is woefully incomplete. +.Sh SEE ALSO +The +.Tn USB +specifications can be found at +.Dv http://www.usb.org/developers/docs.htm . +.Pp +.Xr hid 4 , +.Xr usb 4 . +.Sh HISTORY +The +.Nm +library first appeared in +.Nx 1.5 . diff --git a/lib/libusbhid/usbhid.h b/lib/libusbhid/usbhid.h new file mode 100644 index 000000000000..65b996fc7fde --- /dev/null +++ b/lib/libusbhid/usbhid.h @@ -0,0 +1,96 @@ +/* $NetBSD: usb.h,v 1.7 2000/04/02 11:10:53 augustss Exp $ */ + +/* + * Copyright (c) 1999 Lennart Augustsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * + */ + +typedef struct report_desc *report_desc_t; + +typedef struct hid_data *hid_data_t; + +typedef enum hid_kind { + hid_input, hid_output, hid_feature, hid_collection, hid_endcollection +}hid_kind_t; + +typedef struct hid_item { + /* Global */ + int _usage_page; + int logical_minimum; + int logical_maximum; + int physical_minimum; + int physical_maximum; + int unit_exponent; + int unit; + int report_size; + int report_ID; +#define NO_REPORT_ID 0 + int report_count; + /* Local */ + unsigned int usage; + int usage_minimum; + int usage_maximum; + int designator_index; + int designator_minimum; + int designator_maximum; + int string_index; + int string_minimum; + int string_maximum; + int set_delimiter; + /* Misc */ + int collection; + int collevel; + enum hid_kind kind; + unsigned int flags; + /* Absolute data position (bits) */ + unsigned int pos; + /* */ + struct hid_item *next; +} hid_item_t; + +#define HID_PAGE(u) ((u) >> 16) +#define HID_USAGE(u) ((u) & 0xffff) + +/* Obtaining a report descriptor, descr.c: */ +report_desc_t hid_get_report_desc __P((int file)); +void hid_dispose_report_desc __P((report_desc_t)); + +/* Parsing of a HID report descriptor, parse.c: */ +hid_data_t hid_start_parse __P((report_desc_t d, int kindset)); +void hid_end_parse __P((hid_data_t s)); +int hid_get_item __P((hid_data_t s, hid_item_t *h)); +int hid_report_size __P((report_desc_t d, enum hid_kind k, int *idp)); +int hid_locate __P((report_desc_t d, unsigned int usage, enum hid_kind k, hid_item_t *h)); + +/* Conversion to/from usage names, usage.c: */ +const char *hid_usage_page __P((int i)); +const char *hid_usage_in_page __P((unsigned int u)); +void hid_init __P((const char *file)); + +/* Extracting/insertion of data, data.c: */ +int hid_get_data __P((const void *p, const hid_item_t *h)); +void hid_set_data __P((void *p, const hid_item_t *h, int data)); diff --git a/lib/libusbhid/usbvar.h b/lib/libusbhid/usbvar.h new file mode 100644 index 000000000000..7ed04e5edea1 --- /dev/null +++ b/lib/libusbhid/usbvar.h @@ -0,0 +1,36 @@ +/* $NetBSD: usbvar.h,v 1.2 1999/05/11 21:15:46 augustss Exp $ */ + +/* + * Copyright (c) 1999 Lennart Augustsson + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + * $FreeBSD$ + * + */ + +struct report_desc { + unsigned int size; + unsigned char data[1]; +}; + diff --git a/share/misc/Makefile b/share/misc/Makefile index 70111ace275e..a087e0d4b055 100644 --- a/share/misc/Makefile +++ b/share/misc/Makefile @@ -2,7 +2,8 @@ # $FreeBSD$ FILES= ascii birthtoken bsd-family-tree eqnchar flowers init.ee \ - iso3166 iso639 man.template mdoc.template operator scsi_modes + iso3166 iso639 man.template mdoc.template operator scsi_modes \ + usb_hid_usages NOOBJ= noobj all clean cleandir depend lint tags: diff --git a/share/misc/usb_hid_usages b/share/misc/usb_hid_usages new file mode 100644 index 000000000000..bb0f40cad718 --- /dev/null +++ b/share/misc/usb_hid_usages @@ -0,0 +1,1078 @@ +# $NetBSD: usb_hid_usages,v 1.3 1999/07/02 15:46:53 simonb Exp $ +# $FreeBSD$ +# +# USB HID usage table +# Syntax: +# - lines that do not start with a white space give the number and name of +# a usage page. +# - lines that start with a white space give the number and name of +# a usage with the last given page. +# If the number is * then the line matches all usages and the name +# is a printf formatting string that will be given the usage number. +# +1 Generic Desktop + 0x00 Undefined + 0x01 Pointer + 0x02 Mouse + 0x03 Reserved + 0x04 Joystick + 0x05 Game Pad + 0x06 Keyboard + 0x07 Keypad + 0x08 Multi-axis Controller + 0x30 X + 0x31 Y + 0x32 Z + 0x33 Rx + 0x34 Ry + 0x35 Rz + 0x36 Slider + 0x37 Dial + 0x38 Wheel + 0x39 Hat Switch + 0x3A Counted Buffer + 0x3B Byte Count + 0x3C Motion Wakeup + 0x40 Vx + 0x41 Vy + 0x42 Vz + 0x43 Vbrx + 0x44 Vbry + 0x45 Vbrx + 0x46 Vno + 0x80 System Control + 0x81 System Power Down + 0x82 System Sleep + 0x83 System Wake Up + 0x84 System Context Menu + 0x85 System Main Menu + 0x86 System App Menu + 0x87 System Menu Help + 0x88 System Menu Exit + 0x89 System Menu Select + 0x8A System Menu Right + 0x8B System Menu Left + 0x8C System Menu Up + 0x8D System Menu Down + 0x90 D-pad Up + 0x91 D-pad Down + 0x92 D-pad Right + 0x93 D-pad Left + +2 Simulation Controls + 0x00 Undefined + 0x01 Flight Simulation Device + 0x02 Automobile Simulation Device + 0x03 Tank Simulation Device + 0x04 Spaceship Simulation Device + 0x05 Submarine Simulation Device + 0x06 Sailing Simulation Device + 0x07 Motorcycle Simulation Device + 0x08 Sports Simulation Device + 0x09 Airplane Simulation Device + 0x0A Helicopter Simulation Device + 0x0B Magic Carpet Simulation Device + 0x0C Bicycle + 0x20 Flight Control Stick + 0x21 Flight Stick + 0x22 Cyclic Control + 0x23 Cyclic Trim + 0x24 Flight Yoke + 0x25 Track Control + 0x26 Driving Control + 0xB0 Aileron + 0xB1 Aileron Trim + 0xB2 Anti-Torque Control + 0xB3 Auto-pilot Enable + 0xB4 Chaff Release + 0xB5 Collective Control + 0xB6 Dive Brake + 0xB7 Electronic Counter Measures + 0xB8 Elevator + 0xB9 Elevator Trim + 0xBA Rudder + 0xBB Throttle + 0xBC Flight Communication + 0xBD Flare Release + 0xBE Landing Gear + 0xBF Toe Brake + 0xC0 Trigger + 0xC1 Weapons Arm + 0xC2 Weapons Select + 0xC3 Wing Flaps + 0xC4 Accelerator + 0xC5 Brake + 0xC6 Clutch + 0xC7 Shifter + 0xC8 Steering + 0xC9 Turret Direction + 0xCA Barrel Elevation + 0xCB Dive Plane + 0xCC Ballast + 0xCD Bicycle Crank + 0xCE Handle Bars + 0xCF Front Brake + 0xD0 Rear Brake + +3 VR Controls + 0x00 Unidentified + 0x01 Belt + 0x02 Body Suit + 0x03 Flexor + 0x04 Glove + 0x05 Head Tracker + 0x06 Head Mounted Display + 0x07 Hand Tracker + 0x08 Oculometer + 0x09 Vest + 0x0A Animatronic Device + 0x20 Stereo Enable + 0x21 Display Enable + +4 Sports Controls + 0x00 Unidentified + 0x01 Baseball Bat + 0x02 Golf Club + 0x03 Rowing Machine + 0x04 Treadmill + 0x30 Oar + 0x31 Slope + 0x32 Rate + 0x33 Stick Speed + 0x34 Stick Face Angle + 0x35 Stick Heel/Toe + 0x36 Stick Follow Through + 0x37 Stick Tempo + 0x38 Stick Type + 0x39 Stick Height + 0x50 Putter + 0x51 1 Iron + 0x52 2 Iron + 0x53 3 Iron + 0x54 4 Iron + 0x55 5 Iron + 0x56 6 Iron + 0x57 7 Iron + 0x58 8 Iron + 0x59 9 Iron + 0x5A 10 Iron + 0x5B 11 Iron + 0x5C Sand Wedge + 0x5D Loft Wedge + 0x5E Power Wedge + 0x5F 1 Wood + 0x60 3 Wood + 0x61 5 Wood + 0x62 7 Wood + 0x63 9 Wood + +5 Game Controls + 0x00 Undefined + 0x01 3D Game Controller + 0x02 Pinball Device + 0x03 Gun Device + 0x20 Point of View + 0x21 Turn Right/Left + 0x22 Pitch Right/Left + 0x23 Roll Forward/Backward + 0x24 Move Right/Left + 0x25 Move Forward/Backward + 0x26 Move Up/Down + 0x27 Lean Right/Left + 0x28 Lean Forward/Backward + 0x29 Height of POV + 0x2A Flipper + 0x2B Secondary Flipper + 0x2C Bump + 0x2D New Game + 0x2E Shoot Ball + 0x2F Player + 0x30 Gun Bolt + 0x31 Gun Clip + 0x32 Gun Selector + 0x33 Gun Single Shot + 0x34 Gun Burst + 0x35 Gun Automatic + 0x36 Gun Safety + 0x37 Gamepad Fire/Jump + 0x39 Gamepad Trigger + +7 Keyboard + 0x00 Reserved (no event indicated) + 0x01 Keyboard ErrorRollOver + 0x02 Keyboard POSTFail + 0x03 Keyboard ErrorUndefined + 0x04 Keyboard a and A + 0x05 Keyboard b and B + 0x06 Keyboard c and C + 0x07 Keyboard d and D + 0x08 Keyboard e and E + 0x09 Keyboard f and F + 0x0A Keyboard g and G + 0x0B Keyboard h and H + 0x0C Keyboard i and I + 0x0D Keyboard j and J + 0x0E Keyboard k and K + 0x0F Keyboard l and L + 0x10 Keyboard m and M + 0x11 Keyboard n and N + 0x12 Keyboard o and O + 0x13 Keyboard p and P + 0x14 Keyboard q and Q + 0x15 Keyboard r and R + 0x16 Keyboard s and S + 0x17 Keyboard t and T + 0x18 Keyboard u and U + 0x19 Keyboard v and V + 0x1A Keyboard w and W + 0x1B Keyboard x and X + 0x1C Keyboard y and Y + 0x1D Keyboard z and Z + 0x1E Keyboard 1 and ! + 0x1F Keyboard 2 and @ + 0x20 Keyboard 3 and # + 0x21 Keyboard 4 and $ + 0x22 Keyboard 5 and % + 0x23 Keyboard 6 and ^ + 0x24 Keyboard 7 and & + 0x25 Keyboard 8 and * + 0x26 Keyboard 9 and ( + 0x27 Keyboard 0 and ) + 0x28 Keyboard Return (ENTER) + 0x29 Keyboard ESCAPE + 0x2A Keyboard DELETE (Backspace) + 0x2B Keyboard Tab + 0x2C Keyboard Spacebar + 0x2D Keyboard - and (underscore) + 0x2E Keyboard = and + + 0x2F Keyboard [ and { + 0x30 Keyboard ] and } + 0x31 Keyboard \ and | + 0x32 Keyboard Non-US # and ~ + 0x33 Keyboard ; and : + 0x34 Keyboard ' and " + 0x35 Keyboard Grave Accent and Tilde + 0x36 Keyboard, and < + 0x37 Keyboard . and > + 0x38 Keyboard / and ? + 0x39 Keyboard Caps Lock + 0x3A Keyboard F1 + 0x3B Keyboard F2 + 0x3C Keyboard F3 + 0x3D Keyboard F4 + 0x3E Keyboard F5 + 0x3F Keyboard F6 + 0x40 Keyboard F7 + 0x41 Keyboard F8 + 0x42 Keyboard F9 + 0x43 Keyboard F10 + 0x44 Keyboard F11 + 0x45 Keyboard F12 + 0x46 Keyboard PrintScreen + 0x47 Keyboard Scroll Lock + 0x48 Keyboard Pause + 0x49 Keyboard Insert + 0x4A Keyboard Home + 0x4B Keyboard PageUp + 0x4C Keyboard Delete Forward + 0x4D Keyboard End + 0x4E Keyboard PageDown + 0x4F Keyboard RightArrow + 0x50 Keyboard LeftArrow + 0x51 Keyboard DownArrow + 0x52 Keyboard UpArrow + 0x53 Keypad Num Lock and Clear + 0x54 Keypad / + 0x55 Keypad * + 0x56 Keypad - + 0x57 Keypad + + 0x58 Keypad ENTER + 0x59 Keypad 1 and End + 0x5A Keypad 2 and Down Arrow + 0x5B Keypad 3 and PageDn + 0x5C Keypad 4 and Left Arrow + 0x5D Keypad 5 + 0x5E Keypad 6 and Right Arrow + 0x5F Keypad 7 and Home + 0x60 Keypad 8 and Up Arrow + 0x61 Keypad 9 and PageUp + 0x62 Keypad 0 and Insert + 0x63 Keypad . and Delete + 0x64 Keyboard Non-US \ and | + 0x65 Keyboard Application + 0x66 Keyboard Power + 0x67 Keypad = + 0x68 Keyboard F13 + 0x69 Keyboard F14 + 0x6A Keyboard F15 + 0x6B Keyboard F16 + 0x6C Keyboard F17 + 0x6D Keyboard F18 + 0x6E Keyboard F19 + 0x6F Keyboard F20 + 0x70 Keyboard F21 + 0x71 Keyboard F22 + 0x72 Keyboard F23 + 0x73 Keyboard F24 + 0x74 Keyboard Execute + 0x75 Keyboard Help + 0x76 Keyboard Menu + 0x77 Keyboard Select + 0x78 Keyboard Stop + 0x79 Keyboard Again + 0x7A Keyboard Undo + 0x7B Keyboard Cut + 0x7C Keyboard Copy + 0x7D Keyboard Paste + 0x7E Keyboard Find + 0x7F Keyboard Mute + 0x80 Keyboard Volume Up + 0x81 Keyboard Volume Down + 0x82 Keyboard Locking Caps Lock + 0x83 Keyboard Locking Num Lock + 0x84 Keyboard Locking Scroll Lock + 0x85 Keypad Comma + 0x86 Keypad Equal Sign + 0x87 Keyboard International1 + 0x88 Keyboard International2 + 0x89 Keyboard International3 + 0x8A Keyboard International4 + 0x8B Keyboard International5 + 0x8C Keyboard International6 + 0x8D Keyboard International7 + 0x8E Keyboard International8 + 0x8F Keyboard International9 + 0x90 Keyboard LANG1 + 0x91 Keyboard LANG2 + 0x92 Keyboard LANG3 + 0x93 Keyboard LANG4 + 0x94 Keyboard LANG5 + 0x95 Keyboard LANG6 + 0x96 Keyboard LANG7 + 0x97 Keyboard LANG8 + 0x98 Keyboard LANG9 + 0x99 Keyboard Alternate Erase + 0x9A Keyboard SysReq/Attention + 0x9B Keyboard Cancel + 0x9C Keyboard Clear + 0x9D Keyboard Prior + 0x9E Keyboard Return + 0x9F Keyboard Separator + 0xA0 Keyboard Out + 0xA1 Keyboard Oper + 0xA2 Keyboard Clear/Again + 0xA3 Keyboard CrSel/Props + 0xA4 Keyboard ExSel + 0xE0 Keyboard LeftControl + 0xE1 Keyboard LeftShift + 0xE2 Keyboard LeftAlt + 0xE3 Keyboard Left GUI + 0xE4 Keyboard RightControl + 0xE5 Keyboard RightShift + 0xE6 Keyboard RightAlt + 0xE7 Keyboard Right GUI + +8 LEDs + 0x00 Undefined + 0x01 Num Lock + 0x02 Caps Lock + 0x03 Scroll Lock + 0x04 Compose + 0x05 Kana + 0x06 Power + 0x07 Shift + 0x08 Do Not Disturb + 0x09 Mute + 0x0A Tone Enable + 0x0B High Cut Filter + 0x0C Low Cut Filter + 0x0D Equalizer Enable + 0x0E Sound Field On + 0x0F Surround Field On + 0x10 Repeat + 0x11 Stereo + 0x12 Sampling Rate Detect + 0x13 Spinning + 0x14 CAV + 0x15 CLV + 0x16 Recording Format Detect + 0x17 Off-Hook + 0x18 Ring + 0x19 Message Waiting + 0x1A Data Mode + 0x1B Battery Operation + 0x1C Battery OK + 0x1D Battery Low + 0x1E Speaker + 0x1F Head Set + 0x20 Hold + 0x21 Microphone + 0x22 Coverage + 0x23 Night Mode + 0x24 Send Calls + 0x25 Call Pickup + 0x26 Conference + 0x27 Stand-by + 0x28 Camera On + 0x29 Camera Off + 0x2A On-Line + 0x2B Off-Line + 0x2C Busy + 0x2D Ready + 0x2E Paper-Out + 0x2F Paper-Jam + 0x30 Remote + 0x31 Forward + 0x32 Reverse + 0x33 Stop + 0x34 Rewind + 0x35 Fast Forward + 0x36 Play + 0x37 Pause + 0x38 Record + 0x39 Error + 0x3A Usage Selected Indicator + 0x3B Usage In Use Indicator + 0x3C Usage Multi Mode Indicator + 0x3D Indicator On + 0x3E Indicator Flash + 0x3F Indicator Slow Blink + 0x40 Indicator Fast Blink + 0x41 Indicator Off + 0x42 Flash On Time + 0x43 Slow Blink On Time + 0x44 Slow Blink Off Time + 0x45 Fast Blink On Time + 0x46 Fast Blink Off Time + 0x47 Usage Indicator Color + 0x48 Red + 0x49 Green + 0x4A Amber + 0x4B Generic Indicator + 0x4C System Suspend + 0x4D External Power Connected + 0x4C-FFFF Reserved + +9 Button + 0x00 No Button Pressed + * Button %d + +10 Ordinal + 0x00 Unused + * Instance %d + +11 Telephony + 0x00 Unassigned + 0x01 Phone + 0x02 Answering Machine + 0x03 Message Controls + 0x04 Handset + 0x05 Headset + 0x06 Telephony Key Pad + 0x07 Programmable Button + 0x20 Hook Switch + 0x21 Flash + 0x22 Feature + 0x23 Hold + 0x24 Redial + 0x25 Transfer + 0x26 Drop + 0x27 Park + 0x28 Forward Calls + 0x29 Alternate Function + 0x2A Line + 0x2B Speaker Phone + 0x2C Conference + 0x2D Ring Enable + 0x2E Ring Select + 0x2F Phone Mute + 0x30 Caller ID + 0x50 Speed Dial + 0x51 Store Number + 0x52 Recall Number + 0x53 Phone Directory + 0x70 Voice Mail + 0x71 Screen Calls + 0x72 Do Not Disturb + 0x73 Message + 0x74 Answer On/Off + 0x90 Inside Dial Tone + 0x91 Outside Dial Tone + 0x92 Inside Ring Tone + 0x93 Outside Ring Tone + 0x94 Priority Ring Tone + 0x95 Inside Ringback + 0x96 Priority Ringback + 0x97 Line Busy Tone + 0x98 Reorder Tone + 0x99 Call Waiting Tone + 0x9A Confirmation Tone 1 + 0x9B Confirmation Tone 2 + 0x9C Tones Off + 0xB0 Phone Key 0 + 0xB1 Phone Key 1 + 0xB2 Phone Key 2 + 0xB3 Phone Key 3 + 0xB4 Phone Key 4 + 0xB5 Phone Key 5 + 0xB6 Phone Key 6 + 0xB7 Phone Key 7 + 0xB8 Phone Key 8 + 0xB9 Phone Key 9 + 0xBA Phone Key Star + 0xBB Phone Key Pound + 0xBC Phone Key A + 0xBD Phone Key B + 0xBE Phone Key C + 0xBF Phone Key D + +12 Consumer + 0x00 Unassigned + 0x01 Consumer Control + 0x02 Numeric Key Pad + 0x03 Programmable Buttons + 0x20 +10 + 0x21 +100 + 0x22 AM/PM + 0x30 Power + 0x31 Reset + 0x32 Sleep + 0x33 Sleep After + 0x34 Sleep Mode + 0x35 Illumination + 0x36 Function Buttons + 0x40 Menu + 0x41 Menu Pick + 0x42 Menu Up + 0x43 Menu Down + 0x44 Menu Left + 0x45 Menu Right + 0x46 Menu Escape + 0x47 Menu Value Increase + 0x48 Menu Value Decrease + 0x60 Data On Screen + 0x61 Closed Caption + 0x62 Closed Caption Select + 0x63 VCR/TV + 0x64 Broadcast Mode + 0x65 Snapshot + 0x66 Still + 0x80 Selection + 0x81 Assign Selection + 0x82 Mode Step + 0x83 Recall Last + 0x84 Enter Channel + 0x85 Order Movie + 0x86 Channel + 0x87 Media Selection + 0x88 Media Select Computer + 0x89 Media Select TV + 0x8A Media Select WWW + 0x8B Media Select DVD + 0x8C Media Select Telephone + 0x8D Media Select Program Guide + 0x8E Media Select Video Phone + 0x8F Media Select Games + 0x90 Media Select Messages + 0x91 Media Select CD + 0x92 Media Select VCR + 0x93 Media Select Tuner + 0x94 Quit + 0x95 Help + 0x96 Media Select Tape + 0x97 Media Select Cable + 0x98 Media Select Satellite + 0x99 Media Select Security + 0x9A Media Select Home + 0x9B Media Select Call + 0x9C Channel Increment + 0x9D Channel Decrement + 0x9E Media Select SAP + 0xA0 VCR Plus + 0xA1 Once + 0xA2 Daily + 0xA3 Weekly + 0xA4 Monthly + 0xB0 Play + 0xB1 Pause + 0xB2 Record + 0xB3 Fast Forward + 0xB4 Rewind + 0xB5 Scan Next Track + 0xB6 Scan Previous Track + 0xB7 Stop + 0xB8 Eject + 0xB9 Random Play + 0xBA Select DisC + 0xBB Enter Disc + 0xBC Repeat + 0xBD Tracking + 0xBE Track Normal + 0xBF Slow Tracking + 0xC0 Frame Forward + 0xC1 Frame Back + 0xC2 Mark + 0xC3 Clear Mark + 0xC4 Repeat From Mark + 0xC5 Return To Mark + 0xC6 Search Mark Forward + 0xC7 Search Mark Backwards + 0xC8 Counter Reset + 0xC9 Show Counter + 0xCA Tracking Increment + 0xCB Tracking Decrement + 0xE0 Volume + 0xE1 Balance + 0xE2 Mute + 0xE3 Bass + 0xE4 Treble + 0xE5 Bass Boost + 0xE6 Surround Mode + 0xE7 Loudness + 0xE8 MPX + 0xE9 Volume Up + 0xEA Volume Down + 0xF0 Speed Select + 0xF1 Playback Speed + 0xF2 Standard Play + 0xF3 Long Play + 0xF4 Extended Play + 0xF5 Slow + 0x100 Fan Enable + 0x101 Fan Speed + 0x102 Light + 0x103 Light Illumination Level + 0x104 Climate Control Enable + 0x105 Room Temperature + 0x106 Security Enable + 0x107 Fire Alarm + 0x108 Police Alarm + 0x150 Balance Right + 0x151 Balance Left + 0x152 Bass Increment + 0x153 Bass Decrement + 0x154 Treble Increment + 0x155 Treble Decrement + 0x160 Speaker System + 0x161 Channel Left + 0x162 Channel Right + 0x163 Channel Center + 0x164 Channel Front + 0x165 Channel Center Front + 0x166 Channel Side + 0x167 Channel Surround + 0x168 Channel Low Frequency Enhancement + 0x169 Channel Top + 0x16A Channel Unknown + 0x170 Sub-channel + 0x171 Sub-channel Increment + 0x172 Sub-channel Decrement + 0x173 Alternate Audio Increment + 0x174 Alternate Audio Decrement + 0x180 Application Launch Buttons + 0x181 AL Launch Button Configuration Tool + 0x182 AL Programmable Button Configuration + 0x183 AL Consumer Control Configuration + 0x184 AL Word Processor + 0x185 AL Text Editor + 0x186 AL Spreadsheet + 0x187 AL Graphics Editor + 0x188 AL Presentation App + 0x189 AL Database App + 0x18A AL Email Reader + 0x18B AL Newsreader + 0x18C AL Voicemail + 0x18D AL Contacts/Address Book + 0x18E AL Calendar/Schedule + 0x18F AL Task/Project Manager + 0x190 AL Log/Journal/Timecard + 0x191 AL Checkbook/Finance + 0x192 AL Calculator + 0x193 AL A/V Capture/Playback + 0x194 AL Local Machine Browser + 0x195 AL LAN/WAN Browser + 0x196 AL Internet Browser + 0x197 AL Remote Networking/ISP Connect + 0x198 AL Network Conference + 0x199 AL Network Chat + 0x19A AL Telephony/Dialer + 0x19B AL Logon + 0x19C AL Logoff + 0x19D AL Logon/Logoff + 0x19E AL Terminal Lock/Screensaver + 0x19F AL Control Panel + 0x1A0 AL Command Line Processor/Run + 0x1A1 AL Process/Task Manager + 0x1A2 AL Select Tast/Application + 0x1A3 AL Next Task/Application + 0x1A4 AL Previous Task/Application + 0x1A5 AL Preemptive Halt Task/Application + 0x200 Generic GUI Application Controls + 0x201 AC New + 0x202 AC Open + 0x203 AC Close + 0x204 AC Exit + 0x205 AC Maximize + 0x206 AC Minimize + 0x207 AC Save + 0x208 AC Print + 0x209 AC Properties + 0x21A AC Undo + 0x21B AC Copy + 0x21C AC Cut + 0x21D AC Paste + 0x21E AC Select All + 0x21F AC Find + 0x220 AC Find and Replace + 0x221 AC Search + 0x222 AC Go To + 0x223 AC Home + 0x224 AC Back + 0x225 AC Forward + 0x226 AC Stop + 0x227 AC Refresh + 0x228 AC Previous Link + 0x229 AC Next Link + 0x22A AC Bookmarks + 0x22B AC History + 0x22C AC Subscriptions + 0x22D AC Zoom In + 0x22E AC Zoom Out + 0x22F AC Zoom + 0x230 AC Full Screen View + 0x231 AC Normal View + 0x232 AC View Toggle + 0x233 AC Scroll Up + 0x234 AC Scroll Down + 0x235 AC Scroll + 0x236 AC Pan Left + 0x237 AC Pan Right + 0x238 AC Pan + 0x239 AC New Window + 0x23A AC Tile Horizontally + 0x23B AC Tile Vertically + 0x23C AC Format + +13 Digitizer + 0x00 Undefined + 0x01 Digitizer + 0x02 Pen + 0x03 Light Pen + 0x04 Touch Screen + 0x05 Touch Pad + 0x06 White Board + 0x07 Coordinate Measuring Machine + 0x08 3-D Digitizer + 0x09 Stereo Plotter + 0x0A Articulated Arm + 0x0B Armature + 0x0C Multiple Point Digitizer + 0x0D Free Space Wand + 0x20 Stylus + 0x21 Puck + 0x22 Finger + 0x30 Tip Pressure + 0x31 Barrel Pressure + 0x32 In Range + 0x33 Touch + 0x34 Untouch + 0x35 Tap + 0x36 Quality + 0x37 Data Valid + 0x38 Transducer Index + 0x39 Tablet Function Keys + 0x3A Program Change Keys + 0x3B Battery Strength + 0x3C Invert + 0x3D X Tilt + 0x3E Y Tilt + 0x3F Azimuth + 0x40 Altitude + 0x41 Twist + 0x42 Tip Switch + 0x43 Secondary Tip Switch + 0x44 Barrel Switch + 0x45 Eraser + 0x46 Tablet Pick + +15 Physical Interface Device + +16 Unicode + * Unicode Char u%04x + +20 Alphnumeric Display + 0x00 Undefined + 0x01 Alphanumeric Display + 0x20 Display Attributes Report + 0x21 ASCII Character Set + 0x22 Data Read Back + 0x23 Font Read Back + 0x24 Display Control Report + 0x25 Clear Display + 0x26 Display Enable + 0x27 Screen Saver Delay + 0x28 Screen Saver Enable + 0x29 Vertical Scroll + 0x2A Horizontal Scroll + 0x2B Character Report + 0x2C Display Data + 0x2D Display Status + 0x2E Stat Not Ready + 0x2F Stat Ready + 0x30 Err Not a loadable character + 0x31 Err Font data cannot be read + 0x32 Cursor Position Report + 0x33 Row + 0x34 Column + 0x35 Rows + 0x36 Columns + 0x37 Cursor Pixel Positioning + 0x38 Cursor Mode + 0x39 Cursor Enable + 0x3A Cursor Blink + 0x3B Font Report + 0x3C Font Data + 0x3D Character Width + 0x3E Character Height + 0x3F Character Spacing Horizontal + 0x40 Character Spacing Vertical + 0x41 Unicode Character Set + +128 Monitor + 0x00 Undefined + 0x01 Monitor Control + 0x02 EDID Information + 0x03 VDIF Information + 0x04 VESA Version + 0x05 On Screen Display + 0x06 Auto Size Center + 0x07 Polarity Horz Synch + 0x08 Polarity Vert Synch + 0x09 Sync Type + 0x0A Screen Position + 0x0B Horizontal Frequency + 0x0C Vertical Frequency + +129 Monitor Enumerated Values + 0x00 unassigned + * ENUM %d + +130 VESA Virtual Controls + 0x10 Brightness + 0x12 Contrast + 0x16 Video Gain Red + 0x18 Video Gain Green + 0x1A Video Gain Blue + 0x1C Focus + 0x20 Horizontal Position + 0x22 Horizontal Size + 0x24 Horizontal Pincushion + 0x26 Horizontal Pincushion Balance + 0x28 Horizontal Misconvergence + 0x2A Horizontal Linearity + 0x2C Horizontal Linearity Balance + 0x30 Vertical Position + 0x32 Vertical Size + 0x34 Vertical Pincushion + 0x36 Vertical Pincushion Balance + 0x38 Vertical Misconvergence + 0x3A Vertical Linearity + 0x3C Vertical Linearity Balance + 0x40 Parallelogram Distortion + 0x42 Trapezoidal Distortion + 0x44 Tilt + 0x46 Top Corner Distortion Control + 0x48 Top Corner Distortion Balance + 0x4A Bottom Corner Distortion Control + 0x4C Bottom Corner Distortion Balance + 0x56 Moiré Horizontal + 0x58 Moiré Vertical + 0x5E Input Level Select + 0x60 Input Source Select + 0x62 Stereo Mode + 0x6C Video Black Level Red + 0x6E Video Black Level Green + 0x70 Video Black Level Blue + +131 VESA Command + 0x00 Undefined + 0x01 Settings + 0x02 Degauss + +132 Power Device + 0x00 Undefined + 0x01 iName + 0x02 PresentStatus + 0x03 ChangedStatus + 0x04 UPS + 0x05 PowerSupply + 0x10 BatterySystem + 0x11 BatterySystemID + 0x12 Battery + 0x13 BatteryID + 0x14 Charger + 0x15 ChargerID + 0x16 PowerConverter + 0x17 PowerConverterID + 0x18 OutletSystem + 0x19 OutletSystemID + 0x1A Input + 0x1B InputID + 0x1C Output + 0x1D OutputID + 0x1E Flow + 0x1F FlowID + 0x20 Outlet + 0x21 OutletID + 0x22 Gang + 0x23 GangID + 0x24 Sink + 0x25 SinkID + 0x30 Voltage + 0x31 Current + 0x32 Frequency + 0x33 ApparentPower + 0x34 ActivePower + 0x35 PercentLoad + 0x36 Temperature + 0x37 Humidity + 0x40 ConfigVoltage + 0x41 ConfigCurrent + 0x42 ConfigFrequency + 0x43 ConfigApparentPower + 0x44 ConfigActivePower + 0x45 ConfigPercentLoad + 0x46 ConfigTemperature + 0x47 ConfigHumidity + 0x50 SwitchOnControl + 0x51 SwitchOffControl + 0x52 ToggleControl + 0x53 LowVoltageTransfer + 0x54 HighVoltageTransfer + 0x55 DelayBeforeReboot + 0x56 DelayBeforeStartup + 0x57 DelayBeforeShutdown + 0x58 Test + 0x59 Vendorspecificcommand + 0x60 Present + 0x61 Good + 0x62 InternalFailure + 0x63 VoltageOutOfRange + 0x64 FrequencyOutOfRange + 0x65 Overload + 0x66 OverCharged + 0x67 OverTemperature + 0x68 ShutdownRequested + 0x69 ShutdownImminent + 0x6A VendorSpecificAnswerValid + 0x6B SwitchOn/Off + 0x6C Switcheble + 0x6D Used + 0x6E Boost + 0x6F Buck + 0x70 Initialized + 0x71 Tested + +133 Battery System + 0x00 Undefined + 0x01 SMBBatteryMode + 0x02 SMBBatteryStatus + 0x03 SMBAlarmWarning + 0x04 SMBChargerMode + 0x05 SMBChargerStatus + 0x06 SMBChargerSpecInfo + 0x07 SMBSelectorState + 0x08 SMBSelectorPreset + 0x09 SMBSelectorInfo + 0x10 OptionalMfgFunction1 + 0x11 OptionalMfgFunction2 + 0x12 OptionalMfgFunction3 + 0x13 OptionalMfgFunction4 + 0x14 OptionalMfgFunction5 + 0x15 ConnectionToSMBus + 0x16 OutputConnection + 0x17 ChargerConnection + 0x18 BatteryInsertion + 0x19 Usenext + 0x1A OKToUse + 0x28 ManufacturerAccess + 0x29 RemainingCapacityLimit + 0x2A RemainingTimeLimit + 0x2B AtRate + 0x2C CapacityMode + 0x2D BroadcastToCharger + 0x2E PrimaryBattery + 0x2F ChargeController + 0x40 TerminateCharge + 0x41 TermminateDischarge + 0x42 BelowRemainingCapacityLimit + 0x43 RemainingTimeLimitExpired + 0x44 Charging + 0x45 Discharging + 0x46 FullyCharged + 0x47 FullyDischarged + 0x48 ConditionningFlag + 0x49 AtRateOK + 0x4A SMBErrorCode + 0x4B NeedReplacement + 0x60 AtRateTimeToFull + 0x61 AtRateTimeToEmpty + 0x62 AverageCurrent + 0x63 Maxerror + 0x64 RelativeStateOfCharge + 0x65 AbsoluteStateOfCharge + 0x66 RemainingCapacity + 0x67 FullChargeCapacity + 0x68 RunTimeToEmpty + 0x69 AverageTimeToEmpty + 0x6A AverageTimeToFull + 0x6B CycleCount + 0x80 BattPackModelLevel + 0x81 InternalChargeController + 0x82 PrimaryBatterySupport + 0x83 DesignCapacity + 0x84 SpecificationInfo + 0x85 ManufacturerDate + 0x86 SerialNumber + 0x87 iManufacturerName + 0x88 iDevicename + 0x89 iDeviceChemistery + 0x8A iManufacturerData + 0x8B Rechargeable + 0x8C WarningCapacityLimit + 0x8D CapacityGranularity1 + 0x8E CapacityGranularity2 + 0xC0 InhibitCharge + 0xC1 EnablePolling + 0xC2 ResetToZero + 0xD0 ACPresent + 0xD1 BatteryPresent + 0xD2 PowerFail + 0xD3 AlarmInhibited + 0xD4 ThermistorUnderRange + 0xD5 ThermistorHot + 0xD6 ThermistorCold + 0xD7 ThermistorOverRange + 0xD8 VoltageOutOfRange + 0xD9 CurrentOutOfRange + 0xDA CurrentNotRegulated + 0xDB VoltageNotRegulated + 0xDC MasterMode + 0xDD ChargerBattery/HostControlled + 0xF0 ChargerSpecInfo + 0xF1 ChargerSpecRef + 0xF2 Level2 + 0xF3 Level3 + +140 Bar Code Scanner + +141 Scale Device + +144 Camera Control + +145 Arcade Device + +# Some Micro$oft non-standard extensions +0xff00 Microsoft + 0xe9 Base Up + 0xea Base Down