Files
rfid.NDEF/NfcAdapter.cpp
2021-12-10 17:14:41 +01:00

218 lines
5.0 KiB
C++

#include <NfcAdapter.h>
NfcAdapter::NfcAdapter(PN532Interface &interface)
{
shield = new PN532(interface);
}
NfcAdapter::~NfcAdapter(void)
{
delete shield;
}
void NfcAdapter::begin(boolean verbose)
{
shield->begin();
uint32_t versiondata = shield->getFirmwareVersion();
if (! versiondata)
{
#ifdef NDEF_USE_SERIAL
Serial.print(F("Didn't find PN53x board"));
#endif
}
if (verbose)
{
#ifdef NDEF_USE_SERIAL
Serial.print(F("Found chip PN5")); Serial.println((versiondata>>24) & 0xFF, HEX);
Serial.print(F("Firmware ver. ")); Serial.print((versiondata>>16) & 0xFF, DEC);
Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
#endif
}
// configure board to read RFID tags
shield->SAMConfig();
}
boolean NfcAdapter::tagPresent(unsigned long timeout)
{
uint8_t success;
uidLength = 0;
if (timeout == 0)
{
success = shield->readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, (uint8_t*)&uidLength);
}
else
{
success = shield->readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, (uint8_t*)&uidLength, timeout);
}
return success;
}
boolean NfcAdapter::erase()
{
NdefMessage message = NdefMessage();
message.addEmptyRecord();
return write(message);
}
boolean NfcAdapter::format()
{
boolean success;
#ifdef NDEF_SUPPORT_MIFARE_CLASSIC
if (uidLength == 4)
{
MifareClassic mifareClassic = MifareClassic(*shield);
success = mifareClassic.formatNDEF(uid, uidLength);
}
else
#endif
{
#ifdef NDEF_USE_SERIAL
Serial.print(F("Unsupported Tag."));
#endif
success = false;
}
return success;
}
boolean NfcAdapter::clean()
{
uint8_t type = guessTagType();
#ifdef NDEF_SUPPORT_MIFARE_CLASSIC
if (type == TAG_TYPE_MIFARE_CLASSIC)
{
#ifdef NDEF_DEBUG
Serial.println(F("Cleaning Mifare Classic"));
#endif
MifareClassic mifareClassic = MifareClassic(*shield);
return mifareClassic.formatMifare(uid, uidLength);
}
else
#endif
if (type == TAG_TYPE_2)
{
#ifdef NDEF_DEBUG
Serial.println(F("Cleaning Mifare Ultralight"));
#endif
MifareUltralight ultralight = MifareUltralight(*shield);
return ultralight.clean();
}
else
{
#ifdef NDEF_USE_SERIAL
Serial.print(F("No driver for card type "));Serial.println(type);
#endif
return false;
}
}
NfcTag NfcAdapter::read()
{
uint8_t type = guessTagType();
#ifdef NDEF_SUPPORT_MIFARE_CLASSIC
if (type == TAG_TYPE_MIFARE_CLASSIC)
{
#ifdef NDEF_DEBUG
Serial.println(F("Reading Mifare Classic"));
#endif
MifareClassic mifareClassic = MifareClassic(*shield);
return mifareClassic.read(uid, uidLength);
}
else
#endif
if (type == TAG_TYPE_2)
{
#ifdef NDEF_DEBUG
Serial.println(F("Reading Mifare Ultralight"));
#endif
MifareUltralight ultralight = MifareUltralight(*shield);
return ultralight.read(uid, uidLength);
}
else if (type == TAG_TYPE_UNKNOWN)
{
#ifdef NDEF_USE_SERIAL
Serial.print(F("Can not determine tag type"));
#endif
return NfcTag(uid, uidLength);
}
else
{
// Serial.print(F("No driver for card type "));Serial.println(type);
// TODO should set type here
return NfcTag(uid, uidLength);
}
}
boolean NfcAdapter::write(NdefMessage& ndefMessage)
{
boolean success;
uint8_t type = guessTagType();
#ifdef NDEF_SUPPORT_MIFARE_CLASSIC
if (type == TAG_TYPE_MIFARE_CLASSIC)
{
#ifdef NDEF_DEBUG
Serial.println(F("Writing Mifare Classic"));
#endif
MifareClassic mifareClassic = MifareClassic(*shield);
success = mifareClassic.write(ndefMessage, uid, uidLength);
}
else
#endif
if (type == TAG_TYPE_2)
{
#ifdef NDEF_DEBUG
Serial.println(F("Writing Mifare Ultralight"));
#endif
MifareUltralight mifareUltralight = MifareUltralight(*shield);
success = mifareUltralight.write(ndefMessage, uid, uidLength);
}
else if (type == TAG_TYPE_UNKNOWN)
{
#ifdef NDEF_USE_SERIAL
Serial.print(F("Can not determine tag type"));
#endif
success = false;
}
else
{
#ifdef NDEF_USE_SERIAL
Serial.print(F("No driver for card type "));Serial.println(type);
#endif
success = false;
}
return success;
}
// TODO this should return a Driver MifareClassic, MifareUltralight, Type 4, Unknown
// Guess Tag Type by looking at the ATQA and SAK values
// Need to follow spec for Card Identification. Maybe AN1303, AN1305 and ???
unsigned int NfcAdapter::guessTagType()
{
// 4 byte id - Mifare Classic
// - ATQA 0x4 && SAK 0x8
// 7 byte id
// - ATQA 0x44 && SAK 0x8 - Mifare Classic
// - ATQA 0x44 && SAK 0x0 - Mifare Ultralight NFC Forum Type 2
// - ATQA 0x344 && SAK 0x20 - NFC Forum Type 4
if (uidLength == 4)
{
return TAG_TYPE_MIFARE_CLASSIC;
}
else
{
return TAG_TYPE_2;
}
}