writeNdefMessage 中断 I/O 后,NFC 标签变得“损坏”

Orb*_*bit 5 android nfc ndef

我们有一个 Android 应用程序,它与自定义硬件设备上的 NFC 标签进行通信。硬件设备还可以对安装在其上的标签进行通信和操作。

Android 应用程序通过两种方式与 NFC 标签通信:

  1. IsoDep#transceive(byte[]) 用于触发硬件设备的电源循环。
  2. Ndef#writeNdefMessage(NdefMessage) 用于使用一些用户数据编写 NdefMessage/NdefRecord。

从功能上讲,这些操作类似于:

private static final byte[] NDEF_SELECT_APP_FRAME = new byte[] {
    (byte) 0x00, (byte) 0xA4, (byte) 0x04,                  
    (byte) 0x00, (byte) 0x07, (byte) 0xD2,                  
    (byte) 0x76, (byte) 0x00, (byte) 0x00,                  
    (byte) 0x85, (byte) 0x01, (byte) 0x01                   
}; 

private static final byte[] SYSTEM_FILE_SELECT = new byte[] {   
    (byte) 0x00, (byte) 0xA4, (byte) 0x00,                  
    (byte) 0x0C, (byte) 0x02, (byte) 0xE1,                  
    (byte) 0x01                                             
};                                                              

private static final byte[] TOGGLE_GPO = new byte[] {           
    (byte) 0xA2, (byte) 0xD6, (byte) 0x00,                  
    (byte) 0x1F, (byte) 0x01, (byte) 0x00                   
}; 

boolean recordSuccess = writeRecord(tag, intent, context);
if (recordSuccess) {
    boolean success = transceive(NDEF_SELECT_APP_FRAME, tag, context)
            && transceive(SYSTEM_FILE_SELECT, tag, context)
            && transceive(TOGGLE_GPO, tag, context);
    if (success) {
        // Success!
    } else {
        // Error!
    }
}
Run Code Online (Sandbox Code Playgroud)

我们发现,在写入 Ndef 数据时,I/O 似乎偶尔可能会被中断(我们不确定为什么,但我们假设在正确的时间将手机从标签上拉开是原因)。这似乎导致标签处于类似“损坏”的状态,在标签上无法再找到以前的 Ndef 数据。事实上,tag.getTechList()即使Ndef它最初是可用的,也不会在标签上列为可用技术。

所有将 Ndef 数据写入标签的进一步尝试都将失败,因为Ndef.get(tag)将返回null.

据我所知,从这一点开始的正常程序是使用NdefFormatable. 但是,NdefFormatable在 中没有列为技术类型tag.getTechList(),因此NdefFormatable.get(tag)也返回null

问题:

  1. 为什么标签似乎被损坏/擦除?
  2. 为什么 Ndef 在损坏后没有被列为标签技术,即使该标签最初支持它?
  3. 鉴于这种状态NdefFormatable.get(tag)似乎又恢复了,我们如何才能从这种状态中恢复过来null

编辑: NFC 芯片似乎是 M24SR04-Y。规格表可在此处找到:https : //www.st.com/resource/en/datasheet/m24sr04-g.pdf

TagInfo 应用显示的能力容器内容:

# Capability Container (CC) file content:
Mapping version 2.0
CC length: 15 bytes
Maximum Le value: 246 bytes
Maximum Lc value: 246 bytes
NDEF File Control TLV:
* Length: 6 bytes
* NDEF file ID: 0x0001
* Maximum NDEF data size: 512 bytes
* NDEF access: Read & Write
[0] 00 0F 20 00 F6 00 F6 04 06 00 01 02 00 00 00    |.. ............ |
Run Code Online (Sandbox Code Playgroud)

And*_*rew 2

如果不知道它是什么类型的卡以及它符合什么 NFC 规范,这个问题很难回答。

了解这一点的第一步是获取 NFC 卡的数据表。可能值得使用像 nxpinfo 这样的 Android 应用程序来尝试确定卡上的芯片类型和 NFC 规范类型,然后可以得出所使用的数据表/nfc 规范。

答案
2) 卡上 NDEF 的支持是由大多数规范中称为“能力容器”的东西决定的,它可以存储在特定的块地址或其他读取方法中。

如果所使用的 NFC 规范的定义方法没有可读的“功能容器”,则该卡将不会被视为支持 NDEF 且可格式化。

这可能是一张自定义卡,并且“功能容器”也已损坏。

1) 如果没有有关卡类型的更多详细信息,则未知,但另一个原因可能是 2 个读卡器/写入器正在尝试同时访问该卡(一个来自硬件设备,一个来自应用程序)。正常的 NDEF 写入/读取不会导致问题,但可能是硬件设备执行了某些自定义卡访问方法。

希望当您使用应用程序访问卡时,硬件已关闭,因此不可能发生此类冲突。

如果没有,可以制作一个连接到 LED 的简单线圈,以制作基本的 NFC 场检测器,以查看硬件是否定期对卡进行可能导致冲突的操作。

3)再次难以回答有关该卡的更多信息,但如果这是导致该问题的原因,则可能会在自定义卡类型上重新编写低级别的“功能容器”以使其再次可格式化问题。

更新

因为它看起来是 NFC Type 4 芯片,但也有 I2C 接口。它还具有一些扩展的非标准命令

问题

我猜硬件是通过 i2C 连接的?

阅读规范后,卡上似乎有 2 个安全级别超出了 NDEF 规范(我不确定 nxpinfo 应用程序是否会理解这些值,但可能会显示它们)。

因此,NDEF 文件可能受密码保护或只读。

如果 NDEF 文件有写入密码,则正常的 NDEF 格式化将无法对其进行格式化。
您需要使用非标准Verify command密码并获得授权才能格式化。

如果 NDEF 文件已被永久锁定(只读),则只有 I2C 连接可以解锁 NDEF 文件。在此状态下的卡无法通过任何 Android 应用程序进行格式化。

下一步是使用功能容器的十六进制内容更新问题,以便确定安全级别。

更新2

好的,所以卡没有密码保护或锁定,因为 CC 文件的最后 2 个字节是 00

正如 Adarsh 一样,一些更好的日志记录可能有助于确定原因,希望您的 transceive方法检查来自 IsoDep.tranceive 的响应字节数组并记录任何非成功代码以及任何异常,例如TagLostExceptionIOException等也被捕获和记录。

虽然您指出损坏可能是由手机超出范围引起的,但数据表还显示,通过终止 RF 连接,I2C 连接可以优先于手机的 RF 连接,这也可能导致 NDEF 数据损坏。

如果 RF 连接已被 I2C 连接终止,则手机可能无法对 RF 连接执行任何操作,直到将其移出范围并再次返回。

目前,我除了在损坏和未损坏的卡上使用低级二进制读取自行检查 NDEF 文件的二进制内容之外没有任何其他想法。(Taginfo 应用程序也许可以通过其完整扫描功能来做到这一点)

但由于这张卡卡updates(可以在卡的开头或任何偏移处写入),我希望 Android 在写入 NDEF 消息时始终从开头开始,因此如果 TLV 字节标记被截断的写入损坏,那应该无关紧要一个新的writeNdefMessage. TLV 损坏可能会阻止 Android 从文件中读取 NDEF 消息。(需要检查Android操作系统源代码来确认它的作用)