]> mj.ucw.cz Git - misc.git/blob - rawhid.c
Merge branch 'master' of git+ssh://git.ucw.cz/home/mj/GIT/misc
[misc.git] / rawhid.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <fcntl.h>
4 #include <unistd.h>
5 #include <sys/ioctl.h>
6 #include <linux/hidraw.h>
7
8 typedef unsigned char byte;
9 typedef unsigned int uns;
10
11 static void parse(byte *desc, uns size)
12 {
13         byte *end = desc + size;
14         uns indent = 0;
15
16         while (desc < end) {
17                 uns flags = *desc++;
18                 if (flags == 0xfe) {
19                         printf("FATAL: Unsupported long item found.\n");
20                         return;
21                 }
22                 if ((flags & 0x0c) == 0x0c) {
23                         printf("FATAL: Unsupported item type 3.\n");
24                         return;
25                 }
26                 const uns sizes[4] = { 0, 1, 2, 4 };
27                 uns size = sizes[flags & 3];
28                 if (desc + size > end) {
29                         printf("FATAL: Truncated item.\n");
30                         return;
31                 }
32                 uns val = 0;
33                 for (uns i=0; i<size; i++)
34                         val |= *desc++ << (8*i);
35
36                 printf("%*s%c%x[%d:%08x] ", indent, "", "MGL?"[(flags >> 2) & 3], flags >> 4, size, val);
37                 switch (flags & ~3) {
38                         /* Main */
39                         case 0x80:      printf("Input\n");
40                                         break;
41                         case 0x90:      printf("Output\n");
42                                         break;
43                         case 0xa0:      printf("Collection (type %d) {\n", val);
44                                         indent += 4;
45                                         break;
46                         case 0xb0:      printf("Feature\n");
47                                         break;
48                         case 0xc0:      printf("} EndCollection\n");
49                                         if (indent > 0)
50                                                 indent -= 4;
51                                         else
52                                                 printf("WARNING: Unbalanced collections!\n");
53                                         break;
54
55                         /* Global */
56                         case 0x04:      printf("UsagePage %04x\n", val);
57                                         break;
58                         case 0x14:      printf("LogicalMin %d\n", val);
59                                         break;
60                         case 0x24:      printf("LogicalMax %d\n", val);
61                                         break;
62                         case 0x34:      printf("PhysicalMin %d\n", val);
63                                         break;
64                         case 0x44:      printf("PhysicalMax %d\n", val);
65                                         break;
66                         case 0x54:      printf("UnitExponent\n");
67                                         break;
68                         case 0x64:      printf("Unit\n");
69                                         break;
70                         case 0x74:      printf("ReportSize %d\n", val);
71                                         break;
72                         case 0x84:      printf("ReportID %d\n", val);
73                                         break;
74                         case 0x94:      printf("ReportCount %d\n", val);
75                                         break;
76                         case 0xa4:      printf("PUSH\n");
77                                         break;
78                         case 0xb4:      printf("POP\n");
79                                         break;
80
81                         /* Local */
82                         case 0x08:      printf("Usage %04x\n", val);
83                                         break;
84                         case 0x18:      printf("UsageMin %04x\n", val);
85                                         break;
86                         case 0x28:      printf("UsageMax %04x\n", val);
87                                         break;
88                         case 0x38:      printf("DesignatorIndex %d\n", val);
89                                         break;
90                         case 0x48:      printf("DesignatorMin %d\n", val);
91                                         break;
92                         case 0x58:      printf("DesignatorMax %d\n", val);
93                                         break;
94                         case 0x78:      printf("StringIndex %d\n", val);
95                                         break;
96                         case 0x88:      printf("StringMin %d\n", val);
97                                         break;
98                         case 0x98:      printf("StringMax %d\n", val);
99                                         break;
100                         case 0xa8:      printf("Delimiter %s\n", (val==0 ? "open" : val==1 ? "close" : "???"));
101                                         break;
102
103                         /* Other */
104                         default:        printf("?\n");
105                 }
106         }
107
108         if (indent)
109                 printf("WARNING: Unbalanced collections!\n");
110 }
111
112 int main(void)
113 {
114         int fd = open("/dev/hidraw1", O_RDONLY);
115         if (fd < 0) {
116                 fprintf(stderr, "Cannot open hidraw: %m\n");
117                 return 1;
118         }
119
120         int size;
121         if (ioctl(fd, HIDIOCGRDESCSIZE, &size) < 0) {
122                 fprintf(stderr, "Cannot get desc size: %m\n");
123                 return 1;
124         }
125         printf("Detected descriptor size %d\n", size);
126
127         struct hidraw_report_descriptor desc;
128         desc.size = size;
129         if (ioctl(fd, HIDIOCGRDESC, &desc) < 0) {
130                 fprintf(stderr, "Cannot get desc contents: %m\n");
131                 return 1;
132         }
133         printf("Read %d bytes\n", desc.size);
134
135         struct hidraw_devinfo din;
136         if (ioctl(fd, HIDIOCGRAWINFO, &din) < 0) {
137                 fprintf(stderr, "Cannot get raw info: %m\n");
138                 return 1;
139         }
140         printf("bustype: %d, id=%04x:%04x\n", din.bustype, (unsigned short) din.vendor, (unsigned short) din.product);
141
142         parse(desc.value, size);
143         return 0;
144 }