diff --git a/app/src/main/assets/config b/app/src/main/assets/config index 9e07828a..24d0dae8 100644 --- a/app/src/main/assets/config +++ b/app/src/main/assets/config @@ -40,6 +40,7 @@ module_app account.so module_app contact.so module_app debug_cmd.so module_app mwi.so +module_app presence.so evdev_device /dev/input/event0 opus_bitrate 28000 opus_samplerate 16000 diff --git a/app/src/main/cpp/baresip.c b/app/src/main/cpp/baresip.c index 57695eac..115c040e 100644 --- a/app/src/main/cpp/baresip.c +++ b/app/src/main/cpp/baresip.c @@ -214,7 +214,8 @@ static void ua_event_handler(struct ua *ua, enum ua_event ev, len = re_snprintf(event_buf, sizeof event_buf, "call transfer,%s", prm); break; case UA_EVENT_CALL_TRANSFER_FAILED: - len = re_snprintf(event_buf, sizeof event_buf, "refer failed,%s", prm); + call_hold(call, false); + len = re_snprintf(event_buf, sizeof event_buf, "transfer failed,%s", prm); break; case UA_EVENT_CALL_CLOSED: tone = call_scode(call) ? translate_errorcode(call_scode(call)) : ""; @@ -1236,13 +1237,13 @@ Java_com_tutpro_baresip_Api_ua_1call_1alloc(JNIEnv *env, jobject thiz, jstring j xcall = (struct call *)strtoul(native_xcall, NULL, 10); re_thread_enter(); err = ua_call_alloc(&call, ua, (enum vidmode)javaVidMode, NULL, xcall, call_localuri(xcall), true); + re_thread_leave(); if (err) { LOGW("call allocation for ua %s failed with error %d\n", native_ua, err); call_buf[0] = '\0'; } else { sprintf(call_buf, "%lu", (unsigned long)call); } - re_thread_leave(); (*env)->ReleaseStringUTFChars(env, javaUA, native_ua); (*env)->ReleaseStringUTFChars(env, javaXCall, native_xcall); return (*env)->NewStringUTF(env, call_buf); @@ -1332,35 +1333,24 @@ Java_com_tutpro_baresip_Call_call_1start_1audio(JNIEnv *env, jobject thiz, jstri } JNIEXPORT jint JNICALL -Java_com_tutpro_baresip_Call_call_1hold(JNIEnv *env, jobject thiz, jstring javaCall) { - const char *native_call = (*env)->GetStringUTFChars(env, javaCall, 0); +Java_com_tutpro_baresip_Call_call_1hold(JNIEnv *env, jobject thiz, jstring jCall, jboolean hold) { + const char *native_call = (*env)->GetStringUTFChars(env, jCall, 0); struct call *call = (struct call *) strtoul(native_call, NULL, 10); - int ret; - LOGD("holding call %s\n", native_call); - (*env)->ReleaseStringUTFChars(env, javaCall, native_call); - re_thread_enter(); - // struct audio *au = call_audio(call); - // audio_set_hold(au, true); - // audio_set_source(au, NULL, NULL); - ret = call_hold(call, true); - re_thread_leave(); - return ret; -} - -JNIEXPORT jint JNICALL -Java_com_tutpro_baresip_Call_call_1unhold(JNIEnv *env, jobject thiz, jstring javaCall) { - const char *native_call = (*env)->GetStringUTFChars(env, javaCall, 0); - struct call *call = (struct call *) strtoul(native_call, NULL, 10); - int ret; - LOGD("unholding call %s\n", native_call); - (*env)->ReleaseStringUTFChars(env, javaCall, native_call); - re_thread_enter(); - // struct audio *au = call_audio(call); - // audio_set_hold(au, false); - // audio_set_source(au, "opensles", "nil"); - ret = call_hold(call, false); - re_thread_leave(); - return ret; + int err; + if (hold) { + LOGD("holding call %s\n", native_call); + re_thread_enter(); + err = call_hold(call, true); + re_thread_leave(); + } else { + LOGD("resuming call %s\n", native_call); + re_thread_enter(); + err = call_hold(call, false); + re_thread_leave(); + } + if (err) LOGW("call_hold error: %d\n", err); + (*env)->ReleaseStringUTFChars(env, jCall, native_call); + return err; } JNIEXPORT jboolean JNICALL diff --git a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt index c42aac96..7f304e66 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/BaresipService.kt @@ -759,6 +759,20 @@ class BaresipService: Service() { return } } + "transfer failed" -> { + Log.d(TAG, "AoR $aor call $callp transfer failed: ${ev[1]}") + // stopMediaPlayer() + val call = Call.ofCallp(callp) + if (call == null) { + Log.w(TAG, "Call $callp with failed transfer is not found") + } else { + call.referTo = "" + //Timer().schedule(500) { + // call.resume() + //} + } + if (!Utils.isVisible()) return + } "call closed" -> { nm.cancel(CALL_NOTIFICATION_ID) val call = Call.ofCallp(callp) @@ -837,17 +851,6 @@ class BaresipService: Service() { return } } - "refer failed" -> { - Log.d(TAG, "AoR $aor hanging up call $callp with ${ev[1]}") - Api.ua_hangup(uap, callp, 0, "") - val call = Call.ofCallp(callp) - if (call == null) { - Log.w(TAG, "Call $callp with failed refer is not found") - } else { - call.referTo = "" - } - if (!Utils.isVisible()) return - } } } } diff --git a/app/src/main/kotlin/com/tutpro/baresip/Call.kt b/app/src/main/kotlin/com/tutpro/baresip/Call.kt index d8f162fe..7276888d 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/Call.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/Call.kt @@ -29,14 +29,17 @@ class Call(val callp: String, val ua: UserAgent, val peerUri: String, val dir: S } fun hold(): Int { - return call_hold(callp) + return call_hold(callp, true) } - fun unhold(): Int { - return call_unhold(callp) + fun resume(): Int { + return call_hold(callp, false) } - fun refer(uri: String): Int { + fun transfer(uri: String): Int { + val err = call_hold(callp, true) + if (err != 0) + return err referTo = uri return call_transfer(callp, uri) } @@ -62,8 +65,7 @@ class Call(val callp: String, val ua: UserAgent, val peerUri: String, val dir: S } private external fun call_connect(callp: String, peer_uri: String): Int - private external fun call_hold(callp: String): Int - private external fun call_unhold(callp: String): Int + private external fun call_hold(callp: String, hold: Boolean): Int private external fun call_ismuted(callp: String): Boolean private external fun call_transfer(callp: String, peer_uri: String): Int private external fun call_send_digit(callp: String, digit: Char): Int diff --git a/app/src/main/kotlin/com/tutpro/baresip/Config.kt b/app/src/main/kotlin/com/tutpro/baresip/Config.kt index 5b48017a..24302599 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/Config.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/Config.kt @@ -26,6 +26,11 @@ object Config { "module_app mwi.so") } + if (!config.contains("module presence.so")) { + config = config.replace("module_app mwi.so", + "module_app mwi.so\nmodule_app presence.so") + } + if (!config.contains("opus_application")) { config = "${config}opus_application voip\n" } diff --git a/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt b/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt index ace31117..b57e75ac 100644 --- a/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt +++ b/app/src/main/kotlin/com/tutpro/baresip/MainActivity.kt @@ -359,7 +359,7 @@ class MainActivity : AppCompatActivity() { val call = Call.uaCalls(ua, "")[0] if (call.onhold) { Log.d(TAG, "AoR $aor resuming call ${call.callp} with ${callUri.text}") - call.unhold() + call.resume() call.onhold = false holdButton.setImageResource(R.drawable.pause) } else { @@ -1043,10 +1043,11 @@ class MainActivity : AppCompatActivity() { call(ua, ev[1]) showCall(ua) } - "refer failed" -> { + "transfer failed" -> { Toast.makeText(applicationContext, "${getString(R.string.transfer_failed)}: ${ev[1].trim()}", Toast.LENGTH_LONG).show() + showCall(ua) } "call closed" -> { if (aor == aorSpinner.tag) { @@ -1340,7 +1341,7 @@ class MainActivity : AppCompatActivity() { String.format(getString(R.string.invalid_sip_uri), uri)) else { if (Call.uaCalls(ua, "").size > 0) { - Call.uaCalls(ua, "")[0].refer(uri) + Call.uaCalls(ua, "")[0].transfer(uri) showCall(ua) } }