Не удается отправить большие команды APDU с libnfc, используя nfc_initiator_transceive_bytes()

Я пытаюсь создать оболочку C++ вокруг libnfc, чтобы установить связь между моим Android и PN532 модуль RFID.

Мне это очень помогло: http://nfc-tools.org/index.php/Libnfc:APDU_example

Этот код предназначен для отправки команды APDU, тело которой содержится в message (я не отправляю никаких байтов заголовка и т. д.), и чтения ответа в response.

Проблема: если message превышает 262 символа, я получаю сообщение об ошибке обнаружено переполнение буфера. В противном случае он работает отлично. Я даже не думаю, что ошибка выдается библиотекой NFC.

bool send(const std::string &message, std::string &response){
    std::vector<uint8_t> apduCmd(message.begin(), message.end());
    uint8_t *capdu = &apduCmd[0];
    size_t capdulen = apduCmd.size();
    uint8_t rapdu[10];
    size_t rapdulen = 10;

    // BUFFER OVERFLOW HERE
    int res = nfc_initiator_transceive_bytes(m_nfcDevice, capdu, capdulen, rapdu, rapdulen, 500);
    if (res<0) {
        return false;
    }

    if(res<2 || rapdu[res-2] != 0x90 || rapdu[res-1] != 0x00){
        return false;
    }

    // byteArrayToString omitting the last two bytes
    response = byteArrayToString(rapdu, 0, res-2);
    return true;
}

person Omar Aflak    schedule 14.12.2017    source источник
comment
Возможно, вам придется искать поддержку расширенного APDU - проблема может заключаться в том, что ваше устройство Android не поддерживает APDU с длиной данных > 255 байт cla[1] + ins[1] + param[2] + lc[1] + data[255] + le[1] = 261 bytes   -  person deR_Ed    schedule 17.12.2017


Ответы (1)


Ограничение в 262 байта — это жесткое ограничение, накладываемое NFC-чипом PN532. Это максимальный размер необработанных данных, которые можно отправить (и получить) в одной команде InDataExchange. libnfc явно применяет это ограничение для метода nfc_initiator_transceive_bytes() (см. >определение abtCmd в pn53x_initiator_transceive_bytes() и определение PN53x_EXTENDED_FRAME__DATA_MAX_LEN).

Что вы можете сделать, чтобы преодолеть это ограничение, так это составить свои собственные блоки ISO/IEC 14443-4 (используя InCommunicateThru, т. е. nfc_initiator_transceive_bytes() с отключенным m_nfcDevice->bEasyFraming. Хотя каждый кадр по-прежнему будет ограничен 263 байтами (в PN532 фактически разрешено 264 байта для InCommunicateThru, но libnfc, кажется, ограничивает это до 263 байт), вы можете затем упаковать свои APDU увеличенной длины в несколько I-блоков ISO/IEC 14443-4. собственный (что означает, что вы также должны позаботиться о получении подтверждений и т. д.)

Наконец, поскольку другой конечной точкой связи является устройство Android: многие устройства Android не поддерживают APDU увеличенной длины. Следовательно, даже если вы отправляете более длинные APDU, вы не сможете получить и обработать их на стороне Android. Кроме того, имейте в виду, что вы должны отправлять правильные APDU, соответствующие структурам, определенным в ISO/IEC 7816-4 (т. е. APDU с допустимыми полями заголовка и длины), иначе вы можете столкнуться с проблемами при обмене данными с некоторыми устройствами.

person Michael Roland    schedule 19.12.2017
comment
Спасибо за такой подробный ответ ;) Ну, я думаю, мне придется отправить несколько блоков и реализовать протокол самостоятельно. - person Omar Aflak; 19.12.2017
comment
@OmarAflak Вероятно, проще было бы разделить данные между несколькими APDU и реализовать свой протокол поверх APDU. В этом случае вам не нужно будет особо заботиться о времени (что вам понадобится, если вы самостоятельно обрабатываете передачу ISO/IEC 14443-4). - person Michael Roland; 19.12.2017