Handle a libusb timeout as a non fatal error.
Dives are downloaded using bulk transfers with an 8K buffer. Normally the 2 second timeout is more than sufficient, and the timeout should never expire, unless there is some serious communcation problem. But nevertheless, users are reporting timeouts for dives having a length that is an exact multiple of the USB packet size (64 bytes). In that case, libusb reports a timeout with an non-zero amount of bytes received. Despite the timeout, the received data contains a complete dive. I suspect libusb is somehow unable to determine whether the transfer is complete and therefore waits until the timeout expires. For transfers that are not a multiple of the USB packet size, the end of the transfer is indicated by the last incomplete packet. This is not the case if the length is an exact multiple of the USB packet size. This problem is usually solved by sending a zero-length packet. Maybe the USB stack of the Cobalt is not sending such a zero-length packet? Atomics will address the problem with a Coblat 2 firmware upgrade, that will simply append two zero bytes if the length is a multiple of 64 bytes. As a workaround for older firmware versions, we ignore the timeout and process all received data. This shouldn't have any disadvantages. An incomplete dive, for example due to a real timeout, will now be detected by means of the minimum length and/or the checksum.
This commit is contained in:
parent
00e0cfa0ab
commit
a21f60e0bc
@ -284,7 +284,7 @@ atomics_cobalt_read_dive (dc_device_t *abstract, dc_buffer_t *buffer, int init,
|
||||
unsigned char packet[8 * 1024] = {0};
|
||||
rc = libusb_bulk_transfer (device->handle, 0x82,
|
||||
packet, sizeof (packet), &length, TIMEOUT);
|
||||
if (rc != LIBUSB_SUCCESS) {
|
||||
if (rc != LIBUSB_SUCCESS && rc != LIBUSB_ERROR_TIMEOUT) {
|
||||
ERROR (abstract->context, "Failed to receive the answer.");
|
||||
return EXITCODE(rc);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user