CcidTransceiver: Poke device again if we get zero-sized packet.

This commit is contained in:
Stuart Longland
2023-07-23 20:34:41 +10:00
committed by Vincent Breitmoser
parent 19cd6967c0
commit fec3f85fad

View File

@@ -275,7 +275,20 @@ public class CcidTransceiver {
}
private CcidDataBlock receiveDataBlockImmediate(byte expectedSequenceNumber) throws UsbTransportException {
int readBytes = usbConnection.bulkTransfer(usbBulkIn, inputBuffer, inputBuffer.length, DEVICE_COMMUNICATE_TIMEOUT_MILLIS);
/*
* Some USB CCID devices (notably NitroKey 3) may time-out and need a subsequent poke to
* carry on communications. No particular reason why the number 3 was chosen. If we get a
* zero-sized reply (or a time-out), we try again. Clamped retries prevent an infinite loop
* if things really turn sour.
*/
int attempts = 3;
Timber.d("Receive data block immediate seq=%d", expectedSequenceNumber);
int readBytes;
do {
readBytes = usbConnection.bulkTransfer(usbBulkIn, inputBuffer, inputBuffer.length, DEVICE_COMMUNICATE_TIMEOUT_MILLIS);
Timber.d("Received " + readBytes + " bytes: " + toHexString(inputBuffer));
} while ((readBytes <= 0) && (attempts-- > 0));
if (readBytes < CCID_HEADER_LENGTH) {
throw new UsbTransportException("USB-CCID error - failed to receive CCID header");
}