【问题标题】:Can't receive APDU data with Arduino NFC module无法使用 Arduino NFC 模块接收 APDU 数据
【发布时间】:2014-03-24 08:34:25
【问题描述】:

我正在尝试在我的 LG G2 上使用 HCE,并通过 Elechouse NFC 模块 2.0 向 Arduino Uno 发送一些数据。

问题是nfc.inDataExchange(selectApdu, sizeof(selectApdu), response, &responseLength) 总是返回false。怎么了?

Arduino forums 上, MisterFrench 让它工作起来,我正在使用完全相同的原则做事。我从 Android HCE 示例中获取了以下内容,只是发送了一些垃圾数据:

@Override
public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) {
    Log.i(TAG, "Received APDU: " + ByteArrayToHexString(commandApdu));
    // If the APDU matches the SELECT AID command for this service,
    // send the loyalty card account number, followed by a SELECT_OK status trailer (0x9000).
    if (Arrays.equals(SELECT_APDU, commandApdu)) {

        StringBuilder stringBuilder = new StringBuilder();
        stringBuilder.append(Build.MANUFACTURER);
        stringBuilder.append("#");
        stringBuilder.append(Build.MODEL);
        stringBuilder.append(((TelephonyManager)getSystemService(Context.TELEPHONY_SERVICE)).getDeviceId());
        String data = stringBuilder.toString();
        Log.i(TAG, "Data send");

        return ConcatArrays(data.getBytes(), SELECT_OK_SW);
    } else {
        return UNKNOWN_CMD_SW;
    }
}

在 Arduino 方面,我从 Arduino 论坛获取代码并稍作修改。现在看起来像

void loop(void) {
    bool success;
    Serial.println("Waiting for an ISO14443A card");

    success = nfc.inListPassiveTarget();
    if(success) {
        Serial.println("Found something!");
        uint8_t selectApdu[] = { 
          0x00, /* CLA */
          0xA4, /* INS */
          0x04, /* P1  */
          0x00, /* P2  */
          0x05, /* Length of AID  */
          0xF2, 0x22, 0x22, 0x22, 0x22,
          0x00  /* Le  */};

        uint8_t response[256];
        uint8_t responseLength = sizeof(response);

        success = nfc.inDataExchange(selectApdu, sizeof(selectApdu), response, &responseLength);

        if(success) {
            Serial.print("RAW: ");
            for (int i = 0; i < responseLength; ) {
                Serial.print(response[i++]);
                Serial.print(" ");
            }
            Serial.println(" ");

            for (int i = 0; i < responseLength; i++) {
                Serial.print((char)response[i]);
                Serial.print(" ");
            }
            Serial.println(" ");
        }
        else{
            Serial.println("Failed sending SELECT AID"); 
        }
    }
    else {
        Serial.println("Didn't find anything!");
    }
    delay(1000);
}

我正在使用来自https://github.com/elechouse/PN532 的 Arduino UNO、NFC 库“PN532”

【问题讨论】:

  • 您的 SELECT 命令 APDU 不包含 Le 字段,但是您返回的响应 APDU 的数据长度大于零字节。在您的情况下,将命令 APDU 中的 Le 字段设置为 0x00 是有意义的。不确定这是否会导致问题。
  • @MichaelRoland 我已经添加了 Le 字段,但没有任何变化,不断收到“等待 ISO14443A 卡找到一些东西!发送 SELECT AID 失败”消息

标签: android arduino nfc apdu hce


【解决方案1】:

显然这些行会导致问题:

uint8_t response[256];
uint8_t responseLength = sizeof(response);

success = nfc.inDataExchange(selectApdu, sizeof(selectApdu), response, &responseLength);

在第一行中,您创建了一个 256 字节的数组。在下一行中,将该数组的大小分配给一个 8 位无符号整数 (uint8_t) 变量。 uint8_t 只能保存 0 到 255 (= 2^8-1) 之间的值。因此,response (= 256) 的大小将导致溢出。这导致responseLength 设置为 0(= 256 模 2^8)。因此,您输入 nfc.inDataExchange() 的响应长度太短,无法容纳任何响应。

所以使用

uint8_t response[255];
uint8_t responseLength = sizeof(response);

应该可以。

【讨论】:

  • 还有一件事不正确。我第一次把手机带到读者面前时,我得到了这个答案:“76, 71, 69, 35, 76, 71, 45, 68, 56, 48, 50, 35, 144, 0”,在 ACSII 中的意思是“LGE# LG-D802#”,这正是我想要的。但在那之后,每次我带手机时,我都会读“1, 71, 69, 35, 76, 71, 45, 68, 56, 48, 50, 35, 144, 0”或“11, 71, 69 , 35, 76, 71, 45, 68, 56, 48, 50, 35, 144, 0"。你看,第一个数字变成了 1 或 11。它一直保持到我通过重新连接 USB 电缆重新启动 arduino。重置按钮无法解决此问题。
  • 您是否更改了您在问题中发布的代码中的其他任何内容?看来至少安卓代码肯定变了……
  • 是的。我刚刚删除了检索 IMEI 的代码块,并添加了前导空格以保持所需数据不受影响(现在只更改了空格字符)。我认为问题可能出在缓冲区,因为当我将 NFC 标签带到阅读器时,它让我一直显示“1、71、69、35、76 ...”,
  • 您可能想开始一个新问题(包括当前代码部分、调试输出等)。
【解决方案2】:

这可能是题外话,但我使用的是与您在此处发布的完全相同的代码,但我使用的是 Seeed Studio 的 NFC Shield V2。我认为这可能对其他人也有帮助。我发现一旦我从这里删除了 selectApdu 数组中的最后一个字节:

uint8_t selectApdu[] = { 
      0x00, /* CLA */
      0xA4, /* INS */
      0x04, /* P1  */
      0x00, /* P2  */
      0x05, /* Length of AID  */
      0xF2, 0x22, 0x22, 0x22, 0x22,
      0x00  /* Le  */};

到这里:

uint8_t selectApdu[] = { 
          0x00, /* CLA */
          0xA4, /* INS */
          0x04, /* P1  */
          0x00, /* P2  */
          0x05, /* Length of AID  */
          0xF2, 0x22, 0x22, 0x22, 0x22};

这最终让我的三星 Note 4 可以与 Arduino 和 Seeed Studio 库提供的示例 android_hce 进行通信。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-12
    • 1970-01-01
    • 2018-01-26
    • 2015-11-20
    • 2018-09-12
    • 1970-01-01
    相关资源
    最近更新 更多