標籤:
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
Android MIFARE NFCA源碼解析