I need to develop an Android app that is able to read an NfcV tag containing about 8 kByte of binary data. A single tag block is 8 bytes.
I wrote following code:
for (int i = 0; i < 256; ++i)
{
byte[] cmd = new byte[] {
0x02,
0x20,
(byte)i // Block number
};
byte[] block = nfcV.transceive(cmd);
for(int j = 0; j < 8; ++j) this.sensorData[i * 8 + j] = block[j + 1];
}
But this lets me only read the first 2 kByte of the tag (256 blocks of 8 bytes).
How can I read all 8 kByte?
Unfortunately I have few info about the Tag. I know that it's made by Texas Instruments, and Taginfo app says that it's compatible with ISO/IEC 15693-3 and ISO/IEC 15693-2.
You are using the READ SINGLE BLOCK command (command code 0x20
) to read from an ISO/IEC 15693 tag. The standard only defines the READ SINGLE BLOCK command for block addresses from 0 to 255. Hence, since your tag seems to have a block size of 8 bytes, this command limits you to the first 2 KB of the tag memory.
Reading beyond this address space is not defined by the ISO/IEC 15693 standard. Hence, this depends on the tag type that you use and you should therefore consult the user manual of your tag. Some tag manufacturers overcome this address-space limitation by defining a protocol extension (see Protocol_Extension_flag in the request flags byte of the command)
byte[] cmd = new byte[]{
(byte)0x08, //Protocol_Extension_flag=1
(byte)0x20, //READ SINGLE BLOCK
(byte)(address & 0x00FF), (byte)((address>>8) & 0x00FF)
};
However, this will only work if your tag supports this specific protocol extension. Depending on your tag type, it's also possible, that the tag uses some other method to address the remaining memory.
Also note that several Android devices will not properly work with unaddressed ISO/IEC 15693 commands. Thus, it's typically better to stick to the addressed version of commands. The addressed version of the above command (Addressed_flag set and UID of tag included in command) would like this:
byte tagId = nfcV.getTag().getId();
byte[] cmd = new byte[]{
(byte)0x28, //Addressed_flag=1, Protocol_Extension_flag=1
(byte)0x20, //READ SINGLE BLOCK
(byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, // placeholder for UID
(byte)(address & 0x00FF), (byte)((address>>8) & 0x00FF)
};
System.arraycopy(tagId, 0, cmd, 2, 8);
In both of the above cases, you could try variations of the Data_rate_flag (second lowest bit of the flags byte) and the Sub-carrier_flag (lowest bit of the flags byte), though I'm unsure how different Android devices will handle this.