Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Dependencies: mbed
NFC/NFC.cpp@12:4b881052e3db, 2015-12-12 (annotated)
- Committer:
- vhsstar
- Date:
- Sat Dec 12 03:20:40 2015 +0000
- Revision:
- 12:4b881052e3db
- Parent:
- 11:da190355ca49
All the things
Who changed what in which revision?
| User | Revision | Line number | New contents of line |
|---|---|---|---|
| vhsstar | 11:da190355ca49 | 1 | #include "NFC.h" |
| vhsstar | 11:da190355ca49 | 2 | |
| vhsstar | 11:da190355ca49 | 3 | DigitalOut led1(LED1); |
| vhsstar | 11:da190355ca49 | 4 | DigitalOut led2(LED2); |
| vhsstar | 11:da190355ca49 | 5 | DigitalOut led3(LED3); |
| vhsstar | 11:da190355ca49 | 6 | DigitalOut led4(LED4); |
| vhsstar | 11:da190355ca49 | 7 | |
| vhsstar | 11:da190355ca49 | 8 | //Create an NFC object with the given sda and scl lines |
| vhsstar | 11:da190355ca49 | 9 | NFC::NFC(PinName sda, PinName scl, PinName NFCIRQ, char NFCAddress):bus(sda, scl), address(NFCAddress), interrupt(NFCIRQ) |
| vhsstar | 11:da190355ca49 | 10 | { |
| vhsstar | 11:da190355ca49 | 11 | // configure board to read RFID tags |
| vhsstar | 11:da190355ca49 | 12 | SAMConfig(); |
| vhsstar | 11:da190355ca49 | 13 | } |
| vhsstar | 11:da190355ca49 | 14 | |
| vhsstar | 11:da190355ca49 | 15 | //Read an NFC tag into an NFCTag object |
| vhsstar | 11:da190355ca49 | 16 | bool NFC::readNFCTag(NFCTag* tag) |
| vhsstar | 11:da190355ca49 | 17 | { |
| vhsstar | 11:da190355ca49 | 18 | char success; |
| vhsstar | 11:da190355ca49 | 19 | char uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID |
| vhsstar | 11:da190355ca49 | 20 | char uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type) |
| vhsstar | 11:da190355ca49 | 21 | |
| vhsstar | 11:da190355ca49 | 22 | // Wait for an ISO14443A type cards (Mifare, etc.). When one is found |
| vhsstar | 11:da190355ca49 | 23 | // 'uid' will be populated with the UID, and uidLength will indicate |
| vhsstar | 11:da190355ca49 | 24 | // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight) |
| vhsstar | 11:da190355ca49 | 25 | success = readPassiveTargetID(0x00, uid, &uidLength, 100); |
| vhsstar | 11:da190355ca49 | 26 | |
| vhsstar | 11:da190355ca49 | 27 | |
| vhsstar | 11:da190355ca49 | 28 | if (success) |
| vhsstar | 11:da190355ca49 | 29 | { |
| vhsstar | 11:da190355ca49 | 30 | |
| vhsstar | 11:da190355ca49 | 31 | if (uidLength == 4) |
| vhsstar | 11:da190355ca49 | 32 | { |
| vhsstar | 11:da190355ca49 | 33 | // Now we need to try to authenticate it for read/write access |
| vhsstar | 11:da190355ca49 | 34 | // Try with the factory default KeyA: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF |
| vhsstar | 11:da190355ca49 | 35 | char keya[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
| vhsstar | 11:da190355ca49 | 36 | |
| vhsstar | 11:da190355ca49 | 37 | // Start with block 4 (the first block of sector 1) since sector 0 |
| vhsstar | 11:da190355ca49 | 38 | // contains the manufacturer data and it's probably better just |
| vhsstar | 11:da190355ca49 | 39 | // to leave it alone unless you know what you're doing |
| vhsstar | 11:da190355ca49 | 40 | success = mifareclassic_AuthenticateBlock(uid, uidLength, 4, 0, keya); |
| vhsstar | 11:da190355ca49 | 41 | |
| vhsstar | 11:da190355ca49 | 42 | if (success) |
| vhsstar | 11:da190355ca49 | 43 | { |
| vhsstar | 11:da190355ca49 | 44 | char data[16]; |
| vhsstar | 11:da190355ca49 | 45 | |
| vhsstar | 11:da190355ca49 | 46 | // If you want to write something to block 4 to test with, uncomment |
| vhsstar | 11:da190355ca49 | 47 | // the following line and this text should be read back in a minute |
| vhsstar | 11:da190355ca49 | 48 | success = mifareclassic_ReadDataBlock (4, data); |
| vhsstar | 11:da190355ca49 | 49 | if(success) |
| vhsstar | 11:da190355ca49 | 50 | { |
| vhsstar | 11:da190355ca49 | 51 | memcpy((*tag).itemString, (const char*)data, sizeof data); |
| vhsstar | 11:da190355ca49 | 52 | } |
| vhsstar | 11:da190355ca49 | 53 | } |
| vhsstar | 11:da190355ca49 | 54 | } |
| vhsstar | 11:da190355ca49 | 55 | else |
| vhsstar | 11:da190355ca49 | 56 | { |
| vhsstar | 11:da190355ca49 | 57 | success = 0; |
| vhsstar | 11:da190355ca49 | 58 | } |
| vhsstar | 11:da190355ca49 | 59 | } |
| vhsstar | 11:da190355ca49 | 60 | return success; |
| vhsstar | 11:da190355ca49 | 61 | } |
| vhsstar | 11:da190355ca49 | 62 | |
| vhsstar | 11:da190355ca49 | 63 | //Write a tag from an NFCTag object |
| vhsstar | 11:da190355ca49 | 64 | bool NFC::writeNFCTag(NFCTag* tag) |
| vhsstar | 11:da190355ca49 | 65 | { |
| vhsstar | 11:da190355ca49 | 66 | char success; |
| vhsstar | 11:da190355ca49 | 67 | char uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID |
| vhsstar | 11:da190355ca49 | 68 | char uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type) |
| vhsstar | 11:da190355ca49 | 69 | |
| vhsstar | 11:da190355ca49 | 70 | // Wait for an ISO14443A type cards (Mifare, etc.). When one is found |
| vhsstar | 11:da190355ca49 | 71 | // 'uid' will be populated with the UID, and uidLength will indicate |
| vhsstar | 11:da190355ca49 | 72 | // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight) |
| vhsstar | 11:da190355ca49 | 73 | success = readPassiveTargetID(0x00, uid, &uidLength, 100); |
| vhsstar | 11:da190355ca49 | 74 | |
| vhsstar | 11:da190355ca49 | 75 | |
| vhsstar | 11:da190355ca49 | 76 | if (success) |
| vhsstar | 11:da190355ca49 | 77 | { |
| vhsstar | 11:da190355ca49 | 78 | |
| vhsstar | 11:da190355ca49 | 79 | if (uidLength == 4) |
| vhsstar | 11:da190355ca49 | 80 | { |
| vhsstar | 11:da190355ca49 | 81 | // Now we need to try to authenticate it for read/write access |
| vhsstar | 11:da190355ca49 | 82 | // Try with the factory default KeyA: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF |
| vhsstar | 11:da190355ca49 | 83 | char keya[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF }; |
| vhsstar | 11:da190355ca49 | 84 | |
| vhsstar | 11:da190355ca49 | 85 | // Start with block 4 (the first block of sector 1) since sector 0 |
| vhsstar | 11:da190355ca49 | 86 | // contains the manufacturer data and it's probably better just |
| vhsstar | 11:da190355ca49 | 87 | // to leave it alone unless you know what you're doing |
| vhsstar | 11:da190355ca49 | 88 | success = mifareclassic_AuthenticateBlock(uid, uidLength, 4, 0, keya); |
| vhsstar | 11:da190355ca49 | 89 | |
| vhsstar | 11:da190355ca49 | 90 | if (success) |
| vhsstar | 11:da190355ca49 | 91 | { |
| vhsstar | 11:da190355ca49 | 92 | char data[16]; |
| vhsstar | 11:da190355ca49 | 93 | |
| vhsstar | 11:da190355ca49 | 94 | // If you want to write something to block 4 to test with, uncomment |
| vhsstar | 11:da190355ca49 | 95 | // the following line and this text should be read back in a minute |
| vhsstar | 11:da190355ca49 | 96 | memcpy(data, (const char*)(*tag).itemString, sizeof data); |
| vhsstar | 11:da190355ca49 | 97 | |
| vhsstar | 11:da190355ca49 | 98 | |
| vhsstar | 11:da190355ca49 | 99 | // Try to read the contents of block 4 |
| vhsstar | 11:da190355ca49 | 100 | success = mifareclassic_WriteDataBlock(4, data); |
| vhsstar | 11:da190355ca49 | 101 | } |
| vhsstar | 11:da190355ca49 | 102 | } |
| vhsstar | 11:da190355ca49 | 103 | } |
| vhsstar | 11:da190355ca49 | 104 | return success; |
| vhsstar | 11:da190355ca49 | 105 | } |
| vhsstar | 11:da190355ca49 | 106 | |
| vhsstar | 11:da190355ca49 | 107 | void NFC::progStatus(char status, int waitMs) |
| vhsstar | 11:da190355ca49 | 108 | { |
| vhsstar | 11:da190355ca49 | 109 | led1 = status & 0x01; |
| vhsstar | 11:da190355ca49 | 110 | led2 = (status >> 1) & 0x01; |
| vhsstar | 11:da190355ca49 | 111 | led3 = (status >> 2) & 0x01; |
| vhsstar | 11:da190355ca49 | 112 | led4 = (status >> 3) & 0x01; |
| vhsstar | 11:da190355ca49 | 113 | |
| vhsstar | 11:da190355ca49 | 114 | wait_ms(waitMs); |
| vhsstar | 11:da190355ca49 | 115 | } |
| vhsstar | 11:da190355ca49 | 116 | |
| vhsstar | 11:da190355ca49 | 117 | //Checks if the PN532 is busy |
| vhsstar | 11:da190355ca49 | 118 | char NFC::checkBusy(void) |
| vhsstar | 11:da190355ca49 | 119 | { |
| vhsstar | 11:da190355ca49 | 120 | return interrupt; |
| vhsstar | 11:da190355ca49 | 121 | } |
| vhsstar | 11:da190355ca49 | 122 | |
| vhsstar | 11:da190355ca49 | 123 | char NFC::readAck(void) |
| vhsstar | 11:da190355ca49 | 124 | { |
| vhsstar | 11:da190355ca49 | 125 | |
| vhsstar | 11:da190355ca49 | 126 | |
| vhsstar | 11:da190355ca49 | 127 | char rb[8] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}; |
| vhsstar | 11:da190355ca49 | 128 | char pn532ack[8] = {0x01, 0x00, 0x00, 0xFF, 0x00, 0xFF, 0x00, 0x00}; |
| vhsstar | 11:da190355ca49 | 129 | |
| vhsstar | 11:da190355ca49 | 130 | bus.read(address, rb, 8); |
| vhsstar | 11:da190355ca49 | 131 | |
| vhsstar | 11:da190355ca49 | 132 | char same = 1; |
| vhsstar | 11:da190355ca49 | 133 | |
| vhsstar | 11:da190355ca49 | 134 | for(int i = 0; i < 7; ++i) |
| vhsstar | 11:da190355ca49 | 135 | { |
| vhsstar | 11:da190355ca49 | 136 | if(rb[i] != pn532ack[i]) |
| vhsstar | 11:da190355ca49 | 137 | { |
| vhsstar | 11:da190355ca49 | 138 | same = 0; |
| vhsstar | 11:da190355ca49 | 139 | } |
| vhsstar | 11:da190355ca49 | 140 | } |
| vhsstar | 11:da190355ca49 | 141 | |
| vhsstar | 11:da190355ca49 | 142 | return same; |
| vhsstar | 11:da190355ca49 | 143 | } |
| vhsstar | 11:da190355ca49 | 144 | |
| vhsstar | 11:da190355ca49 | 145 | void NFC::wireReadData(char* buff, char n) |
| vhsstar | 11:da190355ca49 | 146 | { |
| vhsstar | 11:da190355ca49 | 147 | char inBuffer[n+2]; |
| vhsstar | 11:da190355ca49 | 148 | |
| vhsstar | 11:da190355ca49 | 149 | wait_ms(2);//Maybe not needed |
| vhsstar | 11:da190355ca49 | 150 | |
| vhsstar | 11:da190355ca49 | 151 | bus.read(address, inBuffer, n+2); |
| vhsstar | 11:da190355ca49 | 152 | |
| vhsstar | 11:da190355ca49 | 153 | for(int i =0; i < n; ++i) |
| vhsstar | 11:da190355ca49 | 154 | { |
| vhsstar | 11:da190355ca49 | 155 | buff[i] = inBuffer[i+1]; |
| vhsstar | 11:da190355ca49 | 156 | } |
| vhsstar | 11:da190355ca49 | 157 | |
| vhsstar | 11:da190355ca49 | 158 | } |
| vhsstar | 11:da190355ca49 | 159 | |
| vhsstar | 11:da190355ca49 | 160 | char NFC::sendCommand(char* cmd, char cmdlen) |
| vhsstar | 11:da190355ca49 | 161 | { |
| vhsstar | 11:da190355ca49 | 162 | |
| vhsstar | 11:da190355ca49 | 163 | //command buffer |
| vhsstar | 11:da190355ca49 | 164 | char cb[64]; |
| vhsstar | 11:da190355ca49 | 165 | //checksum, duh |
| vhsstar | 11:da190355ca49 | 166 | char checksum; |
| vhsstar | 11:da190355ca49 | 167 | |
| vhsstar | 11:da190355ca49 | 168 | //If the command is too long for the buffer, return error |
| vhsstar | 11:da190355ca49 | 169 | if(cmdlen > (64-8)) |
| vhsstar | 11:da190355ca49 | 170 | { |
| vhsstar | 11:da190355ca49 | 171 | return (unsigned char)-1; |
| vhsstar | 11:da190355ca49 | 172 | } |
| vhsstar | 11:da190355ca49 | 173 | |
| vhsstar | 11:da190355ca49 | 174 | //Initialize the NFC |
| vhsstar | 11:da190355ca49 | 175 | cb[0] = 0x00; //PN532_PREAMBLE |
| vhsstar | 11:da190355ca49 | 176 | cb[1] = 0x00; //PN532_STARTCODE1 |
| vhsstar | 11:da190355ca49 | 177 | cb[2] = 0xFF; //PN532_STARTCODE2 |
| vhsstar | 11:da190355ca49 | 178 | //Add to the checksum |
| vhsstar | 11:da190355ca49 | 179 | checksum = cb[0] + cb[1] + cb[2]; |
| vhsstar | 11:da190355ca49 | 180 | |
| vhsstar | 11:da190355ca49 | 181 | |
| vhsstar | 11:da190355ca49 | 182 | //Send the length of the command and bitflip of command(both plus one, for some reason, don't ask me) |
| vhsstar | 11:da190355ca49 | 183 | cb[3] = (cmdlen+1); |
| vhsstar | 11:da190355ca49 | 184 | cb[4] = (char)(~(cmdlen+1) + 1); //May cause some issues without char cast, look out for this |
| vhsstar | 11:da190355ca49 | 185 | |
| vhsstar | 11:da190355ca49 | 186 | |
| vhsstar | 11:da190355ca49 | 187 | //Send the direction of communication |
| vhsstar | 11:da190355ca49 | 188 | cb[5] = 0xD4; //PN532_HOSTTOPN532 |
| vhsstar | 11:da190355ca49 | 189 | //Add to the checksum |
| vhsstar | 11:da190355ca49 | 190 | checksum += cb[5]; |
| vhsstar | 11:da190355ca49 | 191 | |
| vhsstar | 11:da190355ca49 | 192 | |
| vhsstar | 11:da190355ca49 | 193 | //ACTUAL MESSAGE |
| vhsstar | 11:da190355ca49 | 194 | for(char i = 0; i < cmdlen; ++i) |
| vhsstar | 11:da190355ca49 | 195 | { |
| vhsstar | 11:da190355ca49 | 196 | //Send a byte of the actual command |
| vhsstar | 11:da190355ca49 | 197 | cb[6+i] = cmd[i]; |
| vhsstar | 11:da190355ca49 | 198 | //Add to the checksum |
| vhsstar | 11:da190355ca49 | 199 | checksum += cb[6+i]; |
| vhsstar | 11:da190355ca49 | 200 | } |
| vhsstar | 11:da190355ca49 | 201 | //cb[6] = 0x60; |
| vhsstar | 11:da190355ca49 | 202 | //cb[7] = 0x01; |
| vhsstar | 11:da190355ca49 | 203 | //cb[8] = 0x01; |
| vhsstar | 11:da190355ca49 | 204 | //cb[9] = 0x10; |
| vhsstar | 11:da190355ca49 | 205 | |
| vhsstar | 11:da190355ca49 | 206 | |
| vhsstar | 11:da190355ca49 | 207 | |
| vhsstar | 11:da190355ca49 | 208 | //End That SHEET |
| vhsstar | 11:da190355ca49 | 209 | cb[6+cmdlen] = ~(checksum); |
| vhsstar | 11:da190355ca49 | 210 | cb[7+cmdlen] = 0x00; |
| vhsstar | 11:da190355ca49 | 211 | bus.write(address, cb, cmdlen+8); |
| vhsstar | 11:da190355ca49 | 212 | return 1; |
| vhsstar | 11:da190355ca49 | 213 | } |
| vhsstar | 11:da190355ca49 | 214 | |
| vhsstar | 11:da190355ca49 | 215 | char NFC::sendCommandCheckAck (char* cmd, char cmdlen, int timeout) |
| vhsstar | 11:da190355ca49 | 216 | { |
| vhsstar | 11:da190355ca49 | 217 | int timer = 0; //Create the timer we'll add to |
| vhsstar | 11:da190355ca49 | 218 | if(sendCommand(cmd, cmdlen) == 1) |
| vhsstar | 11:da190355ca49 | 219 | { |
| vhsstar | 11:da190355ca49 | 220 | while(checkBusy()) //While IRQ line is busy |
| vhsstar | 11:da190355ca49 | 221 | { |
| vhsstar | 11:da190355ca49 | 222 | if(timeout != 0) //We only wait for a timeout if it isn't 0 |
| vhsstar | 11:da190355ca49 | 223 | { |
| vhsstar | 11:da190355ca49 | 224 | timer += 10; //Add the 10 miliseconds that we'll wait |
| vhsstar | 11:da190355ca49 | 225 | if(timer > timeout) |
| vhsstar | 11:da190355ca49 | 226 | { |
| vhsstar | 11:da190355ca49 | 227 | return 0; //Time ran out |
| vhsstar | 11:da190355ca49 | 228 | } |
| vhsstar | 11:da190355ca49 | 229 | } |
| vhsstar | 11:da190355ca49 | 230 | wait_ms(10); //Wait the 10 miliseconds that we'll wait |
| vhsstar | 11:da190355ca49 | 231 | } |
| vhsstar | 11:da190355ca49 | 232 | return readAck(); //Read and return acknowledge frame if not busy |
| vhsstar | 11:da190355ca49 | 233 | } |
| vhsstar | 11:da190355ca49 | 234 | return (unsigned char)-1; //return -1 if sendCommand doesn't return 1 (-1) |
| vhsstar | 11:da190355ca49 | 235 | } |
| vhsstar | 11:da190355ca49 | 236 | |
| vhsstar | 11:da190355ca49 | 237 | char NFC::SAMConfig(void) |
| vhsstar | 11:da190355ca49 | 238 | { |
| vhsstar | 11:da190355ca49 | 239 | char outBuffer[4] = {0x14, 0x01, 0x14, 0x01}; |
| vhsstar | 11:da190355ca49 | 240 | char inBuffer[8]; |
| vhsstar | 11:da190355ca49 | 241 | // PN532_COMMAND_SAMCONFIGURATION // normal mode // timeout 50ms // use IRQ pin! |
| vhsstar | 11:da190355ca49 | 242 | |
| vhsstar | 11:da190355ca49 | 243 | if (! sendCommandCheckAck(outBuffer, 4)) |
| vhsstar | 11:da190355ca49 | 244 | { |
| vhsstar | 11:da190355ca49 | 245 | return 0; |
| vhsstar | 11:da190355ca49 | 246 | } |
| vhsstar | 11:da190355ca49 | 247 | |
| vhsstar | 11:da190355ca49 | 248 | // read data packet |
| vhsstar | 11:da190355ca49 | 249 | wireReadData(inBuffer, 8); |
| vhsstar | 11:da190355ca49 | 250 | |
| vhsstar | 11:da190355ca49 | 251 | return (inBuffer[6] == 0x15); |
| vhsstar | 11:da190355ca49 | 252 | } |
| vhsstar | 11:da190355ca49 | 253 | |
| vhsstar | 11:da190355ca49 | 254 | char NFC::readPassiveTargetID(char cardbaudrate, char * uid, char * uidLength, char timeout) |
| vhsstar | 11:da190355ca49 | 255 | { |
| vhsstar | 11:da190355ca49 | 256 | char outBuffer[] = {0x4A, 0x01, cardbaudrate}; |
| vhsstar | 11:da190355ca49 | 257 | char inBuffer[20]; |
| vhsstar | 11:da190355ca49 | 258 | // PN532_COMMAND_INLISTPASSIVETARGET // max 1 cards at once (we can set this to 2 later) //cardbaud rate |
| vhsstar | 11:da190355ca49 | 259 | |
| vhsstar | 11:da190355ca49 | 260 | if (! sendCommandCheckAck(outBuffer, 3, timeout)) |
| vhsstar | 11:da190355ca49 | 261 | { |
| vhsstar | 11:da190355ca49 | 262 | return 0x0; // no cards read |
| vhsstar | 11:da190355ca49 | 263 | } |
| vhsstar | 11:da190355ca49 | 264 | |
| vhsstar | 11:da190355ca49 | 265 | // Wait for a card to enter the field |
| vhsstar | 11:da190355ca49 | 266 | //char status = 0x00; |
| vhsstar | 11:da190355ca49 | 267 | |
| vhsstar | 11:da190355ca49 | 268 | char timer = 0; |
| vhsstar | 11:da190355ca49 | 269 | while (checkBusy()) |
| vhsstar | 11:da190355ca49 | 270 | { |
| vhsstar | 11:da190355ca49 | 271 | if (timeout != 0) |
| vhsstar | 11:da190355ca49 | 272 | { |
| vhsstar | 11:da190355ca49 | 273 | timer+=10; |
| vhsstar | 11:da190355ca49 | 274 | if (timer > timeout) |
| vhsstar | 11:da190355ca49 | 275 | { |
| vhsstar | 11:da190355ca49 | 276 | return 0x0; |
| vhsstar | 11:da190355ca49 | 277 | } |
| vhsstar | 11:da190355ca49 | 278 | } |
| vhsstar | 11:da190355ca49 | 279 | wait_ms(10); |
| vhsstar | 11:da190355ca49 | 280 | } |
| vhsstar | 11:da190355ca49 | 281 | |
| vhsstar | 11:da190355ca49 | 282 | wireReadData(inBuffer, 20); |
| vhsstar | 11:da190355ca49 | 283 | |
| vhsstar | 11:da190355ca49 | 284 | if (inBuffer[7] != 1) |
| vhsstar | 11:da190355ca49 | 285 | { |
| vhsstar | 11:da190355ca49 | 286 | return 0; |
| vhsstar | 11:da190355ca49 | 287 | } |
| vhsstar | 11:da190355ca49 | 288 | |
| vhsstar | 11:da190355ca49 | 289 | int sens_res = inBuffer[9]; |
| vhsstar | 11:da190355ca49 | 290 | sens_res <<= 8; |
| vhsstar | 11:da190355ca49 | 291 | sens_res |= inBuffer[10]; |
| vhsstar | 11:da190355ca49 | 292 | |
| vhsstar | 11:da190355ca49 | 293 | /* Card appears to be Mifare Classic */ |
| vhsstar | 11:da190355ca49 | 294 | *uidLength = inBuffer[12]; |
| vhsstar | 11:da190355ca49 | 295 | |
| vhsstar | 11:da190355ca49 | 296 | for (char i=0; i < inBuffer[12]; i++) |
| vhsstar | 11:da190355ca49 | 297 | { |
| vhsstar | 11:da190355ca49 | 298 | uid[i] = inBuffer[13+i]; |
| vhsstar | 11:da190355ca49 | 299 | } |
| vhsstar | 11:da190355ca49 | 300 | |
| vhsstar | 11:da190355ca49 | 301 | return 1; |
| vhsstar | 11:da190355ca49 | 302 | } |
| vhsstar | 11:da190355ca49 | 303 | |
| vhsstar | 11:da190355ca49 | 304 | char NFC::mifareclassic_AuthenticateBlock (char * uid, char uidLen, int blockNumber, char keyNumber, char * keyData) |
| vhsstar | 11:da190355ca49 | 305 | { |
| vhsstar | 11:da190355ca49 | 306 | //char len; |
| vhsstar | 11:da190355ca49 | 307 | char i; |
| vhsstar | 11:da190355ca49 | 308 | |
| vhsstar | 11:da190355ca49 | 309 | char _uid[7]; // ISO14443A uid |
| vhsstar | 11:da190355ca49 | 310 | char _uidLen; // uid len |
| vhsstar | 11:da190355ca49 | 311 | char _key[6]; // Mifare Classic key |
| vhsstar | 11:da190355ca49 | 312 | |
| vhsstar | 11:da190355ca49 | 313 | // Hang on to the key and uid data |
| vhsstar | 11:da190355ca49 | 314 | memcpy (_key, keyData, 6); |
| vhsstar | 11:da190355ca49 | 315 | memcpy (_uid, uid, uidLen); |
| vhsstar | 11:da190355ca49 | 316 | _uidLen = uidLen; |
| vhsstar | 11:da190355ca49 | 317 | |
| vhsstar | 11:da190355ca49 | 318 | // Prepare the authentication command // |
| vhsstar | 11:da190355ca49 | 319 | pn532_packetbuffer[0] = 0x40; /* Data Exchange Header */ |
| vhsstar | 11:da190355ca49 | 320 | pn532_packetbuffer[1] = 1; /* Max card numbers */ |
| vhsstar | 11:da190355ca49 | 321 | pn532_packetbuffer[2] = (keyNumber) ? 0x61 : 0x60; |
| vhsstar | 11:da190355ca49 | 322 | pn532_packetbuffer[3] = blockNumber; /* Block Number (1K = 0..63, 4K = 0..255 */ |
| vhsstar | 11:da190355ca49 | 323 | memcpy (pn532_packetbuffer+4, _key, 6); |
| vhsstar | 11:da190355ca49 | 324 | for (i = 0; i < _uidLen; i++) |
| vhsstar | 11:da190355ca49 | 325 | { |
| vhsstar | 11:da190355ca49 | 326 | pn532_packetbuffer[10+i] = _uid[i]; /* 4 byte card ID */ |
| vhsstar | 11:da190355ca49 | 327 | } |
| vhsstar | 11:da190355ca49 | 328 | |
| vhsstar | 11:da190355ca49 | 329 | if (! sendCommandCheckAck(pn532_packetbuffer, 10+_uidLen)) |
| vhsstar | 11:da190355ca49 | 330 | return 0; |
| vhsstar | 11:da190355ca49 | 331 | |
| vhsstar | 11:da190355ca49 | 332 | |
| vhsstar | 11:da190355ca49 | 333 | progStatus(0x02, 500); |
| vhsstar | 11:da190355ca49 | 334 | |
| vhsstar | 11:da190355ca49 | 335 | |
| vhsstar | 11:da190355ca49 | 336 | // Read the response packet |
| vhsstar | 11:da190355ca49 | 337 | wireReadData(pn532_packetbuffer, 12); |
| vhsstar | 11:da190355ca49 | 338 | |
| vhsstar | 11:da190355ca49 | 339 | // Check if the response is valid and we are authenticated??? |
| vhsstar | 11:da190355ca49 | 340 | // for an auth success it should be bytes 5-7: 0xD5 0x41 0x00 |
| vhsstar | 11:da190355ca49 | 341 | // Mifare auth error is technically byte 7: 0x14 but anything other and 0x00 is not good |
| vhsstar | 11:da190355ca49 | 342 | if (pn532_packetbuffer[7] != 0x00) |
| vhsstar | 11:da190355ca49 | 343 | { |
| vhsstar | 11:da190355ca49 | 344 | return 0; |
| vhsstar | 11:da190355ca49 | 345 | } |
| vhsstar | 11:da190355ca49 | 346 | |
| vhsstar | 11:da190355ca49 | 347 | return 1; |
| vhsstar | 11:da190355ca49 | 348 | } |
| vhsstar | 11:da190355ca49 | 349 | |
| vhsstar | 11:da190355ca49 | 350 | char NFC::mifareclassic_WriteDataBlock (char blockNumber, char * data) |
| vhsstar | 11:da190355ca49 | 351 | { |
| vhsstar | 11:da190355ca49 | 352 | /* Prepare the first command */ |
| vhsstar | 11:da190355ca49 | 353 | pn532_packetbuffer[0] = 0x40; |
| vhsstar | 11:da190355ca49 | 354 | pn532_packetbuffer[1] = 1; /* Card number */ |
| vhsstar | 11:da190355ca49 | 355 | pn532_packetbuffer[2] = 0xA0; /* Mifare Write command = 0xA0 */ |
| vhsstar | 11:da190355ca49 | 356 | pn532_packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */ |
| vhsstar | 11:da190355ca49 | 357 | memcpy (pn532_packetbuffer+4, data, 16); /* Data Payload */ |
| vhsstar | 11:da190355ca49 | 358 | |
| vhsstar | 11:da190355ca49 | 359 | /* Send the command */ |
| vhsstar | 11:da190355ca49 | 360 | if (! sendCommandCheckAck(pn532_packetbuffer, 20)) |
| vhsstar | 11:da190355ca49 | 361 | { |
| vhsstar | 11:da190355ca49 | 362 | return 0; |
| vhsstar | 11:da190355ca49 | 363 | } |
| vhsstar | 11:da190355ca49 | 364 | wait_ms(10); |
| vhsstar | 11:da190355ca49 | 365 | |
| vhsstar | 11:da190355ca49 | 366 | /* Read the response packet */ |
| vhsstar | 11:da190355ca49 | 367 | wireReadData(pn532_packetbuffer, 26); |
| vhsstar | 11:da190355ca49 | 368 | |
| vhsstar | 11:da190355ca49 | 369 | return 1; |
| vhsstar | 11:da190355ca49 | 370 | } |
| vhsstar | 11:da190355ca49 | 371 | |
| vhsstar | 11:da190355ca49 | 372 | char NFC::mifareclassic_ReadDataBlock (char blockNumber, char * data) |
| vhsstar | 11:da190355ca49 | 373 | { |
| vhsstar | 11:da190355ca49 | 374 | /* Prepare the command */ |
| vhsstar | 11:da190355ca49 | 375 | pn532_packetbuffer[0] = 0x40; |
| vhsstar | 11:da190355ca49 | 376 | pn532_packetbuffer[1] = 1; /* Card number */ |
| vhsstar | 11:da190355ca49 | 377 | pn532_packetbuffer[2] = 0x30; /* Mifare Read command = 0x30 */ |
| vhsstar | 11:da190355ca49 | 378 | pn532_packetbuffer[3] = blockNumber; /* Block Number (0..63 for 1K, 0..255 for 4K) */ |
| vhsstar | 11:da190355ca49 | 379 | |
| vhsstar | 11:da190355ca49 | 380 | /* Send the command */ |
| vhsstar | 11:da190355ca49 | 381 | if (! sendCommandCheckAck(pn532_packetbuffer, 4)) |
| vhsstar | 11:da190355ca49 | 382 | { |
| vhsstar | 11:da190355ca49 | 383 | return 0; |
| vhsstar | 11:da190355ca49 | 384 | } |
| vhsstar | 11:da190355ca49 | 385 | |
| vhsstar | 11:da190355ca49 | 386 | wait_ms(10); |
| vhsstar | 11:da190355ca49 | 387 | |
| vhsstar | 11:da190355ca49 | 388 | /* Read the response packet */ |
| vhsstar | 11:da190355ca49 | 389 | wireReadData(pn532_packetbuffer, 26); |
| vhsstar | 11:da190355ca49 | 390 | /* If byte 8 isn't 0x00 we probably have an error */ |
| vhsstar | 11:da190355ca49 | 391 | if (pn532_packetbuffer[7] != 0x00) |
| vhsstar | 11:da190355ca49 | 392 | { |
| vhsstar | 11:da190355ca49 | 393 | return 0; |
| vhsstar | 11:da190355ca49 | 394 | } |
| vhsstar | 11:da190355ca49 | 395 | |
| vhsstar | 11:da190355ca49 | 396 | /* Copy the 16 data bytes to the output buffer */ |
| vhsstar | 11:da190355ca49 | 397 | /* Block content starts at byte 9 of a valid response */ |
| vhsstar | 11:da190355ca49 | 398 | memcpy (data, pn532_packetbuffer+8, 16); |
| vhsstar | 11:da190355ca49 | 399 | return 1; |
| vhsstar | 11:da190355ca49 | 400 | } |

