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 	ret = fstat(dev->device_handle, &s);
278 	if (-1 == ret)
279 		return ret;
280 	/* Open a udev device from the dev_t. 'c' means character device. */
281 	udev_dev = udev_device_new_from_devnum(udev, 'c', s.st_rdev);
282 	if (udev_dev) {
283 		hid_dev = udev_device_get_parent_with_subsystem_devtype(
284 			udev_dev,
285 			"hid",
286 			NULL);
287 		if (hid_dev) {
288 			unsigned short dev_vid;
289 			unsigned short dev_pid;
290 			int bus_type;
291 			size_t retm;
292 
293 			ret = parse_uevent_info(
294 			           udev_device_get_sysattr_value(hid_dev, "uevent"),
295 			           &bus_type,
296 			           &dev_vid,
297 			           &dev_pid,
298 			           &serial_number_utf8,
299 			           &product_name_utf8);
300 
301 			if (bus_type == BUS_BLUETOOTH) {
302 				switch (key) {
303 					case DEVICE_STRING_MANUFACTURER:
304 						wcsncpy(string, L"", maxlen);
305 						ret = 0;
306 						break;
307 					case DEVICE_STRING_PRODUCT:
308 						retm = mbstowcs(string, product_name_utf8, maxlen);
309 						ret = (retm == (size_t)-1)? -1: 0;
310 						break;
311 					case DEVICE_STRING_SERIAL:
312 						retm = mbstowcs(string, serial_number_utf8, maxlen);
313 						ret = (retm == (size_t)-1)? -1: 0;
314 						break;
315 					case DEVICE_STRING_COUNT:
316 					default:
317 						ret = -1;
318 						break;
319 				}
320 			}
321 			else {
322 				/* This is a USB device. Find its parent USB Device node. */
323 				parent = udev_device_get_parent_with_subsystem_devtype(
324 					   udev_dev,
325 					   "usb",
326 					   "usb_device");
327 				if (parent) {
328 					const char *str;
329 					const char *key_str = NULL;
330 
331 					if (key >= 0 && key < DEVICE_STRING_COUNT) {
332 						key_str = device_string_names[key];
333 					} else {
334 						ret = -1;
335 						goto end;
336 					}
337 
338 					str = udev_device_get_sysattr_value(parent, key_str);
339 					if (str) {
340 						/* Convert the string from UTF-8 to wchar_t */
341 						retm = mbstowcs(string, str, maxlen);
342 						ret = (retm == (size_t)-1)? -1: 0;
343 						goto end;
344 					}
345 				}
346 			}
347 		}
348 	}
349 
350 end:
351         free(serial_number_utf8);
352         free(product_name_utf8);
353 
354 	udev_device_unref(udev_dev);
355 	/* parent and hid_dev don't need to be (and can't be) unref'd.
356 	   I'm not sure why, but they'll throw double-free() errors. */
357 	udev_unref(udev);
358 
359 	return ret;
360 }
361 
hid_init(void)362 int HID_API_EXPORT hid_init(void)
363 {
364 	const char *locale;
365 
366 	/* Set the locale if it's not set. */
367 	locale = setlocale(LC_CTYPE, NULL);
368 	if (!locale)
369 		setlocale(LC_CTYPE, "");
370 
371 	kernel_version = detect_kernel_version();
372 
373 	return 0;
374 }
375 
hid_exit(void)376 int HID_API_EXPORT hid_exit(void)
377 {
378 	/* Nothing to do for this in the Linux/hidraw implementation. */
379 	return 0;
380 }
381 
382 
hid_enumerate(unsigned short vendor_id,unsigned short product_id)383 struct hid_device_info  HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
384 {
385 	struct udev *udev;
386 	struct udev_enumerate *enumerate;
387 	struct udev_list_entry *devices, *dev_list_entry;
388 
389 	struct hid_device_info *root = NULL; /* return object */
390 	struct hid_device_info *cur_dev = NULL;
391 	struct hid_device_info *prev_dev = NULL; /* previous device */
392 
393 	hid_init();
394 
395 	/* Create the udev object */
396 	udev = udev_new();
397 	if (!udev) {
398 		printf("Can't create udev\n");
399 		return NULL;
400 	}
401 
402 	/* Create a list of the devices in the 'hidraw' subsystem. */
403 	enumerate = udev_enumerate_new(udev);
404 	udev_enumerate_add_match_subsystem(enumerate, "hidraw");
405 	udev_enumerate_scan_devices(enumerate);
406 	devices = udev_enumerate_get_list_entry(enumerate);
407 	/* For each item, see if it matches the vid/pid, and if so
408 	   create a udev_device record for it */
409 	udev_list_entry_foreach(dev_list_entry, devices) {
410 		const char *sysfs_path;
411 		const char *dev_path;
412 		const char *str;
413 		struct udev_device *raw_dev; /* The device's hidraw udev node. */
414 		struct udev_device *hid_dev; /* The device's HID udev node. */
415 		struct udev_device *usb_dev; /* The device's USB udev node. */
416 		struct udev_device *intf_dev; /* The device's interface (in the USB sense). */
417 		unsigned short dev_vid;
418 		unsigned short dev_pid;
419 		char *serial_number_utf8 = NULL;
420 		char *product_name_utf8 = NULL;
421 		int bus_type;
422 		int result;
423 
424 		/* Get the filename of the /sys entry for the device
425 		   and create a udev_device object (dev) representing it */
426 		sysfs_path = udev_list_entry_get_name(dev_list_entry);
427 		raw_dev = udev_device_new_from_syspath(udev, sysfs_path);
428 		dev_path = udev_device_get_devnode(raw_dev);
429 
430 		hid_dev = udev_device_get_parent_with_subsystem_devtype(
431 			raw_dev,
432 			"hid",
433 			NULL);
434 
435 		if (!hid_dev) {
436 			/* Unable to find parent hid device. */
437 			goto next;
438 		}
439 
440 		result = parse_uevent_info(
441 			udev_device_get_sysattr_value(hid_dev, "uevent"),
442 			&bus_type,
443 			&dev_vid,
444 			&dev_pid,
445 			&serial_number_utf8,
446 			&product_name_utf8);
447 
448 		if (!result) {
449 			/* parse_uevent_info() failed for at least one field. */
450 			goto next;
451 		}
452 
453 		if (bus_type != BUS_USB && bus_type != BUS_BLUETOOTH) {
454 			/* We only know how to handle USB and BT devices. */
455 			goto next;
456 		}
457 
458 		/* Check the VID/PID against the arguments */
459 		if ((vendor_id == 0x0 || vendor_id == dev_vid) &&
460 		    (product_id == 0x0 || product_id == dev_pid)) {
461 			struct hid_device_info *tmp;
462 
463 			/* VID/PID match. Create the record. */
464 			tmp = malloc(sizeof(struct hid_device_info));
465 			if (cur_dev) {
466 				cur_dev->next = tmp;
467 			}
468 			else {
469 				root = tmp;
470 			}
471 			prev_dev = cur_dev;
472 			cur_dev = tmp;
473 
474 			/* Fill out the record */
475 			cur_dev->next = NULL;
476 			cur_dev->path = dev_path? strdup(dev_path): NULL;
477 
478 			/* VID/PID */
479 			cur_dev->vendor_id = dev_vid;
480 			cur_dev->product_id = dev_pid;
481 
482 			/* Serial Number */
483 			cur_dev->serial_number = utf8_to_wchar_t(serial_number_utf8);
484 
485 			/* Release Number */
486 			cur_dev->release_number = 0x0;
487 
488 			/* Interface Number */
489 			cur_dev->interface_number = -1;
490 
491 			switch (bus_type) {
492 				case BUS_USB:
493 					/* The device pointed to by raw_dev contains information about
494 					   the hidraw device. In order to get information about the
495 					   USB device, get the parent device with the
496 					   subsystem/devtype pair of "usb"/"usb_device". This will
497 					   be several levels up the tree, but the function will find
498 					   it. */
499 					usb_dev = udev_device_get_parent_with_subsystem_devtype(
500 							raw_dev,
501 							"usb",
502 							"usb_device");
503 
504 					if (!usb_dev) {
505 						/* Free this device */
506 						free(cur_dev->serial_number);
507 						free(cur_dev->path);
508 						free(cur_dev);
509 
510 						/* Take it off the device list. */
511 						if (prev_dev) {
512 							prev_dev->next = NULL;
513 							cur_dev = prev_dev;
514 						}
515 						else {
516 							cur_dev = root = NULL;
517 						}
518 
519 						goto next;
520 					}
521 
522 					/* Manufacturer and Product strings */
523 					cur_dev->manufacturer_string = copy_udev_string(usb_dev, device_string_names[DEVICE_STRING_MANUFACTURER]);
524 					cur_dev->product_string = copy_udev_string(usb_dev, device_string_names[DEVICE_STRING_PRODUCT]);
525 
526 					/* Release Number */
527 					str = udev_device_get_sysattr_value(usb_dev, "bcdDevice");
528 					cur_dev->release_number = (str)? strtol(str, NULL, 16): 0x0;
529 
530 					/* Get a handle to the interface's udev node. */
531 					intf_dev = udev_device_get_parent_with_subsystem_devtype(
532 							raw_dev,
533 							"usb",
534 							"usb_interface");
535 					if (intf_dev) {
536 						str = udev_device_get_sysattr_value(intf_dev, "bInterfaceNumber");
537 						cur_dev->interface_number = (str)? strtol(str, NULL, 16): -1;
538 					}
539 
540 					break;
541 
542 				case BUS_BLUETOOTH:
543 					/* Manufacturer and Product strings */
544 					cur_dev->manufacturer_string = wcsdup(L"");
545 					cur_dev->product_string = utf8_to_wchar_t(product_name_utf8);
546 
547 					break;
548 
549 				default:
550 					/* Unknown device type - this should never happen, as we
551 					 * check for USB and Bluetooth devices above */
552 					break;
553 			}
554 		}
555 
556 	next:
557 		free(serial_number_utf8);
558 		free(product_name_utf8);
559 		udev_device_unref(raw_dev);
560 		/* hid_dev, usb_dev and intf_dev don't need to be (and can't be)
561 		   unref()d.  It will cause a double-free() error.  I'm not
562 		   sure why.  */
563 	}
564 	/* Free the enumerator and udev objects. */
565 	udev_enumerate_unref(enumerate);
566 	udev_unref(udev);
567 
568 	return root;
569 }
570 
hid_free_enumeration(struct hid_device_info * devs)571 void  HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs)
572 {
573 	struct hid_device_info *d = devs;
574 	while (d) {
575 		struct hid_device_info *next = d->next;
576 		free(d->path);
577 		free(d->serial_number);
578 		free(d->manufacturer_string);
579 		free(d->product_string);
580 		free(d);
581 		d = next;
582 	}
583 }
584 
hid_open(unsigned short vendor_id,unsigned short product_id,const wchar_t * serial_number)585 hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
586 {
587 	struct hid_device_info *devs, *cur_dev;
588 	const char *path_to_open = NULL;
589 	hid_device *handle = NULL;
590 
591 	devs = hid_enumerate(vendor_id, product_id);
592 	cur_dev = devs;
593 	while (cur_dev) {
594 		if (cur_dev->vendor_id == vendor_id &&
595 		    cur_dev->product_id == product_id) {
596 			if (serial_number) {
597 				if (wcscmp(serial_number, cur_dev->serial_number) == 0) {
598 					path_to_open = cur_dev->path;
599 					break;
600 				}
601 			}
602 			else {
603 				path_to_open = cur_dev->path;
604 				break;
605 			}
606 		}
607 		cur_dev = cur_dev->next;
608 	}
609 
610 	if (path_to_open) {
611 		/* Open the device */
612 		handle = hid_open_path(path_to_open);
613 	}
614 
615 	hid_free_enumeration(devs);
616 
617 	return handle;
618 }
619 
hid_open_path(const char * path)620 hid_device * HID_API_EXPORT hid_open_path(const char *path)
621 {
622 	hid_device *dev = NULL;
623 
624 	hid_init();
625 
626 	dev = new_hid_device();
627 
628 	/* OPEN HERE */
629 	dev->device_handle = open(path, O_RDWR);
630 
631 	/* If we have a good handle, return it. */
632 	if (dev->device_handle > 0) {
633 
634 		/* Get the report descriptor */
635 		int res, desc_size = 0;
636 		struct hidraw_report_descriptor rpt_desc;
637 
638 		memset(&rpt_desc, 0x0, sizeof(rpt_desc));
639 
640 		/* Get Report Descriptor Size */
641 		res = ioctl(dev->device_handle, HIDIOCGRDESCSIZE, &desc_size);
642 		if (res < 0)
643 			perror("HIDIOCGRDESCSIZE");
644 
645 
646 		/* Get Report Descriptor */
647 		rpt_desc.size = desc_size;
648 		res = ioctl(dev->device_handle, HIDIOCGRDESC, &rpt_desc);
649 		if (res < 0) {
650 			perror("HIDIOCGRDESC");
651 		} else {
652 			/* Determine if this device uses numbered reports. */
653 			dev->uses_numbered_reports =
654 				uses_numbered_reports(rpt_desc.value,
655 				                      rpt_desc.size);
656 		}
657 
658 		return dev;
659 	}
660 	else {
661 		/* Unable to open any devices. */
662 		free(dev);
663 		return NULL;
664 	}
665 }
666 
667 
hid_write(hid_device * dev,const unsigned char * data,size_t length)668 int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t length)
669 {
670 	int bytes_written;
671 
672 	bytes_written = write(dev->device_handle, data, length);
673 
674 	return bytes_written;
675 }
676 
677 
hid_read_timeout(hid_device * dev,unsigned char * data,size_t length,int milliseconds)678 int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds)
679 {
680 	int bytes_read;
681 
682 	if (milliseconds >= 0) {
683 		/* Milliseconds is either 0 (non-blocking) or > 0 (contains
684 		   a valid timeout). In both cases we want to call poll()
685 		   and wait for data to arrive.  Don't rely on non-blocking
686 		   operation (O_NONBLOCK) since some kernels don't seem to
687 		   properly report device disconnection through read() when
688 		   in non-blocking mode.  */
689 		int ret;
690 		struct pollfd fds;
691 
692 		fds.fd = dev->device_handle;
693 		fds.events = POLLIN;
694 		fds.revents = 0;
695 		ret = poll(&fds, 1, milliseconds);
696 		if (ret == -1 || ret == 0) {
697 			/* Error or timeout */
698 			return ret;
699 		}
700 		else {
701 			/* Check for errors on the file descriptor. This will
702 			   indicate a device disconnection. */
703 			if (fds.revents & (POLLERR | POLLHUP | POLLNVAL))
704 				return -1;
705 		}
706 	}
707 
708 	bytes_read = read(dev->device_handle, data, length);
709 	if (bytes_read < 0 && (errno == EAGAIN || errno == EINPROGRESS))
710 		bytes_read = 0;
711 
712 	if (bytes_read >= 0 &&
713 	    kernel_version != 0 &&
714 	    kernel_version < KERNEL_VERSION(2,6,34) &&
715 	    dev->uses_numbered_reports) {
716 		/* Work around a kernel bug. Chop off the first byte. */
717 		memmove(data, data+1, bytes_read);
718 		bytes_read--;
719 	}
720 
721 	return bytes_read;
722 }
723 
hid_read(hid_device * dev,unsigned char * data,size_t length)724 int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length)
725 {
726 	return hid_read_timeout(dev, data, length, (dev->blocking)? -1: 0);
727 }
728 
hid_set_nonblocking(hid_device * dev,int nonblock)729 int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock)
730 {
731 	/* Do all non-blocking in userspace using poll(), since it looks
732 	   like there's a bug in the kernel in some versions where
733 	   read() will not return -1 on disconnection of the USB device */
734 
735 	dev->blocking = !nonblock;
736 	return 0; /* Success */
737 }
738 
739 
hid_send_feature_report(hid_device * dev,const unsigned char * data,size_t length)740 int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
741 {
742 	int res;
743 
744 	res = ioctl(dev->device_handle, HIDIOCSFEATURE(length), data);
745 	if (res < 0)
746 		perror("ioctl (SFEATURE)");
747 
748 	return res;
749 }
750 
hid_get_feature_report(hid_device * dev,unsigned char * data,size_t length)751 int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
752 {
753 	int res;
754 
755 	res = ioctl(dev->device_handle, HIDIOCGFEATURE(length), data);
756 	if (res < 0)
757 		perror("ioctl (GFEATURE)");
758 
759 
760 	return res;
761 }
762 
763 
hid_close(hid_device * dev)764 void HID_API_EXPORT hid_close(hid_device *dev)
765 {
766 	if (!dev)
767 		return;
768 	close(dev->device_handle);
769 	free(dev);
770 }
771 
772 
hid_get_manufacturer_string(hid_device * dev,wchar_t * string,size_t maxlen)773 int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
774 {
775 	return get_device_string(dev, DEVICE_STRING_MANUFACTURER, string, maxlen);
776 }
777 
hid_get_product_string(hid_device * dev,wchar_t * string,size_t maxlen)778 int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
779 {
780 	return get_device_string(dev, DEVICE_STRING_PRODUCT, string, maxlen);
781 }
782 
hid_get_serial_number_string(hid_device * dev,wchar_t * string,size_t maxlen)783 int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
784 {
785 	return get_device_string(dev, DEVICE_STRING_SERIAL, string, maxlen);
786 }
787 
hid_get_indexed_string(hid_device * dev,int string_index,wchar_t * string,size_t maxlen)788 int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen)
789 {
790 	return -1;
791 }
792 
793 
hid_error(hid_device * dev)794 HID_API_EXPORT const wchar_t * HID_API_CALL  hid_error(hid_device *dev)
795 {
796 	return NULL;
797 }
798 
hid_get_descriptor(hid_device * dev,unsigned char * data,size_t length)799 int  HID_API_EXPORT_CALL hid_get_descriptor(hid_device *dev, unsigned char *data, size_t length)
800 {
801     int res;
802     unsigned int desc_size = 0;
803     struct hidraw_report_descriptor rpt_desc;
804 
805     memset(&rpt_desc, 0x0, sizeof(rpt_desc));
806 
807     /* Get Report Descriptor Size */
808     res = ioctl(dev->device_handle, HIDIOCGRDESCSIZE, &desc_size);
809     if (res < 0) {
810         perror("HIDIOCGRDESCSIZE");
811         return -1;
812     }
813 
814     // call with NULL buffer / 0 length to query size only
815     if ((data == NULL) || (length == 0))
816         return desc_size;
817 
818     if (length < desc_size) {
819         perror("hid_get_descriptor: insufficent space for descriptor");
820         return -1;
821     }
822 
823     /* Get Report Descriptor */
824     rpt_desc.size = desc_size;
825     res = ioctl(dev->device_handle, HIDIOCGRDESC, &rpt_desc);
826     if (res < 0) {
827         perror("HIDIOCGRDESC");
828         return -1;
829     }
830 
831     memcpy(data, rpt_desc.value, desc_size);
832     return desc_size;
833 }
834