diff --git a/app/build.gradle b/app/build.gradle
index b2f720ca..7f12ccaf 100644
--- a/app/build.gradle
+++ b/app/build.gradle
@@ -7,8 +7,8 @@ android {
applicationId = 'com.tutpro.baresip'
minSdkVersion 21
targetSdkVersion 27
- versionCode = 36
- versionName = '4.1.2'
+ versionCode = 37
+ versionName = '5.0.0'
externalNativeBuild {
cmake {
cFlags '-DHAVE_INTTYPES_H'
diff --git a/app/src/main/AndroidManifest.xml b/app/src/main/AndroidManifest.xml
index 6c5cc781..f513fdb5 100644
--- a/app/src/main/AndroidManifest.xml
+++ b/app/src/main/AndroidManifest.xml
@@ -8,7 +8,6 @@
-
ReleaseStringUTFChars(env, javaMencid, mencid);
return res;
}
+
+JNIEXPORT jstring JNICALL
+Java_com_tutpro_baresip_AccountKt_account_1medianat(JNIEnv *env, jobject thiz, jstring javaAcc)
+{
+ const char *native_acc = (*env)->GetStringUTFChars(env, javaAcc, 0);
+ struct account *acc = (struct account *) strtoul(native_acc, NULL, 10);
+ (*env)->ReleaseStringUTFChars(env, javaAcc, native_acc);
+ if (acc) {
+ const char *medianat = account_medianat(acc);
+ if (medianat) return (*env)->NewStringUTF(env, medianat);
+ }
+ return (*env)->NewStringUTF(env, "");
+}
+
+JNIEXPORT jint JNICALL
+Java_com_tutpro_baresip_AccountKt_account_1set_1medianat(JNIEnv *env, jobject thiz,
+ jstring javaAcc, jstring javaMedNat) {
+ const char *native_acc = (*env)->GetStringUTFChars(env, javaAcc, 0);
+ struct account *acc = (struct account *)strtoul(native_acc, NULL, 10);
+ (*env)->ReleaseStringUTFChars(env, javaAcc, native_acc);
+ const char *mednat = (*env)->GetStringUTFChars(env, javaMedNat, 0);
+ int res;
+ if (strlen(mednat) > 0)
+ res = account_set_medianat(acc, mednat);
+ else
+ res = account_set_medianat(acc, NULL);
+ (*env)->ReleaseStringUTFChars(env, javaMedNat, mednat);
+ return res;
+}
+
JNIEXPORT jstring JNICALL
Java_com_tutpro_baresip_AccountKt_account_1sipnat(JNIEnv *env, jobject thiz, jstring javaAcc)
{
@@ -715,6 +745,56 @@ Java_com_tutpro_baresip_AccountKt_account_1set_1sipnat(JNIEnv *env, jobject thiz
return res;
}
+JNIEXPORT jstring JNICALL
+Java_com_tutpro_baresip_AccountKt_account_1stun_1host(JNIEnv *env, jobject thiz, jstring javaAcc)
+{
+ const char *native_acc = (*env)->GetStringUTFChars(env, javaAcc, 0);
+ struct account *acc = (struct account *) strtoul(native_acc, NULL, 10);
+ (*env)->ReleaseStringUTFChars(env, javaAcc, native_acc);
+ if (acc) {
+ const char *stun_host = account_stun_host(acc);
+ if (stun_host) return (*env)->NewStringUTF(env, stun_host);
+ }
+ return (*env)->NewStringUTF(env, "");
+}
+
+JNIEXPORT jint JNICALL
+Java_com_tutpro_baresip_AccountKt_account_1set_1stun_1host(JNIEnv *env, jobject thiz,
+ jstring javaAcc, jstring javaStunHost) {
+ const char *native_acc = (*env)->GetStringUTFChars(env, javaAcc, 0);
+ struct account *acc = (struct account *)strtoul(native_acc, NULL, 10);
+ (*env)->ReleaseStringUTFChars(env, javaAcc, native_acc);
+ const char *stun_host = (*env)->GetStringUTFChars(env, javaStunHost, 0);
+ int res;
+ if (strlen(stun_host) > 0)
+ res = account_set_stun_host(acc, stun_host);
+ else
+ res = account_set_stun_host(acc, NULL);
+ (*env)->ReleaseStringUTFChars(env, javaStunHost, stun_host);
+ return res;
+}
+
+JNIEXPORT jint JNICALL
+Java_com_tutpro_baresip_AccountKt_account_1stun_1port(JNIEnv *env, jobject thiz, jstring javaAcc)
+{
+ const char *native_acc = (*env)->GetStringUTFChars(env, javaAcc, 0);
+ struct account *acc = (struct account *) strtoul(native_acc, NULL, 10);
+ (*env)->ReleaseStringUTFChars(env, javaAcc, native_acc);
+ return account_stun_port(acc);
+}
+
+JNIEXPORT jint JNICALL
+Java_com_tutpro_baresip_AccountKt_account_1set_1stun_1port(JNIEnv *env, jobject thiz,
+ jstring javaAcc, jint javaStunPort) {
+ const char *native_acc = (*env)->GetStringUTFChars(env, javaAcc, 0);
+ struct account *acc = (struct account *)strtoul(native_acc, NULL, 10);
+ (*env)->ReleaseStringUTFChars(env, javaAcc, native_acc);
+ const uint16_t native_port = javaStunPort;
+ int res;
+ res = account_set_stun_port(acc, native_port);
+ return res;
+}
+
JNIEXPORT jint JNICALL
Java_com_tutpro_baresip_AccountKt_account_1set_1mwi(JNIEnv *env, jobject thiz,
jstring javaAcc, jstring javaValue) {
diff --git a/app/src/main/kotlin/com/tutpro/baresip/Account.kt b/app/src/main/kotlin/com/tutpro/baresip/Account.kt
index 966bdb54..2174ec71 100644
--- a/app/src/main/kotlin/com/tutpro/baresip/Account.kt
+++ b/app/src/main/kotlin/com/tutpro/baresip/Account.kt
@@ -7,15 +7,25 @@ class Account(val accp: String) {
var authUser = account_auth_user(accp)
var authPass = account_auth_pass(accp)
var outbound = ArrayList()
+ var mediaNat = account_medianat(accp)
+ var stunServer = ""
var audioCodec = ArrayList()
var regint = account_regint(accp)
- var mediaenc = account_mediaenc(accp)
+ var mediaEnc = account_mediaenc(accp)
var vmUri = account_vm_uri(accp)
var vmNew = 0
var vmOld = 0
var missedCalls = false
init {
+ val stunHost = account_stun_host(accp)
+ if (stunHost != "") {
+ val stunPort = account_stun_port(accp)
+ if (stunPort == 0)
+ stunServer = stunHost
+ else
+ stunServer = "$stunHost:$stunPort"
+ }
var i = 0
while (true) {
val ob = account_outbound(accp, i)
@@ -59,6 +69,10 @@ class Account(val accp: String) {
res = res + ";sipnat=outbound"
}
+ if (mediaNat != "") res = res + ";medianat=${mediaNat}"
+
+ if (stunServer != "") res = res + ";stunserver=\"stun:@${stunServer}\""
+
if (audioCodec.size > 0) {
var first = true
res = res + ";audio_codecs="
@@ -71,7 +85,7 @@ class Account(val accp: String) {
}
}
- if (mediaenc != "") res = res + ";mediaenc=${mediaenc}"
+ if (mediaEnc != "") res = res + ";mediaenc=${mediaEnc}"
if (vmUri == "")
res = res + ";mwi=no"
@@ -159,8 +173,14 @@ external fun account_set_sipnat(acc: String, sipnat: String): Int
external fun account_audio_codec(acc: String, ix: Int): String
external fun account_regint(acc: String): Int
external fun account_set_regint(acc: String, regint: Int): Int
+external fun account_stun_host(acc: String): String
+external fun account_stun_port(acc: String): Int
+external fun account_set_stun_host(acc: String, host: String): Int
+external fun account_set_stun_port(acc: String, port: Int): Int
external fun account_mediaenc(acc: String): String
-external fun account_set_mediaenc(acc: String, mencid: String): Int
+external fun account_set_mediaenc(acc: String, mediaenc: String): Int
+external fun account_medianat(acc: String): String
+external fun account_set_medianat(acc: String, medianat: String): Int
external fun account_set_audio_codecs(acc: String, codecs: String): Int
external fun account_set_mwi(acc: String, value: String): Int
external fun account_vm_uri(acc: String): String
diff --git a/app/src/main/kotlin/com/tutpro/baresip/AccountActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/AccountActivity.kt
index 4ae06e25..2a8238fa 100644
--- a/app/src/main/kotlin/com/tutpro/baresip/AccountActivity.kt
+++ b/app/src/main/kotlin/com/tutpro/baresip/AccountActivity.kt
@@ -1,6 +1,5 @@
package com.tutpro.baresip
-import android.content.Intent
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.util.Log
@@ -21,6 +20,8 @@ class AccountActivity : AppCompatActivity() {
internal lateinit var authPass: EditText
internal lateinit var outbound1: EditText
internal lateinit var outbound2: EditText
+ internal lateinit var iceCheck: CheckBox
+ internal lateinit var stunServer: EditText
internal lateinit var regCheck: CheckBox
internal lateinit var mediaEnc: String
internal lateinit var vmUri: EditText
@@ -56,6 +57,16 @@ class AccountActivity : AppCompatActivity() {
outbound2.setText(acc.outbound[1])
}
+ iceCheck = findViewById(R.id.Ice) as CheckBox
+ iceCheck.isChecked = acc.mediaNat == "ice"
+ iceCheck.setOnClickListener {
+ stunServer.isEnabled = iceCheck.isChecked
+ }
+
+ stunServer = findViewById(R.id.StunServer) as EditText
+ stunServer.setText(acc.stunServer)
+ stunServer.isEnabled = iceCheck.isChecked
+
regCheck = findViewById(R.id.Register) as CheckBox
regCheck.isChecked = acc.regint > 0
@@ -95,15 +106,15 @@ class AccountActivity : AppCompatActivity() {
}
}
- mediaEnc = acc.mediaenc
+ mediaEnc = acc.mediaEnc
val mediaEncSpinner = findViewById(R.id.mediaEncSpinner) as Spinner
val mediaEncKeys = arrayListOf("zrtp", "dtls_srtpf", "srtp-mand", "srtp", "")
val mediaEncVals = arrayListOf("ZRTP", "DTLS-SRTPF", "SRTP-MAND", "SRTP", "")
- val keyIx = mediaEncKeys.indexOf(acc.mediaenc)
+ val keyIx = mediaEncKeys.indexOf(acc.mediaEnc)
val keyVal = mediaEncVals.elementAt(keyIx)
mediaEncKeys.removeAt(keyIx)
mediaEncVals.removeAt(keyIx)
- mediaEncKeys.add(0, acc.mediaenc)
+ mediaEncKeys.add(0, acc.mediaEnc)
mediaEncVals.add(0, keyVal)
val mediaEncAdapter = ArrayAdapter(this,android.R.layout.simple_spinner_item,
mediaEncVals)
@@ -131,8 +142,6 @@ class AccountActivity : AppCompatActivity() {
override fun onOptionsItemSelected(item: MenuItem): Boolean {
- val intent = Intent(this, MainActivity::class.java)
-
if (item.itemId == R.id.checkIcon) {
val dn = displayName.text.toString().trim()
@@ -170,7 +179,7 @@ class AccountActivity : AppCompatActivity() {
val ap = authPass.text.toString().trim()
if (ap != acc.authPass) {
- if (Utils.checkPrintASCII(ap)) {
+ if (Utils.checkPrintAscii(ap)) {
if (account_set_auth_pass(acc.accp, ap) == 0) {
acc.authPass = account_auth_pass(acc.accp)
// Log.d("Baresip", "New auth password is ${acc.authPass}")
@@ -234,6 +243,46 @@ class AccountActivity : AppCompatActivity() {
Log.e("Baresip", "Setting of regint failed")
}
+ var newMediaNat = ""
+ if (iceCheck.isChecked) newMediaNat = "ice"
+ if (acc.mediaNat != newMediaNat)
+ if (account_set_medianat(acc.accp, newMediaNat) == 0) {
+ acc.mediaNat = account_medianat(acc.accp)
+ Log.d("Baresip", "New medianat is ${acc.mediaNat}")
+ save = true
+ } else {
+ Log.e("Baresip", "Setting of medianat failed")
+ }
+
+ if (iceCheck.isChecked) {
+ val newStunServer = stunServer.text.toString().trim()
+ if (acc.stunServer != newStunServer) {
+ if ((newStunServer != "") &&
+ !Utils.checkHostPort(newStunServer, false)) {
+ Utils.alertView(this, "Notice",
+ "Invalid STUN Server: $newStunServer")
+ return false
+ }
+ var host = ""
+ var port = ""
+ if (newStunServer != "") {
+ val hostPort = newStunServer.split(":")
+ host = hostPort[0]
+ if (hostPort.size == 2) port = hostPort[1]
+ }
+ if ((account_set_stun_host(acc.accp, host) == 0) &&
+ (account_set_stun_port(acc.accp, port.toInt()) == 0)) {
+ acc.stunServer = account_stun_host(acc.accp)
+ if (port != "")
+ acc.stunServer += ":" + account_stun_port(acc.accp).toString()
+ Log.d("Baresip", "New StunServer is ${acc.stunServer}")
+ save = true
+ } else {
+ Log.e("Baresip", "Setting of StunServer failed")
+ }
+ }
+ }
+
val ac = ArrayList(LinkedHashSet(newCodecs.filter { it != "" } as ArrayList))
if (ac != acc.audioCodec) {
Log.d("Baresip", "New codecs ${newCodecs.filter { it != "" }}")
@@ -256,10 +305,10 @@ class AccountActivity : AppCompatActivity() {
}
}
- if (mediaEnc != acc.mediaenc) {
+ if (mediaEnc != acc.mediaEnc) {
if (account_set_mediaenc(acc.accp, mediaEnc) == 0) {
- acc.mediaenc = account_mediaenc(acc.accp)
- Log.d("Baresip", "New mediaenc is ${acc.mediaenc}")
+ acc.mediaEnc = account_mediaenc(acc.accp)
+ Log.d("Baresip", "New mediaenc is ${acc.mediaEnc}")
save = true
} else {
Log.e("Baresip", "Setting of mediaenc $mediaEnc failed")
@@ -324,6 +373,12 @@ class AccountActivity : AppCompatActivity() {
findViewById(R.id.RegTitle) as TextView -> {
Utils.alertView(this, "Register", getString(R.string.register))
}
+ findViewById(R.id.IceTitle) as TextView -> {
+ Utils.alertView(this, "Use ICE", getString(R.string.ice))
+ }
+ findViewById(R.id.StunServerTitle) as TextView -> {
+ Utils.alertView(this, "STUN Server", getString(R.string.stunServer))
+ }
findViewById(R.id.AudioCodecsTitle) as TextView -> {
Utils.alertView(this, "Audio Codecs", getString(R.string.auCodecs))
}
diff --git a/app/src/main/kotlin/com/tutpro/baresip/AccountsActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/AccountsActivity.kt
index 52f86a7b..2eb44f3f 100644
--- a/app/src/main/kotlin/com/tutpro/baresip/AccountsActivity.kt
+++ b/app/src/main/kotlin/com/tutpro/baresip/AccountsActivity.kt
@@ -40,7 +40,7 @@ class AccountsActivity : AppCompatActivity() {
} else if (Account.exists(aor)) {
Log.e("Baresip", "Account $aor already exists")
} else {
- val ua = UserAgent.uaAlloc("<$aor>;regq=0.5;pubint=0;regint=0")
+ val ua = UserAgent.uaAlloc("<$aor>;stunserver=\"stun:stun.l.google.com:19302\";regq=0.5;pubint=0;regint=0")
if (ua == null) {
Log.e("Baresip", "Failed to allocate UA for $aor")
Utils.alertView(this, "Notice",
@@ -101,7 +101,7 @@ class AccountsActivity : AppCompatActivity() {
var accounts = ""
for (a in Account.accounts()) accounts = accounts + a.print() + "\n"
Utils.putFileContents(File(filesPath + "/accounts"), accounts)
- // Log.d("Baresip", "Saved accounts '${accounts}' to '${filesPath}/accounts")
+ // Log.d("Baresip", "Saved accounts '${accounts}' to '${filesPath}/accounts'")
}
}
diff --git a/app/src/main/kotlin/com/tutpro/baresip/ConfigActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/ConfigActivity.kt
new file mode 100644
index 00000000..37f9c8a9
--- /dev/null
+++ b/app/src/main/kotlin/com/tutpro/baresip/ConfigActivity.kt
@@ -0,0 +1,175 @@
+package com.tutpro.baresip
+
+import android.app.Activity
+import android.content.Intent
+import android.os.Bundle
+import android.support.v7.app.AppCompatActivity
+import android.util.Log
+import android.view.Menu
+import android.view.MenuItem
+import android.view.View
+import android.widget.*
+
+import java.io.File
+
+class ConfigActivity : AppCompatActivity() {
+
+ internal lateinit var configFile: File
+ internal lateinit var autoStart: CheckBox
+ internal lateinit var dnsServers: EditText
+ internal lateinit var opusBitRate: EditText
+ internal lateinit var iceLite: CheckBox
+
+ private var oldAutoStart = ""
+ private var oldDnsServers = ""
+ private var oldOpusBitrate = ""
+ private var oldIceMode = ""
+ private var save = false
+ private var config = ""
+
+ override fun onCreate(savedInstanceState: Bundle?) {
+
+ super.onCreate(savedInstanceState)
+ setContentView(R.layout.activity_config)
+
+ configFile = File(applicationContext.filesDir.absolutePath + "/config")
+ config = Utils.getFileContents(configFile)
+ if (config.length <= 100) {
+ Utils.alertView(this, "Internal Error", "Failed to read config file")
+ finish()
+ return
+ }
+
+ autoStart = findViewById(R.id.AutoStart) as CheckBox
+ val asCv = Utils.getNameValue(config, "auto_start")
+ oldAutoStart = if (asCv.size == 0) "no" else asCv[0]
+ autoStart.isChecked = oldAutoStart == "yes"
+
+ dnsServers = findViewById(R.id.DnsServers) as EditText
+ val dsCv = Utils.getNameValue(config, "dns_server")
+ var dsTv = ""
+ for (ds in dsCv) dsTv += ", $ds"
+ oldDnsServers = dsTv.trimStart(',').trimStart(' ')
+ dnsServers.setText(oldDnsServers)
+
+ opusBitRate = findViewById(R.id.OpusBitRate) as EditText
+ val obCv = Utils.getNameValue(config, "opus_bitrate")
+ oldOpusBitrate = if (obCv.size == 0) "28000" else obCv[0]
+ opusBitRate.setText(oldOpusBitrate)
+
+ iceLite = findViewById(R.id.IceLite) as CheckBox
+ val imCv = Utils.getNameValue(config, "ice_mode")
+ oldIceMode = if (imCv.size == 0) "full" else imCv[0]
+ iceLite.isChecked = oldIceMode == "lite"
+
+ }
+
+ override fun onCreateOptionsMenu(menu: Menu): Boolean {
+ super.onCreateOptionsMenu(menu)
+ val inflater = menuInflater
+ inflater.inflate(R.menu.check_icon, menu)
+ return true
+ }
+
+ override fun onOptionsItemSelected(item: MenuItem): Boolean {
+
+ val intent = Intent(this, MainActivity::class.java)
+
+ if (item.itemId == R.id.checkIcon) {
+
+ var autoStartString = "no"
+ if (autoStart.isChecked) autoStartString = "yes"
+ if (oldAutoStart != autoStartString) {
+ config = Utils.removeLinesStartingWithName(config, "auto_start")
+ config += "\nauto_start $autoStartString\n"
+ save = true
+ }
+
+ val dnsServers = dnsServers.text.toString().trim()
+ if (dnsServers != oldDnsServers) {
+ if (!checkDnsServers(dnsServers)) {
+ Utils.alertView(this, "Notice", "Invalid DNS Servers: $dnsServers")
+ return false
+ }
+ config = Utils.removeLinesStartingWithName(config, "dns_server")
+ for (server in dnsServers.split(","))
+ config += "\ndns_server ${server.trim()}\n"
+ save = true
+ }
+
+ val opusBitRate = opusBitRate.text.toString().trim()
+ if (opusBitRate != oldOpusBitrate) {
+ if (!checkOpusBitRate(opusBitRate)) {
+ Utils.alertView(this, "Notice", "Invalid Opus Bit Rate: $opusBitRate")
+ return false
+ }
+ config = Utils.removeLinesStartingWithName(config, "opus_bitrate")
+ config += "\nopus_bitrate $opusBitRate\n"
+ save = true
+ }
+
+ var iceModeString = "full"
+ if (iceLite.isChecked) iceModeString = "lite"
+ if (oldIceMode != iceModeString) {
+ config = Utils.removeLinesStartingWithName(config, "ice_mode")
+ config += "\nice_mode $iceModeString\n"
+ save = true
+ }
+
+ if (save) {
+ var newConfig = ""
+ for (line in config.split("\n")) {
+ val trimmedLine = line.trim()
+ if (trimmedLine.startsWith("#") || (trimmedLine.length == 0)) continue
+ // Log.d("Baresip", "Config line $trimmedLine")
+ newConfig += trimmedLine.split("#")[0] + "\n"
+ }
+ Utils.putFileContents(configFile, newConfig)
+ // Api.reload_config()
+ }
+ setResult(RESULT_OK, intent)
+ finish()
+ return true
+
+ } else if (item.itemId == android.R.id.home) {
+
+ Log.d("Baresip", "Back array was pressed at Config")
+ setResult(Activity.RESULT_CANCELED, intent)
+ finish()
+ return true
+
+ } else return super.onOptionsItemSelected(item)
+ }
+
+ fun onClick(v: View) {
+ when (v) {
+ findViewById(R.id.AutoStartTitle) as TextView-> {
+ Utils.alertView(this, "Start Automatically", getString(R.string.autoStart))
+ }
+ findViewById(R.id.DnsServersTitle) as TextView -> {
+ Utils.alertView(this, "DNS Servers", getString(R.string.dnsServers))
+ }
+ findViewById(R.id.OpusBitRateTitle) as TextView-> {
+ Utils.alertView(this, "Opus Bit Rate", getString(R.string.opusBitRate))
+ }
+ findViewById(R.id.IceLiteTitle) as TextView-> {
+ Utils.alertView(this, "ICE Lite Mode", getString(R.string.iceLite))
+ }
+ }
+ }
+
+ private fun checkDnsServers(dnsServers: String): Boolean {
+ if (dnsServers.length == 0) return true
+ for (server in dnsServers.split(","))
+ if (!Utils.checkHostPort(server.trim(), true)) return false
+ return true
+ }
+
+ private fun checkOpusBitRate(opusBitRate: String): Boolean {
+ val number = opusBitRate.toIntOrNull()
+ if (number == null) return false
+ return (number >=6000) && (number <= 510000)
+ }
+
+}
+
diff --git a/app/src/main/kotlin/com/tutpro/baresip/EditConfigActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/EditConfigActivity.kt
deleted file mode 100644
index 4ca6b3ca..00000000
--- a/app/src/main/kotlin/com/tutpro/baresip/EditConfigActivity.kt
+++ /dev/null
@@ -1,106 +0,0 @@
-package com.tutpro.baresip
-
-import android.app.Activity
-import android.content.Intent
-import android.os.Bundle
-import android.support.v7.app.AppCompatActivity
-import android.util.Log
-import android.util.TypedValue
-import android.view.Menu
-import android.view.MenuItem
-import android.widget.EditText
-import android.widget.TextView
-
-import java.io.File
-import java.io.FileInputStream
-import java.io.FileOutputStream
-import java.io.OutputStreamWriter
-
-class EditConfigActivity : AppCompatActivity() {
-
- private var editText: EditText? = null
- private var path: String? = null
- private var file: File? = null
-
- override fun onCreate(savedInstanceState: Bundle?) {
- super.onCreate(savedInstanceState)
- setContentView(R.layout.activity_edit_config)
-
- editText = findViewById(R.id.editConfig) as EditText
- path = "${applicationContext.filesDir.absolutePath}/config"
- file = File(path!!)
- var content: String
-
- if (!file!!.exists()) {
- Log.e("Baresip", "Failed to find config file")
- content = "No config"
- } else {
- Log.e("Baresip", "Found config file")
- val length = file!!.length().toInt()
- val bytes = ByteArray(length)
- try {
- val `in` = FileInputStream(file!!)
- try {
- `in`.read(bytes)
- } finally {
- `in`.close()
- }
- content = String(bytes)
- } catch (e: java.io.IOException) {
- Log.e("Baresip", "Failed to read config file: " + e.toString())
- content = "Failed to read account file"
- }
-
- }
-
- Log.d("Baresip", "Content length is: " + content.length)
-
- editText!!.setTextSize(TypedValue.COMPLEX_UNIT_PX,
- resources.getDimension(R.dimen.textsize))
- editText!!.setText(content, TextView.BufferType.EDITABLE)
- }
-
- override fun onCreateOptionsMenu(menu: Menu): Boolean {
- super.onCreateOptionsMenu(menu)
- val inflater = menuInflater
- inflater.inflate(R.menu.check_icon, menu)
- return true
- }
-
- override fun onOptionsItemSelected(item: MenuItem): Boolean {
-
- val i = Intent(this, MainActivity::class.java)
-
- if (item.itemId == R.id.checkIcon) {
- try {
- val fOut = FileOutputStream(file!!.absoluteFile, false)
- val fWriter = OutputStreamWriter(fOut)
- val res = editText!!.text.toString()
- try {
- fWriter.write(res)
- fWriter.close()
- fOut.close()
- } catch (e: java.io.IOException) {
- Log.e("Baresip", "Failed to write config file: " + e.toString())
- }
-
- } catch (e: java.io.FileNotFoundException) {
- Log.e("Baresip", "Failed to find config file: " + e.toString())
- }
-
- Log.d("Baresip", "Updated config file")
- setResult(RESULT_OK, i)
- finish()
- return true
-
- } else if (item.itemId == android.R.id.home) {
-
- Log.d("Baresip", "Back array was pressed at Edit Config")
- setResult(Activity.RESULT_CANCELED, i)
- finish()
- return true
-
- } else return super.onOptionsItemSelected(item)
-
- }
-}
diff --git a/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt
index 7475d4c9..a63769d6 100644
--- a/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt
+++ b/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt
@@ -486,7 +486,7 @@ class MainActivity : AppCompatActivity() {
callTitle.text = "Incoming call from ..."
else
callTitle.text = "Outgoing call to ..."
- if (acc.mediaenc == "") {
+ if (acc.mediaEnc == "") {
securityButton.visibility = View.INVISIBLE
} else {
securityButton.setImageResource(R.drawable.box_red)
@@ -819,6 +819,11 @@ class MainActivity : AppCompatActivity() {
R.color.colorPrimary))
return true
}
+ R.id.config -> {
+ i = Intent(this, ConfigActivity::class.java)
+ startActivityForResult(i, CONFIG_CODE)
+ return true
+ }
R.id.accounts -> {
i = Intent(this, AccountsActivity::class.java)
val b = Bundle()
@@ -827,11 +832,6 @@ class MainActivity : AppCompatActivity() {
startActivityForResult(i, ACCOUNTS_CODE)
return true
}
- R.id.config -> {
- i = Intent(this, EditConfigActivity::class.java)
- startActivityForResult(i, EDIT_CONFIG_CODE)
- return true
- }
R.id.about -> {
Api.cmd_exec("audio_debug")
i = Intent(this, AboutActivity::class.java)
@@ -901,15 +901,12 @@ class MainActivity : AppCompatActivity() {
Contact.contacts().map{Contact -> Contact.name}))
}
- EDIT_CONFIG_CODE -> {
- if (resultCode == RESULT_OK) {
+ CONFIG_CODE -> {
+ if (resultCode == RESULT_OK)
Utils.alertView(this, "Notice",
"You need to restart baresip in order to activate saved config!")
- Api.reload_config()
- }
- if (resultCode == RESULT_CANCELED) {
- Log.d("Baresip", "Edit config canceled")
- }
+ if (resultCode == RESULT_CANCELED)
+ Log.d("Baresip", "Config canceled")
}
CALLS_CODE -> {
@@ -1078,7 +1075,7 @@ class MainActivity : AppCompatActivity() {
"connected" -> {
securityButton.setImageResource(call.security)
setSecurityButtonTag(securityButton, call.security)
- if ((ua.account.mediaenc == "zrtp") || (ua.account.mediaenc == "dtls_srtpf"))
+ if ((ua.account.mediaEnc == "zrtp") || (ua.account.mediaEnc == "dtls_srtpf"))
securityButton.visibility = View.VISIBLE
else
securityButton.visibility = View.INVISIBLE
@@ -1109,7 +1106,7 @@ class MainActivity : AppCompatActivity() {
const val ACCOUNTS_CODE = 1
const val CONTACTS_CODE = 2
- const val EDIT_CONFIG_CODE = 3
+ const val CONFIG_CODE = 3
const val CALLS_CODE = 4
const val ABOUT_CODE = 5
const val ACCOUNT_CODE = 6
diff --git a/app/src/main/kotlin/com/tutpro/baresip/RunOnStartup.kt b/app/src/main/kotlin/com/tutpro/baresip/RunOnStartup.kt
index fb811d78..c00a8ea6 100644
--- a/app/src/main/kotlin/com/tutpro/baresip/RunOnStartup.kt
+++ b/app/src/main/kotlin/com/tutpro/baresip/RunOnStartup.kt
@@ -6,18 +6,25 @@ import android.content.Intent
import android.os.Bundle
import android.util.Log
+import java.io.File
+
class RunOnStartup : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) {
if ((intent.action == Intent.ACTION_BOOT_COMPLETED) or
(intent.action == "com.tutpro.baresip.Restart")) {
- Log.d("Baresip", "Start baresip upon boot completed or restart")
- val i = Intent(context, MainActivity::class.java)
- i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
- val b = Bundle()
- b.putBoolean("onStartup", true)
- i.putExtras(b)
- context.startActivity(i)
+ val configFile = File(context.filesDir.absolutePath + "/config")
+ val config = Utils.getFileContents(configFile)
+ val asCv = Utils.getNameValue(config,"auto_start")
+ if ((asCv.size > 0) && (asCv[0] == "yes")) {
+ Log.d("Baresip", "Start baresip upon boot completed or restart")
+ val i = Intent(context, MainActivity::class.java)
+ i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
+ val b = Bundle()
+ b.putBoolean("onStartup", true)
+ i.putExtras(b)
+ context.startActivity(i)
+ }
}
}
diff --git a/app/src/main/kotlin/com/tutpro/baresip/UserAgent.kt b/app/src/main/kotlin/com/tutpro/baresip/UserAgent.kt
index 34a6ed62..175fd23b 100644
--- a/app/src/main/kotlin/com/tutpro/baresip/UserAgent.kt
+++ b/app/src/main/kotlin/com/tutpro/baresip/UserAgent.kt
@@ -36,7 +36,7 @@ class UserAgent (val uap: String) {
fun remove(ua: UserAgent) {
val index = BaresipService.uas.indexOf(ua)
if (index != -1) {
- BaresipService.uas[index].destroy()
+ BaresipService.uas.removeAt(index)
BaresipService.status.removeAt(index)
}
}
diff --git a/app/src/main/kotlin/com/tutpro/baresip/Utils.kt b/app/src/main/kotlin/com/tutpro/baresip/Utils.kt
index cee363ce..3078c59b 100644
--- a/app/src/main/kotlin/com/tutpro/baresip/Utils.kt
+++ b/app/src/main/kotlin/com/tutpro/baresip/Utils.kt
@@ -18,7 +18,6 @@ object Utils {
Log.e("Baresip", "Failed to find file: " + file.path)
return ""
} else {
- Log.e("Baresip", "Found file: " + file.path)
val length = file.length().toInt()
val bytes = ByteArray(length)
try {
@@ -56,6 +55,23 @@ object Utils {
}
+ fun getNameValue(string: String, name: String): ArrayList {
+ val lines = string.split("\n")
+ val result = ArrayList()
+ for (line in lines) {
+ if (line.startsWith(name))
+ result.add((line.substring(name.length).trim()).split(" \t")[0])
+ }
+ return result
+ }
+
+ fun removeLinesStartingWithName(string: String, name: String): String {
+ var result = ""
+ for (line in string.split("\n"))
+ if (!line.startsWith(name)) result += line + "\n"
+ return result
+ }
+
fun copyAssetToFile(context: Context, asset: String, path: String) {
try {
val `is` = context.assets.open(asset)
@@ -131,35 +147,49 @@ object Utils {
fun checkDomain(domain: String): Boolean {
val parts = domain.split(".")
for (p in parts) {
- if (p.length == 0 || p.endsWith("-") || !Regex("^[a-zA-z]([-]|[a-zA-Z0-9])+\$").matches(p))
+ if ((p.length == 0) || p.endsWith("-") ||
+ !Regex("^[a-zA-z]([-a-zA-Z0-9])*\$").matches(p))
return false
}
return true
}
- fun checkPort(p: String) : Boolean {
- val number = p.toIntOrNull()
+ fun checkPort(port: String): Boolean {
+ val number = port.toIntOrNull()
if (number == null) return false
- return (number > 0) and (number < 65536)
+ return (number > 0) && (number < 65536)
}
- fun checkHostPort(hp: String) : Boolean {
+ fun checkHostPort(hp: String, portMandatory: Boolean) : Boolean {
val parts = hp.split(":")
+ if (portMandatory && (parts.size != 2)) return false
if (parts.size == 1) return checkIP(parts[0]) || checkDomain(parts[0])
return checkPort(parts[1]) && (checkIP(parts[0]) || checkDomain(parts[0]))
}
- fun checkParams(p: String) : Boolean {
- /* todo: proper check */
+ fun checkParams(params: String): Boolean {
+ for (param in params.split(";"))
+ if (!checkParam(param)) return false
return true
}
+ fun checkParam(param: String): Boolean {
+ val nameValue = param.split("=")
+ if (nameValue.size == 1)
+ /* Todo: do proper check */
+ return true
+ if (nameValue.size == 2)
+ /* Todo: do proper check */
+ return true
+ return false
+ }
+
fun checkHostPortParams(hpp: String) : Boolean {
val restParams = hpp.split(";", limit = 2)
if (restParams.size == 1)
- return checkHostPort(restParams[0])
+ return checkHostPort(restParams[0], false)
else
- return checkHostPort(restParams[0]) && checkParams(restParams[1])
+ return checkHostPort(restParams[0], false) && checkParams(restParams[1])
}
fun checkSipUri(uri: String): Boolean {
@@ -186,15 +216,9 @@ object Utils {
return checkHostPortParams(uri.substring(4))
}
- fun checkPrintASCII(s: String): Boolean {
+ fun checkPrintAscii(s: String): Boolean {
if (s == "") return true
- val printASCIIRegex = Regex("^[ -~]*\$")
- return printASCIIRegex.matches(s)
- }
-
- fun checkUint(s: String): Boolean {
- val uintRegex = Regex("^[0-9]+\$")
- return uintRegex.matches(s)
+ return Regex("^[ -~]*\$").matches(s)
}
fun checkName(name: String): Boolean {
diff --git a/app/src/main/res/layout/activity_account.xml b/app/src/main/res/layout/activity_account.xml
index d73cf826..3324d744 100644
--- a/app/src/main/res/layout/activity_account.xml
+++ b/app/src/main/res/layout/activity_account.xml
@@ -98,10 +98,10 @@
android:hint="SIP URI of another Proxy Server"
android:textSize="18sp"
android:inputType="textEmailAddress"
- android:layout_width="fill_parent">
+ android:layout_width="fill_parent" >
-
@@ -109,6 +109,7 @@
android:id="@+id/RegTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
+ android:layout_alignParentStart="true"
android:textSize="18sp"
android:textColor="@android:color/black"
android:onClick="onClick"
@@ -118,10 +119,56 @@
android:id="@+id/Register"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
- android:text=""
+ android:layout_alignParentEnd="true"
+ android:layout_gravity="end"
android:checked="false" >
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/src/main/res/layout/activity_edit_accounts.xml b/app/src/main/res/layout/activity_edit_accounts.xml
deleted file mode 100644
index 96dd5793..00000000
--- a/app/src/main/res/layout/activity_edit_accounts.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
diff --git a/app/src/main/res/layout/activity_edit_config.xml b/app/src/main/res/layout/activity_edit_config.xml
deleted file mode 100644
index 95a95a68..00000000
--- a/app/src/main/res/layout/activity_edit_config.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
diff --git a/app/src/main/res/menu/main_menu.xml b/app/src/main/res/menu/main_menu.xml
index 3f19c822..76c3af9a 100644
--- a/app/src/main/res/menu/main_menu.xml
+++ b/app/src/main/res/menu/main_menu.xml
@@ -1,11 +1,11 @@