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