-1

我们设计了一个基于 TI RF430FRL152HEVM 评估模块的电路板,具有 NFC 功能。当 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 44UTF-8 中的“ABCD”在哪里。

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

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

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

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

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

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

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

  • 为什么 NFC TagInfo 有时会看到块,然后在检测到 NDEF 时看到页面?块和页是一样的吗?

  • 其他一切都失败了,我们如何在 Android 简单块读取中进行编码,就像 NFC TagInfo 执行其十六进制转储一样?如果我们能做到这一点,那么 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 技术是 5 类(ISO 15693 / Vicinity)
  • 它还可以正确读取块,并且在选择 Data HEX 显示时,我可以从块 0 开始准确地看到块中的上述数据。

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

因此,我尝试将更多数据从块 0 写入 TAG 以尝试模拟序列号、配置、应用程序区域颁发者块。然后我将 NDEF 消息 ABCD 放在以下部分之后:

01 02 03 04 05 06 07 08 //序列号
00 00 00 80 00 10 00 00 //配置
...

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

所以我的问题是:

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

附加信息 3

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

以下内存配置结果是有效的:

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

1 回答 1

2

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

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

为什么 NFC TagInfo 有时会看到块,然后在检测到 NDEF 时看到页面?块和页是一样的吗?

在这种情况下,块和页是等价的。不同的措辞只是来自芯片制造商使用的术语。请注意,RF430FRL152H 芯片使用术语“页”来对多个块进行分组,因此具有不同的含义。

如果一个人只是在正确的块中写入正确的字节,那么任何东西都可以作为 NDEF 被拾取,毕竟,在低级别有什么区别?

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

为了使您的标签芯片成为 NDEF 标签,您需要对从块 0 开始的 NDEF 内存区域使用以下编码: 请注意,功能容器填充了假定块大小为 8 字节的值。您可以使用固件控制寄存器中的标志 ISOBlockSize 更改 ISO 块大小选项(请参阅RF430FRL15xH 固件用户指南中的第 7.54 节“固件系统控制寄存器” )。

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

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

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

  • 0xE1是标识标签的能力容器的幻数,其中完整的内存区域可以用一个字节的块地址寻址。
  • 0x40编码类型 5 标签内存映射的 1.0 版,并指示对内存的自由读/写访问。
  • 0xF2将整个 NDEF 内存区域(CC 字节除外)定义为长度为 242 ( 0xF2) 乘以 8 字节(= 1936 字节)。请参阅下面的“理论与实践”部分!
  • 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:“T”),表示 NFC 论坛众所周知的文本记录类型(Text RTD)。
  • 0x02.. 0x44:文本记录的有效负载字段:
    • 0x02:文本以 UTF-8 编码,语言字段由 2 个字节组成。
    • 0x65 0x6E:语言字段(ASCII:“en”),表示语言英语。
    • 0x41 0x42 0x43 0x44:文本负载(UTF-8 格式:“ABCD”)。

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

块锁定有什么不同吗?

不,块锁定不会改变您的标签被检测到的方式。它仅更改读取 (Android) 设备访问它的方式:读/写访问或只读访问。

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

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

理论与实践

经过一些进一步的测试,我发现即使在 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. Tag-it HF-I 标准(256 位用户存储器,8 x 4 字节块)

不幸的是,他们都没有使用我上面描述的功能容器与 Galaxy S6 一起工作。问题在于 NDEF 内存区域的大小(MLEN,存储在 CC 的第三个字节中)。显然,上面使用的尺寸对于这两个标签来说太长了。因此,我减少了它以匹配每个标签的标签内存大小:

  1. Tag-it HF-I Plus:
    • 64 x 4 字节 = 256 字节
    • 256 字节 / 8 = 32(MLEN 始终计算为 8 字节的倍数)
    • 减 1 块,因为 CC 不计为数据区的一部分(根据类型 5 标记操作规范)
    • MLEN = 31 = 0x1F
    • 抄送:E1 40 1F 09
  2. Tag-it HF-I 标准:
    • 8 x 4 字节 = 32 字节
    • 32 字节 / 8 = 4(MLEN 始终计算为 8 字节的倍数)
    • 减 1 块,因为 CC 不计为数据区的一部分(根据类型 5 标记操作规范)
    • MLEN = 3 = 0x03
    • 抄送:E1 40 03 09

不过,这并没有奏效。标签未被检测为 NDEF 标签(仅作为NdefFormatable)。最后,我发现 Galaxy S6只有在 MLEN 字节准确地反映了整个内存区域(包括 CC 字节)的大小时才会检测到这些标签。因此,只有以下值有效:

  1. Tag-it HF-I Plus:
    • 抄送:E1 40 20 09
  2. Tag-it HF-I 标准:
    • 抄送:E1 40 04 09

更糟糕的是,虽然 CCE1 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

“应该”,因为不清楚如何识别标签并将其映射到预期的 CC 值。此外,尚不清楚 Galaxy S6 是否知道该特定芯片的任何预期 CC 值。

另一种找到 CC 字节“正确”(= 预期)值的方法是使用该技术将 NDEF 消息写入标签NdefFormatable,然后使用 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 执行其十六进制转储一样?

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 Forum Type 5 Tag Operation specification:来自NFC Forum 网站(不幸的是,NFC Forum 规范不再免费提供)。

    重要提示:请注意不要将其与 open-nfc.org 提供的“NFC Tag Type 5 Specification”混为一谈。尽管两个规范都谈到了标签“ Type 5 ”,但它们指的是完全不同的标签平台。open-nfc.org 的规范与 RF430FRL15xH 芯片兼容。

  • 与最终 NFC Forum Type 5 Tag Operation 规范非常接近的公共文档是 NXP 应用笔记AN11032 NXP Type ICODE Tag Operation。然而,NFC 论坛类型 5 标签操作规范与该应用说明之间存在一些显着差异(特别是关于能力容器的格式)。
  • NFC 数据交换格式 (NDEF) 规范:也来自 NFC 论坛网站或来自此处
  • NFC 记录类型定义 (RTD) 规范:也来自 NFC 论坛网站或来自此处
  • 文本记录类型定义规范:也来自 NFC 论坛网站或来自此处
  • 数字协议规范中的 NFC-V:也来自 NFC 论坛网站。
  • ISO/IEC 15693:该标准定义了标准的低级命令。
  • RF430FRL15xH 用户指南:您可以在第 4.2ff 节中找到用于访问 RAM 存储区的自定义命令。
于 2016-03-26T10:39:11.557 回答