标签错误地列举为MIFARE经典,SAK = 32

标签错误地列举为MIFARE经典,SAK = 32

问题描述:

我有一个Sony Xperia Z3。我正在使用它与MIFARE Classic智能卡进行交互。标签错误地列举为MIFARE经典,SAK = 32

当使用原生MIFARE卡时,我可以正确读取卡。

但是,如果我使用的是仿真的MIFARE Classic,我得到的SAK不正确。在0x38代替我使用MifareClassic.get(tag)

java.lang.RuntimeException: Tag incorrectly enumerated as MIFARE Classic, SAK = 32 

时,我不知道为什么我的手机是不正确的的SAK得到为0x20(32)和下面的错误。

同样的卡正确读取支持MIFARE作为Nexus S的其他设备等

任何想法,为什么这个异常?

TA

SAK值不是您可以用来区分不同NFC标签的魔术值。相反,它有点掩盖价值,它定义了RF协议的一些功能。

不幸的是,谷歌的Android代码使用SAK对Mifare卡识别,你可以在这个代码在这里看到:MifareClassic.java

在你的Xperia Z3会发生什么事是可能的是,NFC控制器和NFC堆栈正确检测到标签为Mifare兼容并报告。一旦你尝试使用标签,你会遇到你提到的问题。

Nexus S可能运行MifareClassic.java代码的固定版本并避免该问题。

你能做些什么:从应用的角度来看,没有什么是真的。这是Android操作系统中的一个错误。如果你有root用户访问权限,你可以很难做到,并且即时修补成员函数。

+0

的SAK可以帮助你知道什么类型的协议都可以用卡来使用。这里的事实是,Z3是我测试过的返回SAK值(0x20)的唯一移动设备。实际上SAK是由卡片响应Select命令而生成的,因此每个移动设备/芯片组应返回相同的值。为什么Z3上的芯片正在以另一种方式做它?这是问题;) – jlanza

尝试调用MifareClassic.get(tag) 欲了解更多信息之前,使用这个补丁为tag = cleanupTag(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; 
} 
+0

谢谢。标签被检测到并且SAK是正确的。但问题是,当我们尝试从Mifare卡中读取内存时,我们发现标签丢失的例外。任何想法? – jlanza