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