diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index b587ac75c..142a7a564 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -341,6 +341,8 @@ static void call_accepted(SalOp *op){ } linphone_core_update_streams (lc,call,md); linphone_call_set_state(call,LinphoneCallPaused,"Call paused"); + if (call->refer_pending) + linphone_core_start_refered_call(lc,call); }else if (sal_media_description_has_dir(md,SalStreamRecvOnly)){ /*we are put on hold when the call is initially accepted */ if (lc->vtable.display_status){ @@ -757,8 +759,10 @@ static void refer_received(Sal *sal, SalOp *op, const char *referto){ ms_message("Automatically pausing current call to accept transfer."); linphone_core_pause_call(lc,call); call->was_automatically_paused=TRUE; - } - linphone_core_start_refered_call(lc,call); + /*then we will start the refered when the pause is accepted, in order to serialize transactions within the dialog. + * Indeed we need to avoid to send a NOTIFY to inform about of state of the refered call while the pause isn't completed. + **/ + }else linphone_core_start_refered_call(lc,call); }else if (lc->vtable.refer_received){ lc->vtable.refer_received(lc,referto); } diff --git a/coreapi/sal_eXosip2.c b/coreapi/sal_eXosip2.c index f21f43654..6a4e2b284 100644 --- a/coreapi/sal_eXosip2.c +++ b/coreapi/sal_eXosip2.c @@ -734,7 +734,7 @@ static int send_notify_for_refer(int did, const char *sipfrag){ eXosip_call_build_notify(did,EXOSIP_SUBCRSTATE_ACTIVE,&msg); if (msg==NULL){ eXosip_unlock(); - ms_error("Could not build NOTIFY for refer."); + ms_warning("Could not build NOTIFY for refer."); return -1; } osip_message_set_content_type(msg,"message/sipfrag"); @@ -760,7 +760,10 @@ int sal_call_notify_refer_state(SalOp *h, SalOp *newcall){ } }else{ if (!newcall->terminated){ - send_notify_for_refer(h->did,"SIP/2.0 200 Ok\r\n"); + if (send_notify_for_refer(h->did,"SIP/2.0 200 Ok\r\n")==-1){ + /* we need previous notify transaction to complete, so buffer the request for later*/ + h->sipfrag_pending="SIP/2.0 200 Ok\r\n"; + } } } } @@ -1536,7 +1539,7 @@ static void process_refer(Sal *sal, SalOp *op, eXosip_event_t *ev){ } } -void process_notify(Sal *sal, eXosip_event_t *ev){ +static void process_notify(Sal *sal, eXosip_event_t *ev){ osip_header_t *h=NULL; char *from=NULL; SalOp *op=find_op(sal,ev); @@ -1900,6 +1903,18 @@ static void other_request_reply(Sal *sal,eXosip_event_t *ev){ } } +static void process_in_call_reply(Sal *sal, eXosip_event_t *ev){ + SalOp *op=find_op(sal,ev); + if (ev->response){ + if (ev->request && strcmp(osip_message_get_method(ev->request),"NOTIFY")==0){ + if (op->sipfrag_pending){ + send_notify_for_refer(op->did,op->sipfrag_pending); + op->sipfrag_pending=NULL; + } + } + } +} + static bool_t process_event(Sal *sal, eXosip_event_t *ev){ ms_message("linphone process event get a message %d\n",ev->type); switch(ev->type){ @@ -1961,6 +1976,10 @@ static bool_t process_event(Sal *sal, eXosip_event_t *ev){ return process_authentication(sal,ev); } break; + case EXOSIP_CALL_MESSAGE_ANSWERED: + ms_message("EXOSIP_CALL_MESSAGE_ANSWERED "); + process_in_call_reply(sal,ev); + break; case EXOSIP_IN_SUBSCRIPTION_NEW: ms_message("CALL_IN_SUBSCRIPTION_NEW "); sal_exosip_subscription_recv(sal,ev); diff --git a/coreapi/sal_eXosip2.h b/coreapi/sal_eXosip2.h index 75dd7e58c..f85ddfa1c 100644 --- a/coreapi/sal_eXosip2.h +++ b/coreapi/sal_eXosip2.h @@ -66,6 +66,7 @@ struct SalOp{ char *replaces; char *referred_by; const SalAuthInfo *auth_info; + const char *sipfrag_pending; bool_t supports_session_timers; bool_t sdp_offering; bool_t reinvite; diff --git a/oRTP b/oRTP index 5e7a3b571..41d13b7e4 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 5e7a3b571a073cab29e52634c11f780d7008e0e8 +Subproject commit 41d13b7e491c7fc418987b63ff6ef80c7e8895a4