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/2010
10 Libusb Version - 8/13/2010
11 FreeBSD Version - 11/1/2011
12
13 Copyright 2009, All Rights Reserved.
14
15 At the discretion of the user of this library,
16 this software may be licensed under the terms of the
17 GNU General Public License v3, a BSD-Style license, or the
18 original HIDAPI license as outlined in the LICENSE.txt,
19 LICENSE-gpl3.txt, LICENSE-bsd.txt, and LICENSE-orig.txt
20 files located at the root of the source distribution.
21 These files may also be found in the public source
22 code repository located at:
23 http://github.com/signal11/hidapi .
24 ********************************************************/
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 <pthread.h>
42 #include <wchar.h>
43
44 /* GNU / LibUSB */
45 #include <libusb.h>
46 #ifndef __ANDROID__
47 #include <iconv.h>
48 #endif
49
50 #include "hidapi.h"
51
52 #ifdef __ANDROID__
53
54 /* Barrier implementation because Android/Bionic don't have pthread_barrier.
55 This implementation came from Brent Priddy and was posted on
56 StackOverflow. It is used with his permission. */
57 typedef int pthread_barrierattr_t;
58 typedef struct pthread_barrier {
59 pthread_mutex_t mutex;
60 pthread_cond_t cond;
61 int count;
62 int trip_count;
63 } pthread_barrier_t;
64
pthread_barrier_init(pthread_barrier_t * barrier,const pthread_barrierattr_t * attr,unsigned int count)65 static int pthread_barrier_init(pthread_barrier_t *barrier, const pthread_barrierattr_t *attr, unsigned int count)
66 {
67 if(count == 0) {
68 errno = EINVAL;
69 return -1;
70 }
71
72 if(pthread_mutex_init(&barrier->mutex, 0) < 0) {
73 return -1;
74 }
75 if(pthread_cond_init(&barrier->cond, 0) < 0) {
76 pthread_mutex_destroy(&barrier->mutex);
77 return -1;
78 }
79 barrier->trip_count = count;
80 barrier->count = 0;
81
82 return 0;
83 }
84
pthread_barrier_destroy(pthread_barrier_t * barrier)85 static int pthread_barrier_destroy(pthread_barrier_t *barrier)
86 {
87 pthread_cond_destroy(&barrier->cond);
88 pthread_mutex_destroy(&barrier->mutex);
89 return 0;
90 }
91
pthread_barrier_wait(pthread_barrier_t * barrier)92 static int pthread_barrier_wait(pthread_barrier_t *barrier)
93 {
94 pthread_mutex_lock(&barrier->mutex);
95 ++(barrier->count);
96 if(barrier->count >= barrier->trip_count)
97 {
98 barrier->count = 0;
99 pthread_cond_broadcast(&barrier->cond);
100 pthread_mutex_unlock(&barrier->mutex);
101 return 1;
102 }
103 else
104 {
105 pthread_cond_wait(&barrier->cond, &(barrier->mutex));
106 pthread_mutex_unlock(&barrier->mutex);
107 return 0;
108 }
109 }
110
111 #endif
112
113 #ifdef __cplusplus
114 extern "C" {
115 #endif
116
117 #ifdef DEBUG_PRINTF
118 #define LOG(...) fprintf(stderr, __VA_ARGS__)
119 #else
120 #define LOG(...) do {} while (0)
121 #endif
122
123 #ifndef __FreeBSD__
124 #define DETACH_KERNEL_DRIVER
125 #endif
126
127 /* Uncomment to enable the retrieval of Usage and Usage Page in
128 hid_enumerate(). Warning, on platforms different from FreeBSD
129 this is very invasive as it requires the detach
130 and re-attach of the kernel driver. See comments inside hid_enumerate().
131 libusb HIDAPI programs are encouraged to use the interface number
132 instead to differentiate between interfaces on a composite HID device. */
133 /*#define INVASIVE_GET_USAGE*/
134
135 /* Linked List of input reports received from the device. */
136 struct input_report {
137 uint8_t *data;
138 size_t len;
139 struct input_report *next;
140 };
141
142
143 struct hid_device_ {
144 /* Handle to the actual device. */
145 libusb_device_handle *device_handle;
146
147 /* Endpoint information */
148 int input_endpoint;
149 int output_endpoint;
150 int input_ep_max_packet_size;
151
152 /* The interface number of the HID */
153 int interface;
154
155 /* Indexes of Strings */
156 int manufacturer_index;
157 int product_index;
158 int serial_index;
159
160 /* Whether blocking reads are used */
161 int blocking; /* boolean */
162
163 /* Read thread objects */
164 pthread_t thread;
165 pthread_mutex_t mutex; /* Protects input_reports */
166 pthread_cond_t condition;
167 pthread_barrier_t barrier; /* Ensures correct startup sequence */
168 int shutdown_thread;
169 int cancelled;
170 struct libusb_transfer *transfer;
171
172 /* List of received input reports. */
173 struct input_report *input_reports;
174 };
175
176 static libusb_context *usb_context = NULL;
177
178 uint16_t get_usb_code_for_current_locale(void);
179 static int return_data(hid_device *dev, unsigned char *data, size_t length);
180
new_hid_device(void)181 static hid_device *new_hid_device(void)
182 {
183 hid_device *dev = calloc(1, sizeof(hid_device));
184 dev->blocking = 1;
185
186 pthread_mutex_init(&dev->mutex, NULL);
187 pthread_cond_init(&dev->condition, NULL);
188 pthread_barrier_init(&dev->barrier, NULL, 2);
189
190 return dev;
191 }
192
free_hid_device(hid_device * dev)193 static void free_hid_device(hid_device *dev)
194 {
195 /* Clean up the thread objects */
196 pthread_barrier_destroy(&dev->barrier);
197 pthread_cond_destroy(&dev->condition);
198 pthread_mutex_destroy(&dev->mutex);
199
200 /* Free the device itself */
201 free(dev);
202 }
203
204 #if 0
205 /*TODO: Implement this funciton on hidapi/libusb.. */
206 static void register_error(hid_device *device, const char *op)
207 {
208
209 }
210 #endif
211
212 #ifdef INVASIVE_GET_USAGE
213 /* Get bytes from a HID Report Descriptor.
214 Only call with a num_bytes of 0, 1, 2, or 4. */
get_bytes(uint8_t * rpt,size_t len,size_t num_bytes,size_t cur)215 static uint32_t get_bytes(uint8_t *rpt, size_t len, size_t num_bytes, size_t cur)
216 {
217 /* Return if there aren't enough bytes. */
218 if (cur + num_bytes >= len)
219 return 0;
220
221 if (num_bytes == 0)
222 return 0;
223 else if (num_bytes == 1) {
224 return rpt[cur+1];
225 }
226 else if (num_bytes == 2) {
227 return (rpt[cur+2] * 256 + rpt[cur+1]);
228 }
229 else if (num_bytes == 4) {
230 return (rpt[cur+4] * 0x01000000 +
231 rpt[cur+3] * 0x00010000 +
232 rpt[cur+2] * 0x00000100 +
233 rpt[cur+1] * 0x00000001);
234 }
235 else
236 return 0;
237 }
238
239 /* Retrieves the device's Usage Page and Usage from the report
240 descriptor. The algorithm is simple, as it just returns the first
241 Usage and Usage Page that it finds in the descriptor.
242 The return value is 0 on success and -1 on failure. */
get_usage(uint8_t * report_descriptor,size_t size,unsigned short * usage_page,unsigned short * usage)243 static int get_usage(uint8_t *report_descriptor, size_t size,
244 unsigned short *usage_page, unsigned short *usage)
245 {
246 unsigned int i = 0;
247 int size_code;
248 int data_len, key_size;
249 int usage_found = 0, usage_page_found = 0;
250
251 while (i < size) {
252 int key = report_descriptor[i];
253 int key_cmd = key & 0xfc;
254
255 //printf("key: %02hhx\n", key);
256
257 if ((key & 0xf0) == 0xf0) {
258 /* This is a Long Item. The next byte contains the
259 length of the data section (value) for this key.
260 See the HID specification, version 1.11, section
261 6.2.2.3, titled "Long Items." */
262 if (i+1 < size)
263 data_len = report_descriptor[i+1];
264 else
265 data_len = 0; /* malformed report */
266 key_size = 3;
267 }
268 else {
269 /* This is a Short Item. The bottom two bits of the
270 key contain the size code for the data section
271 (value) for this key. Refer to the HID
272 specification, version 1.11, section 6.2.2.2,
273 titled "Short Items." */
274 size_code = key & 0x3;
275 switch (size_code) {
276 case 0:
277 case 1:
278 case 2:
279 data_len = size_code;
280 break;
281 case 3:
282 data_len = 4;
283 break;
284 default:
285 /* Can't ever happen since size_code is & 0x3 */
286 data_len = 0;
287 break;
288 };
289 key_size = 1;
290 }
291
292 if (key_cmd == 0x4) {
293 *usage_page = get_bytes(report_descriptor, size, data_len, i);
294 usage_page_found = 1;
295 //printf("Usage Page: %x\n", (uint32_t)*usage_page);
296 }
297 if (key_cmd == 0x8) {
298 *usage = get_bytes(report_descriptor, size, data_len, i);
299 usage_found = 1;
300 //printf("Usage: %x\n", (uint32_t)*usage);
301 }
302
303 if (usage_page_found && usage_found)
304 return 0; /* success */
305
306 /* Skip over this key and it's associated data */
307 i += data_len + key_size;
308 }
309
310 return -1; /* failure */
311 }
312 #endif /* INVASIVE_GET_USAGE */
313
314 #if defined(__FreeBSD__) && __FreeBSD__ < 10
315 /* The libusb version included in FreeBSD < 10 doesn't have this function. In
316 mainline libusb, it's inlined in libusb.h. This function will bear a striking
317 resemblence to that one, because there's about one way to code it.
318
319 Note that the data parameter is Unicode in UTF-16LE encoding.
320 Return value is the number of bytes in data, or LIBUSB_ERROR_*.
321 */
libusb_get_string_descriptor(libusb_device_handle * dev,uint8_t descriptor_index,uint16_t lang_id,unsigned char * data,int length)322 static inline int libusb_get_string_descriptor(libusb_device_handle *dev,
323 uint8_t descriptor_index, uint16_t lang_id,
324 unsigned char *data, int length)
325 {
326 return libusb_control_transfer(dev,
327 LIBUSB_ENDPOINT_IN | 0x0, /* Endpoint 0 IN */
328 LIBUSB_REQUEST_GET_DESCRIPTOR,
329 (LIBUSB_DT_STRING << 8) | descriptor_index,
330 lang_id, data, (uint16_t) length, 1000);
331 }
332
333 #endif
334
335
336 /* Get the first language the device says it reports. This comes from
337 USB string #0. */
get_first_language(libusb_device_handle * dev)338 static uint16_t get_first_language(libusb_device_handle *dev)
339 {
340 uint16_t buf[32];
341 int len;
342
343 /* Get the string from libusb. */
344 len = libusb_get_string_descriptor(dev,
345 0x0, /* String ID */
346 0x0, /* Language */
347 (unsigned char*)buf,
348 sizeof(buf));
349 if (len < 4)
350 return 0x0;
351
352 return buf[1]; /* First two bytes are len and descriptor type. */
353 }
354
is_language_supported(libusb_device_handle * dev,uint16_t lang)355 static int is_language_supported(libusb_device_handle *dev, uint16_t lang)
356 {
357 uint16_t buf[32];
358 int len;
359 int i;
360
361 /* Get the string from libusb. */
362 len = libusb_get_string_descriptor(dev,
363 0x0, /* String ID */
364 0x0, /* Language */
365 (unsigned char*)buf,
366 sizeof(buf));
367 if (len < 4)
368 return 0x0;
369
370
371 len /= 2; /* language IDs are two-bytes each. */
372 /* Start at index 1 because there are two bytes of protocol data. */
373 for (i = 1; i < len; i++) {
374 if (buf[i] == lang)
375 return 1;
376 }
377
378 return 0;
379 }
380
381
382 /* This function returns a newly allocated wide string containing the USB
383 device string numbered by the index. The returned string must be freed
384 by using free(). */
get_usb_string(libusb_device_handle * dev,uint8_t idx)385 static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
386 {
387 char buf[512];
388 int len;
389 wchar_t *str = NULL;
390
391 #ifndef __ANDROID__ /* we don't use iconv on Android */
392 wchar_t wbuf[256];
393 /* iconv variables */
394 iconv_t ic;
395 size_t inbytes;
396 size_t outbytes;
397 size_t res;
398 #ifdef __FreeBSD__
399 const char *inptr;
400 #else
401 char *inptr;
402 #endif
403 char *outptr;
404 #endif
405
406 /* Determine which language to use. */
407 uint16_t lang;
408 lang = get_usb_code_for_current_locale();
409 if (!is_language_supported(dev, lang))
410 lang = get_first_language(dev);
411
412 /* Get the string from libusb. */
413 len = libusb_get_string_descriptor(dev,
414 idx,
415 lang,
416 (unsigned char*)buf,
417 sizeof(buf));
418 if (len < 0)
419 return NULL;
420
421 #ifdef __ANDROID__
422
423 /* Bionic does not have iconv support nor wcsdup() function, so it
424 has to be done manually. The following code will only work for
425 code points that can be represented as a single UTF-16 character,
426 and will incorrectly convert any code points which require more
427 than one UTF-16 character.
428
429 Skip over the first character (2-bytes). */
430 len -= 2;
431 str = malloc((len / 2 + 1) * sizeof(wchar_t));
432 int i;
433 for (i = 0; i < len / 2; i++) {
434 str[i] = buf[i * 2 + 2] | (buf[i * 2 + 3] << 8);
435 }
436 str[len / 2] = 0x00000000;
437
438 #else
439
440 /* buf does not need to be explicitly NULL-terminated because
441 it is only passed into iconv() which does not need it. */
442
443 /* Initialize iconv. */
444 ic = iconv_open("WCHAR_T", "UTF-16LE");
445 if (ic == (iconv_t)-1) {
446 LOG("iconv_open() failed\n");
447 return NULL;
448 }
449
450 /* Convert to native wchar_t (UTF-32 on glibc/BSD systems).
451 Skip the first character (2-bytes). */
452 inptr = buf+2;
453 inbytes = len-2;
454 outptr = (char*) wbuf;
455 outbytes = sizeof(wbuf);
456 res = iconv(ic, (char**)&inptr, &inbytes, &outptr, &outbytes);
457 if (res == (size_t)-1) {
458 LOG("iconv() failed\n");
459 goto err;
460 }
461
462 /* Write the terminating NULL. */
463 wbuf[sizeof(wbuf)/sizeof(wbuf[0])-1] = 0x00000000;
464 if (outbytes >= sizeof(wbuf[0]))
465 *((wchar_t*)outptr) = 0x00000000;
466
467 /* Allocate and copy the string. */
468 str = wcsdup(wbuf);
469
470 err:
471 iconv_close(ic);
472
473 #endif
474
475 return str;
476 }
477
make_path(libusb_device * dev,int interface_number)478 static char *make_path(libusb_device *dev, int interface_number)
479 {
480 char str[64];
481 snprintf(str, sizeof(str), "%04x:%04x:%02x",
482 libusb_get_bus_number(dev),
483 libusb_get_device_address(dev),
484 interface_number);
485 str[sizeof(str)-1] = '\0';
486
487 return strdup(str);
488 }
489
490
hid_init(void)491 int HID_API_EXPORT hid_init(void)
492 {
493 if (!usb_context) {
494 const char *locale;
495
496 /* Init Libusb */
497 if (libusb_init(&usb_context))
498 return -1;
499
500 /* Set the locale if it's not set. */
501 locale = setlocale(LC_CTYPE, NULL);
502 if (!locale)
503 setlocale(LC_CTYPE, "");
504 }
505
506 return 0;
507 }
508
hid_exit(void)509 int HID_API_EXPORT hid_exit(void)
510 {
511 if (usb_context) {
512 libusb_exit(usb_context);
513 usb_context = NULL;
514 }
515
516 return 0;
517 }
518
hid_enumerate(unsigned short vendor_id,unsigned short product_id)519 struct hid_device_info HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
520 {
521 libusb_device **devs;
522 libusb_device *dev;
523 libusb_device_handle *handle;
524 ssize_t num_devs;
525 int i = 0;
526
527 struct hid_device_info *root = NULL; /* return object */
528 struct hid_device_info *cur_dev = NULL;
529
530 if(hid_init() < 0)
531 return NULL;
532
533 num_devs = libusb_get_device_list(usb_context, &devs);
534 if (num_devs < 0)
535 return NULL;
536 while ((dev = devs[i++]) != NULL) {
537 struct libusb_device_descriptor desc;
538 struct libusb_config_descriptor *conf_desc = NULL;
539 int j, k;
540 int interface_num = 0;
541
542 int res = libusb_get_device_descriptor(dev, &desc);
543 unsigned short dev_vid = desc.idVendor;
544 unsigned short dev_pid = desc.idProduct;
545
546 res = libusb_get_active_config_descriptor(dev, &conf_desc);
547 if (res < 0)
548 libusb_get_config_descriptor(dev, 0, &conf_desc);
549 if (conf_desc) {
550 for (j = 0; j < conf_desc->bNumInterfaces; j++) {
551 const struct libusb_interface *intf = &conf_desc->interface[j];
552 for (k = 0; k < intf->num_altsetting; k++) {
553 const struct libusb_interface_descriptor *intf_desc;
554 intf_desc = &intf->altsetting[k];
555 if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) {
556 interface_num = intf_desc->bInterfaceNumber;
557
558 /* Check the VID/PID against the arguments */
559 if ((vendor_id == 0x0 || vendor_id == dev_vid) &&
560 (product_id == 0x0 || product_id == dev_pid)) {
561 struct hid_device_info *tmp;
562
563 /* VID/PID match. Create the record. */
564 tmp = calloc(1, sizeof(struct hid_device_info));
565 if (cur_dev) {
566 cur_dev->next = tmp;
567 }
568 else {
569 root = tmp;
570 }
571 cur_dev = tmp;
572
573 /* Fill out the record */
574 cur_dev->next = NULL;
575 cur_dev->path = make_path(dev, interface_num);
576
577 res = libusb_open(dev, &handle);
578
579 if (res >= 0) {
580 /* Serial Number */
581 if (desc.iSerialNumber > 0)
582 cur_dev->serial_number =
583 get_usb_string(handle, desc.iSerialNumber);
584
585 /* Manufacturer and Product strings */
586 if (desc.iManufacturer > 0)
587 cur_dev->manufacturer_string =
588 get_usb_string(handle, desc.iManufacturer);
589 if (desc.iProduct > 0)
590 cur_dev->product_string =
591 get_usb_string(handle, desc.iProduct);
592
593 #ifdef INVASIVE_GET_USAGE
594 {
595 /*
596 This section is removed because it is too
597 invasive on the system. Getting a Usage Page
598 and Usage requires parsing the HID Report
599 descriptor. Getting a HID Report descriptor
600 involves claiming the interface. Claiming the
601 interface involves detaching the kernel driver.
602 Detaching the kernel driver is hard on the system
603 because it will unclaim interfaces (if another
604 app has them claimed) and the re-attachment of
605 the driver will sometimes change /dev entry names.
606 It is for these reasons that this section is
607 #if 0. For composite devices, use the interface
608 field in the hid_device_info struct to distinguish
609 between interfaces. */
610 unsigned char data[256];
611 #ifdef DETACH_KERNEL_DRIVER
612 int detached = 0;
613 /* Usage Page and Usage */
614 res = libusb_kernel_driver_active(handle, interface_num);
615 if (res == 1) {
616 res = libusb_detach_kernel_driver(handle, interface_num);
617 if (res < 0)
618 LOG("Couldn't detach kernel driver, even though a kernel driver was attached.");
619 else
620 detached = 1;
621 }
622 #endif
623 res = libusb_claim_interface(handle, interface_num);
624 if (res >= 0) {
625 /* Get the HID Report Descriptor. */
626 res = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_RECIPIENT_INTERFACE, LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_REPORT << 8)|interface_num, 0, data, sizeof(data), 5000);
627 if (res >= 0) {
628 unsigned short page=0, usage=0;
629 /* Parse the usage and usage page
630 out of the report descriptor. */
631 get_usage(data, res, &page, &usage);
632 cur_dev->usage_page = page;
633 cur_dev->usage = usage;
634 }
635 else
636 LOG("libusb_control_transfer() for getting the HID report failed with %d\n", res);
637
638 /* Release the interface */
639 res = libusb_release_interface(handle, interface_num);
640 if (res < 0)
641 LOG("Can't release the interface.\n");
642 }
643 else
644 LOG("Can't claim interface %d\n", res);
645 #ifdef DETACH_KERNEL_DRIVER
646 /* Re-attach kernel driver if necessary. */
647 if (detached) {
648 res = libusb_attach_kernel_driver(handle, interface_num);
649 if (res < 0)
650 LOG("Couldn't re-attach kernel driver.\n");
651 }
652 #endif
653 }
654 #endif /* INVASIVE_GET_USAGE */
655
656 libusb_close(handle);
657 }
658 /* VID/PID */
659 cur_dev->vendor_id = dev_vid;
660 cur_dev->product_id = dev_pid;
661
662 /* Release Number */
663 cur_dev->release_number = desc.bcdDevice;
664
665 /* Interface Number */
666 cur_dev->interface_number = interface_num;
667 }
668 }
669 } /* altsettings */
670 } /* interfaces */
671 libusb_free_config_descriptor(conf_desc);
672 }
673 }
674
675 libusb_free_device_list(devs, 1);
676
677 return root;
678 }
679
hid_free_enumeration(struct hid_device_info * devs)680 void HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs)
681 {
682 struct hid_device_info *d = devs;
683 while (d) {
684 struct hid_device_info *next = d->next;
685 free(d->path);
686 free(d->serial_number);
687 free(d->manufacturer_string);
688 free(d->product_string);
689 free(d);
690 d = next;
691 }
692 }
693
hid_open(unsigned short vendor_id,unsigned short product_id,const wchar_t * serial_number)694 hid_device * hid_open(unsigned short vendor_id, unsigned short product_id, const wchar_t *serial_number)
695 {
696 struct hid_device_info *devs, *cur_dev;
697 const char *path_to_open = NULL;
698 hid_device *handle = NULL;
699
700 devs = hid_enumerate(vendor_id, product_id);
701 cur_dev = devs;
702 while (cur_dev) {
703 if (cur_dev->vendor_id == vendor_id &&
704 cur_dev->product_id == product_id) {
705 if (serial_number) {
706 if (cur_dev->serial_number &&
707 wcscmp(serial_number, cur_dev->serial_number) == 0) {
708 path_to_open = cur_dev->path;
709 break;
710 }
711 }
712 else {
713 path_to_open = cur_dev->path;
714 break;
715 }
716 }
717 cur_dev = cur_dev->next;
718 }
719
720 if (path_to_open) {
721 /* Open the device */
722 handle = hid_open_path(path_to_open);
723 }
724
725 hid_free_enumeration(devs);
726
727 return handle;
728 }
729
read_callback(struct libusb_transfer * transfer)730 static void read_callback(struct libusb_transfer *transfer)
731 {
732 hid_device *dev = transfer->user_data;
733 int res;
734
735 if (transfer->status == LIBUSB_TRANSFER_COMPLETED) {
736
737 struct input_report *rpt = malloc(sizeof(*rpt));
738 rpt->data = malloc(transfer->actual_length);
739 memcpy(rpt->data, transfer->buffer, transfer->actual_length);
740 rpt->len = transfer->actual_length;
741 rpt->next = NULL;
742
743 pthread_mutex_lock(&dev->mutex);
744
745 /* Attach the new report object to the end of the list. */
746 if (dev->input_reports == NULL) {
747 /* The list is empty. Put it at the root. */
748 dev->input_reports = rpt;
749 pthread_cond_signal(&dev->condition);
750 }
751 else {
752 /* Find the end of the list and attach. */
753 struct input_report *cur = dev->input_reports;
754 int num_queued = 0;
755 while (cur->next != NULL) {
756 cur = cur->next;
757 num_queued++;
758 }
759 cur->next = rpt;
760
761 /* Pop one off if we've reached 30 in the queue. This
762 way we don't grow forever if the user never reads
763 anything from the device. */
764 if (num_queued > 30) {
765 return_data(dev, NULL, 0);
766 }
767 }
768 pthread_mutex_unlock(&dev->mutex);
769 }
770 else if (transfer->status == LIBUSB_TRANSFER_CANCELLED) {
771 dev->shutdown_thread = 1;
772 dev->cancelled = 1;
773 return;
774 }
775 else if (transfer->status == LIBUSB_TRANSFER_NO_DEVICE) {
776 dev->shutdown_thread = 1;
777 dev->cancelled = 1;
778 return;
779 }
780 else if (transfer->status == LIBUSB_TRANSFER_TIMED_OUT) {
781 //LOG("Timeout (normal)\n");
782 }
783 else {
784 LOG("Unknown transfer code: %d\n", transfer->status);
785 }
786
787 /* Re-submit the transfer object. */
788 res = libusb_submit_transfer(transfer);
789 if (res != 0) {
790 LOG("Unable to submit URB. libusb error code: %d\n", res);
791 dev->shutdown_thread = 1;
792 dev->cancelled = 1;
793 }
794 }
795
796
read_thread(void * param)797 static void *read_thread(void *param)
798 {
799 hid_device *dev = param;
800 unsigned char *buf;
801 const size_t length = dev->input_ep_max_packet_size;
802
803 /* Set up the transfer object. */
804 buf = malloc(length);
805 dev->transfer = libusb_alloc_transfer(0);
806 libusb_fill_interrupt_transfer(dev->transfer,
807 dev->device_handle,
808 dev->input_endpoint,
809 buf,
810 length,
811 read_callback,
812 dev,
813 5000/*timeout*/);
814
815 /* Make the first submission. Further submissions are made
816 from inside read_callback() */
817 libusb_submit_transfer(dev->transfer);
818
819 /* Notify the main thread that the read thread is up and running. */
820 pthread_barrier_wait(&dev->barrier);
821
822 /* Handle all the events. */
823 while (!dev->shutdown_thread) {
824 int res;
825 res = libusb_handle_events(usb_context);
826 if (res < 0) {
827 /* There was an error. */
828 LOG("read_thread(): libusb reports error # %d\n", res);
829
830 /* Break out of this loop only on fatal error.*/
831 if (res != LIBUSB_ERROR_BUSY &&
832 res != LIBUSB_ERROR_TIMEOUT &&
833 res != LIBUSB_ERROR_OVERFLOW &&
834 res != LIBUSB_ERROR_INTERRUPTED) {
835 break;
836 }
837 }
838 }
839
840 /* Cancel any transfer that may be pending. This call will fail
841 if no transfers are pending, but that's OK. */
842 libusb_cancel_transfer(dev->transfer);
843
844 while (!dev->cancelled)
845 libusb_handle_events_completed(usb_context, &dev->cancelled);
846
847 /* Now that the read thread is stopping, Wake any threads which are
848 waiting on data (in hid_read_timeout()). Do this under a mutex to
849 make sure that a thread which is about to go to sleep waiting on
850 the condition acutally will go to sleep before the condition is
851 signaled. */
852 pthread_mutex_lock(&dev->mutex);
853 pthread_cond_broadcast(&dev->condition);
854 pthread_mutex_unlock(&dev->mutex);
855
856 /* The dev->transfer->buffer and dev->transfer objects are cleaned up
857 in hid_close(). They are not cleaned up here because this thread
858 could end either due to a disconnect or due to a user
859 call to hid_close(). In both cases the objects can be safely
860 cleaned up after the call to pthread_join() (in hid_close()), but
861 since hid_close() calls libusb_cancel_transfer(), on these objects,
862 they can not be cleaned up here. */
863
864 return NULL;
865 }
866
867
hid_open_path(const char * path)868 hid_device * HID_API_EXPORT hid_open_path(const char *path)
869 {
870 hid_device *dev = NULL;
871
872 libusb_device **devs;
873 libusb_device *usb_dev;
874 int res;
875 int d = 0;
876 int good_open = 0;
877
878 if(hid_init() < 0)
879 return NULL;
880
881 dev = new_hid_device();
882
883 libusb_get_device_list(usb_context, &devs);
884 while ((usb_dev = devs[d++]) != NULL) {
885 struct libusb_device_descriptor desc;
886 struct libusb_config_descriptor *conf_desc = NULL;
887 int i,j,k;
888 libusb_get_device_descriptor(usb_dev, &desc);
889
890 if (libusb_get_active_config_descriptor(usb_dev, &conf_desc) < 0)
891 continue;
892 for (j = 0; j < conf_desc->bNumInterfaces; j++) {
893 const struct libusb_interface *intf = &conf_desc->interface[j];
894 for (k = 0; k < intf->num_altsetting; k++) {
895 const struct libusb_interface_descriptor *intf_desc;
896 intf_desc = &intf->altsetting[k];
897 if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) {
898 char *dev_path = make_path(usb_dev, intf_desc->bInterfaceNumber);
899 if (!strcmp(dev_path, path)) {
900 /* Matched Paths. Open this device */
901
902 /* OPEN HERE */
903 res = libusb_open(usb_dev, &dev->device_handle);
904 if (res < 0) {
905 LOG("can't open device\n");
906 free(dev_path);
907 break;
908 }
909 good_open = 1;
910 #ifdef DETACH_KERNEL_DRIVER
911 /* Detach the kernel driver, but only if the
912 device is managed by the kernel */
913 if (libusb_kernel_driver_active(dev->device_handle, intf_desc->bInterfaceNumber) == 1) {
914 res = libusb_detach_kernel_driver(dev->device_handle, intf_desc->bInterfaceNumber);
915 if (res < 0) {
916 libusb_close(dev->device_handle);
917 LOG("Unable to detach Kernel Driver\n");
918 free(dev_path);
919 good_open = 0;
920 break;
921 }
922 }
923 #endif
924 res = libusb_claim_interface(dev->device_handle, intf_desc->bInterfaceNumber);
925 if (res < 0) {
926 LOG("can't claim interface %d: %d\n", intf_desc->bInterfaceNumber, res);
927 free(dev_path);
928 libusb_close(dev->device_handle);
929 good_open = 0;
930 break;
931 }
932
933 /* Store off the string descriptor indexes */
934 dev->manufacturer_index = desc.iManufacturer;
935 dev->product_index = desc.iProduct;
936 dev->serial_index = desc.iSerialNumber;
937
938 /* Store off the interface number */
939 dev->interface = intf_desc->bInterfaceNumber;
940
941 /* Find the INPUT and OUTPUT endpoints. An
942 OUTPUT endpoint is not required. */
943 for (i = 0; i < intf_desc->bNumEndpoints; i++) {
944 const struct libusb_endpoint_descriptor *ep
945 = &intf_desc->endpoint[i];
946
947 /* Determine the type and direction of this
948 endpoint. */
949 int is_interrupt =
950 (ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK)
951 == LIBUSB_TRANSFER_TYPE_INTERRUPT;
952 int is_output =
953 (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)
954 == LIBUSB_ENDPOINT_OUT;
955 int is_input =
956 (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)
957 == LIBUSB_ENDPOINT_IN;
958
959 /* Decide whether to use it for intput or output. */
960 if (dev->input_endpoint == 0 &&
961 is_interrupt && is_input) {
962 /* Use this endpoint for INPUT */
963 dev->input_endpoint = ep->bEndpointAddress;
964 dev->input_ep_max_packet_size = ep->wMaxPacketSize;
965 }
966 if (dev->output_endpoint == 0 &&
967 is_interrupt && is_output) {
968 /* Use this endpoint for OUTPUT */
969 dev->output_endpoint = ep->bEndpointAddress;
970 }
971 }
972
973 pthread_create(&dev->thread, NULL, read_thread, dev);
974
975 /* Wait here for the read thread to be initialized. */
976 pthread_barrier_wait(&dev->barrier);
977
978 }
979 free(dev_path);
980 }
981 }
982 }
983 libusb_free_config_descriptor(conf_desc);
984
985 }
986
987 libusb_free_device_list(devs, 1);
988
989 /* If we have a good handle, return it. */
990 if (good_open) {
991 return dev;
992 }
993 else {
994 /* Unable to open any devices. */
995 free_hid_device(dev);
996 return NULL;
997 }
998 }
999
1000
hid_write(hid_device * dev,const unsigned char * data,size_t length)1001 int HID_API_EXPORT hid_write(hid_device *dev, const unsigned char *data, size_t length)
1002 {
1003 int res;
1004 int report_number = data[0];
1005 int skipped_report_id = 0;
1006
1007 if (report_number == 0x0) {
1008 data++;
1009 length--;
1010 skipped_report_id = 1;
1011 }
1012
1013
1014 if (dev->output_endpoint <= 0) {
1015 /* No interrput out endpoint. Use the Control Endpoint */
1016 res = libusb_control_transfer(dev->device_handle,
1017 LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT,
1018 0x09/*HID Set_Report*/,
1019 (2/*HID output*/ << 8) | report_number,
1020 dev->interface,
1021 (unsigned char *)data, length,
1022 1000/*timeout millis*/);
1023
1024 if (res < 0)
1025 return -1;
1026
1027 if (skipped_report_id)
1028 length++;
1029
1030 return length;
1031 }
1032 else {
1033 /* Use the interrupt out endpoint */
1034 int actual_length;
1035 res = libusb_interrupt_transfer(dev->device_handle,
1036 dev->output_endpoint,
1037 (unsigned char*)data,
1038 length,
1039 &actual_length, 1000);
1040
1041 if (res < 0)
1042 return -1;
1043
1044 if (skipped_report_id)
1045 actual_length++;
1046
1047 return actual_length;
1048 }
1049 }
1050
1051 /* Helper function, to simplify hid_read().
1052 This should be called with dev->mutex locked. */
return_data(hid_device * dev,unsigned char * data,size_t length)1053 static int return_data(hid_device *dev, unsigned char *data, size_t length)
1054 {
1055 /* Copy the data out of the linked list item (rpt) into the
1056 return buffer (data), and delete the liked list item. */
1057 struct input_report *rpt = dev->input_reports;
1058 size_t len = (length < rpt->len)? length: rpt->len;
1059 if (len > 0)
1060 memcpy(data, rpt->data, len);
1061 dev->input_reports = rpt->next;
1062 free(rpt->data);
1063 free(rpt);
1064 return len;
1065 }
1066
cleanup_mutex(void * param)1067 static void cleanup_mutex(void *param)
1068 {
1069 hid_device *dev = param;
1070 pthread_mutex_unlock(&dev->mutex);
1071 }
1072
1073
hid_read_timeout(hid_device * dev,unsigned char * data,size_t length,int milliseconds)1074 int HID_API_EXPORT hid_read_timeout(hid_device *dev, unsigned char *data, size_t length, int milliseconds)
1075 {
1076 int bytes_read = -1;
1077
1078 #if 0
1079 int transferred;
1080 int res = libusb_interrupt_transfer(dev->device_handle, dev->input_endpoint, data, length, &transferred, 5000);
1081 LOG("transferred: %d\n", transferred);
1082 return transferred;
1083 #endif
1084
1085 pthread_mutex_lock(&dev->mutex);
1086 pthread_cleanup_push(&cleanup_mutex, dev);
1087
1088 /* There's an input report queued up. Return it. */
1089 if (dev->input_reports) {
1090 /* Return the first one */
1091 bytes_read = return_data(dev, data, length);
1092 goto ret;
1093 }
1094
1095 if (dev->shutdown_thread) {
1096 /* This means the device has been disconnected.
1097 An error code of -1 should be returned. */
1098 bytes_read = -1;
1099 goto ret;
1100 }
1101
1102 if (milliseconds == -1) {
1103 /* Blocking */
1104 while (!dev->input_reports && !dev->shutdown_thread) {
1105 pthread_cond_wait(&dev->condition, &dev->mutex);
1106 }
1107 if (dev->input_reports) {
1108 bytes_read = return_data(dev, data, length);
1109 }
1110 }
1111 else if (milliseconds > 0) {
1112 /* Non-blocking, but called with timeout. */
1113 int res;
1114 struct timespec ts;
1115 clock_gettime(CLOCK_REALTIME, &ts);
1116 ts.tv_sec += milliseconds / 1000;
1117 ts.tv_nsec += (milliseconds % 1000) * 1000000;
1118 if (ts.tv_nsec >= 1000000000L) {
1119 ts.tv_sec++;
1120 ts.tv_nsec -= 1000000000L;
1121 }
1122
1123 while (!dev->input_reports && !dev->shutdown_thread) {
1124 res = pthread_cond_timedwait(&dev->condition, &dev->mutex, &ts);
1125 if (res == 0) {
1126 if (dev->input_reports) {
1127 bytes_read = return_data(dev, data, length);
1128 break;
1129 }
1130
1131 /* If we're here, there was a spurious wake up
1132 or the read thread was shutdown. Run the
1133 loop again (ie: don't break). */
1134 }
1135 else if (res == ETIMEDOUT) {
1136 /* Timed out. */
1137 bytes_read = 0;
1138 break;
1139 }
1140 else {
1141 /* Error. */
1142 bytes_read = -1;
1143 break;
1144 }
1145 }
1146 }
1147 else {
1148 /* Purely non-blocking */
1149 bytes_read = 0;
1150 }
1151
1152 ret:
1153 pthread_mutex_unlock(&dev->mutex);
1154 pthread_cleanup_pop(0);
1155
1156 return bytes_read;
1157 }
1158
hid_read(hid_device * dev,unsigned char * data,size_t length)1159 int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length)
1160 {
1161 return hid_read_timeout(dev, data, length, dev->blocking ? -1 : 0);
1162 }
1163
hid_set_nonblocking(hid_device * dev,int nonblock)1164 int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock)
1165 {
1166 dev->blocking = !nonblock;
1167
1168 return 0;
1169 }
1170
1171
hid_send_feature_report(hid_device * dev,const unsigned char * data,size_t length)1172 int HID_API_EXPORT hid_send_feature_report(hid_device *dev, const unsigned char *data, size_t length)
1173 {
1174 int res = -1;
1175 int skipped_report_id = 0;
1176 int report_number = data[0];
1177
1178 if (report_number == 0x0) {
1179 data++;
1180 length--;
1181 skipped_report_id = 1;
1182 }
1183
1184 res = libusb_control_transfer(dev->device_handle,
1185 LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_OUT,
1186 0x09/*HID set_report*/,
1187 (3/*HID feature*/ << 8) | report_number,
1188 dev->interface,
1189 (unsigned char *)data, length,
1190 1000/*timeout millis*/);
1191
1192 if (res < 0)
1193 return -1;
1194
1195 /* Account for the report ID */
1196 if (skipped_report_id)
1197 length++;
1198
1199 return length;
1200 }
1201
hid_get_feature_report(hid_device * dev,unsigned char * data,size_t length)1202 int HID_API_EXPORT hid_get_feature_report(hid_device *dev, unsigned char *data, size_t length)
1203 {
1204 int res = -1;
1205 int skipped_report_id = 0;
1206 int report_number = data[0];
1207
1208 if (report_number == 0x0) {
1209 /* Offset the return buffer by 1, so that the report ID
1210 will remain in byte 0. */
1211 data++;
1212 length--;
1213 skipped_report_id = 1;
1214 }
1215 res = libusb_control_transfer(dev->device_handle,
1216 LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE|LIBUSB_ENDPOINT_IN,
1217 0x01/*HID get_report*/,
1218 (3/*HID feature*/ << 8) | report_number,
1219 dev->interface,
1220 (unsigned char *)data, length,
1221 1000/*timeout millis*/);
1222
1223 if (res < 0)
1224 return -1;
1225
1226 if (skipped_report_id)
1227 res++;
1228
1229 return res;
1230 }
1231
1232
hid_close(hid_device * dev)1233 void HID_API_EXPORT hid_close(hid_device *dev)
1234 {
1235 if (!dev)
1236 return;
1237
1238 /* Cause read_thread() to stop. */
1239 dev->shutdown_thread = 1;
1240 libusb_cancel_transfer(dev->transfer);
1241
1242 /* Wait for read_thread() to end. */
1243 pthread_join(dev->thread, NULL);
1244
1245 /* Clean up the Transfer objects allocated in read_thread(). */
1246 free(dev->transfer->buffer);
1247 libusb_free_transfer(dev->transfer);
1248
1249 /* release the interface */
1250 libusb_release_interface(dev->device_handle, dev->interface);
1251
1252 /* Close the handle */
1253 libusb_close(dev->device_handle);
1254
1255 /* Clear out the queue of received reports. */
1256 pthread_mutex_lock(&dev->mutex);
1257 while (dev->input_reports) {
1258 return_data(dev, NULL, 0);
1259 }
1260 pthread_mutex_unlock(&dev->mutex);
1261
1262 free_hid_device(dev);
1263 }
1264
1265
hid_get_manufacturer_string(hid_device * dev,wchar_t * string,size_t maxlen)1266 int HID_API_EXPORT_CALL hid_get_manufacturer_string(hid_device *dev, wchar_t *string, size_t maxlen)
1267 {
1268 return hid_get_indexed_string(dev, dev->manufacturer_index, string, maxlen);
1269 }
1270
hid_get_product_string(hid_device * dev,wchar_t * string,size_t maxlen)1271 int HID_API_EXPORT_CALL hid_get_product_string(hid_device *dev, wchar_t *string, size_t maxlen)
1272 {
1273 return hid_get_indexed_string(dev, dev->product_index, string, maxlen);
1274 }
1275
hid_get_serial_number_string(hid_device * dev,wchar_t * string,size_t maxlen)1276 int HID_API_EXPORT_CALL hid_get_serial_number_string(hid_device *dev, wchar_t *string, size_t maxlen)
1277 {
1278 return hid_get_indexed_string(dev, dev->serial_index, string, maxlen);
1279 }
1280
hid_get_indexed_string(hid_device * dev,int string_index,wchar_t * string,size_t maxlen)1281 int HID_API_EXPORT_CALL hid_get_indexed_string(hid_device *dev, int string_index, wchar_t *string, size_t maxlen)
1282 {
1283 wchar_t *str;
1284
1285 str = get_usb_string(dev->device_handle, string_index);
1286 if (str) {
1287 wcsncpy(string, str, maxlen);
1288 string[maxlen-1] = L'\0';
1289 free(str);
1290 return 0;
1291 }
1292 else
1293 return -1;
1294 }
1295
1296
hid_error(hid_device * dev)1297 HID_API_EXPORT const wchar_t * HID_API_CALL hid_error(hid_device *dev)
1298 {
1299 return NULL;
1300 }
1301
1302
1303 struct lang_map_entry {
1304 const char *name;
1305 const char *string_code;
1306 uint16_t usb_code;
1307 };
1308
1309 #define LANG(name,code,usb_code) { name, code, usb_code }
1310 static struct lang_map_entry lang_map[] = {
1311 LANG("Afrikaans", "af", 0x0436),
1312 LANG("Albanian", "sq", 0x041C),
1313 LANG("Arabic - United Arab Emirates", "ar_ae", 0x3801),
1314 LANG("Arabic - Bahrain", "ar_bh", 0x3C01),
1315 LANG("Arabic - Algeria", "ar_dz", 0x1401),
1316 LANG("Arabic - Egypt", "ar_eg", 0x0C01),
1317 LANG("Arabic - Iraq", "ar_iq", 0x0801),
1318 LANG("Arabic - Jordan", "ar_jo", 0x2C01),
1319 LANG("Arabic - Kuwait", "ar_kw", 0x3401),
1320 LANG("Arabic - Lebanon", "ar_lb", 0x3001),
1321 LANG("Arabic - Libya", "ar_ly", 0x1001),
1322 LANG("Arabic - Morocco", "ar_ma", 0x1801),
1323 LANG("Arabic - Oman", "ar_om", 0x2001),
1324 LANG("Arabic - Qatar", "ar_qa", 0x4001),
1325 LANG("Arabic - Saudi Arabia", "ar_sa", 0x0401),
1326 LANG("Arabic - Syria", "ar_sy", 0x2801),
1327 LANG("Arabic - Tunisia", "ar_tn", 0x1C01),
1328 LANG("Arabic - Yemen", "ar_ye", 0x2401),
1329 LANG("Armenian", "hy", 0x042B),
1330 LANG("Azeri - Latin", "az_az", 0x042C),
1331 LANG("Azeri - Cyrillic", "az_az", 0x082C),
1332 LANG("Basque", "eu", 0x042D),
1333 LANG("Belarusian", "be", 0x0423),
1334 LANG("Bulgarian", "bg", 0x0402),
1335 LANG("Catalan", "ca", 0x0403),
1336 LANG("Chinese - China", "zh_cn", 0x0804),
1337 LANG("Chinese - Hong Kong SAR", "zh_hk", 0x0C04),
1338 LANG("Chinese - Macau SAR", "zh_mo", 0x1404),
1339 LANG("Chinese - Singapore", "zh_sg", 0x1004),
1340 LANG("Chinese - Taiwan", "zh_tw", 0x0404),
1341 LANG("Croatian", "hr", 0x041A),
1342 LANG("Czech", "cs", 0x0405),
1343 LANG("Danish", "da", 0x0406),
1344 LANG("Dutch - Netherlands", "nl_nl", 0x0413),
1345 LANG("Dutch - Belgium", "nl_be", 0x0813),
1346 LANG("English - Australia", "en_au", 0x0C09),
1347 LANG("English - Belize", "en_bz", 0x2809),
1348 LANG("English - Canada", "en_ca", 0x1009),
1349 LANG("English - Caribbean", "en_cb", 0x2409),
1350 LANG("English - Ireland", "en_ie", 0x1809),
1351 LANG("English - Jamaica", "en_jm", 0x2009),
1352 LANG("English - New Zealand", "en_nz", 0x1409),
1353 LANG("English - Phillippines", "en_ph", 0x3409),
1354 LANG("English - Southern Africa", "en_za", 0x1C09),
1355 LANG("English - Trinidad", "en_tt", 0x2C09),
1356 LANG("English - Great Britain", "en_gb", 0x0809),
1357 LANG("English - United States", "en_us", 0x0409),
1358 LANG("Estonian", "et", 0x0425),
1359 LANG("Farsi", "fa", 0x0429),
1360 LANG("Finnish", "fi", 0x040B),
1361 LANG("Faroese", "fo", 0x0438),
1362 LANG("French - France", "fr_fr", 0x040C),
1363 LANG("French - Belgium", "fr_be", 0x080C),
1364 LANG("French - Canada", "fr_ca", 0x0C0C),
1365 LANG("French - Luxembourg", "fr_lu", 0x140C),
1366 LANG("French - Switzerland", "fr_ch", 0x100C),
1367 LANG("Gaelic - Ireland", "gd_ie", 0x083C),
1368 LANG("Gaelic - Scotland", "gd", 0x043C),
1369 LANG("German - Germany", "de_de", 0x0407),
1370 LANG("German - Austria", "de_at", 0x0C07),
1371 LANG("German - Liechtenstein", "de_li", 0x1407),
1372 LANG("German - Luxembourg", "de_lu", 0x1007),
1373 LANG("German - Switzerland", "de_ch", 0x0807),
1374 LANG("Greek", "el", 0x0408),
1375 LANG("Hebrew", "he", 0x040D),
1376 LANG("Hindi", "hi", 0x0439),
1377 LANG("Hungarian", "hu", 0x040E),
1378 LANG("Icelandic", "is", 0x040F),
1379 LANG("Indonesian", "id", 0x0421),
1380 LANG("Italian - Italy", "it_it", 0x0410),
1381 LANG("Italian - Switzerland", "it_ch", 0x0810),
1382 LANG("Japanese", "ja", 0x0411),
1383 LANG("Korean", "ko", 0x0412),
1384 LANG("Latvian", "lv", 0x0426),
1385 LANG("Lithuanian", "lt", 0x0427),
1386 LANG("F.Y.R.O. Macedonia", "mk", 0x042F),
1387 LANG("Malay - Malaysia", "ms_my", 0x043E),
1388 LANG("Malay – Brunei", "ms_bn", 0x083E),
1389 LANG("Maltese", "mt", 0x043A),
1390 LANG("Marathi", "mr", 0x044E),
1391 LANG("Norwegian - Bokml", "no_no", 0x0414),
1392 LANG("Norwegian - Nynorsk", "no_no", 0x0814),
1393 LANG("Polish", "pl", 0x0415),
1394 LANG("Portuguese - Portugal", "pt_pt", 0x0816),
1395 LANG("Portuguese - Brazil", "pt_br", 0x0416),
1396 LANG("Raeto-Romance", "rm", 0x0417),
1397 LANG("Romanian - Romania", "ro", 0x0418),
1398 LANG("Romanian - Republic of Moldova", "ro_mo", 0x0818),
1399 LANG("Russian", "ru", 0x0419),
1400 LANG("Russian - Republic of Moldova", "ru_mo", 0x0819),
1401 LANG("Sanskrit", "sa", 0x044F),
1402 LANG("Serbian - Cyrillic", "sr_sp", 0x0C1A),
1403 LANG("Serbian - Latin", "sr_sp", 0x081A),
1404 LANG("Setsuana", "tn", 0x0432),
1405 LANG("Slovenian", "sl", 0x0424),
1406 LANG("Slovak", "sk", 0x041B),
1407 LANG("Sorbian", "sb", 0x042E),
1408 LANG("Spanish - Spain (Traditional)", "es_es", 0x040A),
1409 LANG("Spanish - Argentina", "es_ar", 0x2C0A),
1410 LANG("Spanish - Bolivia", "es_bo", 0x400A),
1411 LANG("Spanish - Chile", "es_cl", 0x340A),
1412 LANG("Spanish - Colombia", "es_co", 0x240A),
1413 LANG("Spanish - Costa Rica", "es_cr", 0x140A),
1414 LANG("Spanish - Dominican Republic", "es_do", 0x1C0A),
1415 LANG("Spanish - Ecuador", "es_ec", 0x300A),
1416 LANG("Spanish - Guatemala", "es_gt", 0x100A),
1417 LANG("Spanish - Honduras", "es_hn", 0x480A),
1418 LANG("Spanish - Mexico", "es_mx", 0x080A),
1419 LANG("Spanish - Nicaragua", "es_ni", 0x4C0A),
1420 LANG("Spanish - Panama", "es_pa", 0x180A),
1421 LANG("Spanish - Peru", "es_pe", 0x280A),
1422 LANG("Spanish - Puerto Rico", "es_pr", 0x500A),
1423 LANG("Spanish - Paraguay", "es_py", 0x3C0A),
1424 LANG("Spanish - El Salvador", "es_sv", 0x440A),
1425 LANG("Spanish - Uruguay", "es_uy", 0x380A),
1426 LANG("Spanish - Venezuela", "es_ve", 0x200A),
1427 LANG("Southern Sotho", "st", 0x0430),
1428 LANG("Swahili", "sw", 0x0441),
1429 LANG("Swedish - Sweden", "sv_se", 0x041D),
1430 LANG("Swedish - Finland", "sv_fi", 0x081D),
1431 LANG("Tamil", "ta", 0x0449),
1432 LANG("Tatar", "tt", 0X0444),
1433 LANG("Thai", "th", 0x041E),
1434 LANG("Turkish", "tr", 0x041F),
1435 LANG("Tsonga", "ts", 0x0431),
1436 LANG("Ukrainian", "uk", 0x0422),
1437 LANG("Urdu", "ur", 0x0420),
1438 LANG("Uzbek - Cyrillic", "uz_uz", 0x0843),
1439 LANG("Uzbek – Latin", "uz_uz", 0x0443),
1440 LANG("Vietnamese", "vi", 0x042A),
1441 LANG("Xhosa", "xh", 0x0434),
1442 LANG("Yiddish", "yi", 0x043D),
1443 LANG("Zulu", "zu", 0x0435),
1444 LANG(NULL, NULL, 0x0),
1445 };
1446
get_usb_code_for_current_locale(void)1447 uint16_t get_usb_code_for_current_locale(void)
1448 {
1449 char *locale;
1450 char search_string[64];
1451 char *ptr;
1452 struct lang_map_entry *lang;
1453
1454 /* Get the current locale. */
1455 locale = setlocale(0, NULL);
1456 if (!locale)
1457 return 0x0;
1458
1459 /* Make a copy of the current locale string. */
1460 strncpy(search_string, locale, sizeof(search_string));
1461 search_string[sizeof(search_string)-1] = '\0';
1462
1463 /* Chop off the encoding part, and make it lower case. */
1464 ptr = search_string;
1465 while (*ptr) {
1466 *ptr = tolower(*ptr);
1467 if (*ptr == '.') {
1468 *ptr = '\0';
1469 break;
1470 }
1471 ptr++;
1472 }
1473
1474 /* Find the entry which matches the string code of our locale. */
1475 lang = lang_map;
1476 while (lang->string_code) {
1477 if (!strcmp(lang->string_code, search_string)) {
1478 return lang->usb_code;
1479 }
1480 lang++;
1481 }
1482
1483 /* There was no match. Find with just the language only. */
1484 /* Chop off the variant. Chop it off at the '_'. */
1485 ptr = search_string;
1486 while (*ptr) {
1487 *ptr = tolower(*ptr);
1488 if (*ptr == '_') {
1489 *ptr = '\0';
1490 break;
1491 }
1492 ptr++;
1493 }
1494
1495 #if 0 /* TODO: Do we need this? */
1496 /* Find the entry which matches the string code of our language. */
1497 lang = lang_map;
1498 while (lang->string_code) {
1499 if (!strcmp(lang->string_code, search_string)) {
1500 return lang->usb_code;
1501 }
1502 lang++;
1503 }
1504 #endif
1505
1506 /* Found nothing. */
1507 return 0x0;
1508 }
1509
1510 #ifdef __cplusplus
1511 }
1512 #endif
1513