title: APDU via USB Connection
body: <p>I want to create an android app to find my micro-usb (smartcard reader device), so I have a problem with receive data in smartcard (I sent an APDU that is 0x... to smartcard by method usbDeviceConnection.bulkTransfer. But I don’t know how to receive data or something that answer back (It have to answer a data in card back to me after I sent command). And when it answer back how can I encode or translate hex to string?</p>
  
  <p>I guess, (ref from code) I have a 2 endpoint so I have question about endpointIn and endpointOut. What are these params? How can I use it to send and receive data between device and app? I think right, or not? And what is BroadcastReceiver do?</p>
  
  <pre><code>protected void onCreate(Bundle savedInstanceState) {
     super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
     tv = (TextView) findViewById(R.id.textview);   
     //register the broadcast receiver
     mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
    IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
    registerReceiver(mUsbReceiver, filter);
  
    registerReceiver(mUsbDeviceReceiver, new IntentFilter(UsbManager.ACTION_USB_DEVICE_ATTACHED));
    registerReceiver(mUsbDeviceReceiver, new IntentFilter(UsbManager.ACTION_USB_DEVICE_DETACHED));
  
    connectUsb();
  }
  </code></pre>
  
  <p>Here is connectUSB method.</p>
  
  <pre><code>private void connectUsb() {
    Toast.makeText(MainActivity.this,
     "connectUsb()",
    Toast.LENGTH_LONG).show();
  
  
    searchEndPoint();
  
     if (usbInterfaceFound != null) {
    setupUsbComm();
  
     threadUsbTx = new ThreadUsbTx(usbDeviceConnection, endpointOut);
     threadUsbTx.start();
  
     //bytes are APDU to send for get data from card.
     threadUsbTx.insertCmd(
     new byte[]{(byte) 0xA0, (byte) 0xA4, 0x00, 0x00, 0x02, 0x3F, 0x00});
     threadUsbTx.insertCmd(
     new byte[]{(byte)0x80, (byte)0xb0, 0x00, 0x04, 0x02, 0x00, 0x0d});
     threadUsbTx.insertCmd(
     new byte[]{0x00, (byte)0xc0, 0x00, 0x00, 0x0d});
     }
    }
  </code></pre>
  
  <p>Here is class ThreadUsbTx..</p>
  
  <pre><code>class ThreadUsbTx extends Thread {
     boolean running;
  
    UsbDeviceConnection txConnection;
    UsbEndpoint txEndpoint;
    Queue&lt;byte[]&gt; cmdQueue;
     byte[] cmdToSent;
  
  
    ThreadUsbTx(UsbDeviceConnection conn, UsbEndpoint endpoint) {
     txConnection = conn;
     txEndpoint = endpoint;
     cmdQueue = new LinkedList&lt;byte[]&gt;();
     cmdToSent = null;
  
     running = true;
    }
  
     public void setRunning(boolean r) {
     running = r;
    }
  
     public void insertCmd(byte[] cmd) {
     synchronized (cmdQueue) {
     cmdQueue.add(cmd);
    }
    }
  
     @Override
     public void run() {
  
     while (running) {
  
     synchronized (cmdQueue) {
     if (cmdQueue.size() &gt; 0) {
     cmdToSent = cmdQueue.remove();
    }
    }
  
     if (cmdToSent != null) {
  
     final int usbResult = usbDeviceConnection.bulkTransfer(
     txEndpoint,
     cmdToSent,
     cmdToSent.length,
     0);
  
     final String s = new String(cmdToSent);
    String result = null;
  
     try {
    result = new String(cmdToSent,"TIS620"); // To Thai language
    } catch (UnsupportedEncodingException e) {
    e.printStackTrace();
    }
  
     final String finalResult = result;
    runOnUiThread(new Runnable() {
  
     @Override
     public void run() {
    Toast.makeText(MainActivity.this,
     finalResult+" "+String.format("%040x",cmdToSent),
    Toast.LENGTH_LONG).show();
    }
    });
     cmdToSent = null;
     }
    }
    }
    }
  </code></pre>