Skip to content
Language: EN

How do you read the memory of a Type 2 tag page by page?

With the READ command, 0x30 followed by a page number, which returns sixteen bytes: four pages of four bytes each. Pages 0 to 2 hold the identifier and the static lock bytes, page 3 holds the capability container, and content starts at page 4. What follows the data area depends on the chip.

READ returns four pages

Type 2 memory is counted in pages of four bytes. READ, command 0x30 followed by the number of the first page, returns sixteen bytes, that page and the three after it. WRITE, 0xA2 followed by a page number and four bytes, writes a single page. Both values are in the definitions of Android's open source NFC stack; the normative text is the NFC Forum Type 2 Tag specification, which the Forum sells.

On Android, MifareUltralight.readPages() sends the READ and writePage() the WRITE. The class is optional, and a phone that lacks it still lists NfcA for the same tag, whose transceive() sends the same command. On iOS, a tag of the Ultralight family arrives as NFCMiFareTag, and the command goes through sendMiFareCommand, with the CRC that Apple's reference asks for.

The last pages need care. According to the MifareUltralight reference, a READ that runs past the last readable page returns pages wrapped back to the first: on an original MIFARE Ultralight, reading from page 0x0E returns pages 0x0E, 0x0F, 0x00 and 0x01. Code that reads the end of memory keeps only the pages it asked for.

The first sixteen bytes describe the tag. Pages 0 to 2 hold the identifier and internal bytes, and the last two bytes of page 2 are the static lock bytes, whose bits make pages read only for good. Page 3 is the capability container, described in general on the capability container page:

The capability container of a Type 2 tag, page 3
ByteHoldsValues in the Android stack
0NDEF magic number0xE1
1Version of the mapping0x10, 0x11 or 0x12
2Size of the data area, divided by 80x12 announces 144 bytes
3Access to the data area0x00 read and write, 0x0F read only

A tag whose byte 0 is anything other than 0xE1 is not formatted for NDEF. Byte 3 matters as much as the lock bits: the Android stack refuses to write NDEF when it does not grant write access, whatever the lock bits say.

Finding the NDEF message

From page 4, the data area holds a sequence of TLV blocks: a type byte, a length, then the value. The types are few:

TLV blocks in the data area of a Type 2 tag
TypeBlock
0x00NULL, padding that readers skip
0x01Lock Control, which describes the lock bytes
0x02Memory Control, which marks reserved areas
0x03The NDEF message
0xFDProprietary information
0xFETerminator, the last block of the data area

The length takes one byte up to 254, and three bytes from 255: 0xFF, then the length on two bytes. Code walks the blocks from page 4, skips those it does not need, and reads the message where the 0x03 block says it is. It does not assume the message starts at page 4, since a Lock Control or Memory Control block can come first.

Byte 2 of the capability container bounds the walk. Beyond 64 bytes, the size the Android stack treats as the static layout, a tag has dynamic lock bytes as well, and a Lock Control block, where present, tells where they are.

Where the chip takes over

What follows the data area belongs to the chip: dynamic lock bytes, configuration, counters, the password. An NTAG213 has 45 pages, its dynamic lock bytes in page 40 and its configuration in pages 41 to 44, according to its fiche on wakdev.com; an NTAG215 has 135 pages and keeps the same settings in pages 130 to 134. Code reads these pages from the fiche of the chip in hand, never from a page number that worked on another.

Reading can itself change something. A chip with a read counter increments it on the first read after the tag enters the field, as the NTAG213 fiche describes, and a chip whose password protects reading refuses READ on the protected pages until the code authenticates, as the authentication page explains.

Frequently asked questions

Can I read a Type 2 tag without the MifareUltralight class?

Yes. Every such tag also reports NfcA, whose transceive method sends the same READ command, 0x30 followed by the page number.

Why do the last bytes I read repeat the first pages?

The read ran past the end of memory and wrapped around, as the MifareUltralight reference describes. Keep only the pages you asked for.

Where does the NDEF message start?

Where the TLV block of type 0x03 says, found by walking the blocks from page 4. Other blocks can come before it.

Does reading a tag change it?

Not its content. On a chip with a read counter, the first read after the tag enters the field increments the counter.