Чтение RFID-метки ISO15693 через Android NFC приводит к некорректному выводу данных

У нас есть несколько тегов 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): e1ead 12345678 5000 00B1 2345 6181 5064 1602 2016 1603 2016 1602 2018001188990002092016

Байты данных в шестнадцатеричном представлении:

0000316561640031 3233340035363738 0035303030003030 42310032333‌43500 363138310035303‌6 3400313630320032 303‌1360031363033 0032303‌136003136 30320032303‌13800 30303131003838332 39303030303 300 393030303 300 930 3003030

Теперь часть этих данных верна, но я не уверен, почему эти символы " " присутствуют. ID тега тоже не верный.

Отдельно я попытался преобразовать байтовый массив 'response' и ID тега в шестнадцатеричную строку, а затем в ASCII с тем же результатом.

1 ответ

Решение

Полученное вами значение является ожидаемым ответом на отправляемую команду:

Вы отправляете команду READ MULTIPLE BLOCKS (код команды 0x23) для чтения 19 блоков, начиная со смещения 0. Размер блока вашего тега составляет 4 байта.

Кроме того, вы указываете байт флагов 0x60, который преобразуется в флаги Address_flag и Option_flag. Address_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);

Наконец, декодирование идентификатора тега в UTF-8 не имеет смысла для тегов ИСО / МЭК 15693. Я не уверен, какое значение вы ожидаете, но, вероятно, вы хотели просто преобразовать байты идентификатора в их шестнадцатеричное представление.

Другие вопросы по тегам