Чтение 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 4231003233343500 3631383100353036 3400313630320032 3031360031363033 0032303136003136 3032003230313800 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. Я не уверен, какое значение вы ожидаете, но, вероятно, вы хотели просто преобразовать байты идентификатора в их шестнадцатеричное представление.