use of es.inteco.labs.android.usb.device.ccid.response.UsbResponse in project jmulticard by ctt-gob-es.
the class SmartCardChannel method transmit.
/**
* Transmite un comando USB a través del interfaz del dispositivo.
* @param command Comando USB
* @return Respuesta USB al comando
* @throws UsbCommandTransmissionException
* @throws UsbSmartCardChannelException
*/
UsbResponse transmit(final UsbCommand command) throws UsbCommandTransmissionException, UsbSmartCardChannelException {
final int responseLength = MAX_SIZE_APDU_T0 + UsbResponse.USB_HEADER_BASE_SIZE;
// Se envia el comando
usbSendCommand(command.getBytes());
// Se recoge la respuesta
UsbResponse usbResponse = new UsbResponse(command, usbRetrieveResponse(responseLength));
// Si el dispositivo CCID solicita Time Extension hay que esperar a obtener la respuesta nueva Request Wait
int timeExtensionRetryCounter = 0;
while (usbResponse.getCommandStatus() == UsbResponse.COMMAND_STATUS_TIME_EXTENSION && timeExtensionRetryCounter++ < MAX_TIME_EXTENSION_RETRIES) {
// Se esperan TIME_EXTENSION_RETRY_MS ms antes de solicitar de nuevo la respuesta
SystemClock.sleep(TIME_EXTENSION_RETRY_MS);
usbResponse = new UsbResponse(command, usbRetrieveResponse(responseLength));
}
// Comprobar si la respuesta corresponde con la peticion
if (command.getInstructionCount() != usbResponse.getSequenceNumber()) {
// $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
throw new UsbSmartCardChannelException("El ID de secuencia del comando [" + command.getInstructionCount() + "] no coincide con el de la respuesta [" + usbResponse.getSequenceNumber() + "]");
}
return usbResponse;
}
use of es.inteco.labs.android.usb.device.ccid.response.UsbResponse in project jmulticard by ctt-gob-es.
the class SmartCardUsbDevice method resetCCID.
/**
* Manda un reset al dispositivo CCID.
* @return ATR devuelto por el dispositivo
* @throws UsbDeviceException
* @throws NotAvailableUSBDeviceException
*/
public ATR resetCCID() throws UsbDeviceException, NotAvailableUSBDeviceException {
if (!isCardPresent()) {
// $NON-NLS-1$
throw new UsbDeviceException("No se ha detectado una tarjeta en el lector");
}
try {
// PowerOff
final UsbCommand powerOffCommand = UsbInstructionFactory.getInstance().getIccPowerOffCommand();
final UsbResponse powerOffResponse = getChannel().transmit(powerOffCommand);
if (!powerOffResponse.isOk()) {
// $NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
throw new UsbDeviceException("Imposible enviar PowerOff al terminal [" + HexUtils.hexify(new byte[] { powerOffResponse.getStatus() }, false) + "] - (" + HexUtils.hexify(new byte[] { powerOffResponse.getError() }, false) + ")");
}
// PowerOn
final UsbCommand powerOnCommand = UsbInstructionFactory.getInstance().getIccPowerOnCommand();
final UsbResponse powerOnResponse = getChannel().transmit(powerOnCommand);
if (powerOnResponse.isOk()) {
return new ATR(powerOnResponse.getDataBytes());
}
// $NON-NLS-1$
throw new UsbDeviceException("Imposible enviar PowerOn al terminal");
} catch (final UsbCommandTransmissionException e) {
throw new UsbDeviceException(e);
} catch (final UsbResponseException e) {
throw new UsbDeviceException(e);
} catch (final UsbSmartCardChannelException e) {
// Es necesario reconectar
if (this.flag_reconnect_channel++ < MAX_RECONNECT_CHANNEL_RETRIES) {
releaseChannel();
return resetCCID();
}
throw new UsbDeviceException(e);
}
}
use of es.inteco.labs.android.usb.device.ccid.response.UsbResponse in project jmulticard by ctt-gob-es.
the class SmartCardUsbDevice method transmit.
/**
* Envía una APDU al dispositivo.
* @param apdu Comando APDU
* @return Respuesta al envío (APDU respuesta)
* @throws UsbDeviceException
* @throws NotAvailableUSBDeviceException
*/
public byte[] transmit(final byte[] apdu) throws UsbDeviceException, NotAvailableUSBDeviceException {
try {
final UsbCommand xfrBlock = UsbInstructionFactory.getInstance().getXfrBlockCommand(apdu);
final UsbResponse response = getChannel().transmit(xfrBlock);
if (response.isOk()) {
this.flag_transmit_retries = 0;
this.flag_reconnect_channel = 0;
return response.getDataBytes();
}
// $NON-NLS-1$
throw new UsbDeviceException("Error en la transmision de la APDU");
} catch (final UsbCommandTransmissionException e) {
// Es necesario reconectar
if (this.flag_transmit_retries++ < MAX_TRANSMIT_RETRIES) {
SystemClock.sleep(RETRY_TIMEOUT);
return transmit(apdu);
}
throw new UsbDeviceException(e);
} catch (final UsbResponseException e) {
throw new UsbDeviceException(e);
} catch (final UsbSmartCardChannelException e) {
if (this.flag_reconnect_channel++ < MAX_RECONNECT_CHANNEL_RETRIES) {
releaseChannel();
return transmit(apdu);
}
throw new UsbDeviceException(e);
}
}
Aggregations