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