Android MIFARE NFCA源码解析 TagTechnology定义了所有标签的共有接口类 BasicTagTechnology 实现了TagTechnology的一些接口 再有具体的标签协议继承BasicTagTechnology NFC-A 遵循ISO 14443-3A协议。 关键字 ATQA Answer To Request acc. to ISO/IEC 14443-4 ATS Answer To Select acc. to ISO/IEC 14443-4 DIF Dual Interface (cards) COS Card Operating System CL Cascade Level acc. to ISO/IEC 14443-3 CT Cascade Tag, Type A n.a. not applicable NFC Near Field Communication PCD Proximity Coupling Device (“Contactless Reader”) PICC Proximity Integrated Circuit (“Contactless Card”) PKE Public Key Encryption (like RSA or ECC) REQA Request Command, Type A SAK Select Acknowledge, Type A Select Select Command, Type A RID Random ID, typically dynamically generated at Power-on Reset RFU Reserved for future use UID Unique Identifier, Type A NUID Non-Unique Identifier 当读卡器检测到了卡片就会发送REQA请求命令,在感应区内的卡片接收到REQA,将会反馈ATQA消息。 SAK的第六位表明PICC卡是否符合ISO/IEC14443-4 标准。 The bit numbering in the ISO/IEC 14443 starts with LSBit = bit 1, but not LSBit =bit 0. So one byte counts bit 1...8 instead of bit 0...7. The ISO/IEC 14443 transfers LSByte first. So e.g. 0x 00 44 (ATQA of the MFUL) is often received as 0x 44 00. ATQA ISO/IEC 14443-3 协议标准 ATQA Coding of NXP Contactless Card ICs SAK coding of NXP Contactless Card ICs 如下图可以根据ATQA,SAK,ATS判断厂家和产品的类型 举例 <string name="tag_000409">MIFARE Mini, NXP</string> <string name="tag_000408">MIFARE Classic 1k, NXP</string> <string name="tag_000218">MIFARE Classic 4k, NXP</string> <string name="tag_004218">MIFARE Classic 4k, NXP</string> <string name="tag_004400">MIFARE Ultralight, NXP</string> <string name="tag_000488">MIFARE Classic 1K, Infineon</string> getResources().getIdentifier(prefix + atqa + sak + ats, "string", getPackageName()) NfcA get(Tag tag) 获取NFCA一个实例,首先判断 tag.hasTech(TagTechnology.NFC_A) 这个TAG是否是NFC_A TAG。 然后才生成NFC A TAG实例 getAtqa() 读写器呼叫磁场内的卡片,卡片对呼叫做出应答。收到卡呼叫命令后,卡片将对命令做出应答(Answer To Request,ATQA), 告诉读写器自己是否遵守面向比特的防冲突机制, ATQA/SENS_RES 这里获取卡片应答的消息。 举例:用来判断是否是Mifare Classic tag NfcA nfca = NfcA.get(tag); byte[] atqa = nfca.getAtqa(); if (atqa[1] == 0 &&(atqa[0] == 4 || atqa[0] == (byte)0x44 ||atqa[0] == 2 || atqa[0] == (byte)0x42)) getSak() SAK/SEL_RES 返回选择命令的信息 举例: byte sak = (byte)nfca.getSak(); if (sak == 8 || sak == 9 || sak == (byte)0x18 ||sak == (byte)0x88) Transceive() Send raw NFC-A commands to the tag and receive the response. 发送命令到TAG,并接收返回值。 注意: 1:发送命令时不用增加CRC,因为系统会自动加。 2:发送命令是完整的字节。SENS_REQ3:因为是I/O操作,会发生阻塞,不用在主线程调用这个函数。 getMaxTransceiveLength() 获取最大的发送字节长度 参考文档 NfcA.java http://www.nxp.com/documents/application_note/AN10833.pdf http://nfc-tools.org/index.php?title=ISO14443A 时间 起草与2015-10-15