ESP32-Bus-Pirate/lib/PN532/examples/mifareclassic_ndeftoclassic/mifareclassic_ndeftoclassic.ino

208 lines
8.1 KiB
C++

/**************************************************************************/
/*!
@file mifareclassic_ndeftoclassic.pde
@author KTOWN (Adafruit Industries)
@license BSD (see license.txt)
This examples attempts to take a Mifare Classic 1K card that has been
formatted for NDEF messages using mifareclassic_formatndef, and resets
the authentication keys back to the Mifare Classic defaults
This is an example sketch for the Adafruit PN532 NFC/RFID breakout boards
This library works with the Adafruit NFC Shield
----> https://www.adafruit.com/products/789
Check out the links above for our tutorials and wiring diagrams
These chips use SPI or I2C to communicate
Adafruit invests time and resources providing this open source code,
please support Adafruit and open-source hardware by purchasing
products from Adafruit!
*/
/**************************************************************************/
#include <Wire.h>
#include <SPI.h>
#include <Adafruit_PN532.h>
// If using the breakout with SPI, define the pins for SPI communication.
#define PN532_SCK (2)
#define PN532_MOSI (3)
#define PN532_SS (4)
#define PN532_MISO (5)
// If using the breakout or shield with I2C, define just the pins connected
// to the IRQ and reset lines. Use the values below (2, 3) for the shield!
#define PN532_IRQ (2)
#define PN532_RESET (3) // Not connected by default on the NFC Shield
// Uncomment just _one_ line below depending on how your breakout or shield
// is connected to the Arduino:
// Use this line for a breakout with a SPI connection:
Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);
// Use this line for a breakout with a hardware SPI connection. Note that
// the PN532 SCK, MOSI, and MISO pins need to be connected to the Arduino's
// hardware SPI SCK, MOSI, and MISO pins. On an Arduino Uno these are
// SCK = 13, MOSI = 11, MISO = 12. The SS line can be any digital IO pin.
//Adafruit_PN532 nfc(PN532_SS);
// Or use this line for a breakout or shield with an I2C connection:
//Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);
#define NR_SHORTSECTOR (32) // Number of short sectors on Mifare 1K/4K
#define NR_LONGSECTOR (8) // Number of long sectors on Mifare 4K
#define NR_BLOCK_OF_SHORTSECTOR (4) // Number of blocks in a short sector
#define NR_BLOCK_OF_LONGSECTOR (16) // Number of blocks in a long sector
// Determine the sector trailer block based on sector number
#define BLOCK_NUMBER_OF_SECTOR_TRAILER(sector) (((sector)<NR_SHORTSECTOR)? \
((sector)*NR_BLOCK_OF_SHORTSECTOR + NR_BLOCK_OF_SHORTSECTOR-1):\
(NR_SHORTSECTOR*NR_BLOCK_OF_SHORTSECTOR + (sector-NR_SHORTSECTOR)*NR_BLOCK_OF_LONGSECTOR + NR_BLOCK_OF_LONGSECTOR-1))
// Determine the sector's first block based on the sector number
#define BLOCK_NUMBER_OF_SECTOR_1ST_BLOCK(sector) (((sector)<NR_SHORTSECTOR)? \
((sector)*NR_BLOCK_OF_SHORTSECTOR):\
(NR_SHORTSECTOR*NR_BLOCK_OF_SHORTSECTOR + (sector-NR_SHORTSECTOR)*NR_BLOCK_OF_LONGSECTOR))
// The default Mifare Classic key
static const uint8_t KEY_DEFAULT_KEYAB[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
void setup(void) {
Serial.begin(115200);
while (!Serial) delay(10); // for Leonardo/Micro/Zero
Serial.println("Looking for PN532...");
nfc.begin();
uint32_t versiondata = nfc.getFirmwareVersion();
if (! versiondata) {
Serial.print("Didn't find PN53x board");
while (1); // halt
}
// Got ok data, print it out!
Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
}
void loop(void) {
uint8_t success; // Flag to check if there was an error with the PN532
uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
uint8_t blockBuffer[16]; // Buffer to store block contents
uint8_t blankAccessBits[3] = { 0xff, 0x07, 0x80 };
uint8_t idx = 0;
uint8_t numOfSector = 16; // Assume Mifare Classic 1K for now (16 4-block sectors)
Serial.println("Place your NDEF formatted Mifare Classic 1K card on the reader");
Serial.println("and press any key to continue ...");
// Wait for user input before proceeding
while (!Serial.available());
while (Serial.available()) Serial.read();
// Wait for an ISO14443A type card (Mifare, etc.). When one is found
// 'uid' will be populated with the UID, and uidLength will indicate
// if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
if (success)
{
// We seem to have a tag ...
// Display some basic information about it
Serial.println("Found an ISO14443A card/tag");
Serial.print(" UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
Serial.print(" UID Value: ");
nfc.PrintHex(uid, uidLength);
Serial.println("");
// Make sure this is a Mifare Classic card
if (uidLength != 4)
{
Serial.println("Ooops ... this doesn't seem to be a Mifare Classic card!");
return;
}
Serial.println("Seems to be a Mifare Classic card (4 byte UID)");
Serial.println("");
Serial.println("Reformatting card for Mifare Classic (please don't touch it!) ... ");
// Now run through the card sector by sector
for (idx = 0; idx < numOfSector; idx++)
{
// Step 1: Authenticate the current sector using key B 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
success = nfc.mifareclassic_AuthenticateBlock (uid, uidLength, BLOCK_NUMBER_OF_SECTOR_TRAILER(idx), 1, (uint8_t *)KEY_DEFAULT_KEYAB);
if (!success)
{
Serial.print("Authentication failed for sector "); Serial.println(numOfSector);
return;
}
// Step 2: Write to the other blocks
if (idx == 16)
{
memset(blockBuffer, 0, sizeof(blockBuffer));
if (!(nfc.mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 3, blockBuffer)))
{
Serial.print("Unable to write to sector "); Serial.println(numOfSector);
return;
}
}
if ((idx == 0) || (idx == 16))
{
memset(blockBuffer, 0, sizeof(blockBuffer));
if (!(nfc.mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 2, blockBuffer)))
{
Serial.print("Unable to write to sector "); Serial.println(numOfSector);
return;
}
}
else
{
memset(blockBuffer, 0, sizeof(blockBuffer));
if (!(nfc.mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 3, blockBuffer)))
{
Serial.print("Unable to write to sector "); Serial.println(numOfSector);
return;
}
if (!(nfc.mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 2, blockBuffer)))
{
Serial.print("Unable to write to sector "); Serial.println(numOfSector);
return;
}
}
memset(blockBuffer, 0, sizeof(blockBuffer));
if (!(nfc.mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 1, blockBuffer)))
{
Serial.print("Unable to write to sector "); Serial.println(numOfSector);
return;
}
// Step 3: Reset both keys to 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
memcpy(blockBuffer, KEY_DEFAULT_KEYAB, sizeof(KEY_DEFAULT_KEYAB));
memcpy(blockBuffer + 6, blankAccessBits, sizeof(blankAccessBits));
blockBuffer[9] = 0x69;
memcpy(blockBuffer + 10, KEY_DEFAULT_KEYAB, sizeof(KEY_DEFAULT_KEYAB));
// Step 4: Write the trailer block
if (!(nfc.mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)), blockBuffer)))
{
Serial.print("Unable to write trailer block of sector "); Serial.println(numOfSector);
return;
}
}
}
// Wait a bit before trying again
Serial.println("\n\nDone!");
delay(1000);
Serial.flush();
while(Serial.available()) Serial.read();
}