0
votes

When I try to transceive commands for NFC-V Tag-it HF-I Plus Inlay tag I get a TagLostException for most of the commands.

From the links I have gone through this exception may be caused by incorrect commands.

How can I create correct ISO15693 command byte[] for Nfc V Tag-it HF-I Plus Inlay?

The datasheet shows the supported commands but how can I create correct commands to read NFC-V tags?

The commands in the document are:

The tag that I'm trying to read is:

Code:

Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
Log.i(TAG, " tag "+tag );
if (tag != null) {
    NfcV tech = NfcV.get(tag);
    Log.i(TAG, " tech "+tech  );

    if (tech != null) {
    try {
        tech.connect();
        Log.i(TAG, " on connect" );
        byte[] data = tech.transceive(Nfcv.InventoryRequest());
        Log.i(TAG, "resp data " + data);
        StringBuilder sb = new StringBuilder();
        for (int i = 0; i < data.length; i++) {
            byte b = data[i];
            System.out.println(b);
            sb.append(String.format("%02X ", b));
        }
        System.out.println("response: " + sb.toString());
    } catch (IOException e) {
        e.printStackTrace();
    } finally {
        try {
            tech.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

I have gone through the following:

EDIT

Commands that I have tried:

public class Nfcv {
    // texas get system info -> tag lost exception
    public static byte[] GET_SYSTEM_INFO = ReadNfcActivity.hexStringToByteArray("010A00030418002B0000");

    //read multiple blocks -> not working
    byte[] read_multiple_blocks= ReadNfcActivity.hexStringToByteArray("010C00030418002301020000");

    byte[] readSingleBlock = ReadNfcActivity.hexStringToByteArray("010B000304180020050000");

    // readUID generic command -> not working
    public static byte[] readUID = ReadNfcActivity.hexStringToByteArray("FFCA000000");

    public static  byte[] InventoryRequest(){
        //working response: 00 00 3A E5 00 04 00 00 07 E0
        // R/0 UID is E0 07 00 00 04 00 E5 3A 00 00 (reverse)
        return new byte[] { (byte) 0x24, (byte) 0x01, (byte) 0x00};
    }

    //-> not working
    private byte[] ReadSingleBlockUnadressed(byte blocknumber) {
        return new byte[] {(byte) 0x00, (byte) 0x20, blocknumber};
    }

    //-> response 03
    public static byte[] get_system_info = {0x00,(byte)0x2B};
}
1
It might help if you added the relevant code (e.g. what is Nfcv.InventoryRequest()?)Michael Roland
@MichaelRoland pls see my editRachita Nanda

1 Answers

2
votes

The Android NFC stack automatically handles polling (searching for tags various tag technologies/protocols), anti-collision (enumeration of multiple tags within one tag technology/protocol) and activation (intitiating communication with one specific tag) for you. You should, therefore, never send commands used for anti-collision and activation yourself. The Inventory command is one such command (that is used to discover tags in range).

With regard to the Inventory command, there is typically no need to send this command. All the information that you would get from this command is already provided by the Android NFC API:

  • You can get the UID using tag.getId().
  • You can get the DSFID using tech.getDsfId().

Also, for your app to work reliable across different Android device platforms (= different NFC stacks), you should always use the addressed version of commands (i.e. Address_flag set and UID sent as part of request). See Android NfcV get information command returns only one byte.

If you want to read from/write to the tag, you could use the READ_SINGLE_BLOCK and WRITE_SINGLE_BLOCK commands:

byte[] tagUid = tag.getId();  // store tag UID for use in addressed commands
int blockAddress = 0; // block address that you want to read from/write to

READ_SINGLE_BLOCK:

byte[] cmd = new byte[] {
    (byte)0x20,  // FLAGS
    (byte)0x20,  // READ_SINGLE_BLOCK
    0, 0, 0, 0, 0, 0, 0, 0,
    (byte)(blockAddress & 0x0ff)
};
System.arraycopy(tagUid, 0, cmd, 2, 8);

byte[] response = tech.transceive(cmd);

WRITE_SINGLE_BLOCK:

byte[] cmd = new byte[] {
    (byte)0x60,  // FLAGS
    (byte)0x21,  // WRITE_SINGLE_BLOCK
    0, 0, 0, 0, 0, 0, 0, 0,
    (byte)(blockAddress & 0x0ff),
    ... // data block that you want to write (same length as the blocks that you read)
};
System.arraycopy(tagUid, 0, cmd, 2, 8);

byte[] response = tech.transceive(cmd);