Introduce timeout on DESfire operations

There are a few reasons why an NFC operation may timeout, including
the pn533 USB toggle bit bug. In that case it helps to report the
problem to calling process so that it can retry operation, instead
of hanging forever.

For instance, mifare_desfire_format_picc() may make the chip
unresponsive (see commit 91d3ff9cc4),
but if calling process gets ETIMEDOUT, it can select_application,
authenticate and format_picc again, with some success.
This commit is contained in:
Emmanuel Dreyfus 2018-12-11 03:47:03 +01:00
parent c18f702840
commit 2d9ada743b

View file

@ -168,8 +168,8 @@ static ssize_t read_data(FreefareTag tag, uint8_t command, uint8_t file_no, off
MIFARE_DESFIRE (tag)->last_pcd_error = OPERATION_OK; \ MIFARE_DESFIRE (tag)->last_pcd_error = OPERATION_OK; \
DEBUG_XFER (__msg, __len, "===> "); \ DEBUG_XFER (__msg, __len, "===> "); \
int _res; \ int _res; \
if ((_res = nfc_initiator_transceive_bytes (tag->device, __msg, __len, __res, __##res##_size + 1, 0)) < 0) { \ if ((_res = nfc_initiator_transceive_bytes (tag->device, __msg, __len, __res, __##res##_size + 1, 500)) < 0) { \
return errno = EIO, -1; \ return errno = (errno == ETIMEDOUT) ? errno : EIO, -1; \
} \ } \
__##res##_n = _res; \ __##res##_n = _res; \
DEBUG_XFER (__res, __##res##_n, "<=== "); \ DEBUG_XFER (__res, __##res##_n, "<=== "); \
@ -306,8 +306,8 @@ mifare_desfire_connect(FreefareTag tag)
uint8_t AID[] = { 0xd2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x00}; uint8_t AID[] = { 0xd2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x00};
BUFFER_APPEND(cmd, sizeof(AID)); BUFFER_APPEND(cmd, sizeof(AID));
BUFFER_APPEND_BYTES(cmd, AID, sizeof(AID)); BUFFER_APPEND_BYTES(cmd, AID, sizeof(AID));
if ((nfc_initiator_transceive_bytes(tag->device, cmd, BUFFER_SIZE(cmd), res, BUFFER_MAXSIZE(cmd), 0) < 0) || (res[0] != 0x90 || res[1] != 0x00)) { if ((nfc_initiator_transceive_bytes(tag->device, cmd, BUFFER_SIZE(cmd), res, BUFFER_MAXSIZE(cmd), 500) < 0) || (res[0] != 0x90 || res[1] != 0x00)) {
errno = EIO; errno = (errno == ETIMEDOUT) ? errno : EIO;
return -1; return -1;
} }
tag->active = 1; tag->active = 1;