LEER TAG

Dependents:   NFC_HTM_READ EMULAR_TAGS Escribir_tag NFC_HTM_READ-WRITE

Committer:
mauroar211
Date:
Fri Apr 24 19:02:44 2015 +0000
Revision:
1:a549ef8b142a
Parent:
0:b805b487fbef
SE RESTAURARON LOS ARCHIVO DE LA LIBRER?A;

Who changed what in which revision?

UserRevisionLine numberNew contents of line
mauroar211 0:b805b487fbef 1 /**************************************************************************/
mauroar211 0:b805b487fbef 2 /*!
mauroar211 0:b805b487fbef 3 @file PN532.cpp
mauroar211 0:b805b487fbef 4 @author Adafruit Industries & Seeed Studio
mauroar211 0:b805b487fbef 5 @license BSD
mauroar211 0:b805b487fbef 6 */
mauroar211 0:b805b487fbef 7 /**************************************************************************/
mauroar211 0:b805b487fbef 8
mauroar211 0:b805b487fbef 9 #include "PN532.h"
mauroar211 0:b805b487fbef 10 #include "PN532_debug.h"
mauroar211 0:b805b487fbef 11 #include <string.h>
mauroar211 1:a549ef8b142a 12 #include "mbed.h"
mauroar211 0:b805b487fbef 13
mauroar211 0:b805b487fbef 14 #ifndef ARDUINO
mauroar211 0:b805b487fbef 15 #include <stdio.h>
mauroar211 0:b805b487fbef 16 #endif
mauroar211 0:b805b487fbef 17
mauroar211 0:b805b487fbef 18 #define HAL(func) (_interface->func)
mauroar211 0:b805b487fbef 19
mauroar211 0:b805b487fbef 20 PN532::PN532(PN532Interface &interface)
mauroar211 0:b805b487fbef 21 {
mauroar211 0:b805b487fbef 22 _interface = &interface;
mauroar211 0:b805b487fbef 23 }
mauroar211 0:b805b487fbef 24
mauroar211 0:b805b487fbef 25 /**************************************************************************/
mauroar211 0:b805b487fbef 26 /*!
mauroar211 0:b805b487fbef 27 @brief Setups the HW
mauroar211 0:b805b487fbef 28 */
mauroar211 0:b805b487fbef 29 /**************************************************************************/
mauroar211 0:b805b487fbef 30 void PN532::begin()
mauroar211 0:b805b487fbef 31 {
mauroar211 0:b805b487fbef 32 HAL(begin)();
mauroar211 0:b805b487fbef 33 HAL(wakeup)();
mauroar211 0:b805b487fbef 34 }
mauroar211 0:b805b487fbef 35
mauroar211 0:b805b487fbef 36 /**************************************************************************/
mauroar211 0:b805b487fbef 37 /*!
mauroar211 0:b805b487fbef 38 @brief Prints a hexadecimal value in plain characters
mauroar211 0:b805b487fbef 39
mauroar211 0:b805b487fbef 40 @param data Pointer to the uint8_t data
mauroar211 0:b805b487fbef 41 @param numBytes Data length in bytes
mauroar211 0:b805b487fbef 42 */
mauroar211 0:b805b487fbef 43 /**************************************************************************/
mauroar211 0:b805b487fbef 44 void PN532::PrintHex(const uint8_t *data, const uint32_t numBytes)
mauroar211 0:b805b487fbef 45 {
mauroar211 0:b805b487fbef 46 #ifdef ARDUINO
mauroar211 0:b805b487fbef 47 for (uint8_t i = 0; i < numBytes; i++) {
mauroar211 0:b805b487fbef 48 if (data[i] < 0x10) {
mauroar211 0:b805b487fbef 49 Serial.print(" 0");
mauroar211 0:b805b487fbef 50 } else {
mauroar211 0:b805b487fbef 51 Serial.print(' ');
mauroar211 0:b805b487fbef 52 }
mauroar211 0:b805b487fbef 53 Serial.print(data[i], HEX);
mauroar211 0:b805b487fbef 54 }
mauroar211 0:b805b487fbef 55 Serial.println("");
mauroar211 0:b805b487fbef 56 #else
mauroar211 0:b805b487fbef 57 for (uint8_t i = 0; i < numBytes; i++) {
mauroar211 0:b805b487fbef 58 printf(" %2X", data[i]);
mauroar211 0:b805b487fbef 59 }
mauroar211 0:b805b487fbef 60 printf("\n");
mauroar211 0:b805b487fbef 61 #endif
mauroar211 0:b805b487fbef 62 }
mauroar211 0:b805b487fbef 63
mauroar211 0:b805b487fbef 64 /**************************************************************************/
mauroar211 0:b805b487fbef 65 /*!
mauroar211 0:b805b487fbef 66 @brief Prints a hexadecimal value in plain characters, along with
mauroar211 0:b805b487fbef 67 the char equivalents in the following format
mauroar211 0:b805b487fbef 68
mauroar211 0:b805b487fbef 69 00 00 00 00 00 00 ......
mauroar211 0:b805b487fbef 70
mauroar211 0:b805b487fbef 71 @param data Pointer to the data
mauroar211 0:b805b487fbef 72 @param numBytes Data length in bytes
mauroar211 0:b805b487fbef 73 */
mauroar211 0:b805b487fbef 74 /**************************************************************************/
mauroar211 0:b805b487fbef 75 void PN532::PrintHexChar(const uint8_t *data, const uint32_t numBytes)
mauroar211 0:b805b487fbef 76 {
mauroar211 0:b805b487fbef 77 #ifdef ARDUINO
mauroar211 0:b805b487fbef 78 for (uint8_t i = 0; i < numBytes; i++) {
mauroar211 0:b805b487fbef 79 if (data[i] < 0x10) {
mauroar211 0:b805b487fbef 80 Serial.print(" 0");
mauroar211 0:b805b487fbef 81 } else {
mauroar211 0:b805b487fbef 82 Serial.print(' ');
mauroar211 0:b805b487fbef 83 }
mauroar211 0:b805b487fbef 84 Serial.print(data[i], HEX);
mauroar211 0:b805b487fbef 85 }
mauroar211 0:b805b487fbef 86 Serial.print(" ");
mauroar211 0:b805b487fbef 87 for (uint8_t i = 0; i < numBytes; i++) {
mauroar211 0:b805b487fbef 88 char c = data[i];
mauroar211 0:b805b487fbef 89 if (c <= 0x1f || c > 0x7f) {
mauroar211 0:b805b487fbef 90 Serial.print('.');
mauroar211 0:b805b487fbef 91 } else {
mauroar211 0:b805b487fbef 92 Serial.print(c);
mauroar211 0:b805b487fbef 93 }
mauroar211 0:b805b487fbef 94 }
mauroar211 0:b805b487fbef 95 Serial.println("");
mauroar211 0:b805b487fbef 96 #else
mauroar211 0:b805b487fbef 97 for (uint8_t i = 0; i < numBytes; i++) {
mauroar211 0:b805b487fbef 98 printf(" %2X", data[i]);
mauroar211 0:b805b487fbef 99 }
mauroar211 0:b805b487fbef 100 printf(" ");
mauroar211 0:b805b487fbef 101 for (uint8_t i = 0; i < numBytes; i++) {
mauroar211 0:b805b487fbef 102 char c = data[i];
mauroar211 0:b805b487fbef 103 if (c <= 0x1f || c > 0x7f) {
mauroar211 0:b805b487fbef 104 printf(".");
mauroar211 0:b805b487fbef 105 } else {
mauroar211 0:b805b487fbef 106 printf("%c", c);
mauroar211 0:b805b487fbef 107 }
mauroar211 0:b805b487fbef 108 printf("\n");
mauroar211 0:b805b487fbef 109 }
mauroar211 0:b805b487fbef 110 #endif
mauroar211 0:b805b487fbef 111 }
mauroar211 0:b805b487fbef 112
mauroar211 0:b805b487fbef 113 /**************************************************************************/
mauroar211 0:b805b487fbef 114 /*!
mauroar211 0:b805b487fbef 115 @brief Checks the firmware version of the PN5xx chip
mauroar211 0:b805b487fbef 116
mauroar211 0:b805b487fbef 117 @returns The chip's firmware version and ID
mauroar211 0:b805b487fbef 118 */
mauroar211 0:b805b487fbef 119 /**************************************************************************/
mauroar211 0:b805b487fbef 120 uint32_t PN532::getFirmwareVersion(void)
mauroar211 0:b805b487fbef 121 {
mauroar211 0:b805b487fbef 122 uint32_t response;
mauroar211 0:b805b487fbef 123
mauroar211 0:b805b487fbef 124 pn532_packetbuffer[0] = PN532_COMMAND_GETFIRMWAREVERSION;
mauroar211 0:b805b487fbef 125
mauroar211 0:b805b487fbef 126 if (HAL(writeCommand)(pn532_packetbuffer, 1)) {
mauroar211 0:b805b487fbef 127 return 0;
mauroar211 0:b805b487fbef 128 }
mauroar211 0:b805b487fbef 129
mauroar211 0:b805b487fbef 130 // read data packet
mauroar211 0:b805b487fbef 131 int16_t status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer));
mauroar211 0:b805b487fbef 132 if (0 > status) {
mauroar211 0:b805b487fbef 133 return 0;
mauroar211 0:b805b487fbef 134 }
mauroar211 0:b805b487fbef 135
mauroar211 0:b805b487fbef 136 response = pn532_packetbuffer[0];
mauroar211 0:b805b487fbef 137 response <<= 8;
mauroar211 0:b805b487fbef 138 response |= pn532_packetbuffer[1];
mauroar211 0:b805b487fbef 139 response <<= 8;
mauroar211 0:b805b487fbef 140 response |= pn532_packetbuffer[2];
mauroar211 0:b805b487fbef 141 response <<= 8;
mauroar211 0:b805b487fbef 142 response |= pn532_packetbuffer[3];
mauroar211 0:b805b487fbef 143
mauroar211 0:b805b487fbef 144 return response;
mauroar211 0:b805b487fbef 145 }
mauroar211 0:b805b487fbef 146
mauroar211 0:b805b487fbef 147
mauroar211 0:b805b487fbef 148 /**************************************************************************/
mauroar211 0:b805b487fbef 149 /*!
mauroar211 0:b805b487fbef 150 Writes an 8-bit value that sets the state of the PN532's GPIO pins
mauroar211 0:b805b487fbef 151
mauroar211 0:b805b487fbef 152 @warning This function is provided exclusively for board testing and
mauroar211 0:b805b487fbef 153 is dangerous since it will throw an error if any pin other
mauroar211 0:b805b487fbef 154 than the ones marked "Can be used as GPIO" are modified! All
mauroar211 0:b805b487fbef 155 pins that can not be used as GPIO should ALWAYS be left high
mauroar211 0:b805b487fbef 156 (value = 1) or the system will become unstable and a HW reset
mauroar211 0:b805b487fbef 157 will be required to recover the PN532.
mauroar211 0:b805b487fbef 158
mauroar211 0:b805b487fbef 159 pinState[0] = P30 Can be used as GPIO
mauroar211 0:b805b487fbef 160 pinState[1] = P31 Can be used as GPIO
mauroar211 0:b805b487fbef 161 pinState[2] = P32 *** RESERVED (Must be 1!) ***
mauroar211 0:b805b487fbef 162 pinState[3] = P33 Can be used as GPIO
mauroar211 0:b805b487fbef 163 pinState[4] = P34 *** RESERVED (Must be 1!) ***
mauroar211 0:b805b487fbef 164 pinState[5] = P35 Can be used as GPIO
mauroar211 0:b805b487fbef 165
mauroar211 0:b805b487fbef 166 @returns 1 if everything executed properly, 0 for an error
mauroar211 0:b805b487fbef 167 */
mauroar211 0:b805b487fbef 168 /**************************************************************************/
mauroar211 0:b805b487fbef 169 bool PN532::writeGPIO(uint8_t pinstate)
mauroar211 0:b805b487fbef 170 {
mauroar211 0:b805b487fbef 171 // Make sure pinstate does not try to toggle P32 or P34
mauroar211 0:b805b487fbef 172 pinstate |= (1 << PN532_GPIO_P32) | (1 << PN532_GPIO_P34);
mauroar211 0:b805b487fbef 173
mauroar211 0:b805b487fbef 174 // Fill command buffer
mauroar211 0:b805b487fbef 175 pn532_packetbuffer[0] = PN532_COMMAND_WRITEGPIO;
mauroar211 0:b805b487fbef 176 pn532_packetbuffer[1] = PN532_GPIO_VALIDATIONBIT | pinstate; // P3 Pins
mauroar211 0:b805b487fbef 177 pn532_packetbuffer[2] = 0x00; // P7 GPIO Pins (not used ... taken by I2C)
mauroar211 0:b805b487fbef 178
mauroar211 0:b805b487fbef 179 DMSG("Writing P3 GPIO: ");
mauroar211 0:b805b487fbef 180 DMSG_HEX(pn532_packetbuffer[1]);
mauroar211 0:b805b487fbef 181 DMSG("\n");
mauroar211 0:b805b487fbef 182
mauroar211 0:b805b487fbef 183 // Send the WRITEGPIO command (0x0E)
mauroar211 0:b805b487fbef 184 if (HAL(writeCommand)(pn532_packetbuffer, 3))
mauroar211 0:b805b487fbef 185 return 0;
mauroar211 0:b805b487fbef 186
mauroar211 0:b805b487fbef 187 return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)));
mauroar211 0:b805b487fbef 188 }
mauroar211 0:b805b487fbef 189
mauroar211 0:b805b487fbef 190 /**************************************************************************/
mauroar211 0:b805b487fbef 191 /*!
mauroar211 0:b805b487fbef 192 Reads the state of the PN532's GPIO pins
mauroar211 0:b805b487fbef 193
mauroar211 0:b805b487fbef 194 @returns An 8-bit value containing the pin state where:
mauroar211 0:b805b487fbef 195
mauroar211 0:b805b487fbef 196 pinState[0] = P30
mauroar211 0:b805b487fbef 197 pinState[1] = P31
mauroar211 0:b805b487fbef 198 pinState[2] = P32
mauroar211 0:b805b487fbef 199 pinState[3] = P33
mauroar211 0:b805b487fbef 200 pinState[4] = P34
mauroar211 0:b805b487fbef 201 pinState[5] = P35
mauroar211 0:b805b487fbef 202 */
mauroar211 0:b805b487fbef 203 /**************************************************************************/
mauroar211 0:b805b487fbef 204 uint8_t PN532::readGPIO(void)
mauroar211 0:b805b487fbef 205 {
mauroar211 0:b805b487fbef 206 pn532_packetbuffer[0] = PN532_COMMAND_READGPIO;
mauroar211 0:b805b487fbef 207
mauroar211 0:b805b487fbef 208 // Send the READGPIO command (0x0C)
mauroar211 0:b805b487fbef 209 if (HAL(writeCommand)(pn532_packetbuffer, 1))
mauroar211 0:b805b487fbef 210 return 0x0;
mauroar211 0:b805b487fbef 211
mauroar211 0:b805b487fbef 212 HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer));
mauroar211 0:b805b487fbef 213
mauroar211 0:b805b487fbef 214 /* READGPIO response without prefix and suffix should be in the following format:
mauroar211 0:b805b487fbef 215
mauroar211 0:b805b487fbef 216 byte Description
mauroar211 0:b805b487fbef 217 ------------- ------------------------------------------
mauroar211 0:b805b487fbef 218 b0 P3 GPIO Pins
mauroar211 0:b805b487fbef 219 b1 P7 GPIO Pins (not used ... taken by I2C)
mauroar211 0:b805b487fbef 220 b2 Interface Mode Pins (not used ... bus select pins)
mauroar211 0:b805b487fbef 221 */
mauroar211 0:b805b487fbef 222
mauroar211 0:b805b487fbef 223
mauroar211 0:b805b487fbef 224 DMSG("P3 GPIO: "); DMSG_HEX(pn532_packetbuffer[7]);
mauroar211 0:b805b487fbef 225 DMSG("P7 GPIO: "); DMSG_HEX(pn532_packetbuffer[8]);
mauroar211 0:b805b487fbef 226 DMSG("I0I1 GPIO: "); DMSG_HEX(pn532_packetbuffer[9]);
mauroar211 0:b805b487fbef 227 DMSG("\n");
mauroar211 0:b805b487fbef 228
mauroar211 0:b805b487fbef 229 return pn532_packetbuffer[0];
mauroar211 0:b805b487fbef 230 }
mauroar211 0:b805b487fbef 231
mauroar211 0:b805b487fbef 232 /**************************************************************************/
mauroar211 0:b805b487fbef 233 /*!
mauroar211 0:b805b487fbef 234 @brief Configures the SAM (Secure Access Module)
mauroar211 0:b805b487fbef 235 */
mauroar211 0:b805b487fbef 236 /**************************************************************************/
mauroar211 0:b805b487fbef 237 bool PN532::SAMConfig(void)
mauroar211 0:b805b487fbef 238 {
mauroar211 0:b805b487fbef 239 pn532_packetbuffer[0] = PN532_COMMAND_SAMCONFIGURATION;
mauroar211 0:b805b487fbef 240 pn532_packetbuffer[1] = 0x01; // normal mode;
mauroar211 0:b805b487fbef 241 pn532_packetbuffer[2] = 0x14; // timeout 50ms * 20 = 1 second
mauroar211 0:b805b487fbef 242 pn532_packetbuffer[3] = 0x01; // use IRQ pin!
mauroar211 0:b805b487fbef 243
mauroar211 0:b805b487fbef 244 DMSG("SAMConfig\n");
mauroar211 0:b805b487fbef 245
mauroar211 0:b805b487fbef 246 if (HAL(writeCommand)(pn532_packetbuffer, 4))
mauroar211 0:b805b487fbef 247 return false;
mauroar211 0:b805b487fbef 248
mauroar211 0:b805b487fbef 249 return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)));
mauroar211 0:b805b487fbef 250 }
mauroar211 0:b805b487fbef 251
mauroar211 0:b805b487fbef 252 /**************************************************************************/
mauroar211 0:b805b487fbef 253 /*!
mauroar211 0:b805b487fbef 254 Sets the MxRtyPassiveActivation uint8_t of the RFConfiguration register
mauroar211 0:b805b487fbef 255
mauroar211 0:b805b487fbef 256 @param maxRetries 0xFF to wait forever, 0x00..0xFE to timeout
mauroar211 0:b805b487fbef 257 after mxRetries
mauroar211 0:b805b487fbef 258
mauroar211 0:b805b487fbef 259 @returns 1 if everything executed properly, 0 for an error
mauroar211 0:b805b487fbef 260 */
mauroar211 0:b805b487fbef 261 /**************************************************************************/
mauroar211 0:b805b487fbef 262 bool PN532::setPassiveActivationRetries(uint8_t maxRetries)
mauroar211 0:b805b487fbef 263 {
mauroar211 0:b805b487fbef 264 pn532_packetbuffer[0] = PN532_COMMAND_RFCONFIGURATION;
mauroar211 0:b805b487fbef 265 pn532_packetbuffer[1] = 5; // Config item 5 (MaxRetries)
mauroar211 0:b805b487fbef 266 pn532_packetbuffer[2] = 0xFF; // MxRtyATR (default = 0xFF)
mauroar211 0:b805b487fbef 267 pn532_packetbuffer[3] = 0x01; // MxRtyPSL (default = 0x01)
mauroar211 0:b805b487fbef 268 pn532_packetbuffer[4] = maxRetries;
mauroar211 0:b805b487fbef 269
mauroar211 0:b805b487fbef 270 if (HAL(writeCommand)(pn532_packetbuffer, 5))
mauroar211 0:b805b487fbef 271 return 0x0; // no ACK
mauroar211 0:b805b487fbef 272
mauroar211 0:b805b487fbef 273 return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)));
mauroar211 0:b805b487fbef 274 }
mauroar211 0:b805b487fbef 275
mauroar211 0:b805b487fbef 276 /***** ISO14443A Commands ******/
mauroar211 0:b805b487fbef 277
mauroar211 0:b805b487fbef 278 /**************************************************************************/
mauroar211 0:b805b487fbef 279 /*!
mauroar211 0:b805b487fbef 280 Waits for an ISO14443A target to enter the field
mauroar211 0:b805b487fbef 281
mauroar211 0:b805b487fbef 282 @param cardBaudRate Baud rate of the card
mauroar211 0:b805b487fbef 283 @param uid Pointer to the array that will be populated
mauroar211 0:b805b487fbef 284 with the card's UID (up to 7 bytes)
mauroar211 0:b805b487fbef 285 @param uidLength Pointer to the variable that will hold the
mauroar211 0:b805b487fbef 286 length of the card's UID.
mauroar211 0:b805b487fbef 287
mauroar211 0:b805b487fbef 288 @returns 1 if everything executed properly, 0 for an error
mauroar211 0:b805b487fbef 289 */
mauroar211 0:b805b487fbef 290 /**************************************************************************/
mauroar211 0:b805b487fbef 291 bool PN532::readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength, uint16_t timeout)
mauroar211 0:b805b487fbef 292 {
mauroar211 0:b805b487fbef 293 pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
mauroar211 0:b805b487fbef 294 pn532_packetbuffer[1] = 1; // max 1 cards at once (we can set this to 2 later)
mauroar211 0:b805b487fbef 295 pn532_packetbuffer[2] = cardbaudrate;
mauroar211 0:b805b487fbef 296
mauroar211 0:b805b487fbef 297 if (HAL(writeCommand)(pn532_packetbuffer, 3)) {
mauroar211 0:b805b487fbef 298 return 0x0; // command failed
mauroar211 0:b805b487fbef 299 }
mauroar211 0:b805b487fbef 300
mauroar211 0:b805b487fbef 301 // read data packet
mauroar211 0:b805b487fbef 302 if (HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), timeout) < 0) {
mauroar211 0:b805b487fbef 303 return 0x0;
mauroar211 0:b805b487fbef 304 }
mauroar211 0:b805b487fbef 305
mauroar211 0:b805b487fbef 306 // check some basic stuff
mauroar211 0:b805b487fbef 307 /* ISO14443A card response should be in the following format:
mauroar211 0:b805b487fbef 308
mauroar211 0:b805b487fbef 309 byte Description
mauroar211 0:b805b487fbef 310 ------------- ------------------------------------------
mauroar211 0:b805b487fbef 311 b0 Tags Found
mauroar211 0:b805b487fbef 312 b1 Tag Number (only one used in this example)
mauroar211 0:b805b487fbef 313 b2..3 SENS_RES
mauroar211 0:b805b487fbef 314 b4 SEL_RES
mauroar211 0:b805b487fbef 315 b5 NFCID Length
mauroar211 0:b805b487fbef 316 b6..NFCIDLen NFCID
mauroar211 0:b805b487fbef 317 */
mauroar211 0:b805b487fbef 318
mauroar211 0:b805b487fbef 319 if (pn532_packetbuffer[0] != 1)
mauroar211 0:b805b487fbef 320 return 0;
mauroar211 0:b805b487fbef 321
mauroar211 0:b805b487fbef 322 uint16_t sens_res = pn532_packetbuffer[2];
mauroar211 0:b805b487fbef 323 sens_res <<= 8;
mauroar211 0:b805b487fbef 324 sens_res |= pn532_packetbuffer[3];
mauroar211 0:b805b487fbef 325
mauroar211 0:b805b487fbef 326 DMSG("ATQA: 0x"); DMSG_HEX(sens_res);
mauroar211 0:b805b487fbef 327 DMSG("SAK: 0x"); DMSG_HEX(pn532_packetbuffer[4]);
mauroar211 0:b805b487fbef 328 DMSG("\n");
mauroar211 0:b805b487fbef 329
mauroar211 0:b805b487fbef 330 /* Card appears to be Mifare Classic */
mauroar211 0:b805b487fbef 331 *uidLength = pn532_packetbuffer[5];
mauroar211 0:b805b487fbef 332
mauroar211 0:b805b487fbef 333 for (uint8_t i = 0; i < pn532_packetbuffer[5]; i++) {
mauroar211 0:b805b487fbef 334 uid[i] = pn532_packetbuffer[6 + i];
mauroar211 0:b805b487fbef 335 }
mauroar211 0:b805b487fbef 336
mauroar211 0:b805b487fbef 337 return 1;
mauroar211 0:b805b487fbef 338 }
mauroar211 0:b805b487fbef 339
mauroar211 0:b805b487fbef 340
mauroar211 0:b805b487fbef 341 /***** Mifare Classic Functions ******/
mauroar211 0:b805b487fbef 342
mauroar211 0:b805b487fbef 343 /**************************************************************************/
mauroar211 0:b805b487fbef 344 /*!
mauroar211 0:b805b487fbef 345 Indicates whether the specified block number is the first block
mauroar211 0:b805b487fbef 346 in the sector (block 0 relative to the current sector)
mauroar211 0:b805b487fbef 347 */
mauroar211 0:b805b487fbef 348 /**************************************************************************/
mauroar211 0:b805b487fbef 349 bool PN532::mifareclassic_IsFirstBlock (uint32_t uiBlock)
mauroar211 0:b805b487fbef 350 {
mauroar211 0:b805b487fbef 351 // Test if we are in the small or big sectors
mauroar211 0:b805b487fbef 352 if (uiBlock < 128)
mauroar211 0:b805b487fbef 353 return ((uiBlock) % 4 == 0);
mauroar211 0:b805b487fbef 354 else
mauroar211 0:b805b487fbef 355 return ((uiBlock) % 16 == 0);
mauroar211 0:b805b487fbef 356 }
mauroar211 0:b805b487fbef 357
mauroar211 0:b805b487fbef 358 /**************************************************************************/
mauroar211 0:b805b487fbef 359 /*!
mauroar211 0:b805b487fbef 360 Indicates whether the specified block number is the sector trailer
mauroar211 0:b805b487fbef 361 */
mauroar211 0:b805b487fbef 362 /**************************************************************************/
mauroar211 0:b805b487fbef 363 bool PN532::mifareclassic_IsTrailerBlock (uint32_t uiBlock)
mauroar211 0:b805b487fbef 364 {
mauroar211 0:b805b487fbef 365 // Test if we are in the small or big sectors
mauroar211 0:b805b487fbef 366 if (uiBlock < 128)
mauroar211 0:b805b487fbef 367 return ((uiBlock + 1) % 4 == 0);
mauroar211 0:b805b487fbef 368 else
mauroar211 0:b805b487fbef 369 return ((uiBlock + 1) % 16 == 0);
mauroar211 0:b805b487fbef 370 }
mauroar211 0:b805b487fbef 371
mauroar211 0:b805b487fbef 372 /**************************************************************************/
mauroar211 0:b805b487fbef 373 /*!
mauroar211 0:b805b487fbef 374 Tries to authenticate a block of memory on a MIFARE card using the
mauroar211 0:b805b487fbef 375 INDATAEXCHANGE command. See section 7.3.8 of the PN532 User Manual
mauroar211 0:b805b487fbef 376 for more information on sending MIFARE and other commands.
mauroar211 0:b805b487fbef 377
mauroar211 0:b805b487fbef 378 @param uid Pointer to a byte array containing the card UID
mauroar211 0:b805b487fbef 379 @param uidLen The length (in bytes) of the card's UID (Should
mauroar211 0:b805b487fbef 380 be 4 for MIFARE Classic)
mauroar211 0:b805b487fbef 381 @param blockNumber The block number to authenticate. (0..63 for
mauroar211 0:b805b487fbef 382 1KB cards, and 0..255 for 4KB cards).
mauroar211 0:b805b487fbef 383 @param keyNumber Which key type to use during authentication
mauroar211 0:b805b487fbef 384 (0 = MIFARE_CMD_AUTH_A, 1 = MIFARE_CMD_AUTH_B)
mauroar211 0:b805b487fbef 385 @param keyData Pointer to a byte array containing the 6 bytes
mauroar211 0:b805b487fbef 386 key value
mauroar211 0:b805b487fbef 387
mauroar211 0:b805b487fbef 388 @returns 1 if everything executed properly, 0 for an error
mauroar211 0:b805b487fbef 389 */
mauroar211 0:b805b487fbef 390 /**************************************************************************/
mauroar211 0:b805b487fbef 391 uint8_t PN532::mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData)
mauroar211 0:b805b487fbef 392 {
mauroar211 0:b805b487fbef 393 uint8_t i;
mauroar211 0:b805b487fbef 394
mauroar211 0:b805b487fbef 395 // Hang on to the key and uid data
mauroar211 0:b805b487fbef 396 memcpy (_key, keyData, 6);
mauroar211 0:b805b487fbef 397 memcpy (_uid, uid, uidLen);
mauroar211 0:b805b487fbef 398 _uidLen = uidLen;
mauroar211 0:b805b487fbef 399
mauroar211 0:b805b487fbef 400 // Prepare the authentication command //
mauroar211 0:b805b487fbef 401 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE; /* Data Exchange Header */
mauroar211 0:b805b487fbef 402 pn532_packetbuffer[1] = 1; /* Max card numbers */
mauroar211 0:b805b487fbef 403 pn532_packetbuffer[2] = (keyNumber) ? MIFARE_CMD_AUTH_B : MIFARE_CMD_AUTH_A;
mauroar211 0:b805b487fbef 404 pn532_packetbuffer[3] = blockNumber; /* Block Number (1K = 0..63, 4K = 0..255 */
mauroar211 0:b805b487fbef 405 memcpy (pn532_packetbuffer + 4, _key, 6);
mauroar211 0:b805b487fbef 406 for (i = 0; i < _uidLen; i++) {
mauroar211 0:b805b487fbef 407 pn532_packetbuffer[10 + i] = _uid[i]; /* 4 bytes card ID */
mauroar211 0:b805b487fbef 408 }
mauroar211 0:b805b487fbef 409
mauroar211 0:b805b487fbef 410 if (HAL(writeCommand)(pn532_packetbuffer, 10 + _uidLen))
mauroar211 0:b805b487fbef 411 return 0;
mauroar211 0:b805b487fbef 412
mauroar211 0:b805b487fbef 413 // Read the response packet
mauroar211 0:b805b487fbef 414 HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer));
mauroar211 0:b805b487fbef 415
mauroar211 0:b805b487fbef 416 // Check if the response is valid and we are authenticated???
mauroar211 0:b805b487fbef 417 // for an auth success it should be bytes 5-7: 0xD5 0x41 0x00
mauroar211 0:b805b487fbef 418 // Mifare auth error is technically byte 7: 0x14 but anything other and 0x00 is not good
mauroar211 0:b805b487fbef 419 if (pn532_packetbuffer[0] != 0x00) {
mauroar211 0:b805b487fbef 420 DMSG("Authentification failed\n");
mauroar211 0:b805b487fbef 421 return 0;
mauroar211 0:b805b487fbef 422 }
mauroar211 0:b805b487fbef 423
mauroar211 0:b805b487fbef 424 return 1;
mauroar211 0:b805b487fbef 425 }
mauroar211 0:b805b487fbef 426
mauroar211 0:b805b487fbef 427 /**************************************************************************/
mauroar211 0:b805b487fbef 428 /*!
mauroar211 0:b805b487fbef 429 Tries to read an entire 16-bytes data block at the specified block
mauroar211 0:b805b487fbef 430 address.
mauroar211 0:b805b487fbef 431
mauroar211 0:b805b487fbef 432 @param blockNumber The block number to authenticate. (0..63 for
mauroar211 0:b805b487fbef 433 1KB cards, and 0..255 for 4KB cards).
mauroar211 0:b805b487fbef 434 @param data Pointer to the byte array that will hold the
mauroar211 0:b805b487fbef 435 retrieved data (if any)
mauroar211 0:b805b487fbef 436
mauroar211 0:b805b487fbef 437 @returns 1 if everything executed properly, 0 for an error
mauroar211 0:b805b487fbef 438 */
mauroar211 0:b805b487fbef 439 /**************************************************************************/
mauroar211 0:b805b487fbef 440 uint8_t PN532::mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data)
mauroar211 0:b805b487fbef 441 {
mauroar211 0:b805b487fbef 442 DMSG("Trying to read 16 bytes from block ");
mauroar211 0:b805b487fbef 443 DMSG_INT(blockNumber);
mauroar211 0:b805b487fbef 444
mauroar211 0:b805b487fbef 445 /* Prepare the command */
mauroar211 0:b805b487fbef 446 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
mauroar211 0:b805b487fbef 447 pn532_packetbuffer[1] = 1; /* Card number */
mauroar211 0:b805b487fbef 448 pn532_packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
mauroar211 0:b805b487fbef 449 pn532_packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
mauroar211 0:b805b487fbef 450
mauroar211 0:b805b487fbef 451 /* Send the command */
mauroar211 0:b805b487fbef 452 if (HAL(writeCommand)(pn532_packetbuffer, 4)) {
mauroar211 0:b805b487fbef 453 return 0;
mauroar211 0:b805b487fbef 454 }
mauroar211 0:b805b487fbef 455
mauroar211 0:b805b487fbef 456 /* Read the response packet */
mauroar211 0:b805b487fbef 457 HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer));
mauroar211 0:b805b487fbef 458
mauroar211 0:b805b487fbef 459 /* If byte 8 isn't 0x00 we probably have an error */
mauroar211 0:b805b487fbef 460 if (pn532_packetbuffer[0] != 0x00) {
mauroar211 0:b805b487fbef 461 return 0;
mauroar211 0:b805b487fbef 462 }
mauroar211 0:b805b487fbef 463
mauroar211 0:b805b487fbef 464 /* Copy the 16 data bytes to the output buffer */
mauroar211 0:b805b487fbef 465 /* Block content starts at byte 9 of a valid response */
mauroar211 0:b805b487fbef 466 memcpy (data, pn532_packetbuffer + 1, 16);
mauroar211 0:b805b487fbef 467
mauroar211 0:b805b487fbef 468 return 1;
mauroar211 0:b805b487fbef 469 }
mauroar211 0:b805b487fbef 470
mauroar211 0:b805b487fbef 471 /**************************************************************************/
mauroar211 0:b805b487fbef 472 /*!
mauroar211 0:b805b487fbef 473 Tries to write an entire 16-bytes data block at the specified block
mauroar211 0:b805b487fbef 474 address.
mauroar211 0:b805b487fbef 475
mauroar211 0:b805b487fbef 476 @param blockNumber The block number to authenticate. (0..63 for
mauroar211 0:b805b487fbef 477 1KB cards, and 0..255 for 4KB cards).
mauroar211 0:b805b487fbef 478 @param data The byte array that contains the data to write.
mauroar211 0:b805b487fbef 479
mauroar211 0:b805b487fbef 480 @returns 1 if everything executed properly, 0 for an error
mauroar211 0:b805b487fbef 481 */
mauroar211 0:b805b487fbef 482 /**************************************************************************/
mauroar211 0:b805b487fbef 483 uint8_t PN532::mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data)
mauroar211 0:b805b487fbef 484 {
mauroar211 0:b805b487fbef 485 /* Prepare the first command */
mauroar211 0:b805b487fbef 486 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
mauroar211 0:b805b487fbef 487 pn532_packetbuffer[1] = 1; /* Card number */
mauroar211 0:b805b487fbef 488 pn532_packetbuffer[2] = MIFARE_CMD_WRITE; /* Mifare Write command = 0xA0 */
mauroar211 0:b805b487fbef 489 pn532_packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */
mauroar211 0:b805b487fbef 490 memcpy (pn532_packetbuffer + 4, data, 16); /* Data Payload */
mauroar211 0:b805b487fbef 491
mauroar211 0:b805b487fbef 492 /* Send the command */
mauroar211 0:b805b487fbef 493 if (HAL(writeCommand)(pn532_packetbuffer, 20)) {
mauroar211 0:b805b487fbef 494 return 0;
mauroar211 0:b805b487fbef 495 }
mauroar211 0:b805b487fbef 496
mauroar211 0:b805b487fbef 497 /* Read the response packet */
mauroar211 0:b805b487fbef 498 return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)));
mauroar211 0:b805b487fbef 499 }
mauroar211 0:b805b487fbef 500
mauroar211 0:b805b487fbef 501 /**************************************************************************/
mauroar211 0:b805b487fbef 502 /*!
mauroar211 0:b805b487fbef 503 Formats a Mifare Classic card to store NDEF Records
mauroar211 0:b805b487fbef 504
mauroar211 0:b805b487fbef 505 @returns 1 if everything executed properly, 0 for an error
mauroar211 0:b805b487fbef 506 */
mauroar211 0:b805b487fbef 507 /**************************************************************************/
mauroar211 0:b805b487fbef 508 uint8_t PN532::mifareclassic_FormatNDEF (void)
mauroar211 0:b805b487fbef 509 {
mauroar211 0:b805b487fbef 510 uint8_t sectorbuffer1[16] = {0x14, 0x01, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1};
mauroar211 0:b805b487fbef 511 uint8_t sectorbuffer2[16] = {0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1, 0x03, 0xE1};
mauroar211 0:b805b487fbef 512 uint8_t sectorbuffer3[16] = {0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0x78, 0x77, 0x88, 0xC1, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
mauroar211 0:b805b487fbef 513
mauroar211 0:b805b487fbef 514 // Note 0xA0 0xA1 0xA2 0xA3 0xA4 0xA5 must be used for key A
mauroar211 0:b805b487fbef 515 // for the MAD sector in NDEF records (sector 0)
mauroar211 0:b805b487fbef 516
mauroar211 0:b805b487fbef 517 // Write block 1 and 2 to the card
mauroar211 0:b805b487fbef 518 if (!(mifareclassic_WriteDataBlock (1, sectorbuffer1)))
mauroar211 0:b805b487fbef 519 return 0;
mauroar211 0:b805b487fbef 520 if (!(mifareclassic_WriteDataBlock (2, sectorbuffer2)))
mauroar211 0:b805b487fbef 521 return 0;
mauroar211 0:b805b487fbef 522 // Write key A and access rights card
mauroar211 0:b805b487fbef 523 if (!(mifareclassic_WriteDataBlock (3, sectorbuffer3)))
mauroar211 0:b805b487fbef 524 return 0;
mauroar211 0:b805b487fbef 525
mauroar211 0:b805b487fbef 526 // Seems that everything was OK (?!)
mauroar211 0:b805b487fbef 527 return 1;
mauroar211 0:b805b487fbef 528 }
mauroar211 0:b805b487fbef 529
mauroar211 0:b805b487fbef 530 /**************************************************************************/
mauroar211 0:b805b487fbef 531 /*!
mauroar211 0:b805b487fbef 532 Writes an NDEF URI Record to the specified sector (1..15)
mauroar211 0:b805b487fbef 533
mauroar211 0:b805b487fbef 534 Note that this function assumes that the Mifare Classic card is
mauroar211 0:b805b487fbef 535 already formatted to work as an "NFC Forum Tag" and uses a MAD1
mauroar211 0:b805b487fbef 536 file system. You can use the NXP TagWriter app on Android to
mauroar211 0:b805b487fbef 537 properly format cards for this.
mauroar211 0:b805b487fbef 538
mauroar211 0:b805b487fbef 539 @param sectorNumber The sector that the URI record should be written
mauroar211 0:b805b487fbef 540 to (can be 1..15 for a 1K card)
mauroar211 0:b805b487fbef 541 @param uriIdentifier The uri identifier code (0 = none, 0x01 =
mauroar211 0:b805b487fbef 542 "http://www.", etc.)
mauroar211 0:b805b487fbef 543 @param url The uri text to write (max 38 characters).
mauroar211 0:b805b487fbef 544
mauroar211 0:b805b487fbef 545 @returns 1 if everything executed properly, 0 for an error
mauroar211 0:b805b487fbef 546 */
mauroar211 0:b805b487fbef 547 /**************************************************************************/
mauroar211 0:b805b487fbef 548 uint8_t PN532::mifareclassic_WriteNDEFURI (uint8_t sectorNumber, uint8_t uriIdentifier, const char *url)
mauroar211 0:b805b487fbef 549 {
mauroar211 0:b805b487fbef 550 // Figure out how long the string is
mauroar211 0:b805b487fbef 551 uint8_t len = strlen(url);
mauroar211 0:b805b487fbef 552
mauroar211 0:b805b487fbef 553 // Make sure we're within a 1K limit for the sector number
mauroar211 0:b805b487fbef 554 if ((sectorNumber < 1) || (sectorNumber > 15))
mauroar211 0:b805b487fbef 555 return 0;
mauroar211 0:b805b487fbef 556
mauroar211 0:b805b487fbef 557 // Make sure the URI payload is between 1 and 38 chars
mauroar211 0:b805b487fbef 558 if ((len < 1) || (len > 38))
mauroar211 0:b805b487fbef 559 return 0;
mauroar211 0:b805b487fbef 560
mauroar211 0:b805b487fbef 561 // Note 0xD3 0xF7 0xD3 0xF7 0xD3 0xF7 must be used for key A
mauroar211 0:b805b487fbef 562 // in NDEF records
mauroar211 0:b805b487fbef 563
mauroar211 0:b805b487fbef 564 // Setup the sector buffer (w/pre-formatted TLV wrapper and NDEF message)
mauroar211 0:b805b487fbef 565 uint8_t sectorbuffer1[16] = {0x00, 0x00, 0x03, len + 5, 0xD1, 0x01, len + 1, 0x55, uriIdentifier, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
mauroar211 0:b805b487fbef 566 uint8_t sectorbuffer2[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
mauroar211 0:b805b487fbef 567 uint8_t sectorbuffer3[16] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
mauroar211 0:b805b487fbef 568 uint8_t sectorbuffer4[16] = {0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7, 0x7F, 0x07, 0x88, 0x40, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF};
mauroar211 0:b805b487fbef 569 if (len <= 6) {
mauroar211 0:b805b487fbef 570 // Unlikely we'll get a url this short, but why not ...
mauroar211 0:b805b487fbef 571 memcpy (sectorbuffer1 + 9, url, len);
mauroar211 0:b805b487fbef 572 sectorbuffer1[len + 9] = 0xFE;
mauroar211 0:b805b487fbef 573 } else if (len == 7) {
mauroar211 0:b805b487fbef 574 // 0xFE needs to be wrapped around to next block
mauroar211 0:b805b487fbef 575 memcpy (sectorbuffer1 + 9, url, len);
mauroar211 0:b805b487fbef 576 sectorbuffer2[0] = 0xFE;
mauroar211 0:b805b487fbef 577 } else if ((len > 7) || (len <= 22)) {
mauroar211 0:b805b487fbef 578 // Url fits in two blocks
mauroar211 0:b805b487fbef 579 memcpy (sectorbuffer1 + 9, url, 7);
mauroar211 0:b805b487fbef 580 memcpy (sectorbuffer2, url + 7, len - 7);
mauroar211 0:b805b487fbef 581 sectorbuffer2[len - 7] = 0xFE;
mauroar211 0:b805b487fbef 582 } else if (len == 23) {
mauroar211 0:b805b487fbef 583 // 0xFE needs to be wrapped around to final block
mauroar211 0:b805b487fbef 584 memcpy (sectorbuffer1 + 9, url, 7);
mauroar211 0:b805b487fbef 585 memcpy (sectorbuffer2, url + 7, len - 7);
mauroar211 0:b805b487fbef 586 sectorbuffer3[0] = 0xFE;
mauroar211 0:b805b487fbef 587 } else {
mauroar211 0:b805b487fbef 588 // Url fits in three blocks
mauroar211 0:b805b487fbef 589 memcpy (sectorbuffer1 + 9, url, 7);
mauroar211 0:b805b487fbef 590 memcpy (sectorbuffer2, url + 7, 16);
mauroar211 0:b805b487fbef 591 memcpy (sectorbuffer3, url + 23, len - 24);
mauroar211 0:b805b487fbef 592 sectorbuffer3[len - 22] = 0xFE;
mauroar211 0:b805b487fbef 593 }
mauroar211 0:b805b487fbef 594
mauroar211 0:b805b487fbef 595 // Now write all three blocks back to the card
mauroar211 0:b805b487fbef 596 if (!(mifareclassic_WriteDataBlock (sectorNumber * 4, sectorbuffer1)))
mauroar211 0:b805b487fbef 597 return 0;
mauroar211 0:b805b487fbef 598 if (!(mifareclassic_WriteDataBlock ((sectorNumber * 4) + 1, sectorbuffer2)))
mauroar211 0:b805b487fbef 599 return 0;
mauroar211 0:b805b487fbef 600 if (!(mifareclassic_WriteDataBlock ((sectorNumber * 4) + 2, sectorbuffer3)))
mauroar211 0:b805b487fbef 601 return 0;
mauroar211 0:b805b487fbef 602 if (!(mifareclassic_WriteDataBlock ((sectorNumber * 4) + 3, sectorbuffer4)))
mauroar211 0:b805b487fbef 603 return 0;
mauroar211 0:b805b487fbef 604
mauroar211 0:b805b487fbef 605 // Seems that everything was OK (?!)
mauroar211 0:b805b487fbef 606 return 1;
mauroar211 0:b805b487fbef 607 }
mauroar211 0:b805b487fbef 608
mauroar211 0:b805b487fbef 609 /***** Mifare Ultralight Functions ******/
mauroar211 0:b805b487fbef 610
mauroar211 0:b805b487fbef 611 /**************************************************************************/
mauroar211 0:b805b487fbef 612 /*!
mauroar211 0:b805b487fbef 613 Tries to read an entire 4-bytes page at the specified address.
mauroar211 0:b805b487fbef 614
mauroar211 0:b805b487fbef 615 @param page The page number (0..63 in most cases)
mauroar211 0:b805b487fbef 616 @param buffer Pointer to the byte array that will hold the
mauroar211 0:b805b487fbef 617 retrieved data (if any)
mauroar211 0:b805b487fbef 618 */
mauroar211 0:b805b487fbef 619 /**************************************************************************/
mauroar211 0:b805b487fbef 620 uint8_t PN532::mifareultralight_ReadPage (uint8_t page, uint8_t *buffer)
mauroar211 0:b805b487fbef 621 {
mauroar211 0:b805b487fbef 622 if (page >= 64) {
mauroar211 0:b805b487fbef 623 DMSG("Page value out of range\n");
mauroar211 0:b805b487fbef 624 return 0;
mauroar211 0:b805b487fbef 625 }
mauroar211 0:b805b487fbef 626
mauroar211 0:b805b487fbef 627 /* Prepare the command */
mauroar211 0:b805b487fbef 628 pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
mauroar211 0:b805b487fbef 629 pn532_packetbuffer[1] = 1; /* Card number */
mauroar211 0:b805b487fbef 630 pn532_packetbuffer[2] = MIFARE_CMD_READ; /* Mifare Read command = 0x30 */
mauroar211 0:b805b487fbef 631 pn532_packetbuffer[3] = page; /* Page Number (0..63 in most cases) */
mauroar211 0:b805b487fbef 632
mauroar211 0:b805b487fbef 633 /* Send the command */
mauroar211 0:b805b487fbef 634 if (HAL(writeCommand)(pn532_packetbuffer, 4)) {
mauroar211 0:b805b487fbef 635 return 0;
mauroar211 0:b805b487fbef 636 }
mauroar211 0:b805b487fbef 637
mauroar211 0:b805b487fbef 638 /* Read the response packet */
mauroar211 0:b805b487fbef 639 HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer));
mauroar211 0:b805b487fbef 640
mauroar211 0:b805b487fbef 641 /* If byte 8 isn't 0x00 we probably have an error */
mauroar211 0:b805b487fbef 642 if (pn532_packetbuffer[0] == 0x00) {
mauroar211 0:b805b487fbef 643 /* Copy the 4 data bytes to the output buffer */
mauroar211 0:b805b487fbef 644 /* Block content starts at byte 9 of a valid response */
mauroar211 0:b805b487fbef 645 /* Note that the command actually reads 16 bytes or 4 */
mauroar211 0:b805b487fbef 646 /* pages at a time ... we simply discard the last 12 */
mauroar211 0:b805b487fbef 647 /* bytes */
mauroar211 0:b805b487fbef 648 memcpy (buffer, pn532_packetbuffer + 1, 4);
mauroar211 0:b805b487fbef 649 } else {
mauroar211 0:b805b487fbef 650 return 0;
mauroar211 0:b805b487fbef 651 }
mauroar211 0:b805b487fbef 652
mauroar211 0:b805b487fbef 653 // Return OK signal
mauroar211 0:b805b487fbef 654 return 1;
mauroar211 0:b805b487fbef 655 }
mauroar211 0:b805b487fbef 656
mauroar211 0:b805b487fbef 657 /**************************************************************************/
mauroar211 0:b805b487fbef 658 /*!
mauroar211 0:b805b487fbef 659 @brief Exchanges an APDU with the currently inlisted peer
mauroar211 0:b805b487fbef 660
mauroar211 0:b805b487fbef 661 @param send Pointer to data to send
mauroar211 0:b805b487fbef 662 @param sendLength Length of the data to send
mauroar211 0:b805b487fbef 663 @param response Pointer to response data
mauroar211 0:b805b487fbef 664 @param responseLength Pointer to the response data length
mauroar211 0:b805b487fbef 665 */
mauroar211 0:b805b487fbef 666 /**************************************************************************/
mauroar211 0:b805b487fbef 667 bool PN532::inDataExchange(uint8_t *send, uint8_t sendLength, uint8_t *response, uint8_t *responseLength)
mauroar211 0:b805b487fbef 668 {
mauroar211 0:b805b487fbef 669 //uint8_t i;
mauroar211 0:b805b487fbef 670
mauroar211 0:b805b487fbef 671 pn532_packetbuffer[0] = 0x40; // PN532_COMMAND_INDATAEXCHANGE;
mauroar211 0:b805b487fbef 672 pn532_packetbuffer[1] = inListedTag;
mauroar211 0:b805b487fbef 673
mauroar211 0:b805b487fbef 674 if (HAL(writeCommand)(pn532_packetbuffer, 2, send, sendLength)) {
mauroar211 0:b805b487fbef 675 return false;
mauroar211 0:b805b487fbef 676 }
mauroar211 0:b805b487fbef 677
mauroar211 0:b805b487fbef 678 int16_t status = HAL(readResponse)(response, *responseLength, 1000);
mauroar211 0:b805b487fbef 679 if (status < 0) {
mauroar211 0:b805b487fbef 680 return false;
mauroar211 0:b805b487fbef 681 }
mauroar211 0:b805b487fbef 682
mauroar211 0:b805b487fbef 683 if ((response[0] & 0x3f) != 0) {
mauroar211 0:b805b487fbef 684 DMSG("Status code indicates an error\n");
mauroar211 0:b805b487fbef 685 return false;
mauroar211 0:b805b487fbef 686 }
mauroar211 0:b805b487fbef 687
mauroar211 0:b805b487fbef 688 uint8_t length = status;
mauroar211 0:b805b487fbef 689 length -= 1;
mauroar211 0:b805b487fbef 690
mauroar211 0:b805b487fbef 691 if (length > *responseLength) {
mauroar211 0:b805b487fbef 692 length = *responseLength; // silent truncation...
mauroar211 0:b805b487fbef 693 }
mauroar211 0:b805b487fbef 694
mauroar211 0:b805b487fbef 695 for (uint8_t i = 0; i < length; i++) {
mauroar211 0:b805b487fbef 696 response[i] = response[i + 1];
mauroar211 0:b805b487fbef 697 }
mauroar211 0:b805b487fbef 698 *responseLength = length;
mauroar211 0:b805b487fbef 699
mauroar211 0:b805b487fbef 700 return true;
mauroar211 0:b805b487fbef 701 }
mauroar211 0:b805b487fbef 702
mauroar211 0:b805b487fbef 703 /**************************************************************************/
mauroar211 0:b805b487fbef 704 /*!
mauroar211 0:b805b487fbef 705 @brief 'InLists' a passive target. PN532 acting as reader/initiator,
mauroar211 0:b805b487fbef 706 peer acting as card/responder.
mauroar211 0:b805b487fbef 707 */
mauroar211 0:b805b487fbef 708 /**************************************************************************/
mauroar211 0:b805b487fbef 709 bool PN532::inListPassiveTarget()
mauroar211 0:b805b487fbef 710 {
mauroar211 0:b805b487fbef 711 pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
mauroar211 0:b805b487fbef 712 pn532_packetbuffer[1] = 1;
mauroar211 0:b805b487fbef 713 pn532_packetbuffer[2] = 0;
mauroar211 0:b805b487fbef 714
mauroar211 0:b805b487fbef 715 DMSG("inList passive target\n");
mauroar211 0:b805b487fbef 716
mauroar211 0:b805b487fbef 717 if (HAL(writeCommand)(pn532_packetbuffer, 3)) {
mauroar211 0:b805b487fbef 718 return false;
mauroar211 0:b805b487fbef 719 }
mauroar211 0:b805b487fbef 720
mauroar211 0:b805b487fbef 721 int16_t status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), 30000);
mauroar211 0:b805b487fbef 722 if (status < 0) {
mauroar211 0:b805b487fbef 723 return false;
mauroar211 0:b805b487fbef 724 }
mauroar211 0:b805b487fbef 725
mauroar211 0:b805b487fbef 726 if (pn532_packetbuffer[0] != 1) {
mauroar211 0:b805b487fbef 727 return false;
mauroar211 0:b805b487fbef 728 }
mauroar211 0:b805b487fbef 729
mauroar211 0:b805b487fbef 730 inListedTag = pn532_packetbuffer[1];
mauroar211 0:b805b487fbef 731
mauroar211 0:b805b487fbef 732 return true;
mauroar211 0:b805b487fbef 733 }
mauroar211 0:b805b487fbef 734
mauroar211 0:b805b487fbef 735 int8_t PN532::tgInitAsTarget(const uint8_t* command, const uint8_t len, const uint16_t timeout){
mauroar211 0:b805b487fbef 736
mauroar211 0:b805b487fbef 737 int8_t status = HAL(writeCommand)(command, len);
mauroar211 0:b805b487fbef 738 if (status < 0) {
mauroar211 0:b805b487fbef 739 return -1;
mauroar211 0:b805b487fbef 740 }
mauroar211 0:b805b487fbef 741
mauroar211 0:b805b487fbef 742 status = HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), timeout);
mauroar211 0:b805b487fbef 743 if (status > 0) {
mauroar211 0:b805b487fbef 744 return 1;
mauroar211 0:b805b487fbef 745 } else if (PN532_TIMEOUT == status) {
mauroar211 0:b805b487fbef 746 return 0;
mauroar211 0:b805b487fbef 747 } else {
mauroar211 0:b805b487fbef 748 return -2;
mauroar211 0:b805b487fbef 749 }
mauroar211 0:b805b487fbef 750 }
mauroar211 0:b805b487fbef 751
mauroar211 0:b805b487fbef 752 /**
mauroar211 0:b805b487fbef 753 * Peer to Peer
mauroar211 0:b805b487fbef 754 */
mauroar211 0:b805b487fbef 755 int8_t PN532::tgInitAsTarget(uint16_t timeout)
mauroar211 0:b805b487fbef 756 {
mauroar211 0:b805b487fbef 757 const uint8_t command[] = {
mauroar211 0:b805b487fbef 758 PN532_COMMAND_TGINITASTARGET,
mauroar211 0:b805b487fbef 759 0,
mauroar211 0:b805b487fbef 760 0x00, 0x00, //SENS_RES
mauroar211 0:b805b487fbef 761 0x00, 0x00, 0x00, //NFCID1
mauroar211 0:b805b487fbef 762 0x40, //SEL_RES
mauroar211 0:b805b487fbef 763
mauroar211 0:b805b487fbef 764 0x01, 0xFE, 0x0F, 0xBB, 0xBA, 0xA6, 0xC9, 0x89, // POL_RES
mauroar211 0:b805b487fbef 765 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
mauroar211 0:b805b487fbef 766 0xFF, 0xFF,
mauroar211 0:b805b487fbef 767
mauroar211 0:b805b487fbef 768 0x01, 0xFE, 0x0F, 0xBB, 0xBA, 0xA6, 0xC9, 0x89, 0x00, 0x00, //NFCID3t: Change this to desired value
mauroar211 0:b805b487fbef 769
mauroar211 0:b805b487fbef 770 0x06, 0x46, 0x66, 0x6D, 0x01, 0x01, 0x10, 0x00// LLCP magic number and version parameter
mauroar211 0:b805b487fbef 771 };
mauroar211 0:b805b487fbef 772 return tgInitAsTarget(command, sizeof(command), timeout);
mauroar211 0:b805b487fbef 773 }
mauroar211 0:b805b487fbef 774
mauroar211 0:b805b487fbef 775 int16_t PN532::tgGetData(uint8_t *buf, uint8_t len)
mauroar211 0:b805b487fbef 776 {
mauroar211 0:b805b487fbef 777 buf[0] = PN532_COMMAND_TGGETDATA;
mauroar211 0:b805b487fbef 778
mauroar211 0:b805b487fbef 779 if (HAL(writeCommand)(buf, 1)) {
mauroar211 0:b805b487fbef 780 return -1;
mauroar211 0:b805b487fbef 781 }
mauroar211 0:b805b487fbef 782
mauroar211 0:b805b487fbef 783 int16_t status = HAL(readResponse)(buf, len, 3000);
mauroar211 0:b805b487fbef 784 if (0 >= status) {
mauroar211 0:b805b487fbef 785 return status;
mauroar211 0:b805b487fbef 786 }
mauroar211 0:b805b487fbef 787
mauroar211 0:b805b487fbef 788 uint16_t length = status - 1;
mauroar211 0:b805b487fbef 789
mauroar211 0:b805b487fbef 790
mauroar211 0:b805b487fbef 791 if (buf[0] != 0) {
mauroar211 0:b805b487fbef 792 DMSG("status is not ok\n");
mauroar211 0:b805b487fbef 793 return -5;
mauroar211 0:b805b487fbef 794 }
mauroar211 0:b805b487fbef 795
mauroar211 0:b805b487fbef 796 for (uint8_t i = 0; i < length; i++) {
mauroar211 0:b805b487fbef 797 buf[i] = buf[i + 1];
mauroar211 0:b805b487fbef 798 }
mauroar211 0:b805b487fbef 799
mauroar211 0:b805b487fbef 800 return length;
mauroar211 0:b805b487fbef 801 }
mauroar211 0:b805b487fbef 802
mauroar211 0:b805b487fbef 803 bool PN532::tgSetData(const uint8_t *header, uint8_t hlen, const uint8_t *body, uint8_t blen)
mauroar211 0:b805b487fbef 804 {
mauroar211 0:b805b487fbef 805 if (hlen > (sizeof(pn532_packetbuffer) - 1)) {
mauroar211 0:b805b487fbef 806 return false;
mauroar211 0:b805b487fbef 807 }
mauroar211 0:b805b487fbef 808
mauroar211 0:b805b487fbef 809 for (int8_t i = hlen - 1; i >= 0; i--){
mauroar211 0:b805b487fbef 810 pn532_packetbuffer[i + 1] = header[i];
mauroar211 0:b805b487fbef 811 }
mauroar211 0:b805b487fbef 812 pn532_packetbuffer[0] = PN532_COMMAND_TGSETDATA;
mauroar211 0:b805b487fbef 813
mauroar211 0:b805b487fbef 814 if (HAL(writeCommand)(pn532_packetbuffer, hlen + 1, body, blen)) {
mauroar211 0:b805b487fbef 815 return false;
mauroar211 0:b805b487fbef 816 }
mauroar211 0:b805b487fbef 817
mauroar211 0:b805b487fbef 818 if (0 > HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), 3000)) {
mauroar211 0:b805b487fbef 819 return false;
mauroar211 0:b805b487fbef 820 }
mauroar211 0:b805b487fbef 821
mauroar211 0:b805b487fbef 822 if (0 != pn532_packetbuffer[0]) {
mauroar211 0:b805b487fbef 823 return false;
mauroar211 0:b805b487fbef 824 }
mauroar211 0:b805b487fbef 825
mauroar211 0:b805b487fbef 826 return true;
mauroar211 0:b805b487fbef 827 }
mauroar211 0:b805b487fbef 828
mauroar211 0:b805b487fbef 829 int16_t PN532::inRelease(const uint8_t relevantTarget){
mauroar211 0:b805b487fbef 830
mauroar211 0:b805b487fbef 831 pn532_packetbuffer[0] = PN532_COMMAND_INRELEASE;
mauroar211 0:b805b487fbef 832 pn532_packetbuffer[1] = relevantTarget;
mauroar211 0:b805b487fbef 833
mauroar211 0:b805b487fbef 834 if (HAL(writeCommand)(pn532_packetbuffer, 2)) {
mauroar211 0:b805b487fbef 835 return 0;
mauroar211 0:b805b487fbef 836 }
mauroar211 0:b805b487fbef 837
mauroar211 0:b805b487fbef 838 // read data packet
mauroar211 0:b805b487fbef 839 return HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer));
mauroar211 0:b805b487fbef 840 }
mauroar211 0:b805b487fbef 841
mauroar211 0:b805b487fbef 842