无法使用 nfc_initiator_transceive_bytes() 通过 libnfc 发​​送大型 APDU 命令

Cannot send large APDU commands with libnfc using nfc_initiator_transceive_bytes()

我正在尝试围绕 libnfc to make a communication between my Android and the PN532 RFID 模块构建一个 C++ 包装器。

这对我帮助很大:http://nfc-tools.org/index.php/Libnfc:APDU_example

此代码旨在发送一个 APDU 命令,其中 body 包含在 message 中(我没有发送任何 header 字节等)并将响应读入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;
}

262 字节的限制是 PN532 NFC 芯片的硬性限制。这是可以在一个 InDataExchange 命令中发送(和接收)的原始数据的最大大小。 libnfc 对方法 nfc_initiator_transceive_bytes() 明确强制执行此限制(请参阅 the definition of abtCmd in pn53x_initiator_transceive_bytes() and the definition of PN53x_EXTENDED_FRAME__DATA_MAX_LEN)。

你可以做些什么来克服这个限制,就是组成你自己的 ISO/IEC 14443-4 块(使用 InCommunicateThru,即 nfc_initiator_transceive_bytes() 并关闭 m_nfcDevice->bEasyFraming。虽然每一帧仍将限制为 263 字节(PN532 实际上允许 InCommunicateThru 为 264 字节,但 libnfc 似乎将其限制为 263 字节),然后您可以将扩展长度的 APDU 打包成多个 ISO/IEC 14443-4 I-blocks . 但是,您需要自己处理整个 ISO/IEC 14443-4 帧(这意味着您还必须处理接收确认等)

最后,由于另一个通信端点是 Android 设备:许多 Android 设备不支持扩展长度的 APDU。因此,即使您发送更长的 APDU,您也可能无法在 Android 端接收和处理它们。另外,请注意您应该发送符合 ISO/IEC 7816-4 中定义的结构的正确 APDU(即具有有效 header 和长度字段的 APDU),否则您可能 运行 遇到问题与某些设备通话。