Receive only a single USB packet at a time
The hidapi based implementation returns as soon as the first packet is received, while the libusb based implementation tries to read the requested number of bytes. That fails with a timeout if the requested number of bytes is larger than the size of a single packet and no further packets are received. Avoid this problem by limiting the size to the maximum packet size.
This commit is contained in:
parent
8a6abab1da
commit
bf93040ab1
@ -86,6 +86,7 @@ struct dc_usbhid_device_t {
|
|||||||
int interface;
|
int interface;
|
||||||
unsigned char endpoint_in;
|
unsigned char endpoint_in;
|
||||||
unsigned char endpoint_out;
|
unsigned char endpoint_out;
|
||||||
|
unsigned short packetsize;
|
||||||
#elif defined(USE_HIDAPI)
|
#elif defined(USE_HIDAPI)
|
||||||
char *path;
|
char *path;
|
||||||
#endif
|
#endif
|
||||||
@ -125,6 +126,7 @@ typedef struct dc_usbhid_t {
|
|||||||
int interface;
|
int interface;
|
||||||
unsigned char endpoint_in;
|
unsigned char endpoint_in;
|
||||||
unsigned char endpoint_out;
|
unsigned char endpoint_out;
|
||||||
|
unsigned short packetsize;
|
||||||
unsigned int timeout;
|
unsigned int timeout;
|
||||||
#elif defined(USE_HIDAPI)
|
#elif defined(USE_HIDAPI)
|
||||||
hid_device *handle;
|
hid_device *handle;
|
||||||
@ -507,6 +509,7 @@ dc_usbhid_iterator_next (dc_iterator_t *abstract, void *out)
|
|||||||
device->interface = interface->bInterfaceNumber;
|
device->interface = interface->bInterfaceNumber;
|
||||||
device->endpoint_in = ep_in->bEndpointAddress;
|
device->endpoint_in = ep_in->bEndpointAddress;
|
||||||
device->endpoint_out = ep_out->bEndpointAddress;
|
device->endpoint_out = ep_out->bEndpointAddress;
|
||||||
|
device->packetsize = ep_in->wMaxPacketSize;
|
||||||
|
|
||||||
*(dc_usbhid_device_t **) out = device;
|
*(dc_usbhid_device_t **) out = device;
|
||||||
|
|
||||||
@ -614,6 +617,7 @@ dc_usbhid_open (dc_iostream_t **out, dc_context_t *context, dc_usbhid_device_t *
|
|||||||
usbhid->interface = device->interface;
|
usbhid->interface = device->interface;
|
||||||
usbhid->endpoint_in = device->endpoint_in;
|
usbhid->endpoint_in = device->endpoint_in;
|
||||||
usbhid->endpoint_out = device->endpoint_out;
|
usbhid->endpoint_out = device->endpoint_out;
|
||||||
|
usbhid->packetsize = device->packetsize;
|
||||||
usbhid->timeout = 0;
|
usbhid->timeout = 0;
|
||||||
|
|
||||||
#elif defined(USE_HIDAPI)
|
#elif defined(USE_HIDAPI)
|
||||||
@ -704,6 +708,10 @@ dc_usbhid_read (dc_iostream_t *abstract, void *data, size_t size, size_t *actual
|
|||||||
int nbytes = 0;
|
int nbytes = 0;
|
||||||
|
|
||||||
#if defined(USE_LIBUSB)
|
#if defined(USE_LIBUSB)
|
||||||
|
if (size > usbhid->packetsize) {
|
||||||
|
size = usbhid->packetsize;
|
||||||
|
}
|
||||||
|
|
||||||
int rc = libusb_interrupt_transfer (usbhid->handle, usbhid->endpoint_in, data, size, &nbytes, usbhid->timeout);
|
int rc = libusb_interrupt_transfer (usbhid->handle, usbhid->endpoint_in, data, size, &nbytes, usbhid->timeout);
|
||||||
if (rc != LIBUSB_SUCCESS || nbytes < 0) {
|
if (rc != LIBUSB_SUCCESS || nbytes < 0) {
|
||||||
ERROR (abstract->context, "Usb read interrupt transfer failed (%s).",
|
ERROR (abstract->context, "Usb read interrupt transfer failed (%s).",
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user