2016-12-06 83 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堆栈)。我们确实提供培训;-) –