Commit 22e1427e authored by Simon Morlat's avatar Simon Morlat

fix automatic resuming of calls after failed failed transfer

parent 476e1006
......@@ -638,3 +638,11 @@ bool_t sal_op_is_ipv6(SalOp *op){
return sal_address_is_ipv6((SalAddress*)contact);
}
bool_t sal_op_is_idle(SalOp *op){
if (op->dialog){
return !belle_sip_dialog_request_pending(op->dialog);
}
return TRUE;
}
......@@ -555,6 +555,23 @@ static void call_terminated(SalOp *op, const char *from){
linphone_call_set_state(call, LinphoneCallEnd,"Call ended");
}
static int resume_call_after_failed_transfer(LinphoneCall *call){
ms_message("!!!!!!!!!!resume_call_after_failed_transfer");
if (call->was_automatically_paused && call->state==LinphoneCallPausing)
return BELLE_SIP_CONTINUE; /*was still in pausing state*/
if (call->was_automatically_paused && call->state==LinphoneCallPaused){
if (sal_op_is_idle(call->op)){
linphone_core_resume_call(call->core,call);
}else {
ms_message("!!!!!!!!!!resume_call_after_failed_transfer, salop was busy");
return BELLE_SIP_CONTINUE;
}
}
linphone_call_unref(call);
return BELLE_SIP_STOP;
}
static void call_failure(SalOp *op, SalError error, SalReason sr, const char *details, int code){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
char *msg486=_("User is busy.");
......@@ -682,19 +699,10 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de
}
if (referer){
/*
* 1- resume call automatically if we had to pause it before to execute the transfer
* 2- notify other party of the transfer faillure
* This must be done at the end because transferer call can't be resumed until transfer-target call is changed to error state.
* This must be done in this order because if the notify transaction will prevent the resume transaction to take place.
* On the contrary, the notify transaction is queued and then executed after the resume completes.
**/
if (linphone_call_get_state(referer)==LinphoneCallPaused && referer->was_automatically_paused){
/*resume to the call that send us the refer automatically*/
linphone_core_resume_call(lc,referer);
referer->was_automatically_paused=FALSE;
}
/*notify referer of the failure*/
linphone_core_notify_refer_state(lc,referer,call);
/*schedule automatic resume of the call. This must be done only after the notifications are completed due to dialog serialization of requests.*/
linphone_core_queue_task(lc,(belle_sip_source_func_t)resume_call_after_failed_transfer,linphone_call_ref(referer),"Automatic call resuming after failed transfer");
}
}
......
......@@ -3594,10 +3594,8 @@ void linphone_core_preempt_sound_resources(LinphoneCore *lc){
*
* @ingroup call_control
**/
int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *the_call)
{
int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *call){
char temp[255]={0};
LinphoneCall *call = the_call;
const char *subject="Call resuming";
if(call->state!=LinphoneCallPaused ){
......@@ -3606,18 +3604,20 @@ int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *the_call)
}
if (call->params.in_conference==FALSE){
if (linphone_core_sound_resources_locked(lc)){
ms_warning("Cannot resume call %p because another call is locking the sound resources.",the_call);
ms_warning("Cannot resume call %p because another call is locking the sound resources.",call);
return -1;
}
linphone_core_preempt_sound_resources(lc);
ms_message("Resuming call %p",call);
}
call->was_automatically_paused=FALSE;
/* Stop playing music immediately. If remote side is a conference it
prevents the participants to hear it while the 200OK comes back.*/
if (call->audiostream) audio_stream_play(call->audiostream, NULL);
linphone_call_make_local_media_description(lc,the_call);
linphone_call_make_local_media_description(lc,call);
if (call->ice_session != NULL) {
linphone_core_update_local_media_description_from_ice(call->localdesc, call->ice_session);
}
......
......@@ -1321,5 +1321,13 @@ const char *linphone_core_get_video_display_filter(LinphoneCore *lc){
return lp_config_get_string(lc->config,"video","displaytype",NULL);
}
/**
* Queue a task into the main loop. The data pointer must remain valid until the task is completed.
* task_fun must return BELLE_SIP_STOP when job is finished.
**/
void linphone_core_queue_task(LinphoneCore *lc, belle_sip_source_func_t task_fun, void *data, const char *task_description){
belle_sip_source_t *s=sal_create_timer(lc->sal,task_fun,data, 20, task_description);
belle_sip_object_unref(s);
}
......@@ -382,6 +382,8 @@ bool_t linphone_core_rtcp_enabled(const LinphoneCore *lc);
LinphoneCall * is_a_linphone_call(void *user_pointer);
LinphoneProxyConfig * is_a_linphone_proxy_config(void *user_pointer);
void linphone_core_queue_task(LinphoneCore *lc, belle_sip_source_func_t task_fun, void *data, const char *task_description);
static const int linphone_proxy_config_magic=0x7979;
/*chat*/
......
......@@ -539,12 +539,8 @@ const char *sal_op_get_from(const SalOp *op);
const SalAddress *sal_op_get_from_address(const SalOp *op);
const char *sal_op_get_to(const SalOp *op);
const SalAddress *sal_op_get_to_address(const SalOp *op);
#ifndef USE_BELLESIP
const char *sal_op_get_contact(const SalOp *op);
#else
const SalAddress *sal_op_get_contact_address(const SalOp *op);
#define sal_op_get_contact sal_op_get_contact_address /*for liblinphone compatibility*/
#endif
const char *sal_op_get_route(const SalOp *op);
const MSList* sal_op_get_route_addresses(const SalOp *op);
const char *sal_op_get_proxy(const SalOp *op);
......@@ -562,6 +558,8 @@ void sal_op_set_service_route(SalOp *op,const SalAddress* service_route);
void sal_op_set_manual_refresher_mode(SalOp *op, bool_t enabled);
bool_t sal_op_is_ipv6(SalOp *op);
/*returns TRUE if there is no pending request that may block a future one */
bool_t sal_op_is_idle(SalOp *op);
/*Call API*/
int sal_call_set_local_media_description(SalOp *h, SalMediaDescription *desc);
......
......@@ -1257,6 +1257,12 @@ static void unattended_call_transfer_with_error(void) {
/*the error must be reported back to marie*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallError,1,2000));
/*and pauline should resume the call automatically*/
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallResuming,1,2000));
/*and call should be resumed*/
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallStreamsRunning,1,2000));
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
ms_list_free(lcs);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment