【问题标题】:Reading ISO15693 RFID tag through Android NFC results in incorrect data output通过 Android NFC 读取 ISO15693 RFID 标签会导致数据输出不正确
【发布时间】:2016-11-22 05:45:37
【问题描述】:

我们有一些 ISO15693 标签,我们曾经使用 RFID 阅读器读取这些标签。今天我开始在 Android 上开发一个示例应用程序,以使用 NfcV 和 Android 6 (API 23) 读取相同的标签。

我能够从标签中读取一些数据,但数据中有一些意外字符。这是我使用的代码:

private void readTagData(Tag tag) throws Exception {
    byte[] id = tag.getId();
    String strTag = new String(id, "UTF-8");
    boolean techFound = false;
    for (String tech : tag.getTechList()) {
        if (tech.equals(NfcV.class.getName())) {
            techFound = true;
            NfcV nfcvTag = NfcV.get(tag);
            try {
                nfcvTag.connect();
            } catch (IOException e) {
                Toast.makeText(this, "IO Exception", Toast.LENGTH_LONG).show();
                return;
            }
            try {
                int offset = 0;  
                int blocks = 19;  
                byte[] cmd = new byte[]{
                        (byte)0x60,                  
                        (byte)0x23,                  
                        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,  // placeholder for tag UID
                        (byte)(offset & 0x0ff),      
                        (byte)((blocks - 1) & 0x0ff)
                };
                System.arraycopy(id, 0, cmd, 2, 8);
                byte[] response = nfcvTag.transceive(cmd);

                response = Arrays.copyOfRange(response, 0, 96);
                String strData = new String(response, "UTF-8");
                mTextView.setText("TAG:" + strTag + " DATA:" + strData);
            } catch (IOException e) {
                Toast.makeText(this, "An error occurred while reading", Toast.LENGTH_SHORT).show();
                return;
            }

            try {
                nfcvTag.close();
            } catch (IOException e) {
                Toast.makeText(getApplicationContext(), "Unable to close the connection!", Toast.LENGTH_SHORT).show();
                return;
            }
        }
    }
}

输出

标签 ID(UTF-8 解码):{��WP�

数据(UTF-8 解码):����1ead��1234��5678��5000��00B1��2345��6181��5064��1602��2016��1603��2016。 �1602��2018��0011��8899��0002��0920��16����

十六进制表示的数据字节:

0000316561640031 3233340035363738 0035303030003030 42310032333‌43500 363138310035303‌6 3400313630320032 303‌1360031363033 0032303‌136003136 30320032303‌13800 303031310038383‌9 3900303030320030 393‌​2300031360000

现在部分数据是正确的,但我不确定为什么会有这些“�”字符。标签 ID 也不正确。

另外,我尝试将字节数组“响应”和标记 ID 转换为十六进制字符串,然后转换为 ASCII,结果相同。

【问题讨论】:

  • 也许他们在不使用 UTF-8 的情况下将其写入 RFID 标签
  • 肯定是旧的 RFID 应用程序使用 UTF-8 从旧应用程序读取以下代码: result = byteArray != null ?新字符串(byteBuf.array(), "UTF-8") : null;
  • 尝试 Latin-1 而不是 UTF-8
  • 标签 ID 肯定不是您可以明智地解释为 UTF-8 字符串的东西。关于剩余数据:难道只有部分块以 UTF-8 编码?您还确定数据从块 0 开始吗​​?您可能还想向我们揭示这些字节数组的十六进制表示,并且,由于您似乎拥有一些“旧应用程序”的代码(一个似乎可以工作的),您可能想揭示相关的代码片段(即对其他应用程序进行实际阅读和解释)......
  • 啊,当然要删除响应的第一个字节(即标志字节),仅将响应的数据字段转换为 UTF-8 字符串。

标签: android tags nfc rfid iso-15693


【解决方案1】:

您收到的值是您发送的命令的预期响应:

您发送参数化的命令 READ MULTIPLE BLOCKS(命令代码 0x23)以读取从偏移量 0 开始的 19 个块。您的标签的块大小似乎是 4 个字节。

此外,您指定 0x60 的标志字节,它转换为标志 Address_flagOption_flagAddress_flag 使命令寻址(即您必须指定目标标签的 UID,这是您正确的做法)。 Option_flag 使标签除了返回块数据本身之外还返回块安全状态。因此,您的标签的响应如下所示:

+-------+-------+-------+-------+-------+-------+- ------+-------+-------+-------+--------+-...-+----- ---+-------+-------+-------+-------+ |旗帜 | BSS_0 | BLOCK_DATA_0 | BSS_1 | BLOCK_DATA_1 | ... | BSS_18 | BLOCK_DATA_18 | +-------+-------+-------+-------+-------+-------+- ------+-------+-------+-------+--------+-...-+----- ---+-------+-------+-------+-------+

第一个字节,即响应标志,指示命令的总体结果(例如,在您的情况下,0x00 表示成功)。由于Option_flag,每个数据块都以BSS_x 字节(块安全状态)为前缀,对于所有块来说,它似乎都是0x00。

由于您似乎对区块安全状态不感兴趣,您不妨使用不带Option_flag (flags = 0x20) 的命令:

byte[] cmd = new byte[]{
        (byte)0x20,                  
        (byte)0x23,                  
        (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00, (byte)0x00,  // placeholder for tag UID
        (byte)(offset & 0x0ff),      
        (byte)((blocks - 1) & 0x0ff)
};

然后,响应将是:

+-------+-------+-------+-------+-------+-------+- ------+-------+-------+-...-+-------+--------+-- --+--------+ |旗帜 | BLOCK_DATA_0 | BLOCK_DATA_1 | ... | BLOCK_DATA_18 | +-------+-------+-------+-------+-------+-------+- ------+-------+-------+-...-+-------+--------+-- --+--------+

因此,为了从响应中提取数据块,您可以使用:

response = Arrays.copyOfRange(response, 1, 4 * blocks);

最后,将标签 ID 解码为 UTF-8 对于 ISO/IEC 15693 标签完全没有意义。我不确定你会期望那里的值,但可能你想简单地将 ID 的字节转换为它们的十六进制表示。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-09-30
    • 1970-01-01
    • 2015-12-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多