From 05c858bf96028508037afdabf53303f7d2571d62 Mon Sep 17 00:00:00 2001 From: Jef Driesen Date: Tue, 11 Jul 2017 00:15:39 +0200 Subject: [PATCH] Fix compatibility issue with hidapi The hidapi library requires that the first byte contains the report ID. For devices which support only a single report, the report ID byte should be zero. The remaining bytes contain the actual report data. Now, when hidapi uses libusb internally, it strips the zero report ID byte again before passing the data to libusb. Thus in order to remain compatible with the hidapi based implementation, our libusb based implementation should do the same. --- src/usbhid.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/usbhid.c b/src/usbhid.c index 0a93824..b99cf21 100644 --- a/src/usbhid.c +++ b/src/usbhid.c @@ -391,14 +391,32 @@ dc_usbhid_write (dc_usbhid_t *usbhid, const void *data, size_t size, size_t *act goto out_invalidargs; } + if (size == 0) { + goto out; + } + #if defined(HAVE_LIBUSB) && !defined(__APPLE__) - int rc = libusb_interrupt_transfer (usbhid->handle, usbhid->endpoint_out, (void *) data, size, &nbytes, 0); + const unsigned char *buffer = (const unsigned char *) data; + size_t length = size; + + // Skip a report id of zero. + unsigned char report = buffer[0]; + if (report == 0) { + buffer++; + length--; + } + + int rc = libusb_interrupt_transfer (usbhid->handle, usbhid->endpoint_out, (void *) buffer, length, &nbytes, 0); if (rc != LIBUSB_SUCCESS) { ERROR (usbhid->context, "Usb write interrupt transfer failed (%s).", libusb_error_name (rc)); status = syserror (rc); goto out; } + + if (report == 0) { + nbytes++; + } #elif defined(HAVE_HIDAPI) nbytes = hid_write(usbhid->handle, data, size); if (nbytes < 0) {