Clean up and polish Mifare Classic tech.
- It's useful to have accessors at block level, so apps don't really have to know about the sector structure (and how many blocks there are in a sector). - There's no way to tell whether a read/write/ didn't work because of auth failure. The documentation should be changed to make this point clear. - Added increment/decrement commands, for atomic increment/decrement of value blocks. Change-Id: I590feacbcd1443f1be7a86ab046a5b1f33e2e04c
This commit is contained in:
committed by
Nick Pelly
parent
c8e8a12b3c
commit
ab82a5b9a8
@@ -161,7 +161,9 @@ public final class MifareClassic extends BasicTagTechnology {
|
||||
mSize = SIZE_4K;
|
||||
break;
|
||||
default:
|
||||
// Unknown, not MIFARE
|
||||
// Unknown mifare
|
||||
mType = TYPE_UNKNOWN;
|
||||
mSize = SIZE_UNKNOWN;
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -226,9 +228,10 @@ public final class MifareClassic extends BasicTagTechnology {
|
||||
|
||||
// Methods that require connect()
|
||||
/**
|
||||
* Authenticate for a given sector.
|
||||
* Authenticate for a given block.
|
||||
* Note that this will authenticate the entire sector the block belongs to.
|
||||
*/
|
||||
public boolean authenticateSector(int sector, byte[] key, boolean keyA) {
|
||||
public boolean authenticateBlock(int block, byte[] key, boolean keyA) {
|
||||
checkConnected();
|
||||
|
||||
byte[] cmd = new byte[12];
|
||||
@@ -241,7 +244,7 @@ public final class MifareClassic extends BasicTagTechnology {
|
||||
}
|
||||
|
||||
// Second byte is block address
|
||||
cmd[1] = firstBlockInSector(sector);
|
||||
cmd[1] = (byte) block;
|
||||
|
||||
// Next 4 bytes are last 4 bytes of UID
|
||||
byte[] uid = getTag().getId();
|
||||
@@ -260,6 +263,19 @@ public final class MifareClassic extends BasicTagTechnology {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Authenticate for a given sector.
|
||||
*/
|
||||
public boolean authenticateSector(int sector, byte[] key, boolean keyA) {
|
||||
checkConnected();
|
||||
|
||||
byte addr = (byte) ((firstBlockInSector(sector)) & 0xff);
|
||||
|
||||
// Note that authenticating a block of a sector, will authenticate
|
||||
// the entire sector.
|
||||
return authenticateBlock(addr, key, keyA);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sector indexing starts at 0.
|
||||
* Block indexing starts at 0, and resets in each sector.
|
||||
@@ -269,28 +285,69 @@ public final class MifareClassic extends BasicTagTechnology {
|
||||
checkConnected();
|
||||
|
||||
byte addr = (byte) ((firstBlockInSector(sector) + block) & 0xff);
|
||||
byte[] blockread_cmd = { 0x30, addr }; // phHal_eMifareRead
|
||||
return readBlock(addr);
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads absolute block index.
|
||||
* @throws IOException
|
||||
*/
|
||||
public byte[] readBlock(int block) throws IOException {
|
||||
checkConnected();
|
||||
|
||||
byte addr = (byte) block;
|
||||
byte[] blockread_cmd = { 0x30, addr };
|
||||
|
||||
// TODO deal with authentication problems
|
||||
return transceive(blockread_cmd);
|
||||
}
|
||||
|
||||
// public byte[] readSector(int sector);
|
||||
//TODO: define an enumeration for access control settings
|
||||
// public int readSectorAccessControl(int sector);
|
||||
/**
|
||||
* Writes absolute block index.
|
||||
* @throws IOException
|
||||
*/
|
||||
public void writeBlock(int block, byte[] data) throws IOException {
|
||||
checkConnected();
|
||||
|
||||
byte addr = (byte) block;
|
||||
byte[] blockwrite_cmd = new byte[data.length + 2];
|
||||
blockwrite_cmd[0] = (byte) 0xA0; // MF write command
|
||||
blockwrite_cmd[1] = addr;
|
||||
System.arraycopy(data, 0, blockwrite_cmd, 2, data.length);
|
||||
|
||||
transceive(blockwrite_cmd);
|
||||
}
|
||||
|
||||
/**
|
||||
* Writes relative block in sector.
|
||||
* @throws IOException
|
||||
* @throws NotAuthenticatedException
|
||||
*/
|
||||
/*
|
||||
public void writeBlock(int block, byte[] data);
|
||||
public void writeSector(int block, byte[] sector);
|
||||
public void writeSectorAccessControl(int sector, int access);
|
||||
public void increment(int block);
|
||||
public void decrement(int block);
|
||||
public void writeBlock(int sector, int block, byte[] data) throws IOException {
|
||||
checkConnected();
|
||||
|
||||
byte addr = (byte) ((firstBlockInSector(sector) + block) & 0xff);
|
||||
|
||||
writeBlock(addr, data);
|
||||
}
|
||||
|
||||
public void increment(int block) throws IOException {
|
||||
checkConnected();
|
||||
|
||||
byte addr = (byte) block;
|
||||
byte[] incr_cmd = { (byte) 0xC1, (byte) block };
|
||||
|
||||
transceive(incr_cmd);
|
||||
}
|
||||
|
||||
public void decrement(int block) throws IOException {
|
||||
checkConnected();
|
||||
|
||||
byte addr = (byte) block;
|
||||
byte[] incr_cmd = { (byte) 0xC0, (byte) block };
|
||||
|
||||
transceive(incr_cmd);
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* Send data to a tag and receive the response.
|
||||
* <p>
|
||||
|
||||
Reference in New Issue
Block a user