Atlas - hid.c

Home / ext / SDL / src / hidapi / libusb Lines: 38 | Size: 62593 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)]
[FILE BEGIN]
1/******************************************************* 2 HIDAPI - Multi-Platform library for 3 communication with HID devices. 4 5 Alan Ott 6 Signal 11 Software 7 8 libusb/hidapi Team 9 10 Copyright 2022, All Rights Reserved. 11 12 At the discretion of the user of this library, 13 this software may be licensed under the terms of the 14 GNU General Public License v3, a BSD-Style license, or the 15 original HIDAPI license as outlined in the LICENSE.txt, 16 LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt 17 files located at the root of the source distribution. 18 These files may also be found in the public source 19 code repository located at: 20 https://github.com/libusb/hidapi . 21********************************************************/ 22 23#ifndef HIDAPI_USING_SDL_RUNTIME 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 <ctype.h> 31#include <locale.h> 32#include <errno.h> 33 34/* Unix */ 35#include <unistd.h> 36#include <sys/types.h> 37#include <sys/stat.h> 38#include <sys/ioctl.h> 39#include <sys/utsname.h> 40#include <fcntl.h> 41#include <wchar.h> 42 43/* GNU / LibUSB */ 44#include <libusb.h> 45#if !defined(__ANDROID__) && !defined(NO_ICONV) 46#include <iconv.h> 47#ifndef ICONV_CONST 48#define ICONV_CONST 49#endif 50#endif 51#endif /* HIDAPI_USING_SDL_RUNTIME */ 52 53#include "hidapi_libusb.h" 54 55#ifndef HIDAPI_THREAD_MODEL_INCLUDE 56#define HIDAPI_THREAD_MODEL_INCLUDE "hidapi_thread_pthread.h" 57#endif 58#include HIDAPI_THREAD_MODEL_INCLUDE 59 60#ifdef __cplusplus 61extern "C" { 62#endif 63 64#ifdef DEBUG_PRINTF 65#define LOG(...) fprintf(stderr, __VA_ARGS__) 66#else 67#define LOG(...) do {} while (0) 68#endif 69 70#ifndef __FreeBSD__ 71#define DETACH_KERNEL_DRIVER 72#endif 73 74#if defined(_MSC_VER) 75#pragma warning(push) 76#pragma warning(disable:5287) /* operands are different enum types */ 77#endif 78 79/* Uncomment to enable the retrieval of Usage and Usage Page in 80hid_enumerate(). Warning, on platforms different from FreeBSD 81this is very invasive as it requires the detach 82and re-attach of the kernel driver. See comments inside hid_enumerate(). 83libusb HIDAPI programs are encouraged to use the interface number 84instead to differentiate between interfaces on a composite HID device. */ 85/*#define INVASIVE_GET_USAGE*/ 86 87/* Linked List of input reports received from the device. */ 88struct input_report { 89 uint8_t *data; 90 size_t len; 91 struct input_report *next; 92}; 93 94 95struct hid_device_ { 96 /* Handle to the actual device. */ 97 libusb_device_handle *device_handle; 98 99 /* USB Configuration Number of the device */ 100 int config_number; 101 /* The interface number of the HID */ 102 int interface; 103 int interface_class; 104 int interface_subclass; 105 int interface_protocol; 106 107 uint16_t report_descriptor_size; 108 109 /* Endpoint information */ 110 int input_endpoint; 111 int output_endpoint; 112 int input_ep_max_packet_size; 113 114 /* Indexes of Strings */ 115 int manufacturer_index; 116 int product_index; 117 int serial_index; 118 struct hid_device_info* device_info; 119 120 /* Whether blocking reads are used */ 121 int blocking; /* boolean */ 122 123 /* Read thread objects */ 124 hidapi_thread_state thread_state; 125 int shutdown_thread; 126 int transfer_loop_finished; 127 struct libusb_transfer *transfer; 128 129 /* Quirks */ 130 int skip_output_report_id; 131 int no_skip_output_report_id; 132 int no_output_reports_on_intr_ep; 133 134 /* List of received input reports. */ 135 struct input_report *input_reports; 136 137 /* Was kernel driver detached by libusb */ 138#ifdef DETACH_KERNEL_DRIVER 139 int is_driver_detached; 140#endif 141}; 142 143static struct hid_api_version api_version = { 144 .major = HID_API_VERSION_MAJOR, 145 .minor = HID_API_VERSION_MINOR, 146 .patch = HID_API_VERSION_PATCH 147}; 148 149static libusb_context *usb_context = NULL; 150 151uint16_t get_usb_code_for_current_locale(void); 152static int return_data(hid_device *dev, unsigned char *data, size_t length); 153 154static hid_device *new_hid_device(void) 155{ 156 hid_device *dev = (hid_device*) calloc(1, sizeof(hid_device)); 157 dev->blocking = 1; 158 159 hidapi_thread_state_init(&dev->thread_state); 160 161 return dev; 162} 163 164static void free_hid_device(hid_device *dev) 165{ 166 /* Clean up the thread objects */ 167 hidapi_thread_state_destroy(&dev->thread_state); 168 169 hid_free_enumeration(dev->device_info); 170 171 /* Free the device itself */ 172 free(dev); 173} 174 175#if 0 176/*TODO: Implement this function on hidapi/libusb.. */ 177static void register_error(hid_device *dev, const char *op) 178{ 179 180} 181#endif 182 183/* Get bytes from a HID Report Descriptor. 184 Only call with a num_bytes of 0, 1, 2, or 4. */ 185static uint32_t get_bytes(uint8_t *rpt, size_t len, size_t num_bytes, size_t cur) 186{ 187 /* Return if there aren't enough bytes. */ 188 if (cur + num_bytes >= len) 189 return 0; 190 191 if (num_bytes == 0) 192 return 0; 193 else if (num_bytes == 1) { 194 return rpt[cur+1]; 195 } 196 else if (num_bytes == 2) { 197 return (rpt[cur+2] * 256 + rpt[cur+1]); 198 } 199 else if (num_bytes == 4) { 200 return (rpt[cur+4] * 0x01000000 + 201 rpt[cur+3] * 0x00010000 + 202 rpt[cur+2] * 0x00000100 + 203 rpt[cur+1] * 0x00000001); 204 } 205 else 206 return 0; 207} 208 209/* Retrieves the device's Usage Page and Usage from the report 210 descriptor. The algorithm is simple, as it just returns the first 211 Usage and Usage Page that it finds in the descriptor. 212 The return value is 0 on success and -1 on failure. */ 213static int get_usage(uint8_t *report_descriptor, size_t size, 214 unsigned short *usage_page, unsigned short *usage) 215{ 216 unsigned int i = 0; 217 int size_code; 218 int data_len, key_size; 219 int usage_found = 0, usage_page_found = 0; 220 221 while (i < size) { 222 int key = report_descriptor[i]; 223 int key_cmd = key & 0xfc; 224 225 //printf("key: %02hhx\n", key); 226 227 if ((key & 0xf0) == 0xf0) { 228 /* This is a Long Item. The next byte contains the 229 length of the data section (value) for this key. 230 See the HID specification, version 1.11, section 231 6.2.2.3, titled "Long Items." */ 232 if (i+1 < size) 233 data_len = report_descriptor[i+1]; 234 else 235 data_len = 0; /* malformed report */ 236 key_size = 3; 237 } 238 else { 239 /* This is a Short Item. The bottom two bits of the 240 key contain the size code for the data section 241 (value) for this key. Refer to the HID 242 specification, version 1.11, section 6.2.2.2, 243 titled "Short Items." */ 244 size_code = key & 0x3; 245 switch (size_code) { 246 case 0: 247 case 1: 248 case 2: 249 data_len = size_code; 250 break; 251 case 3: 252 data_len = 4; 253 break; 254 default: 255 /* Can't ever happen since size_code is & 0x3 */ 256 data_len = 0; 257 break; 258 } 259 key_size = 1; 260 } 261 262 if (key_cmd == 0x4) { 263 *usage_page = (unsigned short)get_bytes(report_descriptor, size, data_len, i); 264 usage_page_found = 1; 265 //printf("Usage Page: %x\n", (uint32_t)*usage_page); 266 } 267 if (key_cmd == 0x8) { 268 if (data_len == 4) { /* Usages 5.5 / Usage Page 6.2.2.7 */ 269 *usage_page = (unsigned short)get_bytes(report_descriptor, size, 2, i + 2); 270 usage_page_found = 1; 271 *usage = (unsigned short)get_bytes(report_descriptor, size, 2, i); 272 usage_found = 1; 273 } 274 else { 275 *usage = (unsigned short)get_bytes(report_descriptor, size, data_len, i); 276 usage_found = 1; 277 } 278 //printf("Usage: %x\n", (uint32_t)*usage); 279 } 280 281 if (usage_page_found && usage_found) 282 return 0; /* success */ 283 284 /* Skip over this key and it's associated data */ 285 i += data_len + key_size; 286 } 287 288 return -1; /* failure */ 289} 290 291#if defined(__FreeBSD__) && __FreeBSD__ < 10 && !defined(libusb_get_string_descriptor) 292/* The libusb version included in FreeBSD < 10 doesn't have this function. In 293 mainline libusb, it's inlined in libusb.h. This function will bear a striking 294 resemblance to that one, because there's about one way to code it. 295 296 Note that the data parameter is Unicode in UTF-16LE encoding. 297 Return value is the number of bytes in data, or LIBUSB_ERROR_*. 298 */ 299static inline int libusb_get_string_descriptor(libusb_device_handle *dev, 300 uint8_t descriptor_index, uint16_t lang_id, 301 unsigned char *data, int length) 302{ 303 return libusb_control_transfer(dev, 304 LIBUSB_ENDPOINT_IN | 0x0, /* Endpoint 0 IN */ 305 LIBUSB_REQUEST_GET_DESCRIPTOR, 306 (LIBUSB_DT_STRING << 8) | descriptor_index, 307 lang_id, data, (uint16_t) length, 1000); 308} 309 310#endif 311 312 313/* Get the first language the device says it reports. This comes from 314 USB string #0. */ 315static uint16_t get_first_language(libusb_device_handle *dev) 316{ 317 uint16_t buf[32]; 318 int len; 319 320 /* Get the string from libusb. */ 321 len = libusb_get_string_descriptor(dev, 322 0x0, /* String ID */ 323 0x0, /* Language */ 324 (unsigned char*)buf, 325 sizeof(buf)); 326 if (len < 4) 327 return 0x0; 328 329 return buf[1]; /* First two bytes are len and descriptor type. */ 330} 331 332static int is_language_supported(libusb_device_handle *dev, uint16_t lang) 333{ 334 uint16_t buf[32]; 335 int len; 336 int i; 337 338 /* Get the string from libusb. */ 339 len = libusb_get_string_descriptor(dev, 340 0x0, /* String ID */ 341 0x0, /* Language */ 342 (unsigned char*)buf, 343 sizeof(buf)); 344 if (len < 4) 345 return 0x0; 346 347 348 len /= 2; /* language IDs are two-bytes each. */ 349 /* Start at index 1 because there are two bytes of protocol data. */ 350 for (i = 1; i < len; i++) { 351 if (buf[i] == lang) 352 return 1; 353 } 354 355 return 0; 356} 357 358 359/* This function returns a newly allocated wide string containing the USB 360 device string numbered by the index. The returned string must be freed 361 by using free(). */ 362static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx) 363{ 364 char buf[512]; 365 int len; 366 wchar_t *str = NULL; 367 368#if !defined(__ANDROID__) && !defined(NO_ICONV) /* we don't use iconv on Android, or when it is explicitly disabled */ 369 wchar_t wbuf[256]; 370 /* iconv variables */ 371 iconv_t ic; 372 size_t inbytes; 373 size_t outbytes; 374 size_t res; 375 ICONV_CONST char *inptr; 376 char *outptr; 377#endif 378 379 /* Determine which language to use. */ 380 uint16_t lang; 381 lang = get_usb_code_for_current_locale(); 382 if (!is_language_supported(dev, lang)) 383 lang = get_first_language(dev); 384 385 /* Get the string from libusb. */ 386 len = libusb_get_string_descriptor(dev, 387 idx, 388 lang, 389 (unsigned char*)buf, 390 sizeof(buf)); 391 if (len < 2) /* we always skip first 2 bytes */ 392 return NULL; 393 394#if defined(__ANDROID__) || defined(NO_ICONV) 395 396 /* Bionic does not have iconv support nor wcsdup() function, so it 397 has to be done manually. The following code will only work for 398 code points that can be represented as a single UTF-16 character, 399 and will incorrectly convert any code points which require more 400 than one UTF-16 character. 401 402 Skip over the first character (2-bytes). */ 403 len -= 2; 404 str = (wchar_t*) malloc((len / 2 + 1) * sizeof(wchar_t)); 405 int i; 406 for (i = 0; i < len / 2; i++) { 407 str[i] = buf[i * 2 + 2] | (buf[i * 2 + 3] << 8); 408 } 409 str[len / 2] = 0x00000000; 410 411#else 412 413 /* buf does not need to be explicitly NULL-terminated because 414 it is only passed into iconv() which does not need it. */ 415 416 /* Initialize iconv. */ 417 ic = iconv_open("WCHAR_T", "UTF-16LE"); 418 if (ic == (iconv_t)-1) { 419 LOG("iconv_open() failed\n"); 420 return NULL; 421 } 422 423 /* Convert to native wchar_t (UTF-32 on glibc/BSD systems). 424 Skip the first character (2-bytes). */ 425 inptr = buf+2; 426 inbytes = len-2; 427 outptr = (char*) wbuf; 428 outbytes = sizeof(wbuf); 429 res = iconv(ic, &inptr, &inbytes, &outptr, &outbytes); 430 if (res == (size_t)-1) { 431 LOG("iconv() failed\n"); 432 goto err; 433 } 434 435 /* Write the terminating NULL. */ 436 wbuf[sizeof(wbuf)/sizeof(wbuf[0])-1] = 0x00000000; 437 if (outbytes >= sizeof(wbuf[0])) 438 *((wchar_t*)outptr) = 0x00000000; 439 440 /* Allocate and copy the string. */ 441 str = wcsdup(wbuf); 442 443err: 444 iconv_close(ic); 445 446#endif 447 448 return str; 449} 450 451struct usb_string_cache_entry { 452 uint16_t vid; 453 uint16_t pid; 454 wchar_t *vendor; 455 wchar_t *product; 456}; 457 458static struct usb_string_cache_entry *usb_string_cache = NULL; 459static size_t usb_string_cache_size = 0; 460static size_t usb_string_cache_insert_pos = 0; 461 462static int usb_string_cache_grow(void) 463{ 464 struct usb_string_cache_entry *new_cache; 465 size_t allocSize; 466 size_t new_cache_size; 467 468 new_cache_size = usb_string_cache_size + 8; 469 allocSize = sizeof(struct usb_string_cache_entry) * new_cache_size; 470 new_cache = (struct usb_string_cache_entry *)realloc(usb_string_cache, allocSize); 471 if (!new_cache) 472 return -1; 473 474 usb_string_cache = new_cache; 475 usb_string_cache_size = new_cache_size; 476 477 return 0; 478} 479 480static void usb_string_cache_destroy(void) 481{ 482 size_t i; 483 for (i = 0; i < usb_string_cache_insert_pos; i++) { 484 free(usb_string_cache[i].vendor); 485 free(usb_string_cache[i].product); 486 } 487 free(usb_string_cache); 488 489 usb_string_cache = NULL; 490 usb_string_cache_size = 0; 491 usb_string_cache_insert_pos = 0; 492} 493 494static struct usb_string_cache_entry *usb_string_cache_insert(void) 495{ 496 struct usb_string_cache_entry *new_entry = NULL; 497 if (usb_string_cache_insert_pos >= usb_string_cache_size) { 498 if (usb_string_cache_grow() < 0) 499 return NULL; 500 } 501 new_entry = &usb_string_cache[usb_string_cache_insert_pos]; 502 usb_string_cache_insert_pos++; 503 return new_entry; 504} 505 506static int usb_string_can_cache(uint16_t vid, uint16_t pid) 507{ 508 if (!vid || !pid) { 509 /* We can't cache these, they aren't unique */ 510 return 0; 511 } 512 513 if (vid == 0x0f0d && pid == 0x00dc) { 514 /* HORI reuses this VID/PID for many different products */ 515 return 0; 516 } 517 518 /* We can cache these strings */ 519 return 1; 520} 521 522static const struct usb_string_cache_entry *usb_string_cache_find(struct libusb_device_descriptor *desc, struct libusb_device_handle *handle) 523{ 524 struct usb_string_cache_entry *entry = NULL; 525 size_t i; 526 527 /* Search for existing string cache entry */ 528 for (i = 0; i < usb_string_cache_insert_pos; i++) { 529 entry = &usb_string_cache[i]; 530 if (entry->vid != desc->idVendor) 531 continue; 532 if (entry->pid != desc->idProduct) 533 continue; 534 return entry; 535 } 536 537 /* Not found, create one. */ 538 entry = usb_string_cache_insert(); 539 if (!entry) 540 return NULL; 541 542 entry->vid = desc->idVendor; 543 entry->pid = desc->idProduct; 544 if (desc->iManufacturer > 0) 545 entry->vendor = get_usb_string(handle, desc->iManufacturer); 546 else 547 entry->vendor = NULL; 548 if (desc->iProduct > 0) 549 entry->product = get_usb_string(handle, desc->iProduct); 550 else 551 entry->product = NULL; 552 553 return entry; 554} 555 556/** 557 Max length of the result: "000-000.000.000.000.000.000.000:000.000" (39 chars). 558 64 is used for simplicity/alignment. 559*/ 560static void get_path(char (*result)[64], libusb_device *dev, int config_number, int interface_number) 561{ 562 char *str = *result; 563 564 /* Note that USB3 port count limit is 7; use 8 here for alignment */ 565 uint8_t port_numbers[8] = {0, 0, 0, 0, 0, 0, 0, 0}; 566 int num_ports = libusb_get_port_numbers(dev, port_numbers, 8); 567 568 if (num_ports > 0) { 569 int n = snprintf(str, sizeof("000-000"), "%u-%u", libusb_get_bus_number(dev), port_numbers[0]); 570 for (uint8_t i = 1; i < num_ports; i++) { 571 n += snprintf(&str[n], sizeof(".000"), ".%u", port_numbers[i]); 572 } 573 n += snprintf(&str[n], sizeof(":000.000"), ":%u.%u", (uint8_t)config_number, (uint8_t)interface_number); 574 str[n] = '\0'; 575 } else { 576 /* Likely impossible, but check: USB3.0 specs limit number of ports to 7 and buffer size here is 8 */ 577 if (num_ports == LIBUSB_ERROR_OVERFLOW) { 578 LOG("make_path() failed. buffer overflow error\n"); 579 } else { 580 LOG("make_path() failed. unknown error\n"); 581 } 582 str[0] = '\0'; 583 } 584} 585 586static char *make_path(libusb_device *dev, int config_number, int interface_number) 587{ 588 char str[64]; 589 get_path(&str, dev, config_number, interface_number); 590 return strdup(str); 591} 592 593HID_API_EXPORT const struct hid_api_version* HID_API_CALL hid_version(void) 594{ 595 return &api_version; 596} 597 598HID_API_EXPORT const char* HID_API_CALL hid_version_str(void) 599{ 600 return HID_API_VERSION_STR; 601} 602 603int HID_API_EXPORT hid_init(void) 604{ 605 if (!usb_context) { 606 const char *locale; 607 608 /* Init Libusb */ 609 if (libusb_init(&usb_context)) 610 return -1; 611 612 /* Set the locale if it's not set. */ 613 locale = setlocale(LC_CTYPE, NULL); 614 if (!locale) 615 (void) setlocale(LC_CTYPE, ""); 616 } 617 618 return 0; 619} 620 621int HID_API_EXPORT hid_exit(void) 622{ 623 usb_string_cache_destroy(); 624 625 if (usb_context) { 626 libusb_exit(usb_context); 627 usb_context = NULL; 628 } 629 630 return 0; 631} 632 633static int hid_get_report_descriptor_libusb(libusb_device_handle *handle, int interface_num, uint16_t expected_report_descriptor_size, unsigned char *buf, size_t buf_size) 634{ 635 unsigned char *tmp = (unsigned char *)malloc(HID_API_MAX_REPORT_DESCRIPTOR_SIZE); 636 637 if (expected_report_descriptor_size > HID_API_MAX_REPORT_DESCRIPTOR_SIZE) 638 expected_report_descriptor_size = HID_API_MAX_REPORT_DESCRIPTOR_SIZE; 639 640 /* Get the HID Report Descriptor. 641 See USB HID Specification, section 7.1.1 642 */ 643 int res = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_RECIPIENT_INTERFACE, LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_REPORT << 8), (uint16_t)interface_num, tmp, expected_report_descriptor_size, 5000); 644 if (res >= 0) { 645 if (res > (int)buf_size) 646 res = (int)buf_size; 647 648 memcpy(buf, tmp, (size_t)res); 649 } else { 650 LOG("libusb_control_transfer() for getting the HID Report descriptor failed with %d: %s\n", res, libusb_error_name(res)); 651 } 652 free(tmp); 653 654 return res; 655} 656 657/** 658 * Requires an opened device with *claimed interface*. 659 */ 660static void fill_device_info_usage(struct hid_device_info *cur_dev, libusb_device_handle *handle, int interface_num, uint16_t expected_report_descriptor_size) 661{ 662 unsigned char *hid_report_descriptor = malloc(HID_API_MAX_REPORT_DESCRIPTOR_SIZE); 663 unsigned short page = 0, usage = 0; 664 665 int res = hid_get_report_descriptor_libusb(handle, interface_num, expected_report_descriptor_size, hid_report_descriptor, HID_API_MAX_REPORT_DESCRIPTOR_SIZE); 666 if (res >= 0) { 667 /* Parse the usage and usage page 668 out of the report descriptor. */ 669 get_usage(hid_report_descriptor, res, &page, &usage); 670 } 671 672 cur_dev->usage_page = page; 673 cur_dev->usage = usage; 674 675 free(hid_report_descriptor); 676} 677 678#ifdef INVASIVE_GET_USAGE 679static void invasive_fill_device_info_usage(struct hid_device_info *cur_dev, libusb_device_handle *handle, int interface_num, uint16_t report_descriptor_size) 680{ 681 int res = 0; 682 683#ifdef DETACH_KERNEL_DRIVER 684 int detached = 0; 685 /* Usage Page and Usage */ 686 res = libusb_kernel_driver_active(handle, interface_num); 687 if (res == 1) { 688 res = libusb_detach_kernel_driver(handle, interface_num); 689 if (res < 0) 690 LOG("Couldn't detach kernel driver, even though a kernel driver was attached.\n"); 691 else 692 detached = 1; 693 } 694#endif 695 696 res = libusb_claim_interface(handle, interface_num); 697 if (res >= 0) { 698 fill_device_info_usage(cur_dev, handle, interface_num, report_descriptor_size); 699 700 /* Release the interface */ 701 res = libusb_release_interface(handle, interface_num); 702 if (res < 0) 703 LOG("Can't release the interface.\n"); 704 } 705 else 706 LOG("Can't claim interface: (%d) %s\n", res, libusb_error_name(res)); 707 708#ifdef DETACH_KERNEL_DRIVER 709 /* Re-attach kernel driver if necessary. */ 710 if (detached) { 711 res = libusb_attach_kernel_driver(handle, interface_num); 712 if (res < 0) 713 LOG("Couldn't re-attach kernel driver.\n"); 714 } 715#endif 716} 717#endif /* INVASIVE_GET_USAGE */ 718 719/** 720 * Create and fill up most of hid_device_info fields. 721 * usage_page/usage is not filled up. 722 */ 723static struct hid_device_info * create_device_info_for_device(libusb_device *device, libusb_device_handle *handle, struct libusb_device_descriptor *desc, int config_number, int interface_num, int interface_class, int interface_subclass, int interface_protocol) 724{ 725 struct hid_device_info *cur_dev = calloc(1, sizeof(struct hid_device_info)); 726 if (cur_dev == NULL) { 727 return NULL; 728 } 729 730 /* VID/PID */ 731 cur_dev->vendor_id = desc->idVendor; 732 cur_dev->product_id = desc->idProduct; 733 734 cur_dev->release_number = desc->bcdDevice; 735 736 cur_dev->interface_number = interface_num; 737 cur_dev->interface_class = interface_class; 738 cur_dev->interface_subclass = interface_subclass; 739 cur_dev->interface_protocol = interface_protocol; 740 741 cur_dev->bus_type = HID_API_BUS_USB; 742 743 cur_dev->path = make_path(device, config_number, interface_num); 744 745 if (!handle) { 746 return cur_dev; 747 } 748 749 if (desc->iSerialNumber > 0) 750 cur_dev->serial_number = get_usb_string(handle, desc->iSerialNumber); 751 752 /* Manufacturer and Product strings */ 753 const struct usb_string_cache_entry *string_cache; 754 if (usb_string_can_cache(desc->idVendor, desc->idProduct) && 755 (string_cache = usb_string_cache_find(desc, handle)) != NULL) { 756 if (string_cache->vendor) { 757 cur_dev->manufacturer_string = wcsdup(string_cache->vendor); 758 } 759 if (string_cache->product) { 760 cur_dev->product_string = wcsdup(string_cache->product); 761 } 762 } else { 763 if (desc->iManufacturer > 0) 764 cur_dev->manufacturer_string = get_usb_string(handle, desc->iManufacturer); 765 if (desc->iProduct > 0) 766 cur_dev->product_string = get_usb_string(handle, desc->iProduct); 767 } 768 769 return cur_dev; 770} 771 772static uint16_t get_report_descriptor_size_from_interface_descriptors(const struct libusb_interface_descriptor *intf_desc) 773{ 774 int i = 0; 775 int found_hid_report_descriptor = 0; 776 uint16_t result = HID_API_MAX_REPORT_DESCRIPTOR_SIZE; 777 const unsigned char *extra = intf_desc->extra; 778 int extra_length = intf_desc->extra_length; 779 780 /* 781 "extra" contains a HID descriptor 782 See section 6.2.1 of HID 1.1 specification. 783 */ 784 785 while (extra_length >= 2) { /* Descriptor header: bLength/bDescriptorType */ 786 if (extra[1] == LIBUSB_DT_HID) { /* bDescriptorType */ 787 if (extra_length < 6) { 788 LOG("Broken HID descriptor: not enough data\n"); 789 break; 790 } 791 unsigned char bNumDescriptors = extra[5]; 792 if (extra_length < (6 + 3 * bNumDescriptors)) { 793 LOG("Broken HID descriptor: not enough data for Report metadata\n"); 794 break; 795 } 796 for (i = 0; i < bNumDescriptors; i++) { 797 if (extra[6 + 3 * i] == LIBUSB_DT_REPORT) { 798 result = (uint16_t)extra[6 + 3 * i + 2] << 8 | extra[6 + 3 * i + 1]; 799 found_hid_report_descriptor = 1; 800 break; 801 } 802 } 803 804 if (!found_hid_report_descriptor) { 805 /* We expect to find exactly 1 HID descriptor (LIBUSB_DT_HID) 806 which should contain exactly one HID Report Descriptor metadata (LIBUSB_DT_REPORT). */ 807 LOG("Broken HID descriptor: missing Report descriptor\n"); 808 } 809 break; 810 } 811 812 if (extra[0] == 0) { /* bLength */ 813 LOG("Broken HID Interface descriptors: zero-sized descriptor\n"); 814 break; 815 } 816 817 /* Iterate over to the next Descriptor */ 818 extra_length -= extra[0]; 819 extra += extra[0]; 820 } 821 822 return result; 823} 824 825static int is_xbox360(unsigned short vendor_id, const struct libusb_interface_descriptor *intf_desc) 826{ 827 static const int xb360_iface_subclass = 93; 828 static const int xb360_iface_protocol = 1; /* Wired */ 829 static const int xb360w_iface_protocol = 129; /* Wireless */ 830 static const int supported_vendors[] = { 831 0x0079, /* GPD Win 2 */ 832 0x044f, /* Thrustmaster */ 833 0x045e, /* Microsoft */ 834 0x046d, /* Logitech */ 835 0x056e, /* Elecom */ 836 0x06a3, /* Saitek */ 837 0x0738, /* Mad Catz */ 838 0x07ff, /* Mad Catz */ 839 0x0e6f, /* PDP */ 840 0x0f0d, /* Hori */ 841 0x1038, /* SteelSeries */ 842 0x11c9, /* Nacon */ 843 0x12ab, /* Unknown */ 844 0x1430, /* RedOctane */ 845 0x146b, /* BigBen */ 846 0x1532, /* Razer Sabertooth */ 847 0x15e4, /* Numark */ 848 0x162e, /* Joytech */ 849 0x1689, /* Razer Onza */ 850 0x1949, /* Lab126, Inc. */ 851 0x1bad, /* Harmonix */ 852 0x20d6, /* PowerA */ 853 0x24c6, /* PowerA */ 854 0x2c22, /* Qanba */ 855 0x2dc8, /* 8BitDo */ 856 0x37d7, /* Flydigi */ 857 0x9886, /* ASTRO Gaming */ 858 }; 859 860 if (intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC && 861 intf_desc->bInterfaceSubClass == xb360_iface_subclass && 862 (intf_desc->bInterfaceProtocol == xb360_iface_protocol || 863 intf_desc->bInterfaceProtocol == xb360w_iface_protocol)) { 864 size_t i; 865 for (i = 0; i < sizeof(supported_vendors)/sizeof(supported_vendors[0]); ++i) { 866 if (vendor_id == supported_vendors[i]) { 867 return 1; 868 } 869 } 870 } 871 return 0; 872} 873 874static int is_xboxone(unsigned short vendor_id, const struct libusb_interface_descriptor *intf_desc) 875{ 876 static const int xb1_iface_subclass = 71; 877 static const int xb1_iface_protocol = 208; 878 static const int supported_vendors[] = { 879 0x03f0, /* HP */ 880 0x044f, /* Thrustmaster */ 881 0x045e, /* Microsoft */ 882 0x0738, /* Mad Catz */ 883 0x0b05, /* ASUS */ 884 0x0e6f, /* PDP */ 885 0x0f0d, /* Hori */ 886 0x10f5, /* Turtle Beach */ 887 0x1532, /* Razer Wildcat */ 888 0x20d6, /* PowerA */ 889 0x24c6, /* PowerA */ 890 0x294b, /* Snakebyte */ 891 0x2dc8, /* 8BitDo */ 892 0x2e24, /* Hyperkin */ 893 0x2e95, /* SCUF */ 894 0x3285, /* Nacon */ 895 0x3537, /* GameSir */ 896 0x366c, /* ByoWave */ 897 }; 898 899 if (intf_desc->bInterfaceNumber == 0 && 900 intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC && 901 intf_desc->bInterfaceSubClass == xb1_iface_subclass && 902 intf_desc->bInterfaceProtocol == xb1_iface_protocol) { 903 size_t i; 904 for (i = 0; i < sizeof(supported_vendors)/sizeof(supported_vendors[0]); ++i) { 905 if (vendor_id == supported_vendors[i]) { 906 return 1; 907 } 908 } 909 } 910 return 0; 911} 912 913static int should_enumerate_interface(unsigned short vendor_id, const struct libusb_interface_descriptor *intf_desc) 914{ 915#if 0 916 printf("Checking interface 0x%x %d/%d/%d/%d\n", vendor_id, intf_desc->bInterfaceNumber, intf_desc->bInterfaceClass, intf_desc->bInterfaceSubClass, intf_desc->bInterfaceProtocol); 917#endif 918 919 if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) 920 return 1; 921 922 /* Also enumerate Xbox 360 controllers */ 923 if (is_xbox360(vendor_id, intf_desc)) 924 return 1; 925 926 /* Also enumerate Xbox One controllers */ 927 if (is_xboxone(vendor_id, intf_desc)) 928 return 1; 929 930 return 0; 931} 932 933static int libusb_blacklist(unsigned short vendor_id, unsigned short product_id) 934{ 935 size_t i; 936 static const struct { unsigned short vid; unsigned short pid; } known_bad[] = { 937 { 0x1532, 0x0227 } /* Razer Huntsman Gaming keyboard - long delay asking for device details */ 938 }; 939 940 for (i = 0; i < (sizeof(known_bad)/sizeof(known_bad[0])); i++) { 941 if ((vendor_id == known_bad[i].vid) && (product_id == known_bad[i].pid || known_bad[i].pid == 0x0000)) { 942 return 1; 943 } 944 } 945 946 return 0; 947} 948 949struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id) 950{ 951 libusb_device **devs; 952 libusb_device *dev; 953 libusb_device_handle *handle = NULL; 954 ssize_t num_devs; 955 int i = 0; 956 957 struct hid_device_info *root = NULL; /* return object */ 958 struct hid_device_info *cur_dev = NULL; 959 960 if(hid_init() < 0) 961 return NULL; 962 963 num_devs = libusb_get_device_list(usb_context, &devs); 964 if (num_devs < 0) 965 return NULL; 966 while ((dev = devs[i++]) != NULL) { 967 struct libusb_device_descriptor desc; 968 struct libusb_config_descriptor *conf_desc = NULL; 969 int j, k; 970 971 int res = libusb_get_device_descriptor(dev, &desc); 972 if (res < 0) 973 continue; 974 975 unsigned short dev_vid = desc.idVendor; 976 unsigned short dev_pid = desc.idProduct; 977 978 if ((vendor_id != 0x0 && vendor_id != dev_vid) || 979 (product_id != 0x0 && product_id != dev_pid) || 980 libusb_blacklist(dev_vid, dev_pid)) { 981 continue; 982 } 983 984#ifdef HIDAPI_IGNORE_DEVICE 985 /* See if there are any devices we should skip in enumeration */ 986 if (HIDAPI_IGNORE_DEVICE(HID_API_BUS_USB, dev_vid, dev_pid, 0, 0, true)) { 987 continue; 988 } 989#endif 990 991 res = libusb_get_active_config_descriptor(dev, &conf_desc); 992 if (res < 0) 993 libusb_get_config_descriptor(dev, 0, &conf_desc); 994 if (conf_desc) { 995 for (j = 0; j < conf_desc->bNumInterfaces; j++) { 996 const struct libusb_interface *intf = &conf_desc->interface[j]; 997 for (k = 0; k < intf->num_altsetting; k++) { 998 const struct libusb_interface_descriptor *intf_desc; 999 intf_desc = &intf->altsetting[k]; 1000 if (should_enumerate_interface(dev_vid, intf_desc)) { 1001 struct hid_device_info *tmp; 1002 1003 res = libusb_open(dev, &handle); 1004 1005#ifdef __ANDROID__ 1006 if (handle) { 1007 /* There is (a potential) libusb Android backend, in which 1008 device descriptor is not accurate up until the device is opened. 1009 https://github.com/libusb/libusb/pull/874#discussion_r632801373 1010 A workaround is to re-read the descriptor again. 1011 Even if it is not going to be accepted into libusb master, 1012 having it here won't do any harm, since reading the device descriptor 1013 is as cheap as copy 18 bytes of data. */ 1014 libusb_get_device_descriptor(dev, &desc); 1015 } 1016#endif 1017 1018 tmp = create_device_info_for_device(dev, handle, &desc, conf_desc->bConfigurationValue, intf_desc->bInterfaceNumber, intf_desc->bInterfaceClass, intf_desc->bInterfaceSubClass, intf_desc->bInterfaceProtocol); 1019 if (tmp) { 1020#ifdef INVASIVE_GET_USAGE 1021 /* TODO: have a runtime check for this section. */ 1022 1023 /* 1024 This section is removed because it is too 1025 invasive on the system. Getting a Usage Page 1026 and Usage requires parsing the HID Report 1027 descriptor. Getting a HID Report descriptor 1028 involves claiming the interface. Claiming the 1029 interface involves detaching the kernel driver. 1030 Detaching the kernel driver is hard on the system 1031 because it will unclaim interfaces (if another 1032 app has them claimed) and the re-attachment of 1033 the driver will sometimes change /dev entry names. 1034 It is for these reasons that this section is 1035 optional. For composite devices, use the interface 1036 field in the hid_device_info struct to distinguish 1037 between interfaces. */ 1038 if (handle) { 1039 uint16_t report_descriptor_size = get_report_descriptor_size_from_interface_descriptors(intf_desc); 1040 1041 invasive_fill_device_info_usage(tmp, handle, intf_desc->bInterfaceNumber, report_descriptor_size); 1042 } 1043#endif /* INVASIVE_GET_USAGE */ 1044 1045 if (cur_dev) { 1046 cur_dev->next = tmp; 1047 } 1048 else { 1049 root = tmp; 1050 } 1051 cur_dev = tmp; 1052 } 1053 1054 if (res >= 0) { 1055 libusb_close(handle); 1056 handle = NULL; 1057 } 1058 break; 1059 } 1060 } /* altsettings */ 1061 } /* interfaces */ 1062 libusb_free_config_descriptor(conf_desc); 1063 } 1064 } 1065 1066 libusb_free_device_list(devs, 1); 1067 1068 return root; 1069} 1070 1071void HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs) 1072{ 1073 struct hid_device_info *d = devs; 1074 while (d) { 1075 struct hid_device_info *next = d->next; 1076 free(d->path); 1077 free(d->serial_number); 1078 free(d->manufacturer_string); 1079 free(d->product_string); 1080 free(d); 1081 d = next; 1082 } 1083} 1084 1085hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number) 1086{ 1087 struct hid_device_info *devs, *cur_dev; 1088 const char *path_to_open = NULL; 1089 hid_device *handle = NULL; 1090 1091 devs = hid_enumerate(vendor_id, product_id); 1092 cur_dev = devs; 1093 while (cur_dev) { 1094 if (cur_dev->vendor_id == vendor_id && 1095 cur_dev->product_id == product_id) { 1096 if (serial_number) { 1097 if (cur_dev->serial_number && 1098 wcscmp(serial_number, cur_dev->serial_number) == 0) { 1099 path_to_open = cur_dev->path; 1100 break; 1101 } 1102 } 1103 else { 1104 path_to_open = cur_dev->path; 1105 break; 1106 } 1107 } 1108 cur_dev = cur_dev->next; 1109 } 1110 1111 if (path_to_open) { 1112 /* Open the device */ 1113 handle = hid_open_path(path_to_open); 1114 } 1115 1116 hid_free_enumeration(devs); 1117 1118 return handle; 1119} 1120 1121static void LIBUSB_CALL read_callback(struct libusb_transfer *transfer) 1122{ 1123 hid_device *dev = transfer->user_data; 1124 int res; 1125 1126 if (transfer->status == LIBUSB_TRANSFER_COMPLETED) { 1127 1128 struct input_report *rpt = (struct input_report*) malloc(sizeof(*rpt)); 1129 rpt->data = (uint8_t*) malloc(transfer->actual_length); 1130 memcpy(rpt->data, transfer->buffer, transfer->actual_length); 1131 rpt->len = transfer->actual_length; 1132 rpt->next = NULL; 1133 1134 hidapi_thread_mutex_lock(&dev->thread_state); 1135 1136 /* Attach the new report object to the end of the list. */ 1137 if (dev->input_reports == NULL) { 1138 /* The list is empty. Put it at the root. */ 1139 dev->input_reports = rpt; 1140 hidapi_thread_cond_signal(&dev->thread_state); 1141 } 1142 else { 1143 /* Find the end of the list and attach. */ 1144 struct input_report *cur = dev->input_reports; 1145 int num_queued = 0; 1146 while (cur->next != NULL) { 1147 cur = cur->next; 1148 num_queued++; 1149 } 1150 cur->next = rpt; 1151 1152 /* Pop one off if we've reached 30 in the queue. This 1153 way we don't grow forever if the user never reads 1154 anything from the device. */ 1155 if (num_queued > 30) { 1156 return_data(dev, NULL, 0); 1157 } 1158 } 1159 hidapi_thread_mutex_unlock(&dev->thread_state); 1160 } 1161 else if (transfer->status == LIBUSB_TRANSFER_CANCELLED) { 1162 dev->shutdown_thread = 1; 1163 } 1164 else if (transfer->status == LIBUSB_TRANSFER_NO_DEVICE) { 1165 dev->shutdown_thread = 1; 1166 } 1167 else if (transfer->status == LIBUSB_TRANSFER_TIMED_OUT) { 1168 //LOG("Timeout (normal)\n"); 1169 } 1170 else { 1171 LOG("Unknown transfer code: %d\n", transfer->status); 1172 } 1173 1174 if (dev->shutdown_thread) { 1175 dev->transfer_loop_finished = 1; 1176 return; 1177 } 1178 1179 /* Re-submit the transfer object. */ 1180 res = libusb_submit_transfer(transfer); 1181 if (res != 0) { 1182 LOG("Unable to submit URB: (%d) %s\n", res, libusb_error_name(res)); 1183 dev->shutdown_thread = 1; 1184 dev->transfer_loop_finished = 1; 1185 } 1186} 1187 1188 1189static void *read_thread(void *param) 1190{ 1191 int res; 1192 hid_device *dev = param; 1193 uint8_t *buf; 1194 const size_t length = dev->input_ep_max_packet_size; 1195 1196 /* Set up the transfer object. */ 1197 buf = (uint8_t*) malloc(length); 1198 dev->transfer = libusb_alloc_transfer(0); 1199 libusb_fill_interrupt_transfer(dev->transfer, 1200 dev->device_handle, 1201 (unsigned char)dev->input_endpoint, 1202 buf, 1203 (int) length, 1204 read_callback, 1205 dev, 1206 5000/*timeout*/); 1207 1208 /* Make the first submission. Further submissions are made 1209 from inside read_callback() */ 1210 res = libusb_submit_transfer(dev->transfer); 1211 if(res < 0) { 1212 LOG("libusb_submit_transfer failed: %d %s. Stopping read_thread from running\n", res, libusb_error_name(res)); 1213 dev->shutdown_thread = 1; 1214 dev->transfer_loop_finished = 1; 1215 } 1216 1217 /* Notify the main thread that the read thread is up and running. */ 1218 hidapi_thread_barrier_wait(&dev->thread_state); 1219 1220 /* Handle all the events. */ 1221 while (!dev->shutdown_thread) { 1222 res = libusb_handle_events(usb_context); 1223 if (res < 0) { 1224 /* There was an error. */ 1225 LOG("read_thread(): (%d) %s\n", res, libusb_error_name(res)); 1226 1227 /* Break out of this loop only on fatal error.*/ 1228 if (res != LIBUSB_ERROR_BUSY && 1229 res != LIBUSB_ERROR_TIMEOUT && 1230 res != LIBUSB_ERROR_OVERFLOW && 1231 res != LIBUSB_ERROR_INTERRUPTED) { 1232 dev->shutdown_thread = 1; 1233 break; 1234 } 1235 } 1236 } 1237 1238 /* Cancel any transfer that may be pending. This call will fail 1239 if no transfers are pending, but that's OK. */ 1240 libusb_cancel_transfer(dev->transfer); 1241 1242 while (!dev->transfer_loop_finished) 1243 libusb_handle_events_completed(usb_context, &dev->transfer_loop_finished); 1244 1245 /* Now that the read thread is stopping, Wake any threads which are 1246 waiting on data (in hid_read_timeout()). Do this under a mutex to 1247 make sure that a thread which is about to go to sleep waiting on 1248 the condition actually will go to sleep before the condition is 1249 signaled. */ 1250 hidapi_thread_mutex_lock(&dev->thread_state); 1251 hidapi_thread_cond_broadcast(&dev->thread_state); 1252 hidapi_thread_mutex_unlock(&dev->thread_state); 1253 1254 /* The dev->transfer->buffer and dev->transfer objects are cleaned up 1255 in hid_close(). They are not cleaned up here because this thread 1256 could end either due to a disconnect or due to a user 1257 call to hid_close(). In both cases the objects can be safely 1258 cleaned up after the call to hidapi_thread_join() (in hid_close()), but 1259 since hid_close() calls libusb_cancel_transfer(), on these objects, 1260 they can not be cleaned up here. */ 1261 1262 return NULL; 1263} 1264 1265static void init_xbox360(libusb_device_handle *device_handle, unsigned short idVendor, unsigned short idProduct, const struct libusb_config_descriptor *conf_desc) 1266{ 1267 (void)conf_desc; 1268 1269 if ((idVendor == 0x05ac && idProduct == 0x055b) /* Gamesir-G3w */ || 1270 (idVendor == 0x20d6 && idProduct == 0x4010) /* PowerA Battle Dragon Advanced Wireless Controller */ || 1271 (idVendor == 0x20d6 && idProduct == 0x4025) /* PowerA OPS v1 Wireless Controller */ || 1272 idVendor == 0x0f0d /* Hori Xbox controllers */) { 1273 unsigned char data[20]; 1274 1275 /* The HORIPAD FPS for Nintendo Switch requires this to enable input reports. 1276 This VID/PID is also shared with other HORI controllers, but they all seem 1277 to be fine with this as well. 1278 */ 1279 memset(data, 0, sizeof(data)); 1280 libusb_control_transfer(device_handle, 0xC1, 0x01, 0x100, 0x0, data, sizeof(data), 100); 1281 } 1282} 1283 1284static void init_xboxone(libusb_device_handle *device_handle, unsigned short idVendor, unsigned short idProduct, const struct libusb_config_descriptor *conf_desc) 1285{ 1286 static const int vendor_microsoft = 0x045e; 1287 static const int xb1_iface_subclass = 71; 1288 static const int xb1_iface_protocol = 208; 1289 int j, k, res; 1290 1291 (void)idProduct; 1292 1293 for (j = 0; j < conf_desc->bNumInterfaces; j++) { 1294 const struct libusb_interface *intf = &conf_desc->interface[j]; 1295 for (k = 0; k < intf->num_altsetting; k++) { 1296 const struct libusb_interface_descriptor *intf_desc = &intf->altsetting[k]; 1297 if (intf_desc->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC && 1298 intf_desc->bInterfaceSubClass == xb1_iface_subclass && 1299 intf_desc->bInterfaceProtocol == xb1_iface_protocol) { 1300 int bSetAlternateSetting = 0; 1301 1302 /* Newer Microsoft Xbox One controllers have a high speed alternate setting */ 1303 if (idVendor == vendor_microsoft && 1304 intf_desc->bInterfaceNumber == 0 && intf_desc->bAlternateSetting == 1) { 1305 bSetAlternateSetting = 1; 1306 } else if (intf_desc->bInterfaceNumber != 0 && intf_desc->bAlternateSetting == 0) { 1307 bSetAlternateSetting = 1; 1308 } 1309 1310 if (bSetAlternateSetting) { 1311 res = libusb_claim_interface(device_handle, intf_desc->bInterfaceNumber); 1312 if (res < 0) { 1313 LOG("can't claim interface %d: %d\n", intf_desc->bInterfaceNumber, res); 1314 continue; 1315 } 1316 1317 LOG("Setting alternate setting for VID/PID 0x%x/0x%x interface %d to %d\n", idVendor, idProduct, intf_desc->bInterfaceNumber, intf_desc->bAlternateSetting); 1318 1319 res = libusb_set_interface_alt_setting(device_handle, intf_desc->bInterfaceNumber, intf_desc->bAlternateSetting); 1320 if (res < 0) { 1321 LOG("xbox init: can't set alt setting %d: %d\n", intf_desc->bInterfaceNumber, res); 1322 } 1323 1324 libusb_release_interface(device_handle, intf_desc->bInterfaceNumber); 1325 } 1326 } 1327 } 1328 } 1329} 1330 1331static void calculate_device_quirks(hid_device *dev, unsigned short idVendor, unsigned short idProduct) 1332{ 1333 static const int VENDOR_SONY = 0x054c; 1334 static const int PRODUCT_PS3_CONTROLLER = 0x0268; 1335 static const int PRODUCT_NAVIGATION_CONTROLLER = 0x042f; 1336 1337 if (idVendor == VENDOR_SONY && 1338 (idProduct == PRODUCT_PS3_CONTROLLER || idProduct == PRODUCT_NAVIGATION_CONTROLLER)) { 1339 dev->skip_output_report_id = 1; 1340 dev->no_output_reports_on_intr_ep = 1; 1341 } 1342} 1343 1344static int hidapi_initialize_device(hid_device *dev, const struct libusb_interface_descriptor *intf_desc, const struct libusb_config_descriptor *conf_desc) 1345{ 1346 int i =0; 1347 int res = 0; 1348 struct libusb_device_descriptor desc; 1349 libusb_get_device_descriptor(libusb_get_device(dev->device_handle), &desc); 1350 1351#ifdef DETACH_KERNEL_DRIVER 1352 /* Detach the kernel driver, but only if the 1353 device is managed by the kernel */ 1354 dev->is_driver_detached = 0; 1355 if (libusb_kernel_driver_active(dev->device_handle, intf_desc->bInterfaceNumber) == 1) { 1356 res = libusb_detach_kernel_driver(dev->device_handle, intf_desc->bInterfaceNumber); 1357 if (res < 0) { 1358 LOG("Unable to detach Kernel Driver: (%d) %s\n", res, libusb_error_name(res)); 1359 return 0; 1360 } 1361 else { 1362 dev->is_driver_detached = 1; 1363 LOG("Driver successfully detached from kernel.\n"); 1364 } 1365 } 1366#endif 1367 res = libusb_claim_interface(dev->device_handle, intf_desc->bInterfaceNumber); 1368 if (res < 0) { 1369 LOG("can't claim interface %d: (%d) %s\n", intf_desc->bInterfaceNumber, res, libusb_error_name(res)); 1370 1371#ifdef DETACH_KERNEL_DRIVER 1372 if (dev->is_driver_detached) { 1373 res = libusb_attach_kernel_driver(dev->device_handle, intf_desc->bInterfaceNumber); 1374 if (res < 0) 1375 LOG("Failed to reattach the driver to kernel: (%d) %s\n", res, libusb_error_name(res)); 1376 } 1377#endif 1378 return 0; 1379 } 1380 1381 /* Initialize XBox 360 controllers */ 1382 if (is_xbox360(desc.idVendor, intf_desc)) { 1383 dev->no_skip_output_report_id = 1; 1384 init_xbox360(dev->device_handle, desc.idVendor, desc.idProduct, conf_desc); 1385 } 1386 1387 /* Initialize XBox One controllers */ 1388 if (is_xboxone(desc.idVendor, intf_desc)) { 1389 init_xboxone(dev->device_handle, desc.idVendor, desc.idProduct, conf_desc); 1390 } 1391 1392 /* Store off the string descriptor indexes */ 1393 dev->manufacturer_index = desc.iManufacturer; 1394 dev->product_index = desc.iProduct; 1395 dev->serial_index = desc.iSerialNumber; 1396 1397 /* Store off the USB information */ 1398 dev->config_number = conf_desc->bConfigurationValue; 1399 dev->interface = intf_desc->bInterfaceNumber; 1400 dev->interface_class = intf_desc->bInterfaceClass; 1401 dev->interface_subclass = intf_desc->bInterfaceSubClass; 1402 dev->interface_protocol = intf_desc->bInterfaceProtocol; 1403 1404 dev->report_descriptor_size = get_report_descriptor_size_from_interface_descriptors(intf_desc); 1405 1406 dev->input_endpoint = 0; 1407 dev->input_ep_max_packet_size = 0; 1408 dev->output_endpoint = 0; 1409 1410 /* Find the INPUT and OUTPUT endpoints. An 1411 OUTPUT endpoint is not required. */ 1412 for (i = 0; i < intf_desc->bNumEndpoints; i++) { 1413 const struct libusb_endpoint_descriptor *ep 1414 = &intf_desc->endpoint[i]; 1415 1416 /* Determine the type and direction of this 1417 endpoint. */ 1418 int is_interrupt = 1419 (ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) 1420 == LIBUSB_TRANSFER_TYPE_INTERRUPT; 1421 int is_output = 1422 (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) 1423 == LIBUSB_ENDPOINT_OUT; 1424 int is_input = 1425 (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) 1426 == LIBUSB_ENDPOINT_IN; 1427 1428 /* Decide whether to use it for input or output. */ 1429 if (dev->input_endpoint == 0 && 1430 is_interrupt && is_input) { 1431 /* Use this endpoint for INPUT */ 1432 dev->input_endpoint = ep->bEndpointAddress; 1433 dev->input_ep_max_packet_size = ep->wMaxPacketSize; 1434 } 1435 if (dev->output_endpoint == 0 && 1436 is_interrupt && is_output) { 1437 /* Use this endpoint for OUTPUT */ 1438 dev->output_endpoint = ep->bEndpointAddress; 1439 } 1440 } 1441 1442 calculate_device_quirks(dev, desc.idVendor, desc.idProduct); 1443 1444 hidapi_thread_create(&dev->thread_state, read_thread, dev); 1445 1446 /* Wait here for the read thread to be initialized. */ 1447 hidapi_thread_barrier_wait(&dev->thread_state); 1448 return 1; 1449} 1450 1451 1452HID_API_EXPORT hid_device *hid_open_path(const char *path) 1453{ 1454 hid_device *dev = NULL; 1455 1456 libusb_device **devs = NULL; 1457 libusb_device *usb_dev = NULL; 1458 int res = 0; 1459 int d = 0; 1460 int good_open = 0; 1461 1462 if(hid_init() < 0) 1463 return NULL; 1464 1465 dev = new_hid_device(); 1466 1467 libusb_get_device_list(usb_context, &devs); 1468 while ((usb_dev = devs[d++]) != NULL && !good_open) { 1469 struct libusb_device_descriptor desc; 1470 struct libusb_config_descriptor *conf_desc = NULL; 1471 int j,k; 1472 1473 res = libusb_get_device_descriptor(usb_dev, &desc); 1474 if (res < 0) 1475 continue; 1476 1477 res = libusb_get_active_config_descriptor(usb_dev, &conf_desc); 1478 if (res < 0) 1479 libusb_get_config_descriptor(usb_dev, 0, &conf_desc); 1480 if (!conf_desc) 1481 continue; 1482 1483 for (j = 0; j < conf_desc->bNumInterfaces && !good_open; j++) { 1484 const struct libusb_interface *intf = &conf_desc->interface[j]; 1485 for (k = 0; k < intf->num_altsetting && !good_open; k++) { 1486 const struct libusb_interface_descriptor *intf_desc = &intf->altsetting[k]; 1487 if (should_enumerate_interface(desc.idVendor, intf_desc)) { 1488 char dev_path[64]; 1489 get_path(&dev_path, usb_dev, conf_desc->bConfigurationValue, intf_desc->bInterfaceNumber); 1490 if (!strcmp(dev_path, path)) { 1491 /* Matched Paths. Open this device */ 1492 1493 /* OPEN HERE */ 1494 res = libusb_open(usb_dev, &dev->device_handle); 1495 if (res < 0) { 1496 LOG("can't open device\n"); 1497 break; 1498 } 1499 good_open = hidapi_initialize_device(dev, intf_desc, conf_desc); 1500 if (!good_open) 1501 libusb_close(dev->device_handle); 1502 } 1503 } 1504 } 1505 } 1506 libusb_free_config_descriptor(conf_desc); 1507 } 1508 1509 libusb_free_device_list(devs, 1); 1510 1511 /* If we have a good handle, return it. */ 1512 if (good_open) { 1513 return dev; 1514 } 1515 else { 1516 /* Unable to open any devices. */ 1517 free_hid_device(dev); 1518 return NULL; 1519 } 1520} 1521 1522 1523HID_API_EXPORT hid_device * HID_API_CALL hid_libusb_wrap_sys_device(intptr_t sys_dev, int interface_num) 1524{ 1525/* 0x01000107 is a LIBUSB_API_VERSION for 1.0.23 - version when libusb_wrap_sys_device was introduced */ 1526#if (!defined(HIDAPI_TARGET_LIBUSB_API_VERSION) || HIDAPI_TARGET_LIBUSB_API_VERSION >= 0x01000107) && (LIBUSB_API_VERSION >= 0x01000107) 1527 hid_device *dev = NULL; 1528 struct libusb_config_descriptor *conf_desc = NULL; 1529 const struct libusb_interface_descriptor *selected_intf_desc = NULL; 1530 int res = 0; 1531 int j = 0, k = 0; 1532 1533 if(hid_init() < 0) 1534 return NULL; 1535 1536 dev = new_hid_device(); 1537 1538 res = libusb_wrap_sys_device(usb_context, sys_dev, &dev->device_handle); 1539 if (res < 0) { 1540 LOG("libusb_wrap_sys_device failed: %d %s\n", res, libusb_error_name(res)); 1541 goto err; 1542 } 1543 1544 res = libusb_get_active_config_descriptor(libusb_get_device(dev->device_handle), &conf_desc); 1545 if (res < 0) 1546 libusb_get_config_descriptor(libusb_get_device(dev->device_handle), 0, &conf_desc); 1547 1548 if (!conf_desc) { 1549 LOG("Failed to get configuration descriptor: %d %s\n", res, libusb_error_name(res)); 1550 goto err; 1551 } 1552 1553 /* find matching HID interface */ 1554 for (j = 0; j < conf_desc->bNumInterfaces && !selected_intf_desc; j++) { 1555 const struct libusb_interface *intf = &conf_desc->interface[j]; 1556 for (k = 0; k < intf->num_altsetting; k++) { 1557 const struct libusb_interface_descriptor *intf_desc = &intf->altsetting[k]; 1558 if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) { 1559 if (interface_num < 0 || interface_num == intf_desc->bInterfaceNumber) { 1560 selected_intf_desc = intf_desc; 1561 break; 1562 } 1563 } 1564 } 1565 } 1566 1567 if (!selected_intf_desc) { 1568 if (interface_num < 0) { 1569 LOG("Sys USB device doesn't contain a HID interface\n"); 1570 } 1571 else { 1572 LOG("Sys USB device doesn't contain a HID interface with number %d\n", interface_num); 1573 } 1574 goto err; 1575 } 1576 1577 if (!hidapi_initialize_device(dev, selected_intf_desc, conf_desc)) 1578 goto err; 1579 1580 return dev; 1581 1582err: 1583 if (conf_desc) 1584 libusb_free_config_descriptor(conf_desc); 1585 if (dev->device_handle) 1586 libusb_close(dev->device_handle); 1587 free_hid_device(dev); 1588#else 1589 (void)sys_dev; 1590 (void)interface_num; 1591 LOG("libusb_wrap_sys_device is not available\n"); 1592#endif 1593 return NULL; 1594} 1595 1596 1597int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t length) 1598{ 1599 int res; 1600 int report_number; 1601 int skipped_report_id = 0; 1602 1603 if (!data || (length ==0)) { 1604 return -1; 1605 } 1606 1607 report_number = data[0]; 1608 1609 if ((!dev->no_skip_output_report_id && report_number == 0x0) || dev->skip_output_report_id) { 1610 data++; 1611 length--; 1612 skipped_report_id = 1; 1613 } 1614 1615 1616 if (dev->output_endpoint <= 0 || dev->no_output_reports_on_intr_ep) { 1617 /* No interrupt out endpoint. Use the Control Endpoint */ 1618 res = libusb_control_transfer(dev->device_handle, 1619 LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT, 1620 0x09/*HID Set_Report*/, 1621 (uint16_t)((2/*HID output*/ << 8) | report_number), 1622 (uint16_t)dev->interface, 1623 (unsigned char *)data, (uint16_t)length, 1624 1000/*timeout millis*/); 1625 1626 if (res < 0) 1627 return -1; 1628 1629 if (skipped_report_id) 1630 length++; 1631 1632 return (int) length; 1633 } 1634 else { 1635 /* Use the interrupt out endpoint */ 1636 int actual_length; 1637 res = libusb_interrupt_transfer(dev->device_handle, 1638 (unsigned char)dev->output_endpoint, 1639 (unsigned char*)data, 1640 (int) length, 1641 &actual_length, 1000); 1642 1643 if (res < 0) 1644 return -1; 1645 1646 if (skipped_report_id) 1647 actual_length++; 1648 1649 return actual_length; 1650 } 1651} 1652 1653/* Helper function, to simplify hid_read(). 1654 This should be called with dev->mutex locked. */ 1655static int return_data(hid_device *dev, unsigned char *data, size_t length) 1656{ 1657 /* Copy the data out of the linked list item (rpt) into the 1658 return buffer (data), and delete the liked list item. */ 1659 struct input_report *rpt = dev->input_reports; 1660 size_t len = (length < rpt->len)? length: rpt->len; 1661 if (len > 0) 1662 memcpy(data, rpt->data, len); 1663 dev->input_reports = rpt->next; 1664 free(rpt->data); 1665 free(rpt); 1666 return (int) len; 1667} 1668 1669static void cleanup_mutex(void *param) 1670{ 1671 hid_device *dev = param; 1672 hidapi_thread_mutex_unlock(&dev->thread_state); 1673} 1674 1675 1676int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds) 1677{ 1678#if 0 1679 int transferred; 1680 int res = libusb_interrupt_transfer(dev->device_handle, dev->input_endpoint, data, length, &transferred, 5000); 1681 LOG("transferred: %d\n", transferred); 1682 return transferred; 1683#endif 1684 /* by initialising this variable right here, GCC gives a compilation warning/error: */ 1685 /* error: variable ‘bytes_read’ might be clobbered by ‘longjmp’ or ‘vfork’ [-Werror=clobbered] */ 1686 int bytes_read; /* = -1; */ 1687 1688 hidapi_thread_mutex_lock(&dev->thread_state); 1689 hidapi_thread_cleanup_push(cleanup_mutex, dev); 1690 1691 bytes_read = -1; 1692 1693 /* There's an input report queued up. Return it. */ 1694 if (dev->input_reports) { 1695 /* Return the first one */ 1696 bytes_read = return_data(dev, data, length); 1697 goto ret; 1698 } 1699 1700 if (dev->shutdown_thread) { 1701 /* This means the device has been disconnected. 1702 An error code of -1 should be returned. */ 1703 bytes_read = -1; 1704 goto ret; 1705 } 1706 1707 if (milliseconds == -1) { 1708 /* Blocking */ 1709 while (!dev->input_reports && !dev->shutdown_thread) { 1710 hidapi_thread_cond_wait(&dev->thread_state); 1711 } 1712 if (dev->input_reports) { 1713 bytes_read = return_data(dev, data, length); 1714 } 1715 } 1716 else if (milliseconds > 0) { 1717 /* Non-blocking, but called with timeout. */ 1718 int res; 1719 hidapi_timespec ts; 1720 hidapi_thread_gettime(&ts); 1721 hidapi_thread_addtime(&ts, milliseconds); 1722 1723 while (!dev->input_reports && !dev->shutdown_thread) { 1724 res = hidapi_thread_cond_timedwait(&dev->thread_state, &ts); 1725 if (res == 0) { 1726 if (dev->input_reports) { 1727 bytes_read = return_data(dev, data, length); 1728 break; 1729 } 1730 1731 /* If we're here, there was a spurious wake up 1732 or the read thread was shutdown. Run the 1733 loop again (ie: don't break). */ 1734 } 1735 else if (res == HIDAPI_THREAD_TIMED_OUT) { 1736 /* Timed out. */ 1737 bytes_read = 0; 1738 break; 1739 } 1740 else { 1741 /* Error. */ 1742 bytes_read = -1; 1743 break; 1744 } 1745 } 1746 } 1747 else { 1748 /* Purely non-blocking */ 1749 bytes_read = 0; 1750 } 1751 1752ret: 1753 hidapi_thread_mutex_unlock(&dev->thread_state); 1754 hidapi_thread_cleanup_pop(0); 1755 1756 return bytes_read; 1757} 1758 1759int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length) 1760{ 1761 return hid_read_timeout(dev, data, length, dev->blocking ? -1 : 0); 1762} 1763 1764int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock) 1765{ 1766 dev->blocking = !nonblock; 1767 1768 return 0; 1769} 1770 1771 1772int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length) 1773{ 1774 int res = -1; 1775 int skipped_report_id = 0; 1776 int report_number = data[0]; 1777 1778 if (report_number == 0x0) { 1779 data++; 1780 length--; 1781 skipped_report_id = 1; 1782 } 1783 1784 res = libusb_control_transfer(dev->device_handle, 1785 LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT, 1786 0x09/*HID set_report*/, 1787 (uint16_t)((3/*HID feature*/ << 8) | report_number), 1788 (uint16_t)dev->interface, 1789 (unsigned char *)data, (uint16_t)length, 1790 1000/*timeout millis*/); 1791 1792 if (res < 0) 1793 return -1; 1794 1795 /* Account for the report ID */ 1796 if (skipped_report_id) 1797 length++; 1798 1799 return (int) length; 1800} 1801 1802int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length) 1803{ 1804 int res = -1; 1805 int skipped_report_id = 0; 1806 int report_number = data[0]; 1807 1808 if (report_number == 0x0) { 1809 /* Offset the return buffer by 1, so that the report ID 1810 will remain in byte 0. */ 1811 data++; 1812 length--; 1813 skipped_report_id = 1; 1814 } 1815 res = libusb_control_transfer(dev->device_handle, 1816 LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN, 1817 0x01/*HID get_report*/, 1818 (uint16_t)((3/*HID feature*/ << 8) | report_number), 1819 (uint16_t)dev->interface, 1820 (unsigned char *)data, (uint16_t)length, 1821 1000/*timeout millis*/); 1822 1823 if (res < 0) 1824 return -1; 1825 1826 if (skipped_report_id) 1827 res++; 1828 1829 return res; 1830} 1831 1832int HID_API_EXPORT HID_API_CALL hid_get_input_report(hid_device *dev, unsigned char *data, size_t length) 1833{ 1834 int res = -1; 1835 int skipped_report_id = 0; 1836 int report_number = data[0]; 1837 1838 if (report_number == 0x0) { 1839 /* Offset the return buffer by 1, so that the report ID 1840 will remain in byte 0. */ 1841 data++; 1842 length--; 1843 skipped_report_id = 1; 1844 } 1845 res = libusb_control_transfer(dev->device_handle, 1846 LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN, 1847 0x01/*HID get_report*/, 1848 (uint16_t)((1/*HID Input*/ << 8) | report_number), 1849 (uint16_t)dev->interface, 1850 (unsigned char *)data, (uint16_t)length, 1851 1000/*timeout millis*/); 1852 1853 if (res < 0) 1854 return -1; 1855 1856 if (skipped_report_id) 1857 res++; 1858 1859 return res; 1860} 1861 1862void HID_API_EXPORT hid_close(hid_device *dev) 1863{ 1864 if (!dev) 1865 return; 1866 1867 /* Cause read_thread() to stop. */ 1868 dev->shutdown_thread = 1; 1869 libusb_cancel_transfer(dev->transfer); 1870 1871 /* Wait for read_thread() to end. */ 1872 hidapi_thread_join(&dev->thread_state); 1873 1874 /* Clean up the Transfer objects allocated in read_thread(). */ 1875 free(dev->transfer->buffer); 1876 dev->transfer->buffer = NULL; 1877 libusb_free_transfer(dev->transfer); 1878 1879 /* release the interface */ 1880 libusb_release_interface(dev->device_handle, dev->interface); 1881 1882 /* reattach the kernel driver if it was detached */ 1883#ifdef DETACH_KERNEL_DRIVER 1884 if (dev->is_driver_detached) { 1885 int res = libusb_attach_kernel_driver(dev->device_handle, dev->interface); 1886 if (res < 0) 1887 LOG("Failed to reattach the driver to kernel.\n"); 1888 } 1889#endif 1890 1891 /* Close the handle */ 1892 libusb_close(dev->device_handle); 1893 1894 /* Clear out the queue of received reports. */ 1895 hidapi_thread_mutex_lock(&dev->thread_state); 1896 while (dev->input_reports) { 1897 return_data(dev, NULL, 0); 1898 } 1899 hidapi_thread_mutex_unlock(&dev->thread_state); 1900 1901 free_hid_device(dev); 1902} 1903 1904 1905int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen) 1906{ 1907 return hid_get_indexed_string(dev, dev->manufacturer_index, string, maxlen); 1908} 1909 1910int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen) 1911{ 1912 return hid_get_indexed_string(dev, dev->product_index, string, maxlen); 1913} 1914 1915int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen) 1916{ 1917 return hid_get_indexed_string(dev, dev->serial_index, string, maxlen); 1918} 1919 1920HID_API_EXPORT struct hid_device_info *HID_API_CALL hid_get_device_info(hid_device *dev) { 1921 if (!dev->device_info) { 1922 struct libusb_device_descriptor desc; 1923 libusb_device *usb_device = libusb_get_device(dev->device_handle); 1924 libusb_get_device_descriptor(usb_device, &desc); 1925 1926 dev->device_info = create_device_info_for_device(usb_device, dev->device_handle, &desc, dev->config_number, dev->interface, dev->interface_class, dev->interface_subclass, dev->interface_protocol); 1927 // device error already set by create_device_info_for_device, if any 1928 1929 if (dev->device_info) { 1930 fill_device_info_usage(dev->device_info, dev->device_handle, dev->interface, dev->report_descriptor_size); 1931 } 1932 } 1933 1934 return dev->device_info; 1935} 1936 1937int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen) 1938{ 1939 wchar_t *str; 1940 1941 str = get_usb_string(dev->device_handle, (uint8_t)string_index); 1942 if (str) { 1943 wcsncpy(string, str, maxlen); 1944 string[maxlen-1] = L'\0'; 1945 free(str); 1946 return 0; 1947 } 1948 else 1949 return -1; 1950} 1951 1952 1953int HID_API_EXPORT_CALL hid_get_report_descriptor(hid_device *dev, unsigned char *buf, size_t buf_size) 1954{ 1955 return hid_get_report_descriptor_libusb(dev->device_handle, dev->interface, dev->report_descriptor_size, buf, buf_size); 1956} 1957 1958 1959HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev) 1960{ 1961 (void)dev; 1962 return L"hid_error is not implemented yet"; 1963} 1964 1965 1966struct lang_map_entry { 1967 const char *name; 1968 const char *string_code; 1969 uint16_t usb_code; 1970}; 1971 1972#define LANG(name,code,usb_code) { name, code, usb_code } 1973static struct lang_map_entry lang_map[] = { 1974 LANG("Afrikaans", "af", 0x0436), 1975 LANG("Albanian", "sq", 0x041C), 1976 LANG("Arabic - United Arab Emirates", "ar_ae", 0x3801), 1977 LANG("Arabic - Bahrain", "ar_bh", 0x3C01), 1978 LANG("Arabic - Algeria", "ar_dz", 0x1401), 1979 LANG("Arabic - Egypt", "ar_eg", 0x0C01), 1980 LANG("Arabic - Iraq", "ar_iq", 0x0801), 1981 LANG("Arabic - Jordan", "ar_jo", 0x2C01), 1982 LANG("Arabic - Kuwait", "ar_kw", 0x3401), 1983 LANG("Arabic - Lebanon", "ar_lb", 0x3001), 1984 LANG("Arabic - Libya", "ar_ly", 0x1001), 1985 LANG("Arabic - Morocco", "ar_ma", 0x1801), 1986 LANG("Arabic - Oman", "ar_om", 0x2001), 1987 LANG("Arabic - Qatar", "ar_qa", 0x4001), 1988 LANG("Arabic - Saudi Arabia", "ar_sa", 0x0401), 1989 LANG("Arabic - Syria", "ar_sy", 0x2801), 1990 LANG("Arabic - Tunisia", "ar_tn", 0x1C01), 1991 LANG("Arabic - Yemen", "ar_ye", 0x2401), 1992 LANG("Armenian", "hy", 0x042B), 1993 LANG("Azeri - Latin", "az_az", 0x042C), 1994 LANG("Azeri - Cyrillic", "az_az", 0x082C), 1995 LANG("Basque", "eu", 0x042D), 1996 LANG("Belarusian", "be", 0x0423), 1997 LANG("Bulgarian", "bg", 0x0402), 1998 LANG("Catalan", "ca", 0x0403), 1999 LANG("Chinese - China", "zh_cn", 0x0804), 2000 LANG("Chinese - Hong Kong SAR", "zh_hk", 0x0C04), 2001 LANG("Chinese - Macau SAR", "zh_mo", 0x1404), 2002 LANG("Chinese - Singapore", "zh_sg", 0x1004), 2003 LANG("Chinese - Taiwan", "zh_tw", 0x0404), 2004 LANG("Croatian", "hr", 0x041A), 2005 LANG("Czech", "cs", 0x0405), 2006 LANG("Danish", "da", 0x0406), 2007 LANG("Dutch - Netherlands", "nl_nl", 0x0413), 2008 LANG("Dutch - Belgium", "nl_be", 0x0813), 2009 LANG("English - Australia", "en_au", 0x0C09), 2010 LANG("English - Belize", "en_bz", 0x2809), 2011 LANG("English - Canada", "en_ca", 0x1009), 2012 LANG("English - Caribbean", "en_cb", 0x2409), 2013 LANG("English - Ireland", "en_ie", 0x1809), 2014 LANG("English - Jamaica", "en_jm", 0x2009), 2015 LANG("English - New Zealand", "en_nz", 0x1409), 2016 LANG("English - Philippines", "en_ph", 0x3409), 2017 LANG("English - Southern Africa", "en_za", 0x1C09), 2018 LANG("English - Trinidad", "en_tt", 0x2C09), 2019 LANG("English - Great Britain", "en_gb", 0x0809), 2020 LANG("English - United States", "en_us", 0x0409), 2021 LANG("Estonian", "et", 0x0425), 2022 LANG("Farsi", "fa", 0x0429), 2023 LANG("Finnish", "fi", 0x040B), 2024 LANG("Faroese", "fo", 0x0438), 2025 LANG("French - France", "fr_fr", 0x040C), 2026 LANG("French - Belgium", "fr_be", 0x080C), 2027 LANG("French - Canada", "fr_ca", 0x0C0C), 2028 LANG("French - Luxembourg", "fr_lu", 0x140C), 2029 LANG("French - Switzerland", "fr_ch", 0x100C), 2030 LANG("Gaelic - Ireland", "gd_ie", 0x083C), 2031 LANG("Gaelic - Scotland", "gd", 0x043C), 2032 LANG("German - Germany", "de_de", 0x0407), 2033 LANG("German - Austria", "de_at", 0x0C07), 2034 LANG("German - Liechtenstein", "de_li", 0x1407), 2035 LANG("German - Luxembourg", "de_lu", 0x1007), 2036 LANG("German - Switzerland", "de_ch", 0x0807), 2037 LANG("Greek", "el", 0x0408), 2038 LANG("Hebrew", "he", 0x040D), 2039 LANG("Hindi", "hi", 0x0439), 2040 LANG("Hungarian", "hu", 0x040E), 2041 LANG("Icelandic", "is", 0x040F), 2042 LANG("Indonesian", "id", 0x0421), 2043 LANG("Italian - Italy", "it_it", 0x0410), 2044 LANG("Italian - Switzerland", "it_ch", 0x0810), 2045 LANG("Japanese", "ja", 0x0411), 2046 LANG("Korean", "ko", 0x0412), 2047 LANG("Latvian", "lv", 0x0426), 2048 LANG("Lithuanian", "lt", 0x0427), 2049 LANG("F.Y.R.O. Macedonia", "mk", 0x042F), 2050 LANG("Malay - Malaysia", "ms_my", 0x043E), 2051 LANG("Malay – Brunei", "ms_bn", 0x083E), 2052 LANG("Maltese", "mt", 0x043A), 2053 LANG("Marathi", "mr", 0x044E), 2054 LANG("Norwegian - Bokml", "no_no", 0x0414), 2055 LANG("Norwegian - Nynorsk", "no_no", 0x0814), 2056 LANG("Polish", "pl", 0x0415), 2057 LANG("Portuguese - Portugal", "pt_pt", 0x0816), 2058 LANG("Portuguese - Brazil", "pt_br", 0x0416), 2059 LANG("Raeto-Romance", "rm", 0x0417), 2060 LANG("Romanian - Romania", "ro", 0x0418), 2061 LANG("Romanian - Republic of Moldova", "ro_mo", 0x0818), 2062 LANG("Russian", "ru", 0x0419), 2063 LANG("Russian - Republic of Moldova", "ru_mo", 0x0819), 2064 LANG("Sanskrit", "sa", 0x044F), 2065 LANG("Serbian - Cyrillic", "sr_sp", 0x0C1A), 2066 LANG("Serbian - Latin", "sr_sp", 0x081A), 2067 LANG("Setsuana", "tn", 0x0432), 2068 LANG("Slovenian", "sl", 0x0424), 2069 LANG("Slovak", "sk", 0x041B), 2070 LANG("Sorbian", "sb", 0x042E), 2071 LANG("Spanish - Spain (Traditional)", "es_es", 0x040A), 2072 LANG("Spanish - Argentina", "es_ar", 0x2C0A), 2073 LANG("Spanish - Bolivia", "es_bo", 0x400A), 2074 LANG("Spanish - Chile", "es_cl", 0x340A), 2075 LANG("Spanish - Colombia", "es_co", 0x240A), 2076 LANG("Spanish - Costa Rica", "es_cr", 0x140A), 2077 LANG("Spanish - Dominican Republic", "es_do", 0x1C0A), 2078 LANG("Spanish - Ecuador", "es_ec", 0x300A), 2079 LANG("Spanish - Guatemala", "es_gt", 0x100A), 2080 LANG("Spanish - Honduras", "es_hn", 0x480A), 2081 LANG("Spanish - Mexico", "es_mx", 0x080A), 2082 LANG("Spanish - Nicaragua", "es_ni", 0x4C0A), 2083 LANG("Spanish - Panama", "es_pa", 0x180A), 2084 LANG("Spanish - Peru", "es_pe", 0x280A), 2085 LANG("Spanish - Puerto Rico", "es_pr", 0x500A), 2086 LANG("Spanish - Paraguay", "es_py", 0x3C0A), 2087 LANG("Spanish - El Salvador", "es_sv", 0x440A), 2088 LANG("Spanish - Uruguay", "es_uy", 0x380A), 2089 LANG("Spanish - Venezuela", "es_ve", 0x200A), 2090 LANG("Southern Sotho", "st", 0x0430), 2091 LANG("Swahili", "sw", 0x0441), 2092 LANG("Swedish - Sweden", "sv_se", 0x041D), 2093 LANG("Swedish - Finland", "sv_fi", 0x081D), 2094 LANG("Tamil", "ta", 0x0449), 2095 LANG("Tatar", "tt", 0X0444), 2096 LANG("Thai", "th", 0x041E), 2097 LANG("Turkish", "tr", 0x041F), 2098 LANG("Tsonga", "ts", 0x0431), 2099 LANG("Ukrainian", "uk", 0x0422), 2100 LANG("Urdu", "ur", 0x0420), 2101 LANG("Uzbek - Cyrillic", "uz_uz", 0x0843), 2102 LANG("Uzbek – Latin", "uz_uz", 0x0443), 2103 LANG("Vietnamese", "vi", 0x042A), 2104 LANG("Xhosa", "xh", 0x0434), 2105 LANG("Yiddish", "yi", 0x043D), 2106 LANG("Zulu", "zu", 0x0435), 2107 LANG(NULL, NULL, 0x0), 2108}; 2109 2110uint16_t get_usb_code_for_current_locale(void) 2111{ 2112 char *locale; 2113 char search_string[64]; 2114 char *ptr; 2115 struct lang_map_entry *lang; 2116 2117 /* Get the current locale. */ 2118 locale = setlocale(0, NULL); 2119 if (!locale) 2120 return 0x0; 2121 2122 /* Make a copy of the current locale string. */ 2123 strncpy(search_string, locale, sizeof(search_string)-1); 2124 search_string[sizeof(search_string)-1] = '\0'; 2125 2126 /* Chop off the encoding part, and make it lower case. */ 2127 ptr = search_string; 2128 while (*ptr) { 2129 *ptr = (char)tolower(*ptr); 2130 if (*ptr == '.') { 2131 *ptr = '\0'; 2132 break; 2133 } 2134 ptr++; 2135 } 2136 2137 /* Find the entry which matches the string code of our locale. */ 2138 lang = lang_map; 2139 while (lang->string_code) { 2140 if (!strcmp(lang->string_code, search_string)) { 2141 return lang->usb_code; 2142 } 2143 lang++; 2144 } 2145 2146 /* There was no match. Find with just the language only. */ 2147 /* Chop off the variant. Chop it off at the '_'. */ 2148 ptr = search_string; 2149 while (*ptr) { 2150 *ptr = (char)tolower(*ptr); 2151 if (*ptr == '_') { 2152 *ptr = '\0'; 2153 break; 2154 } 2155 ptr++; 2156 } 2157 2158#if 0 /* TODO: Do we need this? */ 2159 /* Find the entry which matches the string code of our language. */ 2160 lang = lang_map; 2161 while (lang->string_code) { 2162 if (!strcmp(lang->string_code, search_string)) { 2163 return lang->usb_code; 2164 } 2165 lang++; 2166 } 2167#endif 2168 2169 /* Found nothing. */ 2170 return 0x0; 2171} 2172 2173#if defined(_MSC_VER) 2174#pragma warning (pop) 2175#endif 2176 2177#ifdef __cplusplus 2178} 2179#endif 2180
[FILE END]
(C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.