首页 > 解决方案 > PN532 NFC - 从 inDataExchange 调用返回超过 256 个字节到 Android HCE

问题描述

阅读下面的最后一段,似乎有一种方法可以通过将大块数据分解成小块来发送大块数据以响应 NFC 发出 inDataExchange 调用:

3.3.7.4 大量数据的传输

链式机制

  • 从发起者到目标:发起者通过InDataExchange功能发送大量数据,252字节的数据包。发起者必须根据需要多次发送 InDataExchange 命令以传输全部数据量。目标必须根据需要多次执行 TgGetData 和 TgSetData 函数,以检索发起方发送的所有数据包。

元链机制

  • 从启动器到目标:在 InDataExchange 第一个参数中称为 MI(更多信息)的一个位向目标指示接收的数据是否是大块的一部分。在这种情况下,目标可以直接继续与 TgGetData 交换(不需要 TgSetData)。
  • 从目标到发起者:目标可以使用TgSetMetaData函数向发起者提供大量数据。发起方已发送 InDataExchange 函数。对发起者的响应是通过 TgSetMetaData 函数而不是 TgSetData 函数发送的。在这种情况下,一位向发起者指示在目标端仍有一些数据可用。发起者应继续使用 InDataExchange 功能(没有数据从发起者发送到目标)。最后一包数据将通过 TgSetData 函数传输。有关详细说明,请参阅 PN532 用户手册(参考 1)。

当我在我的 Android HCE 中对 APDU 调用进行“正常”响应时,它看起来像这样:

private static final byte[] SELECT_OK_SW = HexStringToByteArray("9000");
private static final byte[] UNKNOWN_CMD_SW = HexStringToByteArray("0000");
@Override
    public byte[] processCommandApdu(byte[] commandApdu, Bundle extras) {
        Log.d(TAG, "Received APDU: " + ByteArrayToHexString(commandApdu));
        // If the APDU matches the SELECT AID command for this service,
        // send the account name, followed by a SELECT_OK status trailer (0x9000).
        if (Arrays.equals(SELECT_APDU, commandApdu)) {
            String account="Tommyburger";
            byte[] accountBytes = account.getBytes();
            Log.d(TAG, "Sending account number: " + account);
            return ConcatArrays(accountBytes, SELECT_OK_SW);
        } else {
            Log.d(TAG, "AID didn't match");
            return UNKNOWN_CMD_SW;
        }
    }

查看 532.h 文件中的“命令常量”:

// PN532 Commands
#define PN532_COMMAND_DIAGNOSE              (0x00)
#define PN532_COMMAND_GETFIRMWAREVERSION    (0x02)
#define PN532_COMMAND_GETGENERALSTATUS      (0x04)
#define PN532_COMMAND_READREGISTER          (0x06)
#define PN532_COMMAND_WRITEREGISTER         (0x08)
#define PN532_COMMAND_READGPIO              (0x0C)
#define PN532_COMMAND_WRITEGPIO             (0x0E)
#define PN532_COMMAND_SETSERIALBAUDRATE     (0x10)
#define PN532_COMMAND_SETPARAMETERS         (0x12)
#define PN532_COMMAND_SAMCONFIGURATION      (0x14)
#define PN532_COMMAND_POWERDOWN             (0x16)
#define PN532_COMMAND_RFCONFIGURATION       (0x32)
#define PN532_COMMAND_RFREGULATIONTEST      (0x58)
#define PN532_COMMAND_INJUMPFORDEP          (0x56)
#define PN532_COMMAND_INJUMPFORPSL          (0x46)
#define PN532_COMMAND_INLISTPASSIVETARGET   (0x4A)
#define PN532_COMMAND_INATR                 (0x50)
#define PN532_COMMAND_INPSL                 (0x4E)
#define PN532_COMMAND_INDATAEXCHANGE        (0x40)
#define PN532_COMMAND_INCOMMUNICATETHRU     (0x42)
#define PN532_COMMAND_INDESELECT            (0x44)
#define PN532_COMMAND_INRELEASE             (0x52)
#define PN532_COMMAND_INSELECT              (0x54)
#define PN532_COMMAND_INAUTOPOLL            (0x60)
#define PN532_COMMAND_TGINITASTARGET        (0x8C)
#define PN532_COMMAND_TGSETGENERALBYTES     (0x92)
#define PN532_COMMAND_TGGETDATA             (0x86)
#define PN532_COMMAND_TGSETDATA             (0x8E)
#define PN532_COMMAND_TGSETMETADATA         (0x94)
#define PN532_COMMAND_TGGETINITIATORCOMMAND (0x88)
#define PN532_COMMAND_TGRESPONSETOINITIATOR (0x90)
#define PN532_COMMAND_TGGETTARGETSTATUS     (0x8A)
#define PN532_RESPONSE_INDATAEXCHANGE       (0x41)
#define PN532_RESPONSE_INLISTPASSIVETARGET  (0x4B)

看来我通常在 Android HCE 中将 TGRESPONSETOINITIATOR 命令 0x9000 作为 SELECT_OK_SW 执行。例如,要发送 1k 字节,我会将其分成 256 字节(或更小)的块,并使用 TGSETMETADATA 命令字节 0x9400 发送,除了最后一个块,它将使用 TGSETDATA 命令字节 0x8E00?有没有人这样做过?

标签: androidnfcapduhcepn532

解决方案


推荐阅读