import AcsCommon.Apdu;
import Pcsc.PcscReader;

public class MifareClassic {
	private PcscReader pcscReader_;

	public PcscReader getPcscConnection() {
		return this.pcscReader_;
	}

	public void setPcscConnection(PcscReader pcscConnection) {
		this.pcscReader_ = pcscConnection;
	}

	public MifareClassic() {
		pcscReader_ = null;
	}

	public MifareClassic(PcscReader pcscReader) {
		setPcscConnection(pcscReader);
	}

	public byte[] readBinaryBlock(byte blockNum) throws Exception {
		Apdu apdu = new Apdu();
		byte[] tmpArray = new byte[16];

		apdu.setCommand(new byte[] { (byte) 0xFF, (byte) 0xB0, 0x00, blockNum, 0x10 });

		apdu.setLengthExpected(16 + 2);

		getPcscConnection().sendApduCommand(apdu);

		if (apdu.getStatusWord()[0] != (byte) 0x90)
			throw new Exception("Read failed");

		System.arraycopy(apdu.getReceiveData(), 0, tmpArray, 0, 16);

		return tmpArray;
	}

	public void updateBinaryBlock(byte blockNum, byte[] data, byte length) throws Exception {
		Apdu apdu = new Apdu();

		if (data.length > 48)
			throw new Exception("Data has invalid length");

		if ((length % 16) != 0)
			throw new Exception("Data length must be multiple of 16");

		apdu.setCommand(new byte[] { (byte) 0xFF, (byte) 0xD6, (byte) 0x00, blockNum, length });
		apdu.setSendData(new byte[data.length]);
		apdu.setSendData(data);

		getPcscConnection().sendApduCommand(apdu);

		if (apdu.getStatusWord()[0] != (byte) 0x90)
			throw new Exception("Update failed");
	}
}
