diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index 14ea90b56..49a12cd00 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -198,8 +198,8 @@ static void call_response_event(void *op_base, const belle_sip_response_event_t op->sdp_answer=NULL; } belle_sip_dialog_send_ack(op->dialog,ack); - /*if (op->state != SalOpStateActive)*/ - op->base.root->callbacks.call_accepted(op); + op->base.root->callbacks.call_accepted(op); /*INVITE*/ + op->state=SalOpStateActive; } else { /*nop*/ diff --git a/coreapi/bellesip_sal/sal_op_call_transfer.c b/coreapi/bellesip_sal/sal_op_call_transfer.c index d8823afa8..8dd289414 100644 --- a/coreapi/bellesip_sal/sal_op_call_transfer.c +++ b/coreapi/bellesip_sal/sal_op_call_transfer.c @@ -58,19 +58,26 @@ int sal_call_refer(SalOp *op, const char *refer_to){ } int sal_call_refer_with_replaces(SalOp *op, SalOp *other_call_op){ - belle_sip_dialog_state_t other_call_dialod_state=other_call_op->dialog?belle_sip_dialog_get_state(other_call_op->dialog):BELLE_SIP_DIALOG_NULL; + belle_sip_dialog_state_t other_call_dialog_state=other_call_op->dialog?belle_sip_dialog_get_state(other_call_op->dialog):BELLE_SIP_DIALOG_NULL; + belle_sip_dialog_state_t op_dialog_state=op->dialog?belle_sip_dialog_get_state(op->dialog):BELLE_SIP_DIALOG_NULL; + belle_sip_header_refer_to_t* refer_to; belle_sip_header_referred_by_t* referred_by; /*first, build refer to*/ - if (other_call_dialod_state!=BELLE_SIP_DIALOG_CONFIRMED) { - ms_error(" wrong dialog state [%s] for op [%p], sould be BELLE_SIP_DIALOG_CONFIRMED",belle_sip_dialog_state_to_string(other_call_dialod_state) + if (other_call_dialog_state!=BELLE_SIP_DIALOG_CONFIRMED) { + ms_error(" wrong dialog state [%s] for op [%p], should be BELLE_SIP_DIALOG_CONFIRMED",belle_sip_dialog_state_to_string(other_call_dialog_state) ,other_call_op); return -1; - } else { - refer_to=belle_sip_header_refer_to_create(belle_sip_dialog_get_remote_party(other_call_op->dialog)); - referred_by=belle_sip_header_referred_by_create(belle_sip_dialog_get_local_party(op->dialog)); } + if (op_dialog_state!=BELLE_SIP_DIALOG_CONFIRMED) { + ms_error(" wrong dialog state [%s] for op [%p], should be BELLE_SIP_DIALOG_CONFIRMED",belle_sip_dialog_state_to_string(op_dialog_state) + ,op); + return -1; + } + + refer_to=belle_sip_header_refer_to_create(belle_sip_dialog_get_remote_party(other_call_op->dialog)); + referred_by=belle_sip_header_referred_by_create(belle_sip_dialog_get_local_party(op->dialog)); return sal_call_refer_to(op,refer_to,referred_by); } int sal_call_accept_refer(SalOp *h){ diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index dfb6fa312..ba495f41d 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -508,14 +508,21 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro call->core=lc; if (lc->sip_conf.ping_with_options){ - /*the following sends an option request back to the caller so that - we get a chance to discover our nat'd address before answering.*/ - call->ping_op=sal_op_new(lc->sal); - from_str=linphone_address_as_string_uri_only(from); - sal_op_set_route(call->ping_op,sal_op_get_network_origin(op)); - sal_op_set_user_pointer(call->ping_op,call); - sal_ping(call->ping_op,linphone_core_find_best_identity(lc,from,NULL),from_str); - ms_free(from_str); +#ifdef BUILD_UPNP + if (lc->upnp != NULL && linphone_core_get_firewall_policy(lc)==LinphonePolicyUseUpnp && + linphone_upnp_context_get_state(lc->upnp) == LinphoneUpnpStateOk) { +#else //BUILD_UPNP + { +#endif //BUILD_UPNP + /*the following sends an option request back to the caller so that + we get a chance to discover our nat'd address before answering.*/ + call->ping_op=sal_op_new(lc->sal); + from_str=linphone_address_as_string_uri_only(from); + sal_op_set_route(call->ping_op,sal_op_get_network_origin(op)); + sal_op_set_user_pointer(call->ping_op,call); + sal_ping(call->ping_op,linphone_core_find_best_identity(lc,from,NULL),from_str); + ms_free(from_str); + } } linphone_address_clean(from); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 8f3a6e289..8dcdddf03 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -669,6 +669,9 @@ static void sip_config_read(LinphoneCore *lc) tmp=lp_config_get_int(lc->config,"sip","in_call_timeout",0); linphone_core_set_in_call_timeout(lc,tmp); + + tmp=lp_config_get_int(lc->config,"sip","delayed_timeout",4); + linphone_core_set_delayed_timeout(lc,tmp); /* get proxies config */ for(i=0;; i++){ @@ -2099,7 +2102,7 @@ void linphone_core_iterate(LinphoneCore *lc){ linphone_core_start_invite() */ calls=calls->next; linphone_call_background_tasks(call,one_second_elapsed); - if (call->state==LinphoneCallOutgoingInit && (elapsed>=4)){ + if (call->state==LinphoneCallOutgoingInit && (elapsed>=lc->sip_conf.delayed_timeout)){ /*start the call even if the OPTIONS reply did not arrive*/ if (call->ice_session != NULL) { ms_warning("ICE candidates gathering from [%s] has not finished yet, proceed with the call without ICE anyway." @@ -2655,15 +2658,23 @@ LinphoneCall * linphone_core_invite_address_with_params(LinphoneCore *lc, const } if (call->dest_proxy==NULL && lc->sip_conf.ping_with_options==TRUE){ - /*defer the start of the call after the OPTIONS ping*/ - call->ping_replied=FALSE; - call->ping_op=sal_op_new(lc->sal); - sal_ping(call->ping_op,from,real_url); - sal_op_set_user_pointer(call->ping_op,call); - call->start_time=time(NULL); - }else{ - if (defer==FALSE) linphone_core_start_invite(lc,call); +#ifdef BUILD_UPNP + if (lc->upnp != NULL && linphone_core_get_firewall_policy(lc)==LinphonePolicyUseUpnp && + linphone_upnp_context_get_state(lc->upnp) == LinphoneUpnpStateOk) { +#else //BUILD_UPNP + { +#endif //BUILD_UPNP + /*defer the start of the call after the OPTIONS ping*/ + call->ping_replied=FALSE; + call->ping_op=sal_op_new(lc->sal); + sal_ping(call->ping_op,from,real_url); + sal_op_set_user_pointer(call->ping_op,call); + call->start_time=time(NULL); + defer = TRUE; + } } + + if (defer==FALSE) linphone_core_start_invite(lc,call); if (real_url!=NULL) ms_free(real_url); return call; @@ -3547,6 +3558,26 @@ int linphone_core_get_in_call_timeout(LinphoneCore *lc){ return lc->sip_conf.in_call_timeout; } +/** + * Returns the delayed timeout + * + * @ingroup call_control + * See linphone_core_set_delayed_timeout() for details. +**/ +int linphone_core_get_delayed_timeout(LinphoneCore *lc){ + return lc->sip_conf.delayed_timeout; +} + +/** + * Set the in delayed timeout in seconds. + * + * @ingroup call_control + * After this timeout period, a delayed call (internal call initialisation or resolution) is resumed. +**/ +void linphone_core_set_delayed_timeout(LinphoneCore *lc, int seconds){ + lc->sip_conf.delayed_timeout=seconds; +} + void linphone_core_set_presence_info(LinphoneCore *lc,int minutes_away, const char *contact, LinphoneOnlineStatus presence_mode) @@ -5072,6 +5103,7 @@ void sip_config_uninit(LinphoneCore *lc) lp_config_set_string(lc->config,"sip","contact",config->contact); lp_config_set_int(lc->config,"sip","inc_timeout",config->inc_timeout); lp_config_set_int(lc->config,"sip","in_call_timeout",config->in_call_timeout); + lp_config_set_int(lc->config,"sip","delayed_timeout",config->delayed_timeout); lp_config_set_int(lc->config,"sip","use_info",config->use_info); lp_config_set_int(lc->config,"sip","use_rfc2833",config->use_rfc2833); lp_config_set_int(lc->config,"sip","use_ipv6",config->ipv6_enabled); diff --git a/coreapi/linphonecore.h b/coreapi/linphonecore.h index 774ef925b..78193aaa0 100644 --- a/coreapi/linphonecore.h +++ b/coreapi/linphonecore.h @@ -1099,6 +1099,10 @@ void linphone_core_set_in_call_timeout(LinphoneCore *lc, int seconds); int linphone_core_get_in_call_timeout(LinphoneCore *lc); +void linphone_core_set_delayed_timeout(LinphoneCore *lc, int seconds); + +int linphone_core_get_delayed_timeout(LinphoneCore *lc); + void linphone_core_set_stun_server(LinphoneCore *lc, const char *server); const char * linphone_core_get_stun_server(const LinphoneCore *lc); diff --git a/coreapi/private.h b/coreapi/private.h index 9c6cc85f0..861790e4b 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -427,6 +427,7 @@ typedef struct sip_config MSList *deleted_proxies; int inc_timeout; /*timeout after an un-answered incoming call is rejected*/ int in_call_timeout; /*timeout after a call is hangup */ + int delayed_timeout; /*timeout after a delayed call is resumed */ unsigned int keepalive_period; /* interval in ms between keep alive messages sent to the proxy server*/ LCSipTransports transports; bool_t use_info; diff --git a/mediastreamer2 b/mediastreamer2 index 73a772ac4..756a51419 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 73a772ac4754734c57ecbc1149cbe665acd2f376 +Subproject commit 756a51419d833105a6378db71679073f6e9492b0 diff --git a/tester/call_tester.c b/tester/call_tester.c index 42148cbf6..c68ec96ab 100644 --- a/tester/call_tester.c +++ b/tester/call_tester.c @@ -259,8 +259,9 @@ static void call_paused_resumed() { call_obj = linphone_core_get_current_call(pauline->lc); linphone_core_pause_call(pauline->lc,call_obj); - CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallPaused,1)); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallPausing,1)); CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallPausedByRemote,1)); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallPaused,1)); linphone_core_resume_call(pauline->lc,call_obj); CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2)); @@ -295,8 +296,9 @@ static void call_paused_resumed_from_callee() { call_obj = linphone_core_get_current_call(marie->lc); linphone_core_pause_call(marie->lc,call_obj); - CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallPaused,1)); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallPausing,1)); CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallPausedByRemote,1)); + CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallPaused,1)); linphone_core_resume_call(marie->lc,call_obj); CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2)); @@ -508,6 +510,7 @@ static void call_transfer_existing_call_outgoing_call() { LinphoneCoreManager* laure = linphone_core_manager_new("./tester/laure_rc"); MSList* lcs=ms_list_append(NULL,marie->lc); + const MSList* calls; lcs=ms_list_append(lcs,pauline->lc); lcs=ms_list_append(lcs,laure->lc); @@ -538,13 +541,25 @@ static void call_transfer_existing_call_outgoing_call() { linphone_core_transfer_call_to_another(marie->lc,marie_call_pauline,marie_call_laure); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallRefered,1,2000)); + /*pauline pausing marie*/ + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallPausing,1,2000)); + CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallPaused,1,2000)); /*pauline calling laure*/ CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingProgress,1,2000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransferCallOutgoingInit,1,2000)); CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallIncomingReceived,1,2000)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallOutgoingRinging,1,2000)); CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneTransfertCallOutgoingProgress,1,2000)); - linphone_core_accept_call(laure->lc,linphone_core_get_current_call(laure->lc)); + + /*laure accept call*/ + for(calls=linphone_core_get_calls(laure->lc);calls!=NULL;calls=calls->next) { + LinphoneCall* call = (LinphoneCall*)calls->data; + if (linphone_call_get_state(call) == LinphoneCallIncomingReceived) { + CU_ASSERT_EQUAL(linphone_call_get_replaced_call(call),laure_called_by_marie); + linphone_core_accept_call(laure->lc,call); + break; + } + } CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallConnected,1,2000)); CU_ASSERT_TRUE(wait_for_list(lcs,&laure->stat.number_of_LinphoneCallStreamsRunning,1,2000)); CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallConnected,1,2000));