Como ler um cartão smart card / microprocessador usando um leitor de smart card no android programaticamente

Ultimamente, tenho trabalhado com cartões inteligentes que contêm algumas informações e o que estou tentando obter aqui é buscar esses dados a partir desses cartões inteligentes usando um leitor de cartão inteligente em qualquer smartphone Android. Eu tenho usado umHID OMNIKEY 3021 USB leitor de cartão inteligente que leria esse cartão (e eu sei que esse leitor funciona com esses cartões através de aplicativos do Windows porque eu testei isso pessoalmente)

Agora o Android forneceAnfitrião USB que possibilita a leitura de qualquer host USB, desde que o Android Smartphones o suporte.

E estou tentando usar essas classes fornecidas pelo host USB para acessar os dados contidos neste cartão.

Meu código para detectar qualquer 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);
                }
            }
        }
    }
};

Tudo funciona como o esperado quando recebo oUsbDevice device que fornece as informações do dispositivo, por exemplo:

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]]]]

Agora estou tentando usar issoUsbDevice device para buscar dados e detalhes do cartão, mas não consigo fazer isso e não encontrei nenhuma postagem útil sobre isso.

Eu sei que tenho que usarUsbInterface, UsbEndpoint, UsbDeviceConnection para obter as coisas que quero do cartão, mas não consigo.

Além disso, não consigo encontrar nenhuma amostra ou algo parecido para o mesmo. Alguém pode me indicar a direção certa?

Desculpe pelo longo post, também obrigado antecipadamente :)

EDIT: Graças aMichael Roland, Pude ler sobre o CCID, pois o dispositivo leitor fala o CCID pela interface USB.

Então, eu usei o seguinte 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);
                }
            }
        }

E eu recebi80 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 Mas ainda não tenho certeza do que fazer com o campo Data: ATR ou como formarCommand APDU paraPC_to_RDR_XfrBlock comando..

Eu acho que devo

Enviar comando APDU agrupado no comando PC_to_RDR_XfrBlock

agora; Alguém pode me ajudar com isso?

EDIT 2: Eu descobri o que significa ATR e como formar o comando APDU.

Mas agora eu devo mudar de protocolo

O protocolo padrão é T = 0. Para definir o protocolo T = 1, um PTS (também conhecido como PPS) deve ser enviado ao cartão pelo dispositivo. Como os protocolos T = 0 e T = 1 são obrigatórios para o cartão, o PTS básico para troca de protocolo é obrigatório para o cartão. o cartão. O PTS pode ser usado, como indicado na ISO / IEC 7816-3, para mudar para taxas de transmissão mais altas do que a padrão proposta pela placa no ATR, se houver (TA (1) byte).

E não tenho certeza do que isso significa e como conseguir isso!

questionAnswers(2)

yourAnswerToTheQuestion