2015-05-14 547 views
1

我有一個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

回答

0

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

1

嘗試調用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