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 #include "MifareClassic.h"
mauroar211 0:b805b487fbef 2 #include "PN532_debug.h"
mauroar211 0:b805b487fbef 3
mauroar211 0:b805b487fbef 4 #define BLOCK_SIZE 16
mauroar211 0:b805b487fbef 5 #define LONG_TLV_SIZE 4
mauroar211 0:b805b487fbef 6 #define SHORT_TLV_SIZE 2
mauroar211 0:b805b487fbef 7
mauroar211 0:b805b487fbef 8 #define MIFARE_CLASSIC ("Mifare Classic")
mauroar211 0:b805b487fbef 9
mauroar211 0:b805b487fbef 10 MifareClassic::MifareClassic(PN532& nfcShield)
mauroar211 0:b805b487fbef 11 {
mauroar211 0:b805b487fbef 12 _nfcShield = &nfcShield;
mauroar211 0:b805b487fbef 13 }
mauroar211 0:b805b487fbef 14
mauroar211 0:b805b487fbef 15 MifareClassic::~MifareClassic()
mauroar211 0:b805b487fbef 16 {
mauroar211 0:b805b487fbef 17 }
mauroar211 0:b805b487fbef 18
mauroar211 0:b805b487fbef 19 NfcTag MifareClassic::read(uint8_t *uid, unsigned int uidLength)
mauroar211 0:b805b487fbef 20 {
mauroar211 0:b805b487fbef 21 uint8_t key[6] = { 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7 };
mauroar211 0:b805b487fbef 22 int currentBlock = 4;
mauroar211 0:b805b487fbef 23 int messageStartIndex = 0;
mauroar211 0:b805b487fbef 24 int messageLength = 0;
mauroar211 0:b805b487fbef 25 uint8_t data[BLOCK_SIZE];
mauroar211 0:b805b487fbef 26
mauroar211 0:b805b487fbef 27 // read first block to get message length
mauroar211 0:b805b487fbef 28 int success = _nfcShield->mifareclassic_AuthenticateBlock(uid, uidLength, currentBlock, 0, key);
mauroar211 0:b805b487fbef 29 if (success)
mauroar211 0:b805b487fbef 30 {
mauroar211 0:b805b487fbef 31 success = _nfcShield->mifareclassic_ReadDataBlock(currentBlock, data);
mauroar211 0:b805b487fbef 32 if (success)
mauroar211 0:b805b487fbef 33 {
mauroar211 0:b805b487fbef 34 if (!decodeTlv(data, messageLength, messageStartIndex)) {
mauroar211 0:b805b487fbef 35 return NfcTag(uid, uidLength, "ERROR"); // TODO should the error message go in NfcTag?
mauroar211 0:b805b487fbef 36 }
mauroar211 0:b805b487fbef 37 }
mauroar211 0:b805b487fbef 38 else
mauroar211 0:b805b487fbef 39 {
mauroar211 0:b805b487fbef 40 DMSG("Error. Failed read block ");
mauroar211 0:b805b487fbef 41 DMSG_INT(currentBlock);
mauroar211 0:b805b487fbef 42 return NfcTag(uid, uidLength, MIFARE_CLASSIC);
mauroar211 0:b805b487fbef 43 }
mauroar211 0:b805b487fbef 44 }
mauroar211 0:b805b487fbef 45 else
mauroar211 0:b805b487fbef 46 {
mauroar211 0:b805b487fbef 47 DMSG("Tag is not NDEF formatted.");
mauroar211 0:b805b487fbef 48 // TODO set tag.isFormatted = false
mauroar211 0:b805b487fbef 49 return NfcTag(uid, uidLength, MIFARE_CLASSIC);
mauroar211 0:b805b487fbef 50 }
mauroar211 0:b805b487fbef 51
mauroar211 0:b805b487fbef 52 // this should be nested in the message length loop
mauroar211 0:b805b487fbef 53 int index = 0;
mauroar211 0:b805b487fbef 54 int bufferSize = getBufferSize(messageLength);
mauroar211 0:b805b487fbef 55 uint8_t buffer[bufferSize];
mauroar211 0:b805b487fbef 56
mauroar211 0:b805b487fbef 57 #ifdef MIFARE_CLASSIC_DEBUG
mauroar211 0:b805b487fbef 58 DMSG("Message Length ");
mauroar211 0:b805b487fbef 59 DMSG_INT(messageLength);
mauroar211 0:b805b487fbef 60 DMSG("Buffer Size ");
mauroar211 0:b805b487fbef 61 DMSG_INT(bufferSize);
mauroar211 0:b805b487fbef 62 #endif
mauroar211 0:b805b487fbef 63
mauroar211 0:b805b487fbef 64 while (index < bufferSize)
mauroar211 0:b805b487fbef 65 {
mauroar211 0:b805b487fbef 66
mauroar211 0:b805b487fbef 67 // authenticate on every sector
mauroar211 0:b805b487fbef 68 if (_nfcShield->mifareclassic_IsFirstBlock(currentBlock))
mauroar211 0:b805b487fbef 69 {
mauroar211 0:b805b487fbef 70 success = _nfcShield->mifareclassic_AuthenticateBlock(uid, uidLength, currentBlock, 0, key);
mauroar211 0:b805b487fbef 71 if (!success)
mauroar211 0:b805b487fbef 72 {
mauroar211 0:b805b487fbef 73 DMSG("Error. Block Authentication failed for ");
mauroar211 0:b805b487fbef 74 DMSG_INT(currentBlock);
mauroar211 0:b805b487fbef 75 // TODO error handling
mauroar211 0:b805b487fbef 76 }
mauroar211 0:b805b487fbef 77 }
mauroar211 0:b805b487fbef 78
mauroar211 0:b805b487fbef 79 // read the data
mauroar211 0:b805b487fbef 80 success = _nfcShield->mifareclassic_ReadDataBlock(currentBlock, &buffer[index]);
mauroar211 0:b805b487fbef 81 if (success)
mauroar211 0:b805b487fbef 82 {
mauroar211 0:b805b487fbef 83 #ifdef MIFARE_CLASSIC_DEBUG
mauroar211 0:b805b487fbef 84 DMSG("Block ");
mauroar211 0:b805b487fbef 85 DMSG_INT(currentBlock);
mauroar211 0:b805b487fbef 86 _nfcShield->PrintHexChar(&buffer[index], BLOCK_SIZE);
mauroar211 0:b805b487fbef 87 #endif
mauroar211 0:b805b487fbef 88 }
mauroar211 0:b805b487fbef 89 else
mauroar211 0:b805b487fbef 90 {
mauroar211 0:b805b487fbef 91 DMSG("Read failed ");
mauroar211 0:b805b487fbef 92 DMSG_INT(currentBlock);
mauroar211 0:b805b487fbef 93 // TODO handle errors here
mauroar211 0:b805b487fbef 94 }
mauroar211 0:b805b487fbef 95
mauroar211 0:b805b487fbef 96 index += BLOCK_SIZE;
mauroar211 0:b805b487fbef 97 currentBlock++;
mauroar211 0:b805b487fbef 98
mauroar211 0:b805b487fbef 99 // skip the trailer block
mauroar211 0:b805b487fbef 100 if (_nfcShield->mifareclassic_IsTrailerBlock(currentBlock))
mauroar211 0:b805b487fbef 101 {
mauroar211 0:b805b487fbef 102 #ifdef MIFARE_CLASSIC_DEBUG
mauroar211 0:b805b487fbef 103 DMSG("Skipping block ");
mauroar211 0:b805b487fbef 104 DMSG_INT(currentBlock);
mauroar211 0:b805b487fbef 105 #endif
mauroar211 0:b805b487fbef 106 currentBlock++;
mauroar211 0:b805b487fbef 107 }
mauroar211 0:b805b487fbef 108 }
mauroar211 0:b805b487fbef 109
mauroar211 0:b805b487fbef 110 return NfcTag(uid, uidLength, MIFARE_CLASSIC, &buffer[messageStartIndex], messageLength);
mauroar211 0:b805b487fbef 111 }
mauroar211 0:b805b487fbef 112
mauroar211 0:b805b487fbef 113 int MifareClassic::getBufferSize(int messageLength)
mauroar211 0:b805b487fbef 114 {
mauroar211 0:b805b487fbef 115
mauroar211 0:b805b487fbef 116 int bufferSize = messageLength;
mauroar211 0:b805b487fbef 117
mauroar211 0:b805b487fbef 118 // TLV header is 2 or 4 uint8_ts, TLV terminator is 1 uint8_t.
mauroar211 0:b805b487fbef 119 if (messageLength < 0xFF)
mauroar211 0:b805b487fbef 120 {
mauroar211 0:b805b487fbef 121 bufferSize += SHORT_TLV_SIZE + 1;
mauroar211 0:b805b487fbef 122 }
mauroar211 0:b805b487fbef 123 else
mauroar211 0:b805b487fbef 124 {
mauroar211 0:b805b487fbef 125 bufferSize += LONG_TLV_SIZE + 1;
mauroar211 0:b805b487fbef 126 }
mauroar211 0:b805b487fbef 127
mauroar211 0:b805b487fbef 128 // bufferSize needs to be a multiple of BLOCK_SIZE
mauroar211 0:b805b487fbef 129 if (bufferSize % BLOCK_SIZE != 0)
mauroar211 0:b805b487fbef 130 {
mauroar211 0:b805b487fbef 131 bufferSize = ((bufferSize / BLOCK_SIZE) + 1) * BLOCK_SIZE;
mauroar211 0:b805b487fbef 132 }
mauroar211 0:b805b487fbef 133
mauroar211 0:b805b487fbef 134 return bufferSize;
mauroar211 0:b805b487fbef 135 }
mauroar211 0:b805b487fbef 136
mauroar211 0:b805b487fbef 137 // skip null tlvs (0x0) before the real message
mauroar211 0:b805b487fbef 138 // technically unlimited null tlvs, but we assume
mauroar211 0:b805b487fbef 139 // T & L of TLV in the first block we read
mauroar211 0:b805b487fbef 140 int MifareClassic::getNdefStartIndex(uint8_t *data)
mauroar211 0:b805b487fbef 141 {
mauroar211 0:b805b487fbef 142
mauroar211 0:b805b487fbef 143 for (int i = 0; i < BLOCK_SIZE; i++)
mauroar211 0:b805b487fbef 144 {
mauroar211 0:b805b487fbef 145 if (data[i] == 0x0)
mauroar211 0:b805b487fbef 146 {
mauroar211 0:b805b487fbef 147 // do nothing, skip
mauroar211 0:b805b487fbef 148 }
mauroar211 0:b805b487fbef 149 else if (data[i] == 0x3)
mauroar211 0:b805b487fbef 150 {
mauroar211 0:b805b487fbef 151 return i;
mauroar211 0:b805b487fbef 152 }
mauroar211 0:b805b487fbef 153 else
mauroar211 0:b805b487fbef 154 {
mauroar211 0:b805b487fbef 155 DMSG("Unknown TLV ");
mauroar211 0:b805b487fbef 156 DMSG_HEX(data[i]);
mauroar211 0:b805b487fbef 157 return -2;
mauroar211 0:b805b487fbef 158 }
mauroar211 0:b805b487fbef 159 }
mauroar211 0:b805b487fbef 160
mauroar211 0:b805b487fbef 161 return -1;
mauroar211 0:b805b487fbef 162 }
mauroar211 0:b805b487fbef 163
mauroar211 0:b805b487fbef 164 // Decode the NDEF data length from the Mifare TLV
mauroar211 0:b805b487fbef 165 // Leading null TLVs (0x0) are skipped
mauroar211 0:b805b487fbef 166 // Assuming T & L of TLV will be in the first block
mauroar211 0:b805b487fbef 167 // messageLength and messageStartIndex written to the parameters
mauroar211 0:b805b487fbef 168 // success or failure status is returned
mauroar211 0:b805b487fbef 169 //
mauroar211 0:b805b487fbef 170 // { 0x3, LENGTH }
mauroar211 0:b805b487fbef 171 // { 0x3, 0xFF, LENGTH, LENGTH }
mauroar211 0:b805b487fbef 172 bool MifareClassic::decodeTlv(uint8_t *data, int &messageLength, int &messageStartIndex)
mauroar211 0:b805b487fbef 173 {
mauroar211 0:b805b487fbef 174 int i = getNdefStartIndex(data);
mauroar211 0:b805b487fbef 175
mauroar211 0:b805b487fbef 176 if (i < 0 || data[i] != 0x3)
mauroar211 0:b805b487fbef 177 {
mauroar211 0:b805b487fbef 178 DMSG("Error. Can't decode message length.");
mauroar211 0:b805b487fbef 179 return false;
mauroar211 0:b805b487fbef 180 }
mauroar211 0:b805b487fbef 181 else
mauroar211 0:b805b487fbef 182 {
mauroar211 0:b805b487fbef 183 if (data[i+1] == 0xFF)
mauroar211 0:b805b487fbef 184 {
mauroar211 0:b805b487fbef 185 messageLength = ((0xFF & data[i+2]) << 8) | (0xFF & data[i+3]);
mauroar211 0:b805b487fbef 186 messageStartIndex = i + LONG_TLV_SIZE;
mauroar211 0:b805b487fbef 187 }
mauroar211 0:b805b487fbef 188 else
mauroar211 0:b805b487fbef 189 {
mauroar211 0:b805b487fbef 190 messageLength = data[i+1];
mauroar211 0:b805b487fbef 191 messageStartIndex = i + SHORT_TLV_SIZE;
mauroar211 0:b805b487fbef 192 }
mauroar211 0:b805b487fbef 193 }
mauroar211 0:b805b487fbef 194
mauroar211 0:b805b487fbef 195 return true;
mauroar211 0:b805b487fbef 196 }
mauroar211 0:b805b487fbef 197
mauroar211 0:b805b487fbef 198 bool MifareClassic::write(NdefMessage& m, uint8_t * uid, unsigned int uidLength)
mauroar211 0:b805b487fbef 199 {
mauroar211 0:b805b487fbef 200
mauroar211 0:b805b487fbef 201 uint8_t encoded[m.getEncodedSize()];
mauroar211 0:b805b487fbef 202 m.encode(encoded);
mauroar211 0:b805b487fbef 203
mauroar211 0:b805b487fbef 204 uint8_t buffer[getBufferSize(sizeof(encoded))];
mauroar211 0:b805b487fbef 205 memset(buffer, 0, sizeof(buffer));
mauroar211 0:b805b487fbef 206
mauroar211 0:b805b487fbef 207 #ifdef MIFARE_CLASSIC_DEBUG
mauroar211 0:b805b487fbef 208 DMSG("sizeof(encoded) "));DMSG(sizeof(encoded);
mauroar211 0:b805b487fbef 209 DMSG("sizeof(buffer) "));DMSG(sizeof(buffer);
mauroar211 0:b805b487fbef 210 #endif
mauroar211 0:b805b487fbef 211
mauroar211 0:b805b487fbef 212 if (sizeof(encoded) < 0xFF)
mauroar211 0:b805b487fbef 213 {
mauroar211 0:b805b487fbef 214 buffer[0] = 0x3;
mauroar211 0:b805b487fbef 215 buffer[1] = sizeof(encoded);
mauroar211 0:b805b487fbef 216 memcpy(&buffer[2], encoded, sizeof(encoded));
mauroar211 0:b805b487fbef 217 buffer[2+sizeof(encoded)] = 0xFE; // terminator
mauroar211 0:b805b487fbef 218 }
mauroar211 0:b805b487fbef 219 else
mauroar211 0:b805b487fbef 220 {
mauroar211 0:b805b487fbef 221 buffer[0] = 0x3;
mauroar211 0:b805b487fbef 222 buffer[1] = 0xFF;
mauroar211 0:b805b487fbef 223 buffer[2] = ((sizeof(encoded) >> 8) & 0xFF);
mauroar211 0:b805b487fbef 224 buffer[3] = (sizeof(encoded) & 0xFF);
mauroar211 0:b805b487fbef 225 memcpy(&buffer[4], encoded, sizeof(encoded));
mauroar211 0:b805b487fbef 226 buffer[4+sizeof(encoded)] = 0xFE; // terminator
mauroar211 0:b805b487fbef 227 }
mauroar211 0:b805b487fbef 228
mauroar211 0:b805b487fbef 229 // Write to tag
mauroar211 0:b805b487fbef 230 int index = 0;
mauroar211 0:b805b487fbef 231 int currentBlock = 4;
mauroar211 0:b805b487fbef 232 uint8_t key[6] = { 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7 }; // this is Sector 1 - 15 key
mauroar211 0:b805b487fbef 233
mauroar211 0:b805b487fbef 234 while (index < sizeof(buffer))
mauroar211 0:b805b487fbef 235 {
mauroar211 0:b805b487fbef 236
mauroar211 0:b805b487fbef 237 if (_nfcShield->mifareclassic_IsFirstBlock(currentBlock))
mauroar211 0:b805b487fbef 238 {
mauroar211 0:b805b487fbef 239 int success = _nfcShield->mifareclassic_AuthenticateBlock(uid, uidLength, currentBlock, 0, key);
mauroar211 0:b805b487fbef 240 if (!success)
mauroar211 0:b805b487fbef 241 {
mauroar211 0:b805b487fbef 242 DMSG("Error. Block Authentication failed for ");DMSG_INT(currentBlock);
mauroar211 0:b805b487fbef 243 return false;
mauroar211 0:b805b487fbef 244 }
mauroar211 0:b805b487fbef 245 }
mauroar211 0:b805b487fbef 246
mauroar211 0:b805b487fbef 247 int write_success = _nfcShield->mifareclassic_WriteDataBlock (currentBlock, &buffer[index]);
mauroar211 0:b805b487fbef 248 if (write_success)
mauroar211 0:b805b487fbef 249 {
mauroar211 0:b805b487fbef 250 #ifdef MIFARE_CLASSIC_DEBUG
mauroar211 0:b805b487fbef 251 DMSG("Wrote block ");Serial.print(currentBlock);DMSG(" - ");
mauroar211 0:b805b487fbef 252 _nfcShield->PrintHexChar(&buffer[index], BLOCK_SIZE);
mauroar211 0:b805b487fbef 253 #endif
mauroar211 0:b805b487fbef 254 }
mauroar211 0:b805b487fbef 255 else
mauroar211 0:b805b487fbef 256 {
mauroar211 0:b805b487fbef 257 DMSG("Write failed ");DMSG_INT(currentBlock);
mauroar211 0:b805b487fbef 258 return false;
mauroar211 0:b805b487fbef 259 }
mauroar211 0:b805b487fbef 260 index += BLOCK_SIZE;
mauroar211 0:b805b487fbef 261 currentBlock++;
mauroar211 0:b805b487fbef 262
mauroar211 0:b805b487fbef 263 if (_nfcShield->mifareclassic_IsTrailerBlock(currentBlock))
mauroar211 0:b805b487fbef 264 {
mauroar211 0:b805b487fbef 265 // can't write to trailer block
mauroar211 0:b805b487fbef 266 #ifdef MIFARE_CLASSIC_DEBUG
mauroar211 0:b805b487fbef 267 DMSG("Skipping block ");DMSG(currentBlock);
mauroar211 0:b805b487fbef 268 #endif
mauroar211 0:b805b487fbef 269 currentBlock++;
mauroar211 0:b805b487fbef 270 }
mauroar211 0:b805b487fbef 271
mauroar211 0:b805b487fbef 272 }
mauroar211 0:b805b487fbef 273
mauroar211 0:b805b487fbef 274 return true;
mauroar211 0:b805b487fbef 275 }