diff --git a/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardDetailsFragment.kt b/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardDetailsFragment.kt index 5fa8002..69ed77f 100644 --- a/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardDetailsFragment.kt +++ b/app-common/src/main/java/im/angry/openeuicc/ui/wizard/DownloadWizardDetailsFragment.kt @@ -48,9 +48,8 @@ class DownloadWizardDetailsFragment : DownloadWizardActivity.DownloadWizardStepF matchingId = view.requireViewById(R.id.profile_download_code) confirmationCode = view.requireViewById(R.id.profile_download_confirmation_code) imei = view.requireViewById(R.id.profile_download_imei) - smdp.editText!!.addTextChangedListener { - updateInputCompleteness() - } + smdp.editText!!.addTextChangedListener { updateInputCompleteness() } + imei.editText!!.addTextChangedListener { updateInputCompleteness() } return view } @@ -69,7 +68,34 @@ class DownloadWizardDetailsFragment : DownloadWizardActivity.DownloadWizardStepF } private fun updateInputCompleteness() { - inputComplete = Patterns.DOMAIN_NAME.matcher(smdp.editText!!.text).matches() + inputComplete = runCatching(::validate).isSuccess refreshButtons() } -} \ No newline at end of file + + private fun validate() { + check(Patterns.DOMAIN_NAME.matcher(smdp.editText!!.text).matches()) { + "Invalid SM-DP+ address" + } + check(imei.editText!!.text.let { it.isEmpty() || isValidIMEI(it) }) { + "Invalid IMEI" + } + } +} + +private fun isValidIMEI(input: CharSequence): Boolean { + if (input.length != 15 || !input.all(Char::isDigit)) return false + + fun sumOfDigits(input: Int): Int { + if (input % 2 == 0) return input + var n = input + var sum = 0 + while (n > 0) { + sum += n % 10 + n /= 10 + } + return sum + } + + val sum = input.dropLast(1).map(Char::digitToInt).sumOf(::sumOfDigits) + return (sum * 9) % 10 == input.last().digitToInt() +}