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:
Martijn Coenen
2010-12-17 19:31:39 +01:00
committed by Nick Pelly
parent c8e8a12b3c
commit ab82a5b9a8

View File

@@ -161,7 +161,9 @@ public final class MifareClassic extends BasicTagTechnology {
mSize = SIZE_4K; mSize = SIZE_4K;
break; break;
default: default:
// Unknown, not MIFARE // Unknown mifare
mType = TYPE_UNKNOWN;
mSize = SIZE_UNKNOWN;
break; break;
} }
} }
@@ -226,9 +228,10 @@ public final class MifareClassic extends BasicTagTechnology {
// Methods that require connect() // 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(); checkConnected();
byte[] cmd = new byte[12]; byte[] cmd = new byte[12];
@@ -241,7 +244,7 @@ public final class MifareClassic extends BasicTagTechnology {
} }
// Second byte is block address // Second byte is block address
cmd[1] = firstBlockInSector(sector); cmd[1] = (byte) block;
// Next 4 bytes are last 4 bytes of UID // Next 4 bytes are last 4 bytes of UID
byte[] uid = getTag().getId(); byte[] uid = getTag().getId();
@@ -260,6 +263,19 @@ public final class MifareClassic extends BasicTagTechnology {
return false; 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. * Sector indexing starts at 0.
* Block indexing starts at 0, and resets in each sector. * Block indexing starts at 0, and resets in each sector.
@@ -269,28 +285,69 @@ public final class MifareClassic extends BasicTagTechnology {
checkConnected(); checkConnected();
byte addr = (byte) ((firstBlockInSector(sector) + block) & 0xff); 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); return transceive(blockread_cmd);
} }
// public byte[] readSector(int sector); /**
//TODO: define an enumeration for access control settings * Writes absolute block index.
// public int readSectorAccessControl(int sector); * @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 IOException
* @throws NotAuthenticatedException
*/ */
/* public void writeBlock(int sector, int block, byte[] data) throws IOException {
public void writeBlock(int block, byte[] data); checkConnected();
public void writeSector(int block, byte[] sector);
public void writeSectorAccessControl(int sector, int access); byte addr = (byte) ((firstBlockInSector(sector) + block) & 0xff);
public void increment(int block);
public void decrement(int block); 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. * Send data to a tag and receive the response.
* <p> * <p>