2016-12-06 88 views
-1

我試圖使用SECTOR_SELECT讀寫指定扇區,但是在通過MifareUltralight.transceive()發送命令的第二部分時得到TagLostException。我如何選擇和操縱部門?MifareUltralight:扇區選擇原因TagLostException

我正在使用Android Nexus 6(6.0.1)向NXP NTAG(NT3H1201)發送命令並從中獲取數據。我可以使用帶收發器的GET_VERSION命令(60h)(通過NfcAMifareUltralight)。

我使用選擇一個部門的方法:

public void selectSector(byte sector, MifareUltralight mifareUltralight) throws IOException { 
    if (mifareUltralight.isConnected()) { 
     mifareUltralight.close(); 
    } 

    // SECTOR_SELECT command (see nxp p. 46) 
    byte[] sectorSelectCmdPacket1 = new byte[2]; 
    byte[] sectorSelectCmdPacket2 = new byte[4]; 

    sectorSelectCmdPacket1[0] = (byte) 0xc2; // Sector select command 
    sectorSelectCmdPacket1[1] = (byte) 0xff; 

    sectorSelectCmdPacket2[0] = sector; // Memory sector to be selected; 1 for I2C 2k version 
    sectorSelectCmdPacket2[1] = (byte) 0x00; 
    sectorSelectCmdPacket2[2] = (byte) 0x00; 
    sectorSelectCmdPacket2[3] = (byte) 0x00; 

    mifareUltralight.connect(); 

    try { 
     // ACK = 0A 
     byte[] sectorSelectResp1 = mifareUltralight.transceive(sectorSelectCmdPacket1); 
     Log.w(TAG, bytesToHex(sectorSelectResp1)); 
    } catch (IOException e) { 
     Log.w(TAG, "selectSector: there was an exception while sending first sector select command"); 
     e.printStackTrace(); 
    } 

    try { 
     mifareUltralight.transceive(sectorSelectCmdPacket2); 
     Log.w(TAG, "Second sector select command sent"); 
    } catch (IOException e) { 
     Log.w(TAG, "selectSector: there was an exception while sending second sector select command"); 
     e.printStackTrace(); 
    } 

    mifareUltralight.close(); 
} 

當我打電話selectSector方法,第一收發完成,但第二次卻沒有,導致錯誤

機器人。 nfc.TagLostException:標記丟失。

如何在沒有得到TagLostException的情況下選擇和操作扇區?

回答

0

SECTOR_SELECT命令的第二階段導致TagLostException是正常的。這發生在許多Android設備上,並且由SECTOR_SELECT命令的第二階段被確認(被動ACK)的方式引起。收到該特定命令的異常後,可以安全地繼續與標籤進行通信。只有當您收到一個TagLostException用於您希望獲得明確的ACK /響應數據的命令時,通信纔會出現問題。

另外請注意,您應該而不是選擇扇區後關閉連接,因爲這將重置某些Android設備上的標記。因此,稍後重新連接標籤時可能不再選擇扇區。

一個典型的區段選擇方法會是這個樣子:

public boolean selectSector(int sector) throws IOException { 
    byte[] cmd_sel1 = { (byte)0xC2, (byte)0xFF }; 
    byte[] cmd_sel2 = { (byte)sector, (byte)0x00, (byte)0x00, (byte)0x00 }; 

    byte[] result1 = transceive(cmd_sel1); 
    if (result1 == null) { 
     throw new TagLostException(); 
    } else if ((result1.length == 1) && ((result1[0] & 0x00A) == 0x000)) { 
     // NACK response according to DigitalProtocol 
     return false; 
    } else { 
     try { 
      byte[] result2 = transceive(cmd_sel2); 
      if (result2 == null) { 
       throw new TagLostException(); 
      } else if ((result2.length == 1) && ((result2[0] & 0x00A) == 0x000)) { 
       // NACK response according to DigitalProtocol 
       return false; 
      } else { 
       return true; 
      } 
     } catch (Exception e) { 
      // passive ACK 
      return true; 
     } 
    } 
} 
+0

這是非常有用的信息。謝謝,邁克爾! – fipoceilz7

+0

你會推薦哪些資源來學習這方面的知識? – fipoceilz7

+0

@ fipoceilz7我沒有意識到任何有用的公共資源(除了自己試驗和挖掘Android NFC堆棧)。我們確實提供培訓;-) –