This is useful for parsing the report descriptor with a different tool to find issues with our HID parser.
I've found https://eleccelerator.com/usbdescreqparser/ to be helpful. diff --git usr.bin/usbhidctl/usbhid.c usr.bin/usbhidctl/usbhid.c index 921f211a280..bd0b5da0222 100644 --- usr.bin/usbhidctl/usbhid.c +++ usr.bin/usbhidctl/usbhid.c @@ -106,6 +106,11 @@ static struct { #define REPORT_MAXVAL 2 }; +struct report_desc { + uint32_t size; + uint8_t data[1]; +}; + /* * Extract 16-bit unsigned usage ID from a numeric string. Returns -1 * if string failed to parse correctly. @@ -747,7 +752,7 @@ usage(void) fprintf(stderr, "usage: %s -f device [-t table] [-alv]\n", __progname); - fprintf(stderr, " %s -f device [-t table] [-v] -r\n", + fprintf(stderr, " %s -f device [-t table] [-v] [-r|-R]\n", __progname); fprintf(stderr, " %s -f device [-t table] [-lnv] name ...\n", @@ -764,16 +769,16 @@ main(int argc, char **argv) char const *dev; char const *table; size_t varnum; - int aflag, lflag, nflag, rflag, wflag; - int ch, hidfd; + int aflag, lflag, nflag, rflag, Rflag, wflag; + int ch, hidfd, x; 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 +795,9 @@ main(int argc, char **argv) case 'r': rflag = 1; break; + case 'R': + Rflag = 1; + break; case 't': table = optarg; break; @@ -807,7 +815,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 +951,12 @@ main(int argc, char **argv) if (repdesc == 0) errx(1, "USB_GET_REPORT_DESC"); + if (Rflag) { + for (x = 0; x < repdesc->size; x++) + printf("%s0x%02x", x > 0 ? " " : "", repdesc->data[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..54f5a49270d 100644 --- usr.bin/usbhidctl/usbhidctl.1 +++ usr.bin/usbhidctl/usbhidctl.1 @@ -47,6 +47,11 @@ .Nm .Fl f Ar device .Op Fl t Ar table +.Op Fl v +.Fl R +.Nm +.Fl f Ar device +.Op Fl t Ar table .Op Fl lnv .Ar name ... .Nm @@ -90,6 +95,8 @@ Suppress printing of the item name when querying specific items. Only output the current value. .It Fl r Dump the USB HID report descriptor. +.It Fl R +Dump the USB HID report descriptor as hexadecimal bytes. .It Fl t Ar table Specify a path name for the HID usage table file. .It Fl v
