我正在开发一款应该可以模拟任何类型的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个字节。可能有什么不对?请任何想法。
答案 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;
然后一切都开始了。