diff --git a/app/src/main/cpp/baresip.c b/app/src/main/cpp/baresip.c
index 88b763c5..a2304100 100644
--- a/app/src/main/cpp/baresip.c
+++ b/app/src/main/cpp/baresip.c
@@ -948,6 +948,19 @@ Java_com_tutpro_baresip_Api_account_1set_1answermode(JNIEnv *env, jobject thiz,
return account_set_answermode((struct account *)acc, mode);
}
+JNIEXPORT jboolean JNICALL
+Java_com_tutpro_baresip_Api_account_1rtcp_1mux(JNIEnv *env, jobject thiz, jlong acc)
+{
+ return account_rtcp_mux((struct account *)acc);
+}
+
+JNIEXPORT jint JNICALL
+Java_com_tutpro_baresip_Api_account_1set_1rtcp_1mux(JNIEnv *env, jobject thiz, jlong acc,
+ jboolean value)
+{
+ return account_set_rtcp_mux((struct account *)acc, value);
+}
+
JNIEXPORT jint JNICALL
Java_com_tutpro_baresip_Api_account_1dtmfmode(JNIEnv *env, jobject thiz, jlong acc)
{
diff --git a/app/src/main/kotlin/com/tutpro/baresip/Account.kt b/app/src/main/kotlin/com/tutpro/baresip/Account.kt
index 9b26534e..6034863e 100644
--- a/app/src/main/kotlin/com/tutpro/baresip/Account.kt
+++ b/app/src/main/kotlin/com/tutpro/baresip/Account.kt
@@ -23,6 +23,7 @@ class Account(val accp: Long) {
var videoCodec = ArrayList()
var regint = Api.account_regint(accp)
var mediaEnc = Api.account_mediaenc(accp)
+ var rtcpMux = Api.account_rtcp_mux(accp)
var dtmfMode = Api.account_dtmfmode(accp)
var answerMode = Api.account_answermode(accp)
var vmUri = Api.account_vm_uri(accp)
@@ -117,6 +118,9 @@ class Account(val accp: Long) {
if (mediaEnc != "") res += ";mediaenc=${mediaEnc}"
+ if (rtcpMux)
+ res += ";rtcp_mux=yes"
+
res = if (vmUri == "")
"$res;mwi=no"
else
diff --git a/app/src/main/kotlin/com/tutpro/baresip/AccountActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/AccountActivity.kt
index 0da71749..1af1d076 100644
--- a/app/src/main/kotlin/com/tutpro/baresip/AccountActivity.kt
+++ b/app/src/main/kotlin/com/tutpro/baresip/AccountActivity.kt
@@ -43,6 +43,7 @@ class AccountActivity : AppCompatActivity() {
private lateinit var mediaNatSpinner: Spinner
private lateinit var mediaEnc: String
private lateinit var mediaEncSpinner: Spinner
+ private lateinit var rtcpCheck: CheckBox
private var dtmfMode = Api.DTMFMODE_RTP_EVENT
private lateinit var dtmfModeSpinner: Spinner
private var answerMode = Api.ANSWERMODE_MANUAL
@@ -89,6 +90,7 @@ class AccountActivity : AppCompatActivity() {
stunUser = binding.StunUser
stunPass = binding.StunPass
mediaEncSpinner = binding.mediaEncSpinner
+ rtcpCheck = binding.RtcpMux
dtmfModeSpinner = binding.dtmfModeSpinner
answerModeSpinner = binding.answerModeSpinner
vmUri = binding.voicemailUri
@@ -179,6 +181,8 @@ class AccountActivity : AppCompatActivity() {
"stun-turn-server" ->
if (text.isNotEmpty())
acc.stunServer = text
+ "rtcp-mux" ->
+ acc.rtcpMux = text == "yes"
"dtmf-mode" ->
if (text in arrayOf("rtp-event", "sip-info")) {
acc.dtmfMode = if (text == "rtp-event")
@@ -289,6 +293,8 @@ class AccountActivity : AppCompatActivity() {
}
}
+ rtcpCheck.isChecked = acc.rtcpMux
+
dtmfMode = acc.dtmfMode
val dtmfModeKeys = arrayListOf(Api.DTMFMODE_RTP_EVENT, Api.DTMFMODE_SIP_INFO)
val dtmfModeVals = arrayListOf(getString(R.string.dtmf_inband), getString(R.string.dtmf_info))
@@ -577,6 +583,15 @@ class AccountActivity : AppCompatActivity() {
}
}
+ if (rtcpCheck.isChecked != acc.rtcpMux)
+ if (Api.account_set_rtcp_mux(acc.accp, rtcpCheck.isChecked) == 0) {
+ acc.rtcpMux = Api.account_rtcp_mux(acc.accp)
+ Log.d(TAG, "New rtcpMux is ${acc.rtcpMux}")
+ save = true
+ } else {
+ Log.e(TAG, "Setting of account_rtc_mux failed")
+ }
+
if (dtmfMode != acc.dtmfMode) {
if (Api.account_set_dtmfmode(acc.accp, dtmfMode) == 0) {
acc.dtmfMode = Api.account_dtmfmode(acc.accp)
@@ -750,6 +765,12 @@ class AccountActivity : AppCompatActivity() {
getString(R.string.media_encryption_help)
)
}
+ binding.RtcpMuxTitle.setOnClickListener {
+ Utils.alertView(
+ this, getString(R.string.rtcp_mux),
+ getString(R.string.rtcp_mux_help)
+ )
+ }
binding.DtmfModeTitle.setOnClickListener {
Utils.alertView(
this, getString(R.string.dtmf_mode),
diff --git a/app/src/main/kotlin/com/tutpro/baresip/Api.kt b/app/src/main/kotlin/com/tutpro/baresip/Api.kt
index 678d3afc..312d8f0f 100644
--- a/app/src/main/kotlin/com/tutpro/baresip/Api.kt
+++ b/app/src/main/kotlin/com/tutpro/baresip/Api.kt
@@ -46,6 +46,8 @@ object Api {
external fun account_vm_uri(acc: Long): String
external fun account_answermode(acc: Long): Int
external fun account_set_answermode(acc: Long, mode: Int): Int
+ external fun account_rtcp_mux(acc: Long): Boolean
+ external fun account_set_rtcp_mux(acc: Long, value: Boolean): Int
external fun account_dtmfmode(acc: Long): Int
external fun account_set_dtmfmode(acc: Long, mode: Int): Int
external fun account_extra(acc: Long): String
diff --git a/app/src/main/res/layout/activity_account.xml b/app/src/main/res/layout/activity_account.xml
index e67ed01e..17e21f71 100644
--- a/app/src/main/res/layout/activity_account.xml
+++ b/app/src/main/res/layout/activity_account.xml
@@ -278,6 +278,31 @@
+
+
+
+
+
+
+
+ RTCP-multipleksaus
+ Jos merkitty, RTP- and RTCP-paketit multipleksataan samaan porttiin
+ (RFC 5761).
+
DTMF-moodi
Valitsee tavan, miten DTMF-merkit 0–9, #, * ja A-D lähetetään.
RTP
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index 100fc818..ca2242da 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -177,6 +177,8 @@
Prefer IPv6 Media
If checked, offer to use IPv6 media protocol (if available) when media protocol of peer cannot be automatically determined.
+ RTCP Multiplexing
+ If checked, RTP and RTCP packets are multiplexed on a single port (RFC 5761).
DTMF Mode
Selects how DTMF tones 0–9, #, *, and A-D are sent.
In-band RTP Events