Instrument Neutral Distributed Interface INDI 2.2.5
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 "indi_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
54extern "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#if !defined(__FreeBSD__) && !defined(__OpenBSD__)
69#define DETACH_KERNEL_DRIVER
70#endif
71
72/* Uncomment to enable the retrieval of Usage and Usage Page in
73hid_enumerate(). Warning, on platforms different from FreeBSD
74this is very invasive as it requires the detach
75and re-attach of the kernel driver. See comments inside hid_enumerate().
76libusb HIDAPI programs are encouraged to use the interface number
77instead 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;
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
126static libusb_context *usb_context = NULL;
127
129static int return_data(hid_device *dev, unsigned char *data, size_t length);
130
131static 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
143static 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 function on hidapi/libusb..
156static 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. */
165static 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. */
194static 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. */
272static 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
287static 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(). */
314static 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
372err:
373 iconv_close(ic);
374
375 return str;
376}
377
378static 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
418struct 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
612hid_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
648
649 return handle;
650}
651
652static 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
724static 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 actually 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 input 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
929int 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 interrupt 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. */
977static 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
991static void cleanup_mutex(void *param)
992{
993 hid_device *dev = param;
994 pthread_mutex_unlock(&dev->mutex);
995}
996
997int 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
1088ret:
1089 pthread_mutex_unlock(&dev->mutex);
1090 pthread_cleanup_pop(0);
1091
1092 return bytes_read;
1093}
1094
1095int 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
1107int 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
1135int 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
1196int 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
1201int 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
1206int 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
1211int 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 }
1244static 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 * device
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
int HID_API_EXPORT hid_read(hid_device *dev, unsigned char *data, size_t length)
Read an Input report from a HID device.
int HID_API_EXPORT hid_init(void)
Initialize the HIDAPI library.
Definition hid_libusb.c:388
void HID_API_EXPORT hid_free_enumeration(struct hid_device_info *devs)
Free an enumeration Linked List.
Definition hid_libusb.c:597
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.
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
uint16_t get_usb_code_for_current_locale(void)
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
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.
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.
#define LOG(...)
Definition hid_libusb.c:60
hid_device *HID_API_EXPORT hid_open_path(const char *path)
Open a HID device by its path name.
Definition hid_libusb.c:790
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.
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.
void HID_API_EXPORT hid_close(hid_device *dev)
Close a HID device.
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
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.
HID_API_EXPORT const wchar_t *HID_API_CALL hid_error(hid_device *dev)
Get a string describing the last error which occurred.
int HID_API_EXPORT hid_set_nonblocking(hid_device *dev, int nonblock)
Set the device handle to be non-blocking.
int HID_API_EXPORT hid_exit(void)
Finalize the HIDAPI library.
Definition hid_libusb.c:407
#define LANG(name, code, usb_code)
#define HID_API_EXPORT_CALL
Definition indi_hidapi.h:46
#define HID_API_EXPORT
Definition indi_hidapi.h:42
#define HID_API_CALL
Definition indi_hidapi.h:43
void usage(void)
const char *LIBUSB_CALL libusb_error_name(int errcode)
#define INDI_LOCALE(s)
char locale_char_t
pthread_barrier_t barrier
Definition hid_libusb.c:118
libusb_device_handle * device_handle
Definition hid_libusb.c:96
int input_ep_max_packet_size
Definition hid_libusb.c:101
int input_endpoint
Definition hid_libusb.c:99
struct input_report * input_reports
Definition hid_libusb.c:123
int product_index
Definition hid_libusb.c:108
int shutdown_thread
Definition hid_libusb.c:119
pthread_mutex_t mutex
Definition hid_libusb.c:116
int output_endpoint
Definition hid_libusb.c:100
int manufacturer_index
Definition hid_libusb.c:107
struct libusb_transfer * transfer
Definition hid_libusb.c:120
pthread_cond_t condition
Definition hid_libusb.c:117
pthread_t thread
Definition hid_libusb.c:115
unsigned short product_id
Definition indi_hidapi.h:62
struct hid_device_info * next
Definition indi_hidapi.h:85
unsigned short usage
Definition indi_hidapi.h:77
wchar_t * manufacturer_string
Definition indi_hidapi.h:69
unsigned short vendor_id
Definition indi_hidapi.h:60
unsigned short release_number
Definition indi_hidapi.h:67
wchar_t * serial_number
Definition indi_hidapi.h:64
unsigned short usage_page
Definition indi_hidapi.h:74
wchar_t * product_string
Definition indi_hidapi.h:71
uint8_t * data
Definition hid_libusb.c:88
struct input_report * next
Definition hid_libusb.c:90
uint16_t usb_code
const char * name
const char * string_code