use HCE mode of Samsung Accessories for emulation

This commit is contained in:
Frank Morgner
2016-05-25 21:24:17 +02:00
parent 818d5a0254
commit 790ea80fb7
14 changed files with 390 additions and 81 deletions

View File

@@ -90,9 +90,7 @@
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/builds" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/builds" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/debug" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/dependency-cache" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/dex" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/animated-vector-drawable/23.2.1/jars" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/animated-vector-drawable/23.2.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/23.2.1/jars" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/appcompat-v7/23.2.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/design/23.2.1/jars" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/design/23.2.1/jars" />
@@ -108,14 +106,12 @@
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-support" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/instant-run-support" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/jniLibs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/manifests" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/pre-dexed" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/reload-dex" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/reload-dex" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/res" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/restart-dex" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/restart-dex" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/shaders" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/shaders" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/symbols" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/tmp" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/transforms" /> <excludeFolder url="file://$MODULE_DIR$/build/intermediates/transforms" />
<excludeFolder url="file://$MODULE_DIR$/build/outputs" /> <excludeFolder url="file://$MODULE_DIR$/build/outputs" />
<excludeFolder url="file://$MODULE_DIR$/build/tmp" /> <excludeFolder url="file://$MODULE_DIR$/build/tmp" />
@@ -127,8 +123,8 @@
<orderEntry type="library" exported="" name="design-23.2.1" level="project" /> <orderEntry type="library" exported="" name="design-23.2.1" level="project" />
<orderEntry type="library" exported="" name="jcardsim-3.0.4-SNAPSHOT-android" level="project" /> <orderEntry type="library" exported="" name="jcardsim-3.0.4-SNAPSHOT-android" level="project" />
<orderEntry type="library" exported="" name="animated-vector-drawable-23.2.1" level="project" /> <orderEntry type="library" exported="" name="animated-vector-drawable-23.2.1" level="project" />
<orderEntry type="library" exported="" name="core-3.2.1" level="project" />
<orderEntry type="library" exported="" name="support-annotations-23.2.1" level="project" /> <orderEntry type="library" exported="" name="support-annotations-23.2.1" level="project" />
<orderEntry type="library" exported="" name="core-3.2.1" level="project" />
<orderEntry type="library" exported="" name="recyclerview-v7-23.2.1" level="project" /> <orderEntry type="library" exported="" name="recyclerview-v7-23.2.1" level="project" />
<orderEntry type="library" exported="" name="accessory-v2.3.2" level="project" /> <orderEntry type="library" exported="" name="accessory-v2.3.2" level="project" />
<orderEntry type="library" exported="" name="support-vector-drawable-23.2.1" level="project" /> <orderEntry type="library" exported="" name="support-vector-drawable-23.2.1" level="project" />

View File

@@ -53,8 +53,8 @@ dependencies {
compile 'com.android.support:appcompat-v7:23.0.1' compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:support-v4:23.0.1' compile 'com.android.support:support-v4:23.0.1'
compile 'com.android.support:design:23.2.1' compile 'com.android.support:design:23.2.1'
compile 'com.journeyapps:zxing-android-embedded:3.2.0@aar' compile 'com.journeyapps:zxing-android-embedded:3.2.0@aar'
compile 'com.google.zxing:core:3.2.1' compile 'com.google.zxing:core:3.2.1'
compile group: 'com.madgag.spongycastle', name: 'core', version: '1.51.0.0' compile 'com.madgag.spongycastle:core:1.51.0.0'
compile files('libs/sdk-v1.0.0.jar')
} }

Binary file not shown.

Binary file not shown.

View File

@@ -7,6 +7,13 @@
<uses-permission android:name="android.permission.NFC" /> <uses-permission android:name="android.permission.NFC" />
<uses-feature android:name="android.hardware.nfc.hce" android:required="true" /> <uses-feature android:name="android.hardware.nfc.hce" android:required="true" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
<uses-permission android:name="com.samsung.accessory.permission.ACCESSORY_FRAMEWORK" />
<uses-permission android:name="com.samsung.android.providers.context.permission.WRITE_USE_APP_FEATURE_SURVEY" />
<uses-permission android:name="com.samsung.WATCH_APP_TYPE.Companion" />
<uses-permission android:name="com.samsung.wmanager.ENABLE_NOTIFICATION" />
<application <application
android:allowBackup="true" android:allowBackup="true"
android:icon="@mipmap/ic_launcher" android:icon="@mipmap/ic_launcher"
@@ -37,7 +44,7 @@
</intent-filter> </intent-filter>
</activity> </activity>
<service android:name=".EmulatorService" <service android:name=".EmulatorHostApduService"
android:exported="true" android:exported="true"
android:permission="android.permission.BIND_NFC_SERVICE"> android:permission="android.permission.BIND_NFC_SERVICE">
<intent-filter> <intent-filter>
@@ -47,6 +54,24 @@
<meta-data android:name="android.nfc.cardemulation.host_apdu_service" <meta-data android:name="android.nfc.cardemulation.host_apdu_service"
android:resource="@xml/aid_list"/> android:resource="@xml/aid_list"/>
</service> </service>
<service android:name=".SmartcardProviderService" />
<receiver android:name="com.samsung.android.sdk.accessory.RegisterUponInstallReceiver" >
<intent-filter>
<action android:name="com.samsung.accessory.action.REGISTER_AGENT" />
</intent-filter>
</receiver>
<receiver android:name="com.samsung.android.sdk.accessory.ServiceConnectionIndicationBroadcastReceiver" >
<intent-filter>
<action android:name="com.samsung.accessory.action.SERVICE_CONNECTION_REQUESTED" />
</intent-filter>
</receiver>
<meta-data
android:name="AccessoryServicesLocation"
android:value="/res/xml/accessoryservices.xml" />
<meta-data
android:name="GearAppType"
android:value="tpk" />
</application> </application>
</manifest> </manifest>

View File

@@ -0,0 +1,65 @@
/*
* Copyright (C) 2015 Frank Morgner
*
* This file is part of ACardEmulator.
*
* ACardEmulator is free software: you can redistribute it and/or
* modify it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or (at your
* option) any later version.
*
* ACardEmulator is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
* more details.
*
* You should have received a copy of the GNU General Public License along with
* ACardEmulator. If not, see <http://www.gnu.org/licenses/>.
*/
package com.vsmartcard.acardemulator;
import android.content.Intent;
import android.nfc.cardemulation.HostApduService;
import android.os.Bundle;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import com.vsmartcard.acardemulator.emulators.EmulatorSingleton;
public class EmulatorHostApduService extends HostApduService {
@Override
public void onCreate() {
super.onCreate();
EmulatorSingleton.createEmulator(this);
}
@Override
public void onDestroy() {
super.onDestroy();
}
@Override
public byte[] processCommandApdu(byte[] capdu, Bundle extras) {
return EmulatorSingleton.process(this, capdu);
}
@Override
public void onDeactivated(int reason) {
Intent i = new Intent(EmulatorSingleton.TAG);
Log.d("", "End transaction");
switch (reason) {
case DEACTIVATION_LINK_LOSS:
i.putExtra(EmulatorSingleton.EXTRA_DESELECT, "link lost");
EmulatorSingleton.deactivate();
break;
case DEACTIVATION_DESELECTED:
EmulatorSingleton.deactivate();
break;
}
LocalBroadcastManager.getInstance(this).sendBroadcast(i);
}
}

View File

@@ -41,6 +41,8 @@ import android.view.View;
import android.widget.TextView; import android.widget.TextView;
import android.widget.Toast; import android.widget.Toast;
import com.vsmartcard.acardemulator.emulators.EmulatorSingleton;
public class MainActivity extends AppCompatActivity { public class MainActivity extends AppCompatActivity {
@@ -48,12 +50,12 @@ public class MainActivity extends AppCompatActivity {
private BroadcastReceiver bReceiver = new BroadcastReceiver() { private BroadcastReceiver bReceiver = new BroadcastReceiver() {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(EmulatorService.TAG)) { if (intent.getAction().equals(EmulatorSingleton.TAG)) {
String capdu = intent.getStringExtra(EmulatorService.EXTRA_CAPDU); String capdu = intent.getStringExtra(EmulatorSingleton.EXTRA_CAPDU);
String rapdu = intent.getStringExtra(EmulatorService.EXTRA_RAPDU); String rapdu = intent.getStringExtra(EmulatorSingleton.EXTRA_RAPDU);
String error = intent.getStringExtra(EmulatorService.EXTRA_ERROR); String error = intent.getStringExtra(EmulatorSingleton.EXTRA_ERROR);
String deselect = intent.getStringExtra(EmulatorService.EXTRA_DESELECT); String deselect = intent.getStringExtra(EmulatorSingleton.EXTRA_DESELECT);
String install = intent.getStringExtra(EmulatorService.EXTRA_INSTALL); String install = intent.getStringExtra(EmulatorSingleton.EXTRA_INSTALL);
if (install != null) if (install != null)
textViewVPCDStatus.append(getResources().getString(R.string.status_install) + ":" + install + "\n"); textViewVPCDStatus.append(getResources().getString(R.string.status_install) + ":" + install + "\n");
if (capdu != null) if (capdu != null)
@@ -102,7 +104,7 @@ public class MainActivity extends AppCompatActivity {
if (emulator != getString(R.string.vicc)) { if (emulator != getString(R.string.vicc)) {
Snackbar.make(view, "Scheduled re-installation of all applets...", Snackbar.LENGTH_LONG) Snackbar.make(view, "Scheduled re-installation of all applets...", Snackbar.LENGTH_LONG)
.setAction("Action", null).show(); .setAction("Action", null).show();
EmulatorService.destroySimulator(getApplicationContext()); EmulatorSingleton.destroyEmulator();
} }
} }
}); });
@@ -116,7 +118,7 @@ public class MainActivity extends AppCompatActivity {
LocalBroadcastManager bManager = LocalBroadcastManager.getInstance(this); LocalBroadcastManager bManager = LocalBroadcastManager.getInstance(this);
IntentFilter intentFilter = new IntentFilter(); IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(EmulatorService.TAG); intentFilter.addAction(EmulatorSingleton.TAG);
bManager.registerReceiver(bReceiver, intentFilter); bManager.registerReceiver(bReceiver, intentFilter);
} }

View File

@@ -200,6 +200,8 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
return true; return true;
} }
}); });
bindPreferenceSummaryToValue(findPreference("nfc"));
} }
@Override @Override

View File

@@ -0,0 +1,186 @@
/*
* Copyright (c) 2015 Samsung Electronics Co., Ltd. All rights reserved.
* Redistribution and use in source and binary forms, with or without modification, are permitted provided that
* the following conditions are met:
*
* * Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation and/or
* other materials provided with the distribution.
* * Neither the name of Samsung Electronics Co., Ltd. nor the names of its contributors may be used to endorse
* or promote products derived from this software without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY
* DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
package com.vsmartcard.acardemulator;
import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.GregorianCalendar;
import android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.widget.Toast;
import android.util.Log;
import com.samsung.android.sdk.SsdkUnsupportedException;
import com.samsung.android.sdk.accessory.*;
import com.vsmartcard.acardemulator.emulators.EmulatorSingleton;
public class SmartcardProviderService extends SAAgent {
private static final String TAG = "HelloAccessory(P)";
private static final int HELLOACCESSORY_CHANNEL_ID = 104;
private static final Class<ServiceConnection> SASOCKET_CLASS = ServiceConnection.class;
private final IBinder mBinder = new LocalBinder();
private ServiceConnection mConnectionHandler = null;
Handler mHandler = new Handler();
public SmartcardProviderService() {
super(TAG, SASOCKET_CLASS);
}
@Override
public void onCreate() {
super.onCreate();
SA mAccessory = new SA();
try {
mAccessory.initialize(this);
EmulatorSingleton.createEmulator(this);
} catch (SsdkUnsupportedException e) {
// try to handle SsdkUnsupportedException
if (processUnsupportedException(e) == true) {
EmulatorSingleton.createEmulator(this);
return;
}
} catch (Exception e1) {
e1.printStackTrace();
/*
* Your application can not use Samsung Accessory SDK. Your application should work smoothly
* without using this SDK, or you may want to notify user and close your application gracefully
* (release resources, stop Service threads, close UI thread, etc.)
*/
stopSelf();
}
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
protected void onFindPeerAgentsResponse(SAPeerAgent[] peerAgents, int result) {
Log.d(TAG, "onFindPeerAgentResponse : result =" + result);
}
@Override
protected void onServiceConnectionRequested(SAPeerAgent peerAgent) {
if (peerAgent != null) {
Toast.makeText(getBaseContext(), "connection accepted", Toast.LENGTH_SHORT).show();
acceptServiceConnectionRequest(peerAgent);
}
}
@Override
protected void onServiceConnectionResponse(SAPeerAgent peerAgent, SASocket socket, int result) {
if (result == SAAgent.CONNECTION_SUCCESS) {
if (socket != null) {
mConnectionHandler = (ServiceConnection) socket;
}
} else if (result == SAAgent.CONNECTION_ALREADY_EXIST) {
Log.e(TAG, "onServiceConnectionResponse, CONNECTION_ALREADY_EXIST");
}
}
@Override
protected void onAuthenticationResponse(SAPeerAgent peerAgent, SAAuthenticationToken authToken, int error) {
/*
* The authenticatePeerAgent(peerAgent) API may not be working properly depending on the firmware
* version of accessory device. Please refer to another sample application for Security.
*/
}
@Override
protected void onError(SAPeerAgent peerAgent, String errorMessage, int errorCode) {
super.onError(peerAgent, errorMessage, errorCode);
}
private boolean processUnsupportedException(SsdkUnsupportedException e) {
e.printStackTrace();
int errType = e.getType();
if (errType == SsdkUnsupportedException.VENDOR_NOT_SUPPORTED
|| errType == SsdkUnsupportedException.DEVICE_NOT_SUPPORTED) {
/*
* Your application can not use Samsung Accessory SDK. You application should work smoothly
* without using this SDK, or you may want to notify user and close your app gracefully (release
* resources, stop Service threads, close UI thread, etc.)
*/
stopSelf();
} else if (errType == SsdkUnsupportedException.LIBRARY_NOT_INSTALLED) {
Log.e(TAG, "You need to install Samsung Accessory SDK to use this application.");
} else if (errType == SsdkUnsupportedException.LIBRARY_UPDATE_IS_REQUIRED) {
Log.e(TAG, "You need to update Samsung Accessory SDK to use this application.");
} else if (errType == SsdkUnsupportedException.LIBRARY_UPDATE_IS_RECOMMENDED) {
Log.e(TAG, "We recommend that you update your Samsung Accessory SDK before using this application.");
return false;
}
return true;
}
public class LocalBinder extends Binder {
public SmartcardProviderService getService() {
return SmartcardProviderService.this;
}
}
public class ServiceConnection extends SASocket {
public ServiceConnection() {
super(ServiceConnection.class.getName());
}
@Override
public void onError(int channelId, String errorMessage, int errorCode) {
}
@Override
public void onReceive(int channelId, byte[] data) {
if (mConnectionHandler == null) {
return;
}
final byte[] response = EmulatorSingleton.process(getApplicationContext(), data);
new Thread(new Runnable() {
public void run() {
try {
mConnectionHandler.send(HELLOACCESSORY_CHANNEL_ID, response);
} catch (IOException e) {
e.printStackTrace();
}
}
}).start();
}
@Override
protected void onServiceConnectionLost(int reason) {
mConnectionHandler = null;
EmulatorSingleton.deactivate();
mHandler.post(new Runnable() {
@Override
public void run() {
Toast.makeText(getBaseContext(), "connection lost", Toast.LENGTH_SHORT).show();
}
});
}
}
}

View File

@@ -17,28 +17,19 @@
* ACardEmulator. If not, see <http://www.gnu.org/licenses/>. * ACardEmulator. If not, see <http://www.gnu.org/licenses/>.
*/ */
package com.vsmartcard.acardemulator; package com.vsmartcard.acardemulator.emulators;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.content.SharedPreferences;
import android.nfc.cardemulation.HostApduService;
import android.os.Bundle;
import android.os.StrictMode;
import android.preference.PreferenceManager; import android.preference.PreferenceManager;
import android.support.v4.content.LocalBroadcastManager; import android.support.v4.content.LocalBroadcastManager;
import android.util.Log; import android.util.Log;
import java.io.IOException; import com.vsmartcard.acardemulator.R;
import java.net.InetAddress; import com.vsmartcard.acardemulator.Util;
import java.net.Socket;
import com.vsmartcard.acardemulator.emulators.Emulator;
import com.vsmartcard.acardemulator.emulators.JCEmulator;
import com.vsmartcard.acardemulator.emulators.VICCEmulator;
public class EmulatorService extends HostApduService {
public class EmulatorSingleton {
public static final String TAG = "com.vsmartcard.acardemulator.EmulatorService"; public static final String TAG = "com.vsmartcard.acardemulator.EmulatorService";
public static final String EXTRA_CAPDU = "MSG_CAPDU"; public static final String EXTRA_CAPDU = "MSG_CAPDU";
public static final String EXTRA_RAPDU = "MSG_RAPDU"; public static final String EXTRA_RAPDU = "MSG_RAPDU";
@@ -49,22 +40,35 @@ public class EmulatorService extends HostApduService {
private static Emulator emulator = null; private static Emulator emulator = null;
private static boolean do_destroy = false; private static boolean do_destroy = false;
@Override private static void destroyEmulatorIfRequested(Context context) {
public void onCreate () { if (do_destroy) {
super.onCreate(); emulator.destroy();
emulator = null;
do_destroy = false;
Intent i = new Intent(TAG);
i.putExtra(EXTRA_DESELECT, "Uninstalled all applets.");
LocalBroadcastManager.getInstance(context).sendBroadcast(i);
}
}
public static void destroyEmulator() {
do_destroy = true;
}
public static void createEmulator(Context context) {
// force reloading applets if requested // force reloading applets if requested
do_destroy(); destroyEmulatorIfRequested(context);
if (emulator == null) { if (emulator == null) {
Log.d("", "Begin transaction"); Log.d("", "Begin transaction");
SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(this); SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(context);
String str_emulator = SP.getString("emulator", ""); String str_emulator = SP.getString("emulator", "");
if (str_emulator.equals(getString(R.string.vicc))) { if (str_emulator.equals(context.getString(R.string.vicc))) {
emulator = new VICCEmulator( emulator = new VICCEmulator(
SP.getString("hostname", VICCEmulator.DEFAULT_HOSTNAME), SP.getString("hostname", VICCEmulator.DEFAULT_HOSTNAME),
Integer.parseInt(SP.getString("port", Integer.toString(VICCEmulator.DEFAULT_PORT)))); Integer.parseInt(SP.getString("port", Integer.toString(VICCEmulator.DEFAULT_PORT))));
} else { } else {
emulator = new JCEmulator(this, emulator = new JCEmulator(context,
SP.getBoolean("activate_helloworld", false), SP.getBoolean("activate_helloworld", false),
SP.getBoolean("activate_openpgp", false), SP.getBoolean("activate_openpgp", false),
SP.getBoolean("activate_oath", false), SP.getBoolean("activate_oath", false),
@@ -74,55 +78,19 @@ public class EmulatorService extends HostApduService {
} }
} }
public static void destroySimulator(Context context) { public static byte[] process(Context context, byte[] capdu) {
do_destroy = true;
}
private void do_destroy() {
if (do_destroy) {
emulator.destroy();
emulator = null;
do_destroy = false;
Intent i = new Intent(TAG);
i.putExtra(EXTRA_DESELECT, "Uninstalled all applets.");
LocalBroadcastManager.getInstance(this).sendBroadcast(i);
}
}
@Override
public void onDestroy() {
do_destroy();
super.onDestroy();
}
@Override
public byte[] processCommandApdu(byte[] capdu, Bundle extras) {
byte[] rapdu = emulator.process(capdu); byte[] rapdu = emulator.process(capdu);
Intent i = new Intent(TAG); Intent i = new Intent(TAG);
i.putExtra(EXTRA_CAPDU, Util.byteArrayToHexString(capdu)); i.putExtra(EXTRA_CAPDU, Util.byteArrayToHexString(capdu));
if (rapdu != null) if (rapdu != null)
i.putExtra(EXTRA_RAPDU, Util.byteArrayToHexString(rapdu)); i.putExtra(EXTRA_RAPDU, Util.byteArrayToHexString(rapdu));
LocalBroadcastManager.getInstance(this).sendBroadcast(i); LocalBroadcastManager.getInstance(context).sendBroadcast(i);
return rapdu; return rapdu;
} }
@Override public static void deactivate() {
public void onDeactivated(int reason) { emulator.deactivate();
Intent i = new Intent(TAG);
Log.d("", "End transaction");
switch (reason) {
case DEACTIVATION_LINK_LOSS:
i.putExtra(EXTRA_DESELECT, "link lost");
emulator.deactivate();
break;
case DEACTIVATION_DESELECTED:
emulator.deactivate();
break;
}
LocalBroadcastManager.getInstance(this).sendBroadcast(i);
} }
} }

View File

@@ -9,7 +9,6 @@ import com.licel.jcardsim.base.SimulatorRuntime;
import com.licel.jcardsim.samples.HelloWorldApplet; import com.licel.jcardsim.samples.HelloWorldApplet;
import com.licel.jcardsim.utils.AIDUtil; import com.licel.jcardsim.utils.AIDUtil;
import com.mysmartlogon.gidsApplet.GidsApplet; import com.mysmartlogon.gidsApplet.GidsApplet;
import com.vsmartcard.acardemulator.EmulatorService;
import com.vsmartcard.acardemulator.R; import com.vsmartcard.acardemulator.R;
import com.vsmartcard.acardemulator.Util; import com.vsmartcard.acardemulator.Util;
@@ -100,11 +99,11 @@ public class JCEmulator implements Emulator {
} }
} }
Intent i = new Intent(EmulatorService.TAG); Intent i = new Intent(EmulatorSingleton.TAG);
if (!extra_error.isEmpty()) if (!extra_error.isEmpty())
i.putExtra(EmulatorService.EXTRA_ERROR, extra_error); i.putExtra(EmulatorSingleton.EXTRA_ERROR, extra_error);
if (!extra_install.isEmpty()) if (!extra_install.isEmpty())
i.putExtra(EmulatorService.EXTRA_INSTALL, extra_install); i.putExtra(EmulatorSingleton.EXTRA_INSTALL, extra_install);
LocalBroadcastManager.getInstance(context).sendBroadcast(i); LocalBroadcastManager.getInstance(context).sendBroadcast(i);
} }

View File

@@ -44,6 +44,14 @@
</string-array> </string-array>
<string name="jcardsim">Builtin Java Card Simulator</string> <string name="jcardsim">Builtin Java Card Simulator</string>
<string name="vicc">Remote Virtual Smart Card</string> <string name="vicc">Remote Virtual Smart Card</string>
<string-array name="strNFC">
<item>@string/nfc</item>
<item>@string/gear</item>
</string-array>
<string name="nfc">Builtin NFC</string>
<string name="gear">Samsung Accessory</string>
<string name="vicc_config_info">If you choose the virtual smart card (VICC) as emulator, you need to start the it on your computer with the `--reversed` flag and configure the connection parameters here accordingly.</string> <string name="vicc_config_info">If you choose the virtual smart card (VICC) as emulator, you need to start the it on your computer with the `--reversed` flag and configure the connection parameters here accordingly.</string>
<string name="hint_vicc_port">VICC Port</string> <string name="hint_vicc_port">VICC Port</string>
<string name="hint_vicc_hostname">VICC Hostname</string> <string name="hint_vicc_hostname">VICC Hostname</string>

View File

@@ -0,0 +1,51 @@
<!DOCTYPE resources [
<!ELEMENT resources (application)>
<!ELEMENT application (serviceProfile)+>
<!ATTLIST application name CDATA #REQUIRED>
<!ELEMENT serviceProfile (supportedTransports, serviceChannel+) >
<!ATTLIST application xmlns:android CDATA #IMPLIED>
<!ATTLIST serviceProfile xmlns:android CDATA #IMPLIED>
<!ATTLIST serviceProfile serviceImpl CDATA #REQUIRED>
<!ATTLIST serviceProfile role (PROVIDER | CONSUMER | provider | consumer) #REQUIRED>
<!ATTLIST serviceProfile name CDATA #REQUIRED>
<!ATTLIST serviceProfile id CDATA #REQUIRED>
<!ATTLIST serviceProfile version CDATA #REQUIRED>
<!ATTLIST serviceProfile serviceLimit (ANY | ONE_ACCESSORY | ONE_PEERAGENT | any | one_accessory | one_peeragent) #IMPLIED>
<!ATTLIST serviceProfile serviceTimeout CDATA #IMPLIED>
<!ELEMENT supportedTransports (transport)+>
<!ATTLIST supportedTransports xmlns:android CDATA #IMPLIED>
<!ELEMENT transport EMPTY>
<!ATTLIST transport xmlns:android CDATA #IMPLIED>
<!ATTLIST transport type (TRANSPORT_WIFI | TRANSPORT_BT | TRANSPORT_BLE | TRANSPORT_USB |
transport_wifi | transport_bt | transport_ble | transport_usb) #REQUIRED>
<!ELEMENT serviceChannel EMPTY>
<!ATTLIST serviceChannel xmlns:android CDATA #IMPLIED>
<!ATTLIST serviceChannel id CDATA #REQUIRED>
<!ATTLIST serviceChannel dataRate (LOW | HIGH | low | high) #REQUIRED>
<!ATTLIST serviceChannel priority (LOW | MEDIUM | HIGH | low | medium | high) #REQUIRED>
<!ATTLIST serviceChannel reliability (ENABLE | DISABLE | enable | disable ) #REQUIRED>
]>
<resources>
<application name="HelloAccessoryProvider" >
<serviceProfile
id="/sample/hello"
name="helloaccessory"
role="provider"
serviceImpl="com.vsmartcard.acardemulator.SmartcardProviderService"
version="1.0"
serviceLimit="ANY"
serviceTimeout="10">
<supportedTransports>
<transport type="TRANSPORT_BT" />
<transport type="TRANSPORT_WIFI" />
</supportedTransports>
<serviceChannel
id="104"
dataRate="low"
priority="low"
reliability= "enable"/>
</serviceProfile>
</application>
</resources>

View File

@@ -81,4 +81,11 @@
</PreferenceCategory> </PreferenceCategory>
<ListPreference
android:key="nfc"
android:title="NFC communication hardware"
android:defaultValue="@string/nfc"
android:entries="@array/strNFC"
android:entryValues="@array/strNFC" />
</PreferenceScreen> </PreferenceScreen>