TI RF430FRL152HEVM NFC NDEF格式

时间:2016-03-23 20:43:27

标签: android nfc ndef texas-instruments iso-15693

我们设计了一款基于具有NFC功能的TI RF430FRL152HEVM评估模块的电路板。当Android手机靠近主板的天线时,NFC允许处理器启动并开始读取数据。 它将读取的数据放入内存中。

然后,手机必须使用NFC(或更确切地说是ISO 15693)从设备中获取此数据。

目前我们知道如何执行此操作的唯一方法是将其写入标准NFC内存块。

我们下载了一款名为NFC TagInfo的Android应用程序,这让我们可以扫描传感器并收集传感器内存中的所有数据,即所有数据块。

我们正在将其写入芯片制造商所说的FRAM中的NDEF消息区域。我为另一个项目编写了一个读写器NFC应用程序,虽然效果很好,但它拒绝在这里读取数据,尽管NFC TagInfo确实读取了数据。

我们假设TI芯片已经过NDEF格式化,但我们发现的关于如何做到这一点的所有文档都非常不清楚。所以我们猜它还没有。

有人可以解释如何正确准备内存内容,以便手机可以读取NDEF消息吗?

其他信息

我们从块0开始将数据写入FRAM,并试图模仿在包含非常简单的NDEF消息的典型标记中看到的数据。例如,我们存储了消息" ABCD"使用NFC TagInfo,您可以在前几个块中看到这一点:

04 5c d8 08  4a 62 3e 80
96 48 00 00  e1 10 12 00
01 03 a0 0c  34 03 21 d1
01 1d 54 02  65 6e 41 42
43 44 20 20  ...

41 42 43 44是" ABCD"在UTF-8中。

我们从另一个标签(使用NFC TagInfo读取)获取此数据(NDEF格式+标头),并将此数据复制到我们标签芯片的FRAM块中。我们在NDEF消息结束时停止,FRAM的其余部分为0x000xff

显然,我们从(NXP)和我们的标签芯片(TI)复制数据的标签来自不同的制造商,因此前几个模块中的一些数据对我们的TI芯片无效,但假设Android不应该关心。

但是,当我们使用NFC TagInfo读取TI标签时,它可以读取原始数据块,但它不会将标签识别为NDEF格式的标签。

  • 我们从其他标签复制的NDEF格式是否对我们的标签无效,因为我们没有使用相同的标签内存大小等?

  • 如果只是在正确的块中写入正确的字节,那么可以将任何东西都当作NDEF,毕竟,在低级别有什么区别?

  • 如果是这种情况,那么在哪些块中使用最合理的字节测试用例,是否有更好的方法来测试这个概念?

  • 块锁定有什么区别吗?我们可以看到一些块被锁定在真实标签中。

  • 为什么NFC TagInfo有时会看到块,然后在检测到NDEF时会看到页面?块和页面是否相同?

  • 失败了,我们如何在Android简单块读取中编写代码,就像NFC TagInfo执行其hex-dump一样?如果我们能做到这一点,那么NDEF就没有必要。

其他信息2

我修改了固件,使得从0开始的FRAM包含您提到的数据:

E1 40 F2 09   03 0B D1 01
07 54 02 65   6E 41 42 43
44 FE 00 00   00 00 00 00

但是我似乎无法将TI芯片置于8字节块模式。似乎没有与此相关的控制寄存器。

从我的低级别来看,写入4或8字节的块不是问题,也就是说,我在FRAM存储器中按字节顺序写入上述数据。

当我运行NFC TagInfo时,它执行两项操作但未检测到NDEF消息:

  • 它确实正确检测到UID,RF Tech是Type 5(ISO 15693 / Vicinity)
  • 它也正确地读取了块并且在选择数据HEX显示时我从块0开始精确地看到上面的数据。

我已经查阅了我从http://open-nfc.org/documents/STS_NFC_0707-001%20NFC%20Tag%20Type%205%20Specification.pdf

获得的NFC标签类型5规范

因此,我尝试从块0向TAG写入更多数据,以尝试模拟SERIAL NUMBER,CONFIGURATION,Application area issuer blocks。然后我在部分之后放置了NDEF消息ABCD:

01 02 03 04   05 06 07 08   //serial number
00 00 00 80   00 10 00 00   //configuration
...

我使用了NFC TagInfo,但我也无法检测到NDEF消息。但是,使用数据十六进制显示,我可以验证数据是否正确读出。

所以我的问题是:

  • 是否配置4或8字节块模式以及最有可能定义此模式的位置是否相关?我可以在4字节块模式下工作吗?
  • TAG 5序列号是否相关?根据规范,似乎不会影响NDEF检查。
  • TAG 5申请区域发行人是否相关?似乎与NDEF验证无关。
  • 我的NDEF消息是否放在正确的区域?
  • 对于16位值,是高字节低字节还是低字节高字节排序?
  • 任何想法出了什么问题?

其他信息3

事实证明,TI需要提供补丁才能让NDEF与该芯片配合使用(FRL152H)。基本上,该芯片旨在通过NFC使用内部固件应用程序支持传感器功能的高级控制。需要禁用此应用程序并更改某些设置。

以下内存配置开始起作用:

Block 0:  E1 40 79 00
Block 1:  03 0B D1 01
Block 2:  07 54 02 65
Block 3:  6e 41 42 43
Block 4:  44 FE 00 00

1 个答案:

答案 0 :(得分:2)

我们从其他标签复制的NDEF格式是否对我们的标签无效?

这正是问题所在。查看内存转储的前12个字节,显然是从制造商代码(字节0:0x04)指示的NXP NTAG203(或类似)中复制了数据块,以及容量容器中的内存大小(字节13:0x12)。恩智浦的NTAG和MIFARE Ultralight系列遵循NFC论坛类型2标签操作规范。但是,您的TI芯片(RF430FRL152H)基于ISO / IEC 15693,因此遵循NFC论坛类型5标签操作规范。标签操作规范定义了将NFC标签转换为NDEF标签的数据格式和命令集。有几种(目前有5种)不同的此类规格,因为NFC技术结合了几种不同的RF标准(ISO / IEC 14443,FeliCa,ISO / IEC 15693),并使用在NFC之前已经存在的标签硬件。

为什么NFC TagInfo有时会看到块,然后在检测到NDEF时会看到页面?块和页面是否相同?

在这种情况下,块和页面是等效的。不同的措辞仅来自芯片制造商使用的术语。请注意,RF430FRL152H芯片使用术语"页面"分组几个块,因此具有不同的含义。

如果只是简单地在正确的块中写入正确的字节,那么任何东西都可以被选为NDEF,毕竟,在低级别有什么区别?

不同之处在于,您的TI RF430FRL152H标签芯片需要使用与NXP标签不同的NDEF存储区编码。这仅仅是因为它使用了不同的低级通信技术(调制,编码,成帧,命令集),因此遵循不同的NFC论坛标签操作规范。

为了使您的标签芯片成为NDEF标签,您需要对从块0开始的NDEF存储区使用以下编码:请注意,容量容器填充了假设块大小为8字节的值。您可以使用固件控制寄存器中的标志ISOBlockSize更改ISO块大小选项(请参阅第7.54节"固件系统控制寄存器"在RF430FRL15xH Firmware User's Guide中)。

E1 40 F2 09   03 0B D1 01
07 54 02 65   6E 41 42 43
44 FE 00 00   00 00 00 00

这将导致NDEF消息包含一条带有消息" ABCD"的文本记录。

前4个字节(E1 40 F2 09)是功能容器:

  • 0xE1是标识标记的功能容器的幻数,其中完整的内存区域可以使用一个字节块地址进行寻址。
  • 0x40代码类型5标记内存映射的1.0版,表示对内存的自由读/写访问。
  • 0xF2将整个NDEF内存区域(CC字节除外)定义为长度为242(0xF2)乘以8字节(= 1936字节)。 请参阅&#34; 理论与实践&#34;下面<!/强>
  • 0x09表示您的标签支持READ_MULTIPLE_BLOCKS命令(位0设置)和LOCK_BLOCK命令(位3设置)。

接下来的2个字节(03 0B)是NDEF消息TLV(标记长度值编码数据结构)的标题:

  • 0x03:表示NDEF消息TLV的头字节。
  • 0x0B:NDEF消息的长度TLV = 11个字节。

接下来的11个字节(D1 01 07 54 02 656E 41424344)是NDEF消息:

  • 0xD1:记录标题字节:
    • 第7位和第6位:这是NDEF消息的唯一记录。
    • 位4:这是一个短记录(即有效载荷长度用单个字节编码)。
    • 位2..0:记录类型编码NFC论坛众所周知的类型。
  • 0x01:类型名称字段的长度为1个字节。
  • 0x07:有效负载字段的长度为7个字节。
  • 0x54:类型名称(ASCII:&#34; T&#34;),表示NFC论坛众所周知的文本记录类型(文本RTD)。
  • 0x02 .. 0x44:文本记录的有效内容字段:
    • 0x02:文本以UTF-8编码,语言字段由2个字节组成。
    • 0x65 0x6E:语言字段(ASCII:&#34; en&#34;)表示语言为英语。
    • 0x41 0x42 0x43 0x44:文本有效负载(UTF-8:&#34; ABCD&#34;)。

下一个字节(FE)是终结者TLV,表示已使用数据区的结束。该块的剩余字节应填充零(0x00),以避免某些Android设备出现问题。

块锁定有什么不同吗?

不,块锁定不会改变检测到标记的方式。它只会改变阅读(Android)设备访问它的方式:读/写访问或只读访问。

在所有Android设备上是否可以检测到此标记?

不幸的是,没有。 NFC论坛类型5标签操作规范仅在2015年7月完成。虽然一些Android设备在该日期之前在ISO / IEC 15693(NFC-V)标签上实施了NDEF,但并不希望所有Android设备都出现这种情况。它应该适用于从Android 5.0开始的大多数设备。有些Android设备应该能够支持某些NFC-V标签上的NDEF,即使是Android 4.3。

理论与实践

经过一些进一步的测试后,我发现甚至那些支持5类(NFC-V)标签上的NDEF的设备在NFC堆栈的实现中似乎也有很大的局限性(错误??? ) 。我使用TI Tag-it HF-I系列中的两种标签测试了三星Galaxy S6(Android 5.1.1):

  1. Tag-it HF-I Plus(2048位用户存储器,64 x 4字节块)
  2. 标签HF-I标准(256位用户存储器,8 x 4字节块)
  3. 不幸的是,他们都没有使用我上面描述的功能容器来使用Galaxy S6。问题是NDEF存储区的大小(MLEN,存储在CC的第三个字节中)。显然,上面使用的尺寸对于这两个标签来说太长了。因此,我将其缩小为与每个标签的标签内存大小相匹配:

    1. Tag-it HF-I Plus:
      • 64 x 4字节= 256字节
      • 256字节/ 8 = 32(MLEN始终计算为8字节的倍数)
      • 减去1个块,因为CC不算作数据区的一部分(根据Type 5 Tag Operation规范)
      • MLEN = 31 = 0x1F
      • CC:E1 40 1F 09
    2. Tag-it HF-I标准:
      • 8 x 4字节= 32字节
      • 32字节/ 8 = 4(MLEN始终计算为8字节的倍数)
      • 减去1个块,因为CC不算作数据区的一部分(根据Type 5 Tag Operation规范)
      • MLEN = 3 = 0x03
      • CC:E1 40 03 09
    3. 但是,这不起作用。标签未被检测为NDEF标签(仅作为NdefFormatable)。最后,我发现如果MLEN字节反映完全 整个存储区(包括CC)的大小,那么Galaxy S6 会检测到这些标记字节)。因此,只有以下值有效:

      1. Tag-it HF-I Plus:
        • CC:E1 40 20 09
      2. Tag-it HF-I标准:
        • CC:E1 40 04 09
      3. 更糟糕的是,当CC E1 40 04 09处理Tag-it HF-I标准标签时,它在Tag-it HF-I Plus标签上工作。因此,Galaxy S6的NFC堆栈似乎期望不同标签产品上的CC具有非常特定的值。

        基于此,以下CC值应适用于RF430FRL152H:

        1. 当块大小设置为8字节时:E1 40 F3 09
        2. 当块大小设置为4个字节时:E1 40 79 09
        3. &#34;应该&#34;,因为它不清楚如何识别标签并将其映射到预期的CC值。此外,目前还不清楚Galaxy S6是否知道该特定芯片的任何预期CC值。

          找到&#34;纠正&#34;的另一种方法(=预期)CC字节的值是使用NdefFormatable技术将NDEF消息写入标签,然后使用NFC TagInfo等标签阅读器应用程序读取CC字节:

          Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
          NdefFormatable ndefFormatable = NdefFormatable.get(tag);
          
          if (ndefFormatable != null) {
              try {
                  ndefFormatable.connect();
                  ndefFormatable.format(new NdefMessage(NdefRecord.createTextRecord("en", "ABCD")));
              } catch (Exception e) {
              } finally {
                  try {
                      ndefFormatable.close();
                  } catch (Exception e) {
                  }
              }
          }
          

          使用一些通用标签编写器应用程序也可以这样做(NXP TagWriter似乎无法写入标签)。

          失败了,我们如何在Android中实现简单的块读取,就像NFC TagInfo执行其hex-dump一样?

          RF430FRL152H应被Android检测为NFC-V(NFC术语中的ISO / IEC 15693)标签。因此,一旦您收到NFC意图,您就可以获取标记句柄并获取NfcV类的实例:

          Tag tag = intent.getParcelableExtra(NfcAdapter.EXTRA_TAG);
          NfcV nfcV = NfcV.get(tag);
          

          您可以使用收发方法连接到标签并交换低级命令(例如READ_SINGLE_BLOCK):

          nfcV.connect();
          byte[] tagUid = tag.getId();  // store tag UID for use in addressed commands
          
          int blockAddress = 0;
          byte[] cmd = new byte[] {
              (byte)0x60,  // FLAGS
              (byte)0x20,  // READ_SINGLE_BLOCK
              0, 0, 0, 0, 0, 0, 0, 0,
              (byte)(blockAddress & 0x0ff)
          };
          System.arraycopy(tagUid, 0, cmd, 2, 8);
          
          byte[] response = nfcV.transceive(cmd);
          
          nfcV.close();
          

          在哪里可以获得有关标签格式化,NDEF和低级命令的更多信息?

          • NFC论坛类型5标签操作规范:来自NFC Forum website(遗憾的是,NFC论坛规范不再免费提供)。

            重要提示:小心将其与&#34; NFC标签类型5规范&#34;由open-nfc.org提供。尽管这两个规范都涉及标签&#34; Type 5 &#34;但它们指的是一个完全不同的标签平台。 open-nfc.org的规范与RF430FRL15xH芯片兼容。

          • 与最终NFC论坛类型5标签操作规范非常接近的公共文档是恩智浦应用说明AN11032 NXP Type ICODE Tag Operation。但是,NFC论坛类型5标签操作规范与该应用说明之间存在一些显着差异(特别是关于功能容器的格式)。
          • NFC数据交换格式(NDEF)规范:也来自NFC论坛网站或here
          • NFC记录类型定义(RTD)规范:也来自NFC论坛网站或here
          • 文本记录类型定义规范:也来自NFC论坛网站或here
          • 数字协议规范中的NFC-V:也来自NFC论坛网站。
          • ISO / IEC 15693:该标准定义了标准的低级命令。
          • RF430FRL15xH User Guide:您可以在4.2ff中找到用于访问RAM内存区域的自定义命令。