use of es.gob.jmulticard.apdu.connection.ApduConnectionException in project jmulticard by ctt-gob-es.
the class SmartcardIoConnection method transmit.
/**
* {@inheritDoc}
*/
@Override
public ResponseApdu transmit(final CommandApdu command) throws ApduConnectionException {
if (this.canal == null) {
throw new ApduConnectionException(// $NON-NLS-1$
"No se puede transmitir sobre una conexion cerrada");
}
if (command == null) {
throw new IllegalArgumentException(// $NON-NLS-1$
"No se puede transmitir una APDU nula");
}
if (DEBUG) {
// $NON-NLS-1$
Logger.getLogger("es.gob.jmulticard").info(// $NON-NLS-1$
"Enviada APDU:\n" + HexUtils.hexify(command.getBytes(), true));
}
try {
byte[] sendApdu;
if (command.getData() != null) {
// Si la APDU es mayor que 0xFF la troceamos y la envolvemos
if (command.getData().length > 0xFF) {
int sentLength = 0;
final int totalLength = command.getBytes().length;
final int CONTENT_SIZE_ENVELOPE = 250;
while (totalLength - sentLength > CONTENT_SIZE_ENVELOPE) {
final byte[] apduChunk = Arrays.copyOfRange(command.getBytes(), sentLength, sentLength + CONTENT_SIZE_ENVELOPE);
final CommandAPDU apdu = new CommandAPDU((byte) 0x90, (byte) 0xC2, (byte) 0x00, (byte) 0x00, apduChunk);
final ResponseApdu response = new ResponseApdu(this.canal.transmit(apdu).getBytes());
if (!response.isOk()) {
return response;
}
sentLength += CONTENT_SIZE_ENVELOPE;
}
final byte[] apduChunk = Arrays.copyOfRange(command.getBytes(), sentLength, totalLength);
sendApdu = new CommandAPDU((byte) 0x90, (byte) 0xC2, (byte) 0x00, (byte) 0x00, apduChunk).getBytes();
} else // Si es pequena, se envia directamente
{
sendApdu = command.getBytes();
}
} else {
sendApdu = command.getBytes();
}
final ResponseApdu response = new ResponseApdu(this.canal.transmit(new CommandAPDU(sendApdu)).getBytes());
// Solicitamos el resultado de la operacion si es necesario
if (response.getStatusWord().getMsb() == TAG_RESPONSE_PENDING) {
// Si ya se ha devuelto parte de los datos, los concatenamos al resultado
if (response.getData().length > 0) {
final byte[] data = response.getData();
final byte[] additionalData = transmit(new GetResponseApduCommand((byte) 0x00, response.getStatusWord().getLsb())).getBytes();
final byte[] fullResponse = new byte[data.length + additionalData.length];
System.arraycopy(data, 0, fullResponse, 0, data.length);
System.arraycopy(additionalData, 0, fullResponse, data.length, additionalData.length);
return new ResponseApdu(fullResponse);
}
return transmit(new GetResponseApduCommand((byte) 0x00, response.getStatusWord().getLsb()));
} else // (de eso se encargara la clase de conexion con canal seguro)
if (response.getStatusWord().getMsb() == TAG_RESPONSE_INVALID_LENGTH && command.getCla() == (byte) 0x00) {
command.setLe(response.getStatusWord().getLsb());
return transmit(command);
}
if (DEBUG) {
// $NON-NLS-1$
Logger.getLogger("es.gob.jmulticard").info(// $NON-NLS-1$
"Respuesta:\n" + HexUtils.hexify(response.getBytes(), true));
}
return response;
} catch (final CardException e) {
final Throwable t = e.getCause();
if (t != null && SCARD_W_RESET_CARD.equals(t.getMessage())) {
throw new LostChannelException(t.getMessage());
}
throw new ApduConnectionException(// $NON-NLS-1$
"Error de comunicacion con la tarjeta tratando de transmitir la APDU " + HexUtils.hexify(command.getBytes(), true) + " al lector " + // $NON-NLS-1$
Integer.toString(this.terminalNumber) + // $NON-NLS-1$
" en modo EXCLUSIVE=" + Boolean.toString(this.exclusive) + " con el protocolo " + // $NON-NLS-1$
this.protocol.toString(), // $NON-NLS-1$
e);
} catch (final Exception e) {
e.printStackTrace();
throw new ApduConnectionException(// $NON-NLS-1$
"Error tratando de transmitir la APDU " + HexUtils.hexify(command.getBytes(), true) + " al lector " + // $NON-NLS-1$
Integer.toString(this.terminalNumber) + // $NON-NLS-1$
" en modo EXCLUSIVE=" + Boolean.toString(this.exclusive) + " con el protocolo " + // $NON-NLS-1$
this.protocol.toString(), // $NON-NLS-1$
e);
}
}
use of es.gob.jmulticard.apdu.connection.ApduConnectionException in project jmulticard by ctt-gob-es.
the class AndroidNfcConnection method transmit.
@Override
public ResponseApdu transmit(final CommandApdu command) throws ApduConnectionException {
if (this.mIsoDep == null) {
throw new ApduConnectionException(// $NON-NLS-1$
"No se puede transmitir sobre una conexion NFC cerrada");
}
if (command == null) {
throw new IllegalArgumentException(// $NON-NLS-1$
"No se puede transmitir una APDU nula");
}
if (!this.mIsoDep.isConnected()) {
try {
this.mIsoDep.connect();
} catch (final IOException e) {
throw new ApduConnectionException(// $NON-NLS-1$
"Se ha producido un problema al intentar establecer la conexion por NFC: " + e, // $NON-NLS-1$
e);
}
}
final byte[] commandBytes;
if (command instanceof VerifyApduCommand) {
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
final byte[] bcomm = command.getBytes();
final byte[] bdata = command.getData();
baos.write(bcomm, 0, bcomm.length - 2);
try {
baos.write(new byte[] { (byte) bdata.length });
baos.write(bdata);
} catch (final IOException e) {
throw new ApduConnectionException(// $NON-NLS-1$
"Error preparando la APDU para su envio", e);
}
commandBytes = baos.toByteArray();
} else {
commandBytes = command.getBytes();
}
// Liberamos la conexion para transmitir
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
NFCWatchdogRefresher.stopHoldingConnection();
}
final byte[] bResp;
try {
bResp = this.mIsoDep.transceive(commandBytes);
} catch (final IOException e) {
// Evitamos que salga el PIN en la traza de excepcion
throw new ApduConnectionException(// $NON-NLS-1$
"Error tratando de transmitir la APDU" + (// $NON-NLS-1$
(command instanceof VerifyApduCommand) ? // $NON-NLS-1$
" de verificacion de PIN" : (" " + HexUtils.hexify(command.getBytes(), true))) + // $NON-NLS-1$
" via NFC", e);
} finally {
// Retenemos la conexion hasta nuestro siguiente envio
if (android.os.Build.VERSION.SDK_INT >= android.os.Build.VERSION_CODES.GINGERBREAD_MR1) {
NFCWatchdogRefresher.holdConnection(this.mIsoDep);
}
}
if (bResp.length < 2) {
throw new ApduConnectionException(// $NON-NLS-1$
"No se ha recibido respuesta al envio del comando");
}
final ResponseApdu response = new ResponseApdu(bResp);
if (response.getStatusWord().getMsb() == 97) {
if (response.getData().length > 0) {
final byte[] data = response.getData();
final byte[] additionalData = this.transmit(new GetResponseApduCommand((byte) 0, response.getStatusWord().getLsb())).getBytes();
final byte[] fullResponse = new byte[data.length + additionalData.length];
System.arraycopy(data, 0, fullResponse, 0, data.length);
System.arraycopy(additionalData, 0, fullResponse, data.length, additionalData.length);
return new ResponseApdu(fullResponse);
}
return this.transmit(new GetResponseApduCommand((byte) 0, response.getStatusWord().getLsb()));
}
if (response.getStatusWord().getMsb() == 108 && command.getCla() == 0) {
command.setLe(response.getStatusWord().getLsb());
return this.transmit(command);
}
return response;
}
use of es.gob.jmulticard.apdu.connection.ApduConnectionException in project jmulticard by ctt-gob-es.
the class JMultiCardProviderFactory method getProvider.
/**
* Obtiene el proveedor (con la conexión por defecto) correspondiente
* a la primera tarjeta encontrada en el sistema.
* @return Proveedor (con la conexión por defecto) correspondiente
* a la primera tarjeta encontrada insertada o <code>null</code> si
* no hay ninguna insertada, no ha lector de tarjetas o no se
* encuentra ninguna tarjeta soportada.
*/
public static Provider getProvider() {
final ApduConnection conn = new SmartcardIoConnection();
final long[] terminals;
try {
terminals = conn.getTerminals(false);
} catch (final ApduConnectionException e1) {
LOGGER.warning(// $NON-NLS-1$
"No se ha podido obtener la lista de lectores de tarjetas del sistema: " + e1);
return null;
}
byte[] atr = null;
for (final long terminal : terminals) {
conn.setTerminal((int) terminal);
try {
atr = conn.reset();
} catch (final Exception e) {
continue;
}
}
return getProvider(atr);
}
Aggregations