From 71f91fa4b7a8d2bcb368c8b32181bc917e2b6037 Mon Sep 17 00:00:00 2001 From: Martin Mares Date: Sun, 2 Aug 2009 20:17:42 +0200 Subject: [PATCH] HID games... --- Makefile | 2 + hidtest.c | 4 +- rawhid.c | 144 ++++++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 148 insertions(+), 2 deletions(-) create mode 100644 rawhid.c diff --git a/Makefile b/Makefile index 781c602..5c3729f 100644 --- a/Makefile +++ b/Makefile @@ -20,5 +20,7 @@ batt: LDFLAGS+=$(shell xosd-config --libs) xclipcat: LDFLAGS+=-L/usr/X11R6/lib -lX11 xclipsend: LDFLAGS+=-L/usr/X11R6/lib -lX11 +rawhid: CFLAGS+=-I ~/linux/linux-2.6.28/include + clean: rm -f `find . -name "*~" -or -name "*.[oa]" -or -name "\#*\#" -or -name TAGS -or -name core -or -name .depend -or -name .#*` diff --git a/hidtest.c b/hidtest.c index 07e8065..f2d4a95 100644 --- a/hidtest.c +++ b/hidtest.c @@ -4,7 +4,7 @@ #include #include #include -#include "/home/mj/linux/linux-2.6.23.9/include/linux/hiddev.h" +#include "/home/mj/linux/linux-2.6.27.4/include/linux/hiddev.h" static void die(char *x) { @@ -15,7 +15,7 @@ static void die(char *x) int main(void) { int i, j; - int fd = open("/dev/usb/hiddev0", O_RDWR); + int fd = open("/dev/.static/dev/usb/hiddev5", O_RDWR); if (fd < 0) die("open"); int ver; diff --git a/rawhid.c b/rawhid.c new file mode 100644 index 0000000..431833f --- /dev/null +++ b/rawhid.c @@ -0,0 +1,144 @@ +#include +#include +#include +#include +#include +#include + +typedef unsigned char byte; +typedef unsigned int uns; + +static void parse(byte *desc, uns size) +{ + byte *end = desc + size; + uns indent = 0; + + while (desc < end) { + uns flags = *desc++; + if (flags == 0xfe) { + printf("FATAL: Unsupported long item found.\n"); + return; + } + if ((flags & 0x0c) == 0x0c) { + printf("FATAL: Unsupported item type 3.\n"); + return; + } + const uns sizes[4] = { 0, 1, 2, 4 }; + uns size = sizes[flags & 3]; + if (desc + size > end) { + printf("FATAL: Truncated item.\n"); + return; + } + uns val = 0; + for (uns i=0; i> 2) & 3], flags >> 4, size, val); + switch (flags & ~3) { + /* Main */ + case 0x80: printf("Input\n"); + break; + case 0x90: printf("Output\n"); + break; + case 0xa0: printf("Collection (type %d) {\n", val); + indent += 4; + break; + case 0xb0: printf("Feature\n"); + break; + case 0xc0: printf("} EndCollection\n"); + if (indent > 0) + indent -= 4; + else + printf("WARNING: Unbalanced collections!\n"); + break; + + /* Global */ + case 0x04: printf("UsagePage %04x\n", val); + break; + case 0x14: printf("LogicalMin %d\n", val); + break; + case 0x24: printf("LogicalMax %d\n", val); + break; + case 0x34: printf("PhysicalMin %d\n", val); + break; + case 0x44: printf("PhysicalMax %d\n", val); + break; + case 0x54: printf("UnitExponent\n"); + break; + case 0x64: printf("Unit\n"); + break; + case 0x74: printf("ReportSize %d\n", val); + break; + case 0x84: printf("ReportID %d\n", val); + break; + case 0x94: printf("ReportCount %d\n", val); + break; + case 0xa4: printf("PUSH\n"); + break; + case 0xb4: printf("POP\n"); + break; + + /* Local */ + case 0x08: printf("Usage %04x\n", val); + break; + case 0x18: printf("UsageMin %04x\n", val); + break; + case 0x28: printf("UsageMax %04x\n", val); + break; + case 0x38: printf("DesignatorIndex %d\n", val); + break; + case 0x48: printf("DesignatorMin %d\n", val); + break; + case 0x58: printf("DesignatorMax %d\n", val); + break; + case 0x78: printf("StringIndex %d\n", val); + break; + case 0x88: printf("StringMin %d\n", val); + break; + case 0x98: printf("StringMax %d\n", val); + break; + case 0xa8: printf("Delimiter %s\n", (val==0 ? "open" : val==1 ? "close" : "???")); + break; + + /* Other */ + default: printf("?\n"); + } + } + + if (indent) + printf("WARNING: Unbalanced collections!\n"); +} + +int main(void) +{ + int fd = open("/dev/hidraw1", O_RDONLY); + if (fd < 0) { + fprintf(stderr, "Cannot open hidraw: %m\n"); + return 1; + } + + int size; + if (ioctl(fd, HIDIOCGRDESCSIZE, &size) < 0) { + fprintf(stderr, "Cannot get desc size: %m\n"); + return 1; + } + printf("Detected descriptor size %d\n", size); + + struct hidraw_report_descriptor desc; + desc.size = size; + if (ioctl(fd, HIDIOCGRDESC, &desc) < 0) { + fprintf(stderr, "Cannot get desc contents: %m\n"); + return 1; + } + printf("Read %d bytes\n", desc.size); + + struct hidraw_devinfo din; + if (ioctl(fd, HIDIOCGRAWINFO, &din) < 0) { + fprintf(stderr, "Cannot get raw info: %m\n"); + return 1; + } + printf("bustype: %d, id=%04x:%04x\n", din.bustype, (unsigned short) din.vendor, (unsigned short) din.product); + + parse(desc.value, size); + return 0; +} -- 2.39.2