I'm trying to write some data to a Mifare DesFire card with a Galaxy S3 with following lines:
private byte[] wrapMessage (byte command, byte[] parameters) throws Exception {
ByteArrayOutputStream stream = new ByteArrayOutputStream();
stream.write((byte) 0x90);
stream.write(command);
stream.write((byte) 0x00);
stream.write((byte) 0x00);
if (parameters != null) {
stream.write((byte) parameters.length);
stream.write(parameters);
}
stream.write((byte) 0x00);
return stream.toByteArray();
}
boolean isoDepWrite(Tag tag) {
IsoDep idTag = IsoDep.get(tag);
idTag.setTimeout(5000);
String info = "";
DesfireProtocol dfp = new DesfireProtocol(idTag);
try {
idTag.connect();
info += "Connected to IsoDep Tag...\n";
int[] appList = dfp.getAppList();
dfp.selectApp(appList[0]);
info += "Selected app no: " + appList[0] + "..\n";
int[] fileList = dfp.getFileList();
info += "Selected file no: " + fileList[0] + "\n";
byte[] params = {(byte)fileList[0],
(byte)0x0, (byte)0x0, (byte)0x0,
(byte)0x2, (byte)0x0, (byte)0x0,
(byte)0x41, (byte)0x41};
byte[] message = wrapMessage((byte) 0x3d, params);
byte[] result = idTag.transceive(message);
info += "Result bytes: " + convertByteArrayToHexString(result) + "\n";
toast(info);
return true;
} catch (IOException e) {
info += "Could not connect to IsoDep Tag...\n";
} catch (Exception e) {
info += "Error messages: " + e.getMessage() + " -- " + e.getLocalizedMessage() + "\n";
}
toast(info);
return false;
}
The info I get after the communication is:
Connected to IsoDep tag...
Selected app no: 1109742 // that shows I connected to an Application
Transceieve result bytes: 91 9e // PARAMETER ERROR
I can connect and read that Application's files, but the file has 0's as bytes in it after I try to write. 0x9E is PARAMETER_ERROR, so I'm doing something wrong wrapping/lining the bytes, any samples of bytes or ideas on this?
EDIT: I tried the bytes @nemo recommended:
{0x3d, fileList[0], 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x41, 0x41}
Now I get "67 00" as result bytes, meaning LENGTH ERROR and the file keeps staying the same, only 0's.
LAST EDIT: I simply created a new byte array by:
wrapMessage(0x3d, rest of the bytes in the list @nemo recommended)
And it finally worked. I changed the old one with the working above.
I think you got your Write
command wrong, but this is a shot in the dark.
According to the official DESFire documentation (try searching for M075031
) WriteData
is defined as follows:
WriteData(FileNo, Offset, Length, Data)
As a byte stream this would look like this:
WriteCmd FileNo Offset (3 byte) Length (3 byte) Data (0 to 52 byte)
[0x3D] [0x00] [0x00 0x00 0x00] [0x00 0x00 0x00] [0x00 ... 0x00]
It's even possible to write 59 byte more than those 52 byte, but that's not important here.
IMO you should make a new array with the needed data for the WriteCmd like this:
{0x3d, fileList[0], 0x0, 0x0, 0x0, 0x2, 0x0, 0x0, 0x41, 0x41}
Which should write 2 (0x2) bytes (0x41 and 0x41) to the file identified by fileList[0]
.
Edit: Updated offset, order is LSB to MSB.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With