Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
Fork of PN532 by
Revision 5:51f820fbd18a, committed 2014-10-07
- Comitter:
- icefeet
- Date:
- Tue Oct 07 15:09:46 2014 +0000
- Parent:
- 4:0774b8298eb8
- Commit message:
- Added support for Ultralight Write
Changed in this revision
--- 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