3

I'm trying to build a C++ wrapper around libnfc to make a communication between my Android and the PN532 RFID module.

This helped me a lot: http://nfc-tools.org/index.php/Libnfc:APDU_example

This code is meant to send an APDU command where the body is contained in message (I'm not sending any header bytes etc.) and read the response into response.

Problem: If message exceeds 262 characters then I get a buffer overflow detected error. Otherwise it works perfectly well. I don't even think the error is thrown by the NFC library.

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;
}
4

1 回答 1

1

The limit of 262 bytes is a hard limit imposed the PN532 NFC chip. This is the maximum size of the raw data that can be sent (and received) in one InDataExchange command. libnfc explicitly enforces this limit for the method nfc_initiator_transceive_bytes() (see the definition of abtCmd in pn53x_initiator_transceive_bytes() and the definition of PN53x_EXTENDED_FRAME__DATA_MAX_LEN).

What you could do to overcome this limit, is to compose your own ISO/IEC 14443-4 blocks (using InCommunicateThru, i.e. nfc_initiator_transceive_bytes() with m_nfcDevice->bEasyFraming turned off. While each frame would still be limited to 263 bytes (the PN532 actually allows 264 bytes for InCommunicateThru but libnfc seems to limit this to 263 bytes), you can then pack your extended length APDUs into multiple ISO/IEC 14443-4 I-blocks. However, you would need to handle the whole ISO/IEC 14443-4 framing on your own (which means that you also have to take care of receive acknowledgements, etc.)

Finally, since the other communication endpoint is an Android device: Many Android devices do not support extended length APDUs. Consequently, even if you send longer APDUs, you might not be able to receive and process them on the Android side. Also, be aware that you should send proper APDUs conforming to the structures defined in ISO/IEC 7816-4 (i.e. APDUs with valid header and lengths fields), otherwise you might run into issues when talking to some devices.

于 2017-12-19T10:54:02.350 回答