1 /*******************************************************
2  HIDAPI - Multi-Platform library for
3  communication with HID devices.
4 
5  Alan Ott
6  Signal 11 Software
7 
8  8/22/2009
9  Linux Version - 6/2/2009
10 
11  Copyright 2009, All Rights Reserved.
12 
13  At the discretion of the user of this library,
14  this software may be licensed under the terms of the
15  GNU General Public License v3, a BSD-Style license, or the
16  original HIDAPI license as outlined in the LICENSE.txt,
17  LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
18  files located at the root of the source distribution.
19  These files may also be found in the public source
20  code repository located at:
21         http://github.com/signal11/hidapi .
22 ********************************************************/
23 
24 /* C */
25 #include <stdio.h>
26 #include <string.h>
27 #include <stdlib.h>
28 #include <locale.h>
29 #include <errno.h>
30 
31 /* Unix */
32 #include <unistd.h>
33 #include <sys/types.h>
34 #include <sys/stat.h>
35 #include <sys/ioctl.h>
36 #include <sys/utsname.h>
37 #include <fcntl.h>
38 #include <poll.h>
39 
40 /* Linux */
41 #include <linux/hidraw.h>
42 #include <linux/version.h>
43 #include <linux/input.h>
44 #include <libudev.h>
45 
46 #include "hidapi.h"
47 
48 /* Definitions from linux/hidraw.h. Since these are new, some distros
49    may not have header files which contain them. */
50 #ifndef HIDIOCSFEATURE
51 #define HIDIOCSFEATURE(len)    _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x06, len)
52 #endif
53 #ifndef HIDIOCGFEATURE
54 #define HIDIOCGFEATURE(len)    _IOC(_IOC_WRITE|_IOC_READ, 'H', 0x07, len)
55 #endif
56 
57 
58 /* USB HID device property names */
59 const char *device_string_names[] = {
60 	"manufacturer",
61 	"product",
62 	"serial",
63 };
64 
65 /* Symbolic names for the properties above */
66 enum device_string_id {
67 	DEVICE_STRING_MANUFACTURER,
68 	DEVICE_STRING_PRODUCT,
69 	DEVICE_STRING_SERIAL,
70 
71 	DEVICE_STRING_COUNT,
72 };
73 
74 struct hid_device_ {
75 	int device_handle;
76 	int blocking;
77 	int uses_numbered_reports;
78 };
79 
80 
81 static __u32 kernel_version = 0;
82 
detect_kernel_version(void)83 static __u32 detect_kernel_version(void)
84 {
85 	struct utsname name;
86 	int major, minor, release;
87 	int ret;
88 
89 	uname(&name);
90 	ret = sscanf(name.release, "%d.%d.%d", &major, &minor, &release);
91 	if (ret == 3) {
92 		return KERNEL_VERSION(major, minor, release);
93 	}
94 
95 	ret = sscanf(name.release, "%d.%d", &major, &minor);
96 	if (ret == 2) {
97 		return KERNEL_VERSION(major, minor, 0);
98 	}
99 
100 	printf("Couldn't determine kernel version from version string \"%s\"\n", name.release);
101 	return 0;
102 }
103 
new_hid_device(void)104 static hid_device *new_hid_device(void)
105 {
106 	hid_device *dev = calloc(1, sizeof(hid_device));
107 	dev->device_handle = -1;
108 	dev->blocking = 1;
109 	dev->uses_numbered_reports = 0;
110 
111 	return dev;
112 }
113 
114 
115 /* The caller must free the returned string with free(). */
utf8_to_wchar_t(const char * utf8)116 static wchar_t *utf8_to_wchar_t(const char *utf8)
117 {
118 	wchar_t *ret = NULL;
119 
120 	if (utf8) {
121 		size_t wlen = mbstowcs(NULL, utf8, 0);
122 		if ((size_t) -1 == wlen) {
123 			return wcsdup(L"");
124 		}
125 		ret = calloc(wlen+1, sizeof(wchar_t));
126 		mbstowcs(ret, utf8, wlen+1);
127 		ret[wlen] = 0x0000;
128 	}
129 
130 	return ret;
131 }
132 
133 /* Get an attribute value from a udev_device and return it as a whar_t
134    string. The returned string must be freed with free() when done.*/
copy_udev_string(struct udev_device * dev,const char * udev_name)135 static wchar_t *copy_udev_string(struct udev_device *dev, const char *udev_name)
136 {
137 	return utf8_to_wchar_t(udev_device_get_sysattr_value(dev, udev_name));
138 }
139 
140 /* uses_numbered_reports() returns 1 if report_descriptor describes a device
141    which contains numbered reports. */
uses_numbered_reports(__u8 * report_descriptor,__u32 size)142 static int uses_numbered_reports(__u8 *report_descriptor, __u32 size) {
143 	unsigned int i = 0;
144 	int size_code;
145 	int data_len, key_size;
146 
147 	while (i < size) {
148 		int key = report_descriptor[i];
149 
150 		/* Check for the Report ID key */
151 		if (key == 0x85/*Report ID*/) {
152 			/* This device has a Report ID, which means it uses
153 			   numbered reports. */
154 			return 1;
155 		}
156 
157 		//printf("key: %02hhx\n", key);
158 
159 		if ((key & 0xf0) == 0xf0) {
160 			/* This is a Long Item. The next byte contains the
161 			   length of the data section (value) for this key.
162 			   See the HID specification, version 1.11, section
163 			   6.2.2.3, titled "Long Items." */
164 			if (i+1 < size)
165 				data_len = report_descriptor[i+1];
166 			else
167 				data_len = 0; /* malformed report */
168 			key_size = 3;
169 		}
170 		else {
171 			/* This is a Short Item. The bottom two bits of the
172 			   key contain the size code for the data section
173 			   (value) for this key.  Refer to the HID
174 			   specification, version 1.11, section 6.2.2.2,
175 			   titled "Short Items." */
176 			size_code = key & 0x3;
177 			switch (size_code) {
178 			case 0:
179 			case 1:
180 			case 2:
181 				data_len = size_code;
182 				break;
183 			case 3:
184 				data_len = 4;
185 				break;
186 			default:
187 				/* Can't ever happen since size_code is & 0x3 */
188 				data_len = 0;
189 				break;
190 			};
191 			key_size = 1;
192 		}
193 
194 		/* Skip over this key and it's associated data */
195 		i += data_len + key_size;
196 	}
197 
198 	/* Didn't find a Report ID key. Device doesn't use numbered reports. */
199 	return 0;
200 }
201 
202 /*
203  * The caller is responsible for free()ing the (newly-allocated) character
204  * strings pointed to by serial_number_utf8 and product_name_utf8 after use.
205  */
206 static int
parse_uevent_info(const char * uevent,int * bus_type,unsigned short * vendor_id,unsigned short * product_id,char ** serial_number_utf8,char ** product_name_utf8)207 parse_uevent_info(const char *uevent, int *bus_type,
208 	unsigned short *vendor_id, unsigned short *product_id,
209 	char **serial_number_utf8, char **product_name_utf8)
210 {
211 	char *tmp = strdup(uevent);
212 	char *saveptr = NULL;
213 	char *line;
214 	char *key;
215 	char *value;
216 
217 	int found_id = 0;
218 	int found_serial = 0;
219 	int found_name = 0;
220 
221 	line = strtok_r(tmp, "\n", &saveptr);
222 	while (line != NULL) {
223 		/* line: "KEY=value" */
224 		key = line;
225 		value = strchr(line, '=');
226 		if (!value) {
227 			goto next_line;
228 		}
229 		*value = '\0';
230 		value++;
231 
232 		if (strcmp(key, "HID_ID") == 0) {
233 			/**
234 			 *        type vendor   product
235 			 * HID_ID=0003:000005AC:00008242
236 			 **/
237 			int ret = sscanf(value, "%x:%hx:%hx", bus_type, vendor_id, product_id);
238 			if (ret == 3) {
239 				found_id = 1;
240 			}
241 		} else if (strcmp(key, "HID_NAME") == 0) {
242 			/* The caller has to free the product name */
243 			*product_name_utf8 = strdup(value);
244 			found_name = 1;
245 		} else if (strcmp(key, "HID_UNIQ") == 0) {
246 			/* The caller has to free the serial number */
247 			*serial_number_utf8 = strdup(value);
248 			found_serial = 1;
249 		}
250 
251 next_line:
252 		line = strtok_r(NULL, "\n", &saveptr);
253 	}
254 
255 	free(tmp);
256 	return (found_id && found_name && found_serial);
257 }
258 
259 
get_device_string(hid_device * dev,enum device_string_id key,wchar_t * string,size_t maxlen)260 static int get_device_string(hid_device *dev, enum device_string_id key, wchar_t *string, size_t maxlen)
261 {
262 	struct udev *udev;
263 	struct udev_device *udev_dev, *parent, *hid_dev;
264 	struct stat s;
265 	int ret = -1;
266         char *serial_number_utf8 = NULL;
267         char *product_name_utf8 = NULL;
268 
269 	/* Create the udev object */
270 	udev = udev_new();
271 	if (!udev) {
272 		printf("Can't create udev\n");
273 		return -1;
274 	}
275 
276 	/* Get the dev_t (major/minor numbers) from the file handle. */
277 	fstat(dev->device_handle, &s);
278 	/* Open a udev device from the dev_t. 'c' means character device. */
279 	udev_dev = udev_device_new_from_devnum(udev, 'c', s.st_rdev);
280 	if (udev_dev) {
281 		hid_dev = udev_device_get_parent_with_subsystem_devtype(
282 			udev_dev,
283 			"hid",
284 			NULL);
285 		if (hid_dev) {
286 			unsigned short dev_vid;
287 			unsigned short dev_pid;
288 			int bus_type;
289 			size_t retm;
290 
291 			ret = parse_uevent_info(
292 			           udev_device_get_sysattr_value(hid_dev, "uevent"),
293 			           &bus_type,
294 			           &dev_vid,
295 			           &dev_pid,
296 			           &serial_number_utf8,
297 			           &product_name_utf8);
298 
299 			if (bus_type == BUS_BLUETOOTH) {
300 				switch (key) {
301 					case DEVICE_STRING_MANUFACTURER:
302 						wcsncpy(string, L"", maxlen);
303 						ret = 0;
304 						break;
305 					case DEVICE_STRING_PRODUCT:
306 						retm = mbstowcs(string, product_name_utf8, maxlen);
307 						ret = (retm == (size_t)-1)? -1: 0;
308 						break;
309 					case DEVICE_STRING_SERIAL:
310 						retm = mbstowcs(string, serial_number_utf8, maxlen);
311 						ret = (retm == (size_t)-1)? -1: 0;
312 						break;
313 					case DEVICE_STRING_COUNT:
314 					default:
315 						ret = -1;
316 						break;
317 				}
318 			}
319 			else {
320 				if (key == DEVICE_STRING_SERIAL) {
321 					/* work around */
322 					retm = mbstowcs(string, serial_number_utf8, maxlen);
323 					ret = (retm == (size_t)-1)? -1: 0;
324 					goto end;
325 				}
326 
327 				/* This is a USB device. Find its parent USB Device node. */
328 				parent = udev_device_get_parent_with_subsystem_devtype(
329 					   udev_dev,
330 					   "usb",
331 					   "usb_device");
332 				if (parent) {
333 					const char *str;
334 					const char *key_str = NULL;
335 
336 					if (key >= 0 && key < DEVICE_STRING_COUNT) {
337 						key_str = device_string_names[key];
338 					} else {
339 						ret = -1;
340 						goto end;
341 					}
342 
343 					str = udev_device_get_sysattr_value(parent, key_str);
344 					if (str) {
345 						/* Convert the string from UTF-8 to wchar_t */
346 						retm = mbstowcs(string, str, maxlen);
347 						ret = (retm == (size_t)-1)? -1: 0;
348 						goto end;
349 					}
350 				}
351 			}
352 		}
353 	}
354 
355 end:
356         free(serial_number_utf8);
357         free(product_name_utf8);
358 
359 	udev_device_unref(udev_dev);
360 	/* parent and hid_dev don't need to be (and can't be) unref'd.
361 	   I'm not sure why, but they'll throw double-free() errors. */
362 	udev_unref(udev);
363 
364 	return ret;
365 }
366 
hid_init(void)367 int HID_API_EXPORT hid_init(void)
368 {
369 	const char *locale;
370 
371 	/* Set the locale if it's not set. */
372 	locale = setlocale(LC_CTYPE, NULL);
373 	if (!locale)
374 		setlocale(LC_CTYPE, "");
375 
376 	kernel_version = detect_kernel_version();
377 
378 	return 0;
379 }
380 
hid_exit(void)381 int HID_API_EXPORT hid_exit(void)
382 {
383 	/* Nothing to do for this in the Linux/hidraw implementation. */
384 	return 0;
385 }
386 
387 
hid_enumerate(unsigned short vendor_id,unsigned short product_id)388 struct hid_device_info  HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
389 {
390 	struct udev *udev;
391 	struct udev_enumerate *enumerate;
392 	struct udev_list_entry *devices, *dev_list_entry;
393 
394 	struct hid_device_info *root = NULL; /* return object */
395 	struct hid_device_info *cur_dev = NULL;
396 	struct hid_device_info *prev_dev = NULL; /* previous device */
397 
398 	hid_init();
399 
400 	/* Create the udev object */
401 	udev = udev_new();
402 	if (!udev) {
403 		printf("Can't create udev\n");
404 		return NULL;
405 	}
406 
407 	/* Create a list of the devices in the 'hidraw' subsystem. */
408 	enumerate = udev_enumerate_new(udev);
409 	udev_enumerate_add_match_subsystem(enumerate, "hidraw");
410 	udev_enumerate_scan_devices(enumerate);
411 	devices = udev_enumerate_get_list_entry(enumerate);
412 	/* For each item, see if it matches the vid/pid, and if so
413 	   create a udev_device record for it */
414 	udev_list_entry_foreach(dev_list_entry, devices) {
415 		const char *sysfs_path;
416 		const char *dev_path;
417 		const char *str;
418 		struct udev_device *raw_dev; /* The device's hidraw udev node. */
419 		struct udev_device *hid_dev; /* The device's HID udev node. */
420 		struct udev_device *usb_dev; /* The device's USB udev node. */
421 		struct udev_device *intf_dev; /* The device's interface (in the USB sense). */
422 		unsigned short dev_vid;
423 		unsigned short dev_pid;
424 		char *serial_number_utf8 = NULL;
425 		char *product_name_utf8 = NULL;
426 		int bus_type;
427 		int result;
428 
429 		/* Get the filename of the /sys entry for the device
430 		   and create a udev_device object (dev) representing it */
431 		sysfs_path = udev_list_entry_get_name(dev_list_entry);
432 		raw_dev = udev_device_new_from_syspath(udev, sysfs_path);
433 		dev_path = udev_device_get_devnode(raw_dev);
434 
435 		hid_dev = udev_device_get_parent_with_subsystem_devtype(
436 			raw_dev,
437 			"hid",
438 			NULL);
439 
440 		if (!hid_dev) {
441 			/* Unable to find parent hid device. */
442 			goto next;
443 		}
444 
445 		result = parse_uevent_info(
446 			udev_device_get_sysattr_value(hid_dev, "uevent"),
447 			&bus_type,
448 			&dev_vid,
449 			&dev_pid,
450 			&serial_number_utf8,
451 			&product_name_utf8);
452 
453 		if (!result) {
454 			/* parse_uevent_info() failed for at least one field. */
455 			goto next;
456 		}
457 
458 		if (bus_type != BUS_USB && bus_type != BUS_BLUETOOTH) {
459 			/* We only know how to handle USB and BT devices. */
460 			goto next;
461 		}
462 
463 		/* Check the VID/PID against the arguments */
464 		if ((vendor_id == 0x0 || vendor_id == dev_vid) &&
465 		    (product_id == 0x0 || product_id == dev_pid)) {
466 			struct hid_device_info *tmp;
467 
468 			/* VID/PID match. Create the record. */
469 			tmp = malloc(sizeof(struct hid_device_info));
470 			if (cur_dev) {
471 				cur_dev->next = tmp;
472 			}
473 			else {
474 				root = tmp;
475 			}
476 			prev_dev = cur_dev;
477 			cur_dev = tmp;
478 
479 			/* Fill out the record */
480 			cur_dev->next = NULL;
481 			cur_dev->path = dev_path? strdup(dev_path): NULL;
482 
483 			/* VID/PID */
484 			cur_dev->vendor_id = dev_vid;
485 			cur_dev->product_id = dev_pid;
486 
487 			/* Serial Number */
488 			cur_dev->serial_number = utf8_to_wchar_t(serial_number_utf8);
489 
490 			/* Release Number */
491 			cur_dev->release_number = 0x0;
492 
493 			/* Interface Number */
494 			cur_dev->interface_number = -1;
495 
496 			switch (bus_type) {
497 				case BUS_USB:
498 					/* The device pointed to by raw_dev contains information about
499 					   the hidraw device. In order to get information about the
500 					   USB device, get the parent device with the
501 					   subsystem/devtype pair of "usb"/"usb_device". This will
502 					   be several levels up the tree, but the function will find
503 					   it. */
504 					usb_dev = udev_device_get_parent_with_subsystem_devtype(
505 							raw_dev,
506 							"usb",
507 							"usb_device");
508 
509 					if (!usb_dev) {
510 						/* Free this device */
511 						free(cur_dev->serial_number);
512 						free(cur_dev->path);
513 						free(cur_dev);
514 
515 						/* Take it off the device list. */
516 						if (prev_dev) {
517 							prev_dev->next = NULL;
518 							cur_dev = prev_dev;
519 						}
520 						else {
521 							cur_dev = root = NULL;
522 						}
523 
524 						goto next;
525 					}
526 
527 					/* Manufacturer and Product strings */
528 					cur_dev->manufacturer_string = copy_udev_string(usb_dev, device_string_names[DEVICE_STRING_MANUFACTURER]);
529 					cur_dev->product_string = copy_udev_string(usb_dev, device_string_names[DEVICE_STRING_PRODUCT]);
530 
531 					/* Release Number */
532 					str = udev_device_get_sysattr_value(usb_dev, "bcdDevice");
533 					cur_dev->release_number = (str)? strtol(str, NULL, 16): 0x0;
534 
535 					/* Get a handle to the interface's udev node. */
536 					intf_dev = udev_device_get_parent_with_subsystem_devtype(
537 							raw_dev,
538 							"usb",
539 							"usb_interface");
540 					if (intf_dev) {
541 						str = udev_device_get_sysattr_value(intf_dev, "bInterfaceNumber");
542 						cur_dev->interface_number = (str)? strtol(str, NULL, 16): -1;
543 					}
544 
545 					break;
546 
547 				case BUS_BLUETOOTH:
548 					/* Manufacturer and Product strings */
549 					cur_dev->manufacturer_string = wcsdup(L"");
550 					cur_dev->product_string = utf8_to_wchar_t(product_name_utf8);
551 
552 					break;
553 
554 				default:
555 					/* Unknown device type - this should never happen, as we
556 					 * check for USB and Bluetooth devices above */
557 					break;
558 			}
559 		}
560 
561 	next:
562 		free(serial_number_utf8);
563 		free(product_name_utf8);
564 		udev_device_unref(raw_dev);
565 		/* hid_dev, usb_dev and intf_dev don't need to be (and can't be)
566 		   unref()d.  It will cause a double-free() error.  I'm not
567 		   sure why.  */
568 	}
569 	/* Free the enumerator and udev objects. */
570 	udev_enumerate_unref(enumerate);
571 	udev_unref(udev);
572 
573 	return root;
574 }
575 
hid_free_enumeration(struct hid_device_info * devs)576 void  HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs)
577 {
578 	struct hid_device_info *d = devs;
579 	while (d) {
580 		struct hid_device_info *next = d->next;
581 		free(d->path);
582 		free(d->serial_number);
583 		free(d->manufacturer_string);
584 		free(d->product_string);
585 		free(d);
586 		d = next;
587 	}
588 }
589 
hid_open(unsigned short vendor_id,unsigned short product_id,const wchar_t * serial_number)590 hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
591 {
592 	struct hid_device_info *devs, *cur_dev;
593 	const char *path_to_open = NULL;
594 	hid_device *handle = NULL;
595 
596 	devs = hid_enumerate(vendor_id, product_id);
597 	cur_dev = devs;
598 	while (cur_dev) {
599 		if (cur_dev->vendor_id == vendor_id &&
600 		    cur_dev->product_id == product_id) {
601 			if (serial_number) {
602 				if (wcscmp(serial_number, cur_dev->serial_number) == 0) {
603 					path_to_open = cur_dev->path;
604 					break;
605 				}
606 			}
607 			else {
608 				path_to_open = cur_dev->path;
609 				break;
610 			}
611 		}
612 		cur_dev = cur_dev->next;
613 	}
614 
615 	if (path_to_open) {
616 		/* Open the device */
617 		handle = hid_open_path(path_to_open);
618 	}
619 
620 	hid_free_enumeration(devs);
621 
622 	return handle;
623 }
624 
hid_open_path(const char * path)625 hid_device * HID_API_EXPORT hid_open_path(const char *path)
626 {
627 	hid_device *dev = NULL;
628 
629 	hid_init();
630 
631 	dev = new_hid_device();
632 
633 	/* OPEN HERE */
634 	dev->device_handle = open(path, O_RDWR);
635 
636 	/* If we have a good handle, return it. */
637 	/* test test shoud be >= 0 even if it is not so likely (I guess) */
638 	if (dev->device_handle > 0) {
639 
640 		/* Get the report descriptor */
641 		int res, desc_size = 0;
642 		struct hidraw_report_descriptor rpt_desc;
643 
644 		memset(&rpt_desc, 0x0, sizeof(rpt_desc));
645 
646 		/* Get Report Descriptor Size */
647 		res = ioctl(dev->device_handle, HIDIOCGRDESCSIZE, &desc_size);
648 		if (res < 0)
649 			perror("HIDIOCGRDESCSIZE");
650 
651 
652 		/* Get Report Descriptor */
653 		rpt_desc.size = desc_size;
654 		res = ioctl(dev->device_handle, HIDIOCGRDESC, &rpt_desc);
655 		if (res < 0) {
656 			perror("HIDIOCGRDESC");
657 		} else {
658 			/* Determine if this device uses numbered reports. */
659 			dev->uses_numbered_reports =
660 				uses_numbered_reports(rpt_desc.value,
661 				                      rpt_desc.size);
662 		}
663 
664 		return dev;
665 	}
666 	else {
667 		/* Unable to open any devices. */
668 		free(dev);
669 		return NULL;
670 	}
671 }
672 
hid_get_report_descriptor(hid_device * dev,unsigned char * data,size_t length)673 int HID_API_EXPORT hid_get_report_descriptor(hid_device *dev, unsigned char *data, size_t length)
674 {
675     int res;
676     struct hidraw_report_descriptor rpt_desc;
677     memset(&rpt_desc, 0x0, sizeof(rpt_desc));
678     /* Get Report Descriptor Size */
679     if (dev->device_handle > 0) {
680 	int desc_size;
681 	/* Get Report Descriptor Size */
682 	if (ioctl(dev->device_handle, HIDIOCGRDESCSIZE, &desc_size) < 0)
683 	    return -1;
684 	if (desc_size > length) {
685 	    errno = ERANGE;
686 	    return -1;
687 	}
688 	rpt_desc.size = desc_size;
689 	if (ioctl(dev->device_handle, HIDIOCGRDESC, &rpt_desc) < 0)
690 	    return -1;
691 	memcpy(data, rpt_desc.value, rpt_desc.size);
692 	return rpt_desc.size;
693     }
694     errno = EINVAL;
695     return -1;
696 }
697 
hid_write(hid_device * dev,const unsigned char * data,size_t length)698 int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t length)
699 {
700 	int bytes_written;
701 
702 	bytes_written = write(dev->device_handle, data, length);
703 
704 	return bytes_written;
705 }
706 
707 
hid_read_timeout(hid_device * dev,unsigned char * data,size_t length,int milliseconds)708 int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds)
709 {
710 	int bytes_read;
711 
712 	if (milliseconds >= 0) {
713 		/* Milliseconds is either 0 (non-blocking) or > 0 (contains
714 		   a valid timeout). In both cases we want to call poll()
715 		   and wait for data to arrive.  Don't rely on non-blocking
716 		   operation (O_NONBLOCK) since some kernels don't seem to
717 		   properly report device disconnection through read() when
718 		   in non-blocking mode.  */
719 		int ret;
720 		struct pollfd fds;
721 
722 		fds.fd = dev->device_handle;
723 		fds.events = POLLIN;
724 		fds.revents = 0;
725 		ret = poll(&fds, 1, milliseconds);
726 		if (ret == -1 || ret == 0) {
727 			/* Error or timeout */
728 			return ret;
729 		}
730 		else {
731 			/* Check for errors on the file descriptor. This will
732 			   indicate a device disconnection. */
733 			if (fds.revents & (POLLERR | POLLHUP | POLLNVAL))
734 				return -1;
735 		}
736 	}
737 
738 	bytes_read = read(dev->device_handle, data, length);
739 	if (bytes_read < 0 && (errno == EAGAIN || errno == EINPROGRESS))
740 		bytes_read = 0;
741 
742 	if (bytes_read >= 0 &&
743 	    kernel_version != 0 &&
744 	    kernel_version < KERNEL_VERSION(2,6,34) &&
745 	    dev->uses_numbered_reports) {
746 		/* Work around a kernel bug. Chop off the first byte. */
747 		memmove(data, data+1, bytes_read);
748 		bytes_read--;
749 	}
750 
751 	return bytes_read;
752 }
753 
hid_read(hid_device * dev,unsigned char * data,size_t length)754 int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length)
755 {
756 	return hid_read_timeout(dev, data, length, (dev->blocking)? -1: 0);
757 }
758 
hid_set_nonblocking(hid_device * dev,int nonblock)759 int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock)
760 {
761 	/* Do all non-blocking in userspace using poll(), since it looks
762 	   like there's a bug in the kernel in some versions where
763 	   read() will not return -1 on disconnection of the USB device */
764 
765 	dev->blocking = !nonblock;
766 	return 0; /* Success */
767 }
768 
769 // return an event handle that can be used for poll/epoll/select etc
hid_get_event_handle(hid_device * dev)770 hid_handle_t HID_API_EXPORT hid_get_event_handle(hid_device *dev)
771 {
772     return (hid_handle_t) ((intptr_t)dev->device_handle);
773 }
774 
775 
hid_send_feature_report(hid_device * dev,const unsigned char * data,size_t length)776 int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
777 {
778 	int res;
779 
780 	res = ioctl(dev->device_handle, HIDIOCSFEATURE(length), data);
781 	if (res < 0)
782 		perror("ioctl (SFEATURE)");
783 
784 	return res;
785 }
786 
hid_get_feature_report(hid_device * dev,unsigned char * data,size_t length)787 int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
788 {
789 	int res;
790 
791 	res = ioctl(dev->device_handle, HIDIOCGFEATURE(length), data);
792 	if (res < 0)
793 		perror("ioctl (GFEATURE)");
794 
795 
796 	return res;
797 }
798 
799 
hid_close(hid_device * dev)800 void HID_API_EXPORT hid_close(hid_device *dev)
801 {
802 	if (!dev)
803 		return;
804 	close(dev->device_handle);
805 	free(dev);
806 }
807 
808 
hid_get_manufacturer_string(hid_device * dev,wchar_t * string,size_t maxlen)809 int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
810 {
811 	return get_device_string(dev, DEVICE_STRING_MANUFACTURER, string, maxlen);
812 }
813 
hid_get_product_string(hid_device * dev,wchar_t * string,size_t maxlen)814 int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
815 {
816 	return get_device_string(dev, DEVICE_STRING_PRODUCT, string, maxlen);
817 }
818 
hid_get_serial_number_string(hid_device * dev,wchar_t * string,size_t maxlen)819 int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
820 {
821 	return get_device_string(dev, DEVICE_STRING_SERIAL, string, maxlen);
822 }
823 
hid_get_indexed_string(hid_device * dev,int string_index,wchar_t * string,size_t maxlen)824 int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen)
825 {
826 	return -1;
827 }
828 
829 
hid_error(hid_device * dev)830 HID_API_EXPORT const wchar_t * HID_API_CALL  hid_error(hid_device *dev)
831 {
832 	return NULL;
833 }
834