I'm attempting to change the Application Family Identifier of an RFID tag from 0x07
to 0xC2
and back again using NFC on an Android phone. I've read over the standards, as well as supporting information online, and have been given some command spec by a colleague, but no matter what I do I always get an I/O error.
I am sending the command 00:27:C2
via the NFC Tools android app - however I have also been prompted to try (and failed with) 22:27:C2
and 27:C2
. The tags are new, so I'm 98% sure they're not locked, but it is a possibility and I haven't found a reliable source on how to discover if they are. I have some tags that are ICODE SLIK type, and some that are of an unknown type implementing that ISO standard.
The Log from NFC Tools are always as follows (with different chip ID depending on which I use):
> Waiting
> Chip detected: 24:03:F9:64:50:01:04:E0
> Available I/O Class: NfcV
> Connecting NfcV
> Connected
> Sending «command»
> Error: I/O failure
A warning at the beginning: my answer depends on an NfcV tag ICODE SLIX (SL2S2002) type, so please do not rely on the parameters if you are using another type. Please have a close look to the data sheet of your tag. If you are unsure about the tag type I'm recommending the NXP TagInfo app, available in app stores.
Writing to an NfcV tag is a bi different to other (storage) tags, especially when writing "administrative data" like the AFI. There is not just the command (it's 0x27h) but the Iso15693Flags as well. Using the wrong setting for this flag may damage your tag !
I wrote this method for usage on Android/Java to write a new AFI value using the default OptionSet (Flags). This needs to have the TagUID available in a global variable (tagUid) that is copied into the tagUid placeholder (the placeholder ist just a nulled UID).
public boolean writeAfi(byte afi) {
// written for ICODE SLIX (SL2S2002)
byte[] cmd = new byte[] {
/* FLAGS */ (byte)0x20, // flags: addressed (= UID field present), use default OptionSet
/* COMMAND */ WRITE_AFI_CCOMMAND, //(byte)0x27, // command write afi
/* UID */ (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,
/* OFFSET */ afi
};
System.arraycopy(tagUid, 0, cmd, 2, 8); // copy tagId to UID
byte[] response;
try {
response = nfcV.transceive(cmd);
} catch (IOException e) {
errorCode = RESPONSE_FAILURE;
errorCodeReason = "writeAfi IOException: " + e.getMessage();
Log.e(TAG, "writeAfi IOException: " + e.getMessage());
return false;
}
if (!checkResponse(response)) return false; // errorCode and reason are setup
Log.d(TAG, "afi written successfully");
errorCode = RESPONSE_OK;
errorCodeReason = RESPONSE_OK_STRING;
return true;
}
If this fails there are several reasons for:
a) the TagUID is wrong - double check with e.g. TagInfo
b) The AFI is locked. The AFI can get locked programatically and this is a "one time" command that cannot get reversed ("unlocked"). A brand new card should not be locked but when playing with such a tag...
c) The AFI is password protected, meaning you can write to this field only after a successful authentication. Same as b), a brand new tag is not protected by default.