diff --git a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt index 87a922e9..f6ba87ed 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt @@ -1697,9 +1697,24 @@ class BaresipService: Service() { fun runCall(uap: Long, uri: String, conferenceCall: Boolean, onHoldCallp: Long) { val ua = UserAgent.ofUap(uap) - if (ua != null && ua.account.isMobile && Utils.isUssd(uri)) { - sendUssd(Utils.uriUserPart(uri)) - return + if (ua != null && ua.account.isMobile) { + val user = Utils.uriUserPart(uri) + if (user.startsWith("*#*#") && user.endsWith("#*#*")) { + val code = user.substring(4, user.length - 4) + val intent = Intent("android.provider.Telephony.SECRET_CODE", "android_secret_code://$code".toUri()) + sendBroadcast(intent) + postServiceEvent(ServiceEvent("ussd response", arrayListOf(uap, user, ""), System.nanoTime())) + return + } + if (user == "*#06#") { + val imei = getDeviceId(this) + postServiceEvent(ServiceEvent("imei", arrayListOf(uap, user, imei), System.nanoTime())) + return + } + if (Utils.isUssd(uri)) { + sendUssd(user) + return + } } val executeCall = { @@ -2338,6 +2353,16 @@ class BaresipService: Service() { } } + @SuppressLint("HardwareIds", "MissingPermission") + private fun getDeviceId(context: Context): String { + val tm = context.getSystemService(TELEPHONY_SERVICE) as TelephonyManager + return try { + tm.imei ?: tm.meid ?: "N/A" + } catch (_: SecurityException) { + "N/A" + } + } + private fun toast(message: String, length: Int = Toast.LENGTH_SHORT) { Handler(Looper.getMainLooper()).post { Toast.makeText(this, message, length).show() diff --git a/app/src/main/kotlin/com/tutpro/baresip/MainScreen.kt b/app/src/main/kotlin/com/tutpro/baresip/MainScreen.kt index 174067c3..e95a72af 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/MainScreen.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/MainScreen.kt @@ -2339,6 +2339,15 @@ fun handleServiceEvent(ctx: Context, viewModel: ViewModel, event: String, params val aor = ua.account.aor when (ev[0]) { + "imei" -> { + if (aor == viewModel.selectedAor.value) { + viewModel.dialerState.callButtonsEnabled.value = true + viewModel.dialerState.callUri.value = "" + } + handleDialog(ctx, ctx.getString(R.string.info), "IMEI: " + (params[2] as String)) + handleNextEvent() + return + } "ussd response" -> { if (aor == viewModel.selectedAor.value) { viewModel.dialerState.callButtonsEnabled.value = true diff --git a/app/src/main/kotlin/com/tutpro/baresip/Utils.kt b/app/src/main/kotlin/com/tutpro/baresip/Utils.kt index 166ad925..e42d9a5d 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/Utils.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/Utils.kt @@ -378,8 +378,9 @@ object Utils { } fun isUssd(uri: String): Boolean { - val user = uriUserPart(uri) - return user.startsWith("*") && user.endsWith("#") + val u = uriUserPart(uri) + // Must start with * or # and must end with #, but exclude "Secret Code" pattern (*#*#...#*#*) + return (u.startsWith("*") || u.startsWith("#")) && u.endsWith("#") && !u.startsWith("*#*#") } fun checkUri(uri: String): Boolean {