forked from PeterCxy/OpenEUICC
Compare commits
3 commits
Author | SHA1 | Date | |
---|---|---|---|
2cda633fd0 | |||
7db1c1ea9d | |||
d46461bd2d |
1 changed files with 90 additions and 75 deletions
|
@ -11,12 +11,14 @@ import net.typeblog.lpac_jni.LocalProfileInfo
|
||||||
import net.typeblog.lpac_jni.LocalProfileNotification
|
import net.typeblog.lpac_jni.LocalProfileNotification
|
||||||
import net.typeblog.lpac_jni.ProfileDownloadCallback
|
import net.typeblog.lpac_jni.ProfileDownloadCallback
|
||||||
import net.typeblog.lpac_jni.Version
|
import net.typeblog.lpac_jni.Version
|
||||||
|
import java.util.concurrent.locks.ReentrantLock
|
||||||
|
import kotlin.concurrent.withLock
|
||||||
|
|
||||||
class LocalProfileAssistantImpl(
|
class LocalProfileAssistantImpl(
|
||||||
isdrAid: ByteArray,
|
isdrAid: ByteArray,
|
||||||
rawApduInterface: ApduInterface,
|
rawApduInterface: ApduInterface,
|
||||||
rawHttpInterface: HttpInterface
|
rawHttpInterface: HttpInterface
|
||||||
): LocalProfileAssistant {
|
) : LocalProfileAssistant {
|
||||||
companion object {
|
companion object {
|
||||||
private const val TAG = "LocalProfileAssistantImpl"
|
private const val TAG = "LocalProfileAssistantImpl"
|
||||||
}
|
}
|
||||||
|
@ -74,6 +76,10 @@ class LocalProfileAssistantImpl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Controls concurrency of every single method in this class, since
|
||||||
|
// the C-side is explicitly NOT thread-safe
|
||||||
|
private val lock = ReentrantLock()
|
||||||
|
|
||||||
private val apduInterface = ApduInterfaceWrapper(rawApduInterface)
|
private val apduInterface = ApduInterfaceWrapper(rawApduInterface)
|
||||||
private val httpInterface = HttpInterfaceWrapper(rawHttpInterface)
|
private val httpInterface = HttpInterfaceWrapper(rawHttpInterface)
|
||||||
|
|
||||||
|
@ -105,15 +111,15 @@ class LocalProfileAssistantImpl(
|
||||||
}
|
}
|
||||||
|
|
||||||
override val profiles: List<LocalProfileInfo>
|
override val profiles: List<LocalProfileInfo>
|
||||||
@Synchronized
|
get() = lock.withLock {
|
||||||
get() {
|
|
||||||
val head = LpacJni.es10cGetProfilesInfo(contextHandle)
|
val head = LpacJni.es10cGetProfilesInfo(contextHandle)
|
||||||
var curr = head
|
var curr = head
|
||||||
val ret = mutableListOf<LocalProfileInfo>()
|
val ret = mutableListOf<LocalProfileInfo>()
|
||||||
while (curr != 0L) {
|
while (curr != 0L) {
|
||||||
val state = LocalProfileInfo.State.fromString(LpacJni.profileGetStateString(curr))
|
val state = LocalProfileInfo.State.fromString(LpacJni.profileGetStateString(curr))
|
||||||
val clazz = LocalProfileInfo.Clazz.fromString(LpacJni.profileGetClassString(curr))
|
val clazz = LocalProfileInfo.Clazz.fromString(LpacJni.profileGetClassString(curr))
|
||||||
ret.add(LocalProfileInfo(
|
ret.add(
|
||||||
|
LocalProfileInfo(
|
||||||
LpacJni.profileGetIccid(curr),
|
LpacJni.profileGetIccid(curr),
|
||||||
state,
|
state,
|
||||||
LpacJni.profileGetName(curr),
|
LpacJni.profileGetName(curr),
|
||||||
|
@ -121,7 +127,8 @@ class LocalProfileAssistantImpl(
|
||||||
LpacJni.profileGetServiceProvider(curr),
|
LpacJni.profileGetServiceProvider(curr),
|
||||||
LpacJni.profileGetIsdpAid(curr),
|
LpacJni.profileGetIsdpAid(curr),
|
||||||
clazz
|
clazz
|
||||||
))
|
)
|
||||||
|
)
|
||||||
curr = LpacJni.profilesNext(curr)
|
curr = LpacJni.profilesNext(curr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -130,35 +137,43 @@ class LocalProfileAssistantImpl(
|
||||||
}
|
}
|
||||||
|
|
||||||
override val notifications: List<LocalProfileNotification>
|
override val notifications: List<LocalProfileNotification>
|
||||||
@Synchronized
|
get() = lock.withLock {
|
||||||
get() {
|
|
||||||
val head = LpacJni.es10bListNotification(contextHandle)
|
val head = LpacJni.es10bListNotification(contextHandle)
|
||||||
var curr = head
|
var curr = head
|
||||||
|
|
||||||
|
try {
|
||||||
val ret = mutableListOf<LocalProfileNotification>()
|
val ret = mutableListOf<LocalProfileNotification>()
|
||||||
while (curr != 0L) {
|
while (curr != 0L) {
|
||||||
ret.add(LocalProfileNotification(
|
ret.add(
|
||||||
|
LocalProfileNotification(
|
||||||
LpacJni.notificationGetSeq(curr),
|
LpacJni.notificationGetSeq(curr),
|
||||||
LocalProfileNotification.Operation.fromString(LpacJni.notificationGetOperationString(curr)),
|
LocalProfileNotification.Operation.fromString(
|
||||||
|
LpacJni.notificationGetOperationString(
|
||||||
|
curr
|
||||||
|
)
|
||||||
|
),
|
||||||
LpacJni.notificationGetAddress(curr),
|
LpacJni.notificationGetAddress(curr),
|
||||||
LpacJni.notificationGetIccid(curr),
|
LpacJni.notificationGetIccid(curr),
|
||||||
))
|
)
|
||||||
|
)
|
||||||
curr = LpacJni.notificationsNext(curr)
|
curr = LpacJni.notificationsNext(curr)
|
||||||
}
|
}
|
||||||
LpacJni.notificationsFree(head)
|
|
||||||
return ret.sortedBy { it.seqNumber }.reversed()
|
return ret.sortedBy { it.seqNumber }.reversed()
|
||||||
|
} finally {
|
||||||
|
LpacJni.notificationsFree(head)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override val eID: String
|
override val eID: String
|
||||||
@Synchronized
|
get() = lock.withLock { LpacJni.es10cGetEid(contextHandle)!! }
|
||||||
get() = LpacJni.es10cGetEid(contextHandle)!!
|
|
||||||
|
|
||||||
override val euiccInfo2: EuiccInfo2?
|
override val euiccInfo2: EuiccInfo2?
|
||||||
@Synchronized
|
get() = lock.withLock {
|
||||||
get() {
|
|
||||||
val cInfo = LpacJni.es10cexGetEuiccInfo2(contextHandle)
|
val cInfo = LpacJni.es10cexGetEuiccInfo2(contextHandle)
|
||||||
if (cInfo == 0L) return null
|
if (cInfo == 0L) return null
|
||||||
|
|
||||||
val ret = EuiccInfo2(
|
try {
|
||||||
|
return EuiccInfo2(
|
||||||
Version(LpacJni.euiccInfo2GetSGP22Version(cInfo)),
|
Version(LpacJni.euiccInfo2GetSGP22Version(cInfo)),
|
||||||
Version(LpacJni.euiccInfo2GetProfileVersion(cInfo)),
|
Version(LpacJni.euiccInfo2GetProfileVersion(cInfo)),
|
||||||
Version(LpacJni.euiccInfo2GetEuiccFirmwareVersion(cInfo)),
|
Version(LpacJni.euiccInfo2GetEuiccFirmwareVersion(cInfo)),
|
||||||
|
@ -182,27 +197,27 @@ class LocalProfileAssistantImpl(
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
|
} finally {
|
||||||
LpacJni.euiccInfo2Free(cInfo)
|
LpacJni.euiccInfo2Free(cInfo)
|
||||||
|
}
|
||||||
return ret
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
override fun enableProfile(iccid: String, refresh: Boolean): Boolean = lock.withLock {
|
||||||
override fun enableProfile(iccid: String, refresh: Boolean): Boolean =
|
|
||||||
LpacJni.es10cEnableProfile(contextHandle, iccid, refresh) == 0
|
LpacJni.es10cEnableProfile(contextHandle, iccid, refresh) == 0
|
||||||
|
}
|
||||||
|
|
||||||
@Synchronized
|
override fun disableProfile(iccid: String, refresh: Boolean): Boolean = lock.withLock {
|
||||||
override fun disableProfile(iccid: String, refresh: Boolean): Boolean =
|
|
||||||
LpacJni.es10cDisableProfile(contextHandle, iccid, refresh) == 0
|
LpacJni.es10cDisableProfile(contextHandle, iccid, refresh) == 0
|
||||||
|
}
|
||||||
|
|
||||||
@Synchronized
|
override fun deleteProfile(iccid: String): Boolean = lock.withLock {
|
||||||
override fun deleteProfile(iccid: String): Boolean =
|
|
||||||
LpacJni.es10cDeleteProfile(contextHandle, iccid) == 0
|
LpacJni.es10cDeleteProfile(contextHandle, iccid) == 0
|
||||||
|
}
|
||||||
|
|
||||||
@Synchronized
|
override fun downloadProfile(
|
||||||
override fun downloadProfile(smdp: String, matchingId: String?, imei: String?,
|
smdp: String, matchingId: String?, imei: String?,
|
||||||
confirmationCode: String?, callback: ProfileDownloadCallback) {
|
confirmationCode: String?, callback: ProfileDownloadCallback
|
||||||
|
) = lock.withLock {
|
||||||
val res = LpacJni.downloadProfile(
|
val res = LpacJni.downloadProfile(
|
||||||
contextHandle,
|
contextHandle,
|
||||||
smdp,
|
smdp,
|
||||||
|
@ -229,18 +244,17 @@ class LocalProfileAssistantImpl(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
override fun deleteNotification(seqNumber: Long): Boolean = lock.withLock {
|
||||||
override fun deleteNotification(seqNumber: Long): Boolean =
|
|
||||||
LpacJni.es10bDeleteNotification(contextHandle, seqNumber) == 0
|
LpacJni.es10bDeleteNotification(contextHandle, seqNumber) == 0
|
||||||
|
}
|
||||||
|
|
||||||
@Synchronized
|
override fun handleNotification(seqNumber: Long): Boolean = lock.withLock {
|
||||||
override fun handleNotification(seqNumber: Long): Boolean =
|
|
||||||
LpacJni.handleNotification(contextHandle, seqNumber).also {
|
LpacJni.handleNotification(contextHandle, seqNumber).also {
|
||||||
Log.d(TAG, "handleNotification $seqNumber = $it")
|
Log.d(TAG, "handleNotification $seqNumber = $it")
|
||||||
} == 0
|
} == 0
|
||||||
|
}
|
||||||
|
|
||||||
@Synchronized
|
override fun setNickname(iccid: String, nickname: String) = lock.withLock {
|
||||||
override fun setNickname(iccid: String, nickname: String) {
|
|
||||||
val encoded = try {
|
val encoded = try {
|
||||||
Charsets.UTF_8.encode(nickname).array()
|
Charsets.UTF_8.encode(nickname).array()
|
||||||
} catch (e: CharacterCodingException) {
|
} catch (e: CharacterCodingException) {
|
||||||
|
@ -259,11 +273,12 @@ class LocalProfileAssistantImpl(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun euiccMemoryReset() {
|
override fun euiccMemoryReset() {
|
||||||
|
lock.withLock {
|
||||||
LpacJni.es10cEuiccMemoryReset(contextHandle)
|
LpacJni.es10cEuiccMemoryReset(contextHandle)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Synchronized
|
override fun close() = lock.withLock {
|
||||||
override fun close() {
|
|
||||||
if (!finalized) {
|
if (!finalized) {
|
||||||
LpacJni.euiccFini(contextHandle)
|
LpacJni.euiccFini(contextHandle)
|
||||||
LpacJni.destroyContext(contextHandle)
|
LpacJni.destroyContext(contextHandle)
|
||||||
|
|
Loading…
Add table
Reference in a new issue