我们现在正在开发一种在Android N上嵌入恩智浦NQ220(嵌入SE,称为eSE)的支付卡。该平台是MTK。现在,我们可以使用OMA与eSE进行交互(使用org.simalliance.openmobileapi.jar)。它按预期工作。
我想知道是否有任何方法可以在没有 AID 的情况下打开会话中的频道?此外,在某些情况下,有没有办法控制eSE(开机和关机)的功率并重置eSE?
我的调查如下:
- 关于没有 AID 的开放通道,我在开放移动 API 规范 V3的第 16 页找到了以下句子。
h)方法:通道打开逻辑通道(byte[] aid, Byte P2)
使用 SE 打开一个逻辑通道,选择由>给定 AID 表示的小程序。如果 AID 为 null,这意味着不会在>this 通道上选择任何小程序,则使用默认小程序。由 SE 选择将使用哪个>逻辑通道。
但是,如果我们在 openLogicalChannel(byte[] aid 中将 aid 设置为 null,将显示以下异常。这是怎么回事?默认小程序或 eSE 是否有问题?
01-30 01:06:39.941 V/SmartcardService( 2587): OpenLogicalChannel Exception: Access Control Enforcer: no APDU access allowed!
01-30 01:06:39.947 E/SeControlClient( 3239): Error occured:
01-30 01:06:39.947 E/SeControlClient( 3239): java.lang.SecurityException: Access Control Enforcer: no APDU access allowed!
01-30 01:06:39.947 E/SeControlClient( 3239): at org.simalliance.openmobileapi.SEService.checkForException(SEService.java:255)
01-30 01:06:39.947 E/SeControlClient( 3239): at org.simalliance.openmobileapi.Session.openLogicalChannel(Session.java:295)
OMA中似乎没有重置eSE的方法。但是我在INxpNfcAdapterExtras中找到了reset()方法。但是,当我使用 INxpNfcAdapterExtras.reset() 时,它总是返回 false。以下代码是我们获得INxpNfcAdapterExtras的方式。
private INxpNfcAdapterExtras getNxpNfcAdapterExtras() { if (mNfcAdapter != null) { try { INxpNfcAdapter nxpNfcAdapter = mNfcAdapter.getService().getNxpNfcAdapterInterface(); return nxpNfcAdapter.getNxpNfcAdapterExtrasInterface(); } catch (Exception e) { Log.e(LOGTAG, "Exception occured:", e); } } else { Log.e(LOGTAG, "Please initialize NfcAdapter first."); } return null; }
关于控制eSE的力量,是否与平台有关?你能给我一些建议吗?谢谢。
要访问 SE 函数,您的应用程序必须与安卓设备的所有者一起执行。
您可以在 : https://github.com/NXPNFCLinux/android_nxp-nci/blob/1d95fe24334fa12c9d9eccd1141f8739972c4288/aosp/packages/apps/Nfc/src/com/android/nfc/NfcService.java
重置方法在以下之前检查权限:
public boolean reset(String pkg) throws RemoteException {
NfcService.this.enforceNfceeAdminPerm(pkg);
Bundle result;
boolean stat = false;
try {
stat = _nfcEeReset();
result = writeNoException();
} catch (IOException e) {
result = writeEeException(EE_ERROR_IO, e.getMessage());
}
Log.d(TAG,"reset" + stat);
return stat;
}
检查权限方法:
public void enforceNfceeAdminPerm(String pkg) {
if (pkg == null) {
throw new SecurityException("caller must pass a package name");
}
NfcPermissions.enforceUserPermissions(mContext);
if (!mNfceeAccessControl.check(Binder.getCallingUid(), pkg)) {
throw new SecurityException(NfceeAccessControl.NFCEE_ACCESS_PATH +
" denies NFCEE access to " + pkg);
}
if (UserHandle.getCallingUserId() != UserHandle.USER_OWNER) {
throw new SecurityException("only the owner is allowed to call SE APIs");
}
}
要与设备所有者一起执行您的应用程序,您可以在此处关注我的 anwser: 设备管理员 API,如何成为设备所有者?
- 我不确定你的意思是"控制 eSE 的力量"。如果它打开/关闭了eSE,则eSE与NFC芯片集成,因此如果您在Android eSE中禁用NFC,eSE将关闭电源。
我找到了解决此问题的另一种方法。它使用了恩智浦自己的类NxpNfcAdapterExtrasService。
1.我仍然不知道为什么当我们使用默认小程序(没有 AID)打开频道时会发生异常。但是,使用NxpNfcAdapterExtrasService中的方法,我们可以与eSE建立连接。
2.关于第二个问题。代码是正确的,但如何使用INxpNfcAdapterExtras.reset()的方式是错误的。仅当您使用 eSE 执行某些操作时,此方法才会返回 true。比如传输和执行 APDU 命令。因此,当您要断开与 eSE 的连接时,可以使用此方法。
3.关于第三个问题,我不知道 openUicc()/closeUicc() 方法是否可以控制 eSE 功率。但是,似乎这两种方法按预期工作。