- Added to Settings possibility to choose which audio modules are loaded.

Codecs provided by loaded modules are available for accounts to use.
This commit is contained in:
Juha Heinanen
2019-10-22 17:33:46 +03:00
parent cf3e02c46d
commit 53f751454d
9 changed files with 178 additions and 69 deletions

View File

@ -23,8 +23,8 @@ net_prefer_ipv6 no
module opus.so
module amr.so
module ilbc.so
module g7221.so
module g722.so
module g7221.so
module g726.so
module g711.so
module webrtc_aec.so

View File

@ -1,6 +1,8 @@
package com.tutpro.baresip
import android.content.Context
import java.util.*
import kotlin.collections.ArrayList
class Account(val accp: String) {
@ -151,6 +153,27 @@ class Account(val accp: String) {
return aor.split("@")[1]
}
private fun removeAudioCodecsStartingWith(prefix: String) {
val newCodecs = ArrayList<String>()
for (acSpec in audioCodec)
if (!acSpec.toLowerCase(Locale.ROOT).startsWith(prefix)) newCodecs.add(acSpec)
audioCodec = newCodecs
}
fun removeAudioCodecs(codecModule: String) {
when (codecModule) {
"g711" -> {
removeAudioCodecsStartingWith("pcm")
}
"g722" -> {
removeAudioCodecsStartingWith("g722/")
}
else -> {
removeAudioCodecsStartingWith(codecModule)
}
}
}
companion object {
fun accounts(): ArrayList<Account> {

View File

@ -186,7 +186,7 @@ class BaresipService: Service() {
showStatusNotification()
if (Config.variable("dyn_dns")[0] == "yes")
Config.remove("dns_server")
Config.removeVariable("dns_server")
if (AccountsActivity.noAccounts()) {
val newIntent = Intent(this, MainActivity::class.java)
@ -712,9 +712,9 @@ class BaresipService: Service() {
Log.d(LOG_TAG, "Received 'stopped' from baresip with param '$error'")
isServiceRunning = false
if (error == "ua_init") {
Config.remove("sip_listen")
Config.remove("sip_certificate")
Config.remove("sip_cafile")
Config.removeVariable("sip_listen")
Config.removeVariable("sip_certificate")
Config.removeVariable("sip_cafile")
}
val intent = Intent("service event")
intent.putExtra("event", "stopped")

View File

@ -21,17 +21,6 @@ object Config {
config = "${config}ausrc_format s16\nauplay_format s16\nauenc_format s16\naudec_format s16\nmodule webrtc_aec.so\n"
write = true
}
if (!config.contains(Regex("module[ ]+amr.so"))) {
config = config.replace(Regex("module[ ]+g7...?.so\n"), "")
config = config.replace(Regex("module[ ]+ilbc.so\n"), "")
config = "${config}module amr.so\n"
config = "${config}module ilbc.so\n"
config = "${config}module g7221.so\n"
config = "${config}module g722.so\n"
config = "${config}module g726.so\n"
config = "${config}module g711.so\n"
write = true
}
if (config.contains(Regex("#module_app[ ]+mwi.so"))) {
config = config.replace(Regex("#module_app[ ]+mwi.so"),
"module_app mwi.so")
@ -69,7 +58,7 @@ object Config {
}
val preferIpv6 = variable("prefer_ipv6")
if (preferIpv6.size > 0) {
remove("prefer_ipv6")
removeVariable("prefer_ipv6")
config = "net_prefer_ipv6 ${preferIpv6[0]}\n${config}"
write = true
} else {
@ -112,18 +101,21 @@ object Config {
return result
}
fun add(variable: String, value: String) {
config += "$variable $value\n"
fun addLine(line: String) {
config += "$line\n"
}
fun remove(variable: String) {
config = Utils.removeLinesStartingWithName(config, variable)
Utils.putFileContents(configPath, config.toByteArray())
fun removeLine(line: String) {
config = Utils.removeLinesStartingWithString(config, line)
}
fun replace(variable: String, value: String) {
remove(variable)
add(variable, value)
fun removeVariable(variable: String) {
config = Utils.removeLinesStartingWithString(config, "$variable ")
}
fun replaceVariable(variable: String, value: String) {
removeVariable(variable)
addLine("$variable $value")
}
fun reset(ctx: Context) {

View File

@ -3,14 +3,19 @@ package com.tutpro.baresip
import android.app.Activity
import android.content.Context
import android.content.Intent
import android.graphics.Color
import android.net.ConnectivityManager
import android.os.Build
import android.os.Bundle
import android.support.v7.app.AppCompatActivity
import android.util.TypedValue
import android.view.Gravity
import android.view.Menu
import android.view.MenuItem
import android.view.View
import android.widget.*
import android.widget.RelativeLayout.LayoutParams
import android.widget.AdapterView
class ConfigActivity : AppCompatActivity() {
@ -35,6 +40,7 @@ class ConfigActivity : AppCompatActivity() {
private var oldDnsServers = ""
private var oldCertificateFile = false
private var oldCAFile = false
private var oldAudioModules = mutableMapOf<String, Boolean>()
private var oldAec = false
private var oldOpusBitrate = ""
private var oldOpusPacketLoss = ""
@ -43,6 +49,7 @@ class ConfigActivity : AppCompatActivity() {
private var callVolume = BaresipService.callVolume
private var save = false
private var restart = false
private val audioModules = listOf("opus", "amr", "ilbc", "g722", "g7221", "g726", "g711")
override fun onCreate(savedInstanceState: Bundle?) {
@ -91,6 +98,37 @@ class ConfigActivity : AppCompatActivity() {
oldCAFile = Config.variable("sip_cafile").isNotEmpty()
caFile.isChecked = oldCAFile
val audioModulesList = findViewById(R.id.AudioModulesList) as LinearLayout
var id = 1000
for (module in audioModules) {
val rl = RelativeLayout(this)
val rlParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
rlParams.marginStart = 16
rl.layoutParams = rlParams
val tv = TextView(this)
tv.id = id++
val tvParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
tvParams.addRule(RelativeLayout.ALIGN_PARENT_START)
tvParams.addRule(RelativeLayout.CENTER_VERTICAL)
tvParams.addRule(RelativeLayout.START_OF, id)
tv.layoutParams = tvParams
tv.text = module
tv.setTextSize(TypedValue.COMPLEX_UNIT_SP, 18f)
tv.setTextColor(Color.BLACK)
rl.addView(tv)
val cb = CheckBox(this)
cb.id = id++
val cbParams = LayoutParams(LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT)
cbParams.addRule(RelativeLayout.ALIGN_PARENT_END)
cbParams.addRule(RelativeLayout.CENTER_VERTICAL)
cb.layoutParams = cbParams
cb.gravity = Gravity.END
cb.isChecked = Config.variable("module $module.so").size > 0
oldAudioModules.put(module, cb.isChecked)
rl.addView(cb)
audioModulesList.addView(rl)
}
aec = findViewById(R.id.Aec) as CheckBox
val aecCv = Config.variable("module")
oldAec = aecCv.contains("webrtc_aec.so")
@ -166,7 +204,7 @@ class ConfigActivity : AppCompatActivity() {
var autoStartString = "no"
if (autoStart.isChecked) autoStartString = "yes"
if (oldAutoStart != autoStartString) {
Config.replace("auto_start", autoStartString)
Config.replaceVariable("auto_start", autoStartString)
save = true
restart = false
}
@ -178,8 +216,8 @@ class ConfigActivity : AppCompatActivity() {
"${getString(R.string.invalid_listen_address)}: $listenAddr")
return false
}
Config.remove("sip_listen")
if (listenAddr != "") Config.add("sip_listen", listenAddr)
Config.removeVariable("sip_listen")
if (listenAddr != "") Config.addLine("sip_listen $listenAddr")
save = true
restart = true
}
@ -191,8 +229,8 @@ class ConfigActivity : AppCompatActivity() {
"${getString(R.string.invalid_bind_address)}: $bindAddr")
return false
}
Config.remove("net_interface")
if (bindAddr != "") Config.add("net_interface", bindAddr)
Config.removeVariable("net_interface")
if (bindAddr != "") Config.addLine("net_interface $bindAddr")
save = true
restart = true
}
@ -200,7 +238,7 @@ class ConfigActivity : AppCompatActivity() {
var preferIPv6String = "no"
if (preferIPv6.isChecked) preferIPv6String = "yes"
if (oldPreferIPv6 != preferIPv6String) {
Config.replace("net_prefer_ipv6", preferIPv6String)
Config.replaceVariable("net_prefer_ipv6", preferIPv6String)
save = true
restart = true
}
@ -212,19 +250,19 @@ class ConfigActivity : AppCompatActivity() {
"${getString(R.string.invalid_dns_servers)}: $dnsServers")
return false
}
Config.remove("dyn_dns")
Config.remove("dns_server")
Config.removeVariable("dyn_dns")
Config.removeVariable("dns_server")
if (dnsServers.isNotEmpty()) {
for (server in dnsServers.split(","))
Config.add("dns_server", server)
Config.add("dyn_dns", "no")
Config.addLine("dns_server $server")
Config.addLine("dyn_dns no")
if (Api.net_use_nameserver(dnsServers) != 0) {
Utils.alertView(this, getString(R.string.error),
"${getString(R.string.failed_to_set_dns_servers)}: $dnsServers")
return false
}
} else {
Config.add("dyn_dns", "yes")
Config.addLine("dyn_dns yes")
if (Build.VERSION.SDK_INT >= 23) {
val cm = getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
Config.updateDnsServers(cm.getLinkProperties(cm.activeNetwork).getDnsServers())
@ -249,10 +287,10 @@ class ConfigActivity : AppCompatActivity() {
return false
}
Utils.putFileContents(BaresipService.filesPath + "/cert.pem", content)
Config.remove("sip_certificate")
Config.add("sip_certificate", BaresipService.filesPath + "/cert.pem")
Config.removeVariable("sip_certificate")
Config.addLine("sip_certificate ${BaresipService.filesPath}/cert.pem")
} else {
Config.remove("sip_certificate")
Config.removeVariable("sip_certificate")
}
save = true
restart = true
@ -272,22 +310,44 @@ class ConfigActivity : AppCompatActivity() {
}
Utils.putFileContents(BaresipService.filesPath + "/ca_certs.crt",
content)
Config.remove("sip_cafile")
Config.add("sip_cafile", BaresipService.filesPath + "/ca_certs.crt")
Config.removeVariable("sip_cafile")
Config.addLine("sip_cafile ${BaresipService.filesPath}/ca_certs.crt")
} else {
Config.remove("sip_cafile")
Config.removeVariable("sip_cafile")
}
save = true
restart = true
}
var id = 1001
for (module in audioModules) {
val box = findViewById<CheckBox>(id++)
if (box.isChecked && !oldAudioModules[module]!!) {
if (Api.module_load("$module.so") != 0) {
Utils.alertView(this, getString(R.string.error),
"${getString(R.string.failed_to_load_module)}: $module.so")
return false
}
Config.addLine("module $module.so")
save = true
}
if (!box.isChecked && oldAudioModules[module]!!) {
Api.module_unload("$module.so")
Config.removeLine("module $module.so")
for (ua in UserAgent.uas()) ua.account.removeAudioCodecs(module)
AccountsActivity.saveAccounts()
save = true
}
id++
}
if (aec.isChecked != oldAec) {
Config.remove("module webrtc_aec.so")
Config.removeLine("module webrtc_aec.so")
if (aec.isChecked) {
Config.add("module", "webrtc_aec.so")
Config.addLine("module webrtc_aec.so")
if (Api.module_load("webrtc_aec.so") != 0) {
Utils.alertView(this, getString(R.string.error),
getString(R.string.failed_to_load_aec_module))
getString(R.string.failed_to_load_module))
aec.isChecked = false
return false
}
@ -304,8 +364,8 @@ class ConfigActivity : AppCompatActivity() {
"${getString(R.string.invalid_opus_bitrate)}: $opusBitRate.")
return false
}
Config.remove("opus_bitrate")
Config.add("opus_bitrate", opusBitRate)
Config.removeVariable("opus_bitrate")
Config.addLine("opus_bitrate $opusBitRate")
save = true
restart = true
}
@ -317,11 +377,11 @@ class ConfigActivity : AppCompatActivity() {
"${getString(R.string.invalid_opus_packet_loss)}: $opusPacketLoss")
return false
}
Config.remove("opus_inbandfec")
Config.remove("opus_packet_loss")
Config.removeVariable("opus_inbandfec")
Config.removeVariable("opus_packet_loss")
if (opusPacketLoss != "0") {
Config.add("opus_inbandfec", "yes")
Config.add("opus_packet_loss", opusPacketLoss)
Config.addLine("opus_inbandfec yes")
Config.addLine("opus_packet_loss $opusPacketLoss")
}
save = true
restart = true
@ -330,21 +390,21 @@ class ConfigActivity : AppCompatActivity() {
var iceModeString = "full"
if (iceLite.isChecked) iceModeString = "lite"
if (oldIceMode != iceModeString) {
Config.replace("ice_mode", iceModeString)
Config.replaceVariable("ice_mode", iceModeString)
save = true
restart = true
}
if (BaresipService.callVolume != callVolume) {
BaresipService.callVolume = callVolume
Config.replace("call_volume", callVolume.toString())
Config.replaceVariable("call_volume", callVolume.toString())
save = true
}
var logLevelString = "2"
if (debug.isChecked) logLevelString = "0"
if (oldLogLevel != logLevelString) {
Config.replace("log_level", logLevelString)
Config.replaceVariable("log_level", logLevelString)
Api.log_level_set(logLevelString.toInt())
Log.logLevelSet(logLevelString.toInt())
save = true
@ -415,6 +475,10 @@ class ConfigActivity : AppCompatActivity() {
Utils.alertView(this, getString(R.string.tls_ca_file),
getString(R.string.tls_ca_file_help))
}
findViewById(R.id.AudioModulesTitle) as TextView -> {
Utils.alertView(this, getString(R.string.audio_modules_title),
getString(R.string.audio_modules_help))
}
findViewById(R.id.AecTitle) as TextView-> {
Utils.alertView(this, getString(R.string.aec),
getString(R.string.aec_help))

View File

@ -38,10 +38,10 @@ object Utils {
return result
}
fun removeLinesStartingWithName(string: String, name: String): String {
fun removeLinesStartingWithString(lines: String, string: String): String {
var result = ""
for (line in string.split("\n"))
if (!line.startsWith(name) && (line.length > 0)) result += line + "\n"
for (line in lines.split("\n"))
if (!line.startsWith(string) && (line.length > 0)) result += line + "\n"
return result
}

View File

@ -192,7 +192,29 @@
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp"
android:orientation="horizontal" >
android:orientation="vertical" >
<TextView
android:id="@+id/AudioModulesTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:textSize="18sp"
android:textColor="@android:color/black"
android:onClick="onClick"
android:text="@string/audio_modules_title" >
</TextView>
<LinearLayout
android:id="@+id/AudioModulesList"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:layout_marginTop="24dp"
android:orientation="vertical" >
</LinearLayout>
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginBottom="12dp" >
<TextView
android:id="@+id/AecTitle"
android:layout_width="wrap_content"

View File

@ -186,9 +186,23 @@
DNS-palvelijoihin.</string>
<string name="invalid_dns_servers">Virheelliset DNS-palvelimet</string>
<string name="failed_to_set_dns_servers">DNS-palvelinten asetus epäonnistui</string>
<string name="tls_certificate_file">TLS-varmennintiedosto</string>
<string name="tls_certificate_file_help">Jos merkitty, tiedosto \'cert.pem\', joka sisältää
tämän baresip-sovelluksen julkisen ja yksityisen TLS-varmentimen, on joko jo ladattu tai tullaan
lataamaan Download-hakemistosta. Turvallisuusyistä tuhoa tiedosto heti lataamisen jälkeen.
</string>
<string name="tls_ca_file">TLS CA-tiedosto</string>
<string name="tls_ca_file_help">Jos merkitty, tiedosto \'ca_certs.crt\', joka sisältää
TLS-varmenninauktoriteettien julkiset varmentimen, on joko jo ladattu tai tullaan lataamaan
Download-hakemistosta.
</string>
<string name="audio_modules_title">Audio-modulit</string>
<string name="audio_modules_help">Merkittyjen modulien tarjoamat audio-koodekit ovat tilien
käytettävissä.
</string>
<string name="failed_to_load_module">Modulin lataaminen epäonnistui</string>
<string name="aec">Akustinen kaiun poisto</string>
<string name="aec_help">Jos merkitty, kaikua yritetään poistaa puheluiden aikana.</string>
<string name="failed_to_load_aec_module">Kaiunpoistomodulin lataaminen epäonnistui.</string>
<string name="opus_bit_rate">Opus-koodekin bittinopeus</string>
<string name="opus_bit_rate_help">Opus-koodekin käyttämä
keskimääräinen enimmäisnopeus. Mahdollisia arvoja ovat
@ -306,15 +320,6 @@
<string name="call_is_secure">Tämä pulelu on turvallinen ja kohde on
todennettu! Haluatko poistaa todennuksen?</string>
<string name="unverify">Poista todennus</string>
<string name="tls_ca_file">TLS CA-tiedosto</string>
<string name="tls_ca_file_help">Jos merkitty, tiedosto \'ca_certs.crt\', joka sisältää
todennusauktoriteettien TLS-sertifikaatit, on ladattu tai ladataan Download-kansiosta.
</string>
<string name="tls_certificate_file">TLS sertifikaattitiedosto</string>
<string name="tls_certificate_file_help">"Jos merkitty, tiedosto \'cert.pem\', joka sisältää
tämän baresip-sovelluksen TLS-sertifikaatin ja yksityisen avaimen, on ladattu tai ladataan
Download-kansiosta."
</string>
<string name="backed_up">Sovelluksen tiedot talletettiin Download-kansion tiedostoon
\'baresip.bs\'.
</string>

View File

@ -181,9 +181,12 @@
<string name="tls_ca_file">TLS CA File</string>
<string name="tls_ca_file_help">If checked, file \'ca_certs.crt\' containing TLS certificates
of Certificate Authorities has been or will be loaded from Download directory.</string>
<string name="audio_modules_title">Audio Modules</string>
<string name="audio_modules_help">Audio codecs provided by the checked modules are
available for use by the accounts.</string>
<string name="failed_to_load_module">Failed to load module.</string>
<string name="aec">Acoustic Echo Cancellation</string>
<string name="aec_help">If checked, echo cancellation is attempted on call audio.</string>
<string name="failed_to_load_aec_module">Failed to load Acoustic Echo Cancellation module.</string>
<string name="opus_bit_rate">Opus Bit Rate</string>
<string name="opus_bit_rate_help">Average maximum bit rate used by Opus audio stream.
Valid values are 6000-510000. Factory default is 28000.</string>