]> git.itanic.dy.fi Git - glucose/blob - hiddev.c
Read options from command line
[glucose] / hiddev.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <sys/ioctl.h>
5 #include <linux/hiddev.h>
6 #include <errno.h>
7 #include <string.h>
8 #include <fcntl.h>
9
10 #include "hiddev.h"
11
12 #define PRINT_FIELD(field) printf(#field ": %04x\n", field)
13
14 int hiddev_read(unsigned char *data, int bufsize, int fd)
15 {
16         struct hiddev_event readBuffer[READ_BUFFER_LENGTH];
17         int ret, n, i;
18
19         ret = read(fd, readBuffer, sizeof(readBuffer));
20         if (ret < 0)
21                 return ret;
22
23         n = ret / sizeof(readBuffer[0]);
24         for (i = 0; i < n && i < bufsize; i++)
25                 data[i] = readBuffer[i].value;
26         return n;
27 }
28
29 int hiddev_write(const unsigned char data[64], int fd , int usage_code)
30 {
31         int rc = 0, uindex, error;
32
33         struct hiddev_usage_ref uref;
34         struct hiddev_report_info rinfo;
35
36         uref.report_id = *data++;
37         uref.report_type = HID_REPORT_TYPE_OUTPUT;
38         uref.field_index = 0;
39
40         uref.usage_code = usage_code;
41
42         for (uindex = 0; uindex < 63; uindex++) {
43                 uref.usage_index = uindex;
44                 uref.value = *data++;
45
46                 rc = ioctl(fd, HIDIOCSUSAGE, &uref);
47                 if (rc != 0)
48                         goto err;
49         }
50
51         rinfo.report_type = HID_REPORT_TYPE_OUTPUT;
52         rinfo.report_id =  0x0;
53         rinfo.num_fields = 1;
54
55         rc = ioctl(fd, HIDIOCSREPORT, &rinfo);
56         if (rc != 0)
57                 goto err2;
58
59         return 0;
60 err2:
61         printf("HIDIOCSREPORT\n");
62 err:
63         error = errno;
64         printf("Error in IOCTL: %s\n", strerror(error));
65
66         return rc;
67 }
68
69 static int get_usagecode(int fd)
70 {
71         struct hiddev_usage_ref uref;
72         int rc, error;
73
74         uref.report_type = HID_REPORT_TYPE_OUTPUT;
75         uref.report_id = 0x0;
76         uref.field_index = 0;
77         uref.usage_index = 0;
78
79         rc = ioctl(fd, HIDIOCGUCODE, &uref);
80         if (rc < 0) {
81                 error = errno;
82                 printf("Error gettin usage code: %s\n", strerror(error));
83                 return rc;
84         }
85
86         return uref.usage_code;
87 }
88
89 int hiddev_open(const char *device_path, int *usage_code)
90 {
91         struct hiddev_devinfo device_info;
92         struct hiddev_report_info rinfo;
93         int ret, error;
94         int fd;
95         fd = ret = open(device_path, O_RDWR);
96
97         if (fd < 0)
98                 goto err;
99
100
101         rinfo.report_type = HID_REPORT_TYPE_OUTPUT;
102         rinfo.report_id = HID_REPORT_ID_FIRST;
103         ret = ioctl(fd, HIDIOCGREPORTINFO, &rinfo);
104         if (ret < 0)
105                 goto err;
106
107         PRINT_FIELD(rinfo.report_type);
108         PRINT_FIELD(rinfo.report_id);
109         PRINT_FIELD(rinfo.num_fields);
110
111         *usage_code = get_usagecode(fd);
112
113         if (*usage_code < 0)
114                 return -8;
115
116         ret = ioctl(fd, HIDIOCGDEVINFO, &device_info);
117
118         if (ret < 0)
119                 goto err;
120
121         PRINT_FIELD(device_info.bustype);
122         PRINT_FIELD(device_info.busnum);
123         PRINT_FIELD(device_info.devnum);
124         PRINT_FIELD(device_info.ifnum);
125         PRINT_FIELD(device_info.vendor);
126         PRINT_FIELD(device_info.product);
127         PRINT_FIELD(device_info.version);
128         PRINT_FIELD(device_info.num_applications);
129
130         return fd;
131
132 err:
133         error = errno;
134         printf("Error opening device %s: %s\n", device_path, strerror(error));
135         return ret;
136 }
137