Stan Nieuw / PN532_customlib

Fork of PN532 by Components

Files at this revision

API Documentation at this revision

Comitter:
stanvn
Date:
Tue Feb 09 16:16:11 2016 +0000
Parent:
6:26c1b3b6c192
Child:
8:30bba738e292
Commit message:
Library can now read types by reading the SAK bit instead of guessing it.

Changed in this revision

MifareClassic.cpp Show annotated file Show diff for this revision Revisions of this file
MifareClassic.h 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
NfcAdapter.cpp Show annotated file Show diff for this revision Revisions of this file
NfcAdapter.h 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
--- a/MifareClassic.cpp	Tue Mar 25 16:48:10 2014 +0000
+++ b/MifareClassic.cpp	Tue Feb 09 16:16:11 2016 +0000
@@ -6,10 +6,30 @@
 #define SHORT_TLV_SIZE 2
 
 #define MIFARE_CLASSIC ("Mifare Classic")
+#define TAG_TYPE_MIFARE_MINI (0)
+#define TAG_TYPE_MIFARE_1K (1)
+#define TAG_TYPE_MIFARE_4K (2)
+#define TAG_TYPE_MIFARE_UL (3)
+#define TAG_TYPE_MIFARE_PLUS_2K (4)
+#define TAG_TYPE_MIFARE_PLUS_4K (5)
+#define TAG_TYPE_14443 (6)
 
-MifareClassic::MifareClassic(PN532& nfcShield)
+
+MifareClassic::MifareClassic(PN532& nfcShield, uint8_t tag_type)
 {
   _nfcShield = &nfcShield;
+  if(tag_type == TAG_TYPE_MIFARE_MINI)
+  	type = "Mifare Classic Mini";
+  else if(tag_type == TAG_TYPE_MIFARE_1K)
+  	type = "Mifare Classic 1K";
+  else if(tag_type == TAG_TYPE_MIFARE_4K)
+  	type = "Mifare Classic 4K";
+  else if(tag_type == TAG_TYPE_MIFARE_PLUS_2K)
+  	type = "Mifare plus 2K";
+  else if(tag_type == TAG_TYPE_MIFARE_PLUS_4K)
+  	type = "Mifare plus 4K";
+  else
+  	type = "Unknown";
 }
 
 MifareClassic::~MifareClassic()
@@ -39,14 +59,14 @@
         {
             DMSG("Error. Failed read block ");
 			DMSG_INT(currentBlock);
-            return NfcTag(uid, uidLength, MIFARE_CLASSIC);
+            return NfcTag(uid, uidLength, type);
         }
     }
     else
     {
         DMSG("Tag is not NDEF formatted.");
         // TODO set tag.isFormatted = false
-        return NfcTag(uid, uidLength, MIFARE_CLASSIC);
+        return NfcTag(uid, uidLength, type);
     }
 
     // this should be nested in the message length loop
@@ -107,7 +127,7 @@
         }
     }
 
-    return NfcTag(uid, uidLength, MIFARE_CLASSIC, &buffer[messageStartIndex], messageLength);
+    return NfcTag(uid, uidLength, type, &buffer[messageStartIndex], messageLength);
 }
 
 int MifareClassic::getBufferSize(int messageLength)
--- a/MifareClassic.h	Tue Mar 25 16:48:10 2014 +0000
+++ b/MifareClassic.h	Tue Feb 09 16:16:11 2016 +0000
@@ -8,7 +8,7 @@
 class MifareClassic
 {
     public:
-        MifareClassic(PN532& nfcShield);
+        MifareClassic(PN532& nfcShield, uint8_t tag_type);
         ~MifareClassic();
         NfcTag read(uint8_t *uid, unsigned int uidLength);
         bool write(NdefMessage& ndefMessage, uint8_t *uid, unsigned int uidLength);
@@ -17,6 +17,7 @@
         int getBufferSize(int messageLength);
         int getNdefStartIndex(uint8_t *data);
         bool decodeTlv(uint8_t *data, int &messageLength, int &messageStartIndex);
+        string type;
 };
 
 #endif
--- a/MifareUltralight.cpp	Tue Mar 25 16:48:10 2014 +0000
+++ b/MifareUltralight.cpp	Tue Feb 09 16:16:11 2016 +0000
@@ -10,7 +10,7 @@
 #define ULTRALIGHT_DATA_START_INDEX 2
 #define ULTRALIGHT_MAX_PAGE 63
 
-#define NFC_FORUM_TAG_TYPE_2 ("NFC Forum Type 2")
+#define NFC_FORUM_TAG_TYPE_2 ("Mifare Ultra Light")
 
 MifareUltralight::MifareUltralight(PN532& nfcShield)
 {
--- a/NfcAdapter.cpp	Tue Mar 25 16:48:10 2014 +0000
+++ b/NfcAdapter.cpp	Tue Feb 09 16:16:11 2016 +0000
@@ -34,7 +34,7 @@
     uidLength = 0;
 
     // TODO is cast of uidLength OK?
-    success = shield->readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, (uint8_t*)&uidLength);
+    success = shield->readPassiveTarget(PN532_MIFARE_ISO14443A, uid, (uint8_t*)&uidLength, &sak);
 
     // if (success)
     // {
@@ -51,25 +51,26 @@
 NfcTag NfcAdapter::read()
 {
 
-    uint8_t type = guessTagType();
+    uint8_t type = getTagType();
 
     // TODO need an abstraction of Driver
-    if (type == TAG_TYPE_MIFARE_CLASSIC)
+    if (type == TAG_TYPE_MIFARE_UL)
+    {
+        #ifdef NDEF_DEBUG
+        printf("Reading Mifare Ultralight");
+        #endif
+        MifareUltralight ultralight = MifareUltralight(*shield);
+        return ultralight.read(uid, uidLength);
+    }
+    else if (type >= TAG_TYPE_MIFARE_MINI && type <= TAG_TYPE_MIFARE_PLUS_4K)
     {
         #ifdef NDEF_DEBUG
         DMSG("Reading Mifare Classic");
         #endif
-        MifareClassic mifareClassic = MifareClassic(*shield);
+        MifareClassic mifareClassic = MifareClassic(*shield, type);
         return mifareClassic.read(uid, uidLength);
     }
-    else if (type == TAG_TYPE_2)
-    {
-        #ifdef NDEF_DEBUG
-        DMSG("Reading Mifare Ultralight");
-        #endif
-        MifareUltralight ultralight = MifareUltralight(*shield);
-        return ultralight.read(uid, uidLength);
-    }
+    
     else if (type == TAG_TYPE_UNKNOWN)
     {
         DMSG("Can not determine tag type");
@@ -93,7 +94,7 @@
 
     if (uidLength == 4)
     {
-        MifareClassic mifareClassic = MifareClassic(*shield);
+        MifareClassic mifareClassic = MifareClassic(*shield, 0);
         success = mifareClassic.write(ndefMessage, uid, uidLength);
     }
     else
@@ -109,7 +110,6 @@
 // Need to follow spec for Card Identification. Maybe AN1303, AN1305 and ???
 unsigned int NfcAdapter::guessTagType()
 {
-
     // 4 uint8_t id - Mifare Classic
     //  - ATQA 0x4 && SAK 0x8
     // 7 uint8_t id
@@ -119,10 +119,33 @@
 
     if (uidLength == 4)
     {
-        return TAG_TYPE_MIFARE_CLASSIC;
+        return TAG_TYPE_MIFARE_1K;
     }
     else
     {
         return TAG_TYPE_2;
     }
 }
+unsigned int NfcAdapter::getTagType(){
+    if((sak & 0b00011011) == 0b00001001){
+        return TAG_TYPE_MIFARE_MINI;
+    }
+    else if((sak & 0b00011011) == 0b00001000){
+        return TAG_TYPE_MIFARE_1K;
+    }
+    else if((sak & 0b00011010) == 0b00011000){
+        return TAG_TYPE_MIFARE_4K;
+    }
+    else if((sak & 0b00111010) == 0){
+        return TAG_TYPE_MIFARE_UL;
+    }
+    else if((sak & 0b00111010) == 0b00100000){
+        return TAG_TYPE_14443;
+    }
+    else if((sak & 0b00011011) == 0b00010000){
+        return TAG_TYPE_MIFARE_PLUS_2K;
+    }
+    else if((sak & 0b00011011) == 0b00010001){
+        return TAG_TYPE_MIFARE_4K;
+    }
+}
\ No newline at end of file
--- a/NfcAdapter.h	Tue Mar 25 16:48:10 2014 +0000
+++ b/NfcAdapter.h	Tue Feb 09 16:16:11 2016 +0000
@@ -10,7 +10,14 @@
 #include <MifareClassic.h>
 #include <MifareUltralight.h>
 
-#define TAG_TYPE_MIFARE_CLASSIC (0)
+#define TAG_TYPE_MIFARE_MINI (0)
+#define TAG_TYPE_MIFARE_1K (1)
+#define TAG_TYPE_MIFARE_4K (2)
+#define TAG_TYPE_MIFARE_UL (3)
+#define TAG_TYPE_MIFARE_PLUS_2K (4)
+#define TAG_TYPE_MIFARE_PLUS_4K (5)
+#define TAG_TYPE_14443 (6)
+
 #define TAG_TYPE_1 (1)
 #define TAG_TYPE_2 (2)
 #define TAG_TYPE_3 (3)
@@ -37,7 +44,9 @@
         PN532* shield;
         uint8_t uid[7];    // Buffer to store the returned UID
         unsigned int uidLength; // Length of the UID (4 or 7 uint8_ts depending on ISO14443A card type)
+        uint8_t sak;
         unsigned int guessTagType();
+        unsigned int getTagType();
 };
 
 #endif
--- a/PN532.cpp	Tue Mar 25 16:48:10 2014 +0000
+++ b/PN532.cpp	Tue Feb 09 16:16:11 2016 +0000
@@ -12,6 +12,8 @@
 
 #ifndef ARDUINO
 #include <stdio.h>
+#include <stdlib.h>
+
 #endif
 
 #define HAL(func)   (_interface->func)
@@ -325,7 +327,10 @@
     DMSG("ATQA: 0x");  DMSG_HEX(sens_res);
     DMSG("SAK: 0x");  DMSG_HEX(pn532_packetbuffer[4]);
     DMSG("\n");
-
+    printf("ATQA: ");
+    for(int i = 0; i < 8; i++){
+        printf("%02x ",pn532_packetbuffer[i]);
+    }
     /* Card appears to be Mifare Classic */
     *uidLength = pn532_packetbuffer[5];
 
@@ -337,6 +342,72 @@
 }
 
 
+/***** ISO14443A Commands ******/
+// UPDATED FROM readPassiveTargetID with SAK bit
+/**************************************************************************/
+/*!
+    Waits for an ISO14443A target to enter the field 
+
+    @param  cardBaudRate  Baud rate of the card
+    @param  uid           Pointer to the array that will be populated
+                          with the card's UID (up to 7 bytes)
+    @param  uidLength     Pointer to the variable that will hold the
+                          length of the card's UID.
+    @param  sak           Pointer to the variable that will hold the
+                          SAK bit
+
+    @returns 1 if everything executed properly, 0 for an error
+*/
+/**************************************************************************/
+bool PN532::readPassiveTarget(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength, uint8_t *sak, uint16_t timeout)
+{
+    pn532_packetbuffer[0] = PN532_COMMAND_INLISTPASSIVETARGET;
+    pn532_packetbuffer[1] = 1;  // max 1 cards at once (we can set this to 2 later)
+    pn532_packetbuffer[2] = cardbaudrate;
+
+    if (HAL(writeCommand)(pn532_packetbuffer, 3)) {
+        return 0x0;  // command failed
+    }
+
+    // read data packet
+    if (HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer), timeout) < 0) {
+        return 0x0;
+    }
+
+    // check some basic stuff
+    /* ISO14443A card response should be in the following format:
+
+      byte            Description
+      -------------   ------------------------------------------
+      b0              Tags Found
+      b1              Tag Number (only one used in this example)
+      b2..3           SENS_RES
+      b4              SEL_RES
+      b5              NFCID Length
+      b6..NFCIDLen    NFCID
+    */
+
+    if (pn532_packetbuffer[0] != 1)
+        return 0;
+
+    uint16_t sens_res = pn532_packetbuffer[2];
+    sens_res <<= 8;
+    sens_res |= pn532_packetbuffer[3];
+
+    DMSG("ATQA: 0x");  DMSG_HEX(sens_res);
+    DMSG("SAK: 0x");  DMSG_HEX(pn532_packetbuffer[4]);
+    DMSG("\n");
+    *sak = pn532_packetbuffer[4];
+    /* Card appears to be Mifare Classic */
+    *uidLength = pn532_packetbuffer[5];
+
+    for (uint8_t i = 0; i < pn532_packetbuffer[5]; i++) {
+        uid[i] = pn532_packetbuffer[6 + i];
+    }
+
+    return 1;
+}
+
 /***** Mifare Classic Functions ******/
 
 /**************************************************************************/
--- a/PN532.h	Tue Mar 25 16:48:10 2014 +0000
+++ b/PN532.h	Tue Feb 09 16:16:11 2016 +0000
@@ -143,6 +143,7 @@
     // ISO14443A functions
     bool inListPassiveTarget();
     bool readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength, uint16_t timeout = 1000);
+    bool readPassiveTarget(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength, uint8_t *sak, uint16_t timeout = 1000) ;
     bool inDataExchange(uint8_t *send, uint8_t sendLength, uint8_t *response, uint8_t *responseLength);
 
     // Mifare Classic functions
@@ -171,6 +172,8 @@
     uint8_t _uidLen;  // uid len
     uint8_t _key[6];  // Mifare Classic key
     uint8_t inListedTag; // Tg number of inlisted tag.
+    uint8_t _SAK; // SAK bit received from card
+    uint8_t _ATQA; //
 
     uint8_t pn532_packetbuffer[64];