Fix some crashes related to asynchronous ICE candidates gathering.

This commit is contained in:
Ghislain MARY 2012-08-01 09:30:27 +02:00
parent 950c65ffd9
commit 922caf698f
4 changed files with 29 additions and 14 deletions

View file

@ -187,7 +187,7 @@ static void call_received(SalOp *h){
linphone_core_add_call(lc,call);
linphone_call_ref(call); /*prevent the call from being destroyed while we are notifying, if the user declines within the state callback */
if (linphone_core_get_firewall_policy(lc) == LinphonePolicyUseIce) {
if ((linphone_core_get_firewall_policy(lc) == LinphonePolicyUseIce) && sal_op_get_ice_session(call->op)) {
/* Defer ringing until the end of the ICE candidates gathering process. */
ms_message("Defer ringing to gather ICE candidates");
return;
@ -254,13 +254,20 @@ static void call_ringing(SalOp *h){
static void call_accepted(SalOp *op){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
IceSession *ice_session=sal_op_get_ice_session(op);
SalMediaDescription *md;
if (call==NULL){
ms_warning("No call to accept.");
return ;
}
if (ice_session == NULL) {
/* Ensure the ICE check list pointers for the call streams are resetted to prevent crashes */
if (call->audiostream != NULL) call->audiostream->ice_check_list = NULL;
if (call->videostream != NULL) call->videostream->ice_check_list = NULL;
}
md=sal_call_get_final_media_description(op);
if (call->state==LinphoneCallOutgoingProgress ||

View file

@ -394,8 +394,7 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
linphone_call_start_media_streams_for_ice_gathering(call);
if (linphone_core_gather_ice_candidates(call->core,call)<0) {
/* Ice candidates gathering failed, proceed with the call anyway. */
ice_session_destroy(sal_op_get_ice_session(call->op));
sal_op_set_ice_session(call->op, NULL);
linphone_call_delete_ice_session(call);
linphone_call_stop_media_streams(call);
}
break;
@ -404,8 +403,7 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro
/* No break to also destroy ice session in this case. */
default:
if (sal_op_get_ice_session(call->op) != NULL) {
ice_session_destroy(sal_op_get_ice_session(call->op));
sal_op_set_ice_session(call->op, NULL);
linphone_call_delete_ice_session(call);
}
break;
}
@ -1466,6 +1464,16 @@ void linphone_call_start_media_streams_for_ice_gathering(LinphoneCall *call){
}
}
void linphone_call_delete_ice_session(LinphoneCall *call){
IceSession *ice_session = sal_op_get_ice_session(call->op);
if (ice_session != NULL) {
ice_session_destroy(ice_session);
sal_op_set_ice_session(call->op, NULL);
if (call->audiostream != NULL) call->audiostream->ice_check_list = NULL;
if (call->videostream != NULL) call->videostream->ice_check_list = NULL;
}
}
static void linphone_call_log_fill_stats(LinphoneCallLog *log, AudioStream *st){
audio_stream_get_local_rtp_stats (st,&log->local_stats);
log->quality=audio_stream_get_average_quality_rating(st);
@ -1473,6 +1481,7 @@ static void linphone_call_log_fill_stats(LinphoneCallLog *log, AudioStream *st){
void linphone_call_stop_media_streams(LinphoneCall *call){
if (call->audiostream!=NULL) {
call->audiostream->ice_check_list = NULL;
rtp_session_unregister_event_queue(call->audiostream->session,call->audiostream_app_evq);
ortp_ev_queue_flush(call->audiostream_app_evq);
ortp_ev_queue_destroy(call->audiostream_app_evq);
@ -1497,9 +1506,11 @@ void linphone_call_stop_media_streams(LinphoneCall *call){
#ifdef VIDEO_ENABLED
if (call->videostream!=NULL){
call->videostream->ice_check_list = NULL;
rtp_session_unregister_event_queue(call->videostream->session,call->videostream_app_evq);
ortp_ev_queue_flush(call->videostream_app_evq);
ortp_ev_queue_destroy(call->videostream_app_evq);
call->videostream_app_evq=NULL;
video_stream_stop(call->videostream);
call->videostream=NULL;
}
@ -1737,8 +1748,7 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse
ice_session_eliminate_redundant_candidates(ice_session);
ice_session_choose_default_candidates(ice_session);
} else {
ice_session_destroy(ice_session);
sal_op_set_ice_session(call->op, NULL);
linphone_call_delete_ice_session(call);
}
if (call->state==LinphoneCallOutgoingInit) {
linphone_core_start_invite(call->core,call,NULL);
@ -1792,8 +1802,7 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse
ice_session_eliminate_redundant_candidates(ice_session);
ice_session_choose_default_candidates(ice_session);
} else {
ice_session_destroy(sal_op_get_ice_session(call->op));
sal_op_set_ice_session(call->op, NULL);
linphone_call_delete_ice_session(call);
}
if (call->state==LinphoneCallOutgoingInit) {
linphone_core_start_invite(call->core,call,NULL);

View file

@ -1854,8 +1854,7 @@ void linphone_core_iterate(LinphoneCore *lc){
/*start the call even if the OPTIONS reply did not arrive*/
if (sal_op_get_ice_session(call->op) != NULL) {
/* ICE candidates gathering has not finished yet, proceed with the call without ICE anyway. */
ice_session_destroy(sal_op_get_ice_session(call->op));
sal_op_set_ice_session(call->op, NULL);
linphone_call_delete_ice_session(call);
linphone_call_stop_media_streams(call);
}
linphone_core_start_invite(lc,call,NULL);
@ -2294,8 +2293,7 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const
call->start_time=time(NULL);
if (linphone_core_gather_ice_candidates(lc,call)<0) {
/* Ice candidates gathering failed, proceed with the call anyway. */
ice_session_destroy(sal_op_get_ice_session(call->op));
sal_op_set_ice_session(call->op, NULL);
linphone_call_delete_ice_session(call);
linphone_call_stop_media_streams(call);
} else {
if (real_url!=NULL) ms_free(real_url);

View file

@ -247,6 +247,7 @@ void linphone_call_init_media_streams(LinphoneCall *call);
void linphone_call_start_media_streams(LinphoneCall *call, bool_t all_inputs_muted, bool_t send_ringbacktone);
void linphone_call_start_media_streams_for_ice_gathering(LinphoneCall *call);
void linphone_call_stop_media_streams(LinphoneCall *call);
void linphone_call_delete_ice_session(LinphoneCall *call);
const char * linphone_core_get_identity(LinphoneCore *lc);
const char * linphone_core_get_route(LinphoneCore *lc);