Destroy stale channels properly
This commit is contained in:
parent
c78743f03f
commit
6451e0a0d6
|
@ -2,8 +2,14 @@ package im.angry.openeuicc.core
|
|||
|
||||
import com.truphone.lpa.LocalProfileAssistant
|
||||
|
||||
interface EuiccChannelStateManager {
|
||||
val valid: Boolean
|
||||
fun destroy()
|
||||
}
|
||||
|
||||
data class EuiccChannel(
|
||||
val slotId: Int,
|
||||
val name: String,
|
||||
val lpa: LocalProfileAssistant
|
||||
val lpa: LocalProfileAssistant,
|
||||
val stateManager: EuiccChannelStateManager
|
||||
)
|
|
@ -41,16 +41,23 @@ class EuiccChannelManager(private val context: Context) {
|
|||
private suspend fun findEuiccChannelBySlot(slotId: Int): EuiccChannel? {
|
||||
ensureSEService()
|
||||
val existing = channels.find { it.slotId == slotId }
|
||||
if (existing != null) return existing
|
||||
|
||||
var apduChannel: ApduChannel?
|
||||
apduChannel = OmapiApduChannel.tryConnectUiccSlot(seService!!, slotId)
|
||||
|
||||
if (apduChannel == null) {
|
||||
return null
|
||||
if (existing != null) {
|
||||
if (existing.stateManager.valid) {
|
||||
return existing
|
||||
} else {
|
||||
existing.stateManager.destroy()
|
||||
channels.remove(existing)
|
||||
}
|
||||
}
|
||||
|
||||
val channel = EuiccChannel(slotId, "SIM $slotId", LocalProfileAssistantImpl(apduChannel))
|
||||
var apduChannel: ApduChannel? = null
|
||||
var stateManager: EuiccChannelStateManager? = null
|
||||
OmapiApduChannel.tryConnectUiccSlot(seService!!, slotId)?.let { (_apduChannel, _stateManager) ->
|
||||
apduChannel = _apduChannel
|
||||
stateManager = _stateManager
|
||||
} ?: return null
|
||||
|
||||
val channel = EuiccChannel(slotId, "SIM $slotId", LocalProfileAssistantImpl(apduChannel), stateManager!!)
|
||||
channels.add(channel)
|
||||
return channel
|
||||
}
|
||||
|
@ -77,6 +84,10 @@ class EuiccChannelManager(private val context: Context) {
|
|||
get() = channels.toList()
|
||||
|
||||
fun invalidate() {
|
||||
for (channel in channels) {
|
||||
channel.stateManager.destroy()
|
||||
}
|
||||
|
||||
channels.clear()
|
||||
seService?.shutdown()
|
||||
seService = null
|
||||
|
|
|
@ -14,12 +14,20 @@ class OmapiApduChannel(private val channel: Channel) : ApduChannel {
|
|||
private const val TAG = "OmapiApduChannel"
|
||||
private val APPLET_ID = byteArrayOf(-96, 0, 0, 5, 89, 16, 16, -1, -1, -1, -1, -119, 0, 0, 1, 0)
|
||||
|
||||
fun tryConnectUiccSlot(service: SEService, slotId: Int): OmapiApduChannel? {
|
||||
fun tryConnectUiccSlot(service: SEService, slotId: Int): Pair<ApduChannel, EuiccChannelStateManager>? {
|
||||
try {
|
||||
val reader = service.getUiccReader(slotId + 1) // slotId from telephony starts from 0
|
||||
val session = reader.openSession()
|
||||
val channel = session.openLogicalChannel(APPLET_ID) ?: return null
|
||||
return OmapiApduChannel(channel)
|
||||
val stateManager = object : EuiccChannelStateManager {
|
||||
override val valid: Boolean
|
||||
get() = channel.isOpen
|
||||
|
||||
override fun destroy() {
|
||||
channel.close()
|
||||
}
|
||||
}
|
||||
return Pair(OmapiApduChannel(channel), stateManager)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to open eUICC channel for slot ${slotId}, skipping")
|
||||
Log.e(TAG, Log.getStackTraceString(e))
|
||||
|
|
Loading…
Reference in New Issue