Merge branch 'GearS2'

This commit is contained in:
Frank Morgner
2017-01-15 20:42:15 +01:00
33 changed files with 1633 additions and 99 deletions

View File

@@ -1 +1 @@
/build
/build

View File

@@ -32,12 +32,14 @@
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/debug" isTestSource="false" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/debug" type="java-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/r/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/aidl/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/buildConfig/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/rs/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/source/apt/androidTest/debug" isTestSource="true" generated="true" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/rs/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/build/generated/res/resValues/androidTest/debug" type="java-test-resource" />
<sourceFolder url="file://$MODULE_DIR$/src/debug/res" type="java-resource" />
@@ -87,12 +89,8 @@
<sourceFolder url="file://$MODULE_DIR$/src/androidTest/shaders" isTestSource="true" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/assets" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/blame" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/builds" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/bundles" />
<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/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/appcompat-v7/23.2.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/design/23.2.1/jars" />
@@ -101,39 +99,32 @@
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.android.support/support-vector-drawable/23.2.1/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/exploded-aar/com.journeyapps/zxing-android-embedded/3.2.0/jars" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-runtime-classes" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-safeguard" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/incremental-verifier" />
<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/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/res" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/restart-dex" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/rs" />
<excludeFolder url="file://$MODULE_DIR$/build/intermediates/shaders" />
<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/outputs" />
<excludeFolder url="file://$MODULE_DIR$/build/tmp" />
</content>
<orderEntry type="jdk" jdkName="Android API 23 Platform" jdkType="Android SDK" />
<orderEntry type="sourceFolder" forTests="false" />
<orderEntry type="library" exported="" name="support-v4-23.2.1" level="project" />
<orderEntry type="library" exported="" name="sdk-v1.0.0" 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="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="recyclerview-v7-23.2.1" 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="zxing-android-embedded-3.2.0" level="project" />
<orderEntry type="library" exported="" name="accessory-v2.3.2" level="project" />
<orderEntry type="library" exported="" name="jcardsim-3.0.4-SNAPSHOT-android" level="project" />
<orderEntry type="library" exported="" name="design-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="support-v4-23.2.1" level="project" />
<orderEntry type="library" exported="" name="core-1.51.0.0" level="project" />
<orderEntry type="library" exported="" name="support-annotations-23.2.1" level="project" />
<orderEntry type="library" exported="" name="animated-vector-drawable-23.2.1" level="project" />
<orderEntry type="library" exported="" name="support-vector-drawable-23.2.1" level="project" />
<orderEntry type="library" exported="" name="appcompat-v7-23.2.1" level="project" />
</component>
</module>

View File

@@ -3,7 +3,6 @@ apply plugin: 'com.android.application'
android {
compileSdkVersion 23
buildToolsVersion "23.0.1"
defaultConfig {
applicationId "com.vsmartcard.acardemulator"
minSdkVersion 19
@@ -49,12 +48,12 @@ android.applicationVariants.all { variant ->
}
dependencies {
compile fileTree(dir: 'libs', include: ['*.jar'])
compile fileTree(include: ['*.jar'], dir: 'libs')
compile 'com.android.support:appcompat-v7:23.0.1'
compile 'com.android.support:support-v4:23.0.1'
compile 'com.android.support:design:23.2.1'
compile 'com.journeyapps:zxing-android-embedded:3.2.0@aar'
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

@@ -6,6 +6,13 @@
<uses-permission android:name="android.permission.INTERNET"/>
<uses-permission android:name="android.permission.NFC" />
<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
android:allowBackup="true"
@@ -37,7 +44,7 @@
</intent-filter>
</activity>
<service android:name=".EmulatorService"
<service android:name=".EmulatorHostApduService"
android:exported="true"
android:permission="android.permission.BIND_NFC_SERVICE">
<intent-filter>
@@ -47,6 +54,24 @@
<meta-data android:name="android.nfc.cardemulation.host_apdu_service"
android:resource="@xml/aid_list"/>
</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>
</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.Toast;
import com.vsmartcard.acardemulator.emulators.EmulatorSingleton;
public class MainActivity extends AppCompatActivity {
@@ -48,12 +50,12 @@ public class MainActivity extends AppCompatActivity {
private BroadcastReceiver bReceiver = new BroadcastReceiver() {
@Override
public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(EmulatorService.TAG)) {
String capdu = intent.getStringExtra(EmulatorService.EXTRA_CAPDU);
String rapdu = intent.getStringExtra(EmulatorService.EXTRA_RAPDU);
String error = intent.getStringExtra(EmulatorService.EXTRA_ERROR);
String deselect = intent.getStringExtra(EmulatorService.EXTRA_DESELECT);
String install = intent.getStringExtra(EmulatorService.EXTRA_INSTALL);
if (intent.getAction().equals(EmulatorSingleton.TAG)) {
String capdu = intent.getStringExtra(EmulatorSingleton.EXTRA_CAPDU);
String rapdu = intent.getStringExtra(EmulatorSingleton.EXTRA_RAPDU);
String error = intent.getStringExtra(EmulatorSingleton.EXTRA_ERROR);
String deselect = intent.getStringExtra(EmulatorSingleton.EXTRA_DESELECT);
String install = intent.getStringExtra(EmulatorSingleton.EXTRA_INSTALL);
if (install != null)
textViewVPCDStatus.append(getResources().getString(R.string.status_install) + ":" + install + "\n");
if (capdu != null)
@@ -102,7 +104,7 @@ public class MainActivity extends AppCompatActivity {
if (emulator != getString(R.string.vicc)) {
Snackbar.make(view, "Scheduled re-installation of all applets...", Snackbar.LENGTH_LONG)
.setAction("Action", null).show();
EmulatorService.destroySimulator(getApplicationContext());
EmulatorSingleton.destroyEmulator();
}
}
});
@@ -116,8 +118,11 @@ public class MainActivity extends AppCompatActivity {
LocalBroadcastManager bManager = LocalBroadcastManager.getInstance(this);
IntentFilter intentFilter = new IntentFilter();
intentFilter.addAction(EmulatorService.TAG);
intentFilter.addAction(EmulatorSingleton.TAG);
bManager.registerReceiver(bReceiver, intentFilter);
Intent serviceIntent = new Intent(this.getApplicationContext(), SmartcardProviderService.class);
startService(serviceIntent);
}
@Override

View File

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

View File

@@ -0,0 +1,220 @@
/*
* 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 android.content.Intent;
import android.os.Binder;
import android.os.Handler;
import android.os.IBinder;
import android.text.TextUtils;
import android.util.Log;
import android.widget.Toast;
import com.samsung.android.sdk.SsdkUnsupportedException;
import com.samsung.android.sdk.accessory.SA;
import com.samsung.android.sdk.accessory.SAAgent;
import com.samsung.android.sdk.accessory.SAAuthenticationToken;
import com.samsung.android.sdk.accessory.SAPeerAgent;
import com.samsung.android.sdk.accessory.SASocket;
import com.vsmartcard.acardemulator.emulators.EmulatorSingleton;
import java.io.IOException;
public class SmartcardProviderService extends SAAgent {
private static final String TAG = "ACardEmulator";
private static final int ACCESSORY_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)) {
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();
}
findPeerAgents();
}
@Override
public IBinder onBind(Intent intent) {
return mBinder;
}
@Override
protected void onFindPeerAgentsResponse(SAPeerAgent[] peerAgents, int result) {
switch (result) {
case PEER_AGENT_FOUND:
break;
case FINDPEER_SERVICE_NOT_FOUND:
break;
case FINDPEER_DEVICE_NOT_CONNECTED:
break;
default:
break;
}
Log.d(TAG, "onFindPeerAgentResponse : result =" + result);
}
@Override
protected void onServiceConnectionRequested(SAPeerAgent peerAgent) {
if (peerAgent != null) {
//TODO: Check for keys and everything
acceptServiceConnectionRequest(peerAgent);
}
}
@Override
protected void onServiceConnectionResponse(SAPeerAgent peerAgent, SASocket socket, int result) {
if (result == SAAgent.CONNECTION_SUCCESS) {
if (socket != null) {
mConnectionHandler = (ServiceConnection) socket;
Toast.makeText(getBaseContext(), "connection established", Toast.LENGTH_SHORT).show();
}
} 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[] sendResponse;
if (data[0] == 'd') {
// APDU is sent
byte[] newData = new byte[data.length - 1];
System.arraycopy(data, 1, newData, 0, data.length - 1);
byte[] response = EmulatorSingleton.process(getApplicationContext(), newData);
sendResponse = new byte[response.length + 1];
sendResponse[0] = 'd';
System.arraycopy(response, 0, sendResponse, 1, response.length);
} else if (data[0] == 'a') {
// request for aids
String[] aidList = EmulatorSingleton.getRegisteredAids(getApplicationContext());
String aidListJoined = TextUtils.join(",", aidList);
sendResponse = new byte[aidListJoined.length() + 1];
sendResponse[0] = 'a';
byte[] aids = aidListJoined.getBytes();
System.arraycopy(aids, 0, sendResponse, 1, aids.length);
} else {
Log.e(TAG, "unknown message from consumer: " + new String(data));
return;
}
new Thread(new Runnable() {
public void run() {
try {
mConnectionHandler.send(ACCESSORY_CHANNEL_ID, sendResponse);
} 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,31 @@
* 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.Intent;
import android.content.SharedPreferences;
import android.nfc.cardemulation.HostApduService;
import android.os.Bundle;
import android.os.StrictMode;
import android.content.res.Resources;
import android.content.res.XmlResourceParser;
import android.nfc.NfcAdapter;
import android.nfc.cardemulation.CardEmulation;
import android.preference.PreferenceManager;
import android.support.annotation.XmlRes;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Log;
import com.vsmartcard.acardemulator.R;
import com.vsmartcard.acardemulator.Util;
import org.xmlpull.v1.XmlPullParser;
import org.xmlpull.v1.XmlPullParserException;
import java.io.IOException;
import java.net.InetAddress;
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 {
import java.util.ArrayList;
import java.util.List;
public class EmulatorSingleton {
public static final String TAG = "com.vsmartcard.acardemulator.EmulatorService";
public static final String EXTRA_CAPDU = "MSG_CAPDU";
public static final String EXTRA_RAPDU = "MSG_RAPDU";
@@ -49,22 +52,35 @@ public class EmulatorService extends HostApduService {
private static Emulator emulator = null;
private static boolean do_destroy = false;
@Override
public void onCreate () {
super.onCreate();
private static void destroyEmulatorIfRequested(Context context) {
if (do_destroy) {
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
do_destroy();
destroyEmulatorIfRequested(context);
if (emulator == null) {
Log.d("", "Begin transaction");
SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(this);
SharedPreferences SP = PreferenceManager.getDefaultSharedPreferences(context);
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(
SP.getString("hostname", VICCEmulator.DEFAULT_HOSTNAME),
Integer.parseInt(SP.getString("port", Integer.toString(VICCEmulator.DEFAULT_PORT))));
} else {
emulator = new JCEmulator(this,
emulator = new JCEmulator(context,
SP.getBoolean("activate_helloworld", false),
SP.getBoolean("activate_openpgp", false),
SP.getBoolean("activate_oath", false),
@@ -74,55 +90,45 @@ public class EmulatorService extends HostApduService {
}
}
public static void destroySimulator(Context context) {
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) {
public static byte[] process(Context context, byte[] capdu) {
byte[] rapdu = emulator.process(capdu);
Intent i = new Intent(TAG);
i.putExtra(EXTRA_CAPDU, Util.byteArrayToHexString(capdu));
if (rapdu != null)
i.putExtra(EXTRA_RAPDU, Util.byteArrayToHexString(rapdu));
LocalBroadcastManager.getInstance(this).sendBroadcast(i);
LocalBroadcastManager.getInstance(context).sendBroadcast(i);
return rapdu;
}
@Override
public void onDeactivated(int reason) {
Intent i = new Intent(TAG);
public static String[] getRegisteredAids(Context context) {
List<String> aidList = new ArrayList<>();
XmlResourceParser aidXmlParser = context.getResources().getXml(R.xml.aid_list);
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;
try {
while (aidXmlParser.getEventType() != XmlPullParser.END_DOCUMENT) {
if (aidXmlParser.getEventType() == XmlPullParser.START_TAG) {
if (aidXmlParser.getName().equals("aid-filter")) {
int aid = aidXmlParser.getAttributeResourceValue(0, -1);
if (aid != -1) {
aidList.add(context.getResources().getString(aid));
}
}
}
aidXmlParser.next();
}
aidXmlParser.close();
} catch (XmlPullParserException | IOException e) {
Log.e(TAG.substring(0, 23), "Couldn't parse aid xml list.");
}
LocalBroadcastManager.getInstance(this).sendBroadcast(i);
return aidList.toArray(new String[0]);
}
}
public static void deactivate() {
emulator.deactivate();
}
}

View File

@@ -9,7 +9,6 @@ import com.licel.jcardsim.base.SimulatorRuntime;
import com.licel.jcardsim.samples.HelloWorldApplet;
import com.licel.jcardsim.utils.AIDUtil;
import com.mysmartlogon.gidsApplet.GidsApplet;
import com.vsmartcard.acardemulator.EmulatorService;
import com.vsmartcard.acardemulator.R;
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())
i.putExtra(EmulatorService.EXTRA_ERROR, extra_error);
i.putExtra(EmulatorSingleton.EXTRA_ERROR, extra_error);
if (!extra_install.isEmpty())
i.putExtra(EmulatorService.EXTRA_INSTALL, extra_install);
i.putExtra(EmulatorSingleton.EXTRA_INSTALL, extra_install);
LocalBroadcastManager.getInstance(context).sendBroadcast(i);
}

View File

@@ -4,7 +4,7 @@
android:layout_width="match_parent"
android:layout_height="match_parent"
android:fitsSystemWindows="true"
tools:context="com.vsmartcard.smartcardemulator.MainActivity">
tools:context="com.vsmartcard.acardemulator.MainActivity">
<android.support.design.widget.AppBarLayout
android:id="@+id/app_bar"

View File

@@ -44,6 +44,14 @@
</string-array>
<string name="jcardsim">Builtin Java Card Simulator</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="hint_vicc_port">VICC Port</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="VirtualSmartCardReader" >
<serviceProfile
id="/com/vsmcartcard"
name="VirtualSmartCardReaderProvider"
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="high"
reliability= "enable"/>
</serviceProfile>
</application>
</resources>

View File

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

View File

@@ -5,7 +5,7 @@ buildscript {
jcenter()
}
dependencies {
classpath 'com.android.tools.build:gradle:2.1.0'
classpath 'com.android.tools.build:gradle:2.2.0'
// NOTE: Do not place your application dependencies here; they belong
// in the individual module build.gradle files

View File

@@ -1,6 +1,6 @@
#Thu May 12 09:46:58 CEST 2016
#Tue Oct 04 22:11:09 CEST 2016
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-2.10-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-2.14.1-all.zip