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