diff --git a/app/src/main/cpp/baresip.c b/app/src/main/cpp/baresip.c
index d0b74e61..fbc8754f 100644
--- a/app/src/main/cpp/baresip.c
+++ b/app/src/main/cpp/baresip.c
@@ -1062,6 +1062,42 @@ Java_com_tutpro_baresip_Api_account_1vm_1uri(JNIEnv *env, jobject thiz, jstring
return (*env)->NewStringUTF(env, "");
}
+JNIEXPORT jint JNICALL
+Java_com_tutpro_baresip_Api_account_1answermode(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);
+ return account_answermode(acc);
+}
+
+JNIEXPORT jint JNICALL
+Java_com_tutpro_baresip_Api_account_1set_1answermode(JNIEnv *env, jobject thiz,
+ jstring jAcc, jint jMode) {
+ 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 uint32_t mode = (uint32_t)jMode;
+ return account_set_answermode(acc, mode);
+}
+
+JNIEXPORT jint JNICALL
+Java_com_tutpro_baresip_Api_account_1dtmfmode(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);
+ return account_dtmfmode(acc);
+}
+
+JNIEXPORT jint JNICALL
+Java_com_tutpro_baresip_Api_account_1set_1dtmfmode(JNIEnv *env, jobject thiz,
+ jstring jAcc, jint jMode) {
+ 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 uint32_t mode = (uint32_t)jMode;
+ return account_set_dtmfmode(acc, mode);
+}
+
JNIEXPORT jstring JNICALL
Java_com_tutpro_baresip_Api_account_1extra(JNIEnv *env, jobject thiz, jstring javaAcc)
{
diff --git a/app/src/main/kotlin/com/tutpro/baresip/Account.kt b/app/src/main/kotlin/com/tutpro/baresip/Account.kt
index 0c106484..23544d88 100644
--- a/app/src/main/kotlin/com/tutpro/baresip/Account.kt
+++ b/app/src/main/kotlin/com/tutpro/baresip/Account.kt
@@ -21,7 +21,8 @@ class Account(val accp: String) {
var regint = Api.account_regint(accp)
var mediaEnc = Api.account_mediaenc(accp)
var preferIPv6Media = false
- var answerMode = ""
+ var dtmfMode = Api.account_dtmfmode(accp)
+ var answerMode = Api.account_answermode(accp)
var vmUri = Api.account_vm_uri(accp)
var vmNew = 0
var vmOld = 0
@@ -56,8 +57,6 @@ class Account(val accp: String) {
val extra = Api.account_extra(accp)
preferIPv6Media = Utils.paramValue(extra,"prefer_ipv6_media") == "yes"
- answerMode = Utils.paramValue(extra,"answer_mode")
- if (answerMode == "") answerMode = "manual"
callHistory = Utils.paramValue(extra,"call_history") == ""
}
@@ -114,6 +113,9 @@ class Account(val accp: String) {
else
res = res + ";mwi=yes;vm_uri=\"$vmUri\""
+ if (answerMode == Api.ANSWERMODE_AUTO)
+ res += ";answermode=auto"
+
res += ";ptime=20;regint=${regint};regq=0.5;pubint=0;call_transfer=yes"
var extra = ""
@@ -121,9 +123,6 @@ class Account(val accp: String) {
if (!callHistory)
extra += ";call_history=no"
- if (answerMode == "auto")
- extra += ";answer_mode=auto"
-
if (preferIPv6Media)
extra += ";prefer_ipv6_media=yes"
diff --git a/app/src/main/kotlin/com/tutpro/baresip/AccountActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/AccountActivity.kt
index 259b539d..f27e41b4 100644
--- a/app/src/main/kotlin/com/tutpro/baresip/AccountActivity.kt
+++ b/app/src/main/kotlin/com/tutpro/baresip/AccountActivity.kt
@@ -39,7 +39,9 @@ class AccountActivity : AppCompatActivity() {
private lateinit var mediaEnc: String
private lateinit var mediaEncSpinner: Spinner
private lateinit var ipV6MediaCheck: CheckBox
- private lateinit var answerMode: String
+ private var dtmfMode = Api.DTMFMODE_RTP_EVENT
+ private lateinit var dtmfModeSpinner: Spinner
+ private var answerMode = Api.ANSWERMODE_MANUAL
private lateinit var answerModeSpinner: Spinner
private lateinit var vmUri: EditText
private lateinit var defaultCheck: CheckBox
@@ -74,6 +76,7 @@ class AccountActivity : AppCompatActivity() {
stunPass = binding.StunPass
mediaEncSpinner = binding.mediaEncSpinner
ipV6MediaCheck = binding.PreferIPv6Media
+ dtmfModeSpinner = binding.dtmfModeSpinner
answerModeSpinner = binding.answerModeSpinner
vmUri = binding.voicemailUri
defaultCheck = binding.Default
@@ -181,8 +184,29 @@ class AccountActivity : AppCompatActivity() {
ipV6MediaCheck.isChecked = acc.preferIPv6Media
+ 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))
+ keyIx = dtmfModeKeys.indexOf(acc.dtmfMode)
+ keyVal = dtmfModeVals.elementAt(keyIx)
+ dtmfModeKeys.removeAt(keyIx)
+ dtmfModeVals.removeAt(keyIx)
+ dtmfModeKeys.add(0, acc.dtmfMode)
+ dtmfModeVals.add(0, keyVal)
+ val dtmfModeAdapter = ArrayAdapter(this,android.R.layout.simple_spinner_item,
+ dtmfModeVals)
+ dtmfModeAdapter.setDropDownViewResource(android.R.layout.simple_spinner_dropdown_item)
+ dtmfModeSpinner.adapter = dtmfModeAdapter
+ dtmfModeSpinner.onItemSelectedListener = object : AdapterView.OnItemSelectedListener {
+ override fun onItemSelected(parent: AdapterView<*>, view: View, position: Int, id: Long) {
+ dtmfMode = dtmfModeKeys[dtmfModeVals.indexOf(parent.selectedItem.toString())]
+ }
+ override fun onNothingSelected(parent: AdapterView<*>) {
+ }
+ }
+
answerMode = acc.answerMode
- val answerModeKeys = arrayListOf("manual", "auto")
+ val answerModeKeys = arrayListOf(Api.ANSWERMODE_MANUAL, Api.ANSWERMODE_AUTO)
val answerModeVals = arrayListOf(getString(R.string.manual), getString(R.string.auto))
keyIx = answerModeKeys.indexOf(acc.answerMode)
keyVal = answerModeVals.elementAt(keyIx)
@@ -436,10 +460,24 @@ class AccountActivity : AppCompatActivity() {
save = true
}
+ if (dtmfMode != acc.dtmfMode) {
+ if (Api.account_set_dtmfmode(acc.accp, dtmfMode) == 0) {
+ acc.dtmfMode = Api.account_dtmfmode(acc.accp)
+ Log.d(TAG, "New dtmfmode is ${acc.dtmfMode}")
+ save = true
+ } else {
+ Log.e(TAG, "Setting of dtmfmode $dtmfMode failed")
+ }
+ }
+
if (answerMode != acc.answerMode) {
- acc.answerMode = answerMode
- Log.d(TAG, "New answermode is ${acc.answerMode}")
- save = true
+ if (Api.account_set_answermode(acc.accp, answerMode) == 0) {
+ acc.answerMode = Api.account_answermode(acc.accp)
+ Log.d(TAG, "New answermode is ${acc.answerMode}")
+ save = true
+ } else {
+ Log.e(TAG, "Setting of answermode $answerMode failed")
+ }
}
var tVmUri = vmUri.text.toString().trim()
@@ -562,6 +600,10 @@ class AccountActivity : AppCompatActivity() {
Utils.alertView(this, getString(R.string.prefer_ipv6_media),
getString(R.string.prefer_ipv6_media_help))
}
+ binding.DtmfModeTitle -> {
+ Utils.alertView(this, getString(R.string.dtmf_mode),
+ getString(R.string.dtmf_mode_help))
+ }
binding.AnswerModeTitle -> {
Utils.alertView(this, getString(R.string.answer_mode),
getString(R.string.answer_mode_help))
@@ -649,9 +691,20 @@ class AccountActivity : AppCompatActivity() {
acc.stunServer = text
"prefer-ipv6-media" ->
acc.preferIPv6Media = text == "yes"
+ "dtmf-mode" ->
+ if (text in arrayOf("rtp-event", "sip-info")) {
+ acc.dtmfMode = if (text == "rtp-event")
+ Api.DTMFMODE_RTP_EVENT
+ else
+ Api.DTMFMODE_SIP_INFO
+ }
"answer-mode" ->
- if (text in arrayOf("manual", "auto"))
- acc.answerMode = text
+ if (text in arrayOf("manual", "auto")) {
+ acc.answerMode = if (text == "manual")
+ Api.ANSWERMODE_MANUAL
+ else
+ Api.ANSWERMODE_AUTO
+ }
"voicemail-uri" ->
if (text.isNotEmpty())
acc.vmUri = text
diff --git a/app/src/main/kotlin/com/tutpro/baresip/Api.kt b/app/src/main/kotlin/com/tutpro/baresip/Api.kt
index f251e55e..36da1793 100644
--- a/app/src/main/kotlin/com/tutpro/baresip/Api.kt
+++ b/app/src/main/kotlin/com/tutpro/baresip/Api.kt
@@ -7,6 +7,10 @@ object Api {
const val AF_INET6 = 10
const val VIDMODE_OFF = 0
const val VIDMODE_ON = 1
+ const val ANSWERMODE_MANUAL = 0
+ const val ANSWERMODE_AUTO = 2
+ const val DTMFMODE_RTP_EVENT = 0
+ const val DTMFMODE_SIP_INFO = 1
external fun account_set_display_name(acc: String, dn: String): Int
external fun account_display_name(acc: String): String
@@ -36,6 +40,10 @@ object Api {
external fun account_set_video_codecs(acc: String, codecs: String): Int
external fun account_set_mwi(acc: String, value: String): Int
external fun account_vm_uri(acc: String): String
+ external fun account_answermode(acc: String): Int
+ external fun account_set_answermode(acc: String, mode: Int): Int
+ external fun account_dtmfmode(acc: String): Int
+ external fun account_set_dtmfmode(acc: String, mode: Int): Int
external fun account_extra(acc: String): String
external fun account_debug(acc: String)
diff --git a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt
index 6a2c2854..28aed3bd 100644
--- a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt
+++ b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt
@@ -530,7 +530,7 @@ class BaresipService: Service() {
Log.d(LOG_TAG, "Incoming call $uap/$callp/$peerUri")
Call(callp, ua, peerUri, "in", "incoming",
Utils.dtmfWatcher(callp)).add()
- if (ua.account.answerMode == "manual") {
+ if (ua.account.answerMode == Api.ANSWERMODE_MANUAL) {
if (Build.VERSION.SDK_INT >= 23) {
Log.d(LOG_TAG, "CurrentInterruptionFilter ${nm.currentInterruptionFilter}")
if (nm.currentInterruptionFilter <= NotificationManager.INTERRUPTION_FILTER_ALL)
diff --git a/app/src/main/res/layout/activity_account.xml b/app/src/main/res/layout/activity_account.xml
index b93f74af..18b14a24 100644
--- a/app/src/main/res/layout/activity_account.xml
+++ b/app/src/main/res/layout/activity_account.xml
@@ -277,6 +277,23 @@
+
+
+
+
+
+
+ DTMF-moodi
+ Valitsee miten DTMF-merkit 0–9, #, * ja A-D lähetetään.
+ RTP-tapahtumina
+ SIP INFO-pyyntöinä
Vastaustapa
Valitsee tulevien puheluiden vastaustavan.
Manuaalinen
diff --git a/app/src/main/res/values/strings.xml b/app/src/main/res/values/strings.xml
index c509134e..efabb6f6 100644
--- a/app/src/main/res/values/strings.xml
+++ b/app/src/main/res/values/strings.xml
@@ -166,6 +166,10 @@
Prefer IPv6 Media
If checked, offer to use IPv6 media protocol (if available) when media protocol of peer cannot be automatically determined.
+ DTMF Mode
+ Selects how DTMF tones 0–9, #, *, and A-D are sent.
+ In-band RTP Events
+ SIP INFO Requests
Answer Mode
Selects how incoming calls are answered.
Manual