We have an Android application that communicates with an NFC tag on a custom hardware device. The hardware device can also communicate and perform operations on the tag mounted to it.
The Android application communicates with the NFC tag in two ways:
IsoDep#transceive(byte[])
for triggering a power cycle of the hardware device.Ndef#writeNdefMessage(NdefMessage)
for writing an NdefMessage/NdefRecord with some user data.Functionally, these operations look something akin to:
private static final byte[] NDEF_SELECT_APP_FRAME = new byte[] {
(byte) 0x00, (byte) 0xA4, (byte) 0x04,
(byte) 0x00, (byte) 0x07, (byte) 0xD2,
(byte) 0x76, (byte) 0x00, (byte) 0x00,
(byte) 0x85, (byte) 0x01, (byte) 0x01
};
private static final byte[] SYSTEM_FILE_SELECT = new byte[] {
(byte) 0x00, (byte) 0xA4, (byte) 0x00,
(byte) 0x0C, (byte) 0x02, (byte) 0xE1,
(byte) 0x01
};
private static final byte[] TOGGLE_GPO = new byte[] {
(byte) 0xA2, (byte) 0xD6, (byte) 0x00,
(byte) 0x1F, (byte) 0x01, (byte) 0x00
};
boolean recordSuccess = writeRecord(tag, intent, context);
if (recordSuccess) {
boolean success = transceive(NDEF_SELECT_APP_FRAME, tag, context)
&& transceive(SYSTEM_FILE_SELECT, tag, context)
&& transceive(TOGGLE_GPO, tag, context);
if (success) {
// Success!
} else {
// Error!
}
}
We've found that, very occasionally, it seems possible that I/O can be interrupted while the Ndef data is being written (we're not sure why, but we presume pulling the phone away from the tag at just the right time is the reason). This seems to result in the tag being in a "corrupted"-like state, where the previous Ndef data can no longer be found on the tag. In fact, tag.getTechList()
won't even list Ndef
as an available technology on the tag, though it was originally available.
All further attempts to write Ndef data to the tag will then fail because Ndef.get(tag)
will return null
.
As far as I'm aware, the normal procedure from this point would be to reformat the tag using NdefFormatable
. However, NdefFormatable
is not listed as a technology type in tag.getTechList()
, and so NdefFormatable.get(tag)
also returns null
.
Questions:
NdefFormatable.get(tag)
seems to return null
?EDIT: The NFC chip appears to be a M24SR04-Y. The specification sheet can be found here: https://www.st.com/resource/en/datasheet/m24sr04-g.pdf.
Capability Container contents shown by TagInfo app:
# Capability Container (CC) file content:
Mapping version 2.0
CC length: 15 bytes
Maximum Le value: 246 bytes
Maximum Lc value: 246 bytes
NDEF File Control TLV:
* Length: 6 bytes
* NDEF file ID: 0x0001
* Maximum NDEF data size: 512 bytes
* NDEF access: Read & Write
[0] 00 0F 20 00 F6 00 F6 04 06 00 01 02 00 00 00 |.. ............ |
After having a glance at the datasheet shared by you, following are my observations:
With reference to the code snippet of operations shared by you:
Update:
Cheers!
This is very difficult to answer without knowing what type of card it is and what NFC specification it conforms to.
The first step to understanding this is to get the datasheet for the NFC card. It might be worth using an Android app like nxpinfo on it to try and determine the chip type and NFC specification type on the card which could then lead to the datasheet/nfc specification used.
Answers
2) The support of NDEF on a card is determined by a thing called the "Capability Container" in most specs, This can be stored at a specific block address or other method of reading it.
If there is no readable "Capability Container" by the defined method for the NFC specification used then the Card won't be seen as NDEF capable and formatable.
Possible this is a custom card and the "Capability Container" has been corrupted as well.
1) Unknown without more details about the card type, but another cause could be that 2 reader/writers are trying to access the card at the same time (One from the hardware device and one from the App). Normal NDEF writing/reading should not cause a problem but may be the hardware device does some custom card access method.
Hopefully when you use the App to access the Card the Hardware is powered off, so it is not possible for for this type of clash.
If not may be make a simple coil of wire connected to an LED to make a basic NFC field detector to see if the hardware is periodically doing stuff with the card that might cause a clash.
3) Again difficult to answer with knowing more about the card, BUT it might be possible on what is probably a custom card type to re-write the "Capability Container" at a low level to make formatable again if this was the cause of the problem.
Update
As it appears to be a NFC Type 4 chip but also has and I2C interface as well. It also has some extended non standard commands
Question
I guess the hardware is connected via i2C?
Reading the spec there seems to be 2 levels of security on the card that are outside of the NDEF spec (I'm not sure that the nxpinfo app will understand the values but might show them).
So it is possible that the NDEF file is password protected or made read only.
If the NDEF file has a write password the normal NDEF formatting won't be able to format it.
You will need to use a non standard Verify command
and password to be authorised before you can format it.
If the NDEF file has been permanently locked (made read only) then only the I2C connection can unlock the NDEF file. A card in this state cannot be formatted via any Android App.
The next step is to update the question with the Hex contents of the Capability Container, so the security level can be determined.
Update 2
Ok, so the card is not password protected or locked because the last 2 bytes of the CC file are 00
And as Adarsh some better logging might help determine the cause hopefully your transceive
methods check the response byte array from the IsoDep.tranceive and log any non success codes and any exceptions like TagLostException
, IOException
, etc are also caught and logged.
While you state that the corruption might be caused by the phone going out of range, the Datasheet also shows that the I2C connection can take priority over the RF connection from the phone by killing the RF connection, this could also cause corruption of the NDEF data.
If the RF connection has been killed by the I2C connection then the phone would probably not be able to do anything with the RF connection until it was removed out of range and brought back again.
At the moment I don't have any other thoughts than checking the binary contents of the NDEF file yourself with a low level binary read on a corrupted and non corrupted card. (The Taginfo App might be able to do this with it's full scan function)
But as this card updates
cards (can write at the start of the card or at any offset) I would expect Android to always start at the beginning when writing an NDEF message so should not matter if the TLV byte markers were corrupted by a truncated write for a new writeNdefMessage
. The corruption of the TLV could stop Android from reading NDEF messages from the file. (Need to check Android OS source code to confirm what it does)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With