jjzjj

Android nfcA.connect()、nfcA.transceive()、nfcA.setTimeout() 和 nfcA.getMaxTransceiveLength()

coder 2023-12-01 原文

我有许多新手 NfcA 问题。在 docs 和网络上的其他地方似乎对此几乎没有指导,所以我希望没有人介意我在这里将一些基本问题串在一起......

我正在使用 nfcA.transceive() 将数据写入我的 NTAG213 标签,如下所示:

    byte[] result = nfcA.transceive(new byte[] {
            (byte)0xA2,  // WRITE
            (byte)(pageNum & 0x0ff),
            myData[0], myData[1], myData[2], myData[3]
    });

1. result 数组是值 10 的单个字节。这是什么意思,我应该注意哪些其他值?

我也使用相同的方法从我的 NTAG213 标签中读取数据:
    byte[] result = nfcA.transceive(new byte[] {
            (byte)0x30,  // READ
            (byte)(pageNum & 0x0ff)
    });

2. 我希望这会返回 4 个字节的用户数据(即对应于我的 pageNum 的 4 个字节),但它返回了 16 个字节。为什么会这样?

3. 在调用 nfcA.isConnected() 之前检查 nfcA.connect() 是否是一种好习惯,如果是这样,这样做是否可能会产生任何显着的性能损失? (我问,因为我已经看到了来自有信誉的来源的代码示例。)

4. nfcA.setTimeout()之前还是之后调用nfcA.connect()更好?

5. 对于我的 NTAG213 标签 nfcA.getMaxTransceiveLength() 返回 253。这是否真的意味着我可以一次写入多达 251 个字节的用户数据(加上其他 2 个字节),如果是这样,那是可取的还是写得更好每个页面(4 个字节)都有单独的 nfcA.transceive() 调用?

最佳答案

1. WRITE 命令的结果数组是值 10 的单个字节。这是什么意思以及我应该注意哪些其他值?

值 10(十六进制的 Ah 或二进制表示的 1010b)是一个显式 ACK,当一个没有返回数据的命令成功时返回一个确认。

可能的值是实际数据、ACK、被动 ACK 或 NACK。这些由 NFC 论坛数字协议(protocol)规范和 NFC 论坛类型 2 标签操作规范定义。

  • 如果希望命令在成功时返回实际数据,则返回数据而不是显式 ACK 值。
  • ACK 定义为 4 位短帧(有关详细信息,请参阅 NFC 论坛数字协议(protocol)规范和 ISO/IEC 14443-3),其值为 1010b (Ah)。
  • 被动 ACK 定义为标签在特定超时内根本不发送响应。
  • NACK 定义为 4 位短帧,值为 0x0xb(其中 x 为 0 或 1)。

  • NTAG213/215/216 产品数据表对可能的 NACK 值更具体一点:
  • 0000b (0h) 表示命令参数无效。
  • 0001b (1h) 表示奇偶校验或 CRC 错误。
  • 0100b (4h) 表示无效的身份验证计数器溢出。
  • 0101b (5h) 表示 EEPROM 写入错误。

  • 除了上述之外,某些设备上的 NFC 堆栈实现不会正确地将 NACK 响应传播到应用程序。相反,他们要么抛出 TagLostException 要么返回 null 。同样,您可能(?)得到一个 TagLostException 指示被动 ACK。

    因此,您通常会检查以下收发方法的结果(除非您发送预期会导致被动 ACK 的命令):
    try {
       response = nfca.transceive(command);
       if (response == null) {
           // either communication to the tag was lost or a NACK was received
       } else if ((response.length == 1) && ((response[0] & 0x00A) != 0x00A)) {
           // NACK response according to Digital Protocol/T2TOP
       } else {
           // success: response contains ACK or actual data
       }
    } catch (TagLostException e) {
       // either communication to the tag was lost or a NACK was received
    }
    

    2. 我希望 READ 方法返回 4 个字节的用户数据(即与我的 pageNum 对应的 4 个字节),但它返回了 16 个字节。为什么会这样?

    READ 命令被定义为返回从指定 block 号开始的 4 个数据 block (在 NFC 论坛类型 2 标签操作规范中)。因此,如果您发送 block 4 的 READ 命令,您将获得 block 4、5、6 和 7 的数据。

    3. 在调用 nfcA.isConnected() 之前检查 nfcA.connect() 是否是一种好习惯,如果是这样,这样做是否可能会产生任何显着的性能损失?

    如果您直接从 NFC 系统服务(通过 NFC Intent )收到 Tag 句柄,则不会连接标签。因此,除非您在调用 Tag 之前使用 nfca.connect() 句柄,否则我不明白您为什么要在之前调用 nfca.isConnected() 。但是,在连接之前调用该方法几乎没有任何性能开销,因为在封闭标签技术对象上调用 isConnected() 将由 famwork API 处理,而无需调用 NFC 系统服务。因此,它的开销并不比 if 对象的 bool 成员变量上的简单 NfcA 多多少。

    4. 在 nfcA.setTimeout() 之前或之后调用 nfcA.connect() 更好吗?

    我不确定那个。然而,收发超时通常在断开标签技术时重置。

    5. 对于我的 NTAG213 标签 nfcA.getMaxTransceiveLength() 返回 253。这是否真的意味着我可以一次写入多达 251 个字节的用户数据(加上其他 2 个字节),如果是这样,是可取的还是写每一页更好(4 个字节)有单独的 nfcA.transceive() 调用?

    不,你一次只能写一个 block 。这受到 NTAG213 的 WRITE 命令的限制,它只支持一个 block 作为数据输入。

    但是,253 的收发缓冲区大小允许您使用 FAST_READ 命令一次读取多个 block (最多 62 个,因此对于 NTAG213 最多 45 个):
    int firstBlockNum = 0;
    int lastBlockNum = 42;
    byte[] result = nfcA.transceive(new byte[] {
            (byte)0x3A,  // FAST_READ
            (byte)(firstBlockNum & 0x0ff),
            (byte)(lastBlockNum & 0x0ff),
    });
    

    关于Android nfcA.connect()、nfcA.transceive()、nfcA.setTimeout() 和 nfcA.getMaxTransceiveLength(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40288795/

    有关Android nfcA.connect()、nfcA.transceive()、nfcA.setTimeout() 和 nfcA.getMaxTransceiveLength()的更多相关文章

    1. ruby HTTPClient : How to use persistent connections? - 2

      如何通过HTTPClient使用持久HTTP连接?发送HTTP请求时是否只是设置KeepAlive的问题?文档指出支持持久连接,但没有告诉我们如何使用它们。 最佳答案 是availableinNet::HTTP如文档中所写,Net::HTTP.startimmediatelycreatesaconnectiontoanHTTPserverwhichiskeptopenforthedurationoftheblock.Theconnectionwillremainopenformultiplerequestsintheblockift

    2. ruby - 使用 watir-webdriver 打开多个线程导致 'Connection refused' 错误 - 2

      我有这个简单的例子:require'watir-webdriver'arr=[]sites=["www.google.com","www.bbc.com","www.cnn.com","www.gmail.com"]sites.eachdo|site|arr每次我运行这个脚本,我都会得到ruby/2.1.0/net/http.rb:879:in`initialize':Connectionrefused-connect(2)for"127.0.0.1"port9517(Errno::ECONNREFUSED)或者其中一个浏览器在至少一个线程上意外关闭。另一方面,如果我在每个循环周期结束

    3. ruby-on-rails - connect() 到 unix :/var/run/unicorn. 连接到上游时 sock 失败(111:连接被拒绝) - 2

      我遵循ruby​​onrails一个应用程序点击部署。数据库做得很好,即使我检查Rails控制台一切正常017/02/2615:34:17[error]18564#0:*31connect()tounix:/var/run/unicorn.sockfailed(111:Connectionrefused)whileconnectingtoupstream,client:121.52.156.57,server:_,request:"GET/HTTP/1.1",upstream:"http://unix:/var/run/unicorn.sock:/",host:"188.166.157

    4. ruby-on-rails - Faraday::ConnectionFailed,Connection refused - connect(2) for “localhost” port 9200 Error Ruby on Rails - 2

      我正在尝试使用RubyonRails在我的应用程序中添加Searchkickgem,但是当我在搜索框中键入一个词时,我的应用程序中出现此错误。我已经根据需要安装了elasticsearch和最新版本的java,但错误仍然是一样的。这是我得到的错误:Faraday::ConnectionFailedinPostsController#searchConnectionrefused-connect(2)for"localhost"port9200这是我的代码:终端显示已安装Elasticsearch:终端Warning:elasticsearch-1.7.3alreadyinstalled

    5. ruby-on-rails - 将 Facebook Connect 与 Authlogic 结合使用 - 2

      我正在尝试使Authlogic和FacebookConnect(使用Facebook)发挥良好的作用,以便您可以通过正常注册方式或使用Facebookconnect创建帐户。我已经能够让连接以一种方式工作,但注销只会在facebook而不是我的网站上注销,我必须删除cookie才能使其正常工作。任何帮助都会很棒,谢谢! 最佳答案 这是我使用FacebookConnect扩展、authlogic和OpenID制作的示例应用程序。它仍然需要一些工作,但它确实起作用了。http://big-glow-mama.heroku.com/htt

    6. ruby-on-rails - Elasticsearch 问题 : Cannot connect AWS elasticsearch service - 2

      我有一个关于配置elasticsearch以连接AWSelasticsearch服务以在生产环境中运行项目的问题。我的gem文件:gem'searchkick'gem'faraday_middleware-aws-signers-v4'gem'aws-sdk','~>2'gem"elasticsearch",">=1.0.15"引用:https://github.com/ankane/searchkick我的config/initializers/elasticsearch.rb文件:require"faraday_middleware/aws_signers_v4"ENV["ELAS

    7. ruby-on-rails - rails : Find rows without connection in HABTM relation - 2

      我有两个模型,Users和Leads与HABTM关系相关:classLead我现在如何才能只获得那些与用户无关的线索?提前致谢! 最佳答案 您正在寻找的是antijoin.有三种标准方法可以实现这一点,使用空左外连接使用带有NOT和IN关键字的子查询的where子句使用带有NOT和EXISTS关键字的where子句基本上,EXISTS关键字将检查子查询是否返回任何行并将其报告为匹配项,NOT显然会否定真正的匹配项。这是我的首选方式(使用NOT&EXISTS)classUser这是一个使用arel的非SQL方法classUserher

    8. sql - 来自 ActiveRecord::Base.connection.execute(sql) - PostgreSQL 的结果 - 2

      在使用ActiveRecord::BaseConnection类执行SQL语句后,如何找到PostgreSQL处理的记录数?temp_sql="UPDATEtable_aSETcolumn_a='abc'WHEREcolumn_b=1"result=ActiveRecord::Base.establish_connection(@db).connection.execute(temp_sql)或者您可以建议更好的方法来做到这一点。请记住,上面的更新声明是一个简单的更新声明,以保持问题简短。我真正的查询是“基于集合”的,涉及复杂的创建临时表、更新、插入语句。

    9. ruby - 在 AWS Linux 上增加 RestClient/Net::HTTP 中的 connect(2) 超时 - 2

      我正在使用rest-client发布到一个非常慢的网络服务。我将timeout设置为600秒,并且我已经确认它正在传递给Net::HTTP的@read_timeout和@open_timeout.但是,大约两分钟后,我收到一个低级超时错误,Errno::ETIMEDOUT:Connectiontimedout-connect(2):回溯的相关部分是Operationtimedout-connect(2)for[myhost]port[myport]/Users/dmoles/.rvm/rubies/ruby-2.2.5/lib/ruby/2.2.0/net/http.rb:879:in

    10. 解决错误LibreSSL SSL_connect: SSL_ERROR_SYSCALL in connection to - 2

      gitclone出现错误OpenSSLSSL_connect:SSL_ERROR_SYSCALLinconnectiontogithub.com:443升级node时错误OpenSSLSSL_connect:SSL_ERROR_SYSCALLinconnectiontonodejs.org:443解决方法以下几种解决方法可以尝试,由于开发环境不同,不一定每个都适用你的问题我用的mac电脑,方法一解决了我的问题,我先用的其它方法然而并没有解决方法一修改计算机网络配置由于使用IPv6的原因,可能会导致这一问题的出现系统在解析hostname时使用了ipv6可以配置计算机不使用IPv6,故使用以下命

    随机推荐