On Fri, 28 May 2021 at 21:52:57 -0500, joshua stein wrote: > > Another approach which keeps the structure opaque is the extend the > > usbhid(3) API with something like: > > > > void > > hid_get_report_desc_data(report_desc_t d, uint8_t **data, uint32_t > > *size) > > { > > *data = d->data; > > *size = d->size; > > }
Here's a new version of the usbhidctl diff using this new usbhid API, with man page help from jmc. diff --git usr.bin/usbhidctl/usbhid.c usr.bin/usbhidctl/usbhid.c index 921f211a280..910263d1392 100644 --- usr.bin/usbhidctl/usbhid.c +++ usr.bin/usbhidctl/usbhid.c @@ -755,6 +755,7 @@ usage(void) fprintf(stderr, " %s -f device [-t table] -w name=value ...\n", __progname); + fprintf(stderr, " %s -f device -R\n", __progname); exit(1); } @@ -764,16 +765,18 @@ main(int argc, char **argv) char const *dev; char const *table; size_t varnum; - int aflag, lflag, nflag, rflag, wflag; - int ch, hidfd; + uint32_t repsize; + int aflag, lflag, nflag, rflag, Rflag, wflag; + int ch, hidfd, x; + uint8_t *repdata; report_desc_t repdesc; char devnamebuf[PATH_MAX]; struct Susbvar variables[128]; - wflag = aflag = nflag = verbose = rflag = lflag = 0; + wflag = aflag = nflag = verbose = rflag = Rflag = lflag = 0; dev = NULL; table = NULL; - while ((ch = getopt(argc, argv, "?af:lnrt:vw")) != -1) { + while ((ch = getopt(argc, argv, "?af:lnRrt:vw")) != -1) { switch (ch) { case 'a': aflag = 1; @@ -790,6 +793,9 @@ main(int argc, char **argv) case 'r': rflag = 1; break; + case 'R': + Rflag = 1; + break; case 't': table = optarg; break; @@ -807,7 +813,8 @@ main(int argc, char **argv) } argc -= optind; argv += optind; - if (dev == NULL || (lflag && (wflag || rflag))) { + if (dev == NULL || (lflag && (wflag || rflag || Rflag)) || + (rflag && Rflag)) { /* * No device specified, or attempting to loop and set * or dump report at the same time @@ -942,6 +949,14 @@ main(int argc, char **argv) if (repdesc == 0) errx(1, "USB_GET_REPORT_DESC"); + if (Rflag) { + hid_get_report_desc_data(repdesc, &repdata, &repsize); + + for (x = 0; x < repsize; x++) + printf("%s0x%02x", x > 0 ? " " : "", repdata[x]); + printf("\n"); + } + if (lflag) { devloop(hidfd, repdesc, variables, varnum); /* NOTREACHED */ @@ -951,10 +966,11 @@ main(int argc, char **argv) /* Report mode header */ printf("Report descriptor:\n"); - devshow(hidfd, repdesc, variables, varnum, - 1 << hid_input | - 1 << hid_output | - 1 << hid_feature); + if (!Rflag) + devshow(hidfd, repdesc, variables, varnum, + 1 << hid_input | + 1 << hid_output | + 1 << hid_feature); if (rflag) { /* Report mode trailer */ diff --git usr.bin/usbhidctl/usbhidctl.1 usr.bin/usbhidctl/usbhidctl.1 index 5b8e59f7bd7..0aa5b54f6f9 100644 --- usr.bin/usbhidctl/usbhidctl.1 +++ usr.bin/usbhidctl/usbhidctl.1 @@ -53,6 +53,9 @@ .Fl f Ar device .Op Fl t Ar table .Fl w Ar name Ns = Ns Ar value ... +.Nm +.Fl f Ar device +.Fl R .Sh DESCRIPTION .Nm can be used to output or modify the state of a USB HID (Human Interface Device). @@ -88,6 +91,8 @@ Only 'input' items are displayed in this mode. .It Fl n Suppress printing of the item name when querying specific items. Only output the current value. +.It Fl R +Dump the raw USB HID report descriptor data as hexadecimal bytes. .It Fl r Dump the USB HID report descriptor. .It Fl t Ar table