blob: 9974b66b573379af762d3f4a2f1be69882acd372 [file] [log] [blame]
/*
* Copyright (C) 2011, The Android Open Source Project
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Contributed by: Giesecke & Devrient GmbH.
*/
package org.simalliance.openmobileapi.service;
import android.content.Context;
import android.content.pm.PackageInfo;
import java.lang.reflect.Method;
import java.util.LinkedList;
import java.util.List;
public class AddonTerminal extends Terminal {
private Object mInstance = null;
private Method mIsCardPresent = null;
private Method mInternalConnect = null;
private Method mInternalDisconnect = null;
private Method mInternalTransmit = null;
private Method mInternalOpenLogicalChannel = null;
private Method mInternalOpenLogicalChannelAID = null;
private Method mInternalCloseLogicalChannel = null;
private Method mGetName = null;
private Method mGetAtr = null;
private Method mGetSelectResponse = null;
public static String[] getPackageNames(Context context) {
List<String> packageNameList = new LinkedList<String>();
List<PackageInfo> pis = context.getPackageManager().getInstalledPackages(0);
for (PackageInfo p : pis) {
if (p.packageName.startsWith("org.simalliance.openmobileapi.service.terminals.")
|| p.packageName.startsWith("org.simalliance.openmobileapi.cts")) {
packageNameList.add(p.packageName);
}
}
String[] rstrings = new String[packageNameList.size()];
packageNameList.toArray(rstrings);
return rstrings;
}
public AddonTerminal(Context context, String packageName, String className) {
super("Addon", context);
try {
Context ctx = context.createPackageContext(packageName, Context.CONTEXT_IGNORE_SECURITY
| Context.CONTEXT_INCLUDE_CODE);
ClassLoader cl = ctx.getClassLoader();
Class<?> cls = cl.loadClass(className);
mInstance = cls.getConstructor(new Class[] {
Context.class
}).newInstance(new Object[] {
context
});
if (mInstance != null) {
mGetAtr = mInstance.getClass().getDeclaredMethod("getAtr", (Class<?>[]) null);
mGetName = mInstance.getClass().getDeclaredMethod("getName", (Class<?>[]) null);
mIsCardPresent = mInstance.getClass().getDeclaredMethod("isCardPresent",
(Class<?>[]) null);
mInternalConnect = mInstance.getClass().getDeclaredMethod("internalConnect",
(Class<?>[]) null);
mInternalDisconnect = mInstance.getClass().getDeclaredMethod("internalDisconnect",
(Class<?>[]) null);
mInternalTransmit = mInstance.getClass().getDeclaredMethod("internalTransmit",
new Class[] {
byte[].class
});
mInternalOpenLogicalChannel = mInstance.getClass().getDeclaredMethod(
"internalOpenLogicalChannel", (Class<?>[]) null);
mInternalOpenLogicalChannelAID = mInstance.getClass().getDeclaredMethod(
"internalOpenLogicalChannel", new Class[] {
byte[].class
});
mInternalCloseLogicalChannel = mInstance.getClass().getDeclaredMethod(
"internalCloseLogicalChannel", new Class[] {
int.class
});
mGetSelectResponse = mInstance.getClass().getDeclaredMethod("getSelectResponse",
(Class<?>[]) null);
}
} catch (Exception e) {
throw new IllegalStateException("plugin internal error: " + e);
}
}
/**
* Returns the ATR of the connected card or null if the ATR is not
* available.
*
* @return the ATR of the connected card or null if the ATR is not
* available.
*/
public byte[] getAtr() {
if (mGetAtr == null) {
throw new IllegalStateException("plugin error: Function String getAtr() not found");
}
try {
byte[] resp = (byte[]) mGetAtr.invoke(mInstance, (Object[]) null);
return resp;
} catch (Exception e) {
throw new IllegalStateException("plugin internal error: getAtr() execution: "
+ e.getCause());
}
}
public String getName() {
if (mGetName == null) {
throw new IllegalStateException("plugin error: Function String getName() not found");
}
try {
String s = (String) mGetName.invoke(mInstance, (Object[]) null);
return s;
} catch (Exception e) {
throw new IllegalStateException("plugin internal error: getName() execution: "
+ e.getCause());
}
}
public boolean isCardPresent() throws CardException {
if (mIsCardPresent == null) {
throw new IllegalStateException(
"plugin error: Function String isCardPresent() not found");
}
try {
Boolean v = (Boolean) mIsCardPresent.invoke(mInstance, (Object[]) null);
return v.booleanValue();
} catch (Exception e) {
throw new CardException("plugin internal error: isCardPresent() execution: "
+ e.getCause());
}
}
protected void internalConnect() throws CardException {
if (mInternalConnect == null) {
throw new IllegalStateException(
"plugin error: Function String internalConnect() not found");
}
try {
mInternalConnect.invoke(mInstance, (Object[]) null);
mIsConnected = true;
} catch (Exception e) {
throw new CardException("plugin internal error: internalConnect() execution: "
+ e.getCause());
}
}
protected void internalDisconnect() throws CardException {
if (mInternalDisconnect == null) {
throw new IllegalStateException(
"plugin error: Function String internalDisconnect() not found");
}
try {
mInternalDisconnect.invoke(mInstance, (Object[]) null);
mIsConnected = false;
} catch (Exception e) {
throw new CardException("plugin internal error: internalDisconnect() execution");
}
}
protected byte[] internalTransmit(byte[] command) throws CardException {
if (mInternalTransmit == null) {
throw new IllegalStateException(
"plugin error: Function String internalTransmit() not found");
}
try {
byte[] resp = (byte[]) mInternalTransmit.invoke(mInstance, new Object[] {
command
});
return resp;
} catch (Exception e) {
throw new CardException("plugin internal error: internalTransmit() execution: "
+ e.getCause());
}
}
protected int internalOpenLogicalChannel() throws Exception {
if (mInternalOpenLogicalChannel == null) {
throw new IllegalStateException(
"plugin error: Function String internalOpenLogicalChannel() not found");
}
try {
Integer channel = (Integer) mInternalOpenLogicalChannel.invoke(mInstance,
(Object[]) null);
return channel.intValue();
} catch (Exception e) {
throw (Exception) e.getCause();
}
}
protected int internalOpenLogicalChannel(byte[] aid) throws Exception {
if (mInternalOpenLogicalChannelAID == null) {
throw new IllegalStateException(
"plugin error: Function internalOpenLogicalChannelAID() not found");
}
try {
Integer channel = (Integer) mInternalOpenLogicalChannelAID.invoke(mInstance,
new Object[] {
aid
});
mSelectResponse = (byte[]) mGetSelectResponse.invoke(mInstance, (Object[]) null);
return channel.intValue();
} catch (Exception e) {
throw (Exception) e.getCause();
}
}
protected void internalCloseLogicalChannel(int channelNumber) throws CardException {
if (mInternalCloseLogicalChannel == null) {
throw new IllegalStateException(
"plugin error: Function internalCloseLogicalChannel not found");
}
try {
mInternalCloseLogicalChannel.invoke(mInstance, new Object[] {
channelNumber
});
} catch (Exception e) {
throw new CardException(
"plugin internal error: internalOpenLogicalChannel() execution: "
+ e.getCause());
}
}
}