2 * Copyright (C) 2012 Timo Kokkonen <timo.t.kokkonen@iki.fi>
4 * This program is free software; you can redistribute it and/or
5 * modify it under the terms of the GNU General Public License as
6 * published by the Free Software Foundation; either version 2 of the
7 * License, or (at your option) any later version.
9 * This program is distributed in the hope that it will be useful, but
10 * WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12 * General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
23 #include <sys/ioctl.h>
24 #include <sys/types.h>
25 #include <linux/hiddev.h>
34 #define PRINT_FIELD(level, field) trace(level, #field ": %04x\n", field)
36 #define HIDDEV_PATH "/dev/usb/"
38 int hiddev_read(unsigned char *data, int bufsize, int fd)
40 struct hiddev_event readBuffer[READ_BUFFER_LENGTH];
43 ret = read(fd, readBuffer, sizeof(readBuffer));
47 n = ret / sizeof(readBuffer[0]);
48 for (i = 0; i < n && i < bufsize; i++)
49 data[i] = readBuffer[i].value;
53 int hiddev_write(const unsigned char data[64], int fd , int usage_code)
55 int rc = 0, uindex, error;
57 struct hiddev_usage_ref uref;
58 struct hiddev_report_info rinfo;
60 uref.report_id = *data++;
61 uref.report_type = HID_REPORT_TYPE_OUTPUT;
64 uref.usage_code = usage_code;
66 for (uindex = 0; uindex < 63; uindex++) {
67 uref.usage_index = uindex;
70 rc = ioctl(fd, HIDIOCSUSAGE, &uref);
75 rinfo.report_type = HID_REPORT_TYPE_OUTPUT;
76 rinfo.report_id = 0x0;
79 rc = ioctl(fd, HIDIOCSREPORT, &rinfo);
85 printf("HIDIOCSREPORT\n");
88 printf("Error in IOCTL: %s\n", strerror(error));
93 static int get_usagecode(int fd)
95 struct hiddev_usage_ref uref;
98 uref.report_type = HID_REPORT_TYPE_OUTPUT;
100 uref.field_index = 0;
101 uref.usage_index = 0;
103 rc = ioctl(fd, HIDIOCGUCODE, &uref);
106 printf("Error gettin usage code: %s\n", strerror(error));
110 return uref.usage_code;
113 static int _hiddev_open(const char *device_path, int *usage_code,
114 int vendor_id, int product_id)
116 struct hiddev_devinfo device_info;
117 struct hiddev_report_info rinfo;
121 trace(3, "Opening device %s\n", device_path);
122 fd = ret = open(device_path, O_RDWR);
127 rinfo.report_type = HID_REPORT_TYPE_OUTPUT;
128 rinfo.report_id = HID_REPORT_ID_FIRST;
129 ret = ioctl(fd, HIDIOCGREPORTINFO, &rinfo);
133 PRINT_FIELD(3, rinfo.report_type);
134 PRINT_FIELD(3, rinfo.report_id);
135 PRINT_FIELD(3, rinfo.num_fields);
137 *usage_code = get_usagecode(fd);
142 ret = ioctl(fd, HIDIOCGDEVINFO, &device_info);
147 PRINT_FIELD(3, device_info.bustype);
148 PRINT_FIELD(3, device_info.busnum);
149 PRINT_FIELD(3, device_info.devnum);
150 PRINT_FIELD(3, device_info.ifnum);
151 PRINT_FIELD(3, device_info.vendor);
152 PRINT_FIELD(3, device_info.product);
153 PRINT_FIELD(3, device_info.version);
154 PRINT_FIELD(3, device_info.num_applications);
156 if (product_id && vendor_id) {
157 if (product_id == device_info.product &&
158 vendor_id == device_info.vendor)
160 trace(3, "Vendor and product IDs don't match\n");
172 printf("Error opening device %s: %s\n", device_path,
177 int hiddev_open(const char *device_path, int *usage_code)
179 return _hiddev_open(device_path, usage_code, 0, 0);
182 int hiddev_open_by_id(int vendor_id, int product_id, int *usage_code)
184 struct dirent *dirent;
189 dir = opendir(HIDDEV_PATH);
192 trace(4, "Failed to open directory %s: %s\n", HIDDEV_PATH,
198 dirent = readdir(dir);
202 if (strncmp(dirent->d_name, "hiddev", sizeof("hiddev") - 1))
206 strncat(path, HIDDEV_PATH, sizeof(path) - 1);
207 strncat(path, dirent->d_name, sizeof(path) - 1);
209 fd = _hiddev_open(path, usage_code, vendor_id, product_id);
217 trace(0, "Error reading directory %s: %s\n", HIDDEV_PATH,
222 trace(0, "Canno't find any mathing hiddev devices\n");