2

I am trying to write some data to a NXP ICODE SLIX SL2S2002 tag (ISO 15693) using the WRITE MULTIPLE BLOCKS command through the NfcV object:

private void writeTagData(Tag tag) throws Exception {
    int offset = 0;
    int blocks = 19;

    String _writedata = "1hello34567850000071234561815064150220161603201016022018112233445552031033";
    byte[] data = _writedata.getBytes(StandardCharsets.UTF_8);
    data = Arrays.copyOfRange(data, 0, 4 * blocks );

    byte[] id = tag.getId();
    boolean techFound = false;
    for (String tech : tag.getTechList()) {
        if (tech.equals(NfcV.class.getName())) {
            techFound = true;
            NfcV nfcvTag = NfcV.get(tag);
            try {
                nfcvTag.connect();
            } catch (IOException e) {
                Toast.makeText(this, "IO Exception", Toast.LENGTH_LONG).show();
                return;
            }
            try {
                byte[] cmd = new byte[] {
                        (byte)0x20,
                        (byte)0x24,
                        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
                        (byte)(offset & 0x0ff),
                        (byte)((blocks - 1) & 0x0ff)
                };
                System.arraycopy(id, 0, cmd, 2, 8);

                byte[] cmd_plus_data = new byte[88];
                System.arraycopy(cmd, 0, cmd_plus_data, 0, cmd.length);
                System.arraycopy(data, 0, cmd_plus_data, 12, data.length);

                byte[] response = nfcvTag.transceive(cmd_plus_data);
                String strResponse = Common.toHexString(response);
            } catch (IOException e) {
                Toast.makeText(this, e.getMessage(), Toast.LENGTH_SHORT).show();
                return;
            }

            try {
                nfcvTag.close();
            } catch (IOException e) {
                Toast.makeText(getApplicationContext(), e.getMessage(), Toast.LENGTH_SHORT).show();
                return;
            }
        }
    }
}

The response from the transceive(...) method is 010f (indicating "Unknown Error"). Previously, I was able to read data using the command READ MULTIPLE BLOCKS from the same tag successfully.

I tried to to call getMaxTransceiveLength() on the NfcV object and the value is 253.

Michael Roland
  • 39,663
  • 10
  • 99
  • 206
ibrahim
  • 195
  • 1
  • 2
  • 14

1 Answers1

6

ISO/IEC 15693 defines the WRITE MULTIPLE BLOCKS commands as optional command. It is up to the tag chip (or actually its manufacturer) to implement this command.

In your case, the NXP ICODE SLIX SL2S2xx2 (just like all (most?) ICODE SLI/SLIX tags) does not support the WRITE MULTIPLE BLOCKS command. Consequently, the tag returns the error code 0x0F. The ICODE SLIX SL2S2xx2 datasheet defines that this error code is returned in case a command is not supported.

Instead, the SL2S2xx2 supports the WRITE SINGLE BLOCK (0x21) command. You could use that command in a loop to write all your data:

byte[] cmd = new byte[] {
        /* FLAGS   */ (byte)0x20,
        /* COMMAND */ (byte)0x21,
        /* UID     */ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
        /* OFFSET  */ (byte)0x00,
        /* DATA    */ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00
};
System.arraycopy(id, 0, cmd, 2, 8);

for (int i = 0; i < blocks; ++i) {
    cmd[10] = (byte)((offset + i) & 0x0ff);
    System.arraycopy(data, 4 * i, cmd, 11, 4);

    byte[] response = nfcvTag.transceive(cmd);
}
Michael Roland
  • 39,663
  • 10
  • 99
  • 206
  • This is really nice. May I know where will get the reference of NfcV commands ? – Shihab May 16 '19 at 20:04
  • @Shihab The basic command set (such as READ/WRITE SINGLE BLOCK) is defined in ISO/IEC 15693, so you can find them there. – Michael Roland May 17 '19 at 23:53
  • @Michael Roland sometimes writing multiple single block looses connection and throw, "java.lang.IllegalStateException: Call connect() first!" . And this is pretty random, I mean not at the fixed block. Each write/read in my case write to more than 12 blocks of data. Is it advisable to call tag connect -> write single block -> close tag in a loop for as many blocks. – Praween k May 16 '20 at 07:17