首页 > 解决方案 > writeNdefMessage 中断 I/O 后 NFC 标签变为“损坏”

问题描述

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

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!
    }
}

我们发现,在写入 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    |.. ............ |

标签: androidnfcndef

解决方案


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

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

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

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

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

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

希望当您使用应用程序访问卡时,硬件已断电,因此不可能发生这种类型的冲突。

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

3)再次难以回答有关卡的更多信息,但是如果这是导致问题。

更新

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

问题

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

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

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

如果 NDEF 文件具有写入密码,则正常的 NDEF 格式将无法对其进行格式化。在格式化之前,您
需要使用非标准和密码进行授权。Verify command

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

下一步是用 Capability Container 的 Hex 内容更新问题,以便确定安全级别。

更新 2

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

并且作为 Adarsh,一些更好的日志记录可能有助于确定原因,希望您的 transceive方法检查来自 IsoDep.tranceive 的响应字节数组并记录任何不成功的代码,并且还会捕获和记录任何异常,如TagLostException,IOException等。

虽然您声明损坏可能是由于电话超出范围造成的,但数据表还显示 I2C 连接可以通过终止 RF 连接来优先于来自电话的 RF 连接,这也可能导致 NDEF 数据损坏.

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

目前,除了在损坏和未损坏的卡上读取低级别二进制文件自己检查 NDEF 文件的二进制内容之外,我没有任何其他想法。(Taginfo App 或许可以通过它的全扫描功能做到这一点)

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


推荐阅读