ソースを参照

refactor: ATR should not be the concern of lpac-jni

...instead, use a separate interface to represent channel types that do
support reading ATR.
Peter Cai 1 年間 前
コミット
6b4723daee

+ 5 - 0
app-common/src/main/java/im/angry/openeuicc/core/ApduInterfaceAtrProvider.kt

@@ -0,0 +1,5 @@
+package im.angry.openeuicc.core
+
+interface ApduInterfaceAtrProvider {
+    val atr: ByteArray?
+}

+ 5 - 0
app-common/src/main/java/im/angry/openeuicc/core/EuiccChannel.kt

@@ -16,6 +16,11 @@ interface EuiccChannel {
 
     val valid: Boolean
 
+    /**
+     * Answer to Reset (ATR) value of the underlying interface, if any
+     */
+    val atr: ByteArray?
+
     /**
      * Intrinsic name of this channel. For device-internal SIM slots,
      * this should be null; for USB readers, this should be the name of

+ 4 - 1
app-common/src/main/java/im/angry/openeuicc/core/EuiccChannelImpl.kt

@@ -11,7 +11,7 @@ class EuiccChannelImpl(
     override val type: String,
     override val port: UiccPortInfoCompat,
     override val intrinsicChannelName: String?,
-    apduInterface: ApduInterface,
+    private val apduInterface: ApduInterface,
     verboseLoggingFlow: Flow<Boolean>,
     ignoreTLSCertificateFlow: Flow<Boolean>
 ) : EuiccChannel {
@@ -22,6 +22,9 @@ class EuiccChannelImpl(
     override val lpa: LocalProfileAssistant =
         LocalProfileAssistantImpl(apduInterface, HttpInterfaceImpl(verboseLoggingFlow, ignoreTLSCertificateFlow))
 
+    override val atr: ByteArray?
+        get() = (apduInterface as? ApduInterfaceAtrProvider)?.atr
+
     override val valid: Boolean
         get() = lpa.valid
 

+ 2 - 0
app-common/src/main/java/im/angry/openeuicc/core/EuiccChannelWrapper.kt

@@ -33,6 +33,8 @@ class EuiccChannelWrapper(orig: EuiccChannel) : EuiccChannel {
         get() = channel.valid
     override val intrinsicChannelName: String?
         get() = channel.intrinsicChannelName
+    override val atr: ByteArray?
+        get() = channel.atr
 
     override fun close() = channel.close()
 

+ 0 - 2
app-common/src/main/java/im/angry/openeuicc/core/LocalProfileAssistantWrapper.kt

@@ -30,8 +30,6 @@ class LocalProfileAssistantWrapper(orig: LocalProfileAssistant) :
     override val euiccInfo2: EuiccInfo2?
         get() = lpa.euiccInfo2
 
-    override fun readATR() = lpa.readATR()
-
     override fun setEs10xMss(mss: Byte) = lpa.setEs10xMss(mss)
 
     override fun enableProfile(iccid: String, refresh: Boolean): Boolean =

+ 3 - 3
app-common/src/main/java/im/angry/openeuicc/core/OmapiApduInterface.kt

@@ -15,7 +15,7 @@ class OmapiApduInterface(
     private val service: SEService,
     private val port: UiccPortInfoCompat,
     private val verboseLoggingFlow: Flow<Boolean>
-): ApduInterface {
+): ApduInterface, ApduInterfaceAtrProvider {
     companion object {
         const val TAG = "OmapiApduInterface"
     }
@@ -26,8 +26,8 @@ class OmapiApduInterface(
     override val valid: Boolean
         get() = service.isConnected && (this::session.isInitialized && !session.isClosed)
 
-    override fun readATR() =
-        session.atr?.clone() ?: throw IllegalStateException("atr unavailable")
+    override val atr: ByteArray?
+        get() = session.atr
 
     override fun connect() {
         session = service.getUiccReaderCompat(port.logicalSlotIndex + 1).openSession()

+ 4 - 6
app-common/src/main/java/im/angry/openeuicc/core/usb/UsbApduInterface.kt

@@ -3,6 +3,7 @@ package im.angry.openeuicc.core.usb
 import android.hardware.usb.UsbDeviceConnection
 import android.hardware.usb.UsbEndpoint
 import android.util.Log
+import im.angry.openeuicc.core.ApduInterfaceAtrProvider
 import im.angry.openeuicc.util.*
 import kotlinx.coroutines.flow.Flow
 import net.typeblog.lpac_jni.ApduInterface
@@ -12,7 +13,7 @@ class UsbApduInterface(
     private val bulkIn: UsbEndpoint,
     private val bulkOut: UsbEndpoint,
     private val verboseLoggingFlow: Flow<Boolean>
-): ApduInterface {
+) : ApduInterface, ApduInterfaceAtrProvider {
     companion object {
         private const val TAG = "UsbApduInterface"
     }
@@ -22,6 +23,8 @@ class UsbApduInterface(
 
     private var channelId = -1
 
+    override var atr: ByteArray? = null
+
     override fun connect() {
         ccidDescription = UsbCcidDescription.fromRawDescriptors(conn.rawDescriptors)!!
 
@@ -101,11 +104,6 @@ class UsbApduInterface(
     override val valid: Boolean
         get() = channelId != -1
 
-    private var atr: ByteArray? = null
-
-    override fun readATR() =
-        atr?.clone() ?: throw IllegalStateException("atr unavailable")
-
     private fun isSuccessResponse(resp: ByteArray): Boolean =
         resp.size >= 2 && resp[resp.size - 2] == 0x90.toByte() && resp[resp.size - 1] == 0x00.toByte()
 

+ 1 - 6
app-common/src/main/java/im/angry/openeuicc/ui/EuiccInfoActivity.kt

@@ -23,7 +23,6 @@ import im.angry.openeuicc.common.R
 import im.angry.openeuicc.core.EuiccChannel
 import im.angry.openeuicc.core.EuiccChannelManager
 import im.angry.openeuicc.util.*
-import kotlinx.coroutines.flow.first
 import kotlinx.coroutines.launch
 import net.typeblog.lpac_jni.impl.PKID_GSMA_LIVE_CI
 import net.typeblog.lpac_jni.impl.PKID_GSMA_TEST_CI
@@ -138,11 +137,7 @@ class EuiccInfoActivity : BaseEuiccAccessActivity(), OpenEuiccContextMarker {
         add(
             Item(
                 R.string.euicc_info_atr,
-                try {
-                    channel.lpa.readATR().encodeHex()
-                } catch (e: Exception) {
-                    getString(R.string.euicc_info_atr_unavailable)
-                },
+                channel.atr?.encodeHex() ?: getString(R.string.euicc_info_atr_unavailable),
                 copiedToastResId = R.string.toast_atr_copied,
             )
         )

+ 0 - 3
app/src/main/java/im/angry/openeuicc/core/TelephonyManagerApduInterface.kt

@@ -25,9 +25,6 @@ class TelephonyManagerApduInterface(
         // just that transactions might return errors or nonsense
         get() = lastChannel != -1
 
-    override fun readATR() =
-        throw IllegalStateException("atr unavailable")
-
     override fun connect() {
         // Do nothing
     }

+ 0 - 5
libs/lpac-jni/src/main/java/net/typeblog/lpac_jni/ApduInterface.kt

@@ -16,9 +16,4 @@ interface ApduInterface {
      * callers should further check with the LPA to fully determine the validity of a channel
      */
     val valid: Boolean
-
-    /**
-     * Read Answer To Reset
-     */
-    fun readATR(): ByteArray
 }

+ 0 - 2
libs/lpac-jni/src/main/java/net/typeblog/lpac_jni/LocalProfileAssistant.kt

@@ -23,8 +23,6 @@ interface LocalProfileAssistant {
     // Extended EuiccInfo for use with LUIs, containing information such as firmware version
     val euiccInfo2: EuiccInfo2?
 
-    fun readATR(): ByteArray
-
     /**
      * Set the max segment size (mss) for all es10x commands. This can help with removable
      * eUICCs that may run at a baud rate too fast for the modem.

+ 0 - 2
libs/lpac-jni/src/main/java/net/typeblog/lpac_jni/impl/LocalProfileAssistantImpl.kt

@@ -188,8 +188,6 @@ class LocalProfileAssistantImpl(
             return ret
         }
 
-    override fun readATR() = apduInterface.readATR()
-
     @Synchronized
     override fun enableProfile(iccid: String, refresh: Boolean): Boolean =
         LpacJni.es10cEnableProfile(contextHandle, iccid, refresh) == 0