如何避免异常" Transceive failed"从NFC标签类型A读取数据时?

时间:2017-11-14 11:40:03

标签: android nfc

我正在开发一款应该可以模拟任何类型的NFC标签的应用程序。从零块和页面标记中读取数据类型" NFC类型A"和" MIFARE Ultralight" (我所拥有的标签类型)使用方法:

nfcA.transceive()

mifareUltralight.readPages()

其他数据无法读取,但会抛出异常" Transceive失败"。

以下是适当方法的代码。对于NfcA:

private static ArrayList<IdNameValue> readeNfcADataset(final Tag tag, final Context cxt) {

    String excMsg = "";
    ArrayList<IdNameValue> dataSet = new ArrayList<>();
    NfcA nfcA = NfcA.get(tag);

    if (nfcA != null) {

        dataSet.add(new IdNameValue(cxt.getString(R.string.atqa) + " ",
                "0x" + byteArrayToHexString(nfcA.getAtqa())));
        dataSet.add(new IdNameValue(cxt.getString(R.string.sak) + " ",
                "0x" + shortToHexString(nfcA.getSak())));

        byte blockNumber = 0x00;
        int bytesNumber = 1, pagesNumber = 16, counter = 0;
        byte[][] bytes = new byte[pagesNumber][bytesNumber];

        excMsg = "_________________________________________________\n" +
                cxt.getString(R.string.picc_compliant_with_iso_iec_14443_3A_fnca) + ":";
        Log.i(TAG, excMsg);

        for (int i = 0; i < pagesNumber; i++) {

            excMsg = "";
            while (!nfcA.isConnected()) {
                try {
                    nfcA.connect();
                    excMsg = cxt.getString(R.string.connecting_to_tag_has_been_created);
                    Log.i(TAG, 109 + ": " + excMsg);

                    bytes[i] = nfcA.transceive(new byte[]{
                            (byte) 0x30,  // READ
                            (byte) (blockNumber & 0x0FF)
                    });
                    excMsg = cxt.getString(R.string.made_to_read_data_from_a_block)
                            + Integer.toHexString(blockNumber);
                    Log.i(TAG, 117 + ": " + excMsg);
                    if (nfcA.isConnected()) nfcA.close();
                    excMsg += cxt.getString(R.string.tag_has_been_closed);
                    break;
                } catch (IOException e) {
                    counter++;
                    excMsg = e.getMessage() + ":> " + (excMsg.equals("") ?
                            cxt.getString(R.string.the_connection_tag_is_not_created) :
                            (excMsg.contains(cxt.getString(R.string.connecting_to_tag_has_been_created)) ||
                                    excMsg.contains(cxt.getString(R.string.made_to_read_data_from_a_page))) ?
                                    "Failed to read data from a tag block: "
                                            + Integer.toHexString(blockNumber) :
                                    cxt.getString(R.string.error_closing_tag));
                    Log.e(TAG, 130 + ": " + excMsg);
                }

                if (nfcA.isConnected()) try {
                    nfcA.close();
                } catch (IOException e1) {
                    excMsg += (":> " + e1.getMessage());
                    Log.e(TAG, 137 + ": " + excMsg);
                }

                if (counter > 9) {
                    excMsg = cxt.getString(R.string.the_number_of_connection_attempts_exceeded_the_number_of_ten);

                    Log.e(TAG, 143 + ": " + excMsg);
                    break;
                }
            }
            counter = 0;
            blockNumber += (byte) bytes[i].length;
        }

        if (excMsg.equals(cxt.getString(R.string.the_number_of_connection_attempts_has_exceeded_one_hundred))) {
            dataSet.add(new IdNameValue("Error", " reading the data tag"));
            return dataSet;
        }

        dataSet.add(new IdNameValue("Page", "    0    1    2    3"));

        String name = "";
        String value = "";
        for (int i = 0; i < pagesNumber; i++) {
            if (!value.equals("")) dataSet.add(new IdNameValue(name, value));
            name = (i > 9 ? " " : "    ") + String.valueOf(i) + "   ";
            value = "";
            for (int j = 0; j < bytes[i].length; j++) {
                value += ("  " + byteToHexString(bytes[i][j]));
            }
        }
        dataSet.add(new IdNameValue(name, value));
        return dataSet;
    }
    return dataSet;
}

对于MifareUltraligh:

private static ArrayList<IdNameValue> readeMifareUltralightDataset(final Tag tag, final Context cxt) {

    MifareUltralight mifareUltralight = MifareUltralight.get(tag);
    String excMsg = "";
    int bytesNumber = 1, pagesNumber = 4, counter = 0, startBlock;
    byte[][] bytes = new byte[pagesNumber][bytesNumber];
    startBlock = 0x00;

    excMsg = "_________________________________________________\n" +
            cxt.getString(R.string.mifare_ultralight_or_ultralight_c) + ":";
    Log.i(TAG, excMsg);

    for (int i = 0; i < pagesNumber; i++) {

        while (!mifareUltralight.isConnected()) {
            excMsg = "";
            try {
                mifareUltralight.connect();
                excMsg = cxt.getString(R.string.connecting_to_tag_has_been_created);
                Log.i(TAG, 201 + ": " + excMsg);

                bytes[i] = mifareUltralight.readPages(startBlock);
                excMsg = cxt.getString(R.string.done_reading_pages_twice_blocks)
                        + Integer.toHexString(startBlock) + " - "
                        + Integer.toHexString((startBlock + bytes[i].length) - 1);
                Log.i(TAG, 207 + ": " + excMsg);
                if (mifareUltralight.isConnected()) mifareUltralight.close();
                excMsg = cxt.getString(R.string.tag_has_been_closed);
                Log.i(TAG, 210 + ": " + excMsg);
                break;
            } catch (IOException e) {
                counter++;
                excMsg = e.getMessage() + ":> " + (excMsg.equals("") ?
                        cxt.getString(R.string.the_connection_tag_is_not_created) :
                        (excMsg.contains(cxt.getString(R.string.connecting_to_tag_has_been_created)) ||
                                excMsg.contains(cxt.getString(R.string.done_reading_pages_twice_blocks)) ?
                                "Failed to read page from tag blocks: "
                                        + Integer.toHexString(startBlock) + " - "
                                        + Integer.toHexString(startBlock + bytes[i].length - 1) :
                                cxt.getString(R.string.error_closing_tag)));
                Log.e(TAG, 222 + ": " + excMsg);
            }

            if (mifareUltralight.isConnected()) try {
                mifareUltralight.close();
                break;
            } catch (IOException e) {
                excMsg = (":> " + e.getMessage());
                Log.e(TAG, 230 + ": " + excMsg);
            }

            if (counter > 9) {
                excMsg = cxt.getString(R.string.the_number_of_connection_attempts_exceeded_the_number_of_ten);
                Log.e(TAG, 236 + ": " + excMsg);
                break;
            }
        }
        counter = 0;
        startBlock += bytes[i].length;
    }

    ArrayList<IdNameValue> dataSet = new ArrayList<>();
    if (excMsg.equals(cxt.getString(R.string.the_number_of_connection_attempts_has_exceeded_one_hundred))) {
        dataSet.add(new IdNameValue("Error", " reading the data tag"));
        return dataSet;
    }

    dataSet.add(new IdNameValue("Page", "    0    1    2    3"));

    int n = -1;
    String name = "";
    String value = "";
    for (int i = 0; i < pagesNumber; i++) {
        for (int j = 0; j < bytes[i].length; j++) {
            if (j % 4 == 0) {
                n++;
                if (!value.equals("")) dataSet.add(new IdNameValue(name, value));
                name = (n > 9 ? " " : "    ") + String.valueOf(n) + "   ";
                value = "";
            }
            value += ("  " + byteToHexString(bytes[i][j]));
        }
    }
    dataSet.add(new IdNameValue(name, value));
    return dataSet;
}

它会对生成的日志进行分段:

...cardreader I/TagController: _________________________________________________
                               PICC compliant with ISO/IEC 14443-3A (NFCA):
...cardreader I/TagController: 109: The connecting to tag has been created
...cardreader I/TagController: 117: Made to read data from a block: 0
...cardreader I/TagController: 109: The connecting to tag has been created
...cardreader E/TagController: 130: Transceive failed:> Failed to read data from a tag block: 10
...cardreader I/TagController: 109: The connecting to tag has been created
...cardreader E/TagController: 130: Transceive failed:> Failed to read data from a tag block: 10
...........................................................
...cardreader I/TagController: 109: The connecting to tag has been created
...cardreader E/TagController: 130: Transceive failed:> Failed to read data from a tag block: 1e
...cardreader E/TagController: 143: The number of connection attempts exceeded the number of ten.
...cardreader I/TagController: _________________________________________________
                               MIFARE Ultralight or Ultralight C:
...cardreader I/TagController: 201: The connecting to tag has been created
...cardreader I/TagController: 207: Done reading pages twice blocks:0 - f
...cardreader I/TagController: 210: Tag has been closed
...cardreader I/TagController: 201: The connecting to tag has been created
...cardreader E/TagController: 222: Transceive failed:> Failed to read page from tag blocks: 10 - 10
...cardreader I/TagController: 201: The connecting to tag has been created
...cardreader E/TagController: 222: Transceive failed:> Failed to read page from tag blocks: 11 - 11
...cardreader I/TagController: 201: The connecting to tag has been created
...cardreader E/TagController: 222: Transceive failed:> Failed to read page from tag blocks: 12 - 12

剩余块中的数据可用的事实显示了输出端口监视程序&#34; Arduino 1.8.5&#34;:

Card UID: 04 3A 31 02 54 2E 82
Card SAK: 00
PICC type: MIFARE Ultralight or Ultralight C
Page  0  1  2  3
  0   04 3A 31 87
  1   02 54 2E 82
  2   FA 48 F0 00
  3   FF FF FF FC
  4   45 D9 B0 49
  5   9E 6A 2D 00
  6   1E 82 00 00
  7   1E 82 00 00
  8   1E 7E 05 00
  9   40 00 08 09
 10   B7 DD DB FF
 11   1E 7E 98 48
 12   1E 7E 05 00
 13   40 00 08 09
 14   B7 DD DB FF
 15   1E 7E 98 48

在下面的屏幕截图中,应用程序演示了标签允许读取类型,技术和UID上的数据:   The output data read from the label on its type, technology, and UID

下面显示了从标签读取的输出,前16位数据。 对于NFC A型:   The output read from the data labels (for NFC type A)

对于MIFARE Ultralight:   The output read from the data labels (for MIFARE Ultralight) 可以看出,系统只读取第一个16个字节。可能有什么不对?请任何想法。

1 个答案:

答案 0 :(得分:0)

长期查看文档,即"MF0ICU1 MIFARE Ultralight contactless single-ticket IC" / Rev. 3.9 — 23 July 2014 #028639"MF0ICU2 MIFARE Ultralight C" / Rev. 3.2 — 19 May 2009 #171432,最终了解问题:块寻址中的所有salt都提供给命令输入READE。类型标签NFCA的数字块的计算应如下所示:

blockNumber = (byte) (i * 4);

和标签类型Mifare Ultralight:

startBlock = i * 4;

然后一切都开始了。