- Replaced text mode EditConfigActivity with graphical Config activity

- Current configuration items are Auto Start, DNS Servers, Opus Bit Rate,
  and ICE Lite
- Added ICE and Stun Server account options
- Fixed bug in deleting of an account
- Updated libbaresip.a and baresip.h to baresip new_account_functions
  branch (not yet committed to master)
This commit is contained in:
Juha Heinanen
2018-11-30 02:07:03 +02:00
parent 6f652f3872
commit 4626967ae1
20 changed files with 664 additions and 385 deletions
+2 -2
View File
@@ -7,8 +7,8 @@ android {
applicationId = 'com.tutpro.baresip' applicationId = 'com.tutpro.baresip'
minSdkVersion 21 minSdkVersion 21
targetSdkVersion 27 targetSdkVersion 27
versionCode = 36 versionCode = 37
versionName = '4.1.2' versionName = '5.0.0'
externalNativeBuild { externalNativeBuild {
cmake { cmake {
cFlags '-DHAVE_INTTYPES_H' cFlags '-DHAVE_INTTYPES_H'
+2 -3
View File
@@ -8,7 +8,6 @@
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-permission android:name="android.permission.WAKE_LOCK" /> <uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" /> <uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
<uses-permission android:name="android.permission.CALL_PHONE" />
<uses-feature <uses-feature
android:name="android.hardware.telephony" android:name="android.hardware.telephony"
@@ -67,8 +66,8 @@
android:parentActivityName=".ContactsActivity" > android:parentActivityName=".ContactsActivity" >
</activity> </activity>
<activity <activity
android:name=".EditConfigActivity" android:name=".ConfigActivity"
android:label="Edit Config" android:label="Config"
android:parentActivityName=".MainActivity" > android:parentActivityName=".MainActivity" >
</activity> </activity>
<activity <activity
+41 -170
View File
@@ -1,171 +1,42 @@
# auto_start no
# baresip configuration poll_method epoll
# sip_trans_bsize 128
call_local_timeout 120
call_max_calls 4
audio_player opensles,nil
audio_source opensles,nil
audio_alert opensles,nil
audio_srate 8000-48000
audio_channels 1-2
audio_level no
rtp_tos 184
rtcp_enable yes
rtcp_mux no
jitter_buffer_delay 5-10
rtp_stats no
dns_server 8.8.8.8:53
module opus.so
module g711.so
module opensles.so
module stun.so
module turn.so
module ice.so
module srtp.so
module dtls_srtp.so
module zrtp.so
module_tmp uuid.so
module_tmp account.so
module_app auloop.so
module_app contact.so
module_app debug_cmd.so
module_app mwi.so
evdev_device /dev/input/event0
opus_bitrate 28000
opus_cbr no
opus_inbandfec yes
ice_turn no
ice_debug no
ice_nomination regular
ice_mode full
zrtp_hash yes
#------------------------------------------------------------------------------
# Core
poll_method epoll # poll, select, epoll ..
# SIP
sip_trans_bsize 128
#sip_listen 0.0.0.0:5060
#sip_certificate cert.pem
# Call
call_local_timeout 120
call_max_calls 4
# Audio
audio_player opensles,nil
audio_source opensles,nil
audio_alert opensles,nil
#ausrc_srate 48000
#auplay_srate 48000
#ausrc_channels 0
#auplay_channels 0
audio_level no
# Video
#video_source v4l2,/dev/video0
#video_display x11,nil
video_size 352x288
video_bitrate 500000
video_fps 25
video_fullscreen yes
# AVT - Audio/Video Transport
rtp_tos 184
#rtp_ports 10000-20000
#rtp_bandwidth 512-1024 # [kbit/s]
rtcp_enable yes
rtcp_mux no
jitter_buffer_delay 5-10 # frames
rtp_stats no
#rtp_timeout 60
# Network
dns_server 8.8.8.8:53
#net_interface ^
# BFCP
#bfcp_proto udp
#------------------------------------------------------------------------------
# Modules
# UI Modules
#module stdio.so
#module cons.so
#module evdev.so
# Audio codec Modules (in order)
module opus.so
#module g7221.so
#module amr.so
#module g722.so
#module g726.so
module g711.so
#module l16.so
#module bv32.so
#module mpa.so
#module codec2.so
# Audio filter Modules (in encoding order)
#module vumeter.so
#module sndfile.so
#module plc.so
# Audio driver Modules
module opensles.so
#module aubridge.so
#module aufile.so
# Video codec Modules (in order)
#module avcodec.so
#module vp8.so
#module vp9.so
#module h265.so
# Video filter Modules (in encoding order)
#module selfview.so
#module snapshot.so
#module swscale.so
#module vidinfo.so
# Video source modules
#module v4l.so
#module v4l2.so
#module v4l2_codec.so
#module cairo.so
#module vidbridge.so
# Video display modules
#module directfb.so
#module sdl2.so
#module fakevideo.so
# Audio/Video source modules
#module rst.so
#module gst1.so
#module gst_video1.so
# Media NAT modules
module stun.so
module turn.so
module ice.so
#module natpmp.so
# Media encryption modules
module srtp.so
module dtls_srtp.so
module zrtp.so
#------------------------------------------------------------------------------
# Temporary Modules (loaded then unloaded)
module_tmp uuid.so
module_tmp account.so
#------------------------------------------------------------------------------
# Application Modules
module_app auloop.so
module_app contact.so
module_app debug_cmd.so
#module_app dtmfio.so
#module_app echo.so
module_app mwi.so
#module_app natbd.so
#module_app presence.so
#module_app vidloop.so
#------------------------------------------------------------------------------
# Module parameters
cons_listen 0.0.0.0:5555
http_listen 0.0.0.0:8000
evdev_device /dev/input/event0
# Opus codec parameters
opus_bitrate 28000 # 6000-510000
opus_cbr no
opus_inbandfec yes
# Selfview
#video_selfview window # {window,pip}
#selfview_size 64x64
# ICE
ice_turn no
ice_debug no
ice_nomination regular # {regular,aggressive}
ice_mode full # {full,lite}
# ZRTP
zrtp_hash yes
+80
View File
@@ -686,6 +686,36 @@ Java_com_tutpro_baresip_AccountKt_account_1set_1mediaenc(JNIEnv *env, jobject th
(*env)->ReleaseStringUTFChars(env, javaMencid, mencid); (*env)->ReleaseStringUTFChars(env, javaMencid, mencid);
return res; 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 JNIEXPORT jstring JNICALL
Java_com_tutpro_baresip_AccountKt_account_1sipnat(JNIEnv *env, jobject thiz, jstring javaAcc) 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; 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 JNIEXPORT jint JNICALL
Java_com_tutpro_baresip_AccountKt_account_1set_1mwi(JNIEnv *env, jobject thiz, Java_com_tutpro_baresip_AccountKt_account_1set_1mwi(JNIEnv *env, jobject thiz,
jstring javaAcc, jstring javaValue) { jstring javaAcc, jstring javaValue) {
@@ -7,15 +7,25 @@ class Account(val accp: String) {
var authUser = account_auth_user(accp) var authUser = account_auth_user(accp)
var authPass = account_auth_pass(accp) var authPass = account_auth_pass(accp)
var outbound = ArrayList<String>() var outbound = ArrayList<String>()
var mediaNat = account_medianat(accp)
var stunServer = ""
var audioCodec = ArrayList<String>() var audioCodec = ArrayList<String>()
var regint = account_regint(accp) var regint = account_regint(accp)
var mediaenc = account_mediaenc(accp) var mediaEnc = account_mediaenc(accp)
var vmUri = account_vm_uri(accp) var vmUri = account_vm_uri(accp)
var vmNew = 0 var vmNew = 0
var vmOld = 0 var vmOld = 0
var missedCalls = false var missedCalls = false
init { 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 var i = 0
while (true) { while (true) {
val ob = account_outbound(accp, i) val ob = account_outbound(accp, i)
@@ -59,6 +69,10 @@ class Account(val accp: String) {
res = res + ";sipnat=outbound" res = res + ";sipnat=outbound"
} }
if (mediaNat != "") res = res + ";medianat=${mediaNat}"
if (stunServer != "") res = res + ";stunserver=\"stun:@${stunServer}\""
if (audioCodec.size > 0) { if (audioCodec.size > 0) {
var first = true var first = true
res = res + ";audio_codecs=" 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 == "") if (vmUri == "")
res = res + ";mwi=no" 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_audio_codec(acc: String, ix: Int): String
external fun account_regint(acc: String): Int external fun account_regint(acc: String): Int
external fun account_set_regint(acc: String, regint: Int): 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_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_audio_codecs(acc: String, codecs: String): Int
external fun account_set_mwi(acc: String, value: String): Int external fun account_set_mwi(acc: String, value: String): Int
external fun account_vm_uri(acc: String): String external fun account_vm_uri(acc: String): String
@@ -1,6 +1,5 @@
package com.tutpro.baresip package com.tutpro.baresip
import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.support.v7.app.AppCompatActivity import android.support.v7.app.AppCompatActivity
import android.util.Log import android.util.Log
@@ -21,6 +20,8 @@ class AccountActivity : AppCompatActivity() {
internal lateinit var authPass: EditText internal lateinit var authPass: EditText
internal lateinit var outbound1: EditText internal lateinit var outbound1: EditText
internal lateinit var outbound2: EditText internal lateinit var outbound2: EditText
internal lateinit var iceCheck: CheckBox
internal lateinit var stunServer: EditText
internal lateinit var regCheck: CheckBox internal lateinit var regCheck: CheckBox
internal lateinit var mediaEnc: String internal lateinit var mediaEnc: String
internal lateinit var vmUri: EditText internal lateinit var vmUri: EditText
@@ -56,6 +57,16 @@ class AccountActivity : AppCompatActivity() {
outbound2.setText(acc.outbound[1]) 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 = findViewById(R.id.Register) as CheckBox
regCheck.isChecked = acc.regint > 0 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 mediaEncSpinner = findViewById(R.id.mediaEncSpinner) as Spinner
val mediaEncKeys = arrayListOf("zrtp", "dtls_srtpf", "srtp-mand", "srtp", "") val mediaEncKeys = arrayListOf("zrtp", "dtls_srtpf", "srtp-mand", "srtp", "")
val mediaEncVals = 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) val keyVal = mediaEncVals.elementAt(keyIx)
mediaEncKeys.removeAt(keyIx) mediaEncKeys.removeAt(keyIx)
mediaEncVals.removeAt(keyIx) mediaEncVals.removeAt(keyIx)
mediaEncKeys.add(0, acc.mediaenc) mediaEncKeys.add(0, acc.mediaEnc)
mediaEncVals.add(0, keyVal) mediaEncVals.add(0, keyVal)
val mediaEncAdapter = ArrayAdapter<String>(this,android.R.layout.simple_spinner_item, val mediaEncAdapter = ArrayAdapter<String>(this,android.R.layout.simple_spinner_item,
mediaEncVals) mediaEncVals)
@@ -131,8 +142,6 @@ class AccountActivity : AppCompatActivity() {
override fun onOptionsItemSelected(item: MenuItem): Boolean { override fun onOptionsItemSelected(item: MenuItem): Boolean {
val intent = Intent(this, MainActivity::class.java)
if (item.itemId == R.id.checkIcon) { if (item.itemId == R.id.checkIcon) {
val dn = displayName.text.toString().trim() val dn = displayName.text.toString().trim()
@@ -170,7 +179,7 @@ class AccountActivity : AppCompatActivity() {
val ap = authPass.text.toString().trim() val ap = authPass.text.toString().trim()
if (ap != acc.authPass) { if (ap != acc.authPass) {
if (Utils.checkPrintASCII(ap)) { if (Utils.checkPrintAscii(ap)) {
if (account_set_auth_pass(acc.accp, ap) == 0) { if (account_set_auth_pass(acc.accp, ap) == 0) {
acc.authPass = account_auth_pass(acc.accp) acc.authPass = account_auth_pass(acc.accp)
// Log.d("Baresip", "New auth password is ${acc.authPass}") // Log.d("Baresip", "New auth password is ${acc.authPass}")
@@ -234,6 +243,46 @@ class AccountActivity : AppCompatActivity() {
Log.e("Baresip", "Setting of regint failed") 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<String>(newCodecs.filter { it != "" } as ArrayList<String>)) val ac = ArrayList(LinkedHashSet<String>(newCodecs.filter { it != "" } as ArrayList<String>))
if (ac != acc.audioCodec) { if (ac != acc.audioCodec) {
Log.d("Baresip", "New codecs ${newCodecs.filter { it != "" }}") 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) { if (account_set_mediaenc(acc.accp, mediaEnc) == 0) {
acc.mediaenc = account_mediaenc(acc.accp) acc.mediaEnc = account_mediaenc(acc.accp)
Log.d("Baresip", "New mediaenc is ${acc.mediaenc}") Log.d("Baresip", "New mediaenc is ${acc.mediaEnc}")
save = true save = true
} else { } else {
Log.e("Baresip", "Setting of mediaenc $mediaEnc failed") Log.e("Baresip", "Setting of mediaenc $mediaEnc failed")
@@ -324,6 +373,12 @@ class AccountActivity : AppCompatActivity() {
findViewById(R.id.RegTitle) as TextView -> { findViewById(R.id.RegTitle) as TextView -> {
Utils.alertView(this, "Register", getString(R.string.register)) 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 -> { findViewById(R.id.AudioCodecsTitle) as TextView -> {
Utils.alertView(this, "Audio Codecs", getString(R.string.auCodecs)) Utils.alertView(this, "Audio Codecs", getString(R.string.auCodecs))
} }
@@ -40,7 +40,7 @@ class AccountsActivity : AppCompatActivity() {
} else if (Account.exists(aor)) { } else if (Account.exists(aor)) {
Log.e("Baresip", "Account $aor already exists") Log.e("Baresip", "Account $aor already exists")
} else { } 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) { if (ua == null) {
Log.e("Baresip", "Failed to allocate UA for $aor") Log.e("Baresip", "Failed to allocate UA for $aor")
Utils.alertView(this, "Notice", Utils.alertView(this, "Notice",
@@ -101,7 +101,7 @@ class AccountsActivity : AppCompatActivity() {
var accounts = "" var accounts = ""
for (a in Account.accounts()) accounts = accounts + a.print() + "\n" for (a in Account.accounts()) accounts = accounts + a.print() + "\n"
Utils.putFileContents(File(filesPath + "/accounts"), accounts) Utils.putFileContents(File(filesPath + "/accounts"), accounts)
// Log.d("Baresip", "Saved accounts '${accounts}' to '${filesPath}/accounts") // Log.d("Baresip", "Saved accounts '${accounts}' to '${filesPath}/accounts'")
} }
} }
@@ -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)
}
}
@@ -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)
}
}
@@ -486,7 +486,7 @@ class MainActivity : AppCompatActivity() {
callTitle.text = "Incoming call from ..." callTitle.text = "Incoming call from ..."
else else
callTitle.text = "Outgoing call to ..." callTitle.text = "Outgoing call to ..."
if (acc.mediaenc == "") { if (acc.mediaEnc == "") {
securityButton.visibility = View.INVISIBLE securityButton.visibility = View.INVISIBLE
} else { } else {
securityButton.setImageResource(R.drawable.box_red) securityButton.setImageResource(R.drawable.box_red)
@@ -819,6 +819,11 @@ class MainActivity : AppCompatActivity() {
R.color.colorPrimary)) R.color.colorPrimary))
return true return true
} }
R.id.config -> {
i = Intent(this, ConfigActivity::class.java)
startActivityForResult(i, CONFIG_CODE)
return true
}
R.id.accounts -> { R.id.accounts -> {
i = Intent(this, AccountsActivity::class.java) i = Intent(this, AccountsActivity::class.java)
val b = Bundle() val b = Bundle()
@@ -827,11 +832,6 @@ class MainActivity : AppCompatActivity() {
startActivityForResult(i, ACCOUNTS_CODE) startActivityForResult(i, ACCOUNTS_CODE)
return true return true
} }
R.id.config -> {
i = Intent(this, EditConfigActivity::class.java)
startActivityForResult(i, EDIT_CONFIG_CODE)
return true
}
R.id.about -> { R.id.about -> {
Api.cmd_exec("audio_debug") Api.cmd_exec("audio_debug")
i = Intent(this, AboutActivity::class.java) i = Intent(this, AboutActivity::class.java)
@@ -901,15 +901,12 @@ class MainActivity : AppCompatActivity() {
Contact.contacts().map{Contact -> Contact.name})) Contact.contacts().map{Contact -> Contact.name}))
} }
EDIT_CONFIG_CODE -> { CONFIG_CODE -> {
if (resultCode == RESULT_OK) { if (resultCode == RESULT_OK)
Utils.alertView(this, "Notice", Utils.alertView(this, "Notice",
"You need to restart baresip in order to activate saved config!") "You need to restart baresip in order to activate saved config!")
Api.reload_config() if (resultCode == RESULT_CANCELED)
} Log.d("Baresip", "Config canceled")
if (resultCode == RESULT_CANCELED) {
Log.d("Baresip", "Edit config canceled")
}
} }
CALLS_CODE -> { CALLS_CODE -> {
@@ -1078,7 +1075,7 @@ class MainActivity : AppCompatActivity() {
"connected" -> { "connected" -> {
securityButton.setImageResource(call.security) securityButton.setImageResource(call.security)
setSecurityButtonTag(securityButton, 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 securityButton.visibility = View.VISIBLE
else else
securityButton.visibility = View.INVISIBLE securityButton.visibility = View.INVISIBLE
@@ -1109,7 +1106,7 @@ class MainActivity : AppCompatActivity() {
const val ACCOUNTS_CODE = 1 const val ACCOUNTS_CODE = 1
const val CONTACTS_CODE = 2 const val CONTACTS_CODE = 2
const val EDIT_CONFIG_CODE = 3 const val CONFIG_CODE = 3
const val CALLS_CODE = 4 const val CALLS_CODE = 4
const val ABOUT_CODE = 5 const val ABOUT_CODE = 5
const val ACCOUNT_CODE = 6 const val ACCOUNT_CODE = 6
@@ -6,18 +6,25 @@ import android.content.Intent
import android.os.Bundle import android.os.Bundle
import android.util.Log import android.util.Log
import java.io.File
class RunOnStartup : BroadcastReceiver() { class RunOnStartup : BroadcastReceiver() {
override fun onReceive(context: Context, intent: Intent) { override fun onReceive(context: Context, intent: Intent) {
if ((intent.action == Intent.ACTION_BOOT_COMPLETED) or if ((intent.action == Intent.ACTION_BOOT_COMPLETED) or
(intent.action == "com.tutpro.baresip.Restart")) { (intent.action == "com.tutpro.baresip.Restart")) {
Log.d("Baresip", "Start baresip upon boot completed or restart") val configFile = File(context.filesDir.absolutePath + "/config")
val i = Intent(context, MainActivity::class.java) val config = Utils.getFileContents(configFile)
i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK) val asCv = Utils.getNameValue(config,"auto_start")
val b = Bundle() if ((asCv.size > 0) && (asCv[0] == "yes")) {
b.putBoolean("onStartup", true) Log.d("Baresip", "Start baresip upon boot completed or restart")
i.putExtras(b) val i = Intent(context, MainActivity::class.java)
context.startActivity(i) i.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
val b = Bundle()
b.putBoolean("onStartup", true)
i.putExtras(b)
context.startActivity(i)
}
} }
} }
@@ -36,7 +36,7 @@ class UserAgent (val uap: String) {
fun remove(ua: UserAgent) { fun remove(ua: UserAgent) {
val index = BaresipService.uas.indexOf(ua) val index = BaresipService.uas.indexOf(ua)
if (index != -1) { if (index != -1) {
BaresipService.uas[index].destroy() BaresipService.uas.removeAt(index)
BaresipService.status.removeAt(index) BaresipService.status.removeAt(index)
} }
} }
+42 -18
View File
@@ -18,7 +18,6 @@ object Utils {
Log.e("Baresip", "Failed to find file: " + file.path) Log.e("Baresip", "Failed to find file: " + file.path)
return "" return ""
} else { } else {
Log.e("Baresip", "Found file: " + file.path)
val length = file.length().toInt() val length = file.length().toInt()
val bytes = ByteArray(length) val bytes = ByteArray(length)
try { try {
@@ -56,6 +55,23 @@ object Utils {
} }
fun getNameValue(string: String, name: String): ArrayList<String> {
val lines = string.split("\n")
val result = ArrayList<String>()
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) { fun copyAssetToFile(context: Context, asset: String, path: String) {
try { try {
val `is` = context.assets.open(asset) val `is` = context.assets.open(asset)
@@ -131,35 +147,49 @@ object Utils {
fun checkDomain(domain: String): Boolean { fun checkDomain(domain: String): Boolean {
val parts = domain.split(".") val parts = domain.split(".")
for (p in parts) { 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 false
} }
return true return true
} }
fun checkPort(p: String) : Boolean { fun checkPort(port: String): Boolean {
val number = p.toIntOrNull() val number = port.toIntOrNull()
if (number == null) return false 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(":") val parts = hp.split(":")
if (portMandatory && (parts.size != 2)) return false
if (parts.size == 1) return checkIP(parts[0]) || checkDomain(parts[0]) if (parts.size == 1) return checkIP(parts[0]) || checkDomain(parts[0])
return checkPort(parts[1]) && (checkIP(parts[0]) || checkDomain(parts[0])) return checkPort(parts[1]) && (checkIP(parts[0]) || checkDomain(parts[0]))
} }
fun checkParams(p: String) : Boolean { fun checkParams(params: String): Boolean {
/* todo: proper check */ for (param in params.split(";"))
if (!checkParam(param)) return false
return true 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 { fun checkHostPortParams(hpp: String) : Boolean {
val restParams = hpp.split(";", limit = 2) val restParams = hpp.split(";", limit = 2)
if (restParams.size == 1) if (restParams.size == 1)
return checkHostPort(restParams[0]) return checkHostPort(restParams[0], false)
else else
return checkHostPort(restParams[0]) && checkParams(restParams[1]) return checkHostPort(restParams[0], false) && checkParams(restParams[1])
} }
fun checkSipUri(uri: String): Boolean { fun checkSipUri(uri: String): Boolean {
@@ -186,15 +216,9 @@ object Utils {
return checkHostPortParams(uri.substring(4)) return checkHostPortParams(uri.substring(4))
} }
fun checkPrintASCII(s: String): Boolean { fun checkPrintAscii(s: String): Boolean {
if (s == "") return true if (s == "") return true
val printASCIIRegex = Regex("^[ -~]*\$") return Regex("^[ -~]*\$").matches(s)
return printASCIIRegex.matches(s)
}
fun checkUint(s: String): Boolean {
val uintRegex = Regex("^[0-9]+\$")
return uintRegex.matches(s)
} }
fun checkName(name: String): Boolean { fun checkName(name: String): Boolean {
+51 -4
View File
@@ -98,10 +98,10 @@
android:hint="SIP URI of another Proxy Server" android:hint="SIP URI of another Proxy Server"
android:textSize="18sp" android:textSize="18sp"
android:inputType="textEmailAddress" android:inputType="textEmailAddress"
android:layout_width="fill_parent"> android:layout_width="fill_parent" >
</EditText> </EditText>
<LinearLayout <RelativeLayout
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:orientation="horizontal" > android:orientation="horizontal" >
@@ -109,6 +109,7 @@
android:id="@+id/RegTitle" android:id="@+id/RegTitle"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:textSize="18sp" android:textSize="18sp"
android:textColor="@android:color/black" android:textColor="@android:color/black"
android:onClick="onClick" android:onClick="onClick"
@@ -118,10 +119,56 @@
android:id="@+id/Register" android:id="@+id/Register"
android:layout_width="wrap_content" android:layout_width="wrap_content"
android:layout_height="wrap_content" android:layout_height="wrap_content"
android:text="" android:layout_alignParentEnd="true"
android:layout_gravity="end"
android:checked="false" > android:checked="false" >
</CheckBox> </CheckBox>
</LinearLayout> </RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/IceTitle"
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"
android:text="Use ICE" >
</TextView>
<CheckBox
android:id="@+id/Ice"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_gravity="end"
android:checked="false" >
</CheckBox>
</RelativeLayout>
<TextView
android:id="@+id/StunServerTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_marginStart="10dp"
android:textSize="18sp"
android:textColor="@android:color/black"
android:text="STUN Server"
android:onClick="onClick" >
</TextView>
<EditText
android:id="@+id/StunServer"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_marginStart="10dp"
android:textSize="18sp"
android:scrollHorizontally="true"
android:inputType="textEmailAddress" >
</EditText>
<TextView <TextView
android:id="@+id/AudioCodecsTitle" android:id="@+id/AudioCodecsTitle"
+129
View File
@@ -0,0 +1,129 @@
<?xml version="1.0" encoding="utf-8"?>
<ScrollView
xmlns:android="http://schemas.android.com/apk/res/android"
android:id="@+id/ConfigView"
android:layout_width="match_parent"
android:layout_height="wrap_content"
android:scrollbars="vertical">
<LinearLayout
android:layout_width="fill_parent"
android:orientation="vertical"
android:layout_height="wrap_content"
android:paddingLeft="16dp"
android:paddingRight="16dp"
android:paddingTop="16dp"
android:paddingBottom="24dp"
android:focusableInTouchMode="true" >
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/AutoStartTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:textSize="18sp"
android:textColor="@android:color/black"
android:onClick="onClick"
android:text="Start Automatically" >
</TextView>
<CheckBox
android:id="@+id/AutoStart"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_gravity="end"
android:checked="false" >
</CheckBox>
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/DnsServersTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:textSize="18sp"
android:textColor="@android:color/black"
android:onClick="onClick"
android:text="DNS Servers" >
</TextView>
<EditText
android:id="@+id/DnsServers"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_toEndOf="@+id/DnsServersTitle"
android:layout_centerVertical="true"
android:layout_marginStart="10dp"
android:textSize="18sp"
android:scrollHorizontally="true" >
</EditText>
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/OpusBitRateTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:textSize="18sp"
android:textColor="@android:color/black"
android:onClick="onClick"
android:text="Opus Bit Rate" >
</TextView>
<EditText
android:id="@+id/OpusBitRate"
android:layout_height="wrap_content"
android:layout_width="fill_parent"
android:layout_centerVertical="true"
android:layout_toEndOf="@+id/OpusBitRateTitle"
android:layout_marginStart="10dp"
android:textSize="18sp"
android:scrollHorizontally="true"
android:inputType="numberDecimal" >
</EditText>
</RelativeLayout>
<RelativeLayout
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:orientation="horizontal" >
<TextView
android:id="@+id/IceLiteTitle"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentStart="true"
android:layout_centerVertical="true"
android:textSize="18sp"
android:textColor="@android:color/black"
android:onClick="onClick"
android:text="ICE Lite Mode" >
</TextView>
<CheckBox
android:id="@+id/IceLite"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentEnd="true"
android:layout_centerVertical="true"
android:layout_gravity="end"
android:checked="false" >
</CheckBox>
</RelativeLayout>
</LinearLayout>
</ScrollView>
@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.tutpro.baresip.EditAccountsActivity">
<EditText
android:id="@+id/editAccounts"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World!" />
</RelativeLayout>
@@ -1,18 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
android:paddingBottom="@dimen/activity_vertical_margin"
android:paddingLeft="@dimen/activity_horizontal_margin"
android:paddingRight="@dimen/activity_horizontal_margin"
android:paddingTop="@dimen/activity_vertical_margin"
tools:context="com.tutpro.baresip.EditConfigActivity">
<EditText
android:id="@+id/editConfig"
android:layout_width="fill_parent"
android:layout_height="wrap_content"
android:text="Hello World!" />
</RelativeLayout>
+3 -3
View File
@@ -1,11 +1,11 @@
<menu xmlns:android="http://schemas.android.com/apk/res/android"> <menu xmlns:android="http://schemas.android.com/apk/res/android">
<item android:id="@+id/accounts"
android:title="Accounts" />
<item android:id="@+id/config" <item android:id="@+id/config"
android:title="Config" /> android:title="Config" />
<item android:id="@+id/accounts"
android:title="Accounts" />
<item android:id="@+id/about" <item android:id="@+id/about"
android:title="About" /> android:title="About" />
+16 -5
View File
@@ -5,9 +5,8 @@
<b>Baresip based Android application</b>\n\n <b>Baresip based Android application</b>\n\n
Juha Heinanen [email protected]\n\n Juha Heinanen [email protected]\n\n
<b>Usage Hints</b>\n\n <b>Usage Hints</b>\n\n
- start by creating an account (click item titles for help)\n - check that config default values meet your needs (click item titles for help)\n
- usually there is no need to edit the config\n - then create one or more accounts (again click item titles for help)\n
- in config, dns_server by default points to 8.8.8.8:53 for Android 8+ usage\n
- peers of calls and messages can be added to contacts by long clicks\n - peers of calls and messages can be added to contacts by long clicks\n
- long clicks can also be used to remove calls, chats, messages, and contacts\n - long clicks can also be used to remove calls, chats, messages, and contacts\n
- call click when callee has not been given can be used for re-dial\n - call click when callee has not been given can be used for re-dial\n
@@ -25,6 +24,13 @@
<string name="register">If checked, registration is enabled and REGISTER requests are sent at <string name="register">If checked, registration is enabled and REGISTER requests are sent at
12 minute intervals. 12 minute intervals.
</string> </string>
<string name="ice">If checked, ICE (Interactive Connectivity Establishment) is enabled for NAT
traversal.
</string>
<string name="stunServer">A specific Stun Server used by ICE of form host[:port].
Factory default value is \'stun.l.google.com:19302\', pointing to public Google STUN server.
Username and password are currently not supported.
</string>
<string name="auCodecs">List of supported audio codecs in priority order.</string> <string name="auCodecs">List of supported audio codecs in priority order.</string>
<string name="mediaEnc">Selects media transport encryption protocol.\n <string name="mediaEnc">Selects media transport encryption protocol.\n
ZRTP (recommended) means that ZRTP end-to-end media encryption negotiation is tried after ZRTP (recommended) means that ZRTP end-to-end media encryption negotiation is tried after
@@ -41,5 +47,10 @@
<string name="vmUri">SIP URI for checking of voicemail messages. If left empty, voicemail <string name="vmUri">SIP URI for checking of voicemail messages. If left empty, voicemail
messages (Message Waiting Indications) are not subscribed to. messages (Message Waiting Indications) are not subscribed to.
</string>> </string>>
<string name="title_activity_message">MessageActivity</string> <string name="autoStart">If checked, baresip starts automatically after device (re)start.</string>
</resources> <string name="dnsServers">Comma separated list of DNS servers. Each DNS server is of form
server:port. Factory default value is \'8.8.8.8:53\' pointing to public Google DNS server.</string>
<string name="opusBitRate">Average maximum bit rate used by Opus audio stream.
Valid value are 6000-510000. Factory default is 28000.</string>
<string name="iceLite">If checked, ICE Lite Mode is used.</string>
</resources>
@@ -0,0 +1,6 @@
- Replaced text mode EditConfigActivity with graphical Config activity
- Current configuration items are Auto Start, DNS Servers, Opus Bit Rate,
and ICE Lite
- Added ICE and Stun Server account options
- Fixed bug in deleting of an account
- Updated libbaresip.a and baresip.h to latest baresip master