Search code examples
androidtagsnfcrfidiso-15693

Write Multiple Blocks command failed over NfcV


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.


Solution

  • 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);
    }