Как программно определить размер памяти/номер страницы чипа NFC

Какой самый простой способ программно определить размер памяти или количество страниц чипа NFC (MIFARE Ultralight или NTAGxxx), кроме поиска конкретных номеров страниц и проверки их существования?

Есть ли какой-то конкретный байт в ATR, возвращенный или сохраненный где-то в защищенной зоне памяти чипа, который указывает, является ли это конкретным чипом NTAGxxx, или счетчиком страниц, или счетчиком байтов?


person Auras    schedule 20.02.2015    source источник


Ответы (3)


Как правило, вы можете определить это только путем тщательного снятия отпечатков пальцев и проверки с помощью команд чтения.

  1. Отпечатки пальцев: это означает, что вам потребуется база данных характеристик, характерных для производителя (например, собранная из спецификаций и, к сожалению, гораздо чаще, из эмпирических испытаний, поскольку такая информация не документируется (публично? или вообще?) для большинства тегов), по которым вы можете проверить свой тег.

  2. Зондирование:

    • Start at page 0
    • Читать страницу
    • В случае успеха: увеличить адрес чтения на 4 страницы и начать сначала
    • При ошибке: уменьшите адрес чтения на 1 и повторите попытку чтения, пока не найдете читаемый адрес.
    • В конце сектора: начать сначала со следующего сектора

    Таким образом, вы можете найти последний доступный для чтения адрес страницы, который не обязательно является «настоящим» концом памяти тега (например, в конце могут быть защищенные страницы).

Если ваши теги Ultralight и NTAG являются тегами EV1 (т. е. они реализуют набор команд Ultralight EV1), предоставьте команду GET_VERSION, которую вы можете использовать для получения информации о размере хранилища. Информация о версии в сочетании с базой данных всех существующих отпечатков тегов (вы можете получить эту информацию из спецификаций Ultraight/NTAG) позволит вам надежно1 определить тип тега и, следовательно, объем памяти .

1) За исключением некоторых поддельных чипов, продаваемых как "NTAG", которые имитируют параметры реальных чипов NTAG, но имеют объем памяти, отсутствие поддержки команд и т. д., которые не соответствуют чипу которого они имитируют параметры.

Когда дело доходит до меток NFC, которые соответствуют спецификациям работы метки NFC Forum Type 2, вы также можете полагаться на размер памяти метки, который закодирован в контейнере возможностей. Однако этот размер памяти не обязательно является размером физической памяти.

person Michael Roland    schedule 20.02.2015

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

int numberOfPages = 0;
int tagType = ulTag.getType();
if(tagType == MifareUltralight.TYPE_ULTRALIGHT) {
    numberOfPages = 16;
} else if(tagType == MifareUltralight.TYPE_ULTRALIGHT_C) {
    numberOfPages = 47;
}

getMaxTransceiveLength() должен получить максимальное количество байтов, которое может быть отправлено с помощью transceive(byte[]). Команда Transceive использует первые 3 байта для флагов, команды и номера страницы соответственно.

Нам нужно проверить, работает ли приведенный ниже код?

int totalBytes = ulTag.getMaxTransceiveLength() + 3;
int totalPages =  totalBytes / ulTag.PAGE_SIZE;
person Shihab    schedule 27.11.2018

для MIFARE ULTRALIGHT вы можете проверить версию таким образом.

public static final int OFFSET_128_BYTE =  0x025;
public static final int OFFSET_48_BYTE  =  0x010;

public static int checkType(MifareUltralight mrfid){
    int cfgOffset = -1;
    byte[] response = null;
    byte[] writeResponse = null;
    try {
        response = mrfid.transceive(new byte[]{
                (byte) 0x60 // GET_VERSION
        });
    } catch (TagLostException tle) {
        Utility.log("setPasswordAndEnable GET_VERSION, TagLostException ... ");
        return cfgOffset;
    } catch (IOException ioe) {
        Utility.log("setPasswordAndEnable GET_VERSION, IOException ... ");
        return cfgOffset;
    }
    if ((response != null) && (response.length >= 8)) {
        // success
        if ((response[0] == (byte) 0x00) && (response[1] == (byte) 0x04)) {
            // tag is from NXP
            if (response[2] == (byte) 0x03) {
                // MIFARE Ultralight
                if ((response[4] == (byte) 0x01) && (response[5] == (byte) 0x00)) {
                    // MIFARE Ultralight EV1 (V0)
                    switch (response[6]) {
                        case (byte) 0x0B:
                            // MF0UL11
                            cfgOffset = OFFSET_48_BYTE;
                            break;
                        case (byte) 0x0E:
                            // MF0UL21
                            cfgOffset = OFFSET_128_BYTE;
                            break;

                        default:
                            // unknown
                            break;
                    }
                }
            }
        }
    }
    return cfgOffset;
}
person sturi    schedule 16.01.2020