我有索尼Xperia Z3。我正在使用它与MIFARE Classic智能卡进行交互。
使用原生MIFARE卡时,我可以正确读取卡片。
但是,如果我使用模拟的MIFARE Classic,我会得到一个不正确的SAK。当使用MifareClassic.get(tag)
java.lang.RuntimeException: Tag incorrectly enumerated as MIFARE Classic, SAK = 32
我不知道为什么我的手机会错误地读取SAK。
在支持MIFARE作为Nexus S等的其他设备上正确读取相同的卡
知道这个例外的原因吗?
TA
答案 0 :(得分:1)
在致电tag = cleanupTag(tag)
之前,尝试将此补丁用作MifareClassic.get(tag)
有关详细信息,请参阅MifareClassicTool Sony Z3 issue
private Tag cleanupTag(Tag oTag){
if (oTag == null)
return null;
String[] sTechList = oTag.getTechList();
Parcel oParcel = Parcel.obtain();
oTag.writeToParcel(oParcel, 0);
oParcel.setDataPosition(0);
int len = oParcel.readInt();
byte[] id = null;
if (len >= 0) {
id = new byte[len];
oParcel.readByteArray(id);
}
int[] oTechList = new int[oParcel.readInt()];
oParcel.readIntArray(oTechList);
Bundle[] oTechExtras = oParcel.createTypedArray(Bundle.CREATOR);
int serviceHandle = oParcel.readInt();
int isMock = oParcel.readInt();
IBinder tagService;
if (isMock == 0) {
tagService = oParcel.readStrongBinder();
} else {
tagService = null;
}
oParcel.recycle();
int nfca_idx = -1;
int mc_idx = -1;
short oSak = 0;
short nSak = 0;
for (int idx = 0; idx < sTechList.length; idx++) {
if (sTechList[idx].equals(NfcA.class.getName())) {
if (nfca_idx == -1) {
nfca_idx = idx;
if (oTechExtras[idx] != null
&& oTechExtras[idx].containsKey("sak")) {
oSak = oTechExtras[idx].getShort("sak");
nSak = oSak;
}
} else {
if (oTechExtras[idx] != null
&& oTechExtras[idx].containsKey("sak")) {
nSak = (short) (nSak | oTechExtras[idx].getShort("sak"));
}
}
} else if (sTechList[idx].equals(MifareClassic.class.getName())) {
mc_idx = idx;
}
}
boolean modified = false;
if (oSak != nSak) {
oTechExtras[nfca_idx].putShort("sak", nSak);
modified = true;
}
if (nfca_idx != -1 && mc_idx != -1 && oTechExtras[mc_idx] == null) {
oTechExtras[mc_idx] = oTechExtras[nfca_idx];
modified = true;
}
if (!modified) {
return oTag;
}
Parcel nParcel = Parcel.obtain();
nParcel.writeInt(id.length);
nParcel.writeByteArray(id);
nParcel.writeInt(oTechList.length);
nParcel.writeIntArray(oTechList);
nParcel.writeTypedArray(oTechExtras, 0);
nParcel.writeInt(serviceHandle);
nParcel.writeInt(isMock);
if (isMock == 0) {
nParcel.writeStrongBinder(tagService);
}
nParcel.setDataPosition(0);
Tag nTag = Tag.CREATOR.createFromParcel(nParcel);
nParcel.recycle();
return nTag;
}
答案 1 :(得分:0)
SAK值不是可用于区分不同NFC标签的神奇值。相反,它是一个掩码值,它定义了RF协议的一些功能。
不幸的是,谷歌Android代码使用SAK进行mifare卡识别,您可以在此处的代码中看到:MifareClassic.java
Xperia Z3中发生的情况可能是NFC控制器和NFC堆栈正确检测到标签为Mifare兼容并报告。一旦你尝试使用标签,就会遇到你提到的问题。
Nexus S可能正在运行MifareClassic.java代码的固定版本并避免此问题。
你能做些什么:从应用程序的角度来看,没什么。这是Android操作系统中的一个错误。如果您具有root访问权限,则可以通过艰难的方式完成并动态修补成员函数。