Added TURN media NAT option and possibility to give username/password
for STUN/TURN server.
This commit is contained in:
@@ -994,6 +994,64 @@ Java_com_tutpro_baresip_AccountKt_account_1set_1stun_1port(JNIEnv *env, jobject
|
|||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jstring JNICALL
|
||||||
|
Java_com_tutpro_baresip_AccountKt_account_1stun_1user(JNIEnv *env, jobject thiz, jstring jAcc)
|
||||||
|
{
|
||||||
|
const char *native_acc = (*env)->GetStringUTFChars(env, jAcc, 0);
|
||||||
|
struct account *acc = (struct account *) strtoul(native_acc, NULL, 10);
|
||||||
|
(*env)->ReleaseStringUTFChars(env, jAcc, native_acc);
|
||||||
|
if (acc) {
|
||||||
|
const char *stun_user = account_stun_user(acc);
|
||||||
|
if (stun_user) return (*env)->NewStringUTF(env, stun_user);
|
||||||
|
}
|
||||||
|
return (*env)->NewStringUTF(env, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL
|
||||||
|
Java_com_tutpro_baresip_AccountKt_account_1set_1stun_1user(JNIEnv *env, jobject thiz,
|
||||||
|
jstring jAcc, jstring jUser) {
|
||||||
|
const char *native_acc = (*env)->GetStringUTFChars(env, jAcc, 0);
|
||||||
|
struct account *acc = (struct account *)strtoul(native_acc, NULL, 10);
|
||||||
|
(*env)->ReleaseStringUTFChars(env, jAcc, native_acc);
|
||||||
|
const char *user = (*env)->GetStringUTFChars(env, jUser, 0);
|
||||||
|
int res;
|
||||||
|
if (strlen(user) > 0)
|
||||||
|
res = account_set_stun_user(acc, user);
|
||||||
|
else
|
||||||
|
res = account_set_stun_user(acc, NULL);
|
||||||
|
(*env)->ReleaseStringUTFChars(env, jUser, user);
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jstring JNICALL
|
||||||
|
Java_com_tutpro_baresip_AccountKt_account_1stun_1pass(JNIEnv *env, jobject thiz, jstring jAcc)
|
||||||
|
{
|
||||||
|
const char *native_acc = (*env)->GetStringUTFChars(env, jAcc, 0);
|
||||||
|
struct account *acc = (struct account *) strtoul(native_acc, NULL, 10);
|
||||||
|
(*env)->ReleaseStringUTFChars(env, jAcc, native_acc);
|
||||||
|
if (acc) {
|
||||||
|
const char *stun_pass = account_stun_pass(acc);
|
||||||
|
if (stun_pass) return (*env)->NewStringUTF(env, stun_pass);
|
||||||
|
}
|
||||||
|
return (*env)->NewStringUTF(env, "");
|
||||||
|
}
|
||||||
|
|
||||||
|
JNIEXPORT jint JNICALL
|
||||||
|
Java_com_tutpro_baresip_AccountKt_account_1set_1stun_1pass(JNIEnv *env, jobject thiz,
|
||||||
|
jstring jAcc, jstring jPass) {
|
||||||
|
const char *native_acc = (*env)->GetStringUTFChars(env, jAcc, 0);
|
||||||
|
struct account *acc = (struct account *)strtoul(native_acc, NULL, 10);
|
||||||
|
(*env)->ReleaseStringUTFChars(env, jAcc, native_acc);
|
||||||
|
const char *pass = (*env)->GetStringUTFChars(env, jPass, 0);
|
||||||
|
int res;
|
||||||
|
if (strlen(pass) > 0)
|
||||||
|
res = account_set_stun_pass(acc, pass);
|
||||||
|
else
|
||||||
|
res = account_set_stun_pass(acc, NULL);
|
||||||
|
(*env)->ReleaseStringUTFChars(env, jPass, pass);
|
||||||
|
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) {
|
||||||
|
|||||||
@@ -14,6 +14,8 @@ class Account(val accp: String) {
|
|||||||
var outbound = ArrayList<String>()
|
var outbound = ArrayList<String>()
|
||||||
var mediaNat = account_medianat(accp)
|
var mediaNat = account_medianat(accp)
|
||||||
var stunServer = ""
|
var stunServer = ""
|
||||||
|
var stunUser = account_stun_user(accp)
|
||||||
|
var stunPass = account_stun_pass(accp)
|
||||||
var audioCodec = ArrayList<String>()
|
var audioCodec = ArrayList<String>()
|
||||||
var videoCodec = ArrayList<String>()
|
var videoCodec = ArrayList<String>()
|
||||||
var regint = account_regint(accp)
|
var regint = account_regint(accp)
|
||||||
@@ -92,7 +94,11 @@ class Account(val accp: String) {
|
|||||||
|
|
||||||
if (mediaNat != "") res = res + ";medianat=${mediaNat}"
|
if (mediaNat != "") res = res + ";medianat=${mediaNat}"
|
||||||
|
|
||||||
if (stunServer != "") res = res + ";stunserver=\"stun:${stunServer}\""
|
if (stunServer != "") res = res + ";stunserver=\"${stunServer}\""
|
||||||
|
|
||||||
|
if (stunUser != "") res = res + ";stunuser=\"${stunUser}\""
|
||||||
|
|
||||||
|
if (stunPass != "") res = res + ";stunpass=\"${stunPass}\""
|
||||||
|
|
||||||
if (audioCodec.size > 0) {
|
if (audioCodec.size > 0) {
|
||||||
var first = true
|
var first = true
|
||||||
@@ -243,6 +249,10 @@ external fun account_stun_host(acc: String): String
|
|||||||
external fun account_stun_port(acc: String): Int
|
external fun account_stun_port(acc: String): Int
|
||||||
external fun account_set_stun_host(acc: String, host: 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_set_stun_port(acc: String, port: Int): Int
|
||||||
|
external fun account_stun_user(acc: String): String
|
||||||
|
external fun account_set_stun_user(acc: String, user: String): Int
|
||||||
|
external fun account_stun_pass(acc: String): String
|
||||||
|
external fun account_set_stun_pass(acc: String, pass: String): Int
|
||||||
external fun account_mediaenc(acc: String): String
|
external fun account_mediaenc(acc: String): String
|
||||||
external fun account_set_mediaenc(acc: String, mediaenc: String): Int
|
external fun account_set_mediaenc(acc: String, mediaenc: String): Int
|
||||||
external fun account_medianat(acc: String): String
|
external fun account_medianat(acc: String): String
|
||||||
|
|||||||
@@ -24,6 +24,8 @@ class AccountActivity : AppCompatActivity() {
|
|||||||
internal lateinit var outbound2: EditText
|
internal lateinit var outbound2: EditText
|
||||||
internal lateinit var mediaNat: String
|
internal lateinit var mediaNat: String
|
||||||
internal lateinit var stunServer: EditText
|
internal lateinit var stunServer: EditText
|
||||||
|
internal lateinit var stunUser: EditText
|
||||||
|
internal lateinit var stunPass: EditText
|
||||||
internal lateinit var regCheck: CheckBox
|
internal lateinit var regCheck: CheckBox
|
||||||
internal lateinit var mediaEnc: String
|
internal lateinit var mediaEnc: String
|
||||||
internal lateinit var ipV6MediaCheck: CheckBox
|
internal lateinit var ipV6MediaCheck: CheckBox
|
||||||
@@ -78,8 +80,8 @@ class AccountActivity : AppCompatActivity() {
|
|||||||
|
|
||||||
mediaNat = acc.mediaNat
|
mediaNat = acc.mediaNat
|
||||||
val mediaNatSpinner = findViewById(R.id.mediaNatSpinner) as Spinner
|
val mediaNatSpinner = findViewById(R.id.mediaNatSpinner) as Spinner
|
||||||
val mediaNatKeys = arrayListOf("stun", "ice", "")
|
val mediaNatKeys = arrayListOf("stun", "turn", "ice", "")
|
||||||
val mediaNatVals = arrayListOf("STUN", "ICE", "-")
|
val mediaNatVals = arrayListOf("STUN", "TURN", "ICE", "-")
|
||||||
var keyIx = mediaNatKeys.indexOf(acc.mediaNat)
|
var keyIx = mediaNatKeys.indexOf(acc.mediaNat)
|
||||||
var keyVal = mediaNatVals.elementAt(keyIx)
|
var keyVal = mediaNatVals.elementAt(keyIx)
|
||||||
mediaNatKeys.removeAt(keyIx)
|
mediaNatKeys.removeAt(keyIx)
|
||||||
@@ -94,6 +96,8 @@ class AccountActivity : AppCompatActivity() {
|
|||||||
override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
|
override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
|
||||||
mediaNat = mediaNatKeys[mediaNatVals.indexOf(parent.selectedItem.toString())]
|
mediaNat = mediaNatKeys[mediaNatVals.indexOf(parent.selectedItem.toString())]
|
||||||
stunServer.isEnabled = mediaNat != ""
|
stunServer.isEnabled = mediaNat != ""
|
||||||
|
stunUser.isEnabled = mediaNat != ""
|
||||||
|
stunPass.isEnabled = mediaNat != ""
|
||||||
}
|
}
|
||||||
override fun onNothingSelected(parent: AdapterView<*>) {
|
override fun onNothingSelected(parent: AdapterView<*>) {
|
||||||
}
|
}
|
||||||
@@ -103,6 +107,14 @@ class AccountActivity : AppCompatActivity() {
|
|||||||
stunServer.setText(acc.stunServer)
|
stunServer.setText(acc.stunServer)
|
||||||
stunServer.isEnabled = mediaNat != ""
|
stunServer.isEnabled = mediaNat != ""
|
||||||
|
|
||||||
|
stunUser = findViewById(R.id.StunUser) as EditText
|
||||||
|
stunUser.setText(acc.stunUser)
|
||||||
|
stunUser.isEnabled = mediaNat != ""
|
||||||
|
|
||||||
|
stunPass = findViewById(R.id.StunPass) as EditText
|
||||||
|
stunPass.setText(acc.stunPass)
|
||||||
|
stunPass.isEnabled = mediaNat != ""
|
||||||
|
|
||||||
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_srtp", "srtp-mandf", "srtp-mand", "srtp", "")
|
val mediaEncKeys = arrayListOf("zrtp", "dtls_srtp", "srtp-mandf", "srtp-mand", "srtp", "")
|
||||||
@@ -312,31 +324,64 @@ class AccountActivity : AppCompatActivity() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (mediaNat != "") {
|
if (mediaNat != "") {
|
||||||
val newStunServer = stunServer.text.toString().trim()
|
var newStunServer = stunServer.text.toString().trim()
|
||||||
|
if (newStunServer == "")
|
||||||
|
newStunServer = resources.getString(R.string.stun_server_default)
|
||||||
if (acc.stunServer != newStunServer) {
|
if (acc.stunServer != newStunServer) {
|
||||||
if (!Utils.checkHostPort(newStunServer)) {
|
if (!Utils.checkStunUri(newStunServer)) {
|
||||||
Utils.alertView(this, getString(R.string.notice),
|
Utils.alertView(this, getString(R.string.notice),
|
||||||
String.format(getString(R.string.invalid_stun_server), newStunServer))
|
String.format(getString(R.string.invalid_stun_server), newStunServer))
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
val p = newStunServer.split(":")
|
||||||
var host = ""
|
var host = ""
|
||||||
var port = 0
|
val port: Int
|
||||||
if (newStunServer != "") {
|
if (p.size == 2) {
|
||||||
val hostPort = newStunServer.split(":")
|
host = newStunServer
|
||||||
host = hostPort[0]
|
port = 0
|
||||||
if (hostPort.size == 2) port = hostPort[1].toInt()
|
} else {
|
||||||
|
host = newStunServer.substringBeforeLast(":")
|
||||||
|
port = newStunServer.substringAfterLast(":").toInt()
|
||||||
}
|
}
|
||||||
if ((account_set_stun_host(acc.accp, host) == 0) &&
|
if ((account_set_stun_host(acc.accp, host) == 0) &&
|
||||||
(account_set_stun_port(acc.accp, port) == 0)) {
|
(account_set_stun_port(acc.accp, port) == 0)) {
|
||||||
acc.stunServer = account_stun_host(acc.accp)
|
acc.stunServer = account_stun_host(acc.accp)
|
||||||
if (port != 0)
|
if (port != 0)
|
||||||
acc.stunServer += ":" + account_stun_port(acc.accp).toString()
|
acc.stunServer += ":" + account_stun_port(acc.accp).toString()
|
||||||
Log.d("Baresip", "New StunServer is '${acc.stunServer}'")
|
Log.d("Baresip", "New STUN/TURN server URI is '${acc.stunServer}'")
|
||||||
save = true
|
save = true
|
||||||
} else {
|
} else {
|
||||||
Log.e("Baresip", "Setting of StunServer failed")
|
Log.e("Baresip", "Setting of STUN/TURN URI server failed")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val su = stunUser.text.toString().trim()
|
||||||
|
if (Account.checkAuthUser(su)) {
|
||||||
|
if (account_set_stun_user(acc.accp, su) == 0) {
|
||||||
|
acc.stunUser = account_stun_user(acc.accp);
|
||||||
|
Log.d("Baresip", "New STUN/TURN user is ${acc.stunUser}")
|
||||||
|
save = true
|
||||||
|
} else {
|
||||||
|
Log.e("Baresip", "Setting of STUN/TURN user failed")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Utils.alertView(this, getString(R.string.notice),
|
||||||
|
String.format(getString(R.string.invalid_stun_username), su))
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
val sp = stunPass.text.toString().trim()
|
||||||
|
if (sp.isEmpty() || Account.checkAuthPass(sp)) {
|
||||||
|
if (account_set_stun_pass(acc.accp, sp) == 0) {
|
||||||
|
acc.stunPass = account_stun_pass(acc.accp);
|
||||||
|
Log.d("Baresip", "New stun pass is ${acc.stunPass}")
|
||||||
|
save = true
|
||||||
|
} else {
|
||||||
|
Log.e("Baresip", "Setting of stun pass failed")
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
Utils.alertView(this, getString(R.string.notice),
|
||||||
|
String.format(getString(R.string.invalid_stun_password), sp))
|
||||||
|
return false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mediaEnc != acc.mediaEnc) {
|
if (mediaEnc != acc.mediaEnc) {
|
||||||
@@ -469,6 +514,14 @@ class AccountActivity : AppCompatActivity() {
|
|||||||
Utils.alertView(this, getString(R.string.stun_server),
|
Utils.alertView(this, getString(R.string.stun_server),
|
||||||
getString(R.string.stun_server_help))
|
getString(R.string.stun_server_help))
|
||||||
}
|
}
|
||||||
|
findViewById(R.id.StunUserTitle) as TextView -> {
|
||||||
|
Utils.alertView(this, getString(R.string.stun_username),
|
||||||
|
getString(R.string.stun_username_help))
|
||||||
|
}
|
||||||
|
findViewById(R.id.StunPassTitle) as TextView -> {
|
||||||
|
Utils.alertView(this, getString(R.string.stun_password),
|
||||||
|
getString(R.string.stun_password_help))
|
||||||
|
}
|
||||||
findViewById(R.id.MediaEncTitle) as TextView -> {
|
findViewById(R.id.MediaEncTitle) as TextView -> {
|
||||||
Utils.alertView(this, getString(R.string.media_encryption),
|
Utils.alertView(this, getString(R.string.media_encryption),
|
||||||
getString(R.string.media_encryption_help))
|
getString(R.string.media_encryption_help))
|
||||||
|
|||||||
@@ -125,6 +125,13 @@ object Utils {
|
|||||||
return checkUriUser(aorUser(aor)) && checkDomain(aorDomain(aor))
|
return checkUriUser(aorUser(aor)) && checkDomain(aorDomain(aor))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun checkStunUri(uri: String): Boolean {
|
||||||
|
if (!uri.startsWith("stun:") && !uri.startsWith("stuns:") &&
|
||||||
|
!uri.startsWith("turn:") && !uri.startsWith("turns:"))
|
||||||
|
return false
|
||||||
|
return checkHostPort(uri.substringAfter(":"))
|
||||||
|
}
|
||||||
|
|
||||||
private fun checkPortTransport(portTransport: String): Boolean {
|
private fun checkPortTransport(portTransport: String): Boolean {
|
||||||
val pt = portTransport.split(";transport=")
|
val pt = portTransport.split(";transport=")
|
||||||
if (pt.count() == 1)
|
if (pt.count() == 1)
|
||||||
|
|||||||
@@ -154,6 +154,24 @@
|
|||||||
android:text="@string/audio_codecs" >
|
android:text="@string/audio_codecs" >
|
||||||
</TextView>
|
</TextView>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/MediaEncTitle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingTop="10dp"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textColor="@android:color/black"
|
||||||
|
android:onClick="onClick"
|
||||||
|
android:text="@string/media_encryption" >
|
||||||
|
</TextView>
|
||||||
|
|
||||||
|
<Spinner
|
||||||
|
android:id="@+id/mediaEncSpinner"
|
||||||
|
android:layout_width="match_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingTop="8dp" >
|
||||||
|
</Spinner>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/MediaNatTitle"
|
android:id="@+id/MediaNatTitle"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
@@ -198,22 +216,46 @@
|
|||||||
</EditText>
|
</EditText>
|
||||||
|
|
||||||
<TextView
|
<TextView
|
||||||
android:id="@+id/MediaEncTitle"
|
android:id="@+id/StunUserTitle"
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingTop="10dp"
|
android:paddingTop="10dp"
|
||||||
android:textSize="18sp"
|
android:textSize="18sp"
|
||||||
android:textColor="@android:color/black"
|
android:textColor="@android:color/black"
|
||||||
android:onClick="onClick"
|
android:onClick="onClick"
|
||||||
android:text="@string/media_encryption" >
|
android:text="@string/stun_username" >
|
||||||
</TextView>
|
</TextView>
|
||||||
|
|
||||||
<Spinner
|
<EditText
|
||||||
android:id="@+id/mediaEncSpinner"
|
android:id="@+id/StunUser"
|
||||||
android:layout_width="match_parent"
|
|
||||||
android:layout_height="wrap_content"
|
android:layout_height="wrap_content"
|
||||||
android:paddingTop="8dp" >
|
android:layout_width="fill_parent"
|
||||||
</Spinner>
|
android:hint="@string/user_id"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:inputType="textEmailAddress"
|
||||||
|
android:autofillHints="username" >
|
||||||
|
</EditText>
|
||||||
|
|
||||||
|
<TextView
|
||||||
|
android:id="@+id/StunPassTitle"
|
||||||
|
android:layout_width="wrap_content"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:paddingTop="10dp"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:textColor="@android:color/black"
|
||||||
|
android:onClick="onClick"
|
||||||
|
android:text="@string/stun_password" >
|
||||||
|
</TextView>
|
||||||
|
|
||||||
|
<EditText
|
||||||
|
android:id="@+id/StunPass"
|
||||||
|
android:layout_width="fill_parent"
|
||||||
|
android:layout_height="wrap_content"
|
||||||
|
android:hint="@string/password"
|
||||||
|
android:textSize="18sp"
|
||||||
|
android:inputType="textPassword"
|
||||||
|
android:importantForAutofill="no" >
|
||||||
|
</EditText>
|
||||||
|
|
||||||
<RelativeLayout
|
<RelativeLayout
|
||||||
android:layout_width="wrap_content"
|
android:layout_width="wrap_content"
|
||||||
|
|||||||
@@ -84,13 +84,18 @@
|
|||||||
(vapaaehtoinen). Vaihtoehtoja ovat STUN (Session Traversal Utilities
|
(vapaaehtoinen). Vaihtoehtoja ovat STUN (Session Traversal Utilities
|
||||||
for NAT, RFC 5389) ja ICE (Interactive Connectivity Establishment, RFC 5245).
|
for NAT, RFC 5389) ja ICE (Interactive Connectivity Establishment, RFC 5245).
|
||||||
</string>
|
</string>
|
||||||
<string name="stun_server">STUN-palvelin</string>
|
<string name="stun_server">STUN/TURN-palvelin</string>
|
||||||
<string name="stun_server_help">STUN-palvelimen muotoa palvelin[:portti]
|
<string name="stun_server_help">STUN/TURN-palvelimen muotoa \'kaava:palvelin[:portti]\'
|
||||||
oleva osoite. Oletusarvo on \'stun.l.google.com:19302\', joka
|
oleva osoite, missä kaava on \'stun\', \'stuns\', \'turn\' tai \'turns\'. Oletusarvo on
|
||||||
osoittaa Google:n julkiseen STUN-palvelimeen. Käyttäjätunnusta ja
|
\'stun:stun.l.google.com:19302\', joka osoittaa Google:n julkiseen STUN-palvelimeen.
|
||||||
salasanaa ei voi tällä hetkellä antaa.
|
|
||||||
</string>
|
</string>
|
||||||
<string name="invalid_stun_server">Virheellinen STUN-palvelin \'%1$s\'</string>
|
<string name="invalid_stun_server">Virheellinen STUN/TURN-palvelimen URI \'%1$s\'</string>
|
||||||
|
<string name="stun_username">STUN/TURN-käyttäjätunnus</string>
|
||||||
|
<string name="stun_username_help">Käyttäjätunnus jos STUN/TURN-palvelin vaatii sellaisen</string>
|
||||||
|
<string name="invalid_stun_username">Virheellinen käyttäjätunnus \'%1$s\'</string>
|
||||||
|
<string name="stun_password">STUN/TURN-salasana</string>
|
||||||
|
<string name="stun_password_help">Salasana jos STUN/TURN-palvelin vaatii sellaisen</string>
|
||||||
|
<string name="invalid_stun_password">Virheellinen salasana \'%1$s\'</string>
|
||||||
<string name="media_encryption">Median salaus</string>
|
<string name="media_encryption">Median salaus</string>
|
||||||
<string name="media_encryption_help">Valitsee median salausprotokollan (vapaaehtoinen).
|
<string name="media_encryption_help">Valitsee median salausprotokollan (vapaaehtoinen).
|
||||||
\n • ZRTP (suositeltu) tarkoittaa, että ZRTP-salausta yritetään neuvotella sen jälkeen, kun puhelu on alkanut.
|
\n • ZRTP (suositeltu) tarkoittaa, että ZRTP-salausta yritetään neuvotella sen jälkeen, kun puhelu on alkanut.
|
||||||
|
|||||||
@@ -78,13 +78,19 @@
|
|||||||
(Session Traversal Utilities for NAT, RFC 5389) and ICE (Interactive Connectivity
|
(Session Traversal Utilities for NAT, RFC 5389) and ICE (Interactive Connectivity
|
||||||
Establishment, RFC 5245).
|
Establishment, RFC 5245).
|
||||||
</string>
|
</string>
|
||||||
<string name="stun_server">STUN Server</string>
|
<string name="stun_server">STUN/TURN Server</string>
|
||||||
<string name="stun_server_help">A STUN Server of form host[:port].
|
<string name="stun_server_help">A STUN/TURN Server URI of form scheme:host[:port], where scheme
|
||||||
Factory default value is \'stun.l.google.com:19302\', pointing to public Google STUN server.
|
is \'stun\', \'stuns\', \'turn\', or \'turns\'. Factory default value is
|
||||||
Username and password are currently not supported.
|
\'stun:stun.l.google.com:19302\', pointing to public Google STUN server.
|
||||||
</string>
|
</string>
|
||||||
<string name="invalid_stun_server">Invalid STUN Server \'%1$s\'</string>
|
<string name="invalid_stun_server">Invalid STUN/TURN Server URI \'%1$s\'</string>
|
||||||
<string name="stun_server_default" translatable="false">stun.l.google.com:19302</string>
|
<string name="stun_server_default" translatable="false">stun:stun.l.google.com:19302</string>
|
||||||
|
<string name="stun_username">STUN/TURN Username</string>
|
||||||
|
<string name="stun_username_help">Username if required by STUN/TURN server</string>
|
||||||
|
<string name="invalid_stun_username">Invalid Username \'%1$s\'</string>
|
||||||
|
<string name="stun_password">STUN/TURN Password</string>
|
||||||
|
<string name="stun_password_help">Password if required by STUN/TURN server</string>
|
||||||
|
<string name="invalid_stun_password">Invalid Password \'%1$s\'</string>
|
||||||
<string name="media_encryption">Media Encryption</string>
|
<string name="media_encryption">Media Encryption</string>
|
||||||
<string name="media_encryption_help">Selects media transport encryption protocol (if any).
|
<string name="media_encryption_help">Selects media transport encryption protocol (if any).
|
||||||
\n • ZRTP (recommended) means that ZRTP end-to-end media encryption negotiation is tried after
|
\n • ZRTP (recommended) means that ZRTP end-to-end media encryption negotiation is tried after
|
||||||
|
|||||||
Reference in New Issue
Block a user