Implementation of configurable timeout (#101)

Previously, no timeout or an arbitrary timeout (500ms) was used. This
usually works but causes some issues when operations take longer: for
example, during `mifare_desfire_format_picc`.

This changes increases the previous default timeout to two seconds and
adds a new function that allows setting custom timeouts.
This commit is contained in:
broth-itk 2019-10-30 00:01:40 +01:00 committed by Robert Quattlebaum
parent d13eca5d3c
commit 7f695cfbec
6 changed files with 29 additions and 2 deletions

View file

@ -52,6 +52,7 @@ linkedman = \
freefare.3 freefare_get_tag_type.3 \ freefare.3 freefare_get_tag_type.3 \
freefare.3 freefare_get_tag_uid.3 \ freefare.3 freefare_get_tag_uid.3 \
freefare.3 freefare_get_tags.3 \ freefare.3 freefare_get_tags.3 \
freefare.3 freefare_set_tag_timeout.3 \
freefare.3 freefare_version.3 \ freefare.3 freefare_version.3 \
freefare_error.3 freefare_perror.3 \ freefare_error.3 freefare_perror.3 \
freefare_error.3 freefare_strerror.3 \ freefare_error.3 freefare_strerror.3 \

View file

@ -27,6 +27,7 @@
.Nm freefare_get_tag_type , .Nm freefare_get_tag_type ,
.Nm freefare_get_tag_friendly_name , .Nm freefare_get_tag_friendly_name ,
.Nm freefare_get_tag_uid , .Nm freefare_get_tag_uid ,
.Nm freefare_set_tag_timeout ,
.Nm freefare_free_tag , .Nm freefare_free_tag ,
.Nm freefare_free_tags , .Nm freefare_free_tags ,
.Nm freefare_version .Nm freefare_version
@ -67,6 +68,8 @@ enum freefare_tag_type {
.Ft "char *" .Ft "char *"
.Fn freefare_get_tag_uid "FreefareTag tag" .Fn freefare_get_tag_uid "FreefareTag tag"
.Ft "void" .Ft "void"
.Fn freefare_set_tag_timeout "FreefareTag tag" "int timeout"
.Ft "void"
.Fn freefare_free_tag "FreefareTag tags" .Fn freefare_free_tag "FreefareTag tags"
.Ft "void" .Ft "void"
.Fn freefare_free_tags "FreefareTag *tags" .Fn freefare_free_tags "FreefareTag *tags"
@ -122,6 +125,12 @@ and
functions. functions.
.Pp .Pp
The 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 .Fn freefare_version
function returns the version of the library. function returns the version of the library.
.\" ____ _ _ .\" ____ _ _

View file

@ -39,6 +39,10 @@ freefare_tag_new(nfc_device *device, nfc_target target)
tag = mifare_ultralight_tag_new(device, target); tag = mifare_ultralight_tag_new(device, target);
} }
// Set default timeout
if (tag)
tag->timeout = MIFARE_DEFAULT_TIMEOUT;
return tag; 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); 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. * Free the provided tag.
*/ */

View file

@ -49,6 +49,7 @@ char *freefare_get_tag_uid(FreefareTag tag);
void freefare_free_tag(FreefareTag tag); void freefare_free_tag(FreefareTag tag);
void freefare_free_tags(FreefareTag *tags); void freefare_free_tags(FreefareTag *tags);
bool freefare_selected_tag_is_present(nfc_device *device); bool freefare_selected_tag_is_present(nfc_device *device);
void freefare_set_tag_timeout(FreefareTag tag, int timeout);
const char *freefare_version(void); const char *freefare_version(void);

View file

@ -142,6 +142,8 @@ void *assert_crypto_buffer_size(FreefareTag tag, size_t nbytes);
#define MIFARE_ULTRALIGHT_C_PAGE_COUNT_READ 0x2C #define MIFARE_ULTRALIGHT_C_PAGE_COUNT_READ 0x2C
// Max PAGE_COUNT of the Ultralight Family: // Max PAGE_COUNT of the Ultralight Family:
#define MIFARE_ULTRALIGHT_MAX_PAGE_COUNT 0x30 #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 * This structure is common to all supported MIFARE targets but shall not be
@ -156,6 +158,7 @@ struct freefare_tag {
nfc_target info; nfc_target info;
int type; int type;
int active; int active;
int timeout;
void (*free_tag)(FreefareTag tag); void (*free_tag)(FreefareTag tag);
}; };

View file

@ -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; \ 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, 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; \ return errno = (errno == ETIMEDOUT) ? errno : EIO, -1; \
} \ } \
__##res##_n = _res; \ __##res##_n = _res; \
@ -306,7 +306,7 @@ 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), 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; errno = (errno == ETIMEDOUT) ? errno : EIO;
return -1; return -1;
} }