From 74bc239a711fbca49ee7dacc358d98536a857f04 Mon Sep 17 00:00:00 2001 From: Romain Tartiere Date: Fri, 19 Feb 2010 14:50:18 +0000 Subject: [PATCH] Abstract tag manipulation functions. - Factorize Mifare*Tag as MifareTag; - Factorize mifare_*_get_tags() / mifare_*_free_tags() as freefare_get_tags() and freefare_free_tags(); - Add a new freefare_get_tag_type() function to get a tag type; - Update regression test suite; - Update example. While this is a major change that basically change all the API, programs using libfreefare should be easily modified by replacing any Mifare*Tag variable by a generic MifareTag one, adding a few lines of code to check the target's type using freefare_get_tag_type(), and changing any call to mifare_*_get_tags() / mifare_*_free_tags() by the generic freefare_get_tags() and freefare_free_tags() functions. --- examples/mifare-classic-format.c | 19 ++-- libfreefare/Makefile.am | 3 +- libfreefare/freefare.c | 167 ++++++++++++++++++++++++++++ libfreefare/freefare.h | 73 +++++++------ libfreefare/freefare_internal.h | 54 +++++++++- libfreefare/mad.c | 4 +- libfreefare/mifare_classic.c | 180 ++++++++----------------------- libfreefare/mifare_ultralight.c | 105 ++++-------------- test/mifare_classic_fixture.c | 21 ++-- test/mifare_classic_fixture.h | 2 +- test/mifare_ultralight_fixture.c | 20 ++-- test/mifare_ultralight_fixture.h | 2 +- test/test_mifare_ultralight.c | 10 +- 13 files changed, 378 insertions(+), 282 deletions(-) create mode 100644 libfreefare/freefare.c diff --git a/examples/mifare-classic-format.c b/examples/mifare-classic-format.c index 5e7d2ff..7d0cd58 100644 --- a/examples/mifare-classic-format.c +++ b/examples/mifare-classic-format.c @@ -40,7 +40,7 @@ MifareClassicKey default_keys[] = { }; int -try_format_sector (MifareClassicTag tag, MifareSectorNumber sector) +try_format_sector (MifareTag tag, MifareSectorNumber sector) { for (int i = 0; i < (sizeof (default_keys) / sizeof (MifareClassicKey)); i++) { printf (" s=%d i=%d \n", sector, i); @@ -73,27 +73,32 @@ main(int argc, char *argv[]) { int error = 0; nfc_device_t *device = NULL; - MifareClassicTag *tags = NULL; - MifareClassicTag *tag = NULL; + MifareTag *tags = NULL; + MifareTag *tag = NULL; device = nfc_connect (NULL); if (!device) errx (EXIT_FAILURE, "No NFC device found."); - tags = mifare_classic_get_tags (device); + tags = freefare_get_tags (device); if (!tags) { nfc_disconnect (device); errx (EXIT_FAILURE, "Error listing MIFARE classic tag."); } if (!tags[0]) { - mifare_classic_free_tags (tags); + freefare_free_tags (tags); nfc_disconnect (device); - errx (EXIT_FAILURE, "No MIFARE classic tag on NFC device."); + errx (EXIT_FAILURE, "No MIFARE tag on NFC device."); } tag = tags; + if ((freefare_get_tag_type (*tag) != CLASSIC_1K) && + (freefare_get_tag_type (*tag) != CLASSIC_4K)) { + errx (EXIT_FAILURE, "Not a MIFARE Classic tag."); + } + while (*tag) { char *tag_uid = mifare_classic_get_uid (*tag); @@ -111,7 +116,7 @@ main(int argc, char *argv[]) tag++; } - mifare_classic_free_tags (tags); + freefare_free_tags (tags); nfc_disconnect (device); exit (error); diff --git a/libfreefare/Makefile.am b/libfreefare/Makefile.am index 95d8d5c..8a7ef6e 100644 --- a/libfreefare/Makefile.am +++ b/libfreefare/Makefile.am @@ -4,7 +4,8 @@ AM_LDFLAGS = @LIBNFC_LIBS@ lib_LTLIBRARIES = libfreefare.la -libfreefare_la_SOURCES = mifare_classic.c \ +libfreefare_la_SOURCES = freefare.c \ + mifare_classic.c \ mifare_ultralight.c \ mad.c \ mifare_application.c diff --git a/libfreefare/freefare.c b/libfreefare/freefare.c new file mode 100644 index 0000000..cf5fe13 --- /dev/null +++ b/libfreefare/freefare.c @@ -0,0 +1,167 @@ +/* + * Copyright (C) 2010, Romain Tartiere, Romuald Conty. + * + * This program is free software: you can redistribute it and/or modify it + * under the terms of the GNU Lesser General Public License as published by the + * Free Software Foundation, either version 3 of the License, or (at your + * option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this program. If not, see + * + * $Id$ + */ + +#include + +#include + +#include "freefare_internal.h" + +struct supported_tag { + uint8_t ATQA[2], SAK; + enum mifare_tag_type type; +}; + +struct supported_tag supported_tags[] = { + { { 0x00, 0x44 }, 0x00, ULTRALIGHT }, + { { 0x00, 0x04 }, 0x08, CLASSIC_1K }, + { { 0x00, 0x02 }, 0x08, CLASSIC_4K }, + { { 0x00, 0x02 }, 0x38, CLASSIC_4K }, /* Emulated */ +}; + + +/* + * MIFARE card common functions + * + * The following functions send NFC commands to the initiator to prepare + * communication with a MIFARE card, and perform required cleannups after using + * the targets. + */ + +/* + * Get a list of the MIFARE targets near to the provided NFC initiator. + * + * The list has to be freed using the freefare_free_tags() function. + */ +MifareTag * +freefare_get_tags (nfc_device_t *device) +{ + MifareTag *tags = NULL; + int tag_count = 0; + + nfc_initiator_init(device); + + // Drop the field for a while + nfc_configure(device,NDO_ACTIVATE_FIELD,false); + + // Let the reader only try once to find a tag + nfc_configure(device,NDO_INFINITE_SELECT,false); + + // Configure the CRC and Parity settings + nfc_configure(device,NDO_HANDLE_CRC,true); + nfc_configure(device,NDO_HANDLE_PARITY,true); + + // Enable field so more power consuming cards can power themselves up + nfc_configure(device,NDO_ACTIVATE_FIELD,true); + + // Poll for a ISO14443A (MIFARE) tag + nfc_target_info_t target_info; + + tags = malloc(sizeof (void *)); + if(!tags) return NULL; + tags[0] = NULL; + + while (nfc_initiator_select_tag(device,NM_ISO14443A_106,NULL,0,&target_info)) { + + bool found = false; + enum mifare_tag_type type; + + for (int i = 0; i < sizeof (supported_tags) / sizeof (struct supported_tag); i++) { + if ((target_info.nai.abtAtqa[0] == supported_tags[i].ATQA[0]) && + (target_info.nai.abtAtqa[1] == supported_tags[i].ATQA[1]) && + (target_info.nai.btSak == supported_tags[i].SAK)) { + + type = supported_tags[i].type; + found = true; + break; + } + } + + if (!found) + continue; + + tag_count++; + + /* (Re)Allocate memory for the found MIFARE targets array */ + MifareTag *p = realloc (tags, (tag_count + 1) * sizeof (MifareTag)); + if (p) + tags = p; + else + return tags; // FAIL! Return what has been found so far. + + /* Allocate memory for the found MIFARE target */ + switch (type) { + case CLASSIC_1K: + case CLASSIC_4K: + tags[tag_count-1] = malloc (sizeof (struct mifare_classic_tag)); + break; + case ULTRALIGHT: + tags[tag_count-1] = malloc (sizeof (struct mifare_ultralight_tag)); + break; + } + + if (!tags[tag_count-1]) + return tags; // FAIL! Return what has been found before. + + /* + * Initialize common fields + * (Target specific fields are initialized in mifare_*_connect()) + */ + (tags[tag_count-1])->device = device; + (tags[tag_count-1])->info = target_info.nai; + (tags[tag_count-1])->active = 0; + (tags[tag_count-1])->type = type; + tags[tag_count] = NULL; + + nfc_initiator_deselect_tag (device); + } + + return tags; +} + +/* + * Returns the type of the provided tag. + */ +enum mifare_tag_type +freefare_get_tag_type (MifareTag tag) +{ + return tag->type; +} + +/* + * Free the provided tag list. + */ +void +freefare_free_tags (MifareTag *tags) +{ + if (tags) { + for (int i=0; tags[i]; i++) { + switch (tags[i]->type) { + case CLASSIC_1K: + case CLASSIC_4K: + mifare_classic_free_tag (tags[i]); + break; + case ULTRALIGHT: + mifare_ultralight_free_tag (tags[i]); + break; + } + } + free (tags); + } +} diff --git a/libfreefare/freefare.h b/libfreefare/freefare.h index 27b853d..cfce82f 100644 --- a/libfreefare/freefare.h +++ b/libfreefare/freefare.h @@ -30,23 +30,38 @@ extern "C" { #endif // __cplusplus -struct mifare_ultralight_tag; -typedef struct mifare_ultralight_tag *MifareUltralightTag; +enum mifare_tag_type { + ULTRALIGHT, +// ULTRALIGHT_C, +// MINI, + CLASSIC_1K, + CLASSIC_4K, +// PLUS_S2K, +// PLUS_S4K, +// PLUS_X2K, +// PLUS_X4K, +// DESFIRE_2K, +// DESFIRE_4K, +// DESFIRE_8K +}; + +struct mifare_tag; +typedef struct mifare_tag *MifareTag; + typedef uint8_t MifareUltralightPageNumber; typedef unsigned char MifareUltralightPage[4]; -MifareUltralightTag *mifare_ultralight_get_tags (nfc_device_t *device); -void mifare_ultralight_free_tags (MifareUltralightTag *tags); -int mifare_ultralight_connect (MifareUltralightTag tag); -int mifare_ultralight_disconnect (MifareUltralightTag tag); +MifareTag *freefare_get_tags (nfc_device_t *device); +enum mifare_tag_type freefare_get_tag_type (MifareTag tag); +void freefare_free_tags (MifareTag *tags); -int mifare_ultralight_read (MifareUltralightTag tag, const MifareUltralightPageNumber page, MifareUltralightPage *data); -int mifare_ultralight_write (MifareUltralightTag tag, const MifareUltralightPageNumber page, const MifareUltralightPage data); +int mifare_ultralight_connect (MifareTag tag); +int mifare_ultralight_disconnect (MifareTag tag); -char *mifare_ultralight_get_uid (MifareUltralightTag tag); +int mifare_ultralight_read (MifareTag tag, const MifareUltralightPageNumber page, MifareUltralightPage *data); +int mifare_ultralight_write (MifareTag tag, const MifareUltralightPageNumber page, const MifareUltralightPage data); -struct mifare_classic_tag; -typedef struct mifare_classic_tag *MifareClassicTag; +char *mifare_ultralight_get_uid (MifareTag tag); typedef unsigned char MifareClassicBlock[16]; @@ -56,27 +71,25 @@ typedef unsigned char MifareClassicBlockNumber; typedef enum { MFC_KEY_A, MFC_KEY_B } MifareClassicKeyType; typedef unsigned char MifareClassicKey[6]; -MifareClassicTag *mifare_classic_get_tags (nfc_device_t *device); -void mifare_classic_free_tags (MifareClassicTag *tags); -int mifare_classic_connect (MifareClassicTag tag); -int mifare_classic_disconnect (MifareClassicTag tag); +int mifare_classic_connect (MifareTag tag); +int mifare_classic_disconnect (MifareTag tag); -int mifare_classic_authenticate (MifareClassicTag tag, const MifareClassicBlockNumber block, const MifareClassicKey key, const MifareClassicKeyType key_type); -int mifare_classic_read (MifareClassicTag tag, const MifareClassicBlockNumber block, MifareClassicBlock *data); -int mifare_classic_init_value (MifareClassicTag tag, const MifareClassicBlockNumber block, const int32_t value, const MifareClassicBlockNumber adr); -int mifare_classic_read_value (MifareClassicTag tag, const MifareClassicBlockNumber block, int32_t *value, MifareClassicBlockNumber *adr); -int mifare_classic_write (MifareClassicTag tag, const MifareClassicBlockNumber block, const MifareClassicBlock data); +int mifare_classic_authenticate (MifareTag tag, const MifareClassicBlockNumber block, const MifareClassicKey key, const MifareClassicKeyType key_type); +int mifare_classic_read (MifareTag tag, const MifareClassicBlockNumber block, MifareClassicBlock *data); +int mifare_classic_init_value (MifareTag tag, const MifareClassicBlockNumber block, const int32_t value, const MifareClassicBlockNumber adr); +int mifare_classic_read_value (MifareTag tag, const MifareClassicBlockNumber block, int32_t *value, MifareClassicBlockNumber *adr); +int mifare_classic_write (MifareTag tag, const MifareClassicBlockNumber block, const MifareClassicBlock data); -int mifare_classic_increment (MifareClassicTag tag, const MifareClassicBlockNumber block, const uint32_t amount); -int mifare_classic_decrement (MifareClassicTag tag, const MifareClassicBlockNumber block, const uint32_t amount); -int mifare_classic_restore (MifareClassicTag tag, const MifareClassicBlockNumber block); -int mifare_classic_transfer (MifareClassicTag tag, const MifareClassicBlockNumber block); +int mifare_classic_increment (MifareTag tag, const MifareClassicBlockNumber block, const uint32_t amount); +int mifare_classic_decrement (MifareTag tag, const MifareClassicBlockNumber block, const uint32_t amount); +int mifare_classic_restore (MifareTag tag, const MifareClassicBlockNumber block); +int mifare_classic_transfer (MifareTag tag, const MifareClassicBlockNumber block); -int mifare_classic_get_trailer_block_permission (MifareClassicTag tag, const MifareClassicBlockNumber block, const uint16_t permission, const MifareClassicKeyType key_type); -int mifare_classic_get_data_block_permission (MifareClassicTag tag, const MifareClassicBlockNumber block, const unsigned char permission, const MifareClassicKeyType key_type); +int mifare_classic_get_trailer_block_permission (MifareTag tag, const MifareClassicBlockNumber block, const uint16_t permission, const MifareClassicKeyType key_type); +int mifare_classic_get_data_block_permission (MifareTag tag, const MifareClassicBlockNumber block, const unsigned char permission, const MifareClassicKeyType key_type); -int mifare_classic_format_sector (MifareClassicTag tag, const MifareSectorNumber sector); -char* mifare_classic_get_uid(MifareClassicTag tag); +int mifare_classic_format_sector (MifareTag tag, const MifareSectorNumber sector); +char* mifare_classic_get_uid(MifareTag tag); void mifare_classic_trailer_block (MifareClassicBlock *block, const MifareClassicKey key_a, const uint8_t ab_0, const uint8_t ab_1, const uint8_t ab_2, const uint8_t ab_tb, const uint8_t gpb, const MifareClassicKey key_b); @@ -103,8 +116,8 @@ struct mad; typedef struct mad *Mad; Mad mad_new (uint8_t version); -Mad mad_read (MifareClassicTag tag); -int mad_write (MifareClassicTag tag, Mad mad, MifareClassicKey key_b_sector_00, MifareClassicKey key_b_sector_10); +Mad mad_read (MifareTag tag); +int mad_write (MifareTag tag, Mad mad, MifareClassicKey key_b_sector_00, MifareClassicKey key_b_sector_10); int mad_get_version (Mad mad); void mad_set_version (Mad mad, uint8_t version); MifareSectorNumber mad_get_card_publisher_sector(Mad mad); diff --git a/libfreefare/freefare_internal.h b/libfreefare/freefare_internal.h index 0b87cd8..c195a27 100644 --- a/libfreefare/freefare_internal.h +++ b/libfreefare/freefare_internal.h @@ -24,22 +24,72 @@ struct mad_sector_0x00; struct mad_sector_0x10; void crc8 (uint8_t *crc, const uint8_t value); +void mifare_classic_free_tag (MifareTag tag); +void mifare_ultralight_free_tag (MifareTag tag); uint8_t sector_0x00_crc8 (Mad mad); uint8_t sector_0x10_crc8 (Mad mad); #define MIFARE_ULTRALIGHT_PAGE_COUNT 16 -struct mifare_ultralight_tag { +/* + * This structure is common to all supported MIFARE targets but shall not be + * used directly (it's some kind of abstract class). All members in this + * structure are initialized by freefare_get_tags(). + * + * Extra members in derived classes are initialized in the correpsonding + * mifare_*_connect() function. + */ +struct mifare_tag { nfc_device_t *device; nfc_iso14443a_info_t info; + enum mifare_tag_type type; int active; +}; + +struct mifare_classic_tag { + struct mifare_tag __tag; + + MifareClassicKeyType last_authentication_key_type; + + /* + * The following block numbers are on 2 bytes in order to use invalid + * address and avoid false cache hit with inconsistent data. + */ + struct { + int16_t sector_trailer_block_number; + uint16_t sector_access_bits; + int16_t block_number; + uint8_t block_access_bits; + } cached_access_bits; +}; + +struct mifare_ultralight_tag { + struct mifare_tag __tag; /* mifare_ultralight_read() reads 4 pages at a time (wrapping) */ MifareUltralightPage cache[MIFARE_ULTRALIGHT_PAGE_COUNT + 3]; uint8_t cached_pages[MIFARE_ULTRALIGHT_PAGE_COUNT]; }; +/* + * MifareTag assertion macros + * + * This macros provide a simple and unified way to perform various tests at the + * beginning of the different targets functions. + */ #define ASSERT_ACTIVE(tag) do { if (!tag->active) return errno = ENXIO, -1; } while (0) -#define ASSERT_INACTIVE(tag) do { if (tag->active) return errno = ENXIO, -1; } while (0) +#define ASSERT_INACTIVE(tag) do { if (tag->active) return errno = ENXIO, -1; } while (0) + +#define ASSERT_MIFARE_ULTRALIGHT(tag) do { if (tag->type != ULTRALIGHT) return errno = ENODEV, -1; } while (0) +#define ASSERT_MIFARE_CLASSIC(tag) do { if (tag->type != CLASSIC_1K) return errno = ENODEV, -1; } while (0) + +/* + * MifareTag cast macros + * + * This macros are intended to provide a convenient way to cast abstract + * MifareTag structures to concrete Tags (e.g. MIFARE Classic tag). + */ +#define MIFARE_CLASSIC(tag) ((struct mifare_classic_tag *) tag) +#define MIFARE_ULTRALIGHT(tag) ((struct mifare_ultralight_tag *) tag) #endif /* !__FREEFARE_INTERNAL_H__ */ diff --git a/libfreefare/mad.c b/libfreefare/mad.c index 8bb989b..ddbcd89 100644 --- a/libfreefare/mad.c +++ b/libfreefare/mad.c @@ -147,7 +147,7 @@ sector_0x10_crc8 (Mad mad) * Read a MAD from the provided MIFARE tag. */ Mad -mad_read (MifareClassicTag tag) +mad_read (MifareTag tag) { Mad mad = malloc (sizeof (*mad)); @@ -246,7 +246,7 @@ error: * Write the mad to the provided MIFARE tad using the provided Key-B keys. */ int -mad_write (MifareClassicTag tag, Mad mad, MifareClassicKey key_b_sector_00, MifareClassicKey key_b_sector_10) +mad_write (MifareTag tag, Mad mad, MifareClassicKey key_b_sector_00, MifareClassicKey key_b_sector_10) { MifareClassicBlock data; diff --git a/libfreefare/mifare_classic.c b/libfreefare/mifare_classic.c index 8bbdc6d..56fa0f8 100644 --- a/libfreefare/mifare_classic.c +++ b/libfreefare/mifare_classic.c @@ -48,25 +48,6 @@ #include #include "freefare_internal.h" -struct mifare_classic_tag { - nfc_device_t *device; - nfc_iso14443a_info_t info; - int active; - - MifareClassicKeyType last_authentication_key_type; - - /* - * The following block numbers are on 2 bytes in order to use invalid - * address and avoid false cache hit with inconsistent data. - */ - struct { - int16_t sector_trailer_block_number; - uint16_t sector_access_bits; - int16_t block_number; - uint8_t block_access_bits; - } cached_access_bits; -}; - union mifare_classic_block { unsigned char data[16]; struct { @@ -146,7 +127,7 @@ uint16_t mifare_trailer_access_permissions[] = { * Private functions */ -int get_block_access_bits (MifareClassicTag tag, const MifareClassicBlockNumber block, MifareClassicAccessBits *block_access_bits); +int get_block_access_bits (MifareTag tag, const MifareClassicBlockNumber block, MifareClassicAccessBits *block_access_bits); /* @@ -157,98 +138,23 @@ int get_block_access_bits (MifareClassicTag tag, const MifareClassicBlockNumber * the target. */ -/* - * Get a list of the MIFARE card near to the provided NFC initiator. - * - * The list can be freed using the mifare_classic_free_tags() function. - */ -MifareClassicTag * -mifare_classic_get_tags (nfc_device_t *device) -{ - MifareClassicTag *tags = NULL; - int tag_count = 0; - - nfc_initiator_init(device); - - // Drop the field for a while - nfc_configure(device,NDO_ACTIVATE_FIELD,false); - - // Let the reader only try once to find a tag - nfc_configure(device,NDO_INFINITE_SELECT,false); - - // Configure the CRC and Parity settings - nfc_configure(device,NDO_HANDLE_CRC,true); - nfc_configure(device,NDO_HANDLE_PARITY,true); - - // Enable field so more power consuming cards can power themselves up - nfc_configure(device,NDO_ACTIVATE_FIELD,true); - - // Poll for a ISO14443A (MIFARE) tag - nfc_target_info_t target_info; - - tags = malloc(sizeof (void *)); - if(!tags) return NULL; - tags[0] = NULL; - - while (nfc_initiator_select_tag(device,NM_ISO14443A_106,NULL,0,&target_info)) { - - // Ensure the target is a MIFARE classic tag. - if (!((target_info.nai.abtAtqa[0] == 0x00) && - (target_info.nai.abtAtqa[1] == 0x04) && - (target_info.nai.btSak == 0x08)) && /* NXP MIFARE Classic 1K */ - !((target_info.nai.abtAtqa[0] == 0x00) && - (target_info.nai.abtAtqa[1] == 0x02) && - (target_info.nai.btSak == 0x18)) && /* NXP MIFARE Classic 4K */ - !((target_info.nai.abtAtqa[0] == 0x00) && - (target_info.nai.abtAtqa[1] == 0x02) && - (target_info.nai.btSak == 0x38))) /* Nokia MIFARE Classic 4K - emulated */ - continue; - - tag_count++; - - /* (Re)Allocate memory for the found MIFARE classic array */ - MifareClassicTag *p = realloc (tags, (tag_count) * sizeof (MifareClassicTag) + sizeof (void *)); - if (p) - tags = p; - else - return tags; // FAIL! Return what has been found so far. - - /* Allocate memory for the found MIFARE classic tag */ - if (!(tags[tag_count-1] = malloc (sizeof (struct mifare_classic_tag)))) { - return tags; // FAIL! Return what has been found before. - } - (tags[tag_count-1])->device = device; - (tags[tag_count-1])->info = target_info.nai; - (tags[tag_count-1])->active = 0; - tags[tag_count] = NULL; - - nfc_initiator_deselect_tag (device); - } - - return tags; -} - /* * Free the provided tag list. */ void -mifare_classic_free_tags (MifareClassicTag *tags) +mifare_classic_free_tag (MifareTag tag) { - if (tags) { - for (int i=0; tags[i]; i++) { - free (tags[i]); - } - free (tags); - } + free (tag); } /* * Establish connection to the provided tag. */ int -mifare_classic_connect (MifareClassicTag tag) +mifare_classic_connect (MifareTag tag) { ASSERT_INACTIVE (tag); + ASSERT_MIFARE_CLASSIC (tag); nfc_target_info_t pnti; if (nfc_initiator_select_tag (tag->device, NM_ISO14443A_106, tag->info.abtUid, 4, &pnti)) { @@ -264,9 +170,10 @@ mifare_classic_connect (MifareClassicTag tag) * Terminate connection with the provided tag. */ int -mifare_classic_disconnect (MifareClassicTag tag) +mifare_classic_disconnect (MifareTag tag) { ASSERT_ACTIVE (tag); + ASSERT_MIFARE_CLASSIC (tag); if (nfc_initiator_deselect_tag (tag->device)) { tag->active = 0; @@ -289,9 +196,10 @@ mifare_classic_disconnect (MifareClassicTag tag) * Send an authentification command to the provided MIFARE target. */ int -mifare_classic_authenticate (MifareClassicTag tag, const MifareClassicBlockNumber block, const MifareClassicKey key, const MifareClassicKeyType key_type) +mifare_classic_authenticate (MifareTag tag, const MifareClassicBlockNumber block, const MifareClassicKey key, const MifareClassicKeyType key_type) { ASSERT_ACTIVE (tag); + ASSERT_MIFARE_CLASSIC (tag); unsigned char command[12]; command[0] = (key_type == MFC_KEY_A) ? MC_AUTH_A : MC_AUTH_B; @@ -307,9 +215,9 @@ mifare_classic_authenticate (MifareClassicTag tag, const MifareClassicBlockNumbe return -1; } - tag->cached_access_bits.sector_trailer_block_number = -1; - tag->cached_access_bits.sector_access_bits = 0x00; - tag->last_authentication_key_type = key_type; + MIFARE_CLASSIC(tag)->cached_access_bits.sector_trailer_block_number = -1; + MIFARE_CLASSIC(tag)->cached_access_bits.sector_access_bits = 0x00; + MIFARE_CLASSIC(tag)->last_authentication_key_type = key_type; // No result. The MIFARE tag just ACKed. return 0; @@ -319,9 +227,10 @@ mifare_classic_authenticate (MifareClassicTag tag, const MifareClassicBlockNumbe * Read data from the provided MIFARE target. */ int -mifare_classic_read (MifareClassicTag tag, const MifareClassicBlockNumber block, MifareClassicBlock *data) +mifare_classic_read (MifareTag tag, const MifareClassicBlockNumber block, MifareClassicBlock *data) { ASSERT_ACTIVE (tag); + ASSERT_MIFARE_CLASSIC (tag); unsigned char command[2]; command[0] = MC_READ; @@ -338,7 +247,7 @@ mifare_classic_read (MifareClassicTag tag, const MifareClassicBlockNumber block, } int -mifare_classic_init_value (MifareClassicTag tag, const MifareClassicBlockNumber block, const int32_t value, const MifareClassicBlockNumber adr) +mifare_classic_init_value (MifareTag tag, const MifareClassicBlockNumber block, const int32_t value, const MifareClassicBlockNumber adr) { union mifare_classic_block b; @@ -358,7 +267,7 @@ mifare_classic_init_value (MifareClassicTag tag, const MifareClassicBlockNumber } int -mifare_classic_read_value (MifareClassicTag tag, const MifareClassicBlockNumber block, int32_t *value, MifareClassicBlockNumber *adr) +mifare_classic_read_value (MifareTag tag, const MifareClassicBlockNumber block, int32_t *value, MifareClassicBlockNumber *adr) { MifareClassicBlock data; if (mifare_classic_read (tag, block, &data) < 0) @@ -390,9 +299,10 @@ mifare_classic_read_value (MifareClassicTag tag, const MifareClassicBlockNumber * Write data to the provided MIFARE target. */ int -mifare_classic_write (MifareClassicTag tag, const MifareClassicBlockNumber block, const MifareClassicBlock data) +mifare_classic_write (MifareTag tag, const MifareClassicBlockNumber block, const MifareClassicBlock data) { ASSERT_ACTIVE (tag); + ASSERT_MIFARE_CLASSIC (tag); unsigned char command[2 + sizeof (MifareClassicBlock)]; command[0] = MC_WRITE; @@ -415,9 +325,10 @@ mifare_classic_write (MifareClassicTag tag, const MifareClassicBlockNumber block * data register. */ int -mifare_classic_increment (MifareClassicTag tag, const MifareClassicBlockNumber block, const uint32_t amount) +mifare_classic_increment (MifareTag tag, const MifareClassicBlockNumber block, const uint32_t amount) { ASSERT_ACTIVE (tag); + ASSERT_MIFARE_CLASSIC (tag); unsigned char command[6]; command[0] = MC_INCREMENT; @@ -441,9 +352,10 @@ mifare_classic_increment (MifareClassicTag tag, const MifareClassicBlockNumber b * data register. */ int -mifare_classic_decrement (MifareClassicTag tag, const MifareClassicBlockNumber block, const uint32_t amount) +mifare_classic_decrement (MifareTag tag, const MifareClassicBlockNumber block, const uint32_t amount) { ASSERT_ACTIVE (tag); + ASSERT_MIFARE_CLASSIC (tag); unsigned char command[6]; command[0] = MC_DECREMENT; @@ -466,9 +378,10 @@ mifare_classic_decrement (MifareClassicTag tag, const MifareClassicBlockNumber b * Store the provided block to the internal data register. */ int -mifare_classic_restore (MifareClassicTag tag, const MifareClassicBlockNumber block) +mifare_classic_restore (MifareTag tag, const MifareClassicBlockNumber block) { ASSERT_ACTIVE (tag); + ASSERT_MIFARE_CLASSIC (tag); /* * Same length as the increment and decrement commands but only the first @@ -495,9 +408,10 @@ mifare_classic_restore (MifareClassicTag tag, const MifareClassicBlockNumber blo * Store the internal data register to the provided block. */ int -mifare_classic_transfer (MifareClassicTag tag, const MifareClassicBlockNumber block) +mifare_classic_transfer (MifareTag tag, const MifareClassicBlockNumber block) { ASSERT_ACTIVE (tag); + ASSERT_MIFARE_CLASSIC (tag); unsigned char command[2]; command[0] = MC_TRANSFER; @@ -530,7 +444,7 @@ mifare_classic_transfer (MifareClassicTag tag, const MifareClassicBlockNumber bl * block. */ int -get_block_access_bits (MifareClassicTag tag, const MifareClassicBlockNumber block, MifareClassicAccessBits *block_access_bits) +get_block_access_bits (MifareTag tag, const MifareClassicBlockNumber block, MifareClassicAccessBits *block_access_bits) { /* * The first block which holds the manufacturer block seems to have @@ -545,9 +459,9 @@ get_block_access_bits (MifareClassicTag tag, const MifareClassicBlockNumber bloc MifareClassicBlockNumber trailer = ((block) / 4) * 4 + 3; - if (tag->cached_access_bits.sector_trailer_block_number == trailer) { + if (MIFARE_CLASSIC(tag)->cached_access_bits.sector_trailer_block_number == trailer) { /* cache hit! */ - sector_access_bits = tag->cached_access_bits.sector_access_bits; + sector_access_bits = MIFARE_CLASSIC(tag)->cached_access_bits.sector_access_bits; } else { MifareClassicBlock trailer_data; @@ -563,14 +477,14 @@ get_block_access_bits (MifareClassicTag tag, const MifareClassicBlockNumber bloc errno = EIO; return -1; } - tag->cached_access_bits.sector_trailer_block_number = trailer; - tag->cached_access_bits.block_number = -1; - tag->cached_access_bits.sector_access_bits = sector_access_bits; + MIFARE_CLASSIC(tag)->cached_access_bits.sector_trailer_block_number = trailer; + MIFARE_CLASSIC(tag)->cached_access_bits.block_number = -1; + MIFARE_CLASSIC(tag)->cached_access_bits.sector_access_bits = sector_access_bits; } - if (tag->cached_access_bits.block_number == block) { + if (MIFARE_CLASSIC(tag)->cached_access_bits.block_number == block) { /* cache hit! */ - *block_access_bits = tag->cached_access_bits.block_access_bits; + *block_access_bits = MIFARE_CLASSIC(tag)->cached_access_bits.block_access_bits; } else { *block_access_bits = 0; /* ,-------C3 @@ -587,7 +501,7 @@ get_block_access_bits (MifareClassicTag tag, const MifareClassicBlockNumber bloc if (sector_access_bits & block_access_bits_mask & 0x00f0) *block_access_bits |= 0x02; /* C2 */ if (sector_access_bits & block_access_bits_mask & 0x0f00) *block_access_bits |= 0x04; /* C3 */ - tag->cached_access_bits.block_access_bits = *block_access_bits; + MIFARE_CLASSIC(tag)->cached_access_bits.block_access_bits = *block_access_bits; } return 0; @@ -597,14 +511,14 @@ get_block_access_bits (MifareClassicTag tag, const MifareClassicBlockNumber bloc * Get information about the trailer block. */ int -mifare_classic_get_trailer_block_permission (MifareClassicTag tag, const MifareClassicBlockNumber block, const uint16_t permission, const MifareClassicKeyType key_type) +mifare_classic_get_trailer_block_permission (MifareTag tag, const MifareClassicBlockNumber block, const uint16_t permission, const MifareClassicKeyType key_type) { MifareClassicAccessBits access_bits; if (get_block_access_bits (tag, block, &access_bits) < 0) { return -1; } - if (tag->cached_access_bits.sector_trailer_block_number == block) { + if (MIFARE_CLASSIC(tag)->cached_access_bits.sector_trailer_block_number == block) { return (mifare_trailer_access_permissions[access_bits] & (permission) << ((key_type == MFC_KEY_A) ? 1 : 0)) ? 1 : 0; } else { errno = EINVAL; @@ -616,14 +530,14 @@ mifare_classic_get_trailer_block_permission (MifareClassicTag tag, const MifareC * Get information about data blocks. */ int -mifare_classic_get_data_block_permission (MifareClassicTag tag, const MifareClassicBlockNumber block, const unsigned char permission, const MifareClassicKeyType key_type) +mifare_classic_get_data_block_permission (MifareTag tag, const MifareClassicBlockNumber block, const unsigned char permission, const MifareClassicKeyType key_type) { MifareClassicAccessBits access_bits; if (get_block_access_bits (tag, block, &access_bits) < 0) { return -1; } - if (tag->cached_access_bits.sector_trailer_block_number != block) { + if (MIFARE_CLASSIC(tag)->cached_access_bits.sector_trailer_block_number != block) { return ((mifare_data_access_permissions[access_bits] & (permission << ( (key_type == MFC_KEY_A) ? 4 : 0 ))) ? 1 : 0); } else { errno = EINVAL; @@ -640,18 +554,18 @@ mifare_classic_get_data_block_permission (MifareClassicTag tag, const MifareClas * Reset a MIFARE target sector to factory default. */ int -mifare_classic_format_sector (MifareClassicTag tag, const MifareSectorNumber sector) +mifare_classic_format_sector (MifareTag tag, const MifareSectorNumber sector) { MifareClassicBlockNumber first_sector_block = sector * 4; /* * Check that the current key allow us to rewrite data and trailer blocks. */ - if (((sector != 0) && (mifare_classic_get_data_block_permission(tag, first_sector_block, MCAB_W, tag->last_authentication_key_type) != 1)) || - (mifare_classic_get_data_block_permission(tag, first_sector_block + 1, MCAB_W, tag->last_authentication_key_type) != 1) || - (mifare_classic_get_data_block_permission(tag, first_sector_block + 2, MCAB_W, tag->last_authentication_key_type) != 1) || - (mifare_classic_get_trailer_block_permission(tag, first_sector_block + 3, MCAB_WRITE_KEYA, tag->last_authentication_key_type) != 1) || - (mifare_classic_get_trailer_block_permission(tag, first_sector_block + 3, MCAB_WRITE_ACCESS_BITS, tag->last_authentication_key_type) != 1) || - (mifare_classic_get_trailer_block_permission(tag, first_sector_block + 3, MCAB_WRITE_KEYB, tag->last_authentication_key_type) != 1)) { + if (((sector != 0) && (mifare_classic_get_data_block_permission(tag, first_sector_block, MCAB_W, MIFARE_CLASSIC(tag)->last_authentication_key_type) != 1)) || + (mifare_classic_get_data_block_permission(tag, first_sector_block + 1, MCAB_W, MIFARE_CLASSIC(tag)->last_authentication_key_type) != 1) || + (mifare_classic_get_data_block_permission(tag, first_sector_block + 2, MCAB_W, MIFARE_CLASSIC(tag)->last_authentication_key_type) != 1) || + (mifare_classic_get_trailer_block_permission(tag, first_sector_block + 3, MCAB_WRITE_KEYA, MIFARE_CLASSIC(tag)->last_authentication_key_type) != 1) || + (mifare_classic_get_trailer_block_permission(tag, first_sector_block + 3, MCAB_WRITE_ACCESS_BITS, MIFARE_CLASSIC(tag)->last_authentication_key_type) != 1) || + (mifare_classic_get_trailer_block_permission(tag, first_sector_block + 3, MCAB_WRITE_KEYB, MIFARE_CLASSIC(tag)->last_authentication_key_type) != 1)) { errno = EPERM; return -1; } @@ -681,7 +595,7 @@ mifare_classic_format_sector (MifareClassicTag tag, const MifareSectorNumber sec * UID accessor */ char* -mifare_classic_get_uid(MifareClassicTag tag) +mifare_classic_get_uid(MifareTag tag) { char* uid = malloc((4 * 2) + 1); snprintf(uid, 9, "%02x%02x%02x%02x", tag->info.abtUid[0], tag->info.abtUid[1], tag->info.abtUid[2], tag->info.abtUid[3]); diff --git a/libfreefare/mifare_ultralight.c b/libfreefare/mifare_ultralight.c index a93a7af..7b73686 100644 --- a/libfreefare/mifare_ultralight.c +++ b/libfreefare/mifare_ultralight.c @@ -50,99 +50,29 @@ * the target. */ -/* - * Get a list of the MIFARE card near to the provided NFC initiator. - * - * The list can be freed using the mifare_ultralight_free_tags() function. - */ -MifareUltralightTag * -mifare_ultralight_get_tags (nfc_device_t *device) -{ - MifareUltralightTag *tags = NULL; - int tag_count = 0; - - nfc_initiator_init(device); - - // Drop the field for a while - nfc_configure(device,NDO_ACTIVATE_FIELD,false); - - // Let the reader only try once to find a tag - nfc_configure(device,NDO_INFINITE_SELECT,false); - - // Configure the CRC and Parity settings - nfc_configure(device,NDO_HANDLE_CRC,true); - nfc_configure(device,NDO_HANDLE_PARITY,true); - - // Enable field so more power consuming cards can power themselves up - nfc_configure(device,NDO_ACTIVATE_FIELD,true); - - // Poll for a ISO14443A (MIFARE) tag - nfc_target_info_t target_info; - - tags = malloc(sizeof (void *)); - if(!tags) return NULL; - tags[0] = NULL; - - while (nfc_initiator_select_tag(device,NM_ISO14443A_106,NULL,0,&target_info)) { - - // Ensure the target is a MIFARE UltraLight tag. - if (!((target_info.nai.abtAtqa[0] == 0x00) && - (target_info.nai.abtAtqa[1] == 0x44) && - (target_info.nai.btSak == 0x00))) /* NXP MIFARE UltraLight */ - continue; - - tag_count++; - - /* (Re)Allocate memory for the found MIFARE UltraLight array */ - MifareUltralightTag *p = realloc (tags, (tag_count) * sizeof (MifareUltralightTag) + sizeof (void *)); - if (p) - tags = p; - else - return tags; // FAIL! Return what has been found so far. - - /* Allocate memory for the found MIFARE UltraLight tag */ - if (!(tags[tag_count-1] = malloc (sizeof (struct mifare_ultralight_tag)))) { - return tags; // FAIL! Return what has been found before. - } - (tags[tag_count-1])->device = device; - (tags[tag_count-1])->info = target_info.nai; - (tags[tag_count-1])->active = 0; - for (int i = 0; i < MIFARE_ULTRALIGHT_PAGE_COUNT; i++) { - tags[tag_count-1]->cached_pages[i] = 0; - } - tags[tag_count] = NULL; - - nfc_initiator_deselect_tag (device); - } - - return tags; -} - /* * Free the provided tag list. */ void -mifare_ultralight_free_tags (MifareUltralightTag *tags) +mifare_ultralight_free_tag (MifareTag tag) { - if (tags) { - for (int i=0; tags[i]; i++) { - free (tags[i]); - } - free (tags); - } + free (tag); } /* * Establish connection to the provided tag. */ int -mifare_ultralight_connect (MifareUltralightTag tag) +mifare_ultralight_connect (MifareTag tag) { ASSERT_INACTIVE (tag); + ASSERT_MIFARE_ULTRALIGHT (tag); nfc_target_info_t pnti; if (nfc_initiator_select_tag (tag->device, NM_ISO14443A_106, tag->info.abtUid, 8, &pnti)) { tag->active = 1; + for (int i = 0; i < MIFARE_ULTRALIGHT_PAGE_COUNT; i++) + MIFARE_ULTRALIGHT(tag)->cached_pages[i] = 0; } else { errno = EIO; return -1; @@ -154,9 +84,10 @@ mifare_ultralight_connect (MifareUltralightTag tag) * Terminate connection with the provided tag. */ int -mifare_ultralight_disconnect (MifareUltralightTag tag) +mifare_ultralight_disconnect (MifareTag tag) { ASSERT_ACTIVE (tag); + ASSERT_MIFARE_ULTRALIGHT (tag); if (nfc_initiator_deselect_tag (tag->device)) { tag->active = 0; @@ -179,34 +110,35 @@ mifare_ultralight_disconnect (MifareUltralightTag tag) * Read data from the provided MIFARE tag. */ int -mifare_ultralight_read (MifareUltralightTag tag, MifareUltralightPageNumber page, MifareUltralightPage *data) +mifare_ultralight_read (MifareTag tag, MifareUltralightPageNumber page, MifareUltralightPage *data) { ASSERT_ACTIVE (tag); + ASSERT_MIFARE_ULTRALIGHT (tag); ASSERT_VALID_PAGE (page); - if (!tag->cached_pages[page]) { + if (!MIFARE_ULTRALIGHT(tag)->cached_pages[page]) { uint8_t cmd[2]; cmd[0] = 0x30; cmd[1] = page; size_t n; - if (!(nfc_initiator_transceive_dep_bytes (tag->device, cmd, sizeof (cmd), tag->cache[page], &n))) { + if (!(nfc_initiator_transceive_dep_bytes (tag->device, cmd, sizeof (cmd), MIFARE_ULTRALIGHT(tag)->cache[page], &n))) { errno = EIO; return -1; } /* Handle wrapped pages */ for (int i = MIFARE_ULTRALIGHT_PAGE_COUNT; i <= page + 3; i++) { - memcpy (tag->cache[i % MIFARE_ULTRALIGHT_PAGE_COUNT], tag->cache[i], sizeof (MifareUltralightPage)); + memcpy (MIFARE_ULTRALIGHT(tag)->cache[i % MIFARE_ULTRALIGHT_PAGE_COUNT], MIFARE_ULTRALIGHT(tag)->cache[i], sizeof (MifareUltralightPage)); } /* Mark pages as cached */ for (int i = page; i <= page + 3; i++) { - tag->cached_pages[i % MIFARE_ULTRALIGHT_PAGE_COUNT] = 1; + MIFARE_ULTRALIGHT(tag)->cached_pages[i % MIFARE_ULTRALIGHT_PAGE_COUNT] = 1; } } - memcpy (data, tag->cache[page], sizeof (*data)); + memcpy (data, MIFARE_ULTRALIGHT(tag)->cache[page], sizeof (*data)); return 0; } @@ -214,9 +146,10 @@ mifare_ultralight_read (MifareUltralightTag tag, MifareUltralightPageNumber page * Read data to the provided MIFARE tag. */ int -mifare_ultralight_write (MifareUltralightTag tag, const MifareUltralightPageNumber page, const MifareUltralightPage data) +mifare_ultralight_write (MifareTag tag, const MifareUltralightPageNumber page, const MifareUltralightPage data) { ASSERT_ACTIVE (tag); + ASSERT_MIFARE_ULTRALIGHT (tag); ASSERT_VALID_PAGE (page); uint8_t cmd[6]; @@ -231,7 +164,7 @@ mifare_ultralight_write (MifareUltralightTag tag, const MifareUltralightPageNumb } /* Invalidate page in cache */ - tag->cached_pages[page] = 0; + MIFARE_ULTRALIGHT(tag)->cached_pages[page] = 0; return 0; } @@ -242,7 +175,7 @@ mifare_ultralight_write (MifareUltralightTag tag, const MifareUltralightPageNumb * Miscellaneous functions */ char * -mifare_ultralight_get_uid (MifareUltralightTag tag) +mifare_ultralight_get_uid (MifareTag tag) { char *uid = malloc (2 * 7 + 1); MifareUltralightPage p0, p1; diff --git a/test/mifare_classic_fixture.c b/test/mifare_classic_fixture.c index a514c49..fa34d5f 100644 --- a/test/mifare_classic_fixture.c +++ b/test/mifare_classic_fixture.c @@ -21,8 +21,8 @@ #include static nfc_device_t *device = NULL; -static MifareClassicTag *tags = NULL; -MifareClassicTag tag = NULL; +static MifareTag *tags = NULL; +MifareTag tag = NULL; void setup () @@ -32,12 +32,19 @@ setup () device = nfc_connect (NULL); cut_assert_not_null (device, cut_message ("No device found")); - tags = mifare_classic_get_tags (device); - cut_assert_not_null (tags, cut_message ("mifare_classic_get_tags() failed")); + tags = freefare_get_tags (device); + cut_assert_not_null (tags, cut_message ("freefare_get_tags() failed")); - cut_assert_not_null (tags[0], cut_message ("No MIFARE Classic tag on NFC device")); + tag = NULL; + for (int i=0; tags[i]; i++) { + if ((freefare_get_tag_type(tags[i]) == CLASSIC_1K) || + (freefare_get_tag_type(tags[i]) == CLASSIC_4K)) { + tag = tags[i]; + break; + } + } - tag = tags[0]; + cut_assert_not_null (tag, cut_message ("No MIFARE Classic tag on NFC device")); res = mifare_classic_connect (tag); cut_assert_equal_int (0, res, cut_message ("mifare_classic_connect() failed")); @@ -50,7 +57,7 @@ teardown () mifare_classic_disconnect (tag); if (tags) - mifare_classic_free_tags (tags); + freefare_free_tags (tags); if (device) nfc_disconnect (device); diff --git a/test/mifare_classic_fixture.h b/test/mifare_classic_fixture.h index e24b98d..19f10d0 100644 --- a/test/mifare_classic_fixture.h +++ b/test/mifare_classic_fixture.h @@ -17,4 +17,4 @@ * $Id$ */ -extern MifareClassicTag tag; +extern MifareTag tag; diff --git a/test/mifare_ultralight_fixture.c b/test/mifare_ultralight_fixture.c index 2f29ea2..aa0b57e 100644 --- a/test/mifare_ultralight_fixture.c +++ b/test/mifare_ultralight_fixture.c @@ -21,8 +21,8 @@ #include static nfc_device_t *device = NULL; -static MifareUltralightTag *tags = NULL; -MifareUltralightTag tag = NULL; +static MifareTag *tags = NULL; +MifareTag tag = NULL; void setup () @@ -32,12 +32,18 @@ setup () device = nfc_connect (NULL); cut_assert_not_null (device, cut_message ("No device found")); - tags = mifare_ultralight_get_tags (device); - cut_assert_not_null (tags, cut_message ("Error enumerating NFC tags")); + tags = freefare_get_tags (device); + cut_assert_not_null (tags, cut_message ("freefare_get_tags() failed")); - cut_assert_not_null (tags[0], cut_message ("No MIFARE CLassic tag on NFC device")); + tag = NULL; + for (int i=0; tags[i]; i++) { + if (freefare_get_tag_type(tags[i]) == ULTRALIGHT) { + tag = tags[i]; + break; + } + } - tag = tags[0]; + cut_assert_not_null (tag, cut_message ("No MIFARE UltraLight tag on NFC device")); res = mifare_ultralight_connect (tag); cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_connect() failed")); @@ -50,7 +56,7 @@ teardown () mifare_ultralight_disconnect (tag); if (tags) - mifare_ultralight_free_tags (tags); + freefare_free_tags (tags); if (device) nfc_disconnect (device); diff --git a/test/mifare_ultralight_fixture.h b/test/mifare_ultralight_fixture.h index 7abd272..214bf9c 100644 --- a/test/mifare_ultralight_fixture.h +++ b/test/mifare_ultralight_fixture.h @@ -17,4 +17,4 @@ * $Id$ */ -extern MifareUltralightTag tag; +extern MifareTag tag; diff --git a/test/test_mifare_ultralight.c b/test/test_mifare_ultralight.c index 9f0a996..85e4ccd 100644 --- a/test/test_mifare_ultralight.c +++ b/test/test_mifare_ultralight.c @@ -98,10 +98,10 @@ test_mifare_ultralight_cache (void) /* Check cached pages consistency */ for (int i = 0; i <= 3; i++) { - cut_assert_equal_int (1, tag->cached_pages[i], cut_message ("Wrong page cache value for tag->cached_pages[%d]", i)); + cut_assert_equal_int (1, MIFARE_ULTRALIGHT(tag)->cached_pages[i], cut_message ("Wrong page cache value for tag->cached_pages[%d]", i)); } for (int i = 4; i < MIFARE_ULTRALIGHT_PAGE_COUNT; i++) { - cut_assert_equal_int (0, tag->cached_pages[i], cut_message ("Wrong page cache value for tag->cached_pages[%d]", i)); + cut_assert_equal_int (0, MIFARE_ULTRALIGHT(tag)->cached_pages[i], cut_message ("Wrong page cache value for tag->cached_pages[%d]", i)); } } @@ -133,13 +133,13 @@ test_mifare_ultralight_cache_wrap (void) /* Check cached pages consistency */ for (int i = 0; i <= 2; i++) { - cut_assert_equal_int (1, tag->cached_pages[i], cut_message ("Wrong page cache value for tag->cached_pages[%d]", i)); + cut_assert_equal_int (1, MIFARE_ULTRALIGHT(tag)->cached_pages[i], cut_message ("Wrong page cache value for tag->cached_pages[%d]", i)); } for (int i = 3; i <= 14; i++) { - cut_assert_equal_int (0, tag->cached_pages[i], cut_message ("Wrong page cache value for tag->cached_pages[%d]", i)); + cut_assert_equal_int (0, MIFARE_ULTRALIGHT(tag)->cached_pages[i], cut_message ("Wrong page cache value for tag->cached_pages[%d]", i)); } for (int i = 15; i < MIFARE_ULTRALIGHT_PAGE_COUNT; i++) { - cut_assert_equal_int (1, tag->cached_pages[i], cut_message ("Wrong page cache value for tag->cached_pages[%d]", i)); + cut_assert_equal_int (1, MIFARE_ULTRALIGHT(tag)->cached_pages[i], cut_message ("Wrong page cache value for tag->cached_pages[%d]", i)); } }