Compare commits
No commits in common. "c62e8bcecd80146022a7197cad2a983af5dc803b" and "bea5aa0dcfc978bcf43807f8226788c1c93b5cd7" have entirely different histories.
c62e8bcecd
...
bea5aa0dcf
5 changed files with 68 additions and 57 deletions
|
@ -67,11 +67,6 @@ android {
|
|||
signingConfig signingConfigs.config
|
||||
}
|
||||
}
|
||||
applicationVariants.all { variant ->
|
||||
if (variant.name == "debug") {
|
||||
variant.outputs.each { o -> o.versionCodeOverride = System.currentTimeSeconds() }
|
||||
}
|
||||
}
|
||||
compileOptions {
|
||||
sourceCompatibility JavaVersion.VERSION_1_8
|
||||
targetCompatibility JavaVersion.VERSION_1_8
|
||||
|
|
|
@ -21,16 +21,7 @@ abstract class EuiccChannel(
|
|||
val removable = info.removable
|
||||
|
||||
abstract val lpa: LocalProfileAssistant
|
||||
val valid: Boolean
|
||||
get() {
|
||||
try {
|
||||
// Try to ping the eUICC card by reading the EID
|
||||
lpa.eID
|
||||
} catch (e: Exception) {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
abstract val valid: Boolean
|
||||
|
||||
abstract fun close()
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import net.typeblog.lpac_jni.ApduInterface
|
|||
import net.typeblog.lpac_jni.LocalProfileAssistant
|
||||
import net.typeblog.lpac_jni.impl.HttpInterfaceImpl
|
||||
import net.typeblog.lpac_jni.impl.LocalProfileAssistantImpl
|
||||
import java.lang.IllegalStateException
|
||||
|
||||
class OmapiApduInterface(
|
||||
private val service: SEService,
|
||||
|
@ -24,23 +25,23 @@ class OmapiApduInterface(
|
|||
}
|
||||
|
||||
override fun logicalChannelOpen(aid: ByteArray): Int {
|
||||
check(!this::lastChannel.isInitialized) {
|
||||
"Can only open one channel"
|
||||
if (this::lastChannel.isInitialized) {
|
||||
throw IllegalStateException("Can only open one channel")
|
||||
}
|
||||
lastChannel = session.openLogicalChannel(aid)!!;
|
||||
return 0;
|
||||
}
|
||||
|
||||
override fun logicalChannelClose(handle: Int) {
|
||||
check(handle == 0 && !this::lastChannel.isInitialized) {
|
||||
"Unknown channel"
|
||||
if (handle != 0 || !this::lastChannel.isInitialized) {
|
||||
throw IllegalStateException("Unknown channel")
|
||||
}
|
||||
lastChannel.close()
|
||||
}
|
||||
|
||||
override fun transmit(tx: ByteArray): ByteArray {
|
||||
check(this::lastChannel.isInitialized) {
|
||||
"Unknown channel"
|
||||
if (!this::lastChannel.isInitialized) {
|
||||
throw IllegalStateException("Unknown channel")
|
||||
}
|
||||
|
||||
return lastChannel.transmit(tx)
|
||||
|
@ -52,9 +53,30 @@ class OmapiChannel(
|
|||
service: SEService,
|
||||
info: EuiccChannelInfo,
|
||||
) : EuiccChannel(info) {
|
||||
companion object {
|
||||
private const val TAG = "OmapiChannel"
|
||||
private val APPLET_ID = byteArrayOf(-96, 0, 0, 5, 89, 16, 16, -1, -1, -1, -1, -119, 0, 0, 1, 0)
|
||||
|
||||
/*fun tryConnect(service: SEService, info: EuiccChannelInfo): OmapiChannel? {
|
||||
try {
|
||||
val reader = service.getUiccReader(info.slotId + 1) // slotId from telephony starts from 0
|
||||
val session = reader.openSession()
|
||||
val channel = session.openLogicalChannel(APPLET_ID) ?: return null
|
||||
return OmapiChannel(info, channel)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to open eUICC channel for slot ${info.slotId}, skipping")
|
||||
Log.e(TAG, Log.getStackTraceString(e))
|
||||
return null
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
override val lpa: LocalProfileAssistant = LocalProfileAssistantImpl(
|
||||
OmapiApduInterface(service, info),
|
||||
HttpInterfaceImpl())
|
||||
|
||||
override val valid: Boolean
|
||||
get() = true // TODO: This has to be implemented properly
|
||||
|
||||
override fun close() = lpa.close()
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
package im.angry.openeuicc.core
|
||||
|
||||
import android.telephony.IccOpenLogicalChannelResponse
|
||||
import android.telephony.TelephonyManager
|
||||
import im.angry.openeuicc.util.*
|
||||
import net.typeblog.lpac_jni.LocalProfileAssistant
|
||||
import net.typeblog.lpac_jni.ApduInterface
|
||||
import net.typeblog.lpac_jni.impl.HttpInterfaceImpl
|
||||
|
@ -12,42 +10,24 @@ class TelephonyManagerApduInterface(
|
|||
private val info: EuiccChannelInfo,
|
||||
private val tm: TelephonyManager
|
||||
): ApduInterface {
|
||||
private var lastChannel: Int = -1
|
||||
|
||||
override fun connect() {
|
||||
// Do nothing
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun disconnect() {
|
||||
// Do nothing
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun logicalChannelOpen(aid: ByteArray): Int {
|
||||
check(lastChannel == -1) { "Already initialized" }
|
||||
val hex = aid.encodeHex()
|
||||
val channel = tm.iccOpenLogicalChannelBySlot(info.slotId, hex, 0)
|
||||
if (channel.status != IccOpenLogicalChannelResponse.STATUS_NO_ERROR || channel.channel == IccOpenLogicalChannelResponse.INVALID_CHANNEL) {
|
||||
throw IllegalArgumentException("Cannot open logical channel " + hex + " via TelephonManager on slot " + info.slotId);
|
||||
}
|
||||
return channel.channel
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun logicalChannelClose(handle: Int) {
|
||||
tm.iccCloseLogicalChannelBySlot(info.slotId, handle)
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override fun transmit(tx: ByteArray): ByteArray {
|
||||
check(lastChannel != -1) { "Uninitialized" }
|
||||
|
||||
val cla = tx[0].toInt()
|
||||
val instruction = tx[1].toInt()
|
||||
val p1 = tx[2].toInt()
|
||||
val p2 = tx[3].toInt()
|
||||
val p3 = tx[4].toInt()
|
||||
val p4 = tx.drop(5).toByteArray().encodeHex()
|
||||
|
||||
return tm.iccTransmitApduLogicalChannelBySlot(info.slotId, lastChannel,
|
||||
cla, instruction, p1, p2, p3, p4)?.decodeHex() ?: byteArrayOf()
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -56,10 +36,36 @@ class TelephonyManagerChannel(
|
|||
info: EuiccChannelInfo,
|
||||
private val tm: TelephonyManager
|
||||
) : EuiccChannel(info) {
|
||||
companion object {
|
||||
private const val TAG = "TelephonyManagerApduChannel"
|
||||
private const val EUICC_APP_ID = "A0000005591010FFFFFFFF8900000100"
|
||||
|
||||
// TODO: On Tiramisu, we need to specify the portId also if we want MEP support
|
||||
/*fun tryConnect(tm: TelephonyManager, info: EuiccChannelInfo): TelephonyManagerChannel? {
|
||||
try {
|
||||
val channel = tm.iccOpenLogicalChannelBySlot(info.slotId, EUICC_APP_ID, 0)
|
||||
if (channel.status != IccOpenLogicalChannelResponse.STATUS_NO_ERROR || channel.channel == IccOpenLogicalChannelResponse.INVALID_CHANNEL) {
|
||||
Log.e(TAG, "Unable to open eUICC channel for slot ${info.slotId} via TelephonyManager: ${channel.status}")
|
||||
return null
|
||||
}
|
||||
|
||||
Log.d(TAG, "channel: ${channel.channel}")
|
||||
|
||||
return TelephonyManagerChannel(info, tm, channel.channel)
|
||||
} catch (e: Exception) {
|
||||
Log.e(TAG, "Unable to open eUICC channel for slot ${info.slotId} via TelephonyManager")
|
||||
Log.e(TAG, Log.getStackTraceString(e))
|
||||
return null
|
||||
}
|
||||
}*/
|
||||
}
|
||||
|
||||
override val lpa: LocalProfileAssistant = LocalProfileAssistantImpl(
|
||||
TelephonyManagerApduInterface(info, tm),
|
||||
HttpInterfaceImpl()
|
||||
)
|
||||
override val valid: Boolean
|
||||
get() = true // TODO: Fix this
|
||||
|
||||
override fun close() = lpa.close()
|
||||
}
|
|
@ -1,22 +1,19 @@
|
|||
package im.angry.openeuicc.util
|
||||
|
||||
fun String.decodeHex(): ByteArray {
|
||||
check(length % 2 == 0) { "Must have an even length" }
|
||||
|
||||
val decodedLength = length / 2
|
||||
val out = ByteArray(decodedLength)
|
||||
for (i in 0 until decodedLength) {
|
||||
fun hexStringToByteArray(str: String): ByteArray {
|
||||
val length = str.length / 2
|
||||
val out = ByteArray(length)
|
||||
for (i in 0 until length) {
|
||||
val i2 = i * 2
|
||||
out[i] = substring(i2, i2 + 2).toInt(16).toByte()
|
||||
out[i] = str.substring(i2, i2 + 2).toInt(16).toByte()
|
||||
}
|
||||
return out
|
||||
}
|
||||
|
||||
fun ByteArray.encodeHex(): String {
|
||||
fun byteArrayToHex(arr: ByteArray): String {
|
||||
val sb = StringBuilder()
|
||||
val length = size
|
||||
val length = arr.size
|
||||
for (i in 0 until length) {
|
||||
sb.append(String.format("%02X", this[i]))
|
||||
sb.append(String.format("%02X", arr[i]))
|
||||
}
|
||||
return sb.toString()
|
||||
}
|
Loading…
Add table
Reference in a new issue