Generic library for working with PN532-like chips
Fork of PN532 by
Revision 10:f959b305a571, committed 2015-02-04
- Comitter:
- r4z0r7o3
- Date:
- Wed Feb 04 19:04:54 2015 +0000
- Parent:
- 9:85bfede025da
- Child:
- 11:5b8afec8bee6
- Commit message:
- Try multiple known auth. keys on classic. Also fixed all debugging messages so they all end with newlines.
Changed in this revision
--- a/MifareClassic.cpp Wed Feb 04 16:24:30 2015 +0000 +++ b/MifareClassic.cpp Wed Feb 04 19:04:54 2015 +0000 @@ -7,6 +7,19 @@ #define MIFARE_CLASSIC ("Mifare Classic") +const uint8_t keys_len = 9; +const uint8_t keys[keys_len][6] = { + { 0XFF, 0XFF, 0XFF, 0XFF, 0XFF, 0XFF }, + { 0XD3, 0XF7, 0XD3, 0XF7, 0XD3, 0XF7 }, + { 0XA0, 0XA1, 0XA2, 0XA3, 0XA4, 0XA5 }, + { 0XB0, 0XB1, 0XB2, 0XB3, 0XB4, 0XB5 }, + { 0X4D, 0X3A, 0X99, 0XC3, 0X51, 0XDD }, + { 0X1A, 0X98, 0X2C, 0X7E, 0X45, 0X9A }, + { 0XAA, 0XBB, 0XCC, 0XDD, 0XEE, 0XFF }, + { 0X00, 0X00, 0X00, 0X00, 0X00, 0X00 }, + { 0XAB, 0XCD, 0XEF, 0X12, 0X34, 0X56 }, +}; + MifareClassic::MifareClassic(PN532& nfcShield) { _nfcShield = &nfcShield; @@ -18,14 +31,19 @@ NfcTag MifareClassic::read(uint8_t *uid, unsigned int uidLength) { - uint8_t key[6] = { 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7 }; int currentBlock = 4; int messageStartIndex = 0; int messageLength = 0; uint8_t data[BLOCK_SIZE]; // read first block to get message length - int success = _nfcShield->mifareclassic_AuthenticateBlock(uid, uidLength, currentBlock, 0, key); + int success = 0; + for (uint8_t i=0; i < keys_len; i++) { + success = _nfcShield->mifareclassic_AuthenticateBlock(uid, uidLength, currentBlock, 0, keys[i]); + if (success) + break; + } + if (success) { success = _nfcShield->mifareclassic_ReadDataBlock(currentBlock, data); @@ -39,12 +57,13 @@ { DMSG("Error. Failed read block "); DMSG_INT(currentBlock); + DMSG("\n"); return NfcTag(uid, uidLength, MIFARE_CLASSIC); } } else { - DMSG("Tag is not NDEF formatted."); + DMSG("Tag is not NDEF formatted.\n"); // TODO set tag.isFormatted = false return NfcTag(uid, uidLength, MIFARE_CLASSIC); } @@ -59,6 +78,7 @@ DMSG_INT(messageLength); DMSG("Buffer Size "); DMSG_INT(bufferSize); + DMSG("\n"); #endif while (index < bufferSize) @@ -67,11 +87,18 @@ // authenticate on every sector if (_nfcShield->mifareclassic_IsFirstBlock(currentBlock)) { - success = _nfcShield->mifareclassic_AuthenticateBlock(uid, uidLength, currentBlock, 0, key); + int success = 0; + for (uint8_t i=0; i < keys_len; i++) { + success = _nfcShield->mifareclassic_AuthenticateBlock(uid, uidLength, currentBlock, 0, keys[i]); + if (success) + break; + } + if (!success) { DMSG("Error. Block Authentication failed for "); DMSG_INT(currentBlock); + DMSG("\n"); // TODO error handling } } @@ -84,12 +111,14 @@ DMSG("Block "); DMSG_INT(currentBlock); _nfcShield->PrintHexChar(&buffer[index], BLOCK_SIZE); + DMSG("\n"); #endif } else { DMSG("Read failed "); DMSG_INT(currentBlock); + DMSG("\n"); // TODO handle errors here } @@ -102,6 +131,7 @@ #ifdef MIFARE_CLASSIC_DEBUG DMSG("Skipping block "); DMSG_INT(currentBlock); + DMSG("\n"); #endif currentBlock++; } @@ -154,6 +184,7 @@ { DMSG("Unknown TLV "); DMSG_HEX(data[i]); + DMSG("\n"); return -2; } } @@ -175,7 +206,7 @@ if (i < 0 || data[i] != 0x3) { - DMSG("Error. Can't decode message length."); + DMSG("Error. Can't decode message length.\n"); return false; } else @@ -205,8 +236,9 @@ memset(buffer, 0, sizeof(buffer)); #ifdef MIFARE_CLASSIC_DEBUG - DMSG("sizeof(encoded) "));DMSG(sizeof(encoded); - DMSG("sizeof(buffer) "));DMSG(sizeof(buffer); + DMSG("sizeof(encoded) ");DMSG_INT(sizeof(encoded)); + DMSG("sizeof(buffer) ");DMSG_INT(sizeof(buffer)); + DMSG("\n"); #endif if (sizeof(encoded) < 0xFF) @@ -229,17 +261,22 @@ // Write to tag int index = 0; int currentBlock = 4; - uint8_t key[6] = { 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7 }; // this is Sector 1 - 15 key while (index < sizeof(buffer)) { if (_nfcShield->mifareclassic_IsFirstBlock(currentBlock)) { - int success = _nfcShield->mifareclassic_AuthenticateBlock(uid, uidLength, currentBlock, 0, key); + int success = 0; + for (uint8_t i=0; i < keys_len; i++) { + success = _nfcShield->mifareclassic_AuthenticateBlock(uid, uidLength, currentBlock, 0, keys[i]); + if (success) + break; + } if (!success) { DMSG("Error. Block Authentication failed for ");DMSG_INT(currentBlock); + DMSG("\n"); return false; } } @@ -247,13 +284,15 @@ if (write_success) { #ifdef MIFARE_CLASSIC_DEBUG - DMSG("Wrote block ");Serial.print(currentBlock);DMSG(" - "); + DMSG("Wrote block ");DMSG_INT(currentBlock);DMSG(" - "); _nfcShield->PrintHexChar(&buffer[index], BLOCK_SIZE); + DMSG("\n"); #endif } else { DMSG("Write failed ");DMSG_INT(currentBlock); + DMSG("\n"); return false; } index += BLOCK_SIZE; @@ -263,7 +302,8 @@ { // can't write to trailer block #ifdef MIFARE_CLASSIC_DEBUG - DMSG("Skipping block ");DMSG(currentBlock); + DMSG("Skipping block ");DMSG_INT(currentBlock); + DMSG("\n"); #endif currentBlock++; }
--- a/MifareUltralight.cpp Wed Feb 04 16:24:30 2015 +0000 +++ b/MifareUltralight.cpp Wed Feb 04 19:04:54 2015 +0000 @@ -27,7 +27,7 @@ { if (isUnformatted()) { - DMSG("WARNING: Tag is not formatted."); + DMSG("WARNING: Tag is not formatted.\n"); return NfcTag(uid, uidLength, NFC_FORUM_TAG_TYPE_2); } @@ -54,11 +54,12 @@ #ifdef MIFARE_ULTRALIGHT_DEBUG DMSG("Page ");Serial.print(page);DMSG(" "); nfc->PrintHexChar(&buffer[index], ULTRALIGHT_PAGE_SIZE); + DMSG("\n"); #endif } else { - DMSG("Read failed ");DMSG_INT(page); + DMSG("Read failed ");DMSG_INT(page);DMSG("\n"); // TODO error handling messageLength = 0; break; @@ -143,7 +144,7 @@ } else { - DMSG("Error. Failed read page ");DMSG_INT(page); + DMSG("Error. Failed read page ");DMSG_INT(page);DMSG("\n"); return false; } } @@ -158,7 +159,7 @@ // See AN1303 - different rules for Mifare Family uint8_t2 = (additional data + 48)/8 tagCapacity = data[2] * 8; #ifdef MIFARE_ULTRALIGHT_DEBUG - DMSG("Tag capacity "));Serial.print(tagCapacity);DMSG(F(" uint8_ts"); + DMSG("Tag capacity "));Serial.print(tagCapacity);DMSG(F(" uint8_ts\n"); #endif // TODO future versions should get lock information @@ -180,6 +181,7 @@ #ifdef MIFARE_ULTRALIGHT_DEBUG DMSG("Page "));Serial.print(page);Serial.print(F(" - "); nfc->PrintHexChar(data_ptr, 4); + DMSG("\n"); #endif data_ptr += ULTRALIGHT_PAGE_SIZE; } @@ -201,7 +203,7 @@ #ifdef MIFARE_ULTRALIGHT_DEBUG DMSG("messageLength ");DMSG(messageLength); - DMSG("ndefStartIndex ");DMSG(ndefStartIndex); + DMSG(" ndefStartIndex ");DMSG(ndefStartIndex);DMSG("\n"); #endif }
--- a/NdefMessage.cpp Wed Feb 04 16:24:30 2015 +0000 +++ b/NdefMessage.cpp Wed Feb 04 19:04:54 2015 +0000 @@ -9,9 +9,10 @@ NdefMessage::NdefMessage(const uint8_t * data, const int numuint8_ts) { #ifdef NDEF_DEBUG - DMSG("Decoding "));Serial.print(numuint8_ts);DMSG(F(" uint8_ts"); + DMSG("Decoding ");DMSG_INT(numuint8_ts);DMSG(" uint8_ts"); PrintHexChar(data, numuint8_ts); //DumpHex(data, numuint8_ts, 16); + DMSG("\n"); #endif _recordCount = 0; @@ -154,7 +155,7 @@ } else { - DMSG("WARNING: Too many records. Increase MAX_NDEF_RECORDS."); + DMSG("WARNING: Too many records. Increase MAX_NDEF_RECORDS.\n"); return false; } } @@ -260,7 +261,7 @@ void NdefMessage::print() { - DMSG("\nNDEF Message "); + DMSG("NDEF Message "); DMSG_INT(_recordCount); DMSG(" record"); if (_recordCount == 1) { @@ -275,4 +276,5 @@ { _records[i].print(); } + DMSG("\n"); }
--- a/NdefRecord.cpp Wed Feb 04 16:24:30 2015 +0000 +++ b/NdefRecord.cpp Wed Feb 04 19:04:54 2015 +0000 @@ -360,4 +360,5 @@ } DMSG(" Record is "); DMSG_INT(getEncodedSize()); + DMSG("\n"); } \ No newline at end of file
--- a/NfcAdapter.cpp Wed Feb 04 16:24:30 2015 +0000 +++ b/NfcAdapter.cpp Wed Feb 04 19:04:54 2015 +0000 @@ -17,12 +17,12 @@ uint32_t versiondata = shield->getFirmwareVersion(); if (! versiondata) { - DMSG("Didn't find PN53x board"); + DMSG("Didn't find PN53x board\n"); while (1); // halt } - DMSG("Found chip PN5%2X\r\n", versiondata >> 24); - DMSG("Firmware V%d.%d\r\n", (versiondata >> 16) & 0xFF, (versiondata >> 8) & 0xFF); + DMSG("Found chip PN5%2X\n", versiondata >> 24); + DMSG("Firmware V%d.%d\n", (versiondata >> 16) & 0xFF, (versiondata >> 8) & 0xFF); // configure board to read RFID tags shield->SAMConfig(); @@ -57,7 +57,7 @@ if (type == TAG_TYPE_MIFARE_CLASSIC) { #ifdef NDEF_DEBUG - DMSG("Reading Mifare Classic"); + DMSG("Reading Mifare Classic\n"); #endif MifareClassic mifareClassic = MifareClassic(*shield); return mifareClassic.read(uid, uidLength); @@ -65,14 +65,14 @@ else if (type == TAG_TYPE_2) { #ifdef NDEF_DEBUG - DMSG("Reading Mifare Ultralight"); + DMSG("Reading Mifare Ultralight\n"); #endif MifareUltralight ultralight = MifareUltralight(*shield); return ultralight.read(uid, uidLength); } else if (type == TAG_TYPE_UNKNOWN) { - DMSG("Can not determine tag type"); + DMSG("Can not determine tag type\n"); //DMSG("Can not determine tag type for ATQA 0x"); //Serial.print(atqa, HEX);DMSG(" SAK 0x");DMSG(sak, HEX); return NfcTag(uid, uidLength); @@ -81,6 +81,7 @@ { DMSG("No driver for card type "); DMSG_INT(type); + DMSG("\n"); // TODO should set type here return NfcTag(uid, uidLength); } @@ -98,7 +99,7 @@ } else { - DMSG("Ultralight Tag"); + DMSG("Ultralight Tag\n"); MifareUltralight mifareUltralight = MifareUltralight(*shield); success= mifareUltralight.write(ndefMessage, uid, uidLength); //success = false; @@ -119,8 +120,9 @@ // - ATQA 0x44 && SAK 0x0 - Mifare Ultralight NFC Forum Type 2 // - ATQA 0x344 && SAK 0x20 - NFC Forum Type 4 DMSG("Guess type"); - DMSG("ATQA: 0x"); DMSG_HEX(ATQA); - DMSG("SAK: 0x"); DMSG_HEX(SAK); + DMSG(" ATQA: 0x"); DMSG_HEX(ATQA); + DMSG(" SAK: 0x"); DMSG_HEX(SAK); + DMSG("\n"); /*if (uidLength == 4) { return TAG_TYPE_MIFARE_CLASSIC;
--- a/NfcTag.cpp Wed Feb 04 16:24:30 2015 +0000 +++ b/NfcTag.cpp Wed Feb 04 19:04:54 2015 +0000 @@ -83,7 +83,7 @@ uidString += " "; } - if (_uid[i] < 0xF) + if (_uid[i] < 0xA) { uidString += "0"; } @@ -113,7 +113,7 @@ void NfcTag::print() { DMSG("NFC Tag - "); - DMSG_INT(_tagType); + DMSG(_tagType.c_str()); DMSG("UID - "); DMSG(getUidString().c_str()); if (_ndefMessage == NULL) @@ -124,4 +124,5 @@ { _ndefMessage->print(); } + DMSG("\n"); }
--- a/PN532.cpp Wed Feb 04 16:24:30 2015 +0000 +++ b/PN532.cpp Wed Feb 04 19:04:54 2015 +0000 @@ -388,7 +388,7 @@ @returns 1 if everything executed properly, 0 for an error */ /**************************************************************************/ -uint8_t PN532::mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData) +uint8_t PN532::mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, const uint8_t *keyData) { uint8_t i; @@ -441,6 +441,7 @@ { DMSG("Trying to read 16 bytes from block "); DMSG_INT(blockNumber); + DMSG("\n"); /* Prepare the command */ pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
--- a/PN532.h Wed Feb 04 16:24:30 2015 +0000 +++ b/PN532.h Wed Feb 04 19:04:54 2015 +0000 @@ -148,7 +148,7 @@ // Mifare Classic functions bool mifareclassic_IsFirstBlock (uint32_t uiBlock); bool mifareclassic_IsTrailerBlock (uint32_t uiBlock); - uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, uint8_t *keyData); + uint8_t mifareclassic_AuthenticateBlock (uint8_t *uid, uint8_t uidLen, uint32_t blockNumber, uint8_t keyNumber, const uint8_t *keyData); uint8_t mifareclassic_ReadDataBlock (uint8_t blockNumber, uint8_t *data); uint8_t mifareclassic_WriteDataBlock (uint8_t blockNumber, uint8_t *data); uint8_t mifareclassic_FormatNDEF (void);
--- a/PN532_debug.h Wed Feb 04 16:24:30 2015 +0000 +++ b/PN532_debug.h Wed Feb 04 19:04:54 2015 +0000 @@ -1,7 +1,7 @@ #ifndef __DEBUG_H__ #define __DEBUG_H__ -//#define DEBUG +#define DEBUG #ifdef DEBUG
--- a/emulatetag.cpp Wed Feb 04 16:24:30 2015 +0000 +++ b/emulatetag.cpp Wed Feb 04 19:04:54 2015 +0000 @@ -68,7 +68,7 @@ void EmulateTag::setNdefFile(const uint8_t* ndef, const int16_t ndefLength){ if(ndefLength > (NDEF_MAX_LENGTH -2)){ - DMSG("ndef file too large (> NDEF_MAX_LENGHT -2) - aborting"); + DMSG("ndef file too large (> NDEF_MAX_LENGHT -2) - aborting\n"); return; } @@ -106,7 +106,7 @@ } if(1 != pn532.tgInitAsTarget(command,sizeof(command), tgInitAsTargetTimeout)){ - DMSG("tgInitAsTarget failed or timed out!"); + DMSG("tgInitAsTarget failed or timed out!\n"); return false; } @@ -195,7 +195,7 @@ } break; default: - DMSG("Command not supported!"); + DMSG("Command not supported "); DMSG_HEX(rwbuf[C_APDU_INS]); DMSG("\n"); setResponse(FUNCTION_NOT_SUPPORTED, rwbuf, &sendlen);