some additional fixes
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
- Child:
- 8:7ffdaea03ff9
- 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