From cce247e74754d8579934d198aee1e76134ae0e6b Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Sun, 7 Sep 2025 14:56:09 -0400 Subject: [PATCH 1/3] feat: Display simplified error messages when profile downloading fails i18n pending Co-Authored-By: septs --- .../wizard/DownloadWizardProgressFragment.kt | 55 ++++++- .../ui/wizard/SimplifiedErrorMessages.kt | 154 ++++++++++++++++++ .../res/layout/download_progress_item.xml | 58 +++++-- app-common/src/main/res/values/strings.xml | 21 +++ 4 files changed, 269 insertions(+), 19 deletions(-) create mode 100644 app-common/src/main/java/im/angry/openeuicc/ui/wizard/SimplifiedErrorMessages.kt diff --git a/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardProgressFragment.kt b/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardProgressFragment.kt index 342a687..29e87b0 100644 --- a/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardProgressFragment.kt +++ b/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardProgressFragment.kt @@ -43,18 +43,36 @@ class DownloadWizardProgressFragment : DownloadWizardActivity.DownloadWizardStep private data class ProgressItem( val titleRes: Int, - var state: ProgressState + var state: ProgressState, + var errorMessage: SimplifiedErrorMessages?, ) private val progressItems = arrayOf( - ProgressItem(R.string.download_wizard_progress_step_preparing, ProgressState.NotStarted), - ProgressItem(R.string.download_wizard_progress_step_connecting, ProgressState.NotStarted), + ProgressItem( + R.string.download_wizard_progress_step_preparing, + ProgressState.NotStarted, + null + ), + ProgressItem( + R.string.download_wizard_progress_step_connecting, + ProgressState.NotStarted, + null + ), ProgressItem( R.string.download_wizard_progress_step_authenticating, - ProgressState.NotStarted + ProgressState.NotStarted, + null ), - ProgressItem(R.string.download_wizard_progress_step_downloading, ProgressState.NotStarted), - ProgressItem(R.string.download_wizard_progress_step_finalizing, ProgressState.NotStarted) + ProgressItem( + R.string.download_wizard_progress_step_downloading, + ProgressState.NotStarted, + null + ), + ProgressItem( + R.string.download_wizard_progress_step_finalizing, + ProgressState.NotStarted, + null + ) ) private val adapter = ProgressItemAdapter() @@ -122,8 +140,13 @@ class DownloadWizardProgressFragment : DownloadWizardActivity.DownloadWizardStep // Change the state of the last InProgress item to success (or error) progressItems.forEachIndexed { index, progressItem -> if (progressItem.state == ProgressState.InProgress) { - progressItem.state = - if (state.downloadError == null) ProgressState.Done else ProgressState.Error + if (state.downloadError == null) { + progressItem.state = ProgressState.Done + } else { + progressItem.state = ProgressState.Error + progressItem.errorMessage = + SimplifiedErrorMessages.fromDownloadError(state.downloadError!!) + } } adapter.notifyItemChanged(index) @@ -197,9 +220,15 @@ class DownloadWizardProgressFragment : DownloadWizardActivity.DownloadWizardStep private val progressBar = root.requireViewById(R.id.download_progress_icon_progress) private val icon = root.requireViewById(R.id.download_progress_icon) + private val errorTitle = + root.requireViewById(R.id.download_progress_item_error_title) + private val errorSuggestion = + root.requireViewById(R.id.download_progress_item_error_suggestion) fun bind(item: ProgressItem) { title.text = getString(item.titleRes) + errorTitle.visibility = View.GONE + errorSuggestion.visibility = View.GONE when (item.state) { ProgressState.NotStarted -> { @@ -222,6 +251,16 @@ class DownloadWizardProgressFragment : DownloadWizardActivity.DownloadWizardStep progressBar.visibility = View.GONE icon.setImageResource(R.drawable.ic_error_outline) icon.visibility = View.VISIBLE + + if (item.errorMessage != null) { + errorTitle.visibility = View.VISIBLE + errorTitle.text = getString(item.errorMessage!!.titleResId) + + if (item.errorMessage!!.suggestResId != null) { + errorSuggestion.visibility = View.VISIBLE + errorSuggestion.text = getString(item.errorMessage!!.suggestResId!!) + } + } } } } diff --git a/app-common/src/main/java/im/angry/openeuicc/ui/wizard/SimplifiedErrorMessages.kt b/app-common/src/main/java/im/angry/openeuicc/ui/wizard/SimplifiedErrorMessages.kt new file mode 100644 index 0000000..8ce5740 --- /dev/null +++ b/app-common/src/main/java/im/angry/openeuicc/ui/wizard/SimplifiedErrorMessages.kt @@ -0,0 +1,154 @@ +package im.angry.openeuicc.ui.wizard + +import androidx.annotation.StringRes +import im.angry.openeuicc.common.R +import net.typeblog.lpac_jni.LocalProfileAssistant +import org.json.JSONObject +import java.net.NoRouteToHostException +import java.net.PortUnreachableException +import java.net.SocketException +import java.net.SocketTimeoutException +import java.net.UnknownHostException +import javax.net.ssl.SSLException + +enum class SimplifiedErrorMessages( + @StringRes val titleResId: Int, + @StringRes val suggestResId: Int? +) { + ICCIDAlreadyInUse( + R.string.download_wizard_error_iccid_already, + R.string.download_wizard_error_suggest_profile_installed + ), + InsufficientMemory( + R.string.download_wizard_error_insufficient_memory, + R.string.download_wizard_error_suggest_insufficient_memory + ), + UnsupportedProfile( + R.string.download_wizard_error_unsupported_profile, + null + ), + CardInternalError( + R.string.download_wizard_error_card_internal_error, + null + ), + EIDNotSupported( + R.string.download_wizard_error_eid_not_supported, + R.string.download_wizard_error_suggest_contact_carrier + ), + EIDMismatch( + R.string.download_wizard_error_eid_mismatch, + R.string.download_wizard_error_suggest_contact_reissue + ), + UnreleasedProfile( + R.string.download_wizard_error_profile_unreleased, + R.string.download_wizard_error_suggest_contact_reissue + ), + MatchingIDRefused( + R.string.download_wizard_error_matching_id_refused, + R.string.download_wizard_error_suggest_contact_carrier + ), + ProfileRetriesExceeded( + R.string.download_wizard_error_profile_retries_exceeded, + R.string.download_wizard_error_suggest_contact_carrier + ), + ConfirmationCodeMissing( + R.string.download_wizard_error_confirmation_code_missing, + R.string.download_wizard_error_suggest_contact_carrier + ), + ConfirmationCodeRefused( + R.string.download_wizard_error_confirmation_code_refused, + R.string.download_wizard_error_suggest_contact_carrier + ), + ConfirmationCodeRetriesExceeded( + R.string.download_wizard_error_confirmation_code_retries_exceeded, + R.string.download_wizard_error_suggest_contact_carrier + ), + ProfileExpired( + R.string.download_wizard_error_profile_expired, + R.string.download_wizard_error_suggest_contact_carrier + ), + UnknownHost( + R.string.download_wizard_error_unknown_hostname, + null + ), + NetworkUnreachable( + R.string.download_wizard_error_network_unreachable, + R.string.download_wizard_error_suggest_network_unreachable + ), + TLSError( + R.string.download_wizard_error_tls_certificate, + null + ); + + companion object { + private val httpErrors = buildMap { + // Stage: AuthenticateClient + put("8.1" to "4.8", InsufficientMemory) + put("8.1.1" to "2.1", EIDNotSupported) + put("8.1.1" to "3.8", EIDMismatch) + put("8.2" to "1.2", UnreleasedProfile) + put("8.2.6" to "3.8", MatchingIDRefused) + put("8.8.5" to "6.4", ProfileRetriesExceeded) + + // Stage: GetBoundProfilePackage + put("8.2.7" to "2.2", ConfirmationCodeMissing) + put("8.2.7" to "3.8", ConfirmationCodeRefused) + put("8.2.7" to "6.4", ConfirmationCodeRetriesExceeded) + + // Stage: AuthenticateClient, GetBoundProfilePackage + put("8.8.5" to "4.10", ProfileExpired) + } + + fun fromDownloadError(exc: LocalProfileAssistant.ProfileDownloadException) = when { + exc.lpaErrorReason != "ES10B_ERROR_REASON_UNDEFINED" -> fromLPAErrorReason(exc.lpaErrorReason) + exc.lastHttpResponse?.rcode == 200 -> fromHTTPResponse(exc.lastHttpResponse!!) + exc.lastHttpException != null -> fromHTTPException(exc.lastHttpException!!) + exc.lastApduResponse != null -> fromAPDUResponse(exc.lastApduResponse!!) + else -> null + } + + private fun fromLPAErrorReason(reason: String) = when (reason) { + "ES10B_ERROR_REASON_UNSUPPORTED_CRT_VALUES" -> UnsupportedProfile + "ES10B_ERROR_REASON_UNSUPPORTED_REMOTE_OPERATION_TYPE" -> UnsupportedProfile + "ES10B_ERROR_REASON_UNSUPPORTED_PROFILE_CLASS" -> UnsupportedProfile + "ES10B_ERROR_REASON_INSTALL_FAILED_DUE_TO_ICCID_ALREADY_EXISTS_ON_EUICC" -> ICCIDAlreadyInUse + "ES10B_ERROR_REASON_INSTALL_FAILED_DUE_TO_INSUFFICIENT_MEMORY_FOR_PROFILE" -> InsufficientMemory + "ES10B_ERROR_REASON_INSTALL_FAILED_DUE_TO_INTERRUPTION" -> CardInternalError + "ES10B_ERROR_REASON_INSTALL_FAILED_DUE_TO_PE_PROCESSING_ERROR" -> CardInternalError + else -> null + } + + private fun fromHTTPResponse(httpResponse: net.typeblog.lpac_jni.HttpInterface.HttpResponse): SimplifiedErrorMessages? { + if (httpResponse.data.first().toInt() != '{'.code) return null + val response = JSONObject(httpResponse.data.decodeToString()) + val statusCodeData = response.optJSONObject("header") + ?.optJSONObject("functionExecutionStatus") + ?.optJSONObject("statusCodeData") + ?: return null + val subjectCode = statusCodeData.optString("subjectCode") + val reasonCode = statusCodeData.optString("reasonCode") + return httpErrors[subjectCode to reasonCode] + } + + private fun fromHTTPException(exc: Exception) = when (exc) { + is SSLException -> TLSError + is UnknownHostException -> UnknownHost + is NoRouteToHostException -> NetworkUnreachable + is PortUnreachableException -> NetworkUnreachable + is SocketTimeoutException -> NetworkUnreachable + is SocketException -> exc.message + ?.contains("Connection reset", ignoreCase = true) + ?.let { if (it) NetworkUnreachable else null } + + else -> null + } + + private fun fromAPDUResponse(resp: ByteArray): SimplifiedErrorMessages? { + val isSuccess = resp.size >= 2 && + resp[resp.size - 2] == 0x90.toByte() && + resp[resp.size - 1] == 0x00.toByte() + if (isSuccess) return null + return CardInternalError + } + } +} diff --git a/app-common/src/main/res/layout/download_progress_item.xml b/app-common/src/main/res/layout/download_progress_item.xml index f1d0852..c59673b 100644 --- a/app-common/src/main/res/layout/download_progress_item.xml +++ b/app-common/src/main/res/layout/download_progress_item.xml @@ -1,30 +1,32 @@ + android:layout_height="wrap_content"> + app:layout_constraintBottom_toBottomOf="@id/download_progress_icon_container" + app:layout_constraintEnd_toStartOf="@id/download_progress_icon_container" + app:layout_constraintHorizontal_bias="0.0" + app:layout_constraintStart_toStartOf="parent" + app:layout_constraintTop_toTopOf="@id/download_progress_icon_container" + app:layout_constraintVertical_bias="0.5" /> + app:layout_constraintEnd_toEndOf="parent" + app:layout_constraintTop_toTopOf="parent" + app:layout_constraintVertical_bias="0.0"> + + + + \ No newline at end of file diff --git a/app-common/src/main/res/values/strings.xml b/app-common/src/main/res/values/strings.xml index ae0700b..3a9dda3 100644 --- a/app-common/src/main/res/values/strings.xml +++ b/app-common/src/main/res/values/strings.xml @@ -104,6 +104,27 @@ Last APDU exception: Save Diagnostics at %s + This eSIM profile is already present on your eSIM chip. + Your eSIM chip does not have sufficient memory left to download the profile. + This eSIM profile is unsupported by your eSIM chip. + An error occurred in your eSIM chip. + The EID of your device or eSIM chip is unsupported by your carrier. + This eSIM profile has been downloaded on another device. + This eSIM profile has been revoked. + The activation code is invalid. + The maximum number of download attempts for the eSIM profile has been exceeded. + Confirmation code is required to download this profile. + The confirmation code you entered is invalid. + This eSIM profile has expired. + The maximum number of download attempts for the confirmation code has been exceeded. + Unknown SM-DP+ address + Network is unreachable + TLS certificate error, this eSIM profile is not supported + You are trying to reinstall an already downloaded eSIM profile + Please delete some unused eSIM profiles and try again + Please contact your carrier for assistance. + Please contact your carrier to reissue this eSIM profile. + Please try again after connecting to a different network (e.g. switching between Wi-Fi and data). Logs have been saved to the selected path. Would you like to share the log through another app? From 7bae82daf9104c5682566cdeaf0dafb1cab58f4f Mon Sep 17 00:00:00 2001 From: septs Date: Sun, 7 Sep 2025 21:28:05 +0200 Subject: [PATCH 2/3] chore: add nvram hint (#223) Reviewed-on: https://gitea.angry.im/PeterCxy/OpenEUICC/pulls/223 Co-authored-by: septs Co-committed-by: septs --- .../main/java/im/angry/openeuicc/ui/EuiccInfoActivity.kt | 8 +++++++- app-common/src/main/res/values-zh-rCN/strings.xml | 1 + app-common/src/main/res/values/strings.xml | 1 + 3 files changed, 9 insertions(+), 1 deletion(-) diff --git a/app-common/src/main/java/im/angry/openeuicc/ui/EuiccInfoActivity.kt b/app-common/src/main/java/im/angry/openeuicc/ui/EuiccInfoActivity.kt index bfbcbd8..248afaf 100644 --- a/app-common/src/main/java/im/angry/openeuicc/ui/EuiccInfoActivity.kt +++ b/app-common/src/main/java/im/angry/openeuicc/ui/EuiccInfoActivity.kt @@ -123,7 +123,13 @@ class EuiccInfoActivity : BaseEuiccAccessActivity(), OpenEuiccContextMarker { add(Item(R.string.euicc_info_pp_version, info.ppVersion.toString())) info.sasAccreditationNumber.trim().takeIf(RE_SAS::matches) ?.let { add(Item(R.string.euicc_info_sas_accreditation_number, it.uppercase())) } - add(Item(R.string.euicc_info_free_nvram, info.freeNvram.let(::formatFreeSpace))) + + val nvramText = buildString { + append(formatFreeSpace(info.freeNvram)) + append(' ') + append(getString(R.string.euicc_info_free_nvram_hint)) + } + add(Item(R.string.euicc_info_free_nvram, nvramText)) } channel.lpa.euiccInfo2?.euiccCiPKIdListForSigning.orEmpty().let { signers -> // SGP.28 v1.0, eSIM CI Registration Criteria (Page 5 of 9, 2019-10-24) diff --git a/app-common/src/main/res/values-zh-rCN/strings.xml b/app-common/src/main/res/values-zh-rCN/strings.xml index e947c6a..3865e71 100644 --- a/app-common/src/main/res/values-zh-rCN/strings.xml +++ b/app-common/src/main/res/values-zh-rCN/strings.xml @@ -136,6 +136,7 @@ SAS 认证号码 Protected Profile 版本 NVRAM 剩余空间 (eSIM 存储容量) + (仅供参考) 证书签发者 (CI) GSMA 生产环境 CI GSMA 测试 CI diff --git a/app-common/src/main/res/values/strings.xml b/app-common/src/main/res/values/strings.xml index 3a9dda3..7d0898a 100644 --- a/app-common/src/main/res/values/strings.xml +++ b/app-common/src/main/res/values/strings.xml @@ -165,6 +165,7 @@ SAS Accreditation Number Protected Profile Version Free NVRAM (eSIM profile storage) + (for reference only) Certificate Issuer (CI) GSMA Live CI GSMA Test CI From acfeda8dc9ff251cce5511b6946541add6949999 Mon Sep 17 00:00:00 2001 From: Peter Cai Date: Sun, 7 Sep 2025 17:45:18 -0400 Subject: [PATCH 3/3] i18n: Translate new strings added recently --- app-common/src/main/res/values-ja/strings.xml | 24 +++++++++++++++++++ .../src/main/res/values-zh-rCN/strings.xml | 23 ++++++++++++++++++ .../src/main/res/values-zh-rTW/strings.xml | 24 +++++++++++++++++++ app-common/src/main/res/values/strings.xml | 2 +- 4 files changed, 72 insertions(+), 1 deletion(-) diff --git a/app-common/src/main/res/values-ja/strings.xml b/app-common/src/main/res/values-ja/strings.xml index 946625f..da9d708 100644 --- a/app-common/src/main/res/values-ja/strings.xml +++ b/app-common/src/main/res/values-ja/strings.xml @@ -6,6 +6,7 @@ 情報がありません ヘルプ スロットを再読み込み + 未知 論理スロット %d 有効済み 無効済み @@ -83,6 +84,7 @@ 最終の APDU 例外: 保存 「%s」での診断 + 別のネットワークに接続し(例:Wi-Fi とデータを切り替える)、もう一度お試しください。 ログは共有したパスに保存されました。別のアプリで共有しますか? 新しいニックネーム ニックネームを UTF-8 にエンコードできませんでした @@ -114,6 +116,7 @@ SAS 認定番号 保護されたプロファイルのバージョン NVRAM の空き容量 (eSIM プロファイルストレージ) + (目安) 証明書発行者 (CI) GSMA ライブ CI GSMA テスト CI @@ -150,6 +153,7 @@ SM-DP+ TLS 証明書を無視する RSP サーバーで使用される TLS 証明書を受け入れます 一部のブランドの取り外し可能な eUICC では、独自の非標準 ISD-R AID が使用されている場合があり、サードパーティ アプリからアクセスできなくなります。アプリはこのリストに追加された非標準の AID の使用を試みる可能性がありますが、動作することは保証されません。 + グローバル ES10x MSS 情報 アプリバージョン ソースコード @@ -169,4 +173,24 @@ ISD-R AID リストのカスタマイズ リセット ISD-R AID リスト + この eSIM プロファイルはすでに eSIM チップに存在しています。 + eSIM チップには十分なメモリ容量が残っていません。 + この eSIM プロファイルは、ダウンロード先のeSIM チップではサポートされていません。 + eSIMチップでエラーが発生しました。 + お使いのデバイスまたは eSIM チップの EID は、通信事業者によってサポートされていません。 + この eSIM プロファイルはすでに別のデバイスにダウンロードされています。 + この eSIM プロファイルはキャンセルされました。 + アクティベーションコードが無効です。 + eSIM プロファイルのダウンロード試行回数の上限を超えました。 + このプロファイルをダウンロードするには確認コードが必要です。 + 入力した確認コードは無効です。 + この eSIM プロファイルの有効期限が切れています。 + 確認コードのダウンロード試行回数の上限を超えました。 + 不明なSM-DP+アドレス + ネットワークにアクセスできません + TLS証明書エラー。このeSIMプロファイルはサポートされていません + すでにダウンロードしたeSIMプロファイルを再インストールしようとしています + 不要なeSIMプロファイルをいくつか削除して、もう一度お試しください + 通信事業者にお問い合わせください。 + この eSIM プロファイルを再発行するには、通信事業者にお問い合わせください。 diff --git a/app-common/src/main/res/values-zh-rCN/strings.xml b/app-common/src/main/res/values-zh-rCN/strings.xml index 3865e71..4457e6d 100644 --- a/app-common/src/main/res/values-zh-rCN/strings.xml +++ b/app-common/src/main/res/values-zh-rCN/strings.xml @@ -5,6 +5,7 @@ 未知 帮助 重新加载卡槽 + 未知 逻辑卡槽 %d 已启用 已禁用 @@ -46,6 +47,7 @@ IMEI (可选) 剩余空间不足 当前芯片的剩余空间不足,可能导致配置下载失败。\n是否继续下载? + 请连接到其他网络(例如在 Wi-Fi 和数据之间切换)后重试。 日志已保存到指定路径。需要通过其他 App 分享吗? 新昵称 无法将昵称编码为 UTF-8 @@ -83,6 +85,7 @@ 日志 查看应用程序的最新调试日志 某些品牌的可移除 eUICC 可能会使用自己的非标准 ISD-R AID,导致第三方应用无法访问。此 App 可以尝试使用此列表中添加的非标准 AID,但不能保证它们一定有效。 + 全局 ES10x MSS 信息 App 版本 源码 @@ -170,4 +173,24 @@ 自定义 ISD-R AID 列表 重置 ISD-R AID 列表 + 此 eSIM 配置文件已存在于您的 eSIM 芯片上。 + 您的 eSIM 芯片没有足够的空间来下载配置文件。 + 您的 eSIM 芯片不支持此 eSIM 配置文件。 + eSIM 芯片错误。 + 您的设备或 eSIM 芯片的 EID 不受您的运营商支持。 + 此 eSIM 配置文件已被下载到另一台设备上。 + 此 eSIM 配置文件已被撤销。 + 激活码无效。 + 已超出 eSIM 配置文件的最大下载尝试次数。 + 下载此配置文件需要确认码。 + 您输入的确认码无效。 + 此 eSIM 配置文件已过期。 + 已超出确认码的最大下载尝试次数。 + 未知的 SM-DP+ 地址 + 网络不可达 + TLS 证书错误,不支持此 eSIM 配置文件 + 您正在尝试重新安装已下载的 eSIM 配置文件 + 请删除一些未使用的 eSIM 配置文件,然后重试 + 请联系您的运营商寻求帮助。 + 请联系您的运营商重新签发此 eSIM 配置文件。 \ No newline at end of file diff --git a/app-common/src/main/res/values-zh-rTW/strings.xml b/app-common/src/main/res/values-zh-rTW/strings.xml index 88cc011..ef6c842 100644 --- a/app-common/src/main/res/values-zh-rTW/strings.xml +++ b/app-common/src/main/res/values-zh-rTW/strings.xml @@ -5,6 +5,7 @@ 未知 幫助 重新載入卡槽 + 未知 虛擬卡槽 %d 已啟用 已停用 @@ -46,6 +47,7 @@ IMEI (可選) 剩餘空間不足 目前晶片的剩餘空間不足,可能導致配置下載失敗。\n是否繼續下載? + 請連接到其他網路(例如在 Wi-Fi 和資料之間切換)後重試。 日誌已儲存到指定路徑。需要透過其他 App 分享嗎? 新名稱 無法將名稱編碼為 UTF-8 @@ -83,6 +85,7 @@ 允許 停用/刪除 已啟用的設定檔 預設情況下,此應用程式會阻止您停用可插拔 eSIM 中已啟用的設定檔。\n因為這樣做 有時 會導致無法存取。\n勾選此框以 移除 此保護措施。 某些品牌的可移除 eUICC 可能會使用自己的非標準 ISD-R AID,導致第三方應用程式無法存取。此 App 可以嘗試使用此清單中新增的非標準 AID,但不能保證它們一定有效。 + 全局 ES10x MSS 資訊 App 版本 原始碼 @@ -136,6 +139,7 @@ SAS 認證號碼 Protected Profile 版本 NVRAM 剩餘空間 (eSIM 儲存容量) + (僅供參考) 證書簽發者 (CI) GSMA 生產環境 CI GSMA 測試 CI @@ -169,4 +173,24 @@ 自訂 ISD-R AID 列表 重置 ISD-R AID 列表 + 此 eSIM 設定檔已存在於您的 eSIM 晶片上。 + 您的 eSIM 晶片沒有足夠的空間來下載設定檔。 + 您的 eSIM 晶片不支援此 eSIM 設定檔。 + eSIM 晶片錯誤。 + 您的裝置或 eSIM 晶片的 EID 不受您的電信業者支援。 + 此 eSIM 設定檔已被下載到另一台裝置上。 + 此 eSIM 設定檔已被撤銷。 + 啟用碼無效。 + 已超出 eSIM 設定檔的最大下載嘗試次數。 + 下載此設定檔需要確認碼。 + 您輸入的確認碼無效。 + 此 eSIM 設定檔已過期。 + 已超出確認碼的最大下載嘗試次數。 + 未知的 SM-DP+ 位址 + 網路不可達 + TLS 憑證錯誤,不支援此 eSIM 設定檔 + 您正在嘗試重新安裝已下載的 eSIM 設定文件 + 請刪除一些未使用的 eSIM 設定文件,然後重試 + 請聯絡您的電信業者尋求協助。 + 請聯絡您的電信業者重新簽發此 eSIM 設定檔。 \ No newline at end of file diff --git a/app-common/src/main/res/values/strings.xml b/app-common/src/main/res/values/strings.xml index 7d0898a..a7f2c10 100644 --- a/app-common/src/main/res/values/strings.xml +++ b/app-common/src/main/res/values/strings.xml @@ -222,7 +222,7 @@ Accept any TLS certificate used by the RSP server Allow erasing eUICC This is a dangerous operation and hidden by default. As an alternative, you can delete all profiles manually. - ES10x MSS + ES10x MSS Global ES10x MSS High Speed