无法使用 nfc_initiator_transceive_bytes() 使用 libnfc 发送大型 APDU 命令
Posted
技术标签:
【中文标题】无法使用 nfc_initiator_transceive_bytes() 使用 libnfc 发送大型 APDU 命令【英文标题】:Cannot send large APDU commands with libnfc using nfc_initiator_transceive_bytes() 【发布时间】:2017-12-14 19:39:46 【问题描述】:我正在尝试围绕libnfc 构建一个C++ 包装器,以便在我的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;
【问题讨论】:
您可能需要寻找对扩展 APDU 的支持 - 问题可能是,您的 Android 设备不支持数据长度 > 255 字节的 APDUcla[1] + ins[1] + param[2] + lc[1] + data[255] + le[1] = 261 bytes
【参考方案1】:
262 字节的限制是对 PN532 NFC 芯片施加的硬限制。这是可以在一个 InDataExchange 命令中发送(和接收)的原始数据的最大大小。 libnfc 明确地对方法 nfc_initiator_transceive_bytes()
强制执行此限制(请参阅 the definition of abtCmd
in pn53x_initiator_transceive_bytes()
和 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 块中。但是,您需要处理整个 ISO/自行构建 IEC 14443-4 框架(这意味着您还必须注意接收确认等)
最后,由于另一个通信端点是 Android 设备:许多 Android 设备不支持扩展长度的 APDU。因此,即使您发送更长的 APDU,您也可能无法在 Android 端接收和处理它们。另外,请注意,您应该发送符合 ISO/IEC 7816-4 中定义的结构的正确 APDU(即具有有效标头和长度字段的 APDU),否则在与某些设备通信时可能会遇到问题。
【讨论】:
感谢您提供如此详细的回答;)好吧,我想我将不得不发送多个块并自己实现协议 @OmarAflak 更简单的选择可能是将数据拆分到多个 APDU 并在 APDU 之上实现您的协议。在这种情况下,您不需要太在意时间(如果您自己处理 ISO/IEC 14443-4 传输,则需要这样做)。以上是关于无法使用 nfc_initiator_transceive_bytes() 使用 libnfc 发送大型 APDU 命令的主要内容,如果未能解决你的问题,请参考以下文章
无法使用 StorageClass 配置卷 - 无法获取存储帐户的存储密钥
Worklight Studio 和本地开发,有时无法使用 Java 类,有时无法使用 HTML 文件
Ubuntu 80端口无法使用-非root用户无法使用1024以下端口