android.se.omapi.SEService: My app doesn't connect with the OnConnectedListener

144 views Asked by At

I am trying to create an application that transmits APDUs to a SIMCARD using the OMAPI libraries, but the OnConnected listener for SEService is never called.

I followed the structure I found here: https://android.googlesource.com/platform/cts/+/master/tests/tests/secure_element/omapi/src/android/omapi/cts/OmapiTest.java

I wait up to 30 seconds to see if the OnConnectedListener method is called, but that never happens. I always get the error that I left in the code: throw new TimeoutException( "Service could not be connected after " + SERVICE_CONNECTION_TIME_OUT + "ms");

The SIMCARD I use contains the ARA-M applet, and the necessary SHA-1 keys, that is, the application obtains carrier privileges. In another application using the TelephonyManager libraries I have had success transmitting APDUs.

Please can you help me understand if I am doing something wrong? Do I need to declare some permission in the manifest of my application?

Thank you in advance.

I leave you part of the code that I implemented:

public class MainActivity extends AppCompatActivity [...]{
     /*FOR OMAPI*/
    private final Object serviceMutex = new Object();
    private SEService seService;
    private boolean connected = false;
    private Timer connectionTimer;
    private ServiceConnectionTimerTask mTimerTask = new ServiceConnectionTimerTask();
    private final long SERVICE_CONNECTION_TIME_OUT = 30000;
    //////////////////////////////////////////////////////////////////////////////


   @Override
    public void onCreate(Bundle savedInstanceState) {

      [...]
                setUp(getApplicationContext());

                try {
                    waitForConnection();
                } catch (TimeoutException e) {
                    throw new RuntimeException(e);
                }

                Reader[] readers = seService.getReaders();
                byte [] apdu = {(byte)0x80, (byte)0x02, (byte)0xfC, (byte)0x00};

                for (Reader reader : readers){

                    byte [] response = new byte[0];
                    try {
                        response = Util.internalTransmitAPDU(reader, apdu);
                    } catch (IOException e) {
                        throw new RuntimeException(e);
                    }
                    Log.i("response OMAPI", String.valueOf(response));
                }

   }


    public void setUp(Context context){

        seService = new SEService(context, new SynchronousExecutor(), mListener);
        connectionTimer = new Timer();
        connectionTimer.schedule(mTimerTask, SERVICE_CONNECTION_TIME_OUT);
    }

    static class SynchronousExecutor implements Executor {
        public void execute(Runnable r) {
            r.run();
        }
    }

    private final SEService.OnConnectedListener mListener = () -> {
        synchronized (serviceMutex){
            connected = true;
            serviceMutex.notify();
            Log.i("OMAPI", "EntraOnconnect");
        }


    private void waitForConnection() throws TimeoutException {
        synchronized (serviceMutex) {
            if (!connected) {
                try {
                    serviceMutex.wait();
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
            if (!connected && !seService.isConnected()) {
                throw new TimeoutException(
                        "Service could not be connected after " + SERVICE_CONNECTION_TIME_OUT
                                + " ms");
            }
            if (connectionTimer != null) {
                connectionTimer.cancel();
            }
        }
    }



}
1

There are 1 answers

1
k_o_ On

Try to use the <uses-permission android:name="android.permission.READ_PHONE_STATE" /> permission. Maybe this is missing.

Could you also try to use a different Executor instead SynchronousExecutor? E.g.:

Executors.newSingleThreadExecutor()

Maybe your code is blocked if not running in a different thread.