Added Check Origin account setting

Get Settings and Account strings outside of composables
This commit is contained in:
Juha Heinanen
2025-12-25 11:25:12 +02:00
parent 58688f31df
commit 38b5bef715
10 changed files with 438 additions and 267 deletions

View File

@ -2,6 +2,7 @@ poll_method epoll
call_local_timeout 120
call_max_calls 4
call_hold_other_calls yes
filter_registrar udp,tcp,tls,ws,wss
audio_player aaudio,nil
audio_source aaudio,nil
audio_alert aaudio,nil

View File

@ -827,6 +827,22 @@ JNIEXPORT jint JNICALL Java_com_tutpro_baresip_Api_account_1set_1regint(
return account_set_regint((struct account *)acc, regint);
}
JNIEXPORT jboolean JNICALL Java_com_tutpro_baresip_Api_account_1check_1origin(
JNIEnv *env, jobject obj, jlong acc)
{
(void)env;
(void)obj;
return account_check_origin((struct account *)acc);
}
JNIEXPORT void JNICALL Java_com_tutpro_baresip_Api_account_1set_1check_1origin(
JNIEnv *env, jobject obj, jlong acc, jboolean value)
{
(void)env;
(void)obj;
account_set_check_origin((struct account *)acc, value);
}
JNIEXPORT jstring JNICALL Java_com_tutpro_baresip_Api_account_1mediaenc(
JNIEnv *env, jobject obj, jlong acc)
{

View File

@ -21,6 +21,7 @@ class Account(val accp: Long) {
var audioCodec = ArrayList<String>()
var videoCodec = ArrayList<String>()
var regint = Api.account_regint(accp)
var checkOrigin = true
var configuredRegInt = REGISTRATION_INTERVAL
var mediaEnc = Api.account_mediaenc(accp)
var rtcpMux = Api.account_rtcp_mux(accp)
@ -101,6 +102,8 @@ class Account(val accp: Long) {
res = "$res;sipnat=outbound"
}
if (!checkOrigin) res += ";check_origin=no"
if (mediaNat != "") res += ";medianat=${mediaNat}"
if (stunServer != "")

View File

@ -218,7 +218,6 @@ private fun AccountContent(
) {
val ctx = LocalContext.current
val aor = ua.account.aor
val luri = ua.account.luri
val mediaNat by viewModel.mediaNat.collectAsState()
val showStun by remember { derivedStateOf { mediaNat.isNotEmpty() } }
@ -233,7 +232,7 @@ private fun AccountContent(
horizontalArrangement = Arrangement.Start
) {
OutlinedTextField(
value = luri,
value = ua.account.luri,
enabled = false,
onValueChange = {},
modifier = Modifier.fillMaxWidth(),
@ -254,6 +253,8 @@ private fun AccountContent(
@Composable
fun Nickname() {
val nickNameTitle = stringResource(R.string.nickname)
val nickNameHelp = stringResource(R.string.account_nickname_help)
Row(
Modifier.fillMaxWidth().padding(top = 8.dp, end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
@ -262,18 +263,18 @@ private fun AccountContent(
val nickName by viewModel.nickName.collectAsState()
OutlinedTextField(
value = nickName,
placeholder = { Text(stringResource(R.string.nickname)) },
placeholder = { Text(nickNameTitle) },
onValueChange = { viewModel.nickName.value = it },
modifier = Modifier
.fillMaxWidth()
.clickable {
alertTitle.value = ctx.getString(R.string.nickname)
alertMessage.value = ctx.getString(R.string.account_nickname_help)
alertTitle.value = nickNameTitle
alertMessage.value = nickNameHelp
showAlert.value = true
},
singleLine = true,
textStyle = TextStyle(fontSize = 18.sp),
label = { Text(stringResource(R.string.nickname)) },
label = { Text(nickNameTitle) },
keyboardOptions = KeyboardOptions(
capitalization = KeyboardCapitalization.Words,
keyboardType = KeyboardType.Text),
@ -283,7 +284,8 @@ private fun AccountContent(
@Composable
fun DisplayName() {
val ctx = LocalContext.current
val displayNameTitle = stringResource(R.string.display_name)
val displayNameHelp = stringResource(R.string.display_name_help)
Row(
Modifier.fillMaxWidth().padding(top = 8.dp, end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
@ -292,18 +294,18 @@ private fun AccountContent(
val displayName by viewModel.displayName.collectAsState()
OutlinedTextField(
value = displayName,
placeholder = { Text(stringResource(R.string.display_name)) },
placeholder = { Text(displayNameTitle) },
onValueChange = { viewModel.displayName.value = it },
modifier = Modifier
.fillMaxWidth()
.clickable {
alertTitle.value = ctx.getString(R.string.display_name)
alertMessage.value = ctx.getString(R.string.display_name_help)
alertTitle.value = displayNameTitle
alertMessage.value = displayNameHelp
showAlert.value = true
},
singleLine = true,
textStyle = TextStyle(fontSize = 18.sp),
label = { Text(stringResource(R.string.display_name)) },
label = { Text(displayNameTitle) },
keyboardOptions = KeyboardOptions(
capitalization = KeyboardCapitalization.Sentences,
keyboardType = KeyboardType.Text
@ -314,7 +316,8 @@ private fun AccountContent(
@Composable
fun AuthUser() {
val ctx = LocalContext.current
val authenticationUserNameTitle = stringResource(R.string.authentication_username)
val authenticationUserNameHelp = stringResource(R.string.authentication_username_help)
Row(
Modifier.fillMaxWidth().padding(top = 8.dp, end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
@ -323,17 +326,17 @@ private fun AccountContent(
val authUser by viewModel.authUser.collectAsState()
OutlinedTextField(
value = authUser,
placeholder = { Text(stringResource(R.string.authentication_username)) },
placeholder = { Text(authenticationUserNameTitle) },
onValueChange = { viewModel.authUser.value = it },
modifier = Modifier
.fillMaxWidth()
.clickable {
alertTitle.value = ctx.getString(R.string.authentication_username)
alertMessage.value = ctx.getString(R.string.authentication_username_help)
alertTitle.value = authenticationUserNameTitle
alertMessage.value = authenticationUserNameHelp
showAlert.value = true
},
textStyle = TextStyle(fontSize = 18.sp),
label = { Text(stringResource(R.string.authentication_username)) },
label = { Text(authenticationUserNameTitle) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
)
}
@ -341,7 +344,8 @@ private fun AccountContent(
@Composable
fun AuthPass() {
val ctx = LocalContext.current
val authenticationPasswordTitle = stringResource(R.string.authentication_password)
val authenticationPasswordHelp = stringResource(R.string.authentication_password_help)
val showPassword = remember { mutableStateOf(false) }
Row(
Modifier.fillMaxWidth().padding(top = 8.dp, end = 10.dp),
@ -351,7 +355,7 @@ private fun AccountContent(
val authPass by viewModel.authPass.collectAsState()
OutlinedTextField(
value = authPass,
placeholder = { Text(stringResource(R.string.authentication_password)) },
placeholder = { Text(authenticationPasswordTitle) },
onValueChange = { viewModel.authPass.value = it },
singleLine = true,
visualTransformation = if (showPassword.value)
@ -375,12 +379,12 @@ private fun AccountContent(
modifier = Modifier
.fillMaxWidth()
.clickable {
alertTitle.value = ctx.getString(R.string.authentication_password)
alertMessage.value = ctx.getString(R.string.authentication_password_help)
alertTitle.value = authenticationPasswordTitle
alertMessage.value = authenticationPasswordHelp
showAlert.value = true
},
textStyle = TextStyle(fontSize = 18.sp),
label = { Text(stringResource(R.string.authentication_password)) },
label = { Text(authenticationPasswordTitle) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
)
}
@ -412,14 +416,15 @@ private fun AccountContent(
@Composable
fun Outbound() {
val ctx = LocalContext.current
val outboundProxiesTitle = stringResource(R.string.outbound_proxies)
val outboundProxiesHelp = stringResource(R.string.outbound_proxies_help)
Text(text = stringResource(R.string.outbound_proxies),
fontSize = 18.sp,
modifier = Modifier
.padding(top = 8.dp)
.clickable {
alertTitle.value = ctx.getString(R.string.outbound_proxies)
alertMessage.value = ctx.getString(R.string.outbound_proxies_help)
alertTitle.value = outboundProxiesTitle
alertMessage.value = outboundProxiesHelp
showAlert.value = true
}
)
@ -429,14 +434,15 @@ private fun AccountContent(
horizontalArrangement = Arrangement.Start
) {
val outbound1 by viewModel.outbound1.collectAsState()
val sipUriOfProxyServerTitle = stringResource(R.string.sip_uri_of_proxy_server)
OutlinedTextField(
value = outbound1,
placeholder = { Text(stringResource(R.string.sip_uri_of_proxy_server)) },
placeholder = { Text(sipUriOfProxyServerTitle) },
onValueChange = { viewModel.outbound1.value = it },
modifier = Modifier.fillMaxWidth(),
singleLine = true,
textStyle = TextStyle(fontSize = 18.sp),
label = { Text(stringResource(R.string.sip_uri_of_proxy_server)) },
label = { Text(sipUriOfProxyServerTitle) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
)
}
@ -446,14 +452,15 @@ private fun AccountContent(
horizontalArrangement = Arrangement.Start
) {
val outbound2 by viewModel.outbound2.collectAsState()
val anotherProxyServerTitle = stringResource(R.string.sip_uri_of_another_proxy_server)
OutlinedTextField(
value = outbound2,
placeholder = { Text(stringResource(R.string.sip_uri_of_another_proxy_server)) },
placeholder = { Text(anotherProxyServerTitle) },
onValueChange = { viewModel.outbound2.value = it },
modifier = Modifier.fillMaxWidth(),
singleLine = true,
textStyle = TextStyle(fontSize = 18.sp),
label = { Text(stringResource(R.string.sip_uri_of_another_proxy_server)) },
label = { Text(anotherProxyServerTitle) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
)
}
@ -461,18 +468,19 @@ private fun AccountContent(
@Composable
fun Register() {
val ctx = LocalContext.current
val registerTitle = stringResource(R.string.register)
val registerHelp = stringResource(R.string.register_help)
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
Text(text = stringResource(R.string.register),
Text(text = registerTitle,
modifier = Modifier
.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.register)
alertMessage.value = ctx.getString(R.string.register_help)
alertTitle.value = registerTitle
alertMessage.value = registerHelp
showAlert.value = true
},
fontSize = 18.sp,
@ -487,7 +495,8 @@ private fun AccountContent(
@Composable
fun RegInt() {
val ctx = LocalContext.current
val regIntTitle = stringResource(R.string.reg_int)
val regIntHelp = stringResource(R.string.reg_int_help)
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
@ -496,23 +505,50 @@ private fun AccountContent(
val regInt by viewModel.regInt.collectAsState()
OutlinedTextField(
value = regInt,
placeholder = { Text(stringResource(R.string.reg_int)) },
placeholder = { Text(regIntTitle) },
onValueChange = { viewModel.regInt.value = it },
modifier = Modifier
.fillMaxWidth()
.clickable {
alertTitle.value = ctx.getString(R.string.reg_int)
alertMessage.value = ctx.getString(R.string.reg_int_help)
alertTitle.value = regIntTitle
alertMessage.value = regIntHelp
showAlert.value = true
},
singleLine = true,
textStyle = TextStyle(fontSize = 18.sp),
label = { Text(stringResource(R.string.reg_int)) },
label = { Text(regIntTitle) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Number)
)
}
}
@Composable
fun CheckOrigin() {
val checkOriginTitle = stringResource(R.string.check_origin)
val checkOriginHelp = stringResource(R.string.check_origin_help)
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
Text(text = checkOriginTitle,
modifier = Modifier
.weight(1f)
.clickable {
alertTitle.value = checkOriginTitle
alertMessage.value = checkOriginHelp
showAlert.value = true
},
fontSize = 18.sp,
)
val checkOrigin by viewModel.checkOrigin.collectAsState()
Switch(
checked = checkOrigin,
onCheckedChange = { viewModel.checkOrigin.value = it }
)
}
}
@Composable
fun AudioCodecs(navController: NavController, aor: String) {
Row(
@ -538,18 +574,19 @@ private fun AccountContent(
@Composable
fun MediaEnc() {
val ctx = LocalContext.current
val mediaEncryptionTitle = stringResource(R.string.media_encryption)
val mediaEncryptionHelp = stringResource(R.string.media_encryption_help)
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
Text(text = stringResource(R.string.media_encryption),
Text(text = mediaEncryptionTitle,
modifier = Modifier
.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.media_encryption)
alertMessage.value = ctx.getString(R.string.media_encryption_help)
alertTitle.value = mediaEncryptionTitle
alertMessage.value = mediaEncryptionHelp
showAlert.value = true
},
fontSize = 18.sp
@ -595,18 +632,19 @@ private fun AccountContent(
@Composable
fun MediaNat() {
val ctx = LocalContext.current
val mediaNatTitle = stringResource(R.string.media_nat)
val mediaNatHelp = stringResource(R.string.media_nat_help)
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
Text(text = stringResource(R.string.media_nat),
Text(mediaNatTitle,
modifier = Modifier
.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.media_nat)
alertMessage.value = ctx.getString(R.string.media_nat_help)
alertTitle.value = mediaNatTitle
alertMessage.value = mediaNatHelp
showAlert.value = true
},
fontSize = 18.sp
@ -653,6 +691,8 @@ private fun AccountContent(
@Composable
fun StunServer() {
val stunServerTitle = stringResource(R.string.stun_server)
val stunServerHelp = stringResource(R.string.stun_server_help)
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
@ -661,17 +701,17 @@ private fun AccountContent(
val stunServer by viewModel.stunServer.collectAsState()
OutlinedTextField(
value = stunServer,
placeholder = { Text(stringResource(R.string.stun_server)) },
placeholder = { Text(stunServerTitle) },
onValueChange = { viewModel.stunServer.value = it },
modifier = Modifier
.fillMaxWidth()
.clickable {
alertTitle.value = ctx.getString(R.string.stun_server)
alertMessage.value = ctx.getString(R.string.stun_server_help)
alertTitle.value = stunServerTitle
alertMessage.value = stunServerHelp
showAlert.value = true
},
textStyle = TextStyle(fontSize = 18.sp),
label = { Text(stringResource(R.string.stun_server)) },
label = { Text(stunServerTitle) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
)
}
@ -679,6 +719,8 @@ private fun AccountContent(
@Composable
fun StunUser() {
val stunUsernameTitle = stringResource(R.string.stun_username)
val stunUsernameHelp = stringResource(R.string.stun_username_help)
Row(
Modifier.fillMaxWidth().padding(top = 8.dp, end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
@ -687,17 +729,17 @@ private fun AccountContent(
val stunUser by viewModel.stunUser.collectAsState()
OutlinedTextField(
value = stunUser,
placeholder = { Text(stringResource(R.string.stun_username)) },
placeholder = { Text(stunUsernameTitle) },
onValueChange = { viewModel.stunUser.value = it },
modifier = Modifier
.fillMaxWidth()
.clickable {
alertTitle.value = ctx.getString(R.string.stun_username)
alertMessage.value = ctx.getString(R.string.stun_username_help)
alertTitle.value = stunUsernameTitle
alertMessage.value = stunUsernameHelp
showAlert.value = true
},
textStyle = TextStyle(fontSize = 18.sp),
label = { Text(stringResource(R.string.stun_username)) },
label = { Text(stunUsernameTitle) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
)
}
@ -705,6 +747,8 @@ private fun AccountContent(
@Composable
fun StunPass() {
val stunPasswordTitle = stringResource(R.string.stun_password)
val stunPasswordHelp = stringResource(R.string.stun_password_help)
val showPassword = remember { mutableStateOf(false) }
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
@ -714,7 +758,7 @@ private fun AccountContent(
val stunPass by viewModel.stunPass.collectAsState()
OutlinedTextField(
value = stunPass,
placeholder = { Text(stringResource(R.string.stun_password)) },
placeholder = { Text(stunPasswordTitle) },
onValueChange = { viewModel.stunPass.value = it },
singleLine = true,
visualTransformation = if (showPassword.value)
@ -736,12 +780,12 @@ private fun AccountContent(
modifier = Modifier
.fillMaxWidth()
.clickable {
alertTitle.value = ctx.getString(R.string.stun_password)
alertMessage.value = ctx.getString(R.string.stun_password_help)
alertTitle.value = stunPasswordTitle
alertMessage.value = stunPasswordHelp
showAlert.value = true
},
textStyle = TextStyle(fontSize = 18.sp),
label = { Text(stringResource(R.string.stun_password)) },
label = { Text(stunPasswordTitle) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
)
}
@ -749,18 +793,20 @@ private fun AccountContent(
@Composable
fun RtcpMux() {
val rtcpMuxTitle = stringResource(R.string.rtcp_mux)
val rtcpMuxHelp = stringResource(R.string.rtcp_mux_help)
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
val rtcpMux by viewModel.rtcpMux.collectAsState()
Text(text = stringResource(R.string.rtcp_mux),
Text(text = rtcpMuxTitle,
modifier = Modifier
.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.rtcp_mux)
alertMessage.value = ctx.getString(R.string.rtcp_mux_help)
alertTitle.value = rtcpMuxTitle
alertMessage.value = rtcpMuxHelp
showAlert.value = true
},
fontSize = 18.sp
@ -774,18 +820,21 @@ private fun AccountContent(
@Composable
fun Rel100() {
val rel100Title = stringResource(R.string.rel_100)
val rel100Help = stringResource(R.string.rel_100_help)
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
val rel100 by viewModel.rel100.collectAsState()
Text(text = stringResource(R.string.rel_100),
Text(
text = rel100Title,
modifier = Modifier
.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.rel_100)
alertMessage.value = ctx.getString(R.string.rel_100_help)
alertTitle.value = rel100Title
alertMessage.value = rel100Help
showAlert.value = true
},
fontSize = 18.sp
@ -799,21 +848,26 @@ private fun AccountContent(
@Composable
fun Dtmf() {
val dtmfModeTitle = stringResource(R.string.dtmf_mode)
val dtmfModeHelp = stringResource(R.string.dtmf_mode_help)
val dtmfInbandText = stringResource(R.string.dtmf_inband)
val dtmfInfoText = stringResource(R.string.dtmf_info)
val dtmfAutoText = stringResource(R.string.dtmf_auto)
val dtmfMode by viewModel.dtmfMode.collectAsState()
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
val dtmfModeMap = mapOf(Api.DTMFMODE_RTP_EVENT to ctx.getString(R.string.dtmf_inband),
Api.DTMFMODE_SIP_INFO to ctx.getString(R.string.dtmf_info),
Api.DTMFMODE_AUTO to ctx.getString(R.string.dtmf_auto))
Text(text = stringResource(R.string.dtmf_mode),
val dtmfModeMap = mapOf(Api.DTMFMODE_RTP_EVENT to dtmfInbandText,
Api.DTMFMODE_SIP_INFO to dtmfInfoText,
Api.DTMFMODE_AUTO to dtmfAutoText)
Text(text = dtmfModeTitle,
modifier = Modifier
.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.dtmf_mode)
alertMessage.value = ctx.getString(R.string.dtmf_mode_help)
alertTitle.value = dtmfModeTitle
alertMessage.value = dtmfModeHelp
showAlert.value = true
},
fontSize = 18.sp
@ -856,22 +910,27 @@ private fun AccountContent(
}
}
val manualText = stringResource(R.string.manual)
val autoText = stringResource(R.string.auto)
@Composable
fun Answer() {
val answerModeTitle = stringResource(R.string.answer_mode)
val answerModeHelp = stringResource(R.string.answer_mode_help)
val answerMode by viewModel.answerMode.collectAsState()
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
val answerModeMap = mapOf(Api.ANSWERMODE_MANUAL to ctx.getString(R.string.manual),
Api.ANSWERMODE_AUTO to ctx.getString(R.string.auto))
Text(text = stringResource(R.string.answer_mode),
val answerModeMap = mapOf(Api.ANSWERMODE_MANUAL to manualText,
Api.ANSWERMODE_AUTO to autoText)
Text(text = answerModeTitle,
modifier = Modifier
.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.answer_mode)
alertMessage.value = ctx.getString(R.string.answer_mode_help)
alertTitle.value = answerModeTitle
alertMessage.value = answerModeHelp
showAlert.value = true
},
fontSize = 18.sp
@ -912,20 +971,22 @@ private fun AccountContent(
@Composable
fun Redirect() {
val redirectModeTitle = stringResource(R.string.redirect_mode)
val redirectModeHelp = stringResource(R.string.redirect_mode_help)
val autoRedirect by viewModel.autoRedirect.collectAsState()
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
val redirectModeMap = mapOf(false to ctx.getString(R.string.manual),
true to ctx.getString(R.string.auto))
Text(text = stringResource(R.string.redirect_mode),
val redirectModeMap = mapOf(false to manualText,
true to autoText)
Text(text = redirectModeTitle,
modifier = Modifier
.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.redirect_mode)
alertMessage.value = ctx.getString(R.string.redirect_mode_help)
alertTitle.value = redirectModeTitle
alertMessage.value = redirectModeHelp
showAlert.value = true
},
fontSize = 18.sp
@ -968,18 +1029,20 @@ private fun AccountContent(
@Composable
fun BlockUnknown() {
val blockUnknownTitle = stringResource(R.string.block_unknown)
val blockUnknownHelp = stringResource(R.string.block_unknown_help)
val block by viewModel.blockUnknown.collectAsState()
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
Text(text = stringResource(R.string.block_unknown),
Text(text = blockUnknownTitle,
modifier = Modifier
.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.block_unknown)
alertMessage.value = ctx.getString(R.string.block_unknown_help)
alertTitle.value = blockUnknownTitle
alertMessage.value = blockUnknownHelp
showAlert.value = true
},
fontSize = 18.sp
@ -993,6 +1056,8 @@ private fun AccountContent(
@Composable
fun Voicemail() {
val voicemailUriTitle = stringResource(R.string.voicemail_uri)
val voicemailUriHelp = stringResource(R.string.voicemain_uri_help)
val vmUri by viewModel.vmUri.collectAsState()
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
@ -1001,18 +1066,18 @@ private fun AccountContent(
) {
OutlinedTextField(
value = vmUri,
placeholder = { Text(stringResource(R.string.voicemail_uri)) },
placeholder = { Text(voicemailUriTitle) },
onValueChange = { viewModel.vmUri.value = it },
modifier = Modifier
.fillMaxWidth()
.clickable {
alertTitle.value = ctx.getString(R.string.voicemail_uri)
alertMessage.value = ctx.getString(R.string.voicemain_uri_help)
alertTitle.value = voicemailUriTitle
alertMessage.value = voicemailUriHelp
showAlert.value = true
},
singleLine = true,
textStyle = TextStyle(fontSize = 18.sp),
label = { Text(stringResource(R.string.voicemail_uri)) },
label = { Text(voicemailUriTitle) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
)
}
@ -1020,6 +1085,8 @@ private fun AccountContent(
@Composable
fun CountryCode() {
val countryCodeTitle = stringResource(R.string.country_code)
val countryCodeHelp = stringResource(R.string.country_code_help)
val countryCode by viewModel.countryCode.collectAsState()
Row(
Modifier.fillMaxWidth().padding(top = 8.dp, end = 10.dp),
@ -1028,18 +1095,18 @@ private fun AccountContent(
) {
OutlinedTextField(
value = countryCode,
placeholder = { Text(stringResource(R.string.country_code)) },
placeholder = { Text(countryCodeTitle) },
onValueChange = { viewModel.countryCode.value = it },
modifier = Modifier
.fillMaxWidth()
.clickable {
alertTitle.value = ctx.getString(R.string.country_code)
alertMessage.value = ctx.getString(R.string.country_code_help)
alertTitle.value = countryCodeTitle
alertMessage.value = countryCodeHelp
showAlert.value = true
},
singleLine = true,
textStyle = TextStyle(fontSize = 18.sp),
label = { Text(stringResource(R.string.country_code)) },
label = { Text(countryCodeTitle) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
)
}
@ -1047,6 +1114,8 @@ private fun AccountContent(
@Composable
fun TelProvider() {
val telephonyProviderTitle = stringResource(R.string.telephony_provider)
val telephonyProviderHelp = stringResource(R.string.telephony_provider_help)
val telProvider by viewModel.telProvider.collectAsState()
Row(
Modifier.fillMaxWidth().padding(top = 8.dp, end = 10.dp),
@ -1055,18 +1124,18 @@ private fun AccountContent(
) {
OutlinedTextField(
value = telProvider,
placeholder = { Text(stringResource(R.string.telephony_provider)) },
placeholder = { Text(telephonyProviderTitle) },
onValueChange = { viewModel.telProvider.value = it },
modifier = Modifier
.fillMaxWidth()
.clickable {
alertTitle.value = ctx.getString(R.string.telephony_provider)
alertMessage.value = ctx.getString(R.string.telephony_provider_help)
alertTitle.value = telephonyProviderTitle
alertMessage.value = telephonyProviderHelp
showAlert.value = true
},
singleLine = true,
textStyle = TextStyle(fontSize = 18.sp),
label = { Text(stringResource(R.string.telephony_provider)) },
label = { Text(telephonyProviderTitle) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
)
}
@ -1074,18 +1143,20 @@ private fun AccountContent(
@Composable
fun NumericKeypad() {
val numericKeypadTitle = stringResource(R.string.numeric_keypad)
val numericKeypadHelp = stringResource(R.string.numeric_keypad_help)
val numericKeypad by viewModel.numericKeypad.collectAsState()
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
Text(text = stringResource(R.string.numeric_keypad),
Text(text = numericKeypadTitle,
modifier = Modifier
.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.numeric_keypad)
alertMessage.value = ctx.getString(R.string.numeric_keypad_help)
alertTitle.value = numericKeypadTitle
alertMessage.value = numericKeypadHelp
showAlert.value = true
},
fontSize = 18.sp
@ -1099,18 +1170,20 @@ private fun AccountContent(
@Composable
fun DefaultAccount() {
val defaultAccountTitle = stringResource(R.string.default_account)
val defaultAccountHelp = stringResource(R.string.default_account_help)
val defaultAccount by viewModel.defaultAccount.collectAsState()
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
Text(text = stringResource(R.string.default_account),
Text(text = defaultAccountTitle,
modifier = Modifier
.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.default_account)
alertMessage.value = ctx.getString(R.string.default_account_help)
alertTitle.value = defaultAccountTitle
alertMessage.value = defaultAccountHelp
showAlert.value = true
},
fontSize = 18.sp
@ -1153,7 +1226,10 @@ private fun AccountContent(
AskPassword(ctx, navController, ua)
Outbound()
Register()
RegInt()
if (viewModel.register.collectAsState().value) {
RegInt()
CheckOrigin()
}
AudioCodecs(navController, aor)
MediaEnc()
MediaNat()
@ -1177,7 +1253,9 @@ private fun AccountContent(
}
private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgent): Boolean {
val acc = ua.account
val noticeTitle = ctx.getString(R.string.notice)
val nn = viewModel.nickName.value.trim()
if (nn != acc.nickName) {
@ -1187,14 +1265,14 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen
Log.d(TAG, "New nickname is ${acc.nickName}")
}
else {
alertTitle.value = ctx.getString(R.string.notice)
alertTitle.value = noticeTitle
alertMessage.value = String.format(ctx.getString(R.string.non_unique_account_nickname), nn)
showAlert.value = true
return false
}
}
else {
alertTitle.value = ctx.getString(R.string.notice)
alertTitle.value = noticeTitle
alertMessage.value = String.format(ctx.getString(R.string.invalid_account_nickname), nn)
showAlert.value = true
return false
@ -1212,7 +1290,7 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen
}
}
else {
alertTitle.value = ctx.getString(R.string.notice)
alertTitle.value = noticeTitle
alertMessage.value = String.format(ctx.getString(R.string.invalid_display_name), dn)
showAlert.value = true
return false
@ -1233,7 +1311,7 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen
}
}
else {
alertTitle.value = ctx.getString(R.string.notice)
alertTitle.value = noticeTitle
alertMessage.value = String.format(ctx.getString(R.string.invalid_authentication_username), au)
showAlert.value = true
return false
@ -1254,7 +1332,7 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen
BaresipService.aorPasswords.remove(acc.aor)
}
else {
alertTitle.value = ctx.getString(R.string.notice)
alertTitle.value = noticeTitle
alertMessage.value = String.format(ctx.getString(R.string.invalid_authentication_password), ap)
showAlert.value = true
return false
@ -1280,7 +1358,7 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen
ob.add(ob1)
}
else {
alertTitle.value = ctx.getString(R.string.notice)
alertTitle.value = noticeTitle
alertMessage.value = String.format(ctx.getString(R.string.invalid_proxy_server_uri), ob1)
showAlert.value = true
return false
@ -1293,7 +1371,7 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen
if (checkOutboundUri(ob2))
ob.add(ob2)
else {
alertTitle.value = ctx.getString(R.string.notice)
alertTitle.value = noticeTitle
alertMessage.value = String.format(ctx.getString(R.string.invalid_proxy_server_uri), ob2)
showAlert.value = true
return false
@ -1324,7 +1402,7 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen
0
}
if (regInt !in 60..3600) {
alertTitle.value = ctx.getString(R.string.notice)
alertTitle.value = noticeTitle
alertMessage.value = String.format(ctx.getString(R.string.invalid_reg_int), "$regInt")
showAlert.value = true
return false
@ -1347,6 +1425,13 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen
acc.configuredRegInt = regInt
}
if (acc.regint == 0)
Api.account_set_check_origin(ua.account.accp, false)
else {
Api.account_set_check_origin(ua.account.accp, viewModel.checkOrigin.value)
acc.checkOrigin = Api.account_check_origin(ua.account.accp)
}
val newMediaEnc = viewModel.mediaEnc.value
if (newMediaEnc != acc.mediaEnc) {
if (Api.account_set_mediaenc(acc.accp, newMediaEnc) == 0) {
@ -1402,7 +1487,7 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen
Log.e(TAG, "Setting of STUN/TURN user $newStunUser failed")
}
else {
alertTitle.value = ctx.getString(R.string.notice)
alertTitle.value = noticeTitle
alertMessage.value = String.format(ctx.getString(R.string.invalid_stun_username),
newStunUser)
showAlert.value = true
@ -1419,7 +1504,7 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen
Log.e(TAG, "Setting of stun pass failed")
}
else {
alertTitle.value = ctx.getString(R.string.notice)
alertTitle.value = noticeTitle
alertMessage.value = String.format(ctx.getString(R.string.invalid_stun_password),
newStunPass)
showAlert.value = true
@ -1487,7 +1572,7 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen
if (!newVmUri.startsWith("sip:")) newVmUri = "sip:$newVmUri"
if (!newVmUri.contains("@")) newVmUri = "$newVmUri@${acc.host()}"
if (!Utils.checkUri(newVmUri)) {
alertTitle.value = ctx.getString(R.string.notice)
alertTitle.value = noticeTitle
alertMessage.value = String.format(ctx.getString(R.string.invalid_sip_or_tel_uri),
newVmUri)
showAlert.value = true
@ -1517,7 +1602,7 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen
val hostPart = viewModel.telProvider.value.trim()
if (hostPart != acc.telProvider) {
if (hostPart != "" && !Utils.checkHostPortParams(hostPart)) {
alertTitle.value = ctx.getString(R.string.notice)
alertTitle.value = noticeTitle
alertMessage.value = String.format(ctx.getString(R.string.invalid_sip_uri_hostpart), hostPart)
showAlert.value = true
return false
@ -1534,6 +1619,8 @@ private fun checkOnClick(ctx: Context, viewModel: AccountViewModel, ua: UserAgen
if (viewModel.defaultAccount.value) ua.makeDefault()
Api.account_debug(acc.accp)
Account.saveAccounts()
if (acc.authUser != "" && BaresipService.aorPasswords[acc.aor] == NO_AUTH_PASS) {
@ -1599,8 +1686,11 @@ private fun initAccountFromConfig(acc: Account, onConfigLoaded: () -> Unit) {
900
}
"register" ->
"register" -> {
acc.regint = if (text == "yes") acc.configuredRegInt else 0
if (acc.regint > 0)
acc.checkOrigin = true
}
"audio-codec" ->
if (text in audioCodecs)

View File

@ -13,6 +13,7 @@ class AccountViewModel: ViewModel() {
val outbound2 = MutableStateFlow("")
val register = MutableStateFlow(false)
val regInt = MutableStateFlow("")
val checkOrigin = MutableStateFlow(false)
val mediaEnc = MutableStateFlow("")
val mediaNat = MutableStateFlow("")
val stunServer = MutableStateFlow("")
@ -45,6 +46,7 @@ class AccountViewModel: ViewModel() {
outbound2.value = if (acc.outbound.size > 1) acc.outbound[1] else ""
register.value = acc.regint > 0
regInt.value = acc.configuredRegInt.toString()
checkOrigin.value = acc.checkOrigin
mediaEnc.value = acc.mediaEnc
mediaNat.value = acc.mediaNat
stunServer.value = acc.stunServer

View File

@ -114,8 +114,6 @@ fun AccountsScreen(navController: NavController) {
@Composable
fun AccountsContent(contentPadding: PaddingValues, navController: NavController) {
val ctx = LocalContext.current
val showDialog = remember { mutableStateOf(false) }
val message = remember { mutableStateOf("") }
val positiveAction = remember { mutableStateOf({}) }
@ -166,13 +164,11 @@ fun AccountsContent(contentPadding: PaddingValues, navController: NavController)
navController.navigate("account/$aor/old")
}
)
val deleteAccountMessage = stringResource(R.string.delete_account)
SmallFloatingActionButton(
modifier = Modifier.padding(end = 8.dp),
onClick = {
message.value = String.format(
ctx.getString(R.string.delete_account),
text
)
message.value = String.format(deleteAccountMessage, text)
positiveAction.value = {
CallHistoryNew.clear(aor)
Message.clearMessagesOfAor(aor)
@ -237,7 +233,7 @@ fun NewAccount(navController: NavController) {
}
val ua = UserAgent.uaAlloc(
"<$aor>;stunserver=\"stun:stun.l.google.com:19302\";regq=0.5;pubint=0;regint=0;mwi=no"
"<$aor>;stunserver=\"stun:stun.l.google.com:19302\";regq=0.5;pubint=0;regint=0;check_origin=no;mwi=no"
)
if (ua == null) {
alertTitle.value = ctx.getString(R.string.notice)
@ -246,8 +242,8 @@ fun NewAccount(navController: NavController) {
return null
}
// Api.account_debug(ua.account.accp)
val acc = ua.account
acc.checkOrigin = true
Log.d(TAG, "Allocated UA ${ua.uap} with SIP URI ${acc.luri}")
Account.saveAccounts()
return acc
@ -263,6 +259,8 @@ fun NewAccount(navController: NavController) {
verticalAlignment = Alignment.CenterVertically
) {
val ctx = LocalContext.current
val newAccountTitle = stringResource(R.string.new_account)
val accountsHelp = stringResource(R.string.accounts_help)
OutlinedTextField(
value = newAor,
placeholder = { Text(text = stringResource(R.string.new_account)) },
@ -272,8 +270,8 @@ fun NewAccount(navController: NavController) {
.padding(end = 8.dp)
.verticalScroll(rememberScrollState())
.clickable {
alertTitle.value = ctx.getString(R.string.new_account)
alertMessage.value = ctx.getString(R.string.accounts_help)
alertTitle.value = newAccountTitle
alertMessage.value = accountsHelp
showAlert.value = true
},
singleLine = false,

View File

@ -34,6 +34,8 @@ object Api {
external fun account_audio_codec(acc: Long, ix: Int): String
external fun account_regint(acc: Long): Int
external fun account_set_regint(acc: Long, regint: Int): Int
external fun account_check_origin(acc: Long): Boolean
external fun account_set_check_origin(acc: Long, check: Boolean)
external fun account_stun_uri(acc: Long): String
external fun account_set_stun_uri(acc: Long, uri: String): Int
external fun account_stun_user(acc: Long): String

View File

@ -237,12 +237,19 @@ private fun SettingsContent(
onRestartApp: () -> Unit
) {
val alertTitleText = stringResource(R.string.alert)
val errorTitleText = stringResource(R.string.error)
val noticeTitleText = stringResource(R.string.notice)
val confirmationText = stringResource(R.string.confirmation)
val okButtonText = stringResource(R.string.ok)
val cancelButtonText = stringResource(R.string.cancel)
if (showAlert.value) {
AlertDialog(
showDialog = showAlert,
title = alertTitle.value,
message = alertMessage.value,
positiveButtonText = stringResource(R.string.ok),
positiveButtonText = okButtonText,
)
}
@ -259,18 +266,21 @@ private fun SettingsContent(
@Composable
fun StartAutomatically() {
val startAutomaticallyTitle = stringResource(R.string.start_automatically)
val startAutomaticallyHelp = stringResource(R.string.start_automatically_help)
val appearOnTopPermissionMessage = stringResource(R.string.appear_on_top_permission)
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
val ctx = LocalContext.current
Text(text = stringResource(R.string.start_automatically),
Text(text = startAutomaticallyTitle,
modifier = Modifier
.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.start_automatically)
alertMessage.value = ctx.getString(R.string.start_automatically_help)
alertTitle.value = startAutomaticallyTitle
alertMessage.value = startAutomaticallyHelp
showAlert.value = true
},
fontSize = 18.sp
@ -281,14 +291,14 @@ private fun SettingsContent(
onCheckedChange = {
if (it) {
if (!isAppearOnTopPermissionGranted(ctx)) {
dialogTitle.value = ctx.getString(R.string.notice)
dialogMessage.value = ctx.getString(R.string.appear_on_top_permission)
positiveText.value = ctx.getString(R.string.ok)
dialogTitle.value = noticeTitleText
dialogMessage.value = appearOnTopPermissionMessage
positiveText.value = okButtonText
onPositiveClicked.value = {
val intent = Intent(Settings.ACTION_MANAGE_OVERLAY_PERMISSION)
ctx.startActivity(intent)
}
negativeText.value = ctx.getString(R.string.cancel)
negativeText.value = cancelButtonText
onNegativeClicked.value = {
negativeText.value = ""
}
@ -306,50 +316,21 @@ private fun SettingsContent(
}
@Composable
fun ListenAddress() {
fun AddressFamily() {
val addressFamilyTitle = stringResource(R.string.address_family)
val addressFamilyHelp = stringResource(R.string.address_family_help)
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start,
) {
val ctx = LocalContext.current
val listenAddress by viewModel.listenAddress.collectAsState()
OutlinedTextField(
value = listenAddress,
placeholder = { Text(stringResource(R.string._0_0_0_0_5060)) },
onValueChange = {
viewModel.listenAddress.value = it
},
modifier = Modifier
.fillMaxWidth()
.clickable {
alertTitle.value = ctx.getString(R.string.listen_address)
alertMessage.value = ctx.getString(R.string.listen_address_help)
showAlert.value = true
},
singleLine = true,
textStyle = androidx.compose.ui.text.TextStyle(fontSize = 18.sp),
label = { Text(stringResource(R.string.listen_address)) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
)
}
}
@Composable
fun AddressFamily() {
Row(
Modifier.fillMaxWidth().padding(top = 12.dp).padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
val ctx = LocalContext.current
val addressFamily by viewModel.addressFamily.collectAsState()
Text(text = stringResource(R.string.address_family),
Text(text = addressFamilyTitle,
modifier = Modifier
.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.address_family)
alertMessage.value = ctx.getString(R.string.address_family_help)
alertTitle.value = addressFamilyTitle
alertMessage.value = addressFamilyHelp
showAlert.value = true
},
fontSize = 18.sp
@ -397,14 +378,46 @@ private fun SettingsContent(
}
}
@Composable
fun ListenAddress() {
val listenAddressTitle = stringResource(R.string.listen_address)
val listenAddressHelp = stringResource(R.string.listen_address_help)
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start,
) {
val listenAddress by viewModel.listenAddress.collectAsState()
OutlinedTextField(
value = listenAddress,
placeholder = { Text(stringResource(R.string._0_0_0_0_5060)) },
onValueChange = {
viewModel.listenAddress.value = it
},
modifier = Modifier
.fillMaxWidth()
.clickable {
alertTitle.value = listenAddressTitle
alertMessage.value = listenAddressHelp
showAlert.value = true
},
singleLine = true,
textStyle = androidx.compose.ui.text.TextStyle(fontSize = 18.sp),
label = { Text(listenAddressTitle) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
)
}
}
@Composable
fun TransportProtocols() {
val transportProtocolsTitle = stringResource(R.string.transport_protocols)
val transportProtocolsHelp = stringResource(R.string.transport_protocols_help)
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
val ctx = LocalContext.current
val transportProtocols by viewModel.transportProtocols.collectAsState()
OutlinedTextField(
value = transportProtocols,
@ -414,12 +427,12 @@ private fun SettingsContent(
modifier = Modifier
.fillMaxWidth()
.clickable {
alertTitle.value = ctx.getString(R.string.transport_protocols)
alertMessage.value = ctx.getString(R.string.transport_protocols_help)
alertTitle.value = transportProtocolsTitle
alertMessage.value = transportProtocolsHelp
showAlert.value = true
},
textStyle = androidx.compose.ui.text.TextStyle(fontSize = 18.sp),
label = { Text(stringResource(R.string.transport_protocols)) },
label = { Text(transportProtocolsTitle) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
)
}
@ -427,12 +440,13 @@ private fun SettingsContent(
@Composable
fun DnsServers() {
val dnsServersTitle = stringResource(R.string.dns_servers)
val dnsServersHelp = stringResource(R.string.dns_servers_help)
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
val ctx = LocalContext.current
val dnsServers by viewModel.dnsServers.collectAsState()
OutlinedTextField(
value = dnsServers,
@ -442,12 +456,12 @@ private fun SettingsContent(
modifier = Modifier
.fillMaxWidth()
.clickable {
alertTitle.value = ctx.getString(R.string.dns_servers)
alertMessage.value = ctx.getString(R.string.dns_servers_help)
alertTitle.value = dnsServersTitle
alertMessage.value = dnsServersHelp
showAlert.value = true
},
textStyle = androidx.compose.ui.text.TextStyle(fontSize = 18.sp),
label = { Text(stringResource(R.string.dns_servers)) },
label = { Text(dnsServersTitle) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
)
}
@ -458,6 +472,10 @@ private fun SettingsContent(
val ctx = LocalContext.current
val readCertError = stringResource(R.string.read_cert_error)
val tlsCertificateFileTitle = stringResource(R.string.tls_certificate_file)
val tlsCertificateFileHelp = stringResource(R.string.tls_certificate_file_help)
val requestPermissionLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.RequestPermission()
) {}
@ -478,8 +496,8 @@ private fun SettingsContent(
save = true
restart = true
} catch (e: Error) {
alertTitle.value = ctx.getString(R.string.error)
alertMessage.value = ctx.getString(R.string.read_cert_error) + ": " + e.message
alertTitle.value = errorTitleText
alertMessage.value = readCertError + ": " + e.message
showAlert.value = true
viewModel.tlsCertificateFile.value = false
}
@ -499,12 +517,12 @@ private fun SettingsContent(
horizontalArrangement = Arrangement.Start
) {
val ctx = LocalContext.current
Text(text = stringResource(R.string.tls_certificate_file),
Text(text = tlsCertificateFileTitle,
modifier = Modifier
.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.tls_certificate_file)
alertMessage.value = ctx.getString(R.string.tls_certificate_file_help)
alertTitle.value = tlsCertificateFileTitle
alertMessage.value = tlsCertificateFileHelp
showAlert.value = true
},
fontSize = 18.sp
@ -525,8 +543,8 @@ private fun SettingsContent(
val downloadsPath = Utils.downloadsPath("cert.pem")
val content = Utils.getFileContents(downloadsPath)
if (content == null) {
alertTitle.value = ctx.getString(R.string.error)
alertMessage.value = ctx.getString(R.string.read_cert_error)
alertTitle.value = errorTitleText
alertMessage.value = readCertError
showAlert.value = true
return@Switch
}
@ -569,17 +587,18 @@ private fun SettingsContent(
@Composable
fun VerifyServer() {
val verifyServerTitle = stringResource(R.string.verify_server)
val verifyServerHelp = stringResource(R.string.verify_server_help)
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
val ctx = LocalContext.current
Text(text = stringResource(R.string.verify_server),
Text(text = verifyServerTitle,
modifier = Modifier.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.verify_server)
alertMessage.value = ctx.getString(R.string.verify_server_help)
alertTitle.value = verifyServerTitle
alertMessage.value = verifyServerHelp
showAlert.value = true
},
fontSize = 18.sp
@ -597,6 +616,11 @@ private fun SettingsContent(
val ctx = LocalContext.current
val tlsCaFileTitle = stringResource(R.string.tls_ca_file)
val tlsCaFileHelp = stringResource(R.string.tls_ca_file_help)
val readCaCertsError = stringResource(R.string.read_ca_certs_error)
val noReadPermissionMessage = stringResource(R.string.no_read_permission)
val requestPermissionLauncher = rememberLauncherForActivityResult(
contract = ActivityResultContracts.RequestPermission()
) {}
@ -613,8 +637,8 @@ private fun SettingsContent(
inputStream.close()
restart = true
} catch (e: Error) {
alertTitle.value = ctx.getString(R.string.error)
alertMessage.value = ctx.getString(R.string.read_ca_certs_error) + ": " + e.message
alertTitle.value = errorTitleText
alertMessage.value = readCaCertsError + ": " + e.message
showAlert.value = true
viewModel.caFile.value = false
}
@ -630,11 +654,11 @@ private fun SettingsContent(
horizontalArrangement = Arrangement.Start
) {
val ctx = LocalContext.current
Text(text = stringResource(R.string.tls_ca_file),
Text(text = tlsCaFileTitle,
modifier = Modifier.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.tls_ca_file)
alertMessage.value = ctx.getString(R.string.tls_ca_file_help)
alertTitle.value = tlsCaFileTitle
alertMessage.value = tlsCaFileHelp
showAlert.value = true
},
fontSize = 18.sp
@ -654,8 +678,8 @@ private fun SettingsContent(
val downloadsPath = Utils.downloadsPath("ca_certs.crt")
val content = Utils.getFileContents(downloadsPath)
if (content == null) {
alertTitle.value = ctx.getString(R.string.error)
alertMessage.value = ctx.getString(R.string.read_ca_certs_error)
alertTitle.value = errorTitleText
alertMessage.value = readCaCertsError
showAlert.value = true
return@Switch
}
@ -664,9 +688,9 @@ private fun SettingsContent(
restart = true
}
shouldShowRequestPermissionRationale(activity, permission) -> {
dialogTitle.value = ctx.getString(R.string.notice)
dialogMessage.value = ctx.getString(R.string.no_read_permission)
positiveText.value = ctx.getString(R.string.ok)
dialogTitle.value = noticeTitleText
dialogMessage.value = noReadPermissionMessage
positiveText.value = okButtonText
onPositiveClicked.value = {
requestPermissionLauncher.launch(permission)
}
@ -691,26 +715,27 @@ private fun SettingsContent(
@Composable
fun UserAgent() {
val userAgentTitle = stringResource(R.string.user_agent)
val userAgentHelp = stringResource(R.string.user_agent_help)
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
val ctx = LocalContext.current
val userAgent by viewModel.userAgent.collectAsState()
OutlinedTextField(
value = userAgent,
placeholder = { Text(stringResource(R.string.user_agent)) },
placeholder = { Text(userAgentTitle) },
onValueChange = { viewModel.userAgent.value = it },
modifier = Modifier
.fillMaxWidth()
.clickable {
alertTitle.value = ctx.getString(R.string.user_agent)
alertMessage.value = ctx.getString(R.string.user_agent_help)
alertTitle.value = userAgentTitle
alertMessage.value = userAgentHelp
showAlert.value = true
},
textStyle = androidx.compose.ui.text.TextStyle(fontSize = 18.sp),
label = { Text(stringResource(R.string.user_agent)) },
label = { Text(userAgentTitle) },
keyboardOptions = KeyboardOptions(keyboardType = KeyboardType.Text)
)
}
@ -735,6 +760,14 @@ private fun SettingsContent(
@Composable
fun Contacts(activity: Activity) {
val contactsTitle = stringResource(R.string.contacts)
val contactsHelp = stringResource(R.string.contacts_help)
val consentRequestTitle = stringResource(R.string.consent_request)
val contactsConsentMessage = stringResource(R.string.contacts_consent)
val positiveButtonText = stringResource(R.string.accept)
val negativeButtonText = stringResource(R.string.deny)
val both = stringResource(R.string.both)
val noAndroidContactsMessage = stringResource(R.string.no_android_contacts)
val showAlertDialog = remember { mutableStateOf(false) }
Row(
Modifier.fillMaxWidth().padding(top = 12.dp).padding(end = 10.dp),
@ -742,12 +775,12 @@ private fun SettingsContent(
horizontalArrangement = Arrangement.Start
) {
val ctx = LocalContext.current
Text(text = stringResource(R.string.contacts),
Text(text = contactsTitle,
modifier = Modifier
.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.contacts)
alertMessage.value = ctx.getString(R.string.contacts_help)
alertTitle.value = contactsTitle
alertMessage.value = contactsHelp
showAlert.value = true
},
fontSize = 18.sp
@ -758,7 +791,7 @@ private fun SettingsContent(
val contactNames = listOf(
"baresip",
"Android",
ctx.getString(R.string.both)
both
)
val contactsMode by viewModel.contactsMode.collectAsState()
val contactValues = listOf("baresip", "android", "both")
@ -797,9 +830,9 @@ private fun SettingsContent(
isDropDownExpanded.value = false
val mode = contactValues[index]
if (mode != "baresip" && !Utils.checkPermissions(ctx, contactsPermissions)) {
dialogTitle.value = ctx.getString(R.string.consent_request)
dialogMessage.value = ctx.getString(R.string.contacts_consent)
positiveText.value = ctx.getString(R.string.accept)
dialogTitle.value = consentRequestTitle
dialogMessage.value = contactsConsentMessage
positiveText.value = positiveButtonText
onPositiveClicked.value = {
showDialog.value = false
viewModel.contactsMode.value = mode
@ -831,7 +864,7 @@ private fun SettingsContent(
)
}
}
negativeText.value = ctx.getString(R.string.deny)
negativeText.value = negativeButtonText
onNegativeClicked.value = {
itemPosition.intValue = contactValues.indexOf(contactsMode)
negativeText.value = ""
@ -851,9 +884,9 @@ private fun SettingsContent(
if (showAlertDialog.value)
AlertDialog(
showDialog = showAlertDialog,
title = stringResource(R.string.notice),
message = stringResource(R.string.no_android_contacts),
positiveButtonText = stringResource(R.string.ok),
title = noticeTitleText,
message = noAndroidContactsMessage,
positiveButtonText = okButtonText,
onPositiveClicked = { requestPermissionsLauncher.launch(
arrayOf(
Manifest.permission.READ_CONTACTS,
@ -867,7 +900,9 @@ private fun SettingsContent(
}
@Composable
fun Ringtone(ctx: Context) {
fun Ringtone() {
val ringToneTitle = stringResource(R.string.ringtone)
val selectRingToneMessage = stringResource(R.string.select_ringtone)
val launcher = rememberLauncherForActivityResult(
ActivityResultContracts.StartActivityForResult()
) { result: ActivityResult ->
@ -887,7 +922,7 @@ private fun SettingsContent(
horizontalArrangement = Arrangement.Start
) {
Text(
text = stringResource(R.string.ringtone),
text = ringToneTitle,
modifier = Modifier
.weight(1f)
.clickable {
@ -898,7 +933,7 @@ private fun SettingsContent(
)
intent.putExtra(
RingtoneManager.EXTRA_RINGTONE_TITLE,
ctx.getString(R.string.select_ringtone)
selectRingToneMessage
)
intent.putExtra(
RingtoneManager.EXTRA_RINGTONE_EXISTING_URI,
@ -916,6 +951,8 @@ private fun SettingsContent(
@Composable
fun BatteryOptimizations() {
val batteryOptimizationsTitle = stringResource(R.string.battery_optimizations)
val batteryOptimizationsHelp = stringResource(R.string.battery_optimizations_help)
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
@ -929,12 +966,12 @@ private fun SettingsContent(
viewModel.batteryOptimizations.value =
!powerManager.isIgnoringBatteryOptimizations(ctx.packageName)
}
Text(text = stringResource(R.string.battery_optimizations),
Text(text = batteryOptimizationsTitle,
modifier = Modifier
.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.battery_optimizations)
alertMessage.value = ctx.getString(R.string.battery_optimizations_help)
alertTitle.value = batteryOptimizationsTitle
alertMessage.value = batteryOptimizationsHelp
showAlert.value = true
},
fontSize = 18.sp
@ -953,18 +990,19 @@ private fun SettingsContent(
@Composable
fun DarkTheme() {
val darkThemeTitle = stringResource(R.string.dark_theme)
val darkThemeHelp = stringResource(R.string.dark_theme_help)
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
val ctx = LocalContext.current
Text(text = stringResource(R.string.dark_theme),
Text(text = darkThemeTitle,
modifier = Modifier
.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.dark_theme)
alertMessage.value = ctx.getString(R.string.dark_theme_help)
alertTitle.value = darkThemeTitle
alertMessage.value = darkThemeHelp
showAlert.value = true
},
fontSize = 18.sp
@ -979,17 +1017,18 @@ private fun SettingsContent(
@Composable
fun DynamicColors() {
val dynamicColorsTitle = stringResource(R.string.dynamic_colors)
val dynamicColorsHelp = stringResource(R.string.dynamic_colors_help)
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
val ctx = LocalContext.current
Text(text = stringResource(R.string.dynamic_colors),
Text(text = dynamicColorsTitle,
modifier = Modifier.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.dynamic_colors)
alertMessage.value = ctx.getString(R.string.dynamic_colors_help)
alertTitle.value = dynamicColorsTitle
alertMessage.value = dynamicColorsHelp
showAlert.value = true
},
fontSize = 18.sp
@ -1004,18 +1043,19 @@ private fun SettingsContent(
@Composable
fun ColorBlind() {
val colorBlindTitle = stringResource(R.string.colorblind)
val colorBlindHelp = stringResource(R.string.colorblind_help)
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
val ctx = LocalContext.current
Text(text = stringResource(R.string.colorblind),
Text(text = colorBlindTitle,
modifier = Modifier
.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.colorblind)
alertMessage.value = ctx.getString(R.string.colorblind_help)
alertTitle.value = colorBlindTitle
alertMessage.value = colorBlindHelp
showAlert.value = true
},
fontSize = 18.sp
@ -1029,18 +1069,19 @@ private fun SettingsContent(
}
@Composable
fun ProximitySensing() {
val proximitySensingTitle = stringResource(R.string.proximity_sensing)
val proximitySensingHelp = stringResource(R.string.proximity_sensing_help)
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
val ctx = LocalContext.current
Text(text = stringResource(R.string.proximity_sensing),
Text(text = proximitySensingTitle,
modifier = Modifier
.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.proximity_sensing)
alertMessage.value = ctx.getString(R.string.proximity_sensing_help)
alertTitle.value = proximitySensingTitle
alertMessage.value = proximitySensingHelp
showAlert.value = true
},
fontSize = 18.sp
@ -1056,18 +1097,21 @@ private fun SettingsContent(
@RequiresApi(29)
@Composable
fun DefaultDialer() {
val defaultPhoneAppTitle = stringResource(R.string.default_phone_app)
val defaultPhoneAppHelp = stringResource(R.string.default_phone_app_help)
val dialerRoleNotAvailableMessage = stringResource(R.string.dialer_role_not_available)
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
val ctx = LocalContext.current
Text(text = stringResource(R.string.default_phone_app),
Text(text = defaultPhoneAppTitle,
modifier = Modifier
.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.default_phone_app)
alertMessage.value = ctx.getString(R.string.default_phone_app_help)
alertTitle.value = defaultPhoneAppTitle
alertMessage.value = defaultPhoneAppHelp
showAlert.value = true
},
fontSize = 18.sp
@ -1086,8 +1130,8 @@ private fun SettingsContent(
viewModel.defaultDialer.value = it
if (it) {
if (!roleManager.isRoleAvailable(RoleManager.ROLE_DIALER)) {
alertTitle.value = ctx.getString(R.string.alert)
alertMessage.value = ctx.getString(R.string.dialer_role_not_available)
alertTitle.value = alertTitleText
alertMessage.value = dialerRoleNotAvailableMessage
showAlert.value = true
}
else
@ -1107,17 +1151,18 @@ private fun SettingsContent(
@Composable
fun Debug() {
val debugTitle = stringResource(R.string.debug)
val debugHelp = stringResource(R.string.debug_help)
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
val ctx = LocalContext.current
Text(text = stringResource(R.string.debug),
Text(text = debugTitle,
modifier = Modifier.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.debug)
alertMessage.value = ctx.getString(R.string.debug_help)
alertTitle.value = debugTitle
alertMessage.value = debugHelp
showAlert.value = true
},
fontSize = 18.sp
@ -1132,18 +1177,19 @@ private fun SettingsContent(
@Composable
fun SipTrace() {
val sipTraceTitle = stringResource(R.string.sip_trace)
val sipTraceHelp = stringResource(R.string.sip_trace_help)
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
val ctx = LocalContext.current
Text(text = stringResource(R.string.sip_trace),
Text(text = sipTraceTitle,
modifier = Modifier
.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.sip_trace)
alertMessage.value = ctx.getString(R.string.sip_trace_help)
alertTitle.value = sipTraceTitle
alertMessage.value = sipTraceHelp
showAlert.value = true
},
fontSize = 18.sp
@ -1158,18 +1204,21 @@ private fun SettingsContent(
@Composable
fun Reset(onRestartApp: () -> Unit) {
val resetConfigTitle = stringResource(R.string.reset_config)
val resetConfigHelp = stringResource(R.string.reset_config_help)
val resetConfigAlert = stringResource(R.string.reset_config_alert)
val resetButtonText = stringResource(R.string.reset)
Row(
Modifier.fillMaxWidth().padding(end = 10.dp),
verticalAlignment = Alignment.CenterVertically,
horizontalArrangement = Arrangement.Start
) {
val ctx = LocalContext.current
Text(text = stringResource(R.string.reset_config),
Text(text = resetConfigTitle,
modifier = Modifier
.weight(1f)
.clickable {
alertTitle.value = ctx.getString(R.string.reset_config)
alertMessage.value = ctx.getString(R.string.reset_config_help)
alertTitle.value = resetConfigTitle
alertMessage.value = resetConfigHelp
showAlert.value = true
},
fontSize = 18.sp
@ -1178,14 +1227,14 @@ private fun SettingsContent(
Switch(
checked = reset,
onCheckedChange = {
dialogTitle.value = ctx.getString(R.string.confirmation)
dialogMessage.value = ctx.getString(R.string.reset_config_alert)
positiveText.value = ctx.getString(R.string.reset)
dialogTitle.value = confirmationText
dialogMessage.value = resetConfigAlert
positiveText.value = resetButtonText
onPositiveClicked.value = {
Config.reset()
onRestartApp()
}
negativeText.value = ctx.getString(R.string.cancel)
negativeText.value = cancelButtonText
onNegativeClicked.value = {
reset = false
negativeText.value = ""
@ -1196,8 +1245,6 @@ private fun SettingsContent(
}
}
val ctx = LocalContext.current
if (Config.variable("auto_start") == "yes" &&
!isAppearOnTopPermissionGranted(LocalContext.current)) {
Config.replaceVariable("auto_start", "no")
@ -1219,8 +1266,8 @@ private fun SettingsContent(
verticalArrangement = Arrangement.spacedBy(8.dp),
) {
item { StartAutomatically() }
item { ListenAddress() }
item { AddressFamily() }
item { ListenAddress() }
item { TransportProtocols() }
item { DnsServers() }
item { TlsCertificateFile(activity) }
@ -1229,7 +1276,7 @@ private fun SettingsContent(
item { UserAgent() }
item { AudioSettings(navController) }
item { Contacts(activity) }
item { Ringtone(ctx) }
item { Ringtone() }
item { BatteryOptimizations() }
item { DarkTheme() }
if (VERSION.SDK_INT >= 31) {
@ -1248,6 +1295,8 @@ private fun SettingsContent(
private fun checkOnClick(ctx: Context, viewModel: SettingsViewModel): Boolean {
val noticeTitle = ctx.getString(R.string.notice)
if ((Config.variable("auto_start") == "yes") != viewModel.autoStart.value) {
Config.replaceVariable(
"auto_start",
@ -1259,7 +1308,7 @@ private fun checkOnClick(ctx: Context, viewModel: SettingsViewModel): Boolean {
val listenAddr = viewModel.listenAddress.value.trim()
if (listenAddr != Config.variable("sip_listen")) {
if ((listenAddr != "") && !Utils.checkIpPort(listenAddr)) {
alertTitle.value = ctx.getString(R.string.notice)
alertTitle.value = noticeTitle
alertMessage.value = "${ctx.getString(R.string.invalid_listen_address)}: $listenAddr"
showAlert.value = true
return false
@ -1279,7 +1328,7 @@ private fun checkOnClick(ctx: Context, viewModel: SettingsViewModel): Boolean {
.lowercase(Locale.ROOT).replace(" ", "")
if (transportProtocols != viewModel.oldTransportProtocols) {
if (!checkTransportProtocols(transportProtocols)) {
alertTitle.value = ctx.getString(R.string.notice)
alertTitle.value = noticeTitle
alertMessage.value = "${ctx.getString(R.string.invalid_transport_protocols)}: " +
transportProtocols
showAlert.value = true
@ -1296,7 +1345,7 @@ private fun checkOnClick(ctx: Context, viewModel: SettingsViewModel): Boolean {
.lowercase(Locale.ROOT).replace(" ", ""))
if (dnsServers != viewModel.oldDnsServers) {
if (!checkDnsServers(dnsServers)) {
alertTitle.value = ctx.getString(R.string.notice)
alertTitle.value = noticeTitle
alertMessage.value = "${ctx.getString(R.string.invalid_dns_servers)}: $dnsServers"
showAlert.value = true
return false
@ -1307,7 +1356,7 @@ private fun checkOnClick(ctx: Context, viewModel: SettingsViewModel): Boolean {
Config.addVariable("dns_server", server)
Config.replaceVariable("dyn_dns", "no")
if (Api.net_use_nameserver(dnsServers) != 0) {
alertTitle.value = ctx.getString(R.string.notice)
alertTitle.value = noticeTitle
alertMessage.value = "${ctx.getString(R.string.failed_to_set_dns_servers)}: $dnsServers"
showAlert.value = true
return false
@ -1330,7 +1379,7 @@ private fun checkOnClick(ctx: Context, viewModel: SettingsViewModel): Boolean {
val userAgent = viewModel.userAgent.value.trim()
if (userAgent != Config.variable("user_agent")) {
if (userAgent != "" && !Utils.checkServerVal(userAgent)) {
alertTitle.value = ctx.getString(R.string.notice)
alertTitle.value = noticeTitle
alertMessage.value = "${ctx.getString(R.string.invalid_user_agent)}: " +
userAgent
showAlert.value = true

View File

@ -159,6 +159,10 @@
<string name="reg_int_help">Kertoo kuinka usein baresip lähettää REGISTER-sanomia. Arvon on
oltava välillä 60-3600 (sekunttia).</string>
<string name="invalid_reg_int">Virheellinen Rekisteröintitaajuus \'%1$s\'</string>
<string name="check_origin">Tarkista lähdeosoite</string>
<string name="check_origin_help">Merkitty, sisään tulevat SIP-sanomat sallitaan vain niistä
lähdeosoitteista, joihin REGISTER-sanomat lähetettiin.
</string>
<string name="media_nat">Media NAT hallinta</string>
<string name="media_nat_help">Valitsee media NAT hallintaprotokollan
(vapaaehtoinen). Vaihtoehtoja ovat STUN (Session Traversal Utilities
@ -339,9 +343,10 @@
valittu, baresip käyttää sekä IPv4- että IPv6-osoitteita.
</string>
<string name="transport_protocols">Kuljetusprotokollat</string>
<string name="transport_protocols_help">Pilkulla toisistaan erotettu lista tuettuja SIP sanomien
<string name="transport_protocols_help">Pilkulla toisistaan erotettu lista tuettuja SIP-sanomien
kuljetusprotokollia. Jos jätetään tyhjäksi, oletusarvo on \'udp,tcp,tls,ws,wss\', joka
kaikki tuetut siirtoprotokollat.
sisältää kaikki tuetut kuljetusprotokollat. Listaa vain ne joita tarvitset. UDP-protokollan
käyttöä ei suositella turvallisuus- ja muista syistä.
</string>
<string name="invalid_transport_protocols">Virheellinen kuljetusprotokollalista</string>s
<string name="dns_servers">DNS-palvelimet</string>

View File

@ -155,6 +155,10 @@
<string name="reg_int_help">Tells how often (in seconds) baresip sends REGISTER requests.
Valid values are from 60 to 3600.</string>
<string name="invalid_reg_int">Invalid Registration Interval \'%1$s\'</string>
<string name="check_origin">Check Origin</string>
<string name="check_origin_help">If checked, inbound requests are allowed only from IP addresses
where register requests were sent.
</string>
<string name="media_nat">Media NAT Traversal</string>
<string name="media_nat_help">Selects media NAT traversal protocol (if any). Possible choices are STUN
(Session Traversal Utilities for NAT, RFC 5389) and ICE (Interactive Connectivity
@ -327,7 +331,8 @@
<string name="transport_protocols">Transport Protocols</string>
<string name="transport_protocols_help">Comma separated list of supported SIP request/response
transport protocols. If left empty, default value is \'udp,tcp,tls,ws,wss\' that includes
all supported transport protocols.
all supported transport protocols. List only the ones you need. Use of UDP is not
recommended for security and other reasons.
</string>
<string name="invalid_transport_protocols">Invalid Transport Protocols list</string>
<string name="dns_servers">DNS Servers</string>