NFC Tag에서 얻을 수 있는 정보를 json 문자열 포맷으로 반환하는 함수를 만들어보았다.
테그 정보 :
- UID (고유 ID): tag.id에서 추출한 고유 식별자.
- Tech List: 태그가 지원하는 모든 기술 목록 (tag.techList).
- NfcA (ISO 14443-3A): ATQA, SAK, 최대 전송 길이, 타임아웃 정보.
- IsoDep (ISO 14443-4): 역사적 바이트(historicalBytes), 고층 응답(hiLayerResponse), 최대 전송 길이, 타임아웃 정보.
- NfcB (ISO 14443-3B): 응용 데이터, 프로토콜 정보, 최대 전송 길이.
- NfcF (Felica): 제조사 정보, 시스템 코드, 최대 전송 길이, 타임아웃.
- NfcV (ISO 15693): 응답 플래그, DSFID, 최대 전송 길이.
- MifareClassic: 타입, 크기, 섹터 및 블록 수.
- MifareUltralight: 타입 정보 (Ultralight, Ultralight C).
구현 함수는 다음과 같다.
fun readTagDetailsAsJson(tag: Tag): String {
val tagInfo = mutableMapOf<String, Any>()
// UID 정보 (태그 고유 ID)
tagInfo["uid"] = tag.id.joinToString("") { String.format("%02X", it) }
// 기술 스택 나열 (태그가 지원하는 모든 기술들)
tagInfo["techList"] = tag.techList.joinToString()
// NfcA (ISO 14443-3A) 정보
val nfcA = NfcA.get(tag)
if (nfcA != null) {
tagInfo["NfcA"] = mapOf(
// ATQA: Answer to Request Type A. 태그가 리더기에 응답할 때 사용하는 정보
"atqa" to nfcA.atqa.joinToString("") { String.format("%02X", it) },
// SAK: Select Acknowledge. 태그가 리더기에 제공하는 지원 기능 정보
"sak" to String.format("%02X", nfcA.sak),
// 한 번에 보낼 수 있는 최대 전송 길이 (바이트 단위)
"maxTransceiveLength" to nfcA.maxTransceiveLength,
// 통신 타임아웃 시간 (밀리초 단위)
"timeout" to nfcA.timeout
)
}
// IsoDep (ISO 14443-4) 정보
val isoDep = IsoDep.get(tag)
if (isoDep != null) {
tagInfo["IsoDep"] = mapOf(
// Historical Bytes: 태그가 초기 통신 설정 시 리더기에 제공하는 추가 정보
"historicalBytes" to (isoDep.historicalBytes?.joinToString("") { String.format("%02X", it) } ?: "N/A"),
// Higher Layer Response: 고급 프로토콜에 대한 응답 정보
"hiLayerResponse" to (isoDep.hiLayerResponse?.joinToString("") { String.format("%02X", it) } ?: "N/A"),
// 한 번에 전송할 수 있는 최대 데이터 길이 (바이트 단위)
"maxTransceiveLength" to (isoDep.maxTransceiveLength.toString() ?: "N/A"),
// 통신 타임아웃 시간 (밀리초 단위)
"timeout" to isoDep.timeout
)
}
// NfcB (ISO 14443-3B) 정보
val nfcB = NfcB.get(tag)
if (nfcB != null) {
tagInfo["NfcB"] = mapOf(
// Application Data: 태그의 애플리케이션과 관련된 데이터
"applicationData" to (nfcB.applicationData?.joinToString("") { String.format("%02X", it) } ?: "N/A"),
// Protocol Info: 태그가 제공하는 프로토콜 정보
"protocolInfo" to (nfcB.protocolInfo?.joinToString("") { String.format("%02X", it) } ?: "N/A")
)
}
// NfcF (Felica, JIS 6319-4) 정보
val nfcF = NfcF.get(tag)
if (nfcF != null) {
tagInfo["NfcF"] = mapOf(
// 제조사 코드
"manufacturer" to (nfcF.manufacturer?.joinToString("") { String.format("%02X", it) } ?: "N/A"),
// 시스템 코드
"systemCode" to (nfcF.systemCode?.joinToString("") { String.format("%02X", it) } ?: "N/A"),
// 한 번에 전송할 수 있는 최대 데이터 길이 (바이트 단위)
"maxTransceiveLength" to nfcF.maxTransceiveLength.toString(),
// 통신 타임아웃 시간 (밀리초 단위)
"timeout" to nfcF.timeout.toString()
)
}
// NfcV (ISO 15693) 정보
val nfcV = NfcV.get(tag)
if (nfcV != null) {
tagInfo["NfcV"] = mapOf(
// 응답 플래그
"responseFlags" to String.format("%02X", nfcV.responseFlags),
// DSFID (Data Storage Format Identifier)
"dsfId" to String.format("%02X", nfcV.dsfId),
// 한 번에 전송할 수 있는 최대 데이터 길이 (바이트 단위)
"maxTransceiveLength" to nfcV.maxTransceiveLength
)
}
// NfcBarcode (Type V or JIS 6319-4) 정보 - maxTransceiveLength 지원 없음
val nfcBarcode = NfcBarcode.get(tag)
if (nfcBarcode != null) {
tagInfo["NfcBarcode"] = mapOf(
// 바코드 타입 정보 (Type V or JIS 6319-4)
"type" to nfcBarcode.type
)
}
// MifareClassic 정보
val mifareClassic = MifareClassic.get(tag)
if (mifareClassic != null) {
tagInfo["MifareClassic"] = mapOf(
// MifareClassic 타입 (Classic, Plus, Pro)
"type" to when (mifareClassic.type) {
MifareClassic.TYPE_CLASSIC -> "Classic"
MifareClassic.TYPE_PLUS -> "Plus"
MifareClassic.TYPE_PRO -> "Pro"
else -> "Unknown"
},
// MifareClassic 메모리 크기
"size" to mifareClassic.size,
// 섹터 개수
"sectorCount" to mifareClassic.sectorCount,
// 블록 개수
"blockCount" to mifareClassic.blockCount
)
}
// MifareUltralight 정보
val mifareUltralight = MifareUltralight.get(tag)
if (mifareUltralight != null) {
tagInfo["MifareUltralight"] = mapOf(
// MifareUltralight 타입 (Ultralight, Ultralight C)
"type" to when (mifareUltralight.type) {
MifareUltralight.TYPE_ULTRALIGHT -> "Ultralight"
MifareUltralight.TYPE_ULTRALIGHT_C -> "Ultralight C"
else -> "Unknown"
}
)
}
// JSON 형태로 변환하여 반환
return JSONObject(tagInfo as Map<*, *>).toString()
}
결과값 로그 출력 값은 아래와 같다.
로그 출력 값 예 :
{
"uid": "641B27A2B67881", // 시리얼 번호
"techList": "android.nfc.tech.IsoDep, android.nfc.tech.NfcA", // 태그에서 지원하는 NFC 기술 목록
"NfcA": { // NfcA (ISO/IEC 14443-3A) 기술에 대한 정보
"atqa": "4800", // Answer to Request, Type A (ATQA) 값
"sak": "20", // Select Acknowledge (SAK) 값
"maxTransceiveLength": 253, // NFC 통신에서 한 번에 전송할 수 있는 최대 데이터 길이(바이트)
"timeout": 618 // 통신 타임아웃 시간(밀리초)
},
"IsoDep": { // IsoDep (ISO/IEC 14443-4) 기술에 대한 정보
"historicalBytes": "", // NFC 태그가 최초로 통신을 시작할 때 제공하는 부가적인 정보를 포함
"hiLayerResponse": "N\/A", // 태그가 고급 프로토콜을 지원하는 경우 제공
"maxTransceiveLength": "65279",// IsoDep에서 한 번에 전송할 수 있는 최대 데이터 길이
"timeout": 618 // 통신 타임아웃 시간(밀리초)
}
}