aboutsummaryrefslogtreecommitdiff
path: root/usr.bin/usbhidctl
diff options
context:
space:
mode:
authorAlexander Motin <mav@FreeBSD.org>2011-07-30 13:22:44 +0000
committerAlexander Motin <mav@FreeBSD.org>2011-07-30 13:22:44 +0000
commit1bee2ec756f2ea5255f9f68dd58c1ceae1a2f56c (patch)
tree71e3c3510b7c799897cb17384eecaf618c0fe4f7 /usr.bin/usbhidctl
parentc86c3aa3d989e26dd7f07bef51bec950e95a7727 (diff)
downloadsrc-1bee2ec756f2ea5255f9f68dd58c1ceae1a2f56c.tar.gz
src-1bee2ec756f2ea5255f9f68dd58c1ceae1a2f56c.zip
MFprojects/hid:
- Fix usbhidctl and usbhidaction to handle HID devices with multiple report ids, such as multimedia keyboards. - Add collection type and report id to the `usbhidctl -r` output. They are important for proper device understanding and debugging. - Fix usbhidaction tool to properly handle items having report_count more then 1. Approved by: re (kib) MFC after: 2 weeks
Notes
Notes: svn path=/head/; revision=224511
Diffstat (limited to 'usr.bin/usbhidctl')
-rw-r--r--usr.bin/usbhidctl/usbhid.c54
1 files changed, 39 insertions, 15 deletions
diff --git a/usr.bin/usbhidctl/usbhid.c b/usr.bin/usbhidctl/usbhid.c
index 2ac947d2a5f6..281078d3de2f 100644
--- a/usr.bin/usbhidctl/usbhid.c
+++ b/usr.bin/usbhidctl/usbhid.c
@@ -46,7 +46,6 @@ int verbose = 0;
int all = 0;
int noname = 0;
int hexdump = 0;
-static int reportid;
char **names;
int nnames;
@@ -101,11 +100,12 @@ dumpitem(const char *label, struct hid_item *h)
{
if ((h->flags & HIO_CONST) && !verbose)
return;
- printf("%s size=%d count=%d page=%s usage=%s%s", label,
- h->report_size, h->report_count,
+ printf("%s rid=%d size=%d count=%d page=%s usage=%s%s%s", label,
+ h->report_ID, h->report_size, h->report_count,
hid_usage_page(HID_PAGE(h->usage)),
hid_usage_in_page(h->usage),
- h->flags & HIO_CONST ? " Const" : "");
+ h->flags & HIO_CONST ? " Const" : "",
+ h->flags & HIO_VARIABLE ? "" : " Array");
printf(", logical range %d..%d",
h->logical_minimum, h->logical_maximum);
if (h->physical_minimum != h->physical_maximum)
@@ -116,6 +116,24 @@ dumpitem(const char *label, struct hid_item *h)
printf("\n");
}
+static const char *
+hid_collection_type(int32_t type)
+{
+ static char num[8];
+
+ switch (type) {
+ case 0: return ("Physical");
+ case 1: return ("Application");
+ case 2: return ("Logical");
+ case 3: return ("Report");
+ case 4: return ("Named_Array");
+ case 5: return ("Usage_Switch");
+ case 6: return ("Usage_Modifier");
+ }
+ snprintf(num, sizeof(num), "0x%02x", type);
+ return (num);
+}
+
void
dumpitems(report_desc_t r)
{
@@ -123,10 +141,11 @@ dumpitems(report_desc_t r)
struct hid_item h;
int size;
- for (d = hid_start_parse(r, ~0, reportid); hid_get_item(d, &h); ) {
+ for (d = hid_start_parse(r, ~0, -1); hid_get_item(d, &h); ) {
switch (h.kind) {
case hid_collection:
- printf("Collection page=%s usage=%s\n",
+ printf("Collection type=%s page=%s usage=%s\n",
+ hid_collection_type(h.collection),
hid_usage_page(HID_PAGE(h.usage)),
hid_usage_in_page(h.usage));
break;
@@ -145,13 +164,13 @@ dumpitems(report_desc_t r)
}
}
hid_end_parse(d);
- size = hid_report_size(r, hid_input, 0);
+ size = hid_report_size(r, hid_input, -1);
printf("Total input size %d bytes\n", size);
- size = hid_report_size(r, hid_output, 0);
+ size = hid_report_size(r, hid_output, -1);
printf("Total output size %d bytes\n", size);
- size = hid_report_size(r, hid_feature, 0);
+ size = hid_report_size(r, hid_feature, -1);
printf("Total feature size %d bytes\n", size);
}
@@ -180,14 +199,17 @@ prdata(u_char *buf, struct hid_item *h)
pos = h->pos;
for (i = 0; i < h->report_count; i++) {
data = hid_get_data(buf, h);
+ if (i > 0)
+ printf(" ");
if (h->logical_minimum < 0)
printf("%d", (int)data);
else
printf("%u", data);
if (hexdump)
printf(" [0x%x]", data);
- pos += h->report_size;
+ h->pos += h->report_size;
}
+ h->pos = pos;
}
void
@@ -202,7 +224,7 @@ dumpdata(int f, report_desc_t rd, int loop)
char namebuf[10000], *namep;
hids = 0;
- for (d = hid_start_parse(rd, 1<<hid_input, reportid);
+ for (d = hid_start_parse(rd, 1<<hid_input, -1);
hid_get_item(d, &h); ) {
if (h.kind == hid_collection)
colls[++sp] = h.usage;
@@ -217,7 +239,7 @@ dumpdata(int f, report_desc_t rd, int loop)
}
hid_end_parse(d);
rev(&hids);
- dlen = hid_report_size(rd, hid_input, 0);
+ dlen = hid_report_size(rd, hid_input, -1);
dbuf = malloc(dlen);
if (!loop)
if (hid_set_immed(f, 1) < 0) {
@@ -228,10 +250,12 @@ dumpdata(int f, report_desc_t rd, int loop)
}
do {
r = read(f, dbuf, dlen);
- if (r != dlen) {
- err(1, "bad read %d != %d", r, dlen);
+ if (r < 1) {
+ err(1, "read error");
}
for (n = hids; n; n = n->next) {
+ if (n->report_ID != 0 && dbuf[0] != n->report_ID)
+ continue;
namep = namebuf;
namep += sprintf(namep, "%s:%s.",
hid_usage_page(HID_PAGE(n->collection)),
@@ -242,7 +266,7 @@ dumpdata(int f, report_desc_t rd, int loop)
if (all || gotname(namebuf)) {
if (!noname)
printf("%s=", namebuf);
- prdata(dbuf + (reportid != 0), n);
+ prdata(dbuf, n);
printf("\n");
}
}