1

我们有一些过去使用 RFID 阅读器读取的 ISO15693 标签。今天我开始在 Android 上开发一个示例应用程序,以使用NfcVAndroid 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�</p>

数据(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。

4

1 回答 1

3

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

您发送参数化的命令 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 的字节转换为它们的十六进制表示。

于 2016-11-23T10:08:45.513 回答