Generic library for working with PN532-like chips

Fork of PN532 by Seeed

Revision:
10:f959b305a571
Parent:
5:51f820fbd18a
--- 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++;
         }