Merge branch 'GearS2'
This commit is contained in:
2
ACardEmulator/app/.gitignore
vendored
2
ACardEmulator/app/.gitignore
vendored
@@ -1 +1 @@
|
||||
/build
|
||||
/build
|
||||
@@ -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>
|
||||
@@ -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')
|
||||
}
|
||||
|
||||
BIN
ACardEmulator/app/libs/accessory-v2.3.2.jar
Normal file
BIN
ACardEmulator/app/libs/accessory-v2.3.2.jar
Normal file
Binary file not shown.
BIN
ACardEmulator/app/libs/sdk-v1.0.0.jar
Normal file
BIN
ACardEmulator/app/libs/sdk-v1.0.0.jar
Normal file
Binary file not shown.
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
|
||||
@@ -200,6 +200,8 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
bindPreferenceSummaryToValue(findPreference("nfc"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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>
|
||||
|
||||
51
ACardEmulator/app/src/main/res/xml/accessoryservices.xml
Normal file
51
ACardEmulator/app/src/main/res/xml/accessoryservices.xml
Normal 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>
|
||||
@@ -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>
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user