Krolyxon
Commit 3abfbfd

Branches

Tags

Refs →

orion-rflibAdafruit_PN532Adafruit_PN532.cpp

1832 lines · 61.8 KB · C++

1/**************************************************************************/
2/*!
3 @file Adafruit_PN532.cpp
4
5 @section intro_sec Introduction
6
7 Driver for NXP's PN532 NFC/13.56MHz RFID Transceiver
8
9 This is a library for the Adafruit PN532 NFC/RFID breakout boards
10 This library works with the Adafruit NFC breakout
11 ----> https://www.adafruit.com/products/364
12
13 Check out the links above for our tutorials and wiring diagrams
14 These chips use SPI or I2C to communicate.
15
16 Adafruit invests time and resources providing this open source code,
17 please support Adafruit and open-source hardware by purchasing
18 products from Adafruit!
19
20 @section author Author
21
22 Adafruit Industries
23
24 @section license License
25
26 BSD (see license.txt)
27
28 @section HISTORY
29
30 v2.2 - Added startPassiveTargetIDDetection() to start card detection and
31 readDetectedPassiveTargetID() to read it, useful when using the
32 IRQ pin.
33
34 v2.1 - Added NTAG2xx helper functions
35
36 v2.0 - Refactored to add I2C support from Adafruit_NFCShield_I2C library.
37
38 v1.4 - Added setPassiveActivationRetries()
39
40 v1.2 - Added writeGPIO()
41 - Added readGPIO()
42
43 v1.1 - Changed readPassiveTargetID() to handle multiple UID sizes
44 - Added the following helper functions for text display
45 static void PrintHex(const byte * data, const uint32_t numBytes)
46 static void PrintHexChar(const byte * pbtData, const uint32_t
47 numBytes)
48 - Added the following Mifare Classic functions:
49 bool mifareclassic_IsFirstBlock (uint32_t uiBlock)
50 bool mifareclassic_IsTrailerBlock (uint32_t uiBlock)
51 uint8_t mifareclassic_AuthenticateBlock (uint8_t * uid, uint8_t
52 uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t * keyData) uint8_t
53 mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t * data) uint8_t
54 mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t * data)
55 - Added the following Mifare Ultalight functions:
56 uint8_t mifareultralight_ReadPage (uint8_t page, uint8_t * buffer)
57*/
58/**************************************************************************/
59
60#include "Adafruit_PN532.h"
61
62byte pn532ack[] = {0x00, 0x00, 0xFF,
63 0x00, 0xFF, 0x00}; ///< ACK message from PN532
64byte pn532response_firmwarevers[] = {
65 0x00, 0x00, 0xFF,
66 0x06, 0xFA, 0xD5}; ///< Expected firmware version message from PN532
67
68// Uncomment these lines to enable debug output for PN532(SPI) and/or MIFARE
69// related code
70
71// #define PN532DEBUG
72// #define MIFAREDEBUG
73
74// If using Native Port on Arduino Zero or Due define as SerialUSB
75#define PN532DEBUGPRINT Serial ///< Fixed name for debug Serial instance
76// #define PN532DEBUGPRINT SerialUSB ///< Fixed name for debug Serial instance
77
78#define PN532_PACKBUFFSIZ 64 ///< Packet buffer size in bytes
79byte pn532_packetbuffer[PN532_PACKBUFFSIZ]; ///< Packet buffer used in various
80 ///< transactions
81
82/**************************************************************************/
83/*!
84 @brief Instantiates a new PN532 class using software SPI.
85
86 @param clk SPI clock pin (SCK)
87 @param miso SPI MISO pin
88 @param mosi SPI MOSI pin
89 @param ss SPI chip select pin (CS/SSEL)
90*/
91/**************************************************************************/
92Adafruit_PN532::Adafruit_PN532(uint8_t clk, uint8_t miso, uint8_t mosi,
93 uint8_t ss) {
94 _cs = ss;
95 spi_dev = new Adafruit_SPIDevice(ss, clk, miso, mosi, 1000000,
96 SPI_BITORDER_LSBFIRST, SPI_MODE0);
97}
98
99/**************************************************************************/
100/*!
101 @brief Instantiates a new PN532 class using I2C.
102
103 @param irq Location of the IRQ pin
104 @param reset Location of the RSTPD_N pin
105 @param theWire pointer to I2C bus to use
106*/
107/**************************************************************************/
108Adafruit_PN532::Adafruit_PN532(uint8_t irq, uint8_t reset, TwoWire *theWire)
109 : _irq(irq), _reset(reset) {
110 pinMode(_irq, INPUT);
111 pinMode(_reset, OUTPUT);
112 i2c_dev = new Adafruit_I2CDevice(PN532_I2C_ADDRESS, theWire);
113}
114
115/**************************************************************************/
116/*!
117 @brief Instantiates a new PN532 class using hardware SPI.
118
119 @param ss SPI chip select pin (CS/SSEL)
120 @param theSPI pointer to the SPI bus to use
121*/
122/**************************************************************************/
123Adafruit_PN532::Adafruit_PN532(uint8_t ss, SPIClass *theSPI) {
124 _cs = ss;
125 spi_dev = new Adafruit_SPIDevice(ss, 1000000, SPI_BITORDER_LSBFIRST,
126 SPI_MODE0, theSPI);
127}
128
129/**************************************************************************/
130/*!
131 @brief Instantiates a new PN532 class using hardware UART (HSU).
132
133 @param reset Location of the RSTPD_N pin
134 @param theSer pointer to HardWare Serial bus to use
135*/
136/**************************************************************************/
137Adafruit_PN532::Adafruit_PN532(uint8_t reset, HardwareSerial *theSer)
138 : _reset(reset) {
139 pinMode(_reset, OUTPUT);
140 ser_dev = theSer;
141}
142
143/**************************************************************************/
144/*!
145 @brief Setups the HW
146
147 @returns true if successful, otherwise false
148*/
149/**************************************************************************/
150bool Adafruit_PN532::begin() {
151 if (spi_dev) {
152 // SPI initialization
153 if (!spi_dev->begin()) {
154 return false;
155 }
156 } else if (i2c_dev) {
157 // I2C initialization
158 // PN532 will fail address check since its asleep, so suppress
159 if (!i2c_dev->begin(false)) {
160 return false;
161 }
162 } else if (ser_dev) {
163 ser_dev->begin(115200);
164 // clear out anything in read buffer
165 while (ser_dev->available())
166 ser_dev->read();
167 } else {
168 // no interface specified
169 return false;
170 }
171 reset(); // HW reset - put in known state
172 delay(10);
173 wakeup(); // hey! wakeup!
174 return true;
175}
176
177/**************************************************************************/
178/*!
179 @brief Perform a hardware reset. Requires reset pin to have been provided.
180*/
181/**************************************************************************/
182void Adafruit_PN532::reset(void) {
183 // see Datasheet p.209, Fig.48 for timings
184 if (_reset != -1) {
185 digitalWrite(_reset, LOW);
186 delay(1); // min 20ns
187 digitalWrite(_reset, HIGH);
188 delay(2); // max 2ms
189 }
190}
191
192/**************************************************************************/
193/*!
194 @brief Wakeup from LowVbat mode into Normal Mode.
195*/
196/**************************************************************************/
197void Adafruit_PN532::wakeup(void) {
198 // interface specific wakeups - each one is unique!
199 if (spi_dev) {
200 // hold CS low for 2ms
201 digitalWrite(_cs, LOW);
202 delay(2);
203 } else if (ser_dev) {
204 uint8_t w[3] = {0x55, 0x00, 0x00};
205 ser_dev->write(w, 3);
206 delay(2);
207 }
208
209 // PN532 will clock stretch I2C during SAMConfig as a "wakeup"
210
211 // need to config SAM to stay in Normal Mode
212 SAMConfig();
213}
214
215/**************************************************************************/
216/*!
217 @brief Prints a hexadecimal value in plain characters
218
219 @param data Pointer to the byte data
220 @param numBytes Data length in bytes
221*/
222/**************************************************************************/
223void Adafruit_PN532::PrintHex(const byte *data, const uint32_t numBytes) {
224 uint32_t szPos;
225 for (szPos = 0; szPos < numBytes; szPos++) {
226 PN532DEBUGPRINT.print(F("0x"));
227 // Append leading 0 for small values
228 if (data[szPos] <= 0xF)
229 PN532DEBUGPRINT.print(F("0"));
230 PN532DEBUGPRINT.print(data[szPos] & 0xff, HEX);
231 if ((numBytes > 1) && (szPos != numBytes - 1)) {
232 PN532DEBUGPRINT.print(F(" "));
233 }
234 }
235 PN532DEBUGPRINT.println();
236}
237
238/**************************************************************************/
239/*!
240 @brief Prints a hexadecimal value in plain characters, along with
241 the char equivalents in the following format
242
243 00 00 00 00 00 00 ......
244
245 @param data Pointer to the byte data
246 @param numBytes Data length in bytes
247*/
248/**************************************************************************/
249void Adafruit_PN532::PrintHexChar(const byte *data, const uint32_t numBytes) {
250 uint32_t szPos;
251 for (szPos = 0; szPos < numBytes; szPos++) {
252 // Append leading 0 for small values
253 if (data[szPos] <= 0xF)
254 PN532DEBUGPRINT.print(F("0"));
255 PN532DEBUGPRINT.print(data[szPos], HEX);
256 if ((numBytes > 1) && (szPos != numBytes - 1)) {
257 PN532DEBUGPRINT.print(F(" "));
258 }
259 }
260 PN532DEBUGPRINT.print(F(" "));
261 for (szPos = 0; szPos < numBytes; szPos++) {
262 if (data[szPos] <= 0x1F)
263 PN532DEBUGPRINT.print(F("."));
264 else
265 PN532DEBUGPRINT.print((char)data[szPos]);
266 }
267 PN532DEBUGPRINT.println();
268}
269
270/**************************************************************************/
271/*!
272 @brief Checks the firmware version of the PN5xx chip
273
274 @returns The chip's firmware version and ID
275*/
276/**************************************************************************/
277uint32_t Adafruit_PN532::getFirmwareVersion(void) {
278 uint32_t response;
279
280 pn532_packetbuffer[0] = PN532_COMMAND_GETFIRMWAREVERSION;
281
282 if (!sendCommandCheckAck(pn532_packetbuffer, 1)) {
283 return 0;
284 }
285
286 // read data packet
287 readdata(pn532_packetbuffer, 13);
288
289 // check some basic stuff
290 if (0 != memcmp((char *)pn532_packetbuffer,
291 (char *)pn532response_firmwarevers, 6)) {
292#ifdef PN532DEBUG
293 PN532DEBUGPRINT.println(F("Firmware doesn't match!"));
294#endif
295 return 0;
296 }
297
298 int offset = 7;
299 response = pn532_packetbuffer[offset++];
300 response <<= 8;
301 response |= pn532_packetbuffer[offset++];
302 response <<= 8;
303 response |= pn532_packetbuffer[offset++];
304 response <<= 8;
305 response |= pn532_packetbuffer[offset++];
306
307 return response;
308}
309
310/**************************************************************************/
311/*!
312 @brief Sends a command and waits a specified period for the ACK
313
314 @param cmd Pointer to the command buffer
315 @param cmdlen The size of the command in bytes
316 @param timeout timeout before giving up
317
318 @returns 1 if everything is OK, 0 if timeout occured before an
319 ACK was recieved
320*/
321/**************************************************************************/
322// default timeout of one second
323bool Adafruit_PN532::sendCommandCheckAck(uint8_t *cmd, uint8_t cmdlen,
324 uint16_t timeout) {
325
326 // I2C works without using IRQ pin by polling for RDY byte
327 // seems to work best with some delays between transactions
328 uint8_t SLOWDOWN = 0;
329 if (i2c_dev || spi_dev) // SPI and I2C need 1ms slow for page reads
330 SLOWDOWN = 1;
331
332 // write the command
333 writecommand(cmd, cmdlen);
334
335 // I2C TUNING
336 delay(SLOWDOWN);
337
338 // Wait for chip to say its ready!
339 if (!waitready(timeout)) {
340 return false;
341 }
342
343#ifdef PN532DEBUG
344 if (spi_dev == NULL) {
345 PN532DEBUGPRINT.println(F("IRQ received"));
346 }
347#endif
348
349 // read acknowledgement
350 if (!readack()) {
351#ifdef PN532DEBUG
352 PN532DEBUGPRINT.println(F("No ACK frame received!"));
353#endif
354 return false;
355 }
356
357 // I2C TUNING
358 delay(SLOWDOWN);
359
360 // Wait for chip to say its ready!
361 if (!waitready(timeout)) {
362 return false;
363 }
364
365 return true; // ack'd command
366}
367
368/**************************************************************************/
369/*!
370 @brief Writes an 8-bit value that sets the state of the PN532's GPIO
371 pins.
372 @param pinstate P3 pins state.
373
374 @warning This function is provided exclusively for board testing and
375 is dangerous since it will throw an error if any pin other
376 than the ones marked "Can be used as GPIO" are modified! All
377 pins that can not be used as GPIO should ALWAYS be left high
378 (value = 1) or the system will become unstable and a HW reset
379 will be required to recover the PN532.
380
381 pinState[0] = P30 Can be used as GPIO
382 pinState[1] = P31 Can be used as GPIO
383 pinState[2] = P32 *** RESERVED (Must be 1!) ***
384 pinState[3] = P33 Can be used as GPIO
385 pinState[4] = P34 *** RESERVED (Must be 1!) ***
386 pinState[5] = P35 Can be used as GPIO
387
388 @return 1 if everything executed properly, 0 for an error
389*/
390/**************************************************************************/
391bool Adafruit_PN532::writeGPIO(uint8_t pinstate) {
392 // uint8_t errorbit;
393
394 // Make sure pinstate does not try to toggle P32 or P34
395 pinstate |= (1 << PN532_GPIO_P32) | (1 << PN532_GPIO_P34);
396
397 // Fill command buffer
398 pn532_packetbuffer[0] = PN532_COMMAND_WRITEGPIO;
399 pn532_packetbuffer[1] = PN532_GPIO_VALIDATIONBIT | pinstate; // P3 Pins
400 pn532_packetbuffer[2] = 0x00; // P7 GPIO Pins (not used ... taken by SPI)
401
402#ifdef PN532DEBUG
403 PN532DEBUGPRINT.print(F("Writing P3 GPIO: "));
404 PN532DEBUGPRINT.println(pn532_packetbuffer[1], HEX);
405#endif
406
407 // Send the WRITEGPIO command (0x0E)
408 if (!sendCommandCheckAck(pn532_packetbuffer, 3))
409 return 0x0;
410
411 // Read response packet (00 FF PLEN PLENCHECKSUM D5 CMD+1(0x0F) DATACHECKSUM
412 // 00)
413 readdata(pn532_packetbuffer, 8);
414
415#ifdef PN532DEBUG
416 PN532DEBUGPRINT.print(F("Received: "));
417 PrintHex(pn532_packetbuffer, 8);
418 PN532DEBUGPRINT.println();
419#endif
420
421 int offset = 6;
422 return (pn532_packetbuffer[offset] == 0x0F);
423}
424
425/**************************************************************************/
426/*!
427 Reads the state of the PN532's GPIO pins
428
429 @returns An 8-bit value containing the pin state where:
430
431 pinState[0] = P30
432 pinState[1] = P31
433 pinState[2] = P32
434 pinState[3] = P33
435 pinState[4] = P34
436 pinState[5] = P35
437*/
438/**************************************************************************/
439uint8_t Adafruit_PN532::readGPIO(void) {
440 pn532_packetbuffer[0] = PN532_COMMAND_READGPIO;
441
442 // Send the READGPIO command (0x0C)
443 if (!sendCommandCheckAck(pn532_packetbuffer, 1))
444 return 0x0;
445
446 // Read response packet (00 FF PLEN PLENCHECKSUM D5 CMD+1(0x0D) P3 P7 IO1
447 // DATACHECKSUM 00)
448 readdata(pn532_packetbuffer, 11);
449
450 /* READGPIO response should be in the following format:
451
452 byte Description
453 ------------- ------------------------------------------
454 b0..5 Frame header and preamble (with I2C there is an extra
455 0x00) b6 P3 GPIO Pins b7 P7 GPIO Pins (not used
456 ... taken by SPI) b8 Interface Mode Pins (not used ... bus
457 select pins) b9..10 checksum */
458
459 int p3offset = 7;
460
461#ifdef PN532DEBUG
462 PN532DEBUGPRINT.print(F("Received: "));
463 PrintHex(pn532_packetbuffer, 11);
464 PN532DEBUGPRINT.println();
465 PN532DEBUGPRINT.print(F("P3 GPIO: 0x"));
466 PN532DEBUGPRINT.println(pn532_packetbuffer[p3offset], HEX);
467 PN532DEBUGPRINT.print(F("P7 GPIO: 0x"));
468 PN532DEBUGPRINT.println(pn532_packetbuffer[p3offset + 1], HEX);
469 PN532DEBUGPRINT.print(F("IO GPIO: 0x"));
470 PN532DEBUGPRINT.println(pn532_packetbuffer[p3offset + 2], HEX);
471 // Note: You can use the IO GPIO value to detect the serial bus being used
472 switch (pn532_packetbuffer[p3offset + 2]) {
473 case 0x00: // Using UART
474 PN532DEBUGPRINT.println(F("Using UART (IO = 0x00)"));
475 break;
476 case 0x01: // Using I2C
477 PN532DEBUGPRINT.println(F("Using I2C (IO = 0x01)"));
478 break;
479 case 0x02: // Using SPI
480 PN532DEBUGPRINT.println(F("Using SPI (IO = 0x02)"));
481 break;
482 }
483#endif
484
485 return pn532_packetbuffer[p3offset];
486}
487
488/**************************************************************************/
489/*!
490 @brief Configures the SAM (Secure Access Module)
491 @return true on success, false otherwise.
492*/
493/**************************************************************************/
494bool Adafruit_PN532::SAMConfig(void) {
495 pn532_packetbuffer[0] = PN532_COMMAND_SAMCONFIGURATION;
496 pn532_packetbuffer[1] = 0x01; // normal mode;
497 pn532_packetbuffer[2] = 0x14; // timeout 50ms * 20 = 1 second
498 pn532_packetbuffer[3] = 0x01; // use IRQ pin!
499
500 if (!sendCommandCheckAck(pn532_packetbuffer, 4))
501 return false;
502
503 // read data packet
504 readdata(pn532_packetbuffer, 9);
505
506 int offset = 6;
507 return (pn532_packetbuffer[offset] == 0x15);
508}
509
510/**************************************************************************/
511/*!
512 Sets the MxRtyPassiveActivation byte of the RFConfiguration register
513
514 @param maxRetries 0xFF to wait forever, 0x00..0xFE to timeout
515 after mxRetries
516
517 @returns 1 if everything executed properly, 0 for an error
518*/
519/**************************************************************************/
520bool Adafruit_PN532::setPassiveActivationRetries(uint8_t maxRetries) {
521 pn532_packetbuffer[0] = PN532_COMMAND_RFCONFIGURATION;
522 pn532_packetbuffer[1] = 5; // Config item 5 (MaxRetries)
523 pn532_packetbuffer[2] = 0xFF; // MxRtyATR (default = 0xFF)
524 pn532_packetbuffer[3] = 0x01; // MxRtyPSL (default = 0x01)
525 pn532_packetbuffer[4] = maxRetries;
526
527#ifdef MIFAREDEBUG
528 PN532DEBUGPRINT.print(F("Setting MxRtyPassiveActivation to "));
529 PN532DEBUGPRINT.print(maxRetries, DEC);
530 PN532DEBUGPRINT.println(F(" "));
531#endif
532
533 if (!sendCommandCheckAck(pn532_packetbuffer, 5))
534 return 0x0; // no ACK
535
536 return 1;
537}
538
539/***** ISO14443A Commands ******/
540
541/**************************************************************************/
542/*!
543 @brief Waits for an ISO14443A target to enter the field and reads
544 its ID.
545
546 @param cardbaudrate Baud rate of the card
547 @param uid Pointer to the array that will be populated
548 with the card's UID (up to 7 bytes)
549 @param uidLength Pointer to the variable that will hold the
550 length of the card's UID.
551 @param timeout Timeout in milliseconds.
552
553 @return 1 if everything executed properly, 0 for an error
554*/
555/**************************************************************************/
556bool Adafruit_PN532::readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid,
557 uint8_t *uidLength, uint16_t timeout) {
558 pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
559 pn532_packetbuffer[1] =
560 1; // max 1 cards at once (we can set this to 2 later)
561 pn532_packetbuffer[2] = cardbaudrate;
562
563 if (!sendCommandCheckAck(pn532_packetbuffer, 3, timeout)) {
564#ifdef PN532DEBUG
565 PN532DEBUGPRINT.println(F("No card(s) read"));
566#endif
567 return 0x0; // no cards read
568 }
569
570 return readDetectedPassiveTargetID(uid, uidLength);
571}
572
573/**************************************************************************/
574/*!
575 @brief Put the reader in detection mode, non blocking so interrupts
576 must be enabled.
577 @param cardbaudrate Baud rate of the card
578 @return 1 if everything executed properly, 0 for an error
579*/
580/**************************************************************************/
581bool Adafruit_PN532::startPassiveTargetIDDetection(uint8_t cardbaudrate) {
582 pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
583 pn532_packetbuffer[1] =
584 1; // max 1 cards at once (we can set this to 2 later)
585 pn532_packetbuffer[2] = cardbaudrate;
586
587 return sendCommandCheckAck(pn532_packetbuffer, 3);
588}
589
590/**************************************************************************/
591/*!
592 Reads the ID of the passive target the reader has deteceted.
593
594 @param uid Pointer to the array that will be populated
595 with the card's UID (up to 7 bytes)
596 @param uidLength Pointer to the variable that will hold the
597 length of the card's UID.
598
599 @returns 1 if everything executed properly, 0 for an error
600*/
601/**************************************************************************/
602bool Adafruit_PN532::readDetectedPassiveTargetID(uint8_t *uid,
603 uint8_t *uidLength) {
604 // read data packet
605 readdata(pn532_packetbuffer, 20);
606 // check some basic stuff
607
608 /* ISO14443A card response should be in the following format:
609
610 byte Description
611 ------------- ------------------------------------------
612 b0..6 Frame header and preamble
613 b7 Tags Found
614 b8 Tag Number (only one used in this example)
615 b9..10 SENS_RES
616 b11 SEL_RES
617 b12 NFCID Length
618 b13..NFCIDLen NFCID */
619
620#ifdef MIFAREDEBUG
621 PN532DEBUGPRINT.print(F("Found "));
622 PN532DEBUGPRINT.print(pn532_packetbuffer[7], DEC);
623 PN532DEBUGPRINT.println(F(" tags"));
624#endif
625 if (pn532_packetbuffer[7] != 1)
626 return 0;
627
628 uint16_t sens_res = pn532_packetbuffer[9];
629 sens_res <<= 8;
630 sens_res |= pn532_packetbuffer[10];
631#ifdef MIFAREDEBUG
632 PN532DEBUGPRINT.print(F("ATQA: 0x"));
633 PN532DEBUGPRINT.println(sens_res, HEX);
634 PN532DEBUGPRINT.print(F("SAK: 0x"));
635 PN532DEBUGPRINT.println(pn532_packetbuffer[11], HEX);
636#endif
637
638 /* Card appears to be Mifare Classic */
639 *uidLength = pn532_packetbuffer[12];
640#ifdef MIFAREDEBUG
641 PN532DEBUGPRINT.print(F("UID:"));
642#endif
643 for (uint8_t i = 0; i < pn532_packetbuffer[12]; i++) {
644 uid[i] = pn532_packetbuffer[13 + i];
645#ifdef MIFAREDEBUG
646 PN532DEBUGPRINT.print(F(" 0x"));
647 PN532DEBUGPRINT.print(uid[i], HEX);
648#endif
649 }
650#ifdef MIFAREDEBUG
651 PN532DEBUGPRINT.println();
652#endif
653
654 return 1;
655}
656
657/**************************************************************************/
658/*!
659 @brief Exchanges an APDU with the currently inlisted peer
660
661 @param send Pointer to data to send
662 @param sendLength Length of the data to send
663 @param response Pointer to response data
664 @param responseLength Pointer to the response data length
665 @return true on success, false otherwise.
666*/
667/**************************************************************************/
668bool Adafruit_PN532::inDataExchange(uint8_t *send, uint8_t sendLength,
669 uint8_t *response,
670 uint8_t *responseLength) {
671 if (sendLength > PN532_PACKBUFFSIZ - 2) {
672#ifdef PN532DEBUG
673 PN532DEBUGPRINT.println(F("APDU length too long for packet buffer"));
674#endif
675 return false;
676 }
677 uint8_t i;
678
679 pn532_packetbuffer[0] = 0x40; // PN532_COMMAND_INDATAEXCHANGE;
680 pn532_packetbuffer[1] = _inListedTag;
681 for (i = 0; i < sendLength; ++i) {
682 pn532_packetbuffer[i + 2] = send[i];
683 }
684
685 if (!sendCommandCheckAck(pn532_packetbuffer, sendLength + 2, 1000)) {
686#ifdef PN532DEBUG
687 PN532DEBUGPRINT.println(F("Could not send APDU"));
688#endif
689 return false;
690 }
691
692 if (!waitready(1000)) {
693#ifdef PN532DEBUG
694 PN532DEBUGPRINT.println(F("Response never received for APDU..."));
695#endif
696 return false;
697 }
698
699 readdata(pn532_packetbuffer, sizeof(pn532_packetbuffer));
700
701 if (pn532_packetbuffer[0] == 0 && pn532_packetbuffer[1] == 0 &&
702 pn532_packetbuffer[2] == 0xff) {
703 uint8_t length = pn532_packetbuffer[3];
704 if (pn532_packetbuffer[4] != (uint8_t)(~length + 1)) {
705#ifdef PN532DEBUG
706 PN532DEBUGPRINT.println(F("Length check invalid"));
707 PN532DEBUGPRINT.println(length, HEX);
708 PN532DEBUGPRINT.println((~length) + 1, HEX);
709#endif
710 return false;
711 }
712 if (pn532_packetbuffer[5] == PN532_PN532TOHOST &&
713 pn532_packetbuffer[6] == PN532_RESPONSE_INDATAEXCHANGE) {
714 if ((pn532_packetbuffer[7] & 0x3f) != 0) {
715#ifdef PN532DEBUG
716 PN532DEBUGPRINT.println(F("Status code indicates an error"));
717#endif
718 return false;
719 }
720
721 length -= 3;
722
723 if (length > *responseLength) {
724 length = *responseLength; // silent truncation...
725 }
726
727 for (i = 0; i < length; ++i) {
728 response[i] = pn532_packetbuffer[8 + i];
729 }
730 *responseLength = length;
731
732 return true;
733 } else {
734 PN532DEBUGPRINT.print(F("Don't know how to handle this command: "));
735 PN532DEBUGPRINT.println(pn532_packetbuffer[6], HEX);
736 return false;
737 }
738 } else {
739 PN532DEBUGPRINT.println(F("Preamble missing"));
740 return false;
741 }
742}
743
744/**************************************************************************/
745/*!
746 @brief 'InLists' a passive target. PN532 acting as reader/initiator,
747 peer acting as card/responder.
748 @return true on success, false otherwise.
749*/
750/**************************************************************************/
751bool Adafruit_PN532::inListPassiveTarget() {
752 pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
753 pn532_packetbuffer[1] = 1;
754 pn532_packetbuffer[2] = 0;
755
756#ifdef PN532DEBUG
757 PN532DEBUGPRINT.print(F("About to inList passive target"));
758#endif
759
760 if (!sendCommandCheckAck(pn532_packetbuffer, 3, 1000)) {
761#ifdef PN532DEBUG
762 PN532DEBUGPRINT.println(F("Could not send inlist message"));
763#endif
764 return false;
765 }
766
767 if (!waitready(30000)) {
768 return false;
769 }
770
771 readdata(pn532_packetbuffer, sizeof(pn532_packetbuffer));
772
773 if (pn532_packetbuffer[0] == 0 && pn532_packetbuffer[1] == 0 &&
774 pn532_packetbuffer[2] == 0xff) {
775 uint8_t length = pn532_packetbuffer[3];
776 if (pn532_packetbuffer[4] != (uint8_t)(~length + 1)) {
777#ifdef PN532DEBUG
778 PN532DEBUGPRINT.println(F("Length check invalid"));
779 PN532DEBUGPRINT.println(length, HEX);
780 PN532DEBUGPRINT.println((~length) + 1, HEX);
781#endif
782 return false;
783 }
784 if (pn532_packetbuffer[5] == PN532_PN532TOHOST &&
785 pn532_packetbuffer[6] == PN532_RESPONSE_INLISTPASSIVETARGET) {
786 if (pn532_packetbuffer[7] != 1) {
787#ifdef PN532DEBUG
788 PN532DEBUGPRINT.println(
789 F("Unhandled number of targets inlisted"));
790#endif
791 PN532DEBUGPRINT.println(F("Number of tags inlisted:"));
792 PN532DEBUGPRINT.println(pn532_packetbuffer[7]);
793 return false;
794 }
795
796 _inListedTag = pn532_packetbuffer[8];
797 PN532DEBUGPRINT.print(F("Tag number: "));
798 PN532DEBUGPRINT.println(_inListedTag);
799
800 return true;
801 } else {
802#ifdef PN532DEBUG
803 PN532DEBUGPRINT.print(
804 F("Unexpected response to inlist passive host"));
805#endif
806 return false;
807 }
808 } else {
809#ifdef PN532DEBUG
810 PN532DEBUGPRINT.println(F("Preamble missing"));
811#endif
812 return false;
813 }
814
815 return true;
816}
817
818/***** Mifare Classic Functions ******/
819
820/**************************************************************************/
821/*!
822 @brief Indicates whether the specified block number is the first block
823 in the sector (block 0 relative to the current sector)
824 @param uiBlock Block number to test.
825 @return true if first block, false otherwise.
826*/
827/**************************************************************************/
828bool Adafruit_PN532::mifareclassic_IsFirstBlock(uint32_t uiBlock) {
829 // Test if we are in the small or big sectors
830 if (uiBlock < 128)
831 return ((uiBlock) % 4 == 0);
832 else
833 return ((uiBlock) % 16 == 0);
834}
835
836/**************************************************************************/
837/*!
838 @brief Indicates whether the specified block number is the sector
839 trailer.
840 @param uiBlock Block number to test.
841 @return true if sector trailer, false otherwise.
842*/
843/**************************************************************************/
844bool Adafruit_PN532::mifareclassic_IsTrailerBlock(uint32_t uiBlock) {
845 // Test if we are in the small or big sectors
846 if (uiBlock < 128)
847 return ((uiBlock + 1) % 4 == 0);
848 else
849 return ((uiBlock + 1) % 16 == 0);
850}
851
852/**************************************************************************/
853/*!
854 Tries to authenticate a block of memory on a MIFARE card using the
855 INDATAEXCHANGE command. See section 7.3.8 of the PN532 User Manual
856 for more information on sending MIFARE and other commands.
857
858 @param uid Pointer to a byte array containing the card UID
859 @param uidLen The length (in bytes) of the card's UID (Should
860 be 4 for MIFARE Classic)
861 @param blockNumber The block number to authenticate. (0..63 for
862 1KB cards, and 0..255 for 4KB cards).
863 @param keyNumber Which key type to use during authentication
864 (0 = MIFARE_CMD_AUTH_A, 1 = MIFARE_CMD_AUTH_B)
865 @param keyData Pointer to a byte array containing the 6 byte
866 key value
867
868 @returns 1 if everything executed properly, 0 for an error
869*/
870/**************************************************************************/
871uint8_t Adafruit_PN532::mifareclassic_AuthenticateBlock(uint8_t *uid,
872 uint8_t uidLen,
873 uint32_t blockNumber,
874 uint8_t keyNumber,
875 uint8_t *keyData) {
876 // uint8_t len;
877 uint8_t i;
878
879 // Hang on to the key and uid data
880 memcpy(_key, keyData, 6);
881 memcpy(_uid, uid, uidLen);
882 _uidLen = uidLen;
883
884#ifdef MIFAREDEBUG
885 PN532DEBUGPRINT.print(F("Trying to authenticate card "));
886 Adafruit_PN532::PrintHex(_uid, _uidLen);
887 PN532DEBUGPRINT.print(F("Using authentication KEY "));
888 PN532DEBUGPRINT.print(keyNumber ? 'B' : 'A');
889 PN532DEBUGPRINT.print(F(": "));
890 Adafruit_PN532::PrintHex(_key, 6);
891#endif
892
893 // Prepare the authentication command //
894 pn532_packetbuffer[0] =
895 PN532_COMMAND_INDATAEXCHANGE; /* Data Exchange Header */
896 pn532_packetbuffer[1] = 1; /* Max card numbers */
897 pn532_packetbuffer[2] = (keyNumber) ? MIFARE_CMD_AUTH_B : MIFARE_CMD_AUTH_A;
898 pn532_packetbuffer[3] =
899 blockNumber; /* Block Number (1K = 0..63, 4K = 0..255 */
900 memcpy(pn532_packetbuffer + 4, _key, 6);
901 for (i = 0; i < _uidLen; i++) {
902 pn532_packetbuffer[10 + i] = _uid[i]; /* 4 byte card ID */
903 }
904
905 if (!sendCommandCheckAck(pn532_packetbuffer, 10 + _uidLen))
906 return 0;
907
908 // Read the response packet
909 readdata(pn532_packetbuffer, 12);
910
911 // check if the response is valid and we are authenticated???
912 // for an auth success it should be bytes 5-7: 0xD5 0x41 0x00
913 // Mifare auth error is technically byte 7: 0x14 but anything other and 0x00
914 // is not good
915 if (pn532_packetbuffer[7] != 0x00) {
916#ifdef PN532DEBUG
917 PN532DEBUGPRINT.print(F("Authentification failed: "));
918 Adafruit_PN532::PrintHexChar(pn532_packetbuffer, 12);
919#endif
920 return 0;
921 }
922
923 return 1;
924}
925
926/**************************************************************************/
927/*!
928 Tries to read an entire 16-byte data block at the specified block
929 address.
930
931 @param blockNumber The block number to authenticate. (0..63 for
932 1KB cards, and 0..255 for 4KB cards).
933 @param data Pointer to the byte array that will hold the
934 retrieved data (if any)
935
936 @returns 1 if everything executed properly, 0 for an error
937*/
938/**************************************************************************/
939uint8_t Adafruit_PN532::mifareclassic_ReadDataBlock(uint8_t blockNumber,
940 uint8_t *data) {
941#ifdef MIFAREDEBUG
942 PN532DEBUGPRINT.print(F("Trying to read 16 bytes from block "));
943 PN532DEBUGPRINT.println(blockNumber);
944#endif
945
946 /* Prepare the command */
947 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
948 pn532_packetbuffer[1] = 1; /* Card number */
949 pn532_packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
950 pn532_packetbuffer[3] =
951 blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
952
953 /* Send the command */
954 if (!sendCommandCheckAck(pn532_packetbuffer, 4)) {
955#ifdef MIFAREDEBUG
956 PN532DEBUGPRINT.println(F("Failed to receive ACK for read command"));
957#endif
958 return 0;
959 }
960
961 /* Read the response packet */
962 readdata(pn532_packetbuffer, 26);
963
964 /* If byte 8 isn't 0x00 we probably have an error */
965 if (pn532_packetbuffer[7] != 0x00) {
966#ifdef MIFAREDEBUG
967 PN532DEBUGPRINT.println(F("Unexpected response"));
968 Adafruit_PN532::PrintHexChar(pn532_packetbuffer, 26);
969#endif
970 return 0;
971 }
972
973 /* Copy the 16 data bytes to the output buffer */
974 /* Block content starts at byte 9 of a valid response */
975 memcpy(data, pn532_packetbuffer + 8, 16);
976
977/* Display data for debug if requested */
978#ifdef MIFAREDEBUG
979 PN532DEBUGPRINT.print(F("Block "));
980 PN532DEBUGPRINT.println(blockNumber);
981 Adafruit_PN532::PrintHexChar(data, 16);
982#endif
983
984 return 1;
985}
986
987/**************************************************************************/
988/*!
989 Tries to write an entire 16-byte data block at the specified block
990 address.
991
992 @param blockNumber The block number to authenticate. (0..63 for
993 1KB cards, and 0..255 for 4KB cards).
994 @param data The byte array that contains the data to write.
995
996 @returns 1 if everything executed properly, 0 for an error
997*/
998/**************************************************************************/
999uint8_t Adafruit_PN532::mifareclassic_WriteDataBlock(uint8_t blockNumber,
1000 uint8_t *data) {
1001#ifdef MIFAREDEBUG
1002 PN532DEBUGPRINT.print(F("Trying to write 16 bytes to block "));
1003 PN532DEBUGPRINT.println(blockNumber);
1004#endif
1005
1006 /* Prepare the first command */
1007 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
1008 pn532_packetbuffer[1] = 1; /* Card number */
1009 pn532_packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */
1010 pn532_packetbuffer[3] =
1011 blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
1012 memcpy(pn532_packetbuffer + 4, data, 16); /* Data Payload */
1013
1014 /* Send the command */
1015 if (!sendCommandCheckAck(pn532_packetbuffer, 20)) {
1016#ifdef MIFAREDEBUG
1017 PN532DEBUGPRINT.println(F("Failed to receive ACK for write command"));
1018#endif
1019 return 0;
1020 }
1021 delay(10);
1022
1023 /* Read the response packet */
1024 readdata(pn532_packetbuffer, 26);
1025
1026 return 1;
1027}
1028
1029/**************************************************************************/
1030/*!
1031 Formats a Mifare Classic card to store NDEF Records
1032
1033 @returns 1 if everything executed properly, 0 for an error
1034*/
1035/**************************************************************************/
1036uint8_t Adafruit_PN532::mifareclassic_FormatNDEF(void) {
1037 uint8_t sectorbuffer1[16] = {0x14, 0x01, 0x03, 0xE1, 0x03, 0xE1,
1038 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1,
1039 0x03, 0xE1, 0x03, 0xE1};
1040 uint8_t sectorbuffer2[16] = {0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1,
1041 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1,
1042 0x03, 0xE1, 0x03, 0xE1};
1043 uint8_t sectorbuffer3[16] = {0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5,
1044 0x78, 0x77, 0x88, 0xC1, 0xFF, 0xFF,
1045 0xFF, 0xFF, 0xFF, 0xFF};
1046
1047 // Note 0xA0 0xA1 0xA2 0xA3 0xA4 0xA5 must be used for key A
1048 // for the MAD sector in NDEF records (sector 0)
1049
1050 // Write block 1 and 2 to the card
1051 if (!(mifareclassic_WriteDataBlock(1, sectorbuffer1)))
1052 return 0;
1053 if (!(mifareclassic_WriteDataBlock(2, sectorbuffer2)))
1054 return 0;
1055 // Write key A and access rights card
1056 if (!(mifareclassic_WriteDataBlock(3, sectorbuffer3)))
1057 return 0;
1058
1059 // Seems that everything was OK (?!)
1060 return 1;
1061}
1062
1063/**************************************************************************/
1064/*!
1065 Writes an NDEF URI Record to the specified sector (1..15)
1066
1067 Note that this function assumes that the Mifare Classic card is
1068 already formatted to work as an "NFC Forum Tag" and uses a MAD1
1069 file system. You can use the NXP TagWriter app on Android to
1070 properly format cards for this.
1071
1072 @param sectorNumber The sector that the URI record should be written
1073 to (can be 1..15 for a 1K card)
1074 @param uriIdentifier The uri identifier code (0 = none, 0x01 =
1075 "http://www.", etc.)
1076 @param url The uri text to write (max 38 characters).
1077
1078 @returns 1 if everything executed properly, 0 for an error
1079*/
1080/**************************************************************************/
1081uint8_t Adafruit_PN532::mifareclassic_WriteNDEFURI(uint8_t sectorNumber,
1082 uint8_t uriIdentifier,
1083 const char *url) {
1084 // Figure out how long the string is
1085 uint8_t len = strlen(url);
1086
1087 // Make sure we're within a 1K limit for the sector number
1088 if ((sectorNumber < 1) || (sectorNumber > 15))
1089 return 0;
1090
1091 // Make sure the URI payload is between 1 and 38 chars
1092 if ((len < 1) || (len > 38))
1093 return 0;
1094
1095 // Note 0xD3 0xF7 0xD3 0xF7 0xD3 0xF7 must be used for key A
1096 // in NDEF records
1097
1098 // Setup the sector buffer (w/pre-formatted TLV wrapper and NDEF message)
1099 uint8_t sectorbuffer1[16] = {0x00,
1100 0x00,
1101 0x03,
1102 (uint8_t)(len + 5),
1103 0xD1,
1104 0x01,
1105 (uint8_t)(len + 1),
1106 0x55,
1107 uriIdentifier,
1108 0x00,
1109 0x00,
1110 0x00,
1111 0x00,
1112 0x00,
1113 0x00,
1114 0x00};
1115 uint8_t sectorbuffer2[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1116 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1117 0x00, 0x00, 0x00, 0x00};
1118 uint8_t sectorbuffer3[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1119 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
1120 0x00, 0x00, 0x00, 0x00};
1121 uint8_t sectorbuffer4[16] = {0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7,
1122 0x7F, 0x07, 0x88, 0x40, 0xFF, 0xFF,
1123 0xFF, 0xFF, 0xFF, 0xFF};
1124 if (len <= 6) {
1125 // Unlikely we'll get a url this short, but why not ...
1126 memcpy(sectorbuffer1 + 9, url, len);
1127 sectorbuffer1[len + 9] = 0xFE;
1128 } else if (len == 7) {
1129 // 0xFE needs to be wrapped around to next block
1130 memcpy(sectorbuffer1 + 9, url, len);
1131 sectorbuffer2[0] = 0xFE;
1132 } else if ((len > 7) && (len <= 22)) {
1133 // Url fits in two blocks
1134 memcpy(sectorbuffer1 + 9, url, 7);
1135 memcpy(sectorbuffer2, url + 7, len - 7);
1136 sectorbuffer2[len - 7] = 0xFE;
1137 } else if (len == 23) {
1138 // 0xFE needs to be wrapped around to final block
1139 memcpy(sectorbuffer1 + 9, url, 7);
1140 memcpy(sectorbuffer2, url + 7, len - 7);
1141 sectorbuffer3[0] = 0xFE;
1142 } else {
1143 // Url fits in three blocks
1144 memcpy(sectorbuffer1 + 9, url, 7);
1145 memcpy(sectorbuffer2, url + 7, 16);
1146 memcpy(sectorbuffer3, url + 23, len - 24);
1147 sectorbuffer3[len - 22] = 0xFE;
1148 }
1149
1150 // Now write all three blocks back to the card
1151 if (!(mifareclassic_WriteDataBlock(sectorNumber * 4, sectorbuffer1)))
1152 return 0;
1153 if (!(mifareclassic_WriteDataBlock((sectorNumber * 4) + 1, sectorbuffer2)))
1154 return 0;
1155 if (!(mifareclassic_WriteDataBlock((sectorNumber * 4) + 2, sectorbuffer3)))
1156 return 0;
1157 if (!(mifareclassic_WriteDataBlock((sectorNumber * 4) + 3, sectorbuffer4)))
1158 return 0;
1159
1160 // Seems that everything was OK (?!)
1161 return 1;
1162}
1163
1164/***** Mifare Ultralight Functions ******/
1165
1166/**************************************************************************/
1167/*!
1168 @brief Tries to read an entire 4-byte page at the specified address.
1169
1170 @param page The page number (0..63 in most cases)
1171 @param buffer Pointer to the byte array that will hold the
1172 retrieved data (if any)
1173 @return 1 on success, 0 on error.
1174*/
1175/**************************************************************************/
1176uint8_t Adafruit_PN532::mifareultralight_ReadPage(uint8_t page,
1177 uint8_t *buffer) {
1178 if (page >= 64) {
1179#ifdef MIFAREDEBUG
1180 PN532DEBUGPRINT.println(F("Page value out of range"));
1181#endif
1182 return 0;
1183 }
1184
1185#ifdef MIFAREDEBUG
1186 PN532DEBUGPRINT.print(F("Reading page "));
1187 PN532DEBUGPRINT.println(page);
1188#endif
1189
1190 /* Prepare the command */
1191 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
1192 pn532_packetbuffer[1] = 1; /* Card number */
1193 pn532_packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
1194 pn532_packetbuffer[3] = page; /* Page Number (0..63 in most cases) */
1195
1196 /* Send the command */
1197 if (!sendCommandCheckAck(pn532_packetbuffer, 4)) {
1198#ifdef MIFAREDEBUG
1199 PN532DEBUGPRINT.println(F("Failed to receive ACK for write command"));
1200#endif
1201 return 0;
1202 }
1203
1204 /* Read the response packet */
1205 readdata(pn532_packetbuffer, 26);
1206#ifdef MIFAREDEBUG
1207 PN532DEBUGPRINT.println(F("Received: "));
1208 Adafruit_PN532::PrintHexChar(pn532_packetbuffer, 26);
1209#endif
1210
1211 /* If byte 8 isn't 0x00 we probably have an error */
1212 if (pn532_packetbuffer[7] == 0x00) {
1213 /* Copy the 4 data bytes to the output buffer */
1214 /* Block content starts at byte 9 of a valid response */
1215 /* Note that the command actually reads 16 byte or 4 */
1216 /* pages at a time ... we simply discard the last 12 */
1217 /* bytes */
1218 memcpy(buffer, pn532_packetbuffer + 8, 4);
1219 } else {
1220#ifdef MIFAREDEBUG
1221 PN532DEBUGPRINT.println(F("Unexpected response reading block: "));
1222 Adafruit_PN532::PrintHexChar(pn532_packetbuffer, 26);
1223#endif
1224 return 0;
1225 }
1226
1227/* Display data for debug if requested */
1228#ifdef MIFAREDEBUG
1229 PN532DEBUGPRINT.print(F("Page "));
1230 PN532DEBUGPRINT.print(page);
1231 PN532DEBUGPRINT.println(F(":"));
1232 Adafruit_PN532::PrintHexChar(buffer, 4);
1233#endif
1234
1235 // Return OK signal
1236 return 1;
1237}
1238
1239/**************************************************************************/
1240/*!
1241 Tries to write an entire 4-byte page at the specified block
1242 address.
1243
1244 @param page The page number to write. (0..63 for most cases)
1245 @param data The byte array that contains the data to write.
1246 Should be exactly 4 bytes long.
1247
1248 @returns 1 if everything executed properly, 0 for an error
1249*/
1250/**************************************************************************/
1251uint8_t Adafruit_PN532::mifareultralight_WritePage(uint8_t page,
1252 uint8_t *data) {
1253
1254 if (page >= 64) {
1255#ifdef MIFAREDEBUG
1256 PN532DEBUGPRINT.println(F("Page value out of range"));
1257#endif
1258 // Return Failed Signal
1259 return 0;
1260 }
1261
1262#ifdef MIFAREDEBUG
1263 PN532DEBUGPRINT.print(F("Trying to write 4 byte page"));
1264 PN532DEBUGPRINT.println(page);
1265#endif
1266
1267 /* Prepare the first command */
1268 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
1269 pn532_packetbuffer[1] = 1; /* Card number */
1270 pn532_packetbuffer[2] =
1271 MIFARE_ULTRALIGHT_CMD_WRITE; /* Mifare Ultralight Write command = 0xA2
1272 */
1273 pn532_packetbuffer[3] = page; /* Page Number (0..63 for most cases) */
1274 memcpy(pn532_packetbuffer + 4, data, 4); /* Data Payload */
1275
1276 /* Send the command */
1277 if (!sendCommandCheckAck(pn532_packetbuffer, 8)) {
1278#ifdef MIFAREDEBUG
1279 PN532DEBUGPRINT.println(F("Failed to receive ACK for write command"));
1280#endif
1281
1282 // Return Failed Signal
1283 return 0;
1284 }
1285 delay(10);
1286
1287 /* Read the response packet */
1288 readdata(pn532_packetbuffer, 26);
1289
1290 // Return OK Signal
1291 return 1;
1292}
1293
1294/***** NTAG2xx Functions ******/
1295
1296/**************************************************************************/
1297/*!
1298 @brief Tries to read an entire 4-byte page at the specified address.
1299
1300 @param page The page number (0..63 in most cases)
1301 @param buffer Pointer to the byte array that will hold the
1302 retrieved data (if any)
1303 @return 1 on success, 0 on error.
1304*/
1305/**************************************************************************/
1306uint8_t Adafruit_PN532::ntag2xx_ReadPage(uint8_t page, uint8_t *buffer) {
1307 // TAG Type PAGES USER START USER STOP
1308 // -------- ----- ---------- ---------
1309 // NTAG 203 42 4 39
1310 // NTAG 213 45 4 39
1311 // NTAG 215 135 4 129
1312 // NTAG 216 231 4 225
1313
1314 if (page >= 231) {
1315#ifdef MIFAREDEBUG
1316 PN532DEBUGPRINT.println(F("Page value out of range"));
1317#endif
1318 return 0;
1319 }
1320
1321#ifdef MIFAREDEBUG
1322 PN532DEBUGPRINT.print(F("Reading page "));
1323 PN532DEBUGPRINT.println(page);
1324#endif
1325
1326 /* Prepare the command */
1327 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
1328 pn532_packetbuffer[1] = 1; /* Card number */
1329 pn532_packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
1330 pn532_packetbuffer[3] = page; /* Page Number (0..63 in most cases) */
1331
1332 /* Send the command */
1333 if (!sendCommandCheckAck(pn532_packetbuffer, 4)) {
1334#ifdef MIFAREDEBUG
1335 PN532DEBUGPRINT.println(F("Failed to receive ACK for write command"));
1336#endif
1337 return 0;
1338 }
1339
1340 /* Read the response packet */
1341 readdata(pn532_packetbuffer, 26);
1342#ifdef MIFAREDEBUG
1343 PN532DEBUGPRINT.println(F("Received: "));
1344 Adafruit_PN532::PrintHexChar(pn532_packetbuffer, 26);
1345#endif
1346
1347 /* If byte 8 isn't 0x00 we probably have an error */
1348 if (pn532_packetbuffer[7] == 0x00) {
1349 /* Copy the 4 data bytes to the output buffer */
1350 /* Block content starts at byte 9 of a valid response */
1351 /* Note that the command actually reads 16 byte or 4 */
1352 /* pages at a time ... we simply discard the last 12 */
1353 /* bytes */
1354 memcpy(buffer, pn532_packetbuffer + 8, 4);
1355 } else {
1356#ifdef MIFAREDEBUG
1357 PN532DEBUGPRINT.println(F("Unexpected response reading block: "));
1358 Adafruit_PN532::PrintHexChar(pn532_packetbuffer, 26);
1359#endif
1360 return 0;
1361 }
1362
1363/* Display data for debug if requested */
1364#ifdef MIFAREDEBUG
1365 PN532DEBUGPRINT.print(F("Page "));
1366 PN532DEBUGPRINT.print(page);
1367 PN532DEBUGPRINT.println(F(":"));
1368 Adafruit_PN532::PrintHexChar(buffer, 4);
1369#endif
1370
1371 // Return OK signal
1372 return 1;
1373}
1374
1375/**************************************************************************/
1376/*!
1377 Tries to write an entire 4-byte page at the specified block
1378 address.
1379
1380 @param page The page number to write. (0..63 for most cases)
1381 @param data The byte array that contains the data to write.
1382 Should be exactly 4 bytes long.
1383
1384 @returns 1 if everything executed properly, 0 for an error
1385*/
1386/**************************************************************************/
1387uint8_t Adafruit_PN532::ntag2xx_WritePage(uint8_t page, uint8_t *data) {
1388 // TAG Type PAGES USER START USER STOP
1389 // -------- ----- ---------- ---------
1390 // NTAG 203 42 4 39
1391 // NTAG 213 45 4 39
1392 // NTAG 215 135 4 129
1393 // NTAG 216 231 4 225
1394
1395 if ((page < 4) || (page > 225)) {
1396#ifdef MIFAREDEBUG
1397 PN532DEBUGPRINT.println(F("Page value out of range"));
1398#endif
1399 // Return Failed Signal
1400 return 0;
1401 }
1402
1403#ifdef MIFAREDEBUG
1404 PN532DEBUGPRINT.print(F("Trying to write 4 byte page"));
1405 PN532DEBUGPRINT.println(page);
1406#endif
1407
1408 /* Prepare the first command */
1409 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
1410 pn532_packetbuffer[1] = 1; /* Card number */
1411 pn532_packetbuffer[2] =
1412 MIFARE_ULTRALIGHT_CMD_WRITE; /* Mifare Ultralight Write command = 0xA2
1413 */
1414 pn532_packetbuffer[3] = page; /* Page Number (0..63 for most cases) */
1415 memcpy(pn532_packetbuffer + 4, data, 4); /* Data Payload */
1416
1417 /* Send the command */
1418 if (!sendCommandCheckAck(pn532_packetbuffer, 8)) {
1419#ifdef MIFAREDEBUG
1420 PN532DEBUGPRINT.println(F("Failed to receive ACK for write command"));
1421#endif
1422
1423 // Return Failed Signal
1424 return 0;
1425 }
1426 delay(10);
1427
1428 /* Read the response packet */
1429 readdata(pn532_packetbuffer, 26);
1430
1431 // Return OK Signal
1432 return 1;
1433}
1434
1435/**************************************************************************/
1436/*!
1437 Writes an NDEF URI Record starting at the specified page (4..nn)
1438
1439 Note that this function assumes that the NTAG2xx card is
1440 already formatted to work as an "NFC Forum Tag".
1441
1442 @param uriIdentifier The uri identifier code (0 = none, 0x01 =
1443 "http://www.", etc.)
1444 @param url The uri text to write (null-terminated string).
1445 @param dataLen The size of the data area for overflow checks.
1446
1447 @returns 1 if everything executed properly, 0 for an error
1448*/
1449/**************************************************************************/
1450uint8_t Adafruit_PN532::ntag2xx_WriteNDEFURI(uint8_t uriIdentifier, char *url,
1451 uint8_t dataLen) {
1452 uint8_t pageBuffer[4] = {0, 0, 0, 0};
1453
1454 // Remove NDEF record overhead from the URI data (pageHeader below)
1455 uint8_t wrapperSize = 12;
1456
1457 // Figure out how long the string is
1458 uint8_t len = strlen(url);
1459
1460 // Make sure the URI payload will fit in dataLen (include 0xFE trailer)
1461 if ((len < 1) || (len + 1 > (dataLen - wrapperSize)))
1462 return 0;
1463
1464 // Setup the record header
1465 // See NFCForum-TS-Type-2-Tag_1.1.pdf for details
1466 uint8_t pageHeader[12] = {
1467 /* NDEF Lock Control TLV (must be first and always present) */
1468 0x01, /* Tag Field (0x01 = Lock Control TLV) */
1469 0x03, /* Payload Length (always 3) */
1470 0xA0, /* The position inside the tag of the lock bytes (upper 4 = page
1471 address, lower 4 = byte offset) */
1472 0x10, /* Size in bits of the lock area */
1473 0x44, /* Size in bytes of a page and the number of bytes each lock bit
1474 can lock (4 bit + 4 bits) */
1475 /* NDEF Message TLV - URI Record */
1476 0x03, /* Tag Field (0x03 = NDEF Message) */
1477 (uint8_t)(len + 5), /* Payload Length (not including 0xFE trailer) */
1478 0xD1, /* NDEF Record Header (TNF=0x1:Well known record + SR + ME + MB)
1479 */
1480 0x01, /* Type Length for the record type indicator */
1481 (uint8_t)(len + 1), /* Payload len */
1482 0x55, /* Record Type Indicator (0x55 or 'U' = URI Record) */
1483 uriIdentifier /* URI Prefix (ex. 0x01 = "http://www.") */
1484 };
1485
1486 // Write 12 byte header (three pages of data starting at page 4)
1487 memcpy(pageBuffer, pageHeader, 4);
1488 if (!(ntag2xx_WritePage(4, pageBuffer)))
1489 return 0;
1490 memcpy(pageBuffer, pageHeader + 4, 4);
1491 if (!(ntag2xx_WritePage(5, pageBuffer)))
1492 return 0;
1493 memcpy(pageBuffer, pageHeader + 8, 4);
1494 if (!(ntag2xx_WritePage(6, pageBuffer)))
1495 return 0;
1496
1497 // Write URI (starting at page 7)
1498 uint8_t currentPage = 7;
1499 char *urlcopy = url;
1500 while (len) {
1501 if (len < 4) {
1502 memset(pageBuffer, 0, 4);
1503 memcpy(pageBuffer, urlcopy, len);
1504 pageBuffer[len] = 0xFE; // NDEF record footer
1505 if (!(ntag2xx_WritePage(currentPage, pageBuffer)))
1506 return 0;
1507 // DONE!
1508 return 1;
1509 } else if (len == 4) {
1510 memcpy(pageBuffer, urlcopy, len);
1511 if (!(ntag2xx_WritePage(currentPage, pageBuffer)))
1512 return 0;
1513 memset(pageBuffer, 0, 4);
1514 pageBuffer[0] = 0xFE; // NDEF record footer
1515 currentPage++;
1516 if (!(ntag2xx_WritePage(currentPage, pageBuffer)))
1517 return 0;
1518 // DONE!
1519 return 1;
1520 } else {
1521 // More than one page of data left
1522 memcpy(pageBuffer, urlcopy, 4);
1523 if (!(ntag2xx_WritePage(currentPage, pageBuffer)))
1524 return 0;
1525 currentPage++;
1526 urlcopy += 4;
1527 len -= 4;
1528 }
1529 }
1530
1531 // Seems that everything was OK (?!)
1532 return 1;
1533}
1534
1535/************** high level communication functions (handles both I2C and SPI) */
1536
1537/**************************************************************************/
1538/*!
1539 @brief Tries to read the SPI or I2C ACK signal
1540*/
1541/**************************************************************************/
1542bool Adafruit_PN532::readack() {
1543 uint8_t ackbuff[6];
1544
1545 if (spi_dev) {
1546 uint8_t cmd = PN532_SPI_DATAREAD;
1547 spi_dev->write_then_read(&cmd, 1, ackbuff, 6);
1548 } else if (i2c_dev || ser_dev) {
1549 readdata(ackbuff, 6);
1550 }
1551
1552 return (0 == memcmp((char *)ackbuff, (char *)pn532ack, 6));
1553}
1554
1555/**************************************************************************/
1556/*!
1557 @brief Return true if the PN532 is ready with a response.
1558*/
1559/**************************************************************************/
1560bool Adafruit_PN532::isready() {
1561 if (spi_dev) {
1562 // SPI ready check via Status Request
1563 uint8_t cmd = PN532_SPI_STATREAD;
1564 uint8_t reply;
1565 spi_dev->write_then_read(&cmd, 1, &reply, 1);
1566 return reply == PN532_SPI_READY;
1567 } else if (i2c_dev) {
1568 // I2C ready check via reading RDY byte
1569 uint8_t rdy[1];
1570 i2c_dev->read(rdy, 1);
1571 return rdy[0] == PN532_I2C_READY;
1572 } else if (ser_dev) {
1573 // Serial ready check based on non-zero read buffer
1574 return (ser_dev->available() != 0);
1575 } else if (_irq != -1) {
1576 uint8_t x = digitalRead(_irq);
1577 return x == 0;
1578 }
1579 return false;
1580}
1581
1582/**************************************************************************/
1583/*!
1584 @brief Waits until the PN532 is ready.
1585
1586 @param timeout Timeout before giving up
1587*/
1588/**************************************************************************/
1589bool Adafruit_PN532::waitready(uint16_t timeout) {
1590 uint16_t timer = 0;
1591 while (!isready()) {
1592 if (timeout != 0) {
1593 timer += 10;
1594 if (timer > timeout) {
1595#ifdef PN532DEBUG
1596 PN532DEBUGPRINT.println("TIMEOUT!");
1597#endif
1598 return false;
1599 }
1600 }
1601 delay(10);
1602 }
1603 return true;
1604}
1605
1606/**************************************************************************/
1607/*!
1608 @brief Reads n bytes of data from the PN532 via SPI or I2C.
1609
1610 @param buff Pointer to the buffer where data will be written
1611 @param n Number of bytes to be read
1612*/
1613/**************************************************************************/
1614void Adafruit_PN532::readdata(uint8_t *buff, uint8_t n) {
1615 if (spi_dev) {
1616 // SPI read
1617 uint8_t cmd = PN532_SPI_DATAREAD;
1618 spi_dev->write_then_read(&cmd, 1, buff, n);
1619 } else if (i2c_dev) {
1620 // I2C read
1621 uint8_t rbuff[n + 1]; // +1 for leading RDY byte
1622 i2c_dev->read(rbuff, n + 1);
1623 for (uint8_t i = 0; i < n; i++) {
1624 buff[i] = rbuff[i + 1];
1625 }
1626 } else if (ser_dev) {
1627 // Serial read
1628 ser_dev->readBytes(buff, n);
1629 }
1630#ifdef PN532DEBUG
1631 PN532DEBUGPRINT.print(F("Reading: "));
1632 for (uint8_t i = 0; i < n; i++) {
1633 PN532DEBUGPRINT.print(F(" 0x"));
1634 PN532DEBUGPRINT.print(buff[i], HEX);
1635 }
1636 PN532DEBUGPRINT.println();
1637#endif
1638}
1639
1640/**************************************************************************/
1641/*!
1642 @brief set the PN532 as iso14443a Target behaving as a SmartCard
1643 @return true on success, false otherwise.
1644 @note Author: Salvador Mendoza (salmg.net) new functions:
1645 -AsTarget
1646 -getDataTarget
1647 -setDataTarget
1648*/
1649/**************************************************************************/
1650uint8_t Adafruit_PN532::AsTarget() {
1651 pn532_packetbuffer[0] = 0x8C;
1652 uint8_t target[] = {
1653 0x8C, // INIT AS TARGET
1654 0x00, // MODE -> BITFIELD
1655 0x08, 0x00, // SENS_RES - MIFARE PARAMS
1656 0xdc, 0x44, 0x20, // NFCID1T
1657 0x60, // SEL_RES
1658 0x01, 0xfe, // NFCID2T MUST START WITH 01fe - FELICA PARAMS - POL_RES
1659 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7, 0xc0,
1660 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7, // PAD
1661 0xff, 0xff, // SYSTEM CODE
1662 0xaa, 0x99, 0x88, 0x77, 0x66, 0x55, 0x44,
1663 0x33, 0x22, 0x11, 0x01, 0x00, // NFCID3t MAX 47 BYTES ATR_RES
1664 0x0d, 0x52, 0x46, 0x49, 0x44, 0x49, 0x4f,
1665 0x74, 0x20, 0x50, 0x4e, 0x35, 0x33, 0x32 // HISTORICAL BYTES
1666 };
1667 if (!sendCommandCheckAck(target, sizeof(target)))
1668 return false;
1669
1670 // read data packet
1671 readdata(pn532_packetbuffer, 8);
1672
1673 int offset = 6;
1674 return (pn532_packetbuffer[offset] == 0x15);
1675}
1676/**************************************************************************/
1677/*!
1678 @brief Retrieve response from the emulation mode
1679
1680 @param cmd = data
1681 @param cmdlen = data length
1682 @return true on success, false otherwise.
1683*/
1684/**************************************************************************/
1685uint8_t Adafruit_PN532::getDataTarget(uint8_t *cmd, uint8_t *cmdlen) {
1686 uint8_t length;
1687 pn532_packetbuffer[0] = 0x86;
1688 if (!sendCommandCheckAck(pn532_packetbuffer, 1, 1000)) {
1689 PN532DEBUGPRINT.println(F("Error en ack"));
1690 return false;
1691 }
1692
1693 // read data packet
1694 readdata(pn532_packetbuffer, 64);
1695 length = pn532_packetbuffer[3] - 3;
1696
1697 // if (length > *responseLength) {// Bug, should avoid it in the reading
1698 // target data
1699 // length = *responseLength; // silent truncation...
1700 //}
1701
1702 for (int i = 0; i < length; ++i) {
1703 cmd[i] = pn532_packetbuffer[8 + i];
1704 }
1705 *cmdlen = length;
1706 return true;
1707}
1708
1709/**************************************************************************/
1710/*!
1711 @brief Set data in PN532 in the emulation mode
1712
1713 @param cmd = data
1714 @param cmdlen = data length
1715 @return true on success, false otherwise.
1716*/
1717/**************************************************************************/
1718uint8_t Adafruit_PN532::setDataTarget(uint8_t *cmd, uint8_t cmdlen) {
1719 uint8_t length;
1720 // cmd1[0] = 0x8E; Must!
1721
1722 if (!sendCommandCheckAck(cmd, cmdlen))
1723 return false;
1724
1725 // read data packet
1726 readdata(pn532_packetbuffer, 8);
1727 length = pn532_packetbuffer[3] - 3;
1728 for (int i = 0; i < length; ++i) {
1729 cmd[i] = pn532_packetbuffer[8 + i];
1730 }
1731 // cmdl = 0
1732 cmdlen = length;
1733
1734 int offset = 6;
1735 return (pn532_packetbuffer[offset] == 0x15);
1736}
1737
1738/**************************************************************************/
1739/*!
1740 @brief Writes a command to the PN532, automatically inserting the
1741 preamble and required frame details (checksum, len, etc.)
1742
1743 @param cmd Pointer to the command buffer
1744 @param cmdlen Command length in bytes
1745*/
1746/**************************************************************************/
1747void Adafruit_PN532::writecommand(uint8_t *cmd, uint8_t cmdlen) {
1748 if (spi_dev) {
1749 // SPI command write.
1750 uint8_t checksum;
1751 uint8_t packet[9 + cmdlen];
1752 uint8_t *p = packet;
1753 cmdlen++;
1754
1755 p[0] = PN532_SPI_DATAWRITE;
1756 p++;
1757
1758 p[0] = PN532_PREAMBLE;
1759 p++;
1760 p[0] = PN532_STARTCODE1;
1761 p++;
1762 p[0] = PN532_STARTCODE2;
1763 p++;
1764 checksum = PN532_PREAMBLE + PN532_STARTCODE1 + PN532_STARTCODE2;
1765
1766 p[0] = cmdlen;
1767 p++;
1768 p[0] = ~cmdlen + 1;
1769 p++;
1770
1771 p[0] = PN532_HOSTTOPN532;
1772 p++;
1773 checksum += PN532_HOSTTOPN532;
1774
1775 for (uint8_t i = 0; i < cmdlen - 1; i++) {
1776 p[0] = cmd[i];
1777 p++;
1778 checksum += cmd[i];
1779 }
1780
1781 p[0] = ~checksum;
1782 p++;
1783 p[0] = PN532_POSTAMBLE;
1784 p++;
1785
1786#ifdef PN532DEBUG
1787 Serial.print("Sending : ");
1788 for (int i = 1; i < 8 + cmdlen; i++) {
1789 Serial.print("0x");
1790 Serial.print(packet[i], HEX);
1791 Serial.print(", ");
1792 }
1793 Serial.println();
1794#endif
1795
1796 spi_dev->write(packet, 8 + cmdlen);
1797 } else if (i2c_dev || ser_dev) {
1798 // I2C or Serial command write.
1799 uint8_t packet[8 + cmdlen];
1800 uint8_t LEN = cmdlen + 1;
1801
1802 packet[0] = PN532_PREAMBLE;
1803 packet[1] = PN532_STARTCODE1;
1804 packet[2] = PN532_STARTCODE2;
1805 packet[3] = LEN;
1806 packet[4] = ~LEN + 1;
1807 packet[5] = PN532_HOSTTOPN532;
1808 uint8_t sum = 0;
1809 for (uint8_t i = 0; i < cmdlen; i++) {
1810 packet[6 + i] = cmd[i];
1811 sum += cmd[i];
1812 }
1813 packet[6 + cmdlen] = ~(PN532_HOSTTOPN532 + sum) + 1;
1814 packet[7 + cmdlen] = PN532_POSTAMBLE;
1815
1816#ifdef PN532DEBUG
1817 Serial.print("Sending : ");
1818 for (int i = 1; i < 8 + cmdlen; i++) {
1819 Serial.print("0x");
1820 Serial.print(packet[i], HEX);
1821 Serial.print(", ");
1822 }
1823 Serial.println();
1824#endif
1825
1826 if (i2c_dev) {
1827 i2c_dev->write(packet, 8 + cmdlen);
1828 } else {
1829 ser_dev->write(packet, 8 + cmdlen);
1830 }
1831 }
1832}