some additional fixes

Fork of PN532 by Seeed

Files at this revision

API Documentation at this revision

Comitter:
icefeet
Date:
Tue Oct 07 15:09:46 2014 +0000
Parent:
4:0774b8298eb8
Child:
8:7ffdaea03ff9
Commit message:
Added support for Ultralight Write

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
MifareUltralight.h 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
PN532_debug.h Show annotated file Show diff for this revision Revisions of this file
--- a/MifareClassic.cpp	Thu Nov 21 04:41:47 2013 +0000
+++ b/MifareClassic.cpp	Tue Oct 07 15:09:46 2014 +0000
@@ -243,7 +243,6 @@
                 return false;
             }
         }
-
         int write_success = _nfcShield->mifareclassic_WriteDataBlock (currentBlock, &buffer[index]);
         if (write_success)
         {
--- a/MifareUltralight.cpp	Thu Nov 21 04:41:47 2013 +0000
+++ b/MifareUltralight.cpp	Tue Oct 07 15:09:46 2014 +0000
@@ -77,6 +77,61 @@
 
 }
 
+bool MifareUltralight::write(NdefMessage& m, uint8_t * uid, unsigned int uidLength)
+{
+
+     if (isUnformatted())
+    {
+        printf("WARNING: Tag is not formatted.\r\n");
+        return false;
+    }
+    readCapabilityContainer(); // meta info for tag
+
+    messageLength  = m.getEncodedSize();
+    ndefStartIndex = messageLength < 0xFF ? 2 : 4;
+    calculateBufferSize();
+
+    if(bufferSize>tagCapacity) {
+       /* #ifdef MIFARE_ULTRALIGHT_DEBUG
+        Serial.print(F("Encoded Message length exceeded tag Capacity "));Serial.println(tagCapacity);
+        #endif*/
+        return false;
+    }
+
+    uint8_t encoded[bufferSize];
+    uint8_t *  src = encoded;
+    unsigned int position = 0;
+    uint8_t page = ULTRALIGHT_DATA_START_PAGE;
+
+    // Set message size. With ultralight should always be less than 0xFF but who knows?
+
+    encoded[0] = 0x3;
+    if (messageLength < 0xFF)
+    {
+        encoded[1] = messageLength;
+    }
+    else
+    {
+        encoded[1] = 0xFF;
+        encoded[2] = ((messageLength >> 8) & 0xFF);
+        encoded[3] = (messageLength & 0xFF);
+    }
+
+    m.encode(encoded+ndefStartIndex);
+    // this is always at least 1 byte copy because of terminator.
+    memset(encoded+ndefStartIndex+messageLength,0,bufferSize-ndefStartIndex-messageLength);
+    encoded[ndefStartIndex+messageLength] = 0xFE; // terminator
+
+    while (position < bufferSize){ //bufferSize is always times pagesize so no "last chunk" check
+        // write page
+        if (!nfc->mifareultralight_WritePage(page, src))
+            return false;
+        page++;
+        src+=ULTRALIGHT_PAGE_SIZE;
+        position+=ULTRALIGHT_PAGE_SIZE;
+    }
+    return true;
+}
 bool MifareUltralight::isUnformatted()
 {
     uint8_t page = 4;
--- a/MifareUltralight.h	Thu Nov 21 04:41:47 2013 +0000
+++ b/MifareUltralight.h	Tue Oct 07 15:09:46 2014 +0000
@@ -11,6 +11,7 @@
         MifareUltralight(PN532& nfcShield);
         ~MifareUltralight();
         NfcTag read(uint8_t *uid, unsigned int uidLength);
+        bool write(NdefMessage& ndefMessage, uint8_t *uid, unsigned int uidLength);
     private:
         PN532* nfc;
         unsigned int tagCapacity;
--- a/NfcAdapter.cpp	Thu Nov 21 04:41:47 2013 +0000
+++ b/NfcAdapter.cpp	Tue Oct 07 15:09:46 2014 +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->readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, (uint8_t*)&uidLength,&ATQA,&SAK);
 
     // if (success)
     // {
@@ -90,7 +90,7 @@
 bool NfcAdapter::write(NdefMessage& ndefMessage)
 {
     bool success;
-
+    uint8_t type = guessTagType();
     if (uidLength == 4)
     {
         MifareClassic mifareClassic = MifareClassic(*shield);
@@ -98,8 +98,10 @@
     }
     else
     {
-        DMSG("Unsupported Tag");
-        success = false;
+        DMSG("Ultralight Tag");
+        MifareUltralight mifareUltralight = MifareUltralight(*shield);
+        success= mifareUltralight.write(ndefMessage, uid, uidLength);
+        //success = false;
     }
     return success;
 }
@@ -116,13 +118,21 @@
     //  - ATQA 0x44 && SAK 0x8 - Mifare Classic
     //  - ATQA 0x44 && SAK 0x0 - Mifare Ultralight NFC Forum Type 2
     //  - ATQA 0x344 && SAK 0x20 - NFC Forum Type 4
-
-    if (uidLength == 4)
+    DMSG("Guess type");
+    DMSG("ATQA: 0x");  DMSG_HEX(ATQA);
+    DMSG("SAK: 0x");  DMSG_HEX(SAK);
+    /*if (uidLength == 4)
     {
         return TAG_TYPE_MIFARE_CLASSIC;
     }
     else
     {
         return TAG_TYPE_2;
+    }*/
+    if(ATQA==0x4&&SAK==0x8){
+        return TAG_TYPE_MIFARE_CLASSIC;
+    }
+    if(ATQA==0x44&&SAK==0x0){
+        return TAG_TYPE_2;
     }
 }
--- a/NfcAdapter.h	Thu Nov 21 04:41:47 2013 +0000
+++ b/NfcAdapter.h	Tue Oct 07 15:09:46 2014 +0000
@@ -38,6 +38,8 @@
         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)
         unsigned int guessTagType();
+        uint16_t ATQA;
+        uint8_t SAK;
 };
 
 #endif
--- a/PN532.cpp	Thu Nov 21 04:41:47 2013 +0000
+++ b/PN532.cpp	Tue Oct 07 15:09:46 2014 +0000
@@ -287,7 +287,7 @@
     @returns 1 if everything executed properly, 0 for an error
 */
 /**************************************************************************/
-bool PN532::readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength, uint16_t timeout)
+bool PN532::readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength, uint16_t *atqa, 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)
@@ -321,7 +321,8 @@
     uint16_t sens_res = pn532_packetbuffer[2];
     sens_res <<= 8;
     sens_res |= pn532_packetbuffer[3];
-
+    *atqa = sens_res;
+    *sak = pn532_packetbuffer[4];
     DMSG("ATQA: 0x");  DMSG_HEX(sens_res);
     DMSG("SAK: 0x");  DMSG_HEX(pn532_packetbuffer[4]);
     DMSG("\n");
@@ -496,6 +497,35 @@
     /* Read the response packet */
     return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)));
 }
+/**************************************************************************/
+/*!
+    Tries to write an entire 4-bytes data block at the specified block
+    address.
+
+    @param  blockNumber   The block number to authenticate.  (0..63 for
+                          1KB cards, and 0..255 for 4KB cards).
+    @param  data          The byte array that contains the data to write.
+
+    @returns 1 if everything executed properly, 0 for an error
+*/
+/**************************************************************************/
+uint8_t PN532::mifareultralight_WritePage (uint8_t blockNumber, uint8_t *data)
+{
+    /* Prepare the first command */
+    pn532_packetbuffer[0] = PN532_COMMAND_INDATAEXCHANGE;
+    pn532_packetbuffer[1] = 1;                      /* Card number */
+    pn532_packetbuffer[2] = MIFARE_UL_CMD_WRITE_PAGE;       /* Mifare Write command = 0xA0 */
+    pn532_packetbuffer[3] = blockNumber;            /* Block Number (0..63 for 1K, 0..255 for 4K) */
+    memcpy (pn532_packetbuffer + 4, data, 4);        /* Data Payload */
+
+    /* Send the command */
+    if (HAL(writeCommand)(pn532_packetbuffer, 8)) {
+        return 0;
+    }
+
+    /* Read the response packet */
+    return (0 < HAL(readResponse)(pn532_packetbuffer, sizeof(pn532_packetbuffer)));
+}
 
 /**************************************************************************/
 /*!
--- a/PN532.h	Thu Nov 21 04:41:47 2013 +0000
+++ b/PN532.h	Tue Oct 07 15:09:46 2014 +0000
@@ -61,7 +61,7 @@
 #define MIFARE_CMD_DECREMENT                (0xC0)
 #define MIFARE_CMD_INCREMENT                (0xC1)
 #define MIFARE_CMD_STORE                    (0xC2)
-
+#define MIFARE_UL_CMD_WRITE_PAGE            (0xA2)
 // Prefixes for NDEF Records (to identify record type)
 #define NDEF_URIPREFIX_NONE                 (0x00)
 #define NDEF_URIPREFIX_HTTP_WWWDOT          (0x01)
@@ -139,7 +139,7 @@
 
     // ISO14443A functions
     bool inListPassiveTarget();
-    bool readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength, uint16_t timeout = 1000);
+    bool readPassiveTargetID(uint8_t cardbaudrate, uint8_t *uid, uint8_t *uidLength, uint16_t *atqa, uint8_t *sak, uint16_t timeout = 1000);
     bool inDataExchange(uint8_t *send, uint8_t sendLength, uint8_t *response, uint8_t *responseLength);
 
     // Mifare Classic functions
@@ -153,7 +153,7 @@
 
     // Mifare Ultralight functions
     uint8_t mifareultralight_ReadPage (uint8_t page, uint8_t *buffer);
-
+    uint8_t mifareultralight_WritePage (uint8_t page, uint8_t *buffer);
     // Help functions to display formatted text
     static void PrintHex(const uint8_t *data, const uint32_t numBytes);
     static void PrintHexChar(const uint8_t *pbtData, const uint32_t numBytes);
--- a/PN532_debug.h	Thu Nov 21 04:41:47 2013 +0000
+++ b/PN532_debug.h	Tue Oct 07 15:09:46 2014 +0000
@@ -8,8 +8,8 @@
 #include <stdio.h>
 
 #define DMSG(args...)   printf(args)
-#define DMSG_STR(str)   printf("%s\n", str)
-#define DMSG_INT(num)   printf("%d\n", num)
+#define DMSG_STR(str)   printf("%s\r\n", str)
+#define DMSG_INT(num)   printf("%d\r\n", num)
 #define DMSG_HEX(num)   printf("%2X ", num)
 
 #else