Use Seeeduino Arch (or Arch Pro) + NFC Shield to read a Mifare Classic tag
Fork of PN532_P2P by
Diff: main.cpp
- Revision:
- 1:a9df716f8a64
- Parent:
- 0:21ac4fe1ccf8
- Child:
- 2:b238c6772bc4
--- a/main.cpp Thu Oct 17 07:14:21 2013 +0000 +++ b/main.cpp Thu Oct 17 07:47:22 2013 +0000 @@ -1,21 +1,13 @@ -/** - * Seeeduino Arch + NFC Shield write a NDEF record to a NFC tag - */ - - #include "mbed.h" #include "PN532.h" -#if 0 - +#if 0 // Output debug message or not #define LOG(args...) - #else #include "USBSerial.h" - #define LOG(args...) pc.printf(args) -USBSerial pc; +USBSerial pc; // Use USB to Serial //Serial pc(USBTX, USBRX); #endif @@ -24,27 +16,8 @@ DigitalOut led1(LED1); -/* - We can encode many different kinds of pointers to the card, - from a URL, to an Email address, to a phone number, and many more - check the library header .h file to see the large # of supported - prefixes! -*/ -// For a http://www. url: -const char *url = "seeedstudio.com"; -uint8_t ndefprefix = NDEF_URIPREFIX_HTTP_WWWDOT; - -// for an email address -//const char * url = "mail@example.com"; -//uint8_t ndefprefix = NDEF_URIPREFIX_MAILTO; - -// for a phone number -//const char * url = "+1 212 555 1212"; -//uint8_t ndefprefix = NDEF_URIPREFIX_TEL; - int main() { - nfc.begin(); uint32_t versiondata = nfc.getFirmwareVersion(); if (! versiondata) { @@ -60,20 +33,12 @@ nfc.SAMConfig(); - while (1) { - uint8_t success; // Flag to check if there was an error with the PN532 - uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the continueed UID + uint8_t success; + uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID uint8_t uidLength; // Length of the UID (4 or 7 bytes depending on ISO14443A card type) - bool authenticated = false; // Flag to indicate if the sector is authenticated - // Use the default NDEF keys (these would have have set by mifareclassic_formatndef.pde!) - uint8_t keya[6] = { 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5 }; - uint8_t keyb[6] = { 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7 }; - - LOG("Place your NDEF formatted Mifare Classic card on the reader to update the NDEF record\r\n"); - - // Wait for an ISO14443A type card (Mifare, etc.). When one is found + // Wait for an ISO14443A type cards (Mifare, etc.). When one is found // 'uid' will be populated with the UID, and uidLength will indicate // if the uid is 4 bytes (Mifare Classic) or 7 bytes (Mifare Ultralight) success = nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength, 0); @@ -86,54 +51,76 @@ LOG("0x%X ", uid[i]); } - // Make sure this is a Mifare Classic card - if (uidLength != 4) { - LOG("Ooops ... this doesn't seem to be a Mifare Classic card!\r\n"); - continue; - } + if (uidLength == 4) { + // We probably have a Mifare Classic card ... + LOG("Seems to be a Mifare Classic card (4 byte UID)\r\n"); + + // Now we need to try to authenticate it for read/write access + // Try with the factory default KeyA: 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF + LOG("Trying to authenticate block 4 with default KEYA value\r\n"); + uint8_t keya[6] = { 0xD3, 0xF7, 0xD3, 0xF7, 0xD3, 0xF7 }; + + // Start with block 4 (the first block of sector 1) since sector 0 + // contains the manufacturer data and it's probably better just + // to leave it alone unless you know what you're doing + success = nfc.mifareclassic_AuthenticateBlock(uid, uidLength, 4, 0, keya); + + if (success) { + LOG("Sector 1 (Blocks 4..7) has been authenticated\r\n"); + uint8_t data[16]; - // We probably have a Mifare Classic card ... - LOG("Seems to be a Mifare Classic card (4 byte UID)\r\n"); + // If you want to write something to block 4 to test with, uncomment + // the following line and this text should be read back in a minute + // data = { 'a', 'd', 'a', 'f', 'r', 'u', 'i', 't', '.', 'c', 'o', 'm', 0, 0, 0, 0}; + // success = nfc.mifareclassic_WriteDataBlock (4, data); + + // Try to read the contents of block 4 + success = nfc.mifareclassic_ReadDataBlock(4, data); - // Check if this is an NDEF card (using first block of sector 1 from mifareclassic_formatndef.pde) - // Must authenticate on the first key using 0xD3 0xF7 0xD3 0xF7 0xD3 0xF7 - success = nfc.mifareclassic_AuthenticateBlock (uid, uidLength, 4, 0, keyb); - if (!success) { - LOG("Unable to authenticate block 4 ... is this card NDEF formatted?\r\n"); - continue; + if (success) { + // Data seems to have been read ... spit it out + LOG("Reading Block 4:\r\n"); + for (int i = 0; i < 16; i++) { + LOG("%2X ", data[i]); + } + LOG(" "); + for (int i = 0; i < 16; i++) { + LOG("%c", (char)data[i]); + } + LOG("\r\n"); + } else { + LOG("Ooops ... unable to read the requested block. Try another key?\r\n"); + } + } else { + LOG("Ooops ... authentication failed: Try another key?\r\n"); + } } - LOG("Authentication succeeded (seems to be an NDEF/NFC Forum tag) ...\r\n"); - - // Authenticated seems to have worked - // Try to write an NDEF record to sector 1 - // Use 0x01 for the URI Identifier Code to prepend "http://www." - // to the url (and save some space). For information on URI ID Codes - // see http://www.ladyada.net/wiki/private/articlestaging/nfc/ndef - if (strlen(url) > 38) { - // The length is also checked in the WriteNDEFURI function, but lets - // warn users here just in case they change the value and it's bigger - // than it should be - LOG("URI is too long ... must be less than 38 characters!\r\n"); - continue; - } + if (uidLength == 7) { + // We probably have a Mifare Ultralight card ... + LOG("Seems to be a Mifare Ultralight tag (7 byte UID)\r\n"); - LOG("Updating sector 1 with URI as NDEF Message\r\n"); - - // URI is within size limits ... write it to the card and report success/failure - success = nfc.mifareclassic_WriteNDEFURI(1, ndefprefix, url); - if (success) { - LOG("NDEF URI Record written to sector 1\r\n"); - LOG("\r\n"); - } else { - LOG("NDEF Record creation failed! :(\r\n"); + // Try to read the first general-purpose user page (#4) + LOG("Reading page 4\r\n"); + uint8_t data[32]; + success = nfc.mifareultralight_ReadPage (4, data); + if (success) { + // Data seems to have been read ... spit it out + for (int i = 0; i < 4; i++) { + LOG("%2X ", data[i]); + } + LOG(" "); + for (int i = 0; i < 4; i++) { + LOG("%c", (char)data[i]); + } + LOG("\r\n"); + } else { + LOG("Ooops ... unable to read the requested page!?\r\n"); + } } - } else { - LOG("Didn't find a NFC tag\r\n"); } - - // Wait a bit before trying again - LOG("\n\nDone!\r\n"); - wait(1); + + wait(3); } } +