Question

I have some ISO15693 / Tag-it HF-I Plus chips and need to write something on them. These chips are completly fresh, and i read now a ton of pdf's telling me all the same. But nothing work, and i get all the time the Transceive Failed error.

I send these Data in the transceive command:

Byte:  <data>
0:     0x00 // pdf says the tag understands only flag = 0x00
1:     0x21 // write single block
2-10:  ID // needs to be send for this tag, only supports addressed mode
11:    0x00 // Block ID, try to write to block 0
12-16: DATA // LSB First
17-18: CRC16 // do i need to send this? and if yes, LSB first?

I tried very different flags and write modes but none of them work:

Flags: 0x01, 0x02, 0x20,0x22,0x42,0x40,0x80,0x82
Modes: 0x21,0xA2 (+ Vendor Mode 0x07)

this is my write function:

private void write(Tag tag) throws IOException, FormatException {
if (tag == null) {
    return;
}
NfcV nfc = NfcV.get(tag);
byte[] ID = tag.getId();

nfc.connect();

Log.d(TAG, "Data: " + new String(((EmergencyApplication) getApplication()).getData()));

byte[] data = ((EmergencyApplication) getApplication()).getData();
// NfcV Tag has 64 Blocks with 4 Byte
if ((data.length / 4) > 64) {
    // ERROR HERE!
    Log.d(TAG, "too much data...");
}

for (int i = 0; i < data.length; i++) {
    byte[] arrByte = new byte[17];

    // Flags
    arrByte[0] = 0x00; // Tag only supports flags = 0
    // Command
    arrByte[1] = 0x21;
    // ID
    Log.d(TAG, "Found ID length: " + ID.length + "... ID: " + Arrays.toString(ID));
    System.arraycopy(ID, 0, arrByte, 2, 8);
    // block number
    arrByte[10] = (byte) (i);

    // data
    // TODO send LSB first...
    System.arraycopy(data, i * 4, arrByte, 11, 4);

    // CRC 16 of all command
    byte[] check = new byte[15];
    System.arraycopy(arrByte, 0, check, 0, 15);
    int crc = CRC.crc16(check);
    arrByte[15] = (byte) (crc >> 8);
    arrByte[16] = (byte) (crc & 0xFF);

    Log.d(TAG, "Writing Data: " + Arrays.toString(arrByte));

    byte[] result = nfc.transceive(arrByte);
    Log.d(TAG, "got result: " + Arrays.toString(result));
}

nfc.close();
Toast.makeText(this, "wrote to tag", Toast.LENGTH_LONG).show();

}

Is it another bug with the Nexus S? I use Cyanogenmod 10.1.2, so i think the Tag Lost Bug is fixed here... I can obviously read the tag and if i use the NFC Tag Info App, it shows me all block clear and writeable. I have these PDFs read:

http://rfidshop.com.hk/datasheet%20tag/philip%20icode%20SLI.pdf - Datasheet of my Tag http://www.waazaa.org/download/fcd-15693-3.pdf - ISO15693-3 datasheet http://www.ti.com/lit/ug/scbu003a/scbu003a.pdf - Tag-it HF-I Plus datasheet

I tested Reading with the code from here: Reading a NXP ICODE SLI-L tag with Android - it works on all 64 blocks but writing still doesnt work... even with flag = 0x20...

Edit: I saw now that the DSFID on the Card is 0x00, which means for ISO15693-3 that the card is not writeable at all:

If its programming is not supported by the VICC, the VICC shall respond with the value zero ('00')

This is the byte[] when sending 0x2B:

                                                     DSFID \  / AFI
                                                           |  |
                                                           v  v
infoRmation: [0, 15, 120, 40, -51, -51, 119, -128, 7, -32, 0, 0, 63, 3, -117]
Was it helpful?

Solution

Found some things out, i want to share:

  • Don't Send the Data with LSB first, it seems that the transceive command does this automatically on sending
  • Don't use addressed mode, it seems that the android implementation has some problems with that
  • Set the Option bit (0x40) in the Flags.
  • Fast Mode (0x02) seems to be supported by my tags, so you can set it or not
  • Don't set the CRC16, because it's added by android

But the worst thing at all is, that the Tags does not respond in the time that is compiled into the tag writer. You will get a Tag is lost. Exception but the Data will be written to the Tag! So the solution is to just ignore this exception and maybe validate the data after writing and try again if it doesnt work.

My current write code looks like this:

public static void write(Tag tag, byte[] data) throws IOException, FormatException,
InterruptedException {
if (tag == null) {
    return;
}
NfcV nfc = NfcV.get(tag);

nfc.connect();

Log.d(TAG, "Max Transceive Bytes: " + nfc.getMaxTransceiveLength());

// NfcV Tag has 64 Blocks with 4 Byte
if ((data.length / 4) > 64) {
    // ERROR HERE!
    Log.d(TAG, "too much data...");
}

if ((data.length % 4) != 0) {
    byte[] ndata = new byte[(data.length) + (4 - (data.length % 4))];
    Arrays.fill(ndata, (byte) 0x00);
    System.arraycopy(data, 0, ndata, 0, data.length);
    data = ndata;
}

byte[] arrByte = new byte[7];
// Flags
arrByte[0] = 0x42;
// Command
arrByte[1] = 0x21;

for (int i = 0; i < (data.length / 4); i++) {

    // block number
    arrByte[2] = (byte) (i);

    // data, DONT SEND LSB FIRST!
    arrByte[3] = data[(i * 4)];
    arrByte[4] = data[(i * 4) + 1];
    arrByte[5] = data[(i * 4) + 2];
    arrByte[6] = data[(i * 4) + 3];

    Log.d(TAG, "Writing Data to block " + i + " [" + printHexString(arrByte) + "]");
    try {
    nfc.transceive(arrByte);
    } catch (IOException e) {
    if (e.getMessage().equals("Tag was lost.")) {
        // continue, because of Tag bug
    } else {
        throw e;
    }
    }
}

nfc.close();
}

and it works pretty well. If there is a real error, like the message is not understood, you will get the Transceive Failed message.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top