Android
Tarjeta electrónica
Buscar..
Tarjeta inteligente de envío y recepción.
Para la conexión, aquí hay un fragmento de código para ayudarlo a comprender:
//Allows you to enumerate and communicate with connected USB devices.
UsbManager mUsbManager = (UsbManager) getSystemService(Context.USB_SERVICE);
//Explicitly asking for permission
final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
PendingIntent mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
HashMap<String, UsbDevice> deviceList = mUsbManager.getDeviceList();
UsbDevice device = deviceList.get("//the device you want to work with");
if (device != null) {
mUsbManager.requestPermission(device, mPermissionIntent);
}
Ahora debe comprender que, en java, la comunicación se realiza mediante el paquete javax.smarcard, que no está disponible para Android, por lo que puede obtener una idea de cómo puede comunicarse o enviar / recibir APDU (comando de tarjeta inteligente).
Ahora como se dice en la respuesta mencionada anteriormente
No puede simplemente enviar una APDU (comando de tarjeta inteligente) a través del punto final de carga y esperar recibir una APDU de respuesta a través del punto extremo de entrada. Para obtener los puntos finales, vea el fragmento de código a continuación:
UsbEndpoint epOut = null, epIn = null;
UsbInterface usbInterface;
UsbDeviceConnection connection = mUsbManager.openDevice(device);
for (int i = 0; i < device.getInterfaceCount(); i++) {
usbInterface = device.getInterface(i);
connection.claimInterface(usbInterface, true);
for (int j = 0; j < usbInterface.getEndpointCount(); j++) {
UsbEndpoint ep = usbInterface.getEndpoint(j);
if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {
// from host to device
epOut = ep;
} else if (ep.getDirection() == UsbConstants.USB_DIR_IN) {
// from device to host
epIn = ep;
}
}
}
}
Ahora tiene los puntos finales de entrada y salida para enviar y recibir comandos de APDU y bloques de respuesta de APDU:
Para enviar comandos, vea el fragmento de código a continuación:
public void write(UsbDeviceConnection connection, UsbEndpoint epOut, byte[] command) {
result = new StringBuilder();
connection.bulkTransfer(epOut, command, command.length, TIMEOUT);
//For Printing logs you can use result variable
for (byte bb : command) {
result.append(String.format(" %02X ", bb));
}
}
Y para recibir / leer una respuesta, vea el fragmento de código a continuación:
public int read(UsbDeviceConnection connection, UsbEndpoint epIn) {
result = new StringBuilder();
final byte[] buffer = new byte[epIn.getMaxPacketSize()];
int byteCount = 0;
byteCount = connection.bulkTransfer(epIn, buffer, buffer.length, TIMEOUT);
//For Printing logs you can use result variable
if (byteCount >= 0) {
for (byte bb : buffer) {
result.append(String.format(" %02X ", bb));
}
//Buffer received was : result.toString()
} else {
//Something went wrong as count was : " + byteCount
}
return byteCount;
}
Ahora, si ve esta respuesta aquí, el primer comando a enviar es:
PC_to_RDR_IccPowerOn comando para activar la tarjeta.
que puede crear leyendo la sección 6.1.1 de la documentación de Especificaciones de clase de dispositivo USB aquí.
Ahora vamos a tomar un ejemplo de este comando como el que se encuentra aquí: 62000000000000000000
Cómo puede enviar esto:
write(connection, epOut, "62000000000000000000");
Ahora, después de haber enviado con éxito el comando APDU, puede leer la respuesta usando:
read(connection, epIn);
Y recibir algo como
80 18000000 00 00 00 00 00 3BBF11008131FE45455041000000000000000000000000F1
Ahora, la respuesta recibida en el código aquí estará en la variable de result
del método read()
del código