Generic library for working with PN532-like chips

Fork of PN532 by Seeed

Files at this revision

API Documentation at this revision

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

MifareClassic.cpp Show annotated file Show diff for this revision Revisions of this file
MifareUltralight.cpp Show annotated file Show diff for this revision Revisions of this file
NdefMessage.cpp Show annotated file Show diff for this revision Revisions of this file
NdefRecord.cpp Show annotated file Show diff for this revision Revisions of this file
NfcAdapter.cpp Show annotated file Show diff for this revision Revisions of this file
NfcTag.cpp Show annotated file Show diff for this revision Revisions of this file
PN532.cpp Show annotated file Show diff for this revision Revisions of this file
PN532.h Show annotated file Show diff for this revision Revisions of this file
PN532_debug.h Show annotated file Show diff for this revision Revisions of this file
emulatetag.cpp Show annotated file Show diff for this revision Revisions of this file
--- 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);