use HCE mode of Samsung Accessories for emulation
This commit is contained in:
@@ -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,7 +118,7 @@ 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);
|
||||
}
|
||||
|
||||
|
||||
@@ -200,6 +200,8 @@ public class SettingsActivity extends AppCompatPreferenceActivity {
|
||||
return true;
|
||||
}
|
||||
});
|
||||
|
||||
bindPreferenceSummaryToValue(findPreference("nfc"));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -17,28 +17,19 @@
|
||||
* 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.preference.PreferenceManager;
|
||||
import android.support.v4.content.LocalBroadcastManager;
|
||||
import android.util.Log;
|
||||
|
||||
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 com.vsmartcard.acardemulator.R;
|
||||
import com.vsmartcard.acardemulator.Util;
|
||||
|
||||
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 +40,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 +78,19 @@ 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);
|
||||
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
@@ -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="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>
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user