sdl

FORK: Simple Directmedia Layer
git clone https://git.neptards.moe/neptards/sdl.git
Log | Files | Refs

hid.c (22438B)


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