LEER TAG
Dependents: NFC_HTM_READ EMULAR_TAGS Escribir_tag NFC_HTM_READ-WRITE
MifareUltralight.cpp@1:a549ef8b142a, 2015-04-24 (annotated)
- Committer:
- mauroar211
- Date:
- Fri Apr 24 19:02:44 2015 +0000
- Revision:
- 1:a549ef8b142a
- Parent:
- 0:b805b487fbef
SE RESTAURARON LOS ARCHIVO DE LA LIBRER?A;
Who changed what in which revision?
User | Revision | Line number | New contents of line |
---|---|---|---|
mauroar211 | 0:b805b487fbef | 1 | #include "MifareUltralight.h" |
mauroar211 | 0:b805b487fbef | 2 | |
mauroar211 | 0:b805b487fbef | 3 | #include "PN532_debug.h" |
mauroar211 | 0:b805b487fbef | 4 | |
mauroar211 | 0:b805b487fbef | 5 | #define ULTRALIGHT_PAGE_SIZE 4 |
mauroar211 | 0:b805b487fbef | 6 | #define ULTRALIGHT_READ_SIZE 4 // we should be able to read 16 uint8_ts at a time |
mauroar211 | 0:b805b487fbef | 7 | |
mauroar211 | 0:b805b487fbef | 8 | #define ULTRALIGHT_DATA_START_PAGE 4 |
mauroar211 | 0:b805b487fbef | 9 | #define ULTRALIGHT_MESSAGE_LENGTH_INDEX 1 |
mauroar211 | 0:b805b487fbef | 10 | #define ULTRALIGHT_DATA_START_INDEX 2 |
mauroar211 | 0:b805b487fbef | 11 | #define ULTRALIGHT_MAX_PAGE 63 |
mauroar211 | 0:b805b487fbef | 12 | |
mauroar211 | 0:b805b487fbef | 13 | #define NFC_FORUM_TAG_TYPE_2 ("NFC Forum Type 2") |
mauroar211 | 0:b805b487fbef | 14 | |
mauroar211 | 0:b805b487fbef | 15 | MifareUltralight::MifareUltralight(PN532& nfcShield) |
mauroar211 | 0:b805b487fbef | 16 | { |
mauroar211 | 0:b805b487fbef | 17 | nfc = &nfcShield; |
mauroar211 | 0:b805b487fbef | 18 | ndefStartIndex = 0; |
mauroar211 | 0:b805b487fbef | 19 | messageLength = 0; |
mauroar211 | 0:b805b487fbef | 20 | } |
mauroar211 | 0:b805b487fbef | 21 | |
mauroar211 | 0:b805b487fbef | 22 | MifareUltralight::~MifareUltralight() |
mauroar211 | 0:b805b487fbef | 23 | { |
mauroar211 | 0:b805b487fbef | 24 | } |
mauroar211 | 0:b805b487fbef | 25 | |
mauroar211 | 0:b805b487fbef | 26 | NfcTag MifareUltralight::read(uint8_t * uid, unsigned int uidLength) |
mauroar211 | 0:b805b487fbef | 27 | { |
mauroar211 | 0:b805b487fbef | 28 | if (isUnformatted()) |
mauroar211 | 0:b805b487fbef | 29 | { |
mauroar211 | 0:b805b487fbef | 30 | DMSG("WARNING: Tag is not formatted."); |
mauroar211 | 0:b805b487fbef | 31 | return NfcTag(uid, uidLength, NFC_FORUM_TAG_TYPE_2); |
mauroar211 | 0:b805b487fbef | 32 | } |
mauroar211 | 0:b805b487fbef | 33 | |
mauroar211 | 0:b805b487fbef | 34 | readCapabilityContainer(); // meta info for tag |
mauroar211 | 0:b805b487fbef | 35 | findNdefMessage(); |
mauroar211 | 0:b805b487fbef | 36 | calculateBufferSize(); |
mauroar211 | 0:b805b487fbef | 37 | |
mauroar211 | 0:b805b487fbef | 38 | if (messageLength == 0) { // data is 0x44 0x03 0x00 0xFE |
mauroar211 | 0:b805b487fbef | 39 | NdefMessage message = NdefMessage(); |
mauroar211 | 0:b805b487fbef | 40 | message.addEmptyRecord(); |
mauroar211 | 0:b805b487fbef | 41 | return NfcTag(uid, uidLength, NFC_FORUM_TAG_TYPE_2, message); |
mauroar211 | 0:b805b487fbef | 42 | } |
mauroar211 | 0:b805b487fbef | 43 | |
mauroar211 | 0:b805b487fbef | 44 | bool success; |
mauroar211 | 0:b805b487fbef | 45 | uint8_t page; |
mauroar211 | 0:b805b487fbef | 46 | uint8_t index = 0; |
mauroar211 | 0:b805b487fbef | 47 | uint8_t buffer[bufferSize]; |
mauroar211 | 0:b805b487fbef | 48 | for (page = ULTRALIGHT_DATA_START_PAGE; page < ULTRALIGHT_MAX_PAGE; page++) |
mauroar211 | 0:b805b487fbef | 49 | { |
mauroar211 | 0:b805b487fbef | 50 | // read the data |
mauroar211 | 0:b805b487fbef | 51 | success = nfc->mifareultralight_ReadPage(page, &buffer[index]); |
mauroar211 | 0:b805b487fbef | 52 | if (success) |
mauroar211 | 0:b805b487fbef | 53 | { |
mauroar211 | 0:b805b487fbef | 54 | #ifdef MIFARE_ULTRALIGHT_DEBUG |
mauroar211 | 0:b805b487fbef | 55 | DMSG("Page ");Serial.print(page);DMSG(" "); |
mauroar211 | 0:b805b487fbef | 56 | nfc->PrintHexChar(&buffer[index], ULTRALIGHT_PAGE_SIZE); |
mauroar211 | 0:b805b487fbef | 57 | #endif |
mauroar211 | 0:b805b487fbef | 58 | } |
mauroar211 | 0:b805b487fbef | 59 | else |
mauroar211 | 0:b805b487fbef | 60 | { |
mauroar211 | 0:b805b487fbef | 61 | DMSG("Read failed ");DMSG_INT(page); |
mauroar211 | 0:b805b487fbef | 62 | // TODO error handling |
mauroar211 | 0:b805b487fbef | 63 | messageLength = 0; |
mauroar211 | 0:b805b487fbef | 64 | break; |
mauroar211 | 0:b805b487fbef | 65 | } |
mauroar211 | 0:b805b487fbef | 66 | |
mauroar211 | 0:b805b487fbef | 67 | if (index >= (messageLength + ndefStartIndex)) |
mauroar211 | 0:b805b487fbef | 68 | { |
mauroar211 | 0:b805b487fbef | 69 | break; |
mauroar211 | 0:b805b487fbef | 70 | } |
mauroar211 | 0:b805b487fbef | 71 | |
mauroar211 | 0:b805b487fbef | 72 | index += ULTRALIGHT_PAGE_SIZE; |
mauroar211 | 0:b805b487fbef | 73 | } |
mauroar211 | 0:b805b487fbef | 74 | |
mauroar211 | 0:b805b487fbef | 75 | NdefMessage ndefMessage = NdefMessage(&buffer[ndefStartIndex], messageLength); |
mauroar211 | 0:b805b487fbef | 76 | return NfcTag(uid, uidLength, NFC_FORUM_TAG_TYPE_2, ndefMessage); |
mauroar211 | 0:b805b487fbef | 77 | |
mauroar211 | 0:b805b487fbef | 78 | } |
mauroar211 | 0:b805b487fbef | 79 | |
mauroar211 | 0:b805b487fbef | 80 | bool MifareUltralight::isUnformatted() |
mauroar211 | 0:b805b487fbef | 81 | { |
mauroar211 | 0:b805b487fbef | 82 | uint8_t page = 4; |
mauroar211 | 0:b805b487fbef | 83 | uint8_t data[ULTRALIGHT_READ_SIZE]; |
mauroar211 | 0:b805b487fbef | 84 | bool success = nfc->mifareultralight_ReadPage (page, data); |
mauroar211 | 0:b805b487fbef | 85 | if (success) |
mauroar211 | 0:b805b487fbef | 86 | { |
mauroar211 | 0:b805b487fbef | 87 | return (data[0] == 0xFF && data[1] == 0xFF && data[2] == 0xFF && data[3] == 0xFF); |
mauroar211 | 0:b805b487fbef | 88 | } |
mauroar211 | 0:b805b487fbef | 89 | else |
mauroar211 | 0:b805b487fbef | 90 | { |
mauroar211 | 0:b805b487fbef | 91 | DMSG("Error. Failed read page ");DMSG_INT(page); |
mauroar211 | 0:b805b487fbef | 92 | return false; |
mauroar211 | 0:b805b487fbef | 93 | } |
mauroar211 | 0:b805b487fbef | 94 | } |
mauroar211 | 0:b805b487fbef | 95 | |
mauroar211 | 0:b805b487fbef | 96 | // page 3 has tag capabilities |
mauroar211 | 0:b805b487fbef | 97 | void MifareUltralight::readCapabilityContainer() |
mauroar211 | 0:b805b487fbef | 98 | { |
mauroar211 | 0:b805b487fbef | 99 | uint8_t data[ULTRALIGHT_PAGE_SIZE]; |
mauroar211 | 0:b805b487fbef | 100 | int success = nfc->mifareultralight_ReadPage (3, data); |
mauroar211 | 0:b805b487fbef | 101 | if (success) |
mauroar211 | 0:b805b487fbef | 102 | { |
mauroar211 | 0:b805b487fbef | 103 | // See AN1303 - different rules for Mifare Family uint8_t2 = (additional data + 48)/8 |
mauroar211 | 0:b805b487fbef | 104 | tagCapacity = data[2] * 8; |
mauroar211 | 0:b805b487fbef | 105 | #ifdef MIFARE_ULTRALIGHT_DEBUG |
mauroar211 | 0:b805b487fbef | 106 | DMSG("Tag capacity "));Serial.print(tagCapacity);DMSG(F(" uint8_ts"); |
mauroar211 | 0:b805b487fbef | 107 | #endif |
mauroar211 | 0:b805b487fbef | 108 | |
mauroar211 | 0:b805b487fbef | 109 | // TODO future versions should get lock information |
mauroar211 | 0:b805b487fbef | 110 | } |
mauroar211 | 0:b805b487fbef | 111 | } |
mauroar211 | 0:b805b487fbef | 112 | |
mauroar211 | 0:b805b487fbef | 113 | // read enough of the message to find the ndef message length |
mauroar211 | 0:b805b487fbef | 114 | void MifareUltralight::findNdefMessage() |
mauroar211 | 0:b805b487fbef | 115 | { |
mauroar211 | 0:b805b487fbef | 116 | int page; |
mauroar211 | 0:b805b487fbef | 117 | uint8_t data[12]; // 3 pages |
mauroar211 | 0:b805b487fbef | 118 | uint8_t* data_ptr = &data[0]; |
mauroar211 | 0:b805b487fbef | 119 | |
mauroar211 | 0:b805b487fbef | 120 | // the nxp read command reads 4 pages, unfortunately adafruit give me one page at a time |
mauroar211 | 0:b805b487fbef | 121 | bool success = true; |
mauroar211 | 0:b805b487fbef | 122 | for (page = 4; page < 6; page++) |
mauroar211 | 0:b805b487fbef | 123 | { |
mauroar211 | 0:b805b487fbef | 124 | success = success && nfc->mifareultralight_ReadPage(page, data_ptr); |
mauroar211 | 0:b805b487fbef | 125 | #ifdef MIFARE_ULTRALIGHT_DEBUG |
mauroar211 | 0:b805b487fbef | 126 | DMSG("Page "));Serial.print(page);Serial.print(F(" - "); |
mauroar211 | 0:b805b487fbef | 127 | nfc->PrintHexChar(data_ptr, 4); |
mauroar211 | 0:b805b487fbef | 128 | #endif |
mauroar211 | 0:b805b487fbef | 129 | data_ptr += ULTRALIGHT_PAGE_SIZE; |
mauroar211 | 0:b805b487fbef | 130 | } |
mauroar211 | 0:b805b487fbef | 131 | |
mauroar211 | 0:b805b487fbef | 132 | if (success) |
mauroar211 | 0:b805b487fbef | 133 | { |
mauroar211 | 0:b805b487fbef | 134 | if (data[0] == 0x03) |
mauroar211 | 0:b805b487fbef | 135 | { |
mauroar211 | 0:b805b487fbef | 136 | messageLength = data[1]; |
mauroar211 | 0:b805b487fbef | 137 | ndefStartIndex = 2; |
mauroar211 | 0:b805b487fbef | 138 | } |
mauroar211 | 0:b805b487fbef | 139 | else if (data[5] == 0x3) // page 5 uint8_t 1 |
mauroar211 | 0:b805b487fbef | 140 | { |
mauroar211 | 0:b805b487fbef | 141 | // TODO should really read the lock control TLV to ensure uint8_t[5] is correct |
mauroar211 | 0:b805b487fbef | 142 | messageLength = data[6]; |
mauroar211 | 0:b805b487fbef | 143 | ndefStartIndex = 7; |
mauroar211 | 0:b805b487fbef | 144 | } |
mauroar211 | 0:b805b487fbef | 145 | } |
mauroar211 | 0:b805b487fbef | 146 | |
mauroar211 | 0:b805b487fbef | 147 | #ifdef MIFARE_ULTRALIGHT_DEBUG |
mauroar211 | 0:b805b487fbef | 148 | DMSG("messageLength ");DMSG(messageLength); |
mauroar211 | 0:b805b487fbef | 149 | DMSG("ndefStartIndex ");DMSG(ndefStartIndex); |
mauroar211 | 0:b805b487fbef | 150 | #endif |
mauroar211 | 0:b805b487fbef | 151 | } |
mauroar211 | 0:b805b487fbef | 152 | |
mauroar211 | 0:b805b487fbef | 153 | // buffer is larger than the message, need to handle some data before and after |
mauroar211 | 0:b805b487fbef | 154 | // message and need to ensure we read full pages |
mauroar211 | 0:b805b487fbef | 155 | void MifareUltralight::calculateBufferSize() |
mauroar211 | 0:b805b487fbef | 156 | { |
mauroar211 | 0:b805b487fbef | 157 | // TLV terminator 0xFE is 1 uint8_t |
mauroar211 | 0:b805b487fbef | 158 | bufferSize = messageLength + ndefStartIndex + 1; |
mauroar211 | 0:b805b487fbef | 159 | |
mauroar211 | 0:b805b487fbef | 160 | if (bufferSize % ULTRALIGHT_READ_SIZE != 0) |
mauroar211 | 0:b805b487fbef | 161 | { |
mauroar211 | 0:b805b487fbef | 162 | // buffer must be an increment of page size |
mauroar211 | 0:b805b487fbef | 163 | bufferSize = ((bufferSize / ULTRALIGHT_READ_SIZE) + 1) * ULTRALIGHT_READ_SIZE; |
mauroar211 | 0:b805b487fbef | 164 | } |
mauroar211 | 0:b805b487fbef | 165 | } |