mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-05-07 05:53:06 +00:00
Merge branch 'feature/early-media-call-repair' into dev_refactor_cpp
This commit is contained in:
commit
9507e4bd33
6 changed files with 117 additions and 12 deletions
|
|
@ -3184,6 +3184,16 @@ bool_t linphone_core_content_encoding_supported(const LinphoneCore *lc, const ch
|
|||
return (strcmp(handle_content_encoding, content_encoding) == 0) && lc->sal->isContentEncodingAvailable(content_encoding);
|
||||
}
|
||||
|
||||
static void notify_network_reachable_change (LinphoneCore *lc) {
|
||||
if (!lc->network_reachable_to_be_notified)
|
||||
return;
|
||||
|
||||
lc->network_reachable_to_be_notified = FALSE;
|
||||
linphone_core_notify_network_reachable(lc, lc->sip_network_reachable);
|
||||
if (lc->sip_network_reachable)
|
||||
linphone_core_resolve_stun_server(lc);
|
||||
}
|
||||
|
||||
static void monitor_network_state(LinphoneCore *lc, time_t curtime){
|
||||
bool_t new_status=lc->network_last_status;
|
||||
char newip[LINPHONE_IPADDR_SIZE];
|
||||
|
|
@ -3212,6 +3222,8 @@ static void monitor_network_state(LinphoneCore *lc, time_t curtime){
|
|||
}
|
||||
lc->network_last_check=curtime;
|
||||
}
|
||||
|
||||
notify_network_reachable_change(lc);
|
||||
}
|
||||
|
||||
static void proxy_update(LinphoneCore *lc){
|
||||
|
|
@ -3304,13 +3316,6 @@ void linphone_core_iterate(LinphoneCore *lc){
|
|||
int64_t diff_time;
|
||||
bool one_second_elapsed = false;
|
||||
|
||||
if (lc->network_reachable_to_be_notified) {
|
||||
lc->network_reachable_to_be_notified=FALSE;
|
||||
linphone_core_notify_network_reachable(lc,lc->sip_network_reachable);
|
||||
if (lc->sip_network_reachable) {
|
||||
linphone_core_resolve_stun_server(lc);
|
||||
}
|
||||
}
|
||||
if (lc->prevtime_ms == 0){
|
||||
lc->prevtime_ms = curtime_ms;
|
||||
}
|
||||
|
|
@ -6327,19 +6332,22 @@ static void disable_internal_network_reachability_detection(LinphoneCore *lc){
|
|||
}
|
||||
}
|
||||
|
||||
void linphone_core_set_network_reachable(LinphoneCore* lc,bool_t isReachable) {
|
||||
void linphone_core_set_network_reachable(LinphoneCore *lc, bool_t isReachable) {
|
||||
disable_internal_network_reachability_detection(lc);
|
||||
set_network_reachable(lc, isReachable, ms_time(NULL));
|
||||
notify_network_reachable_change(lc);
|
||||
}
|
||||
|
||||
void linphone_core_set_media_network_reachable(LinphoneCore *lc, bool_t is_reachable){
|
||||
disable_internal_network_reachability_detection(lc);
|
||||
set_media_network_reachable(lc, is_reachable);
|
||||
notify_network_reachable_change(lc);
|
||||
}
|
||||
|
||||
void linphone_core_set_sip_network_reachable(LinphoneCore *lc, bool_t is_reachable){
|
||||
disable_internal_network_reachability_detection(lc);
|
||||
set_sip_network_reachable(lc, is_reachable, ms_time(NULL));
|
||||
notify_network_reachable_change(lc);
|
||||
}
|
||||
|
||||
bool_t linphone_core_is_network_reachable(LinphoneCore* lc) {
|
||||
|
|
|
|||
|
|
@ -60,7 +60,7 @@ public:
|
|||
void pingReply ();
|
||||
void referred (const Address &referToAddr);
|
||||
virtual void remoteRinging ();
|
||||
void replaceOp (SalCallOp *newOp);
|
||||
virtual void replaceOp (SalCallOp *newOp);
|
||||
virtual void terminated ();
|
||||
void updated (bool isUpdate);
|
||||
void updatedByRemote ();
|
||||
|
|
@ -88,6 +88,9 @@ protected:
|
|||
void setBroken ();
|
||||
void setContactOp ();
|
||||
|
||||
virtual void reinviteToRecoverFromConnectionLoss ();
|
||||
virtual void repairByInviteWithReplaces ();
|
||||
|
||||
// CoreListener
|
||||
void onNetworkReachable (bool sipNetworkReachable, bool mediaNetworkReachable) override;
|
||||
void onRegistrationStateChanged (LinphoneProxyConfig *cfg, LinphoneRegistrationState cstate, const std::string &message) override;
|
||||
|
|
@ -98,8 +101,6 @@ private:
|
|||
|
||||
LinphoneAddress * getFixedContact () const;
|
||||
|
||||
virtual void reinviteToRecoverFromConnectionLoss ();
|
||||
void repairByInviteWithReplaces ();
|
||||
void repairIfBroken ();
|
||||
|
||||
protected:
|
||||
|
|
|
|||
|
|
@ -786,6 +786,7 @@ void CallSessionPrivate::reinviteToRecoverFromConnectionLoss () {
|
|||
|
||||
void CallSessionPrivate::repairByInviteWithReplaces () {
|
||||
L_Q();
|
||||
lInfo() << "CallSession [" << q << "] is going to have a new INVITE replacing the previous one in order to recover from lost connectivity";
|
||||
string callId = op->getCallId();
|
||||
const char *fromTag = op->getLocalTag();
|
||||
const char *toTag = op->getRemoteTag();
|
||||
|
|
|
|||
|
|
@ -46,6 +46,7 @@ public:
|
|||
void pauseForTransfer ();
|
||||
void pausedByRemote ();
|
||||
void remoteRinging () override;
|
||||
void replaceOp (SalCallOp *newOp) override;
|
||||
int resumeAfterFailedTransfer ();
|
||||
void resumed ();
|
||||
void startPendingRefer ();
|
||||
|
|
@ -249,6 +250,7 @@ private:
|
|||
|
||||
void refreshSockets ();
|
||||
void reinviteToRecoverFromConnectionLoss () override;
|
||||
void repairByInviteWithReplaces () override;
|
||||
|
||||
#ifdef VIDEO_ENABLED
|
||||
void videoStreamEventCb (const MSFilter *f, const unsigned int eventId, const void *args);
|
||||
|
|
|
|||
|
|
@ -320,6 +320,11 @@ void MediaSessionPrivate::remoteRinging () {
|
|||
}
|
||||
}
|
||||
|
||||
void MediaSessionPrivate::replaceOp (SalCallOp *newOp) {
|
||||
CallSessionPrivate::replaceOp(newOp);
|
||||
updateStreams(newOp->getFinalMediaDescription(), state);
|
||||
}
|
||||
|
||||
int MediaSessionPrivate::resumeAfterFailedTransfer () {
|
||||
L_Q();
|
||||
if (automaticallyPaused && (state == CallSession::State::Pausing))
|
||||
|
|
@ -1176,7 +1181,7 @@ void MediaSessionPrivate::getLocalIp (const Address &remoteAddr) {
|
|||
struct addrinfo *res = nullptr;
|
||||
string host(remoteAddr.getDomain());
|
||||
int err;
|
||||
|
||||
|
||||
if (host[0] == '[')
|
||||
host = host.substr(1, host.size() - 2);
|
||||
memset(&hints, 0, sizeof(hints));
|
||||
|
|
@ -3823,6 +3828,14 @@ void MediaSessionPrivate::reinviteToRecoverFromConnectionLoss () {
|
|||
q->update(getParams());
|
||||
}
|
||||
|
||||
void MediaSessionPrivate::repairByInviteWithReplaces () {
|
||||
if ((state == CallSession::State::IncomingEarlyMedia) || (state == CallSession::State::OutgoingEarlyMedia)) {
|
||||
stopStreams();
|
||||
initializeStreams();
|
||||
}
|
||||
CallSessionPrivate::repairByInviteWithReplaces();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#ifdef VIDEO_ENABLED
|
||||
|
|
|
|||
|
|
@ -5280,6 +5280,84 @@ end:
|
|||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static void recovered_call_on_network_switch_in_early_media_base (bool_t callerLosesNetwork) {
|
||||
LinphoneCoreManager *marie = linphone_core_manager_new("marie_rc");
|
||||
LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc");
|
||||
bctbx_list_t *lcs = NULL;
|
||||
LinphoneCall *marie_call;
|
||||
LinphoneCallLog *marie_call_log;
|
||||
uint64_t connected_time = 0;
|
||||
uint64_t ended_time = 0;
|
||||
|
||||
lcs = bctbx_list_append(lcs, marie->lc);
|
||||
lcs = bctbx_list_append(lcs, pauline->lc);
|
||||
|
||||
/* Marie calls Pauline, and after the call has rung, transitions to an early-media session */
|
||||
marie_call = linphone_core_invite_address(marie->lc, pauline->identity);
|
||||
marie_call_log = linphone_call_get_call_log(marie_call);
|
||||
BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallIncomingReceived, 1, 3000));
|
||||
BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallOutgoingRinging, 1, 1000));
|
||||
|
||||
if (linphone_core_inc_invite_pending(pauline->lc)) {
|
||||
/* Send a 183 to initiate the early media */
|
||||
linphone_call_accept_early_media(linphone_core_get_current_call(pauline->lc));
|
||||
BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallIncomingEarlyMedia, 1, 2000) );
|
||||
BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallOutgoingEarlyMedia, 1, 2000) );
|
||||
BC_ASSERT_TRUE(linphone_call_get_all_muted(marie_call));
|
||||
|
||||
liblinphone_tester_check_rtcp(marie, pauline);
|
||||
|
||||
if (callerLosesNetwork) {
|
||||
/* Disconnect Marie's network and then reconnect it */
|
||||
linphone_core_set_network_reachable(marie->lc, FALSE);
|
||||
BC_ASSERT_EQUAL(marie->stat.number_of_NetworkReachableFalse, 1, int, "%d");
|
||||
linphone_core_set_network_reachable(marie->lc, TRUE);
|
||||
BC_ASSERT_EQUAL(marie->stat.number_of_NetworkReachableTrue, 2, int, "%d");
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneRegistrationOk, 2));
|
||||
} else {
|
||||
/* Disconnect Pauline's network and then reconnect it */
|
||||
linphone_core_set_network_reachable(pauline->lc, FALSE);
|
||||
BC_ASSERT_EQUAL(pauline->stat.number_of_NetworkReachableFalse, 1, int, "%d");
|
||||
linphone_core_set_network_reachable(pauline->lc, TRUE);
|
||||
BC_ASSERT_EQUAL(pauline->stat.number_of_NetworkReachableTrue, 2, int, "%d");
|
||||
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneRegistrationOk, 2));
|
||||
}
|
||||
|
||||
wait_for_until(marie->lc, pauline->lc, NULL, 1, 2000);
|
||||
liblinphone_tester_check_rtcp(marie, pauline);
|
||||
|
||||
if (linphone_core_get_current_call(pauline->lc)
|
||||
&& (linphone_call_get_state(linphone_core_get_current_call(pauline->lc)) == LinphoneCallIncomingEarlyMedia)
|
||||
) {
|
||||
linphone_call_accept(linphone_core_get_current_call(pauline->lc));
|
||||
BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallConnected, 1, 1000));
|
||||
connected_time = ms_get_cur_time_ms();
|
||||
BC_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallStreamsRunning, 1, 1000));
|
||||
BC_ASSERT_PTR_EQUAL(marie_call, linphone_core_get_current_call(marie->lc));
|
||||
BC_ASSERT_FALSE(linphone_call_get_all_muted(marie_call));
|
||||
|
||||
liblinphone_tester_check_rtcp(marie, pauline);
|
||||
wait_for_list(lcs, 0, 1, 2000); /* Just to have a call duration != 0 */
|
||||
|
||||
end_call(pauline, marie);
|
||||
ended_time = ms_get_cur_time_ms();
|
||||
BC_ASSERT_LOWER(labs((long)((linphone_call_log_get_duration(marie_call_log) * 1000) - (int64_t)(ended_time - connected_time))), 1500, long, "%ld");
|
||||
}
|
||||
}
|
||||
|
||||
bctbx_list_free(lcs);
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static void recovered_call_on_network_switch_in_early_media_1 (void) {
|
||||
recovered_call_on_network_switch_in_early_media_base(TRUE);
|
||||
}
|
||||
|
||||
static void recovered_call_on_network_switch_in_early_media_2 (void) {
|
||||
recovered_call_on_network_switch_in_early_media_base(FALSE);
|
||||
}
|
||||
|
||||
static void _call_with_network_switch(bool_t use_ice, bool_t with_socket_refresh, bool_t enable_rtt, bool_t caller_pause, bool_t callee_pause) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
|
||||
|
|
@ -6553,6 +6631,8 @@ test_t call_tests[] = {
|
|||
TEST_ONE_TAG("Recovered call on network switch during re-invite 2", recovered_call_on_network_switch_during_reinvite_2, "CallRecovery"),
|
||||
TEST_ONE_TAG("Recovered call on network switch during re-invite 3", recovered_call_on_network_switch_during_reinvite_3, "CallRecovery"),
|
||||
TEST_ONE_TAG("Recovered call on network switch during re-invite 4", recovered_call_on_network_switch_during_reinvite_4, "CallRecovery"),
|
||||
TEST_ONE_TAG("Recovered call on network switch in early media 1", recovered_call_on_network_switch_in_early_media_1, "CallRecovery"),
|
||||
TEST_ONE_TAG("Recovered call on network switch in early media 2", recovered_call_on_network_switch_in_early_media_2, "CallRecovery"),
|
||||
TEST_ONE_TAG("Call with network switch in paused state", call_with_network_switch_in_paused_state, "CallRecovery"),
|
||||
TEST_ONE_TAG("Call with network switch in paused by remote state", call_with_network_switch_in_paused_by_remote_state, "CallRecovery"),
|
||||
TEST_ONE_TAG("Call with network switch and ICE", call_with_network_switch_and_ice, "ICE"),
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue