在某些背景下,我使用PN532用户手册中指定的In_List_Passive_Target
命令来检索终端字段中所有卡的UID。我还使用ACR122U的伪命令FF 00 00 00 04
将这些命令发送到PN532。
>> FF 00 00 00 04 D4 4A 01 00 # In_List_Passive_Target (1)
<< D5 4B 01 01 00 04 08 04 3E 58 A7 D1 # Response including UID (1)
>> FF 00 00 00 04 D4 4A 01 00 # In_List_Passive_Target (2)
<< D5 4B 01 01 00 04 08 04 9E 69 A7 D1 # Response including UID (2)
>> FF 00 00 00 04 D4 4A 01 00 # In_List_Passive_Target (3)
<< D5 4B 00 # No more cards in field (3)
既然我已经做了这些,我想一个接一个地选择这些。我可以通过在使用完一张卡(In_Deselect
)后停止它,然后使用带有其UID的In_List_Passive_Target
命令选择下一张卡来完成此操作。
然而,每次我选择一张卡时,我都想知道它返回的。这对于Java智能卡IO API来说是困难的,因为终端创建的卡对象总是同一张卡(因此返回相同的),即使我断开卡的连接,然后创建新的卡。考虑到如果我通过PN532终端命令In_Data_Exchange
与卡通信,这是正确的不同卡(而不是通过card对象可访问的旧卡),这很奇怪。我需要能够检测它是哪种类型的卡(Mifare Classic、Desfire、Ultralight等)
这是我为收集卡片创建的功能:
public static void getCardsInField()
{
cardList = new ArrayList<AbstractCard>();
Boolean loop = true;
// Card already connected to the terminal
byte[] firstCardUID = transmitADPUCommand(GET_ADDRESS);
MifareClassic firstCard = new MifareClassic(cardChannel, firstCardUID);
cardList.add(firstCard);
System.out.println(firstCard);
System.out.println(readable(card.getATR().getBytes()));
while(loop)
{
byte[] inDeselectResponse = transmitADPUCommand(IN_DESELECT); // Deselect current card
byte[] inListPassiveTargetsResponse = transmitADPUCommand(IN_LIST_PASSIVE_TARGETS); // Select a new card
System.out.println(">> " + readable(IN_LIST_PASSIVE_TARGETS));
System.out.println("<< " + readable(inListPassiveTargetsResponse));
// Trying to create a new card object for new card
try
{
card.disconnect(true);
card = cardTerminal.connect("*");
cardChannel = card.getBasicChannel();
}
catch (CardException e)
{
e.printStackTrace();
}
if (Arrays.equals(inListPassiveTargetsResponse, IN_LIST_PASSIVE_TARGET_RESPONSE_NO_TARGETS)) // no more targets
{
loop = false;
}
else
{
byte[] loopCardUID = extractUID(inListPassiveTargetsResponse);
MifareClassic loopCard = new MifareClassic(cardChannel, loopCardUID);
cardList.add(loopCard);
System.out.println(loopCard);
System.out.println(readable(card.getATR().getBytes())); // this should be different ATR but it is the old cards atr
}
}
}
非接触式卡没有(重置答案)。仅由接触卡产生(ISO/IEC 7816-3响应于复位引脚的去断言)。此外,PC/SC(基于卡的某些参数)模拟非接触式卡的,因为PC/SC主要是为接触式卡设计的,因此,PC/SC API期望可用。
非接触式卡具有其他值。例如,基于ISO/IEC 14443 Type a的卡具有ATQA(SENS_RES)、SAK(SEL_RES)、UID(NFCID1),并且可能具有ATS(接近)。基于ISO/IEC 14443 B型的非接触式卡具有类似的值。
响应InListPassiveTarget命令,您可以获得识别卡类型所需的所有信息:
Card 1: D5 4B 01 01 00 04 08 04 3E 58 A7 D1
Card 2: D5 4B 01 01 00 04 08 04 9E 69 A7 D1
对于卡1,此数据解码为:
- ATQA(SENS_RES)=
00 04
- SAK(SEL_RES)=
08
- UID(NFCID1)=
3E 58 A7 D1
- ATS=无
对于卡2,此数据解码为:
- ATQA(SENS_RES)=
00 04
- SAK(SEL_RES)=
08
- UID(NFCID1)=
9E 69 A7 D1
- ATS=无
因此,两张卡都具有ATQA=00 04
和SAK=08
,这意味着它们很可能是MIFARE Classic 1K或MIFARE Plus。
请参阅MIFARE类型识别程序,以获取用于识别NXP的ISO/IEC 14443 a类卡的值的综合列表。