6 #include <linux/types.h>
7 #include <linux/hiddev.h>
12 #define PRINT_FIELD(field) printf(#field ": %04x\n", field)
14 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]))
16 #define READ_BUFFER_LENGTH 64
20 unsigned char data[64];
28 static int is_printable(const unsigned char c)
30 return c >= 0x20 && c < 0x80;
33 static int datalen(const unsigned char *data)
37 for (i = 0, len = 0; i < 64; i++)
44 static void print_hex(const unsigned char *data, int len)
48 for (i = 0; i < len; i++)
49 printf("0x%02x ", data[i]);
54 static void print_ascii(const unsigned char *data, int len)
58 for (i = 0; i < len; i++)
59 printf("%c", is_printable(data[i]) ? data[i] : '.');
64 int hid_read(unsigned char *data, int bufsize, int fd)
66 struct hiddev_event readBuffer[READ_BUFFER_LENGTH];
69 ret = read(fd, readBuffer, sizeof(readBuffer));
73 n = ret / sizeof(readBuffer[0]);
74 for (i = 0; i < n && i < bufsize; i++)
75 data[i] = readBuffer[i].value;
80 int hid_write(const unsigned char data[64], int fd , int usage_code)
82 int rc = 0, uindex, error;
84 struct hiddev_usage_ref uref;
85 struct hiddev_report_info rinfo;
87 uref.report_id = *data++;
88 uref.report_type = HID_REPORT_TYPE_OUTPUT;
91 uref.usage_code = usage_code;
93 for (uindex = 0; uindex < 63; uindex++) {
94 uref.usage_index = uindex;
97 rc = ioctl(fd, HIDIOCSUSAGE, &uref);
102 rinfo.report_type = HID_REPORT_TYPE_OUTPUT;
103 rinfo.report_id = 0x0;
104 rinfo.num_fields = 1;
106 rc = ioctl(fd, HIDIOCSREPORT, &rinfo);
112 printf("HIDIOCSREPORT\n");
115 printf("Error in IOCTL: %s\n", strerror(error));
120 int get_usagecode(int fd)
122 struct hiddev_usage_ref uref;
125 uref.report_type = HID_REPORT_TYPE_OUTPUT;
126 uref.report_id = 0x0;
127 uref.field_index = 0;
128 uref.usage_index = 0;
130 rc = ioctl(fd, HIDIOCGUCODE, &uref);
133 printf("Error gettin usage code: %s\n", strerror(error));
137 return uref.usage_code;
140 int hiddev_open(const char *device_path, int *usage_code)
142 struct hiddev_devinfo device_info;
143 struct hiddev_report_info rinfo;
146 fd = ret = open(device_path, O_RDWR);
152 rinfo.report_type = HID_REPORT_TYPE_OUTPUT;
153 rinfo.report_id = HID_REPORT_ID_FIRST;
154 ret = ioctl(fd, HIDIOCGREPORTINFO, &rinfo);
158 PRINT_FIELD(rinfo.report_type);
159 PRINT_FIELD(rinfo.report_id);
160 PRINT_FIELD(rinfo.num_fields);
162 *usage_code = get_usagecode(fd);
167 ret = ioctl(fd, HIDIOCGDEVINFO, &device_info);
172 PRINT_FIELD(device_info.bustype);
173 PRINT_FIELD(device_info.busnum);
174 PRINT_FIELD(device_info.devnum);
175 PRINT_FIELD(device_info.ifnum);
176 PRINT_FIELD(device_info.vendor);
177 PRINT_FIELD(device_info.product);
178 PRINT_FIELD(device_info.version);
179 PRINT_FIELD(device_info.num_applications);
185 printf("Error opening device %s: %s\n", device_path, strerror(error));
189 int send_msg(const struct msg *msg, int fd, int usage_code)
193 if (msg->direction != OUT) {
194 printf("Message direction is not OUT\n");
200 print_hex(msg->data + 1, datalen(msg->data) - 1);
201 print_ascii(msg->data + 1, datalen(msg->data) - 1);
203 ret = hid_write(msg->data, fd, usage_code);
210 int read_and_verify(struct msg *msg, int fd)
212 unsigned char buf[64];
215 while (offset < 64) {
216 ret = hid_read(buf + offset, sizeof(buf) - offset, fd);
224 memcpy(msg->data, buf, sizeof(buf));
225 printf("Got data %d: ", datalen(buf));
226 // print_hex(buf, datalen(buf));
227 print_ascii(buf, datalen(buf));
232 int read_msgs(int fd)
236 read_and_verify(&msg, fd);
237 if (datalen(msg.data) <= 36)
244 #define SET_FIRST_BYTE(byte) \
246 memset(&msg.data, 0, sizeof(msg.data)); \
247 msg.data[4] = (byte); \
251 #define SET_BYTE(idx, byte) \
253 msg.data[(idx) + 4] = (byte); \
257 #define SET_BYTES(byte) msg.data[j++] = (byte)
259 int send_pattern(int fd, int uc, unsigned char byte1, unsigned char byte2)
265 SET_FIRST_BYTE(0x01);
267 send_msg(&msg, fd, uc);
271 send_msg(&msg, fd, uc);
275 send_msg(&msg, fd, uc);
278 SET_FIRST_BYTE(0x02);
281 send_msg(&msg, fd, uc);
285 send_msg(&msg, fd, uc);
291 int communicate(int fd, int uc)
298 SET_FIRST_BYTE(0x01);
300 send_msg(&msg, fd, uc);
304 send_msg(&msg, fd, uc);
308 for (i = 0; i < 6; i++) {
309 send_msg(&msg, fd, uc);
314 send_msg(&msg, fd, uc);
318 send_msg(&msg, fd, uc);
321 send_pattern(fd, uc, 'R', 'A');
322 send_pattern(fd, uc, 'R', 'C');
323 send_pattern(fd, uc, 'R', 'D');
324 send_pattern(fd, uc, 'R', 'G');
325 send_pattern(fd, uc, 'R', 'I');
326 send_pattern(fd, uc, 'R', 'M');
327 send_pattern(fd, uc, 'R', 'P');
328 send_pattern(fd, uc, 'R', 'R');
329 send_pattern(fd, uc, 'R', 'S');
330 send_pattern(fd, uc, 'R', 'T');
331 send_pattern(fd, uc, 'R', 'U');
332 send_pattern(fd, uc, 'R', 'V');
333 send_pattern(fd, uc, 'R', 'W');
334 send_pattern(fd, uc, 'R', 'X');
335 send_pattern(fd, uc, 'W', 'K');
337 SET_FIRST_BYTE(0x08);
346 send_msg(&msg, fd, uc);
349 SET_FIRST_BYTE(0x02);
352 send_msg(&msg, fd, uc);
356 send_msg(&msg, fd, uc);
360 send_msg(&msg, fd, uc);
364 send_msg(&msg, fd, uc);
368 send_msg(&msg, fd, uc);
371 send_pattern(fd, uc, 'R', 'Z');
373 SET_FIRST_BYTE(0x01);
375 send_msg(&msg, fd, uc);
379 send_msg(&msg, fd, uc);
383 send_msg(&msg, fd, uc);
387 send_msg(&msg, fd, uc);
390 send_msg(&msg, fd, uc);
394 send_msg(&msg, fd, uc);
397 send_msg(&msg, fd, uc);
400 send_msg(&msg, fd, uc);
404 send_msg(&msg, fd, uc);
405 read_and_verify(&in, fd);
406 } while (datalen(in.data) > 45);
411 int main(int argc, char *argv[])
415 fd = hiddev_open(argv[1], &usage_code);
419 communicate(fd, usage_code);