/*
* Commons eID Project.
* Copyright (C) 2008-2013 FedICT.
*
* This is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License version
* 3.0 as published by the Free Software Foundation.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this software; if not, see
* http://www.gnu.org/licenses/.
*/
package test.integ.be.fedict.commons.eid.client.simulation;
import java.util.Random;
import javax.smartcardio.CardException;
import javax.smartcardio.CommandAPDU;
import javax.smartcardio.ResponseAPDU;
public class ErrorCapableBeIdCard extends SimulatedBeIDCard {
protected static final ResponseAPDU WAITWAITWAIT = new ResponseAPDU(
new byte[]{0x6c, (byte) 0x00});
protected static final ResponseAPDU WHO_AM_I = new ResponseAPDU(new byte[]{
(byte) 0x6d, (byte) 0x00});
private boolean nextTooFast;
private boolean nextBitError;
private boolean nextRandomResponse;
private boolean nextCardException;
private boolean nextConfused;
private int delay;
private Random random;
public ErrorCapableBeIdCard(final String profile) {
this(profile, System.currentTimeMillis());
}
public ErrorCapableBeIdCard(final String profile, final long seed) {
super(profile);
this.random = new Random(seed);
this.delay = 0;
}
public ErrorCapableBeIdCard introduceTooFastError() {
this.nextTooFast = true;
return this;
}
public ErrorCapableBeIdCard introduceBitError() {
this.nextBitError = true;
return this;
}
public ErrorCapableBeIdCard introduceRandomResponse() {
this.nextRandomResponse = true;
return this;
}
public ErrorCapableBeIdCard introduceCardException() {
this.nextCardException = true;
return this;
}
public ErrorCapableBeIdCard introduceConfusion() {
this.nextConfused = true;
return this;
}
public int getDelay() {
return this.delay;
}
public void setDelay(final int delay) {
this.delay = delay;
}
@Override
protected ResponseAPDU transmit(final CommandAPDU apdu)
throws CardException {
if (this.nextConfused) {
this.nextConfused = false;
try {
Thread.sleep(40000);
} catch (final InterruptedException iex) {
}
return WHO_AM_I;
}
if (this.nextCardException) {
this.nextCardException = false;
throw new CardException("Fake CardException Introduced By "
+ this.getClass().getName());
}
if (this.nextTooFast) {
this.nextTooFast = false;
return WAITWAITWAIT;
}
if (this.nextRandomResponse) {
this.nextRandomResponse = false;
final byte[] randomAPDU = new byte[16];
this.random.nextBytes(randomAPDU);
return new ResponseAPDU(randomAPDU);
}
if (this.delay > 0) {
try {
Thread.sleep(this.delay);
} catch (final InterruptedException iex) {
}
}
if (this.nextBitError) {
final ResponseAPDU response = super.transmit(apdu);
final byte[] responseBytes = response.getBytes();
// flip some bits
responseBytes[this.random.nextInt(responseBytes.length)] ^= (byte) this.random
.nextInt();
return new ResponseAPDU(responseBytes);
}
return super.transmit(apdu);
}
}