MifareUltralight:扇区 select 导致 TagLostException
MifareUltralight: sector select causes TagLostException
我正在尝试使用 SECTOR_SELECT 来读写 to/from 指定的扇区,但是当我通过 MifareUltralight.transceive()
发送命令的第二部分时得到 TagLostException
.我如何 select 和操纵扇区?
我正在使用 Android Nexus 6 (6.0.1) 向 NXP NTAG (NT3H1201) 发送命令并从中获取数据。我可以将 GET_VERSION 命令 (60h) 与收发器一起使用(通过 NfcA
和 MifareUltralight
)。
我用来select一个扇区的方法:
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 方法时,第一个收发完成但第二个没有完成,导致错误
android.nfc.TagLostException: Tag was lost.
如何在没有得到 TagLostException
的情况下 select 和操纵扇区?
SECTOR_SELECT 命令的第二阶段产生 TagLostException
是正常的。这发生在许多 Android 设备上,并且是由 SECTOR_SELECT 命令的第二阶段的确认方式(被动 ACK)引起的。在收到特定命令的异常后,您可以安全地继续与标签通信。仅当您收到一个 TagLostException
的命令时,您期望一个明确的 ACK/response 数据,说明通信有问题。
另请注意,您应该不 在 select 扇区后关闭连接,因为这会重置某些 Android 设备上的标签。因此,当您稍后重新连接标签时,该扇区可能不再 selected。
典型的扇区 select 方法如下所示:
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;
}
}
}
我正在尝试使用 SECTOR_SELECT 来读写 to/from 指定的扇区,但是当我通过 MifareUltralight.transceive()
发送命令的第二部分时得到 TagLostException
.我如何 select 和操纵扇区?
我正在使用 Android Nexus 6 (6.0.1) 向 NXP NTAG (NT3H1201) 发送命令并从中获取数据。我可以将 GET_VERSION 命令 (60h) 与收发器一起使用(通过 NfcA
和 MifareUltralight
)。
我用来select一个扇区的方法:
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 方法时,第一个收发完成但第二个没有完成,导致错误
android.nfc.TagLostException: Tag was lost.
如何在没有得到 TagLostException
的情况下 select 和操纵扇区?
SECTOR_SELECT 命令的第二阶段产生 TagLostException
是正常的。这发生在许多 Android 设备上,并且是由 SECTOR_SELECT 命令的第二阶段的确认方式(被动 ACK)引起的。在收到特定命令的异常后,您可以安全地继续与标签通信。仅当您收到一个 TagLostException
的命令时,您期望一个明确的 ACK/response 数据,说明通信有问题。
另请注意,您应该不 在 select 扇区后关闭连接,因为这会重置某些 Android 设备上的标签。因此,当您稍后重新连接标签时,该扇区可能不再 selected。
典型的扇区 select 方法如下所示:
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;
}
}
}