Cómo leer una tarjeta inteligente / tarjeta de microprocesador usando un lector de tarjeta inteligente en Android mediante programación

Así que últimamente he estado trabajando con tarjetas inteligentes que contienen información y lo que estoy tratando de lograr aquí es obtener estos datos de estas tarjetas inteligentes utilizando un lector de tarjetas inteligentes a través de cualquier teléfono inteligente Android. He estado usando unHID OMNIKEY 3021 USB lector de tarjetas inteligentes que leería estas tarjetas (y sé que este lector funciona con estas tarjetas a través de aplicaciones de Windows porque lo he probado personalmente)

Ahora Android proporcionaPuerto USB eso permite leer cualquier host USB siempre que los teléfonos inteligentes Android lo admitan.

Y estoy tratando de usar estas clases proporcionadas por USB Host para llegar a los datos dentro de esta tarjeta.

Mi código para detectar cualquier host USB:

private static final String ACTION_USB_PERMISSION = "com.android.example.USB_PERMISSION";
PendingIntent mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);

IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
registerReceiver(mUsbReceiver, filter);

IntentFilter attachedFilter = new IntentFilter(UsbManager.ACTION_USB_DEVICE_ATTACHED);
registerReceiver(mUsbAttachedReceiver, attachedFilter);

private final BroadcastReceiver mUsbAttachedReceiver = new BroadcastReceiver() {
    @Override
    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        Utils.writeStringToTextFile("\n1 .Get an action : " + action, FileName);
        if (UsbManager.ACTION_USB_DEVICE_ATTACHED.equals(action)) {
            synchronized (this) {
                device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
                if (device != null) {
                    showToast("Plugged In");
                    mUsbManager.requestPermission(device, mPermissionIntent);
                }
            }
        } else if (UsbManager.ACTION_USB_DEVICE_DETACHED.equals(action)) {
            UsbDevice device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
            if (device != null) {
                showToast("Plugged Out");
                // call your method that cleans up and closes communication with the device
            }
        }
    }
};

private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {

    public void onReceive(Context context, Intent intent) {
        String action = intent.getAction();
        if (ACTION_USB_PERMISSION.equals(action)) {
            synchronized (this) {
                device = intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);

                if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
                    if (device != null) {
                        //call method to set up device communication
                        Utils.writeStringToTextFile("2 .Get an action : " + action + "\nDevice is : " + device, FileName);
                        showToast("Permission Granted for device");

                        Handler h = new Handler();
                        h.postDelayed(run, 1000);

                    }
                } else {
                    showToast("Permission denied for device" + device);
                }
            }
        }
    }
};

Todo funciona como se esperaba cuando recibo elUsbDevice device que da la información del dispositivo, por ejemplo:

Device is : UsbDevice[mName=/dev/bus/usb/001/002,mVendorId=1899,mProductId=12322,mClass=0,mSubclass=0,mProtocol=0,mManufacturerName=OMNIKEY AG,mProductName=Smart Card Reader USB,mVersion=2.0,mSerialNumber=null,mConfigurations=[
UsbConfiguration[mId=1,mName=CCID,mAttributes=160,mMaxPower=50,mInterfaces=[
UsbInterface[mId=0,mAlternateSetting=0,mName=null,mClass=11,mSubclass=0,mProtocol=0,mEndpoints=[
UsbEndpoint[mAddress=131,mAttributes=3,mMaxPacketSize=8,mInterval=24]
UsbEndpoint[mAddress=132,mAttributes=2,mMaxPacketSize=64,mInterval=0]
UsbEndpoint[mAddress=5,mAttributes=2,mMaxPacketSize=64,mInterval=0]]]]

Ahora estoy tratando de usar estoUsbDevice device para obtener datos y detalles de la tarjeta, pero no tuve éxito al hacerlo y no pude encontrar ninguna publicación útil al respecto.

Sé que tengo que usarUsbInterface, UsbEndpoint, UsbDeviceConnection para obtener las cosas que quiero de la tarjeta pero no puedo hacerlo.

Además, no puedo encontrar ninguna muestra o algo similar para el mismo. ¿Alguien puede señalarme en la dirección correcta?

Perdón por el largo post también gracias de antemano :)

EDITAR: Gracias aSr. michael roland, Pude leer sobre CCID ya que el dispositivo lector habla CCID a través de la interfaz USB.

Entonces usé el siguiente código:

        UsbDeviceConnection connection = mUsbManager.openDevice(device);
        UsbEndpoint epOut = null, epIn = null;

        for (int i = 0; i < device.getInterfaceCount(); i++) {
            UsbInterface usbInterface = device.getInterface(i);
            connection.claimInterface(usbInterface, true);

            for (int j = 0; j < usbInterface.getEndpointCount(); j++) {
                UsbEndpoint ep = usbInterface.getEndpoint(j);
                showToast("Endpoint is : " + ep.toString() + " endpoint's type : " + ep.getType() + " endpoint's direction : " + ep.getDirection());
                Log.d(" ", "EP " + i + ": " + ep.getType());
                if (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_BULK) {
                    if (ep.getDirection() == UsbConstants.USB_DIR_OUT) {
                        epOut = ep;

                    } else if (ep.getDirection() == UsbConstants.USB_DIR_IN) {
                        epIn = ep;
                    }

                }
            }

            int dataTransferred = 0;
            byte[] PC_to_RDR_IccPowerOn = hexStringToByteArray("62" + "00000000" + "00" + "00" + "00" + "0000");

            if (epOut != null) {
                //Firstly send Power in on Bulk OUT endpoint
                dataTransferred = connection.bulkTransfer(epOut, PC_to_RDR_IccPowerOn, PC_to_RDR_IccPowerOn.length, TIMEOUT);
            }

            StringBuilder result = new StringBuilder();

            if (epIn != null) {
                final byte[] RDR_to_PC_DataBlock = new byte[epIn.getMaxPacketSize()];
                result = new StringBuilder();
                //Secondly send Power out on Bulk OUT endpoint
                dataTransferred = connection.bulkTransfer(epIn, RDR_to_PC_DataBlock, RDR_to_PC_DataBlock.length, TIMEOUT);
                for (byte bb : RDR_to_PC_DataBlock) {
                    result.append(String.format(" %02X ", bb));
                }

                if (dataTransferred > 0) {
                    Utils.writeStringToTextFile("\n2nd buffer received was : " + result.toString(), "Card_communication_data.txt");
                    String s1 = Arrays.toString(RDR_to_PC_DataBlock);
                    String s2 = new String(RDR_to_PC_DataBlock);
                    showToast("received - " + s1 + " - " + s2);
                } else {
                    showToast("received length at 2nd buffer transfer was " + dataTransferred);
                }
            }
        }

Y recibí80 13 00 00 00 00 00 00 00 00 3B 9A 96 C0 10 31 FE 5D 00 64 05 7B 01 02 31 80 90 00 76 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 Pero aún no estoy seguro de qué hacer con el campo Datos: ATR o cómo formarCommand APDU paraPC_to_RDR_XfrBlock mando..

Creo que se supone que debo

Enviar comando APDU envuelto en el comando PC_to_RDR_XfrBlock

ahora; ¿Puede alguien ayudarme con esto?

EDITAR 2: Descubrí qué significa ATR y cómo formar el comando APDU.

Pero ahora se supone que debo cambiar de protocolo

El protocolo predeterminado es T = 0. Para configurar el protocolo T = 1, el dispositivo debe enviar un PTS (también conocido como PPS) a la tarjeta Como los protocolos T = 0 y T = 1 son obligatorios para la tarjeta, el PTS básico para el cambio de protocolo es obligatorio para la tarjeta. El PTS se puede utilizar, como se indica en ISO / IEC 7816-3, para cambiar a velocidades de transmisión más altas que las predeterminadas propuestas por la tarjeta en el ATR, si corresponde (TA (1) byte).

¡Y no estoy seguro de lo que esto significa y cómo lograrlo!

Respuestas a la pregunta(2)

Su respuesta a la pregunta