Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of PN532 by
MifareUltralight.cpp
- Committer:
- yihui
- Date:
- 2013-11-21
- Revision:
- 3:4189a10038e6
- Child:
- 5:51f820fbd18a
File content as of revision 3:4189a10038e6:
#include "MifareUltralight.h" #include "PN532_debug.h" #define ULTRALIGHT_PAGE_SIZE 4 #define ULTRALIGHT_READ_SIZE 4 // we should be able to read 16 uint8_ts at a time #define ULTRALIGHT_DATA_START_PAGE 4 #define ULTRALIGHT_MESSAGE_LENGTH_INDEX 1 #define ULTRALIGHT_DATA_START_INDEX 2 #define ULTRALIGHT_MAX_PAGE 63 #define NFC_FORUM_TAG_TYPE_2 ("NFC Forum Type 2") MifareUltralight::MifareUltralight(PN532& nfcShield) { nfc = &nfcShield; ndefStartIndex = 0; messageLength = 0; } MifareUltralight::~MifareUltralight() { } NfcTag MifareUltralight::read(uint8_t * uid, unsigned int uidLength) { if (isUnformatted()) { DMSG("WARNING: Tag is not formatted."); return NfcTag(uid, uidLength, NFC_FORUM_TAG_TYPE_2); } readCapabilityContainer(); // meta info for tag findNdefMessage(); calculateBufferSize(); if (messageLength == 0) { // data is 0x44 0x03 0x00 0xFE NdefMessage message = NdefMessage(); message.addEmptyRecord(); return NfcTag(uid, uidLength, NFC_FORUM_TAG_TYPE_2, message); } bool success; uint8_t page; uint8_t index = 0; uint8_t buffer[bufferSize]; for (page = ULTRALIGHT_DATA_START_PAGE; page < ULTRALIGHT_MAX_PAGE; page++) { // read the data success = nfc->mifareultralight_ReadPage(page, &buffer[index]); if (success) { #ifdef MIFARE_ULTRALIGHT_DEBUG DMSG("Page ");Serial.print(page);DMSG(" "); nfc->PrintHexChar(&buffer[index], ULTRALIGHT_PAGE_SIZE); #endif } else { DMSG("Read failed ");DMSG_INT(page); // TODO error handling messageLength = 0; break; } if (index >= (messageLength + ndefStartIndex)) { break; } index += ULTRALIGHT_PAGE_SIZE; } NdefMessage ndefMessage = NdefMessage(&buffer[ndefStartIndex], messageLength); return NfcTag(uid, uidLength, NFC_FORUM_TAG_TYPE_2, ndefMessage); } bool MifareUltralight::isUnformatted() { uint8_t page = 4; uint8_t data[ULTRALIGHT_READ_SIZE]; bool success = nfc->mifareultralight_ReadPage (page, data); if (success) { return (data[0] == 0xFF && data[1] == 0xFF && data[2] == 0xFF && data[3] == 0xFF); } else { DMSG("Error. Failed read page ");DMSG_INT(page); return false; } } // page 3 has tag capabilities void MifareUltralight::readCapabilityContainer() { uint8_t data[ULTRALIGHT_PAGE_SIZE]; int success = nfc->mifareultralight_ReadPage (3, data); if (success) { // See AN1303 - different rules for Mifare Family uint8_t2 = (additional data + 48)/8 tagCapacity = data[2] * 8; #ifdef MIFARE_ULTRALIGHT_DEBUG DMSG("Tag capacity "));Serial.print(tagCapacity);DMSG(F(" uint8_ts"); #endif // TODO future versions should get lock information } } // read enough of the message to find the ndef message length void MifareUltralight::findNdefMessage() { int page; uint8_t data[12]; // 3 pages uint8_t* data_ptr = &data[0]; // the nxp read command reads 4 pages, unfortunately adafruit give me one page at a time bool success = true; for (page = 4; page < 6; page++) { success = success && nfc->mifareultralight_ReadPage(page, data_ptr); #ifdef MIFARE_ULTRALIGHT_DEBUG DMSG("Page "));Serial.print(page);Serial.print(F(" - "); nfc->PrintHexChar(data_ptr, 4); #endif data_ptr += ULTRALIGHT_PAGE_SIZE; } if (success) { if (data[0] == 0x03) { messageLength = data[1]; ndefStartIndex = 2; } else if (data[5] == 0x3) // page 5 uint8_t 1 { // TODO should really read the lock control TLV to ensure uint8_t[5] is correct messageLength = data[6]; ndefStartIndex = 7; } } #ifdef MIFARE_ULTRALIGHT_DEBUG DMSG("messageLength ");DMSG(messageLength); DMSG("ndefStartIndex ");DMSG(ndefStartIndex); #endif } // buffer is larger than the message, need to handle some data before and after // message and need to ensure we read full pages void MifareUltralight::calculateBufferSize() { // TLV terminator 0xFE is 1 uint8_t bufferSize = messageLength + ndefStartIndex + 1; if (bufferSize % ULTRALIGHT_READ_SIZE != 0) { // buffer must be an increment of page size bufferSize = ((bufferSize / ULTRALIGHT_READ_SIZE) + 1) * ULTRALIGHT_READ_SIZE; } }