- 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:
@ -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'
|
||||
|
||||
@ -8,7 +8,6 @@
|
||||
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
|
||||
<uses-permission android:name="android.permission.WAKE_LOCK" />
|
||||
<uses-permission android:name="android.permission.DISABLE_KEYGUARD" />
|
||||
<uses-permission android:name="android.permission.CALL_PHONE" />
|
||||
|
||||
<uses-feature
|
||||
android:name="android.hardware.telephony"
|
||||
@ -67,8 +66,8 @@
|
||||
android:parentActivityName=".ContactsActivity" >
|
||||
</activity>
|
||||
<activity
|
||||
android:name=".EditConfigActivity"
|
||||
android:label="Edit Config"
|
||||
android:name=".ConfigActivity"
|
||||
android:label="Config"
|
||||
android:parentActivityName=".MainActivity" >
|
||||
</activity>
|
||||
<activity
|
||||
|
||||
@ -1,171 +1,42 @@
|
||||
#
|
||||
# baresip configuration
|
||||
#
|
||||
auto_start no
|
||||
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
|
||||
|
||||
@ -686,6 +686,36 @@ Java_com_tutpro_baresip_AccountKt_account_1set_1mediaenc(JNIEnv *env, jobject th
|
||||
(*env)->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) {
|
||||
|
||||
@ -7,15 +7,25 @@ class Account(val accp: String) {
|
||||
var authUser = account_auth_user(accp)
|
||||
var authPass = account_auth_pass(accp)
|
||||
var outbound = ArrayList<String>()
|
||||
var mediaNat = account_medianat(accp)
|
||||
var stunServer = ""
|
||||
var audioCodec = ArrayList<String>()
|
||||
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
|
||||
|
||||
@ -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<String>(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<String>(newCodecs.filter { it != "" } as ArrayList<String>))
|
||||
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))
|
||||
}
|
||||
|
||||
@ -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'")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
175
app/src/main/kotlin/com/tutpro/baresip/ConfigActivity.kt
Normal file
175
app/src/main/kotlin/com/tutpro/baresip/ConfigActivity.kt
Normal file
@ -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 ..."
|
||||
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
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -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)
|
||||
}
|
||||
}
|
||||
|
||||
@ -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<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) {
|
||||
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 {
|
||||
|
||||
@ -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" >
|
||||
</EditText>
|
||||
|
||||
<LinearLayout
|
||||
<RelativeLayout
|
||||
android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content"
|
||||
android:orientation="horizontal" >
|
||||
@ -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" >
|
||||
</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
|
||||
android:id="@+id/AudioCodecsTitle"
|
||||
|
||||
129
app/src/main/res/layout/activity_config.xml
Normal file
129
app/src/main/res/layout/activity_config.xml
Normal 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>
|
||||
@ -1,11 +1,11 @@
|
||||
<menu xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
|
||||
<item android:id="@+id/accounts"
|
||||
android:title="Accounts" />
|
||||
|
||||
<item android:id="@+id/config"
|
||||
android:title="Config" />
|
||||
|
||||
<item android:id="@+id/accounts"
|
||||
android:title="Accounts" />
|
||||
|
||||
<item android:id="@+id/about"
|
||||
android:title="About" />
|
||||
|
||||
|
||||
@ -5,9 +5,8 @@
|
||||
<b>Baresip based Android application</b>\n\n
|
||||
Juha Heinanen jh@tutpro.com\n\n
|
||||
<b>Usage Hints</b>\n\n
|
||||
- start by creating an account (click item titles for help)\n
|
||||
- usually there is no need to edit the config\n
|
||||
- in config, dns_server by default points to 8.8.8.8:53 for Android 8+ usage\n
|
||||
- check that config default values meet your needs (click item titles for help)\n
|
||||
- then create one or more accounts (again click item titles for help)\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
|
||||
- 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
|
||||
12 minute intervals.
|
||||
</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="mediaEnc">Selects media transport encryption protocol.\n
|
||||
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
|
||||
messages (Message Waiting Indications) are not subscribed to.
|
||||
</string>>
|
||||
<string name="title_activity_message">MessageActivity</string>
|
||||
</resources>
|
||||
<string name="autoStart">If checked, baresip starts automatically after device (re)start.</string>
|
||||
<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
|
||||
Reference in New Issue
Block a user