diff --git a/libfreefare/Makefile.am b/libfreefare/Makefile.am index e8663aa..9c5947a 100644 --- a/libfreefare/Makefile.am +++ b/libfreefare/Makefile.am @@ -52,6 +52,7 @@ linkedman = \ freefare.3 freefare_get_tag_type.3 \ freefare.3 freefare_get_tag_uid.3 \ freefare.3 freefare_get_tags.3 \ + freefare.3 freefare_set_tag_timeout.3 \ freefare.3 freefare_version.3 \ freefare_error.3 freefare_perror.3 \ freefare_error.3 freefare_strerror.3 \ diff --git a/libfreefare/freefare.3 b/libfreefare/freefare.3 index f3dc9ad..dd70cb3 100644 --- a/libfreefare/freefare.3 +++ b/libfreefare/freefare.3 @@ -27,6 +27,7 @@ .Nm freefare_get_tag_type , .Nm freefare_get_tag_friendly_name , .Nm freefare_get_tag_uid , +.Nm freefare_set_tag_timeout , .Nm freefare_free_tag , .Nm freefare_free_tags , .Nm freefare_version @@ -67,6 +68,8 @@ enum freefare_tag_type { .Ft "char *" .Fn freefare_get_tag_uid "FreefareTag tag" .Ft "void" +.Fn freefare_set_tag_timeout "FreefareTag tag" "int timeout" +.Ft "void" .Fn freefare_free_tag "FreefareTag tags" .Ft "void" .Fn freefare_free_tags "FreefareTag *tags" @@ -122,6 +125,12 @@ and functions. .Pp The +.Fn freefare_set_tag_timeout +function is used to set the maximum duration for a single NFC operation to +.Fa timeout +mili-seconds. Setting +.Fa timeout +to 0 disables the timeout feature. By default, a timeout of 2000 is configured. .Fn freefare_version function returns the version of the library. .\" ____ _ _ diff --git a/libfreefare/freefare.c b/libfreefare/freefare.c index 79b98ba..1f5c34e 100644 --- a/libfreefare/freefare.c +++ b/libfreefare/freefare.c @@ -39,6 +39,10 @@ freefare_tag_new(nfc_device *device, nfc_target target) tag = mifare_ultralight_tag_new(device, target); } + // Set default timeout + if (tag) + tag->timeout = MIFARE_DEFAULT_TIMEOUT; + return tag; } @@ -202,6 +206,15 @@ bool freefare_selected_tag_is_present(nfc_device *device) return (nfc_initiator_target_is_present(device, NULL) == NFC_SUCCESS); } +/* + * Set NFC operation timeout + */ +void +freefare_set_tag_timeout(FreefareTag tag, int timeout) +{ + tag->timeout = timeout; +} + /* * Free the provided tag. */ diff --git a/libfreefare/freefare.h b/libfreefare/freefare.h index 9e4e333..89f5056 100644 --- a/libfreefare/freefare.h +++ b/libfreefare/freefare.h @@ -49,6 +49,7 @@ char *freefare_get_tag_uid(FreefareTag tag); void freefare_free_tag(FreefareTag tag); void freefare_free_tags(FreefareTag *tags); bool freefare_selected_tag_is_present(nfc_device *device); +void freefare_set_tag_timeout(FreefareTag tag, int timeout); const char *freefare_version(void); diff --git a/libfreefare/freefare_internal.h b/libfreefare/freefare_internal.h index af94d50..26910ed 100644 --- a/libfreefare/freefare_internal.h +++ b/libfreefare/freefare_internal.h @@ -142,6 +142,8 @@ void *assert_crypto_buffer_size(FreefareTag tag, size_t nbytes); #define MIFARE_ULTRALIGHT_C_PAGE_COUNT_READ 0x2C // Max PAGE_COUNT of the Ultralight Family: #define MIFARE_ULTRALIGHT_MAX_PAGE_COUNT 0x30 +// Default timeout (ms) for tag operations +#define MIFARE_DEFAULT_TIMEOUT 2000 /* * This structure is common to all supported MIFARE targets but shall not be @@ -156,6 +158,7 @@ struct freefare_tag { nfc_target info; int type; int active; + int timeout; void (*free_tag)(FreefareTag tag); }; diff --git a/libfreefare/mifare_desfire.c b/libfreefare/mifare_desfire.c index d2c06a2..01c8a2b 100644 --- a/libfreefare/mifare_desfire.c +++ b/libfreefare/mifare_desfire.c @@ -168,7 +168,7 @@ 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, 500)) < 0) { \ + if ((_res = nfc_initiator_transceive_bytes (tag->device, __msg, __len, __res, __##res##_size + 1, tag->timeout)) < 0) { \ return errno = (errno == ETIMEDOUT) ? errno : EIO, -1; \ } \ __##res##_n = _res; \ @@ -306,7 +306,7 @@ 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), 500) < 0) || (res[0] != 0x90 || res[1] != 0x00)) { + if ((nfc_initiator_transceive_bytes(tag->device, cmd, BUFFER_SIZE(cmd), res, BUFFER_MAXSIZE(cmd), tag->timeout) < 0) || (res[0] != 0x90 || res[1] != 0x00)) { errno = (errno == ETIMEDOUT) ? errno : EIO; return -1; }