Чтение метки ISO15693 RFID через 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;
            }
        }
    }
}

Выход

Идентификатор тега (в кодировке UTF-8): {��WP�

Данные (в кодировке UTF-8): �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

Теперь часть этих данных верна, но я не уверен, почему там есть эти символы «�». Идентификатор тега также неверен.

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


person ibrahim    schedule 22.11.2016    source источник
comment
возможно, они записывают это в метку RFID без использования UTF-8   -  person Randyka Yudhistira    schedule 22.11.2016
comment
Определенно старое приложение RFID использует UTF-8 при чтении кода ниже из старого приложения: result = byteArray != null ? новая строка (byteBuf.array(), UTF-8): ноль;   -  person ibrahim    schedule 22.11.2016
comment
попробуйте Latin-1 вместо UTF-8   -  person Randyka Yudhistira    schedule 22.11.2016
comment
Идентификатор тега, безусловно, не является чем-то, что вы могли бы разумно интерпретировать как строку UTF-8. Что касается остальных данных: может ли быть так, что в UTF-8 закодированы только части блоков? Также вы уверены, что данные начинаются с блока 0? Вы также можете показать нам шестнадцатеричное представление этих байтовых массивов, и, поскольку у вас есть код какого-то старого приложения (которое, кажется, работает), вы можете захотеть раскрыть соответствующие фрагменты кода (которые выполняют фактическое чтение и интерпретация) этого другого приложения, а также...   -  person Michael Roland    schedule 22.11.2016
comment
Ах, и, конечно же, хочу удалить первый байт ответа (который является байтом флагов), чтобы преобразовать только поле данных ответа в строку UTF-8.   -  person Michael Roland    schedule 22.11.2016
comment
Да, данные начинаются с блока 0. Вот как интерпретируются данные: 1 = Серийный номер заголовка = ead123456785 Каталог = 00000B123456 и т. д. Данные извлекаются правильно, но имеют ? характер повсюду.   -  person ibrahim    schedule 23.11.2016
comment
The hex string is equal to (000031656164003132333400353637380035303030003030423100323334350036313831003530363400313630320032303136003136303300323031360031363032003230313800303031310038383939003030303200303932300031360000).   -  person ibrahim    schedule 23.11.2016
comment
Старое приложение использует считыватель ID Blue HF и ID Blue SDK для Android для чтения и записи тегов ISO 15693. У меня нет кода для этого, но у меня есть документация по приложению.   -  person ibrahim    schedule 23.11.2016
comment
Я установил приложение RFID NFC Tool из магазина Google на свое устройство и прочитал метку. Полученная шестнадцатеричная строка 31 65 61 64 31 32 33 34 35 36 37 38 35 30 30 30 30 30 42 31 32 33 34 35 36 31 38 31 ... и т. д. «00» недоступна часть блоков читать   -  person ibrahim    schedule 23.11.2016


Ответы (1)


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

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

Кроме того, вы указываете байт флагов 0x60, который преобразуется в флаги Address_flag и Option_flag. Address_flag делает команду адресованной (т. е. вы должны указать UID целевого тега, что вы и делаете правильно). Option_flag заставляет тег возвращать статус безопасности блока в дополнение к самим данным блока. Следовательно, ответ от вашего тега выглядит так:

+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-------+-...-+--------+-------+-------+-------+-------+
| FLAGS | 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)
};

Тогда ответ будет таким:

+-------+-------+-------+-------+-------+-------+-------+-------+-------+-...-+-------+-------+-------+-------+
| FLAGS | BLOCK_DATA_0                  | BLOCK_DATA_1                  | ... | BLOCK_DATA_18                 | 
+-------+-------+-------+-------+-------+-------+-------+-------+-------+-...-+-------+-------+-------+-------+

Следовательно, чтобы извлечь блоки данных из ответа, вы можете использовать:

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

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

person Michael Roland    schedule 23.11.2016