Make Mifare Classic increment/decrement operands little endian
Also make sure they are non-negative. This is not documented in Mifare Classic spec, but based on findings from NXP: - Operand should be stored in little-endian format in the transceive buffer - Tag ignores the sign bit on the operand, its effectively 31-bit unsigned - Overflow and underflow generates an error. Change-Id: Id3389b3894ded732c4b00d564ca53f5df651359e
This commit is contained in:
@@ -22,6 +22,7 @@ import android.os.RemoteException;
|
|||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.nio.ByteBuffer;
|
import java.nio.ByteBuffer;
|
||||||
|
import java.nio.ByteOrder;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Technology class representing MIFARE Classic tags (also known as MIFARE Standard).
|
* Technology class representing MIFARE Classic tags (also known as MIFARE Standard).
|
||||||
@@ -328,12 +329,14 @@ public final class MifareClassic extends BasicTagTechnology {
|
|||||||
*/
|
*/
|
||||||
public void increment(int blockIndex, int value) throws IOException {
|
public void increment(int blockIndex, int value) throws IOException {
|
||||||
validateBlock(blockIndex);
|
validateBlock(blockIndex);
|
||||||
|
validateValueOperand(value);
|
||||||
checkConnected();
|
checkConnected();
|
||||||
|
|
||||||
ByteBuffer cmd = ByteBuffer.allocate(6);
|
ByteBuffer cmd = ByteBuffer.allocate(6);
|
||||||
|
cmd.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
cmd.put( (byte) 0xC1 );
|
cmd.put( (byte) 0xC1 );
|
||||||
cmd.put( (byte) blockIndex );
|
cmd.put( (byte) blockIndex );
|
||||||
cmd.putInt(value); // ByteBuffer does the correct big endian translation
|
cmd.putInt(value);
|
||||||
|
|
||||||
transceive(cmd.array(), false);
|
transceive(cmd.array(), false);
|
||||||
}
|
}
|
||||||
@@ -345,16 +348,24 @@ public final class MifareClassic extends BasicTagTechnology {
|
|||||||
*/
|
*/
|
||||||
public void decrement(int blockIndex, int value) throws IOException {
|
public void decrement(int blockIndex, int value) throws IOException {
|
||||||
validateBlock(blockIndex);
|
validateBlock(blockIndex);
|
||||||
|
validateValueOperand(value);
|
||||||
checkConnected();
|
checkConnected();
|
||||||
|
|
||||||
ByteBuffer cmd = ByteBuffer.allocate(6);
|
ByteBuffer cmd = ByteBuffer.allocate(6);
|
||||||
|
cmd.order(ByteOrder.LITTLE_ENDIAN);
|
||||||
cmd.put( (byte) 0xC0 );
|
cmd.put( (byte) 0xC0 );
|
||||||
cmd.put( (byte) blockIndex );
|
cmd.put( (byte) blockIndex );
|
||||||
cmd.putInt(value); // ByteBuffer does the correct big endian translation
|
cmd.putInt(value);
|
||||||
|
|
||||||
transceive(cmd.array(), false);
|
transceive(cmd.array(), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void validateValueOperand(int value) {
|
||||||
|
if (value < 0) {
|
||||||
|
throw new IllegalArgumentException("value operand negative");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Copy from temporary memory to value block.
|
* Copy from temporary memory to value block.
|
||||||
* @param blockIndex
|
* @param blockIndex
|
||||||
|
|||||||
Reference in New Issue
Block a user