diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 31742c10..9886f1ed 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -8,6 +8,7 @@
+
diff --git a/app/src/main/cpp/baresip.c b/app/src/main/cpp/baresip.c
index bce0d737..30747fa1 100644
--- a/app/src/main/cpp/baresip.c
+++ b/app/src/main/cpp/baresip.c
@@ -5,19 +5,9 @@
#include
#include
#include
+#include "logger.h"
-#define LOGD(...) \
- if (log_level_get() < LEVEL_INFO) ((void)__android_log_print(ANDROID_LOG_DEBUG, "Baresip Lib", __VA_ARGS__))
-
-#define LOGI(...) \
- if (log_level_get() < LEVEL_WARN) ((void)__android_log_print(ANDROID_LOG_DEBUG, "Baresip Lib", __VA_ARGS__))
-
-#define LOGW(...) \
- if (log_level_get() < LEVEL_ERROR) ((void)__android_log_print(ANDROID_LOG_DEBUG, "Baresip Lib", __VA_ARGS__))
-
-#define LOGE(...) \
- if (log_level_get() <= LEVEL_ERROR) ((void)__android_log_print(ANDROID_LOG_DEBUG, "Baresip Lib", __VA_ARGS__))
-
+#define LOG_TAG "Baresip Lib"
typedef struct baresip_context {
JavaVM *javaVM;
@@ -202,6 +192,8 @@ static void ua_event_handler(struct ua *ua, enum ua_event ev,
len = re_snprintf(event_buf, sizeof event_buf, "call answered", prm);
break;
case UA_EVENT_CALL_LOCAL_SDP:
+ if (strcmp(prm, "offer") == 0)
+ return;
len = re_snprintf(event_buf, sizeof event_buf, "call %sed", prm);
break;
case UA_EVENT_CALL_RINGING:
@@ -436,23 +428,12 @@ JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM* vm, void* reserved) {
return JNI_VERSION_1_6;
}
-JNIEXPORT jint JNICALL
-Java_com_tutpro_baresip_Api_net_1add_1address(JNIEnv *env, jobject thiz, jstring javaIp);
-
-JNIEXPORT jint JNICALL
-Java_com_tutpro_baresip_Api_net_1use_1nameserver(JNIEnv *env, jobject thiz, jstring javaServers);
-
JNIEXPORT void JNICALL
-Java_com_tutpro_baresip_BaresipService_baresipStart(JNIEnv *env, jobject instance,
- jstring jPath, jstring jIpAddrs, jstring jNetInterface, jint jNetAf, jint jLogLevel) {
+Java_com_tutpro_baresip_BaresipService_baresipStart(JNIEnv *env, jobject instance, jstring jPath,
+ jstring jAddrs, jint jLogLevel) {
LOGI("starting baresip\n");
- const char *net_interface = (*env)->GetStringUTFChars(env, jNetInterface, 0);
- const int net_af = jNetAf;
-
- const char *ip_addrs = (*env)->GetStringUTFChars(env, jIpAddrs, 0);
-
char start_error[64] = "";
JavaVM *javaVM = g_ctx.javaVM;
@@ -468,6 +449,7 @@ Java_com_tutpro_baresip_BaresipService_baresipStart(JNIEnv *env, jobject instanc
int err;
const char *path = (*env)->GetStringUTFChars(env, jPath, 0);
+ const char *addrs = (*env)->GetStringUTFChars(env, jAddrs, 0);
struct le *le;
runLoggingThread();
@@ -487,15 +469,6 @@ Java_com_tutpro_baresip_BaresipService_baresipStart(JNIEnv *env, jobject instanc
goto out;
}
- if (strlen(net_interface) > 0) {
- struct config *theconf = conf_config();
- str_ncpy(theconf->net.ifname, net_interface,
- sizeof(theconf->net.ifname));
- }
-
- if (net_af != AF_UNSPEC)
- conf_config()->net.af = net_af;
-
err = baresip_init(conf_config());
if (err) {
LOGW("baresip_init() failed (%d)\n", err);
@@ -503,20 +476,21 @@ Java_com_tutpro_baresip_BaresipService_baresipStart(JNIEnv *env, jobject instanc
goto out;
}
- if (strlen(ip_addrs) > 0) {
- char* addr_list = (char*)malloc(strlen(ip_addrs));
+ if (strlen(addrs) > 0) {
+ char* addr_list = (char*)malloc(strlen(addrs));
struct sa temp_sa;
char buf[256];
net_flush_addresses(baresip_network());
- strcpy(addr_list, ip_addrs);
+ strcpy(addr_list, addrs);
char *ptr = strtok(addr_list, ";");
while (ptr != NULL) {
- LOGI("adding address '%s'", ptr);
if (0 == sa_set_str(&temp_sa, ptr, 0)) {
sa_ntop(&temp_sa, buf, 256);
- net_add_address(baresip_network(), &temp_sa);
+ ptr = strtok(NULL, ";");
+ net_add_address_ifname(baresip_network(), &temp_sa, ptr);
} else {
LOGE("invalid ip address %s\n", ptr);
+ ptr = strtok(NULL, ";");
res = EAFNOSUPPORT;
}
ptr = strtok(NULL, ";");
@@ -524,7 +498,7 @@ Java_com_tutpro_baresip_BaresipService_baresipStart(JNIEnv *env, jobject instanc
free(addr_list);
}
- net_debug_log();
+ // net_debug_log();
play_set_path(baresip_player(), path);
@@ -572,7 +546,6 @@ Java_com_tutpro_baresip_BaresipService_baresipStart(JNIEnv *env, jobject instanc
(*env)->DeleteLocalRef(env, javaUA);
}
- LOGI("allocating mqeue\n");
err = mqueue_alloc(&mq, mqueue_handler, NULL);
if (err) {
LOGW("mqueue_alloc failed (%d)\n", err);
@@ -1674,26 +1647,25 @@ Java_com_tutpro_baresip_Api_net_1use_1nameserver(JNIEnv *env, jobject thiz, jstr
}
JNIEXPORT jint JNICALL
-Java_com_tutpro_baresip_Api_net_1add_1address(JNIEnv *env, jobject thiz, jstring javaIp) {
- const char *native_ip = (*env)->GetStringUTFChars(env, javaIp, 0);
+Java_com_tutpro_baresip_Api_net_1add_1address_1ifname(JNIEnv *env, jobject thiz, jstring jAddr,
+ jstring jIfName) {
+ const char *addr = (*env)->GetStringUTFChars(env, jAddr, 0);
+ const char *name = (*env)->GetStringUTFChars(env, jIfName, 0);
int res = 0;
struct sa temp_sa;
char buf[256];
- LOGI("adding address '%s'\n", native_ip);
- if (str_len(native_ip) == 0) {
- (*env)->ReleaseStringUTFChars(env, javaIp, native_ip);
- return 0;
- }
- if (0 == sa_set_str(&temp_sa, native_ip, 0)) {
+ LOGD("adding address/ifname '%s/%s'\n", addr, name);
+ if (0 == sa_set_str(&temp_sa, addr, 0)) {
sa_ntop(&temp_sa, buf, 256);
re_thread_enter();
- net_add_address(baresip_network(), &temp_sa);
+ res = net_add_address_ifname(baresip_network(), &temp_sa, name);
re_thread_leave();
} else {
- LOGE("invalid ip address %s\n", native_ip);
+ LOGE("invalid ip address %s\n", addr);
res = EAFNOSUPPORT;
}
- (*env)->ReleaseStringUTFChars(env, javaIp, native_ip);
+ (*env)->ReleaseStringUTFChars(env, jAddr, addr);
+ (*env)->ReleaseStringUTFChars(env, jIfName, name);
return res;
}
@@ -1711,7 +1683,7 @@ Java_com_tutpro_baresip_Api_net_1rm_1address(JNIEnv *env, jobject thiz, jstring
if (0 == sa_set_str(&temp_sa, native_ip, 0)) {
sa_ntop(&temp_sa, buf, 256);
re_thread_enter();
- net_rm_address(baresip_network(), &temp_sa);
+ res = net_rm_address(baresip_network(), &temp_sa);
re_thread_leave();
} else {
LOGE("invalid ip address %s\n", native_ip);
diff --git a/app/src/main/kotlin/com/tutpro/baresip/Api.kt b/app/src/main/kotlin/com/tutpro/baresip/Api.kt
index bd35057b..d40ac7cb 100644
--- a/app/src/main/kotlin/com/tutpro/baresip/Api.kt
+++ b/app/src/main/kotlin/com/tutpro/baresip/Api.kt
@@ -75,7 +75,7 @@ object Api {
external fun log_level_set(level: Int)
external fun net_use_nameserver(servers: String): Int
- external fun net_add_address(ip_addr: String): Int
+ external fun net_add_address_ifname(ip_addr: String, if_name: String): Int
external fun net_rm_address(ip_addr: String): Int
external fun net_debug()
external fun net_dns_debug()
diff --git a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt
index 16a06995..b56bcf04 100644
--- a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt
+++ b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt
@@ -19,6 +19,8 @@ import android.text.SpannableString
import android.text.style.ForegroundColorSpan
import android.view.View
import android.widget.RemoteViews
+import android.content.Intent
+import android.content.BroadcastReceiver
import androidx.annotation.ColorRes
import androidx.annotation.Keep
import androidx.annotation.StringRes
@@ -48,15 +50,18 @@ class BaresipService: Service() {
private lateinit var partialWakeLock: PowerManager.WakeLock
private lateinit var proximityWakeLock: PowerManager.WakeLock
private lateinit var wifiLock: WifiManager.WifiLock
- private lateinit var br: BroadcastReceiver
+ private lateinit var bluetoothReceiver: BroadcastReceiver
+ private lateinit var hotSpotReceiver: BroadcastReceiver
private var rtTimer: Timer? = null
private var audioFocusRequest: AudioFocusRequest? = null
private var audioFocusUsage = -1
private var origVolume = -1
private val btAdapter = BluetoothAdapter.getDefaultAdapter()
+ private var linkAddresses = mutableMapOf()
private var activeNetwork: Network? = null
- private var linkAddresses = mutableListOf()
+ private var hotSpotIsEnabled = false
+ private var hotSpotAddresses = mapOf()
@SuppressLint("WakelockTimeout")
override fun onCreate() {
@@ -102,21 +107,35 @@ class BaresipService: Service() {
override fun onAvailable(network: Network) {
super.onAvailable(network)
- Log.i(TAG, "Network $network is available")
- updateNetwork()
+ Log.d(TAG, "Network $network is available")
+ // If API >= 26, this will be followed by onCapabilitiesChanged
+ if (isServiceRunning && VERSION.SDK_INT < 26)
+ updateNetwork()
+ }
+
+ override fun onLosing(network: Network, maxMsToLive: Int) {
+ super.onLosing(network, maxMsToLive)
+ Log.d(TAG, "Network $network is losing after $maxMsToLive ms")
}
override fun onLost(network: Network) {
super.onLost(network)
- Log.i(TAG, "Network $network is lost")
- if (activeNetwork == network)
+ Log.d(TAG, "Network $network is lost")
+ if (isServiceRunning)
+ updateNetwork()
+ }
+
+ override fun onCapabilitiesChanged(network: Network, caps: NetworkCapabilities) {
+ super.onCapabilitiesChanged(network, caps)
+ Log.d(TAG, "Network $network capabilities changed: $caps")
+ if (isServiceRunning)
updateNetwork()
}
override fun onLinkPropertiesChanged(network: Network, props: LinkProperties) {
super.onLinkPropertiesChanged(network, props)
- Log.i(TAG, "Network $network link properties changed")
- if (activeNetwork == network)
+ Log.d(TAG, "Network $network link properties changed: $props")
+ if (isServiceRunning)
updateNetwork()
}
@@ -124,6 +143,55 @@ class BaresipService: Service() {
)
wm = applicationContext.getSystemService(Context.WIFI_SERVICE) as WifiManager
+ hotSpotIsEnabled = Utils.isHotSpotOn(wm)
+
+ hotSpotReceiver = object : BroadcastReceiver() {
+ override fun onReceive(contxt: Context, intent: Intent) {
+ val action = intent.action
+ if ("android.net.wifi.WIFI_AP_STATE_CHANGED" == action) {
+ val state = intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE, 0)
+ if (WifiManager.WIFI_STATE_ENABLED == state % 10) {
+ if (hotSpotIsEnabled) {
+ Log.d(TAG, "HotSpot is still enabled")
+ } else {
+ Log.d(TAG, "HotSpot is enabled")
+ hotSpotIsEnabled = true
+ Timer().schedule(1000) {
+ hotSpotAddresses = Utils.hotSpotAddresses()
+ Log.d(TAG, "HotSpot addresses $hotSpotAddresses")
+ if (hotSpotAddresses.isNotEmpty()) {
+ for ((k, v) in hotSpotAddresses)
+ if (Api.net_add_address_ifname(k, v) != 0)
+ Log.e(TAG, "Failed to add $v address $k")
+ Timer().schedule(2000) {
+ Api.uag_reset_transp(register = true, reinvite = false)
+ }
+ } else {
+ Log.w(TAG, "Could not get hotspot addresses")
+ }
+ }
+ }
+ } else {
+ if (!hotSpotIsEnabled) {
+ Log.d(TAG, "HotSpot is still disabled")
+ } else {
+ Log.d(TAG, "HotSpot is disabled")
+ hotSpotIsEnabled = false
+ if (hotSpotAddresses.isNotEmpty()) {
+ for ((k, _) in hotSpotAddresses)
+ if (Api.net_rm_address(k) != 0)
+ Log.e(TAG, "Failed to remove address $k")
+ hotSpotAddresses = mapOf()
+ Api.uag_reset_transp(register = true, reinvite = false)
+ }
+ }
+ }
+ }
+ }
+ }
+
+ this.registerReceiver(hotSpotReceiver,
+ IntentFilter("android.net.wifi.WIFI_AP_STATE_CHANGED"))
tm = getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
@@ -133,7 +201,7 @@ class BaresipService: Service() {
wifiLock = wm.createWifiLock(WifiManager.WIFI_MODE_FULL_HIGH_PERF, "Baresip")
wifiLock.setReferenceCounted(false)
- br = object : BroadcastReceiver() {
+ bluetoothReceiver = object : BroadcastReceiver() {
override fun onReceive(ctx: Context, intent: Intent) {
when (intent.action) {
BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED -> {
@@ -206,7 +274,7 @@ class BaresipService: Service() {
filter.addAction(BluetoothHeadset.ACTION_CONNECTION_STATE_CHANGED)
filter.addAction(BluetoothHeadset.ACTION_AUDIO_STATE_CHANGED)
filter.addAction(AudioManager.ACTION_SCO_AUDIO_STATE_UPDATED)
- this.registerReceiver(br, filter)
+ this.registerReceiver(bluetoothReceiver, filter)
}
super.onCreate()
@@ -230,26 +298,12 @@ class BaresipService: Service() {
"Start" -> {
- var ipAddrs = ""
- for (n in cm.allNetworks) {
- val props = cm.getLinkProperties(n)
- if (props != null) {
- for (a in props.linkAddresses)
- linkAddresses.add(a)
- val addrs = Utils.hostAddresses(props.linkAddresses)
- if (addrs != "") {
- if (ipAddrs == "")
- ipAddrs = addrs
- else
- ipAddrs += ";$addrs"
- }
- }
- }
-
updateDnsServers()
- val assets = arrayOf("accounts", "config", "contacts", "busy.wav", "callwaiting.wav",
- "error.wav", "ringback.wav")
+ val assets = arrayOf(
+ "accounts", "config", "contacts", "busy.wav", "callwaiting.wav",
+ "error.wav", "ringback.wav"
+ )
var file = File(filesPath)
if (!file.exists()) {
Log.d(TAG, "Creating baresip directory")
@@ -278,13 +332,15 @@ class BaresipService: Service() {
CallHistory.restore()
Message.restore()
- if (ipAddrs == "")
- Log.w(TAG, "Starting baresip without IP addresses")
+ linkAddresses = linkAddresses()
+ var addrs = ""
+ for (la in linkAddresses)
+ addrs = "$addrs;${la.key};${la.value}"
+
+ Log.d(TAG, "Link addresses: $addrs")
Thread {
- baresipStart(
- filesPath, ipAddrs, "", Api.AF_UNSPEC, logLevel
- )
+ baresipStart(filesPath, addrs.removePrefix(";"), logLevel)
}.start()
isServiceRunning = true
@@ -293,11 +349,22 @@ class BaresipService: Service() {
if (AccountsActivity.noAccounts()) {
val newIntent = Intent(this, MainActivity::class.java)
- newIntent.flags = Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP or
- Intent.FLAG_ACTIVITY_NEW_TASK
+ newIntent.flags =
+ Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP or
+ Intent.FLAG_ACTIVITY_NEW_TASK
newIntent.putExtra("action", "accounts")
startActivity(newIntent)
}
+
+ if (linkAddresses.isEmpty()) {
+ val newIntent = Intent(this, MainActivity::class.java)
+ newIntent.flags =
+ Intent.FLAG_ACTIVITY_SINGLE_TOP or Intent.FLAG_ACTIVITY_CLEAR_TOP or
+ Intent.FLAG_ACTIVITY_NEW_TASK
+ newIntent.putExtra("action", "no network")
+ startActivity(newIntent)
+ }
+
}
"Call Reject" -> {
@@ -333,8 +400,10 @@ class BaresipService: Service() {
if (ua == null)
Log.w(TAG, "onStartCommand did not find UA $uap")
else
- ChatsActivity.saveUaMessage(ua.account.aor,
- intent.getStringExtra("time")!!.toLong())
+ ChatsActivity.saveUaMessage(
+ ua.account.aor,
+ intent.getStringExtra("time")!!.toLong()
+ )
nm.cancel(MESSAGE_NOTIFICATION_ID)
}
@@ -344,8 +413,10 @@ class BaresipService: Service() {
if (ua == null)
Log.w(TAG, "onStartCommand did not find UA $uap")
else
- ChatsActivity.deleteUaMessage(ua.account.aor,
- intent.getStringExtra("time")!!.toLong())
+ ChatsActivity.deleteUaMessage(
+ ua.account.aor,
+ intent.getStringExtra("time")!!.toLong()
+ )
nm.cancel(MESSAGE_NOTIFICATION_ID)
}
@@ -376,7 +447,8 @@ class BaresipService: Service() {
override fun onDestroy() {
Log.d(TAG, "At Baresip Service onDestroy")
super.onDestroy()
- this.unregisterReceiver(br)
+ this.unregisterReceiver(bluetoothReceiver)
+ this.unregisterReceiver(hotSpotReceiver)
if (am.isBluetoothScoOn) am.stopBluetoothSco()
cleanService()
if (isServiceRunning) {
@@ -847,6 +919,7 @@ class BaresipService: Service() {
@Keep
fun started() {
Log.d(TAG, "Received 'started' from baresip")
+ Api.net_debug()
val intent = Intent("service event")
intent.putExtra("event", "started")
intent.putExtra("params", arrayListOf(callActionUri))
@@ -1084,56 +1157,87 @@ class BaresipService: Service() {
}
private fun updateNetwork() {
+
+ if (!isServiceRunning)
+ return
+
/* for (n in cm.allNetworks)
- Log.i(TAG, "NETWORK $n with caps ${cm.getNetworkCapabilities(n)} and props " +
+ Log.d(TAG, "NETWORK $n with caps ${cm.getNetworkCapabilities(n)} and props " +
"${cm.getLinkProperties(n)} is active ${isNetworkActive(n)}") */
- activeNetwork = activeNetwork()
+
+ updateDnsServers()
+
+ val lnAddrs = linkAddresses()
+
+ Log.d(TAG, "Old/new link addresses $linkAddresses/$lnAddrs")
+
+ var added = 0
+ for (a in lnAddrs)
+ if (!linkAddresses.containsKey(a.key)) {
+ if (Api.net_add_address_ifname(a.key, a.value) != 0)
+ Log.e(TAG, "Failed to add address: $a")
+ else
+ added++
+ }
+ var removed = 0
+ for (a in linkAddresses)
+ if (!lnAddrs.containsKey(a.key)) {
+ if (Api.net_rm_address(a.key) != 0)
+ Log.e(TAG, "Failed to remove address: $a")
+ else
+ removed++
+ }
+
+ val active = activeNetwork()
+ Log.d(TAG, "Added/Removed/Active = $added/$removed/$active")
+
+ if (added > 0 || removed > 0 || active != activeNetwork) {
+ linkAddresses = lnAddrs
+ activeNetwork = active
+ Api.uag_reset_transp(register = true, reinvite = true)
+ }
+
+ Api.net_debug()
+
if (activeNetwork != null) {
- val linkCaps = cm.getNetworkCapabilities(activeNetwork)
- val linkProps = cm.getLinkProperties(activeNetwork)
- Log.d(TAG, "Using active network $activeNetwork with caps: $linkCaps, props: $linkProps")
- val lnAddrs = mutableListOf()
- for (n in cm.allNetworks) {
- val props = cm.getLinkProperties(n)
- if (props != null)
- for (a in props.linkAddresses)
- lnAddrs.add(a)
- }
- var addrUpdate = false
- for (a in lnAddrs)
- if (!linkAddresses.contains(a)) {
- Api.net_add_address(a.address.hostAddress)
- addrUpdate = true
- }
- for (a in linkAddresses)
- if (!lnAddrs.contains(a)) {
- Api.net_rm_address(a.address.hostAddress)
- addrUpdate = true
- }
- val dnsUpdate = updateDnsServers()
- if (addrUpdate) {
- linkAddresses = lnAddrs
- Api.uag_reset_transp(register = true, reinvite = true)
- } else {
- if (dnsUpdate)
- UserAgent.register()
- }
- if (linkCaps != null && linkCaps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
+ val caps = cm.getNetworkCapabilities(activeNetwork)
+ if (caps != null && caps.hasTransport(NetworkCapabilities.TRANSPORT_WIFI)) {
Log.d(TAG, "Acquiring WiFi Lock")
wifiLock.acquire()
- } else {
- Log.d(TAG, "Releasing WiFi Lock")
- wifiLock.release()
+ return
}
- } else
- Log.w(TAG, "No active network")
+ }
+ Log.d(TAG, "Releasing WiFi Lock")
+ wifiLock.release()
}
- private fun updateDnsServers(): Boolean {
+ private fun linkAddresses(): MutableMap {
+ val lnAddrs = mutableMapOf()
+ for (n in cm.allNetworks) {
+ val caps = cm.getNetworkCapabilities(n) ?: continue
+ if (caps.hasCapability(NetworkCapabilities.NET_CAPABILITY_FOREGROUND) ||
+ VERSION.SDK_INT < 28) {
+ val props = cm.getLinkProperties(n) ?: continue
+ for (la in props.linkAddresses)
+ if (la.scope == android.system.OsConstants.RT_SCOPE_UNIVERSE &&
+ props.interfaceName != null)
+ lnAddrs[la.address.hostAddress] = props.interfaceName!!
+ }
+ }
+ if (hotSpotIsEnabled) {
+ hotSpotAddresses = Utils.hotSpotAddresses()
+ Log.d(TAG, "HotSpot addresses $hotSpotAddresses")
+ for ((k, v) in hotSpotAddresses)
+ lnAddrs[k] = v
+ }
+ return lnAddrs
+ }
+
+ private fun updateDnsServers() {
if (isServiceRunning && !dynDns)
- return false
+ return
val servers = mutableListOf()
- // Use DNS servers first from active network (if given)
+ // Use DNS servers first from active network (if available)
for (n in cm.allNetworks)
if (isNetworkActive(n)) {
val linkProps = cm.getLinkProperties(n)
@@ -1157,10 +1261,8 @@ class BaresipService: Service() {
} else {
// Log.d(TAG, "Updated DNS servers: '${servers}'")
dnsServers = servers
- return true
}
}
- return false
}
private fun activeNetwork(): Network? {
@@ -1200,8 +1302,7 @@ class BaresipService: Service() {
isServiceClean = true
}
- private external fun baresipStart(path: String, ipAddrs: String, netInterface: String,
- netAf: Int, logLevel: Int)
+ private external fun baresipStart(path: String, addrs: String, logLevel: Int)
private external fun baresipStop(force: Boolean)
companion object {
diff --git a/app/src/main/kotlin/com/tutpro/baresip/Config.kt b/app/src/main/kotlin/com/tutpro/baresip/Config.kt
index 9099a69c..2b23492a 100644
--- a/app/src/main/kotlin/com/tutpro/baresip/Config.kt
+++ b/app/src/main/kotlin/com/tutpro/baresip/Config.kt
@@ -1,7 +1,6 @@
package com.tutpro.baresip
import android.content.Context
-
import java.net.InetAddress
import java.nio.charset.StandardCharsets
diff --git a/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt
index de4dc843..da1cf15d 100644
--- a/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt
+++ b/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt
@@ -21,6 +21,8 @@ import android.text.TextWatcher
import android.view.*
import android.view.inputmethod.InputMethodManager
import android.widget.*
+import android.content.Intent
+import android.content.BroadcastReceiver
import androidx.activity.result.ActivityResultLauncher
import androidx.activity.result.contract.ActivityResultContracts
import androidx.annotation.RequiresApi
@@ -330,8 +332,12 @@ class MainActivity : AppCompatActivity() {
} else {
val latest = CallHistory.aorLatestHistory(aor)
if (latest != null)
- callUri.setText(Utils.friendlyUri(ContactsActivity.contactName(latest.peerUri),
- Utils.aorDomain(ua.account.aor)))
+ callUri.setText(
+ Utils.friendlyUri(
+ ContactsActivity.contactName(latest.peerUri),
+ Utils.aorDomain(ua.account.aor)
+ )
+ )
}
}
}
@@ -707,8 +713,14 @@ class MainActivity : AppCompatActivity() {
"accounts" -> {
resumeAction = "accounts"
}
+ "no network" -> {
+ Utils.alertView(this, getString(R.string.notice),
+ getString(R.string.no_network))
+ return
+ }
"call" -> {
if (Call.calls().isNotEmpty()) {
+
Toast.makeText(applicationContext, getString(R.string.call_already_active),
Toast.LENGTH_SHORT).show()
return
diff --git a/app/src/main/kotlin/com/tutpro/baresip/Utils.kt b/app/src/main/kotlin/com/tutpro/baresip/Utils.kt
index fd12a540..5c7c1d27 100644
--- a/app/src/main/kotlin/com/tutpro/baresip/Utils.kt
+++ b/app/src/main/kotlin/com/tutpro/baresip/Utils.kt
@@ -10,6 +10,7 @@ import android.graphics.Bitmap
import android.graphics.Bitmap.createScaledBitmap
import android.graphics.Color
import android.net.*
+import android.net.wifi.WifiManager
import android.os.Bundle
import android.os.Environment
import android.provider.DocumentsContract
@@ -24,20 +25,21 @@ import androidx.annotation.RequiresApi
import androidx.appcompat.app.AlertDialog
import androidx.core.app.ActivityCompat
import androidx.core.content.ContextCompat
-
import java.io.*
+import java.lang.reflect.Method
import java.security.SecureRandom
import java.util.*
import java.util.zip.ZipEntry
import java.util.zip.ZipFile
import java.util.zip.ZipOutputStream
-
+import java.net.InetAddress
+import java.net.NetworkInterface
+import java.net.SocketException
import javax.crypto.Cipher
import javax.crypto.SecretKeyFactory
import javax.crypto.spec.IvParameterSpec
import javax.crypto.spec.PBEKeySpec
import javax.crypto.spec.SecretKeySpec
-
import kotlin.collections.ArrayList
object Utils {
@@ -106,10 +108,14 @@ object Utils {
var u = uri
if (uri.startsWith("<") && (uri.endsWith(">")))
u = uri.substring(1).substringBeforeLast(">")
+ u = u.replace(":5060", "")
+ u = u.replace(";transport=udp", "", true)
+ if (u.split(":").size == 3 || uriParams(u).isNotEmpty())
+ return u
return if (u.contains("@")) {
val user = uriUserPart(u)
val host = uriHostPart(u)
- if (isE164Number(user) || (host == domain))
+ if (isE164Number(user) || host == domain)
user
else
"$user@$host"
@@ -277,17 +283,6 @@ object Utils {
return true
}
- fun hostAddresses(list: List?): String {
- var result = ""
- if (list != null) for (la in list)
- if (la.scope == android.system.OsConstants.RT_SCOPE_UNIVERSE)
- if (result == "")
- result = la.address.hostAddress
- else
- result += ";" + la.address.hostAddress
- return result
- }
-
fun implode(list: List, sep: String): String {
var res = ""
for (s in list) {
@@ -305,6 +300,39 @@ object Utils {
return appProcessInfo.importance == ActivityManager.RunningAppProcessInfo.IMPORTANCE_FOREGROUND
}
+ fun isHotSpotOn(wm: WifiManager): Boolean {
+ try {
+ val method: Method = wm.javaClass.getDeclaredMethod("isWifiApEnabled")
+ method.isAccessible = true
+ return method.invoke(wm) as Boolean
+ } catch (ignored: Throwable) {
+ }
+ return false
+ }
+
+ fun hotSpotAddresses(): Map {
+ val result = mutableMapOf()
+ try {
+ val interfaces: Enumeration = NetworkInterface.getNetworkInterfaces()
+ while (interfaces.hasMoreElements()) {
+ val iface: NetworkInterface = interfaces.nextElement()
+ val ifName = iface.name
+ if (ifName.startsWith("ap") || ifName.startsWith("wlan")) {
+ val addresses: Enumeration = iface.inetAddresses
+ while (addresses.hasMoreElements()) {
+ val inetAddress: InetAddress = addresses.nextElement()
+ if (!inetAddress.isLoopbackAddress && !inetAddress.isLinkLocalAddress)
+ result[inetAddress.hostAddress] = ifName
+ }
+ if (result.isNotEmpty()) return result
+ }
+ }
+ } catch (ex: SocketException) {
+ Log.e(TAG, ex.toString())
+ }
+ return result
+ }
+
fun dtmfWatcher(callp: String): TextWatcher {
return object : TextWatcher {
override fun beforeTextChanged(sequence: CharSequence, start: Int, count: Int, after: Int) {}
diff --git a/app/src/main/res/values-fi/strings.xml b/app/src/main/res/values-fi/strings.xml
index 75fa7d41..19ff89b5 100644
--- a/app/src/main/res/values-fi/strings.xml
+++ b/app/src/main/res/values-fi/strings.xml
@@ -495,4 +495,5 @@
Sinulla ei ole yhtään tuettua video-kameraa.
Näytä salasana
+ Ei verkkoyhteyttä!
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index bb958185..5cb60ad2 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -448,4 +448,5 @@
Grant \"Camera\" permission to place or answer video calls.
You don\'t have any supported video cameras.
Show Password
+ No network connection!