Re: usbhidctl: add -R flag to dump raw report descriptor bytes

2021-05-30 Thread joshua stein
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, , );
+
+   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



Re: usbhidctl: add -R flag to dump raw report descriptor bytes

2021-05-30 Thread Theo Buehler
On Fri, May 28, 2021 at 09:52:57PM -0500, joshua stein wrote:
> On Wed, 26 May 2021 at 08:13:52 +0200, Anton Lindqvist wrote:
> > On Tue, May 25, 2021 at 08:31:14AM +0200, Anton Lindqvist wrote:
> > > On Mon, May 24, 2021 at 09:17:26AM -0500, joshua stein wrote:
> > > > 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];
> > > > +};
> > > 
> > > This structure is defined in lib/libusbhid/usbvar.h which is not
> > > installed. Maybe it should and avoid this repetition and potential ABI
> > > breaks (quite unlikely but still)?
> > 
> > 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 version of that:

libusbhid needs a minor bump:

Index: lib/libusbhid/shlib_version
===
RCS file: /cvs/src/lib/libusbhid/shlib_version,v
retrieving revision 1.8
diff -u -p -r1.8 shlib_version
--- lib/libusbhid/shlib_version 12 May 2014 17:03:28 -  1.8
+++ lib/libusbhid/shlib_version 30 May 2021 07:04:33 -
@@ -1,2 +1,2 @@
 major=7
-minor=0
+minor=1
Index: distrib/sets/lists/base/mi
===
RCS file: /cvs/src/distrib/sets/lists/base/mi,v
retrieving revision 1.1022
diff -u -p -r1.1022 mi
--- distrib/sets/lists/base/mi  27 May 2021 05:51:50 -  1.1022
+++ distrib/sets/lists/base/mi  30 May 2021 07:04:51 -
@@ -675,7 +675,7 @@
 ./usr/lib/libtermcap.so.14.0
 ./usr/lib/libtermlib.so.14.0
 ./usr/lib/libtls.so.21.0
-./usr/lib/libusbhid.so.7.0
+./usr/lib/libusbhid.so.7.1
 ./usr/lib/libutil.so.15.0
 ./usr/lib/libz.so.5.0
 ./usr/lib/locate



Re: usbhidctl: add -R flag to dump raw report descriptor bytes

2021-05-30 Thread Anton Lindqvist
On Fri, May 28, 2021 at 09:52:57PM -0500, joshua stein wrote:
> On Wed, 26 May 2021 at 08:13:52 +0200, Anton Lindqvist wrote:
> > On Tue, May 25, 2021 at 08:31:14AM +0200, Anton Lindqvist wrote:
> > > On Mon, May 24, 2021 at 09:17:26AM -0500, joshua stein wrote:
> > > > 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];
> > > > +};
> > > 
> > > This structure is defined in lib/libusbhid/usbvar.h which is not
> > > installed. Maybe it should and avoid this repetition and potential ABI
> > > breaks (quite unlikely but still)?
> > 
> > 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 version of that:

ok anton@



Re: usbhidctl: add -R flag to dump raw report descriptor bytes

2021-05-28 Thread joshua stein
On Wed, 26 May 2021 at 08:13:52 +0200, Anton Lindqvist wrote:
> On Tue, May 25, 2021 at 08:31:14AM +0200, Anton Lindqvist wrote:
> > On Mon, May 24, 2021 at 09:17:26AM -0500, joshua stein wrote:
> > > 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];
> > > +};
> > 
> > This structure is defined in lib/libusbhid/usbvar.h which is not
> > installed. Maybe it should and avoid this repetition and potential ABI
> > breaks (quite unlikely but still)?
> 
> 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 version of that:


diff --git lib/libusbhid/Makefile lib/libusbhid/Makefile
index 2d5a75004ad..be1adde806d 100644
--- lib/libusbhid/Makefile
+++ lib/libusbhid/Makefile
@@ -9,7 +9,7 @@ SRCS=   descr.c parse.c usage.c data.c
 CPPFLAGS+= -I${.CURDIR}
 
 includes:
-   @cd ${.CURDIR}; cmp -s usbhid.h ${DESTDIR}/usr/include/usbhid.h || \
+   cd ${.CURDIR}; cmp -s usbhid.h ${DESTDIR}/usr/include/usbhid.h || \
  ${INSTALL} ${INSTALL_COPY} -m 444 -o $(BINOWN) -g $(BINGRP) usbhid.h \
  ${DESTDIR}/usr/include
 
diff --git lib/libusbhid/descr.c lib/libusbhid/descr.c
index 9d81c2f0e3f..963108f644c 100644
--- lib/libusbhid/descr.c
+++ lib/libusbhid/descr.c
@@ -71,3 +71,10 @@ hid_dispose_report_desc(report_desc_t r)
 
free(r);
 }
+
+void
+hid_get_report_desc_data(report_desc_t d, uint8_t **data, uint32_t *size)
+{
+   *data = d->data;
+   *size = d->size;
+}
diff --git lib/libusbhid/usbhid.3 lib/libusbhid/usbhid.3
index 62771a95798..61b2d3fe2a9 100644
--- lib/libusbhid/usbhid.3
+++ lib/libusbhid/usbhid.3
@@ -33,6 +33,7 @@
 .Nm hid_get_report_desc ,
 .Nm hid_use_report_desc ,
 .Nm hid_dispose_report_desc ,
+.Nm hid_get_report_desc_data ,
 .Nm hid_start_parse ,
 .Nm hid_end_parse ,
 .Nm hid_get_item ,
@@ -55,6 +56,8 @@
 .Fn hid_use_report_desc "unsigned char *data" "unsigned int size"
 .Ft void
 .Fn hid_dispose_report_desc "report_desc_t d"
+.Ft void
+.Fn hid_get_report_desc_data "report_desc_t d" "uint8_t **data" "uint32_t 
*size"
 .Ft hid_data_t
 .Fn hid_start_parse "report_desc_t d" "int kindset" "int id"
 .Ft void
@@ -104,7 +107,8 @@ with a file descriptor obtained by opening a
 device.
 Alternatively a data buffer containing the report descriptor can be passed into
 .Fn hid_use_report_desc .
-The data is copied into an internal structure.
+The data is copied into an internal structure which can be accessed with
+.Fn hid_get_report_desc_data .
 When the report descriptor is no longer needed it should be freed by calling
 .Fn hid_dispose_report_desc .
 The type
diff --git lib/libusbhid/usbhid.h lib/libusbhid/usbhid.h
index 39adb4ad02f..8694c3aea1d 100644
--- lib/libusbhid/usbhid.h
+++ lib/libusbhid/usbhid.h
@@ -77,6 +77,7 @@ typedef struct hid_item {
 report_desc_t  hid_get_report_desc(int file);
 report_desc_t  hid_use_report_desc(unsigned char *data, unsigned int size);
 void   hid_dispose_report_desc(report_desc_t);
+void   hid_get_report_desc_data(report_desc_t, uint8_t **, uint32_t *);
 
 /* Parsing of a HID report descriptor, parse.c: */
 hid_data_t hid_start_parse(report_desc_t d, int kindset, int id);