// AtidRfidController.kt
package com.rfidsoftwares.atid
import android.util.Log
import com.atid.lib.dev.ATRfidManager
import com.atid.lib.dev.ATRfidReader
import com.atid.lib.dev.event.RfidReaderEventListener
import com.atid.lib.dev.rfid.type.ActionState
import com.atid.lib.dev.rfid.type.BankType
import com.atid.lib.dev.rfid.type.ConnectionState
import com.atid.lib.dev.rfid.type.ResultCode
import kotlinx.coroutines.flow.MutableSharedFlow
import kotlinx.coroutines.flow.asSharedFlow
data class AtidScannedTag(
val epc: String,
val rssi: Float,
val phase: Float,
val timestamp: Long = System.currentTimeMillis()
)
class AtidRfidController : RfidReaderEventListener {
private var reader: ATRfidReader? = null
private val _tagFlow = MutableSharedFlow<AtidScannedTag>(extraBufferCapacity = 64)
val tagFlow = _tagFlow.asSharedFlow()
companion object {
private const val TAG = "AtidRfidController"
}
fun initialize(): Boolean {
reader = ATRfidManager.getInstance()
if (reader == null) {
Log.e(TAG, "Hardware module not found or serial port busy")
return false
}
Log.i(TAG, "ATRfidReader initialized successfully")
return true
}
fun onResume() {
reader?.setEventListener(this)
ATRfidManager.wakeUp()
}
fun onPause() {
reader?.removeEventListener(this)
ATRfidManager.sleep()
}
fun onDestroy() {
reader = null
ATRfidManager.onDestroy()
}
fun startInventory(): Boolean {
val r = reader ?: return false
return try {
val res = r.startInventory()
res == ResultCode.NoError
} catch (t: Throwable) {
Log.e(TAG, "Error starting inventory", t)
false
}
}
fun stopInventory(): Boolean {
val r = reader ?: return false
return try {
val res = r.stop()
res == ResultCode.NoError
} catch (t: Throwable) {
Log.e(TAG, "Error stopping inventory", t)
false
}
}
// GS1 Gen2 Standard: Word offset 2 skips CRC (Word 0) and PC (Word 1)
fun readEpcWordPayload(offsetWords: Int = 2, lengthWords: Int = 6, passwordHex: String = "00000000"): String? {
val r = reader ?: return null
return try {
val data = r.readMemory6c(BankType.EPC, offsetWords, lengthWords, passwordHex)
data
} catch (t: Throwable) {
Log.e(TAG, "Memory read failed", t)
null
}
}
// --- RfidReaderEventListener Callbacks ---
override fun onReaderReadTag(reader: ATRfidReader?, tag: String?, rssi: Float, phase: Float) {
if (!tag.isNullOrBlank()) {
val record = AtidScannedTag(
epc = tag.trim().replace(" ", "").uppercase(),
rssi = rssi,
phase = phase
)
_tagFlow.tryEmit(record)
}
}
override fun onReaderStateChanged(reader: ATRfidReader?, state: ConnectionState?) {
Log.i(TAG, "Reader connection state: $state")
}
override fun onReaderActionChanged(reader: ATRfidReader?, action: ActionState?) {
Log.i(TAG, "Reader action state: $action")
}
override fun onReaderResult(
reader: ATRfidReader?,
code: ResultCode?,
action: ActionState?,
epc: String?,
data: String?,
rssi: Float,
phase: Float
) {
Log.d(TAG, "Reader result: code=$code action=$action epc=$epc data=$data")
}
}