How do you read the blocks of an ISO/IEC 15693 tag?
With Read Single Block, command 0x20, or Read Multiple Blocks, 0x23, after asking the tag for its block size and block count with Get System Information, 0x2B. Blocks are often four bytes, but the size varies with the chip. A request can address one tag by its identifier or go to any tag in the field.
How a request is built
An ISO/IEC 15693 request is a flags byte, a command code, then parameters. The NfcV reference asks Android code for exactly those three parts and adds the CRC itself. Core NFC builds the request for each standard command and takes the flags as an option set, NFCISO15693RequestFlag.
Four flags matter for reading, with the values the definitions of Android's open source NFC stack give them:
| Flag | Value | Effect |
|---|---|---|
| High data rate | 0x02 | The tag answers at the faster rate |
| Select | 0x10 | Only a tag in the selected state executes the request |
| Address | 0x20 | The 8 byte identifier follows the command code, and only that tag executes it |
| Option | 0x40 | Defined by each command; on a read, adds the block security status |
Without the address or select flag, every tag in the field that receives the request executes it, which is harmless with one tag and ambiguous with two. Core NFC sets the address flag by default and sends the tag's identifier with the command, and setting the select flag turns addressing off, according to the readSingleBlock reference.
The identifier's byte order is where ports break. Apple gives identifier in big endian order, so it starts with 0xE0, the byte every ISO/IEC 15693 identifier begins with according to the Android stack's definitions. Code that builds an addressed request by hand, or compares identifiers read on both platforms, checks which end the 0xE0 is at before using them.
Ask the tag its size first
Get System Information, 0x2B, returns an information flags byte, the identifier, then optional fields, the memory size among them. That field gives the number of blocks and the block size, both encoded as one less than their value, the block size in its lowest five bits; the Android stack adds one to each before using them.
On iOS, getSystemInfo returns the decoded values, and from iOS 14 systemInfo(requestFlags:) returns them as NFCISO15693SystemInfo, with blockSize and totalBlocks.
The answer varies with the chip. The Android stack handles blocks of 4, 8, 16 and 32 bytes, and an ICODE SLIX2 has 80 blocks of four bytes, the last holding a counter, according to its fiche on wakdev.com. Some chips leave the memory size out, and the Android stack then falls back on sizes it knows for particular references, a table an app would have to hold as well.
One block or several
Read Single Block, 0x20, takes one block number, from 0 to 255 in the standard form, as Apple's reference states. Read Multiple Blocks, 0x23, takes the first block and a count encoded as one less than the number of blocks, so 0x00 reads one block.
A tag with more than 256 blocks needs the extended commands, whose block numbers take two bytes: Extended Read Single Block is 0x30, from the NFC Forum Type 5 Tag specification according to Apple's extendedReadSingleBlock reference, and 0x33 reads several.
Read Multiple Blocks is optional. On a tag formatted for NDEF, bit 0 of the fourth byte of the capability container, in block 0, says whether the tag supports it, and the Android stack reads that bit before using the command. Without it, read one block at a time.
Errors and custom commands
A tag that refuses a request answers with the error bit, 0x01, set in its response flags, followed by an error code: 0x03 for an option the tag does not support, 0x13 for a block it failed to write, among the codes the Android stack names. Core NFC reports such an answer as an error whose user information carries NFCISO15693TagResponseErrorKey and the code from the standard.
Command codes 0xA0 to 0xDF are custom commands, defined by each chip maker. Apple's customCommand reference inserts the manufacturer code after the command byte, and the commands themselves, such as those that manage a chip's passwords, come from that chip's fiche.
Frequently asked questions
Is the block size always four bytes?
No. The Android stack handles blocks of 4, 8, 16 and 32 bytes. Read the size from Get System Information before reading blocks.
What does addressed mode change?
It adds the tag's 8 byte identifier to the request, so only that tag executes it. Core NFC uses it by default.
Why does Read Multiple Blocks fail on some tags?
The command is optional. Check the capability container of a tag formatted for NDEF, or read one block at a time.
Does a phone read an ISO/IEC 15693 tag at a distance?
No. The standard allows range with large readers, but a phone reads it at a tap, as the ISO/IEC 15693 page explains.