【问题标题】:How to properly handle IOException with NFCA.transceive?如何使用 NFCA.transceive 正确处理 IOException?
【发布时间】:2020-07-01 13:18:30
【问题描述】:

我是 Android 开发的初学者,我正在尝试为 NFC 配置“直通”模式。基本上 I2C 在 NFC TAG 上写入一些内容,手机将其拾取,新数据由 I2C 写入等等。我有点纠结于标签的写入时间:同时,由于收发失败,手机收到“NAK”并返回 IOException。我该如何正确处理它?我尝试使用“thread.millis”等到 I2C 完成,但这个解决方案看起来很糟糕,只适用于我的 arduino 和手机。

while (Schleife < 1000) {
                                try {
                                   answer = ultralight.transceive(command); //This one throws an IOException if the data is not ready yet                        
                                   Schleife = Schleife + 1;
                                } catch (IOException ioe) {
                                  //Log.e("UnsupportedEncoding", ioe.toString());
                                }
}

我希望程序重新执行该过程。我尝试的一件事是将 catch 语句包含到 while 循环中,但有时重新运行 while 循环需要很长时间。

感谢每一个回答。

亲切的问候

【问题讨论】:

  • 听起来您有一些 NFC 芯片,您正试图让它与手机通话。提供有关您正在使用的 NFC 芯片硬件的详细信息以及您如何控制该芯片的代码。我认为您误解了 NFC 的工作原理。 NFC芯片可以在读写器、主机卡仿真和点对点三种主要模式下工作。听起来您正在尝试使用读取器/写入器模式来相互交谈,这是行不通的。您需要读写器才能与真实卡(或主机卡仿真模式下的 NFC 芯片)或两者在点对点模式下(但在 Android 10 中已删除)进行通信
  • 感谢您的回复!我正在使用 NXP NFC NTag NT3H1101/NT3H120。它支持所谓的“直通”模式,基本上是I2C在NTAG上写,手机读,I2C再写等等,一切都在瞬间发生。当手机读取 SRAM 时,它会立即尝试再次读取,因为 SRAM 是由 I2C 写入的,所以这不起作用。因此,NFC 芯片返回一个“NAK”,触发我要处理的 IOException。
  • OK 现在我们知道您使用的是哪种芯片更容易理解您有一个双接口 NFC 卡芯片(因此它是 NFC 卡模式的读写器)但是该芯片有一个特殊的模式绕过正常的 EEPROM)。问题是您要收发的command 是什么?在收发级别,NAK 是有效的收发响应,不应是 IO 异常(数据已成功发送和接收)。您还可能想查看android.googlesource.com/platform/frameworks/base/+/refs/heads/…
  • 我正在尝试收发命令“Fast_Read”,该命令在一个命令中读取 sram 的 64 个字节。它看起来像这样:Command[0] = 0xA0; [1] = 0xF0,[2] = 0xFF。它是一个简单的收发命令。

标签: java android android-studio try-catch nfc


【解决方案1】:

我对芯片数据表的阅读是,您正在循环收发错误的命令。

在涉及 SRAM 的终止页的 READ 或 FAST_READ 命令后,位 SRAM_RF_READY 和位 RF_LOCKED 自动重置为 0b,允许 I2C 接口进一步将数据写入 SRAM 缓冲区。向主机发出进一步数据准备就绪的信号要写入,有以下机制:•NFC 接口从 NS_REG 轮询/读取位 SRAM_RF_READY(见表 14),以了解 I2C 接口是否已将新数据写入 SRAM

您应该循环读取 E8h 块并检查 SRAM 是否已准备好通过 RF 连接读取,然后在字节 0 中设置正确位时使用快速读取读取 64 个字节

这就是芯片如何在 I2C 接口和 RF 接口之间实现流控机制以防止错误。

更新
好的,实现表显示了如何在没有流量控制的情况下执行此操作。

关于如何处理 NACK 的问题,首先你需要检查它 以下是我检查 NACK 的方法


if ((answer != null) && (answer.length == 1) && ((answer[0] & 0x00A) != 0x00A)) {
         // Got NACK
        Log.e("Nack", Schleife); //added to identify iteration.

}

记录任何 IOException 的迭代次数会很有帮助

我认为 NACK 和 IO 异常在不同的迭代中。 因为正确的 NACK 不是 IO 异常。

Android 还对引擎盖下的防碰撞进行了编码,因此在收到 NACK 时,您唯一可以尝试的是再次closeconnect

低电平transeive到“0x95 0x70(UID字节)”是正确的 (取自https://android.googlesource.com/kernel/common/+/android-3.18/net/nfc/digital_technology.c#349) “0x95 0x70”我认为是卡类型的正确防碰撞命令。

【讨论】:

  • 感谢您的回复!我已经尝试过这种方法,但是这样做需要“SectorSelect”,因为 RF_READY_BIT 位于那里并且执行 SectorSelect 非常慢。我想尽可能快地传输数据,包括 SectorSelect 会减慢进程。我想试试这个:“同时,NFC 端可以通过轮询位“SRAM_RF_READY”来检查 SRAM 中的数据是否已经可用,或者它只是尝试读取内存,如果它收到 NACK,它会再次执行反- 与标签冲突并重试。”
  • 这可以通过nxp.com/docs/en/application-note/AN11579.pdf找到(第6页),但我根本不知道如何处理NACK或IOException。
猜你喜欢
  • 2012-02-27
  • 2021-07-31
  • 2015-07-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-02-05
  • 2016-12-11
相关资源
最近更新 更多