瀏覽代碼

ui: wizard: Add APDU errors to diagnostics

Peter Cai 1 年之前
父節點
當前提交
326b39ed05

+ 27 - 0
app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardDiagnosticsFragment.kt

@@ -81,6 +81,33 @@ class DownloadWizardDiagnosticsFragment : DownloadWizardActivity.DownloadWizardS
             ret.appendLine()
         }
 
+        err.lastApduResponse?.let { resp ->
+            ret.appendLine(
+                getString(
+                    R.string.download_wizard_diagnostics_last_apdu_response,
+                    resp.encodeHex()
+                )
+            )
+            ret.appendLine()
+
+            val isSuccess =
+                resp.size >= 2 && resp[resp.size - 2] == 0x90.toByte() && resp[resp.size - 1] == 0x00.toByte()
+
+            if (isSuccess) {
+                ret.appendLine(getString(R.string.download_wizard_diagnostics_last_apdu_response_success))
+            } else {
+                ret.appendLine(getString(R.string.download_wizard_diagnostics_last_apdu_response_fail))
+            }
+        }
+
+        err.lastApduException?.let { e ->
+            ret.appendLine(getString(R.string.download_wizard_diagnostics_last_apdu_exception))
+            ret.appendLine()
+            ret.appendLine("${e.javaClass.name}: ${e.message}")
+            ret.appendLine(e.stackTrace.joinToString("\n"))
+            ret.appendLine()
+        }
+
         ret.toString()
     }
 }

+ 4 - 0
app-common/src/main/res/values/strings.xml

@@ -85,6 +85,10 @@
     <string name="download_wizard_diagnostics_last_http_status">Last HTTP status: %d</string>
     <string name="download_wizard_diagnostics_last_http_response">Last HTTP response:</string>
     <string name="download_wizard_diagnostics_last_http_exception">Last HTTP exception:</string>
+    <string name="download_wizard_diagnostics_last_apdu_response">Last APDU response: %s</string>
+    <string name="download_wizard_diagnostics_last_apdu_response_success">Last APDU response is successful</string>
+    <string name="download_wizard_diagnostics_last_apdu_response_fail">Last APDU response is a failure</string>
+    <string name="download_wizard_diagnostics_last_apdu_exception">Last APDU exception:</string>
 
     <string name="profile_rename_new_name">New nickname</string>
 

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

@@ -3,9 +3,12 @@ package net.typeblog.lpac_jni
 import net.typeblog.lpac_jni.HttpInterface.HttpResponse
 
 interface LocalProfileAssistant {
+    @Suppress("ArrayInDataClass")
     data class ProfileDownloadException(
         val lastHttpResponse: HttpResponse?,
         val lastHttpException: Exception?,
+        val lastApduResponse: ByteArray?,
+        val lastApduException: Exception?,
     ) : Exception("Failed to download profile")
 
     val valid: Boolean

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

@@ -11,13 +11,35 @@ import net.typeblog.lpac_jni.LocalProfileNotification
 import net.typeblog.lpac_jni.ProfileDownloadCallback
 
 class LocalProfileAssistantImpl(
-    private val apduInterface: ApduInterface,
+    rawApduInterface: ApduInterface,
     private val httpInterface: HttpInterface
 ): LocalProfileAssistant {
     companion object {
         private const val TAG = "LocalProfileAssistantImpl"
     }
 
+    /**
+     * A thin wrapper over ApduInterface to acquire exceptions and errors transparently
+     */
+    private class ApduInterfaceWrapper(val apduInterface: ApduInterface) :
+        ApduInterface by apduInterface {
+        var lastApduResponse: ByteArray? = null
+        var lastApduException: Exception? = null
+
+        override fun transmit(tx: ByteArray): ByteArray =
+            try {
+                apduInterface.transmit(tx).also {
+                    lastApduResponse = it
+                }
+            } catch (e: Exception) {
+                lastApduResponse = null
+                lastApduException = e
+                throw e
+            }
+    }
+
+    private val apduInterface = ApduInterfaceWrapper(rawApduInterface)
+
     private var finalized = false
     private var contextHandle: Long = LpacJni.createContext(apduInterface, httpInterface)
 
@@ -157,7 +179,9 @@ class LocalProfileAssistantImpl(
         if (res != 0) {
             throw LocalProfileAssistant.ProfileDownloadException(
                 httpInterface.lastHttpResponse,
-                httpInterface.lastHttpException
+                httpInterface.lastHttpException,
+                apduInterface.lastApduResponse,
+                apduInterface.lastApduException,
             )
         }
     }