LEER TAG
Dependents: NFC_HTM_READ EMULAR_TAGS Escribir_tag NFC_HTM_READ-WRITE
PN532.cpp@1:a549ef8b142a, 2015-04-24 (annotated)
- 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?
User | Revision | Line number | New 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 |