Krolyxon
Commit 3120783

Branches

Tags

Refs →

orion-rf.piolibdepsesp32-s3-n16r8Adafruit PN532examplesmifareclassic_ndeftoclassicmifareclassic_ndeftoclassic.ino

207 lines · 8.1 KB

1/**************************************************************************/
2/*!
3 @file mifareclassic_ndeftoclassic.pde
4 @author KTOWN (Adafruit Industries)
5 @license BSD (see license.txt)
6
7 This examples attempts to take a Mifare Classic 1K card that has been
8 formatted for NDEF messages using mifareclassic_formatndef, and resets
9 the authentication keys back to the Mifare Classic defaults
10
11 This is an example sketch for the Adafruit PN532 NFC/RFID breakout boards
12 This library works with the Adafruit NFC Shield
13 ----> https://www.adafruit.com/products/789
14
15 Check out the links above for our tutorials and wiring diagrams
16 These chips use SPI or I2C to communicate
17
18 Adafruit invests time and resources providing this open source code,
19 please support Adafruit and open-source hardware by purchasing
20 products from Adafruit!
21
22*/
23/**************************************************************************/
24
25#include <Wire.h>
26#include <SPI.h>
27#include <Adafruit_PN532.h>
28
29// If using the breakout with SPI, define the pins for SPI communication.
30#define PN532_SCK (2)
31#define PN532_MOSI (3)
32#define PN532_SS (4)
33#define PN532_MISO (5)
34
35// If using the breakout or shield with I2C, define just the pins connected
36// to the IRQ and reset lines. Use the values below (2, 3) for the shield!
37#define PN532_IRQ (2)
38#define PN532_RESET (3) // Not connected by default on the NFC Shield
39
40// Uncomment just _one_ line below depending on how your breakout or shield
41// is connected to the Arduino:
42
43// Use this line for a breakout with a SPI connection:
44Adafruit_PN532 nfc(PN532_SCK, PN532_MISO, PN532_MOSI, PN532_SS);
45
46// Use this line for a breakout with a hardware SPI connection. Note that
47// the PN532 SCK, MOSI, and MISO pins need to be connected to the Arduino's
48// hardware SPI SCK, MOSI, and MISO pins. On an Arduino Uno these are
49// SCK = 13, MOSI = 11, MISO = 12. The SS line can be any digital IO pin.
50//Adafruit_PN532 nfc(PN532_SS);
51
52// Or use this line for a breakout or shield with an I2C connection:
53//Adafruit_PN532 nfc(PN532_IRQ, PN532_RESET);
54
55#define NR_SHORTSECTOR (32) // Number of short sectors on Mifare 1K/4K
56#define NR_LONGSECTOR (8) // Number of long sectors on Mifare 4K
57#define NR_BLOCK_OF_SHORTSECTOR (4) // Number of blocks in a short sector
58#define NR_BLOCK_OF_LONGSECTOR (16) // Number of blocks in a long sector
59
60// Determine the sector trailer block based on sector number
61#define BLOCK_NUMBER_OF_SECTOR_TRAILER(sector) (((sector)<NR_SHORTSECTOR)? \
62 ((sector)*NR_BLOCK_OF_SHORTSECTOR + NR_BLOCK_OF_SHORTSECTOR-1):\
63 (NR_SHORTSECTOR*NR_BLOCK_OF_SHORTSECTOR + (sector-NR_SHORTSECTOR)*NR_BLOCK_OF_LONGSECTOR + NR_BLOCK_OF_LONGSECTOR-1))
64
65// Determine the sector's first block based on the sector number
66#define BLOCK_NUMBER_OF_SECTOR_1ST_BLOCK(sector) (((sector)<NR_SHORTSECTOR)? \
67 ((sector)*NR_BLOCK_OF_SHORTSECTOR):\
68 (NR_SHORTSECTOR*NR_BLOCK_OF_SHORTSECTOR + (sector-NR_SHORTSECTOR)*NR_BLOCK_OF_LONGSECTOR))
69
70// The default Mifare Classic key
71static const uint8_t KEY_DEFAULT_KEYAB[6] = {0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
72
73
74void setup(void) {
75 Serial.begin(115200);
76 while (!Serial) delay(10); // for Leonardo/Micro/Zero
77
78 Serial.println("Looking for PN532...");
79
80 nfc.begin();
81
82 uint32_t versiondata = nfc.getFirmwareVersion();
83 if (! versiondata) {
84 Serial.print("Didn't find PN53x board");
85 while (1); // halt
86 }
87
88 // Got ok data, print it out!
89 Serial.print("Found chip PN5"); Serial.println((versiondata>>24) & 0xFF, HEX);
90 Serial.print("Firmware ver. "); Serial.print((versiondata>>16) & 0xFF, DEC);
91 Serial.print('.'); Serial.println((versiondata>>8) & 0xFF, DEC);
92}
93
94void loop(void) {
95 uint8_t success; // Flag to check if there was an error with the PN532
96 uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID
97 uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type)
98 uint8_t blockBuffer[16]; // Buffer to store block contents
99 uint8_t blankAccessBits[3] = { 0xff, 0x07, 0x80 };
100 uint8_t idx = 0;
101 uint8_t numOfSector = 16; // Assume Mifare Classic 1K for now (16 4-block sectors)
102
103 Serial.println("Place your NDEF formatted Mifare Classic 1K card on the reader");
104 Serial.println("and press any key to continue ...");
105
106 // Wait for user input before proceeding
107 while (!Serial.available());
108 while (Serial.available()) Serial.read();
109
110 // Wait for an ISO14443A type card (Mifare, etc.). When one is found
111 // 'uid' will be populated with the UID, and uidLength will indicate
112 // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight)
113 success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength);
114
115 if (success)
116 {
117 // We seem to have a tag ...
118 // Display some basic information about it
119 Serial.println("Found an ISO14443A card/tag");
120 Serial.print(" UID Length: ");Serial.print(uidLength, DEC);Serial.println(" bytes");
121 Serial.print(" UID Value: ");
122 nfc.PrintHex(uid, uidLength);
123 Serial.println("");
124
125 // Make sure this is a Mifare Classic card
126 if (uidLength != 4)
127 {
128 Serial.println("Ooops ... this doesn't seem to be a Mifare Classic card!");
129 return;
130 }
131
132 Serial.println("Seems to be a Mifare Classic card (4 byte UID)");
133 Serial.println("");
134 Serial.println("Reformatting card for Mifare Classic (please don't touch it!) ... ");
135
136 // Now run through the card sector by sector
137 for (idx = 0; idx < numOfSector; idx++)
138 {
139 // Step 1: Authenticate the current sector using key B 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
140 success = nfc.mifareclassic_AuthenticateBlock (uid, uidLength, BLOCK_NUMBER_OF_SECTOR_TRAILER(idx), 1, (uint8_t *)KEY_DEFAULT_KEYAB);
141 if (!success)
142 {
143 Serial.print("Authentication failed for sector "); Serial.println(numOfSector);
144 return;
145 }
146
147 // Step 2: Write to the other blocks
148 if (idx == 16)
149 {
150 memset(blockBuffer, 0, sizeof(blockBuffer));
151 if (!(nfc.mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 3, blockBuffer)))
152 {
153 Serial.print("Unable to write to sector "); Serial.println(numOfSector);
154 return;
155 }
156 }
157 if ((idx == 0) || (idx == 16))
158 {
159 memset(blockBuffer, 0, sizeof(blockBuffer));
160 if (!(nfc.mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 2, blockBuffer)))
161 {
162 Serial.print("Unable to write to sector "); Serial.println(numOfSector);
163 return;
164 }
165 }
166 else
167 {
168 memset(blockBuffer, 0, sizeof(blockBuffer));
169 if (!(nfc.mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 3, blockBuffer)))
170 {
171 Serial.print("Unable to write to sector "); Serial.println(numOfSector);
172 return;
173 }
174 if (!(nfc.mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 2, blockBuffer)))
175 {
176 Serial.print("Unable to write to sector "); Serial.println(numOfSector);
177 return;
178 }
179 }
180 memset(blockBuffer, 0, sizeof(blockBuffer));
181 if (!(nfc.mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)) - 1, blockBuffer)))
182 {
183 Serial.print("Unable to write to sector "); Serial.println(numOfSector);
184 return;
185 }
186
187 // Step 3: Reset both keys to 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF
188 memcpy(blockBuffer, KEY_DEFAULT_KEYAB, sizeof(KEY_DEFAULT_KEYAB));
189 memcpy(blockBuffer + 6, blankAccessBits, sizeof(blankAccessBits));
190 blockBuffer[9] = 0x69;
191 memcpy(blockBuffer + 10, KEY_DEFAULT_KEYAB, sizeof(KEY_DEFAULT_KEYAB));
192
193 // Step 4: Write the trailer block
194 if (!(nfc.mifareclassic_WriteDataBlock((BLOCK_NUMBER_OF_SECTOR_TRAILER(idx)), blockBuffer)))
195 {
196 Serial.print("Unable to write trailer block of sector "); Serial.println(numOfSector);
197 return;
198 }
199 }
200 }
201
202 // Wait a bit before trying again
203 Serial.println("\n\nDone!");
204 delay(1000);
205 Serial.flush();
206 while(Serial.available()) Serial.read();
207}