From 2d9ada743b79cee2ef8d466001592e18c53145f7 Mon Sep 17 00:00:00 2001 From: Emmanuel Dreyfus Date: Tue, 11 Dec 2018 03:47:03 +0100 Subject: [PATCH] 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 91d3ff9cc4d3b59573c2301e0dc4c8f034ba13f2), but if calling process gets ETIMEDOUT, it can select_application, authenticate and format_picc again, with some success. --- libfreefare/mifare_desfire.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/libfreefare/mifare_desfire.c b/libfreefare/mifare_desfire.c index d6c19b4..d2c06a2 100644 --- a/libfreefare/mifare_desfire.c +++ b/libfreefare/mifare_desfire.c @@ -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; \ DEBUG_XFER (__msg, __len, "===> "); \ int _res; \ - if ((_res = nfc_initiator_transceive_bytes (tag->device, __msg, __len, __res, __##res##_size + 1, 0)) < 0) { \ - return errno = EIO, -1; \ + if ((_res = nfc_initiator_transceive_bytes (tag->device, __msg, __len, __res, __##res##_size + 1, 500)) < 0) { \ + return errno = (errno == ETIMEDOUT) ? errno : EIO, -1; \ } \ __##res##_n = _res; \ DEBUG_XFER (__res, __##res##_n, "<=== "); \ @@ -306,8 +306,8 @@ mifare_desfire_connect(FreefareTag tag) uint8_t AID[] = { 0xd2, 0x76, 0x00, 0x00, 0x85, 0x01, 0x00}; BUFFER_APPEND(cmd, 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)) { - errno = EIO; + if ((nfc_initiator_transceive_bytes(tag->device, cmd, BUFFER_SIZE(cmd), res, BUFFER_MAXSIZE(cmd), 500) < 0) || (res[0] != 0x90 || res[1] != 0x00)) { + errno = (errno == ETIMEDOUT) ? errno : EIO; return -1; } tag->active = 1;