Brokenithm-Android/app/src/main/java/com/github/brokenithm/util/FeliCa.kt

63 lines
2.0 KiB
Kotlin

package com.github.brokenithm.util
import android.nfc.Tag
import android.nfc.tech.NfcF
import android.nfc.tech.TagTechnology
@Suppress("Unused", "MemberVisibilityCanBePrivate", "SpellCheckingInspection", "PropertyName")
class FeliCa private constructor(private val nfcF: NfcF) : TagTechnology {
private lateinit var mTag: Tag
var IDm: ByteArray? = null
private set
var PMm: ByteArray? = null
private set
val systemCode: ByteArray
get() = nfcF.systemCode
override fun connect() = nfcF.connect()
override fun isConnected() = nfcF.isConnected
override fun close() {
IDm = null
PMm = null
nfcF.close()
}
override fun getTag() = mTag
fun getMaxTransceiveLength() = nfcF.maxTransceiveLength
fun transceive(data: ByteArray): ByteArray = nfcF.transceive(data)
var timeout: Int
get() = nfcF.timeout
set(value) { nfcF.timeout = value }
private fun checkConnected() {
if (!nfcF.isConnected)
throw IllegalStateException("Call connect() first!")
}
fun poll(systemCode: Int = 0xFFFF, requestCode: Int = 0x01) {
checkConnected()
val buffer = ByteArray(6)
buffer[0] = 6
buffer[1] = FELICA_CMD_POLLING
buffer[2] = ((systemCode shr 8) and 0xff).toByte()
buffer[3] = (systemCode and 0xff).toByte()
buffer[4] = requestCode.toByte()
buffer[5] = 0
val result = nfcF.transceive(buffer)
if (result.size != 18 && result.size != 20)
throw IllegalStateException("Poll FeliCa response incorrect")
IDm = result.copyOfRange(2, 10)
PMm = result.copyOfRange(10, 18)
}
companion object {
private const val FELICA_CMD_POLLING: Byte = 0x00
fun get(tag: Tag): FeliCa? {
val realTag = NfcF.get(tag) ?: return null
return FeliCa(realTag).apply { mTag = tag }
}
}
}