218 lines
5.0 KiB
C++
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;
|
|
}
|
|
}
|