From 00e32826abaf53dbd9e2c9df32bc099d86929320 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 17 Apr 2025 14:30:23 +0200 Subject: [PATCH] Apply workaround when making a call to a SIP URI having a phone number as username & IP as domain --- .../compatibility/Api29Compatibility.kt | 5 ++++ .../linphone/compatibility/Compatibility.kt | 8 +++++ .../java/org/linphone/core/CoreContext.kt | 29 +++++++++++++++---- 3 files changed, 36 insertions(+), 6 deletions(-) diff --git a/app/src/main/java/org/linphone/compatibility/Api29Compatibility.kt b/app/src/main/java/org/linphone/compatibility/Api29Compatibility.kt index 200e8c9f6..6f0826d77 100644 --- a/app/src/main/java/org/linphone/compatibility/Api29Compatibility.kt +++ b/app/src/main/java/org/linphone/compatibility/Api29Compatibility.kt @@ -20,6 +20,7 @@ package org.linphone.compatibility import android.content.Intent +import android.net.InetAddresses.isNumericAddress import android.net.Uri import android.os.Build import android.provider.MediaStore @@ -62,5 +63,9 @@ class Api29Compatibility { session.contentCaptureContext = ContentCaptureContext.forLocusId(conversationId) } } + + fun isIpAddress(string: String): Boolean { + return isNumericAddress(string) + } } } diff --git a/app/src/main/java/org/linphone/compatibility/Compatibility.kt b/app/src/main/java/org/linphone/compatibility/Compatibility.kt index 9d828fb55..153dcf00f 100644 --- a/app/src/main/java/org/linphone/compatibility/Compatibility.kt +++ b/app/src/main/java/org/linphone/compatibility/Compatibility.kt @@ -28,6 +28,7 @@ import android.content.Context import android.content.Intent import android.net.Uri import android.os.Environment +import android.util.Patterns import android.view.View import androidx.appcompat.app.AppCompatDelegate import org.linphone.core.tools.Log @@ -186,5 +187,12 @@ class Compatibility { Api35Compatibility.setupAppStartupListener(context) } } + + fun isIpAddress(string: String): Boolean { + if (Version.sdkAboveOrEqual(Version.API29_ANDROID_10)) { + return Api29Compatibility.isIpAddress(string) + } + return Patterns.IP_ADDRESS.matcher(string).matches() + } } } diff --git a/app/src/main/java/org/linphone/core/CoreContext.kt b/app/src/main/java/org/linphone/core/CoreContext.kt index d64f615a8..04a9f9130 100644 --- a/app/src/main/java/org/linphone/core/CoreContext.kt +++ b/app/src/main/java/org/linphone/core/CoreContext.kt @@ -34,12 +34,14 @@ import android.provider.Settings.SettingNotFoundException import androidx.annotation.AnyThread import androidx.annotation.UiThread import androidx.annotation.WorkerThread +import androidx.core.text.isDigitsOnly import androidx.lifecycle.MutableLiveData import com.google.firebase.crashlytics.FirebaseCrashlytics import kotlin.system.exitProcess import org.linphone.BuildConfig import org.linphone.LinphoneApplication.Companion.coreContext import org.linphone.LinphoneApplication.Companion.corePreferences +import org.linphone.compatibility.Compatibility import org.linphone.contacts.ContactsManager import org.linphone.core.tools.Log import org.linphone.notifications.NotificationsManager @@ -837,10 +839,6 @@ class CoreContext if (forceZRTP) { params.mediaEncryption = MediaEncryption.ZRTP } - /*if (LinphoneUtils.checkIfNetworkHasLowBandwidth(context)) { - Log.w("$TAG Enabling low bandwidth mode!") - params.isLowBandwidthEnabled = true - }*/ params.recordFile = LinphoneUtils.getRecordingFilePathForAddress(address) @@ -860,8 +858,27 @@ class CoreContext } } - val call = core.inviteAddressWithParams(address, params) - Log.i("$TAG Starting call $call") + val username = address.username.orEmpty() + val domain = address.domain.orEmpty() + val defaultAccount = params.account ?: core.defaultAccount + if (defaultAccount != null && Compatibility.isIpAddress(domain)) { + Log.i("$TAG SIP URI [${address.asStringUriOnly()}] seems to have an IP address as domain") + if (username.isNotEmpty() && (username.startsWith("+") || username.isDigitsOnly())) { + val identityDomain = defaultAccount.params.identityAddress?.domain + Log.w("$TAG Username [$username] looks like a phone number, replacing domain [$domain] by the local account one [$identityDomain]") + if (identityDomain != null) { + val newAddress = address.clone() + newAddress.domain = identityDomain + + core.inviteAddressWithParams(newAddress, params) + Log.i("$TAG Starting call to [${newAddress.asStringUriOnly()}]") + return + } + } + } + + core.inviteAddressWithParams(address, params) + Log.i("$TAG Starting call to [${address.asStringUriOnly()}]") } @WorkerThread