Fix crash when a reINVITE receives a 481 response.

This commit is contained in:
Simon Morlat 2016-10-21 20:54:27 +02:00
parent c7e0929094
commit cceca72237
5 changed files with 85 additions and 9 deletions

View file

@ -948,10 +948,6 @@ static void call_failure(SalOp *op){
msg=_("Incompatible media parameters.");
linphone_core_notify_display_status(lc,msg);
break;
case SalReasonNoMatch:
/* Call leg does not exist response for case of section 5.5 of RFC 6141 */
linphone_call_reinvite_to_recover_from_connection_loss(call);
return; /* Do not continue... */
default:
linphone_core_notify_display_status(lc,_("Call failed."));
}
@ -961,9 +957,11 @@ static void call_failure(SalOp *op){
case LinphoneCallUpdating:
case LinphoneCallPausing:
case LinphoneCallResuming:
ms_message("Call error on state [%s], restoring previous state",linphone_call_state_to_string(call->prevstate));
linphone_call_set_state(call, call->prevstate,ei->full_string);
return;
if (ei->reason != SalReasonNoMatch){
ms_message("Call error on state [%s], restoring previous state",linphone_call_state_to_string(call->prevstate));
linphone_call_set_state(call, call->prevstate,ei->full_string);
return;
}
default:
break; /*nothing to do*/
}
@ -979,7 +977,11 @@ static void call_failure(SalOp *op){
if (ei->reason==SalReasonDeclined){
linphone_call_set_state(call,LinphoneCallEnd,"Call declined.");
}else{
linphone_call_set_state(call,LinphoneCallError,ei->full_string);
if (linphone_call_state_is_early(call->state)){
linphone_call_set_state(call,LinphoneCallError,ei->full_string);
}else{
linphone_call_set_state(call, LinphoneCallEnd, ei->full_string);
}
}
if (ei->reason!=SalReasonNone) linphone_core_play_call_error_tone(lc,linphone_reason_from_sal(ei->reason));
}

View file

@ -49,6 +49,35 @@ static void _linphone_call_set_next_video_frame_decoded_trigger(LinphoneCall *ca
void linphone_call_handle_stream_events(LinphoneCall *call, int stream_index);
bool_t linphone_call_state_is_early(LinphoneCallState state){
switch (state){
case LinphoneCallIdle:
case LinphoneCallOutgoingInit:
case LinphoneCallOutgoingEarlyMedia:
case LinphoneCallOutgoingRinging:
case LinphoneCallOutgoingProgress:
case LinphoneCallIncomingReceived:
case LinphoneCallIncomingEarlyMedia:
case LinphoneCallEarlyUpdatedByRemote:
case LinphoneCallEarlyUpdating:
return TRUE;
case LinphoneCallResuming:
case LinphoneCallEnd:
case LinphoneCallUpdating:
case LinphoneCallRefered:
case LinphoneCallPausing:
case LinphoneCallPausedByRemote:
case LinphoneCallPaused:
case LinphoneCallConnected:
case LinphoneCallError:
case LinphoneCallUpdatedByRemote:
case LinphoneCallReleased:
case LinphoneCallStreamsRunning:
break;
}
return FALSE;
}
MSWebCam *get_nowebcam_device(MSFactory* f){
#ifdef VIDEO_ENABLED
return ms_web_cam_manager_get_cam(ms_factory_get_web_cam_manager(f),"StaticImage: Static picture");

View file

@ -1634,6 +1634,8 @@ char *linphone_presence_model_to_xml(LinphonePresenceModel *model) ;
void linphone_call_check_ice_session(LinphoneCall *call, IceRole role, bool_t is_reinvite);
bool_t linphone_call_state_is_early(LinphoneCallState state);
#ifdef __cplusplus
}
#endif

@ -1 +1 @@
Subproject commit ff857a68653beae24fff732b1afbdd082eb589cc
Subproject commit 079df9659a25a5a06c85e6a64bf226bc4fa7d91b

View file

@ -4559,6 +4559,48 @@ static void call_with_network_switch_and_socket_refresh(void){
_call_with_network_switch(TRUE, TRUE, FALSE);
}
static void call_with_network_switch_no_recovery(void){
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
LinphoneCallParams *pauline_params = NULL;
bctbx_list_t *lcs = NULL;
bool_t call_ok;
lcs = bctbx_list_append(lcs, marie->lc);
lcs = bctbx_list_append(lcs, pauline->lc);
linphone_core_set_nortp_timeout(marie->lc, 50000);
BC_ASSERT_TRUE((call_ok=call_with_params(pauline, marie, pauline_params, NULL)));
if (!call_ok) goto end;
wait_for_until(marie->lc, pauline->lc, NULL, 0, 2000);
/*marie looses the network and reconnects*/
linphone_core_set_network_reachable(marie->lc, FALSE);
/*but meanwhile pauline terminates the call.*/
linphone_core_terminate_call(pauline->lc, linphone_core_get_current_call(pauline->lc));
/*
* We have to wait 32 seconds so that the BYE transaction is terminated, and dialog removed.
* This is the condition to receive a 481 when marie sends the reINVITE.*/
wait_for_list(lcs, NULL, 0, 32500);
/*marie will reconnect, register, and send an automatic reINVITE to try to repair the call*/
linphone_core_set_network_reachable(marie->lc, TRUE);
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneRegistrationOk, 2));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallUpdating, 1));
/*This reINVITE should of course fail, so marie's call should be terminated.*/
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1));
end:
if (pauline_params) {
linphone_call_params_unref(pauline_params);
}
bctbx_list_free(lcs);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
static void call_with_sip_and_rtp_independant_switches(void){
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
@ -5350,6 +5392,7 @@ test_t call_tests[] = {
TEST_NO_TAG("Call paused resumed with custom RTP Modifier", call_paused_resumed_with_custom_rtp_modifier),
TEST_NO_TAG("Call record with custom RTP Modifier", call_record_with_custom_rtp_modifier),
TEST_NO_TAG("Call with network switch", call_with_network_switch),
TEST_NO_TAG("Call with network switch and no recovery possible", call_with_network_switch_no_recovery),
TEST_NO_TAG("Recovered call on network switch in early state 1", recovered_call_on_network_switch_in_early_state_1),
TEST_NO_TAG("Recovered call on network switch in early state 2", recovered_call_on_network_switch_in_early_state_2),
TEST_NO_TAG("Recovered call on network switch in early state 3", recovered_call_on_network_switch_in_early_state_3),