void test_mifare_ultralight_cache (void) { int res; MifareUltralightPage page; res = mifare_ultralight_read (tag, 0, &page); cut_assert_equal_int (0, res, cut_message ("mifare_ultralight_read() failed")); /* Check cached pages consistency */ for (int i = 0; i <= 3; 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, MIFARE_ULTRALIGHT(tag)->cached_pages[i], cut_message ("Wrong page cache value for tag->cached_pages[%d]", i)); } }
/* * Read data to the provided MIFARE tag. */ int mifare_ultralight_write (MifareTag tag, const MifareUltralightPageNumber page, const MifareUltralightPage data) { ASSERT_ACTIVE (tag); ASSERT_MIFARE_ULTRALIGHT (tag); ASSERT_VALID_PAGE (tag, page, true); BUFFER_INIT (cmd, 6); BUFFER_INIT (res, 1); BUFFER_APPEND (cmd, 0xA2); BUFFER_APPEND (cmd, page); BUFFER_APPEND_BYTES (cmd, data, sizeof (MifareUltralightPage)); ULTRALIGHT_TRANSCEIVE (tag, cmd, res); /* Invalidate page in cache */ MIFARE_ULTRALIGHT(tag)->cached_pages[page] = 0; return 0; }
/* * Establish connection to the provided tag. */ int mifare_ultralight_connect (MifareTag tag) { ASSERT_INACTIVE (tag); ASSERT_MIFARE_ULTRALIGHT (tag); nfc_target pnti; nfc_modulation modulation = { .nmt = NMT_ISO14443A, .nbr = NBR_106 }; if (nfc_initiator_select_passive_target (tag->device, modulation, tag->info.abtUid, tag->info.szUidLen, &pnti) >= 0) { tag->active = 1; for (int i = 0; i < MIFARE_ULTRALIGHT_MAX_PAGE_COUNT; i++) MIFARE_ULTRALIGHT(tag)->cached_pages[i] = 0; } else { errno = EIO; return -1; } return 0; }
/* * Read data from the provided MIFARE tag. */ int mifare_ultralight_read (MifareTag tag, MifareUltralightPageNumber page, MifareUltralightPage *data) { ASSERT_ACTIVE (tag); ASSERT_MIFARE_ULTRALIGHT (tag); ASSERT_VALID_PAGE (tag, page, false); if (!MIFARE_ULTRALIGHT(tag)->cached_pages[page]) { BUFFER_INIT (cmd, 2); BUFFER_ALIAS (res, MIFARE_ULTRALIGHT(tag)->cache[page], sizeof(MifareUltralightPage) * 4); BUFFER_APPEND (cmd, 0x30); BUFFER_APPEND (cmd, page); ULTRALIGHT_TRANSCEIVE (tag, cmd, res); /* Handle wrapped pages */ int iPageCount; if (IS_MIFARE_ULTRALIGHT_C(tag)) { iPageCount = MIFARE_ULTRALIGHT_C_PAGE_COUNT_READ; } else { iPageCount = MIFARE_ULTRALIGHT_PAGE_COUNT; } for (int i = iPageCount; i <= page + 3; i++) { memcpy (MIFARE_ULTRALIGHT(tag)->cache[i % iPageCount], MIFARE_ULTRALIGHT(tag)->cache[i], sizeof (MifareUltralightPage)); } /* Mark pages as cached */ for (int i = page; i <= page + 3; i++) { MIFARE_ULTRALIGHT(tag)->cached_pages[i % iPageCount] = 1; } } memcpy (data, MIFARE_ULTRALIGHT(tag)->cache[page], sizeof (*data)); return 0; }