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;
|
||||
}
|
||||
|
||||
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
|
||||
Java_com_tutpro_baresip_AccountKt_account_1set_1mwi(JNIEnv *env, jobject thiz,
|
||||
jstring javaAcc, jstring javaValue) {
|
||||
|
||||
@ -14,6 +14,8 @@ class Account(val accp: String) {
|
||||
var outbound = ArrayList<String>()
|
||||
var mediaNat = account_medianat(accp)
|
||||
var stunServer = ""
|
||||
var stunUser = account_stun_user(accp)
|
||||
var stunPass = account_stun_pass(accp)
|
||||
var audioCodec = ArrayList<String>()
|
||||
var videoCodec = ArrayList<String>()
|
||||
var regint = account_regint(accp)
|
||||
@ -92,7 +94,11 @@ class Account(val accp: String) {
|
||||
|
||||
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) {
|
||||
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_set_stun_host(acc: String, host: String): 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_set_mediaenc(acc: String, mediaenc: String): Int
|
||||
external fun account_medianat(acc: String): String
|
||||
|
||||
@ -24,6 +24,8 @@ class AccountActivity : AppCompatActivity() {
|
||||
internal lateinit var outbound2: EditText
|
||||
internal lateinit var mediaNat: String
|
||||
internal lateinit var stunServer: EditText
|
||||
internal lateinit var stunUser: EditText
|
||||
internal lateinit var stunPass: EditText
|
||||
internal lateinit var regCheck: CheckBox
|
||||
internal lateinit var mediaEnc: String
|
||||
internal lateinit var ipV6MediaCheck: CheckBox
|
||||
@ -78,8 +80,8 @@ class AccountActivity : AppCompatActivity() {
|
||||
|
||||
mediaNat = acc.mediaNat
|
||||
val mediaNatSpinner = findViewById(R.id.mediaNatSpinner) as Spinner
|
||||
val mediaNatKeys = arrayListOf("stun", "ice", "")
|
||||
val mediaNatVals = arrayListOf("STUN", "ICE", "-")
|
||||
val mediaNatKeys = arrayListOf("stun", "turn", "ice", "")
|
||||
val mediaNatVals = arrayListOf("STUN", "TURN", "ICE", "-")
|
||||
var keyIx = mediaNatKeys.indexOf(acc.mediaNat)
|
||||
var keyVal = mediaNatVals.elementAt(keyIx)
|
||||
mediaNatKeys.removeAt(keyIx)
|
||||
@ -94,6 +96,8 @@ class AccountActivity : AppCompatActivity() {
|
||||
override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
|
||||
mediaNat = mediaNatKeys[mediaNatVals.indexOf(parent.selectedItem.toString())]
|
||||
stunServer.isEnabled = mediaNat != ""
|
||||
stunUser.isEnabled = mediaNat != ""
|
||||
stunPass.isEnabled = mediaNat != ""
|
||||
}
|
||||
override fun onNothingSelected(parent: AdapterView<*>) {
|
||||
}
|
||||
@ -103,6 +107,14 @@ class AccountActivity : AppCompatActivity() {
|
||||
stunServer.setText(acc.stunServer)
|
||||
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
|
||||
val mediaEncSpinner = findViewById(R.id.mediaEncSpinner) as Spinner
|
||||
val mediaEncKeys = arrayListOf("zrtp", "dtls_srtp", "srtp-mandf", "srtp-mand", "srtp", "")
|
||||
@ -312,31 +324,64 @@ class AccountActivity : AppCompatActivity() {
|
||||
}
|
||||
|
||||
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 (!Utils.checkHostPort(newStunServer)) {
|
||||
if (!Utils.checkStunUri(newStunServer)) {
|
||||
Utils.alertView(this, getString(R.string.notice),
|
||||
String.format(getString(R.string.invalid_stun_server), newStunServer))
|
||||
return false
|
||||
}
|
||||
val p = newStunServer.split(":")
|
||||
var host = ""
|
||||
var port = 0
|
||||
if (newStunServer != "") {
|
||||
val hostPort = newStunServer.split(":")
|
||||
host = hostPort[0]
|
||||
if (hostPort.size == 2) port = hostPort[1].toInt()
|
||||
val port: Int
|
||||
if (p.size == 2) {
|
||||
host = newStunServer
|
||||
port = 0
|
||||
} else {
|
||||
host = newStunServer.substringBeforeLast(":")
|
||||
port = newStunServer.substringAfterLast(":").toInt()
|
||||
}
|
||||
if ((account_set_stun_host(acc.accp, host) == 0) &&
|
||||
(account_set_stun_port(acc.accp, port) == 0)) {
|
||||
acc.stunServer = account_stun_host(acc.accp)
|
||||
if (port != 0)
|
||||
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
|
||||
} 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) {
|
||||
@ -469,6 +514,14 @@ class AccountActivity : AppCompatActivity() {
|
||||
Utils.alertView(this, getString(R.string.stun_server),
|
||||
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 -> {
|
||||
Utils.alertView(this, getString(R.string.media_encryption),
|
||||
getString(R.string.media_encryption_help))
|
||||
|
||||
@ -125,6 +125,13 @@ object Utils {
|
||||
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 {
|
||||
val pt = portTransport.split(";transport=")
|
||||
if (pt.count() == 1)
|
||||
|
||||
@ -154,6 +154,24 @@
|
||||
android:text="@string/audio_codecs" >
|
||||
</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
|
||||
android:id="@+id/MediaNatTitle"
|
||||
android:layout_width="wrap_content"
|
||||
@ -198,22 +216,46 @@
|
||||
</EditText>
|
||||
|
||||
<TextView
|
||||
android:id="@+id/MediaEncTitle"
|
||||
android:id="@+id/StunUserTitle"
|
||||
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" >
|
||||
android:text="@string/stun_username" >
|
||||
</TextView>
|
||||
|
||||
<Spinner
|
||||
android:id="@+id/mediaEncSpinner"
|
||||
android:layout_width="match_parent"
|
||||
<EditText
|
||||
android:id="@+id/StunUser"
|
||||
android:layout_height="wrap_content"
|
||||
android:paddingTop="8dp" >
|
||||
</Spinner>
|
||||
android:layout_width="fill_parent"
|
||||
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
|
||||
android:layout_width="wrap_content"
|
||||
|
||||
@ -84,13 +84,18 @@
|
||||
(vapaaehtoinen). Vaihtoehtoja ovat STUN (Session Traversal Utilities
|
||||
for NAT, RFC 5389) ja ICE (Interactive Connectivity Establishment, RFC 5245).
|
||||
</string>
|
||||
<string name="stun_server">STUN-palvelin</string>
|
||||
<string name="stun_server_help">STUN-palvelimen muotoa palvelin[:portti]
|
||||
oleva osoite. Oletusarvo on \'stun.l.google.com:19302\', joka
|
||||
osoittaa Google:n julkiseen STUN-palvelimeen. Käyttäjätunnusta ja
|
||||
salasanaa ei voi tällä hetkellä antaa.
|
||||
<string name="stun_server">STUN/TURN-palvelin</string>
|
||||
<string name="stun_server_help">STUN/TURN-palvelimen muotoa \'kaava:palvelin[:portti]\'
|
||||
oleva osoite, missä kaava on \'stun\', \'stuns\', \'turn\' tai \'turns\'. Oletusarvo on
|
||||
\'stun:stun.l.google.com:19302\', joka osoittaa Google:n julkiseen STUN-palvelimeen.
|
||||
</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_help">Valitsee median salausprotokollan (vapaaehtoinen).
|
||||
\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
|
||||
Establishment, RFC 5245).
|
||||
</string>
|
||||
<string name="stun_server">STUN Server</string>
|
||||
<string name="stun_server_help">A STUN Server 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 name="stun_server">STUN/TURN Server</string>
|
||||
<string name="stun_server_help">A STUN/TURN Server URI of form scheme:host[:port], where scheme
|
||||
is \'stun\', \'stuns\', \'turn\', or \'turns\'. Factory default value is
|
||||
\'stun:stun.l.google.com:19302\', pointing to public Google STUN server.
|
||||
</string>
|
||||
<string name="invalid_stun_server">Invalid STUN Server \'%1$s\'</string>
|
||||
<string name="stun_server_default" translatable="false">stun.l.google.com:19302</string>
|
||||
<string name="invalid_stun_server">Invalid STUN/TURN Server URI \'%1$s\'</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_help">Selects media transport encryption protocol (if any).
|
||||
\n • ZRTP (recommended) means that ZRTP end-to-end media encryption negotiation is tried after
|
||||
|
||||
Reference in New Issue
Block a user