add new states LinphoneCallEarlyUpdating and LinphoneCallEarlyUpdatedByRemote to properly handle the early dialog UPDATE scenarios.

fix test suite.
This commit is contained in:
Simon Morlat 2014-10-20 15:09:48 +02:00
parent 7126c413a7
commit 965add9d6e
10 changed files with 67 additions and 31 deletions

View file

@ -411,6 +411,7 @@ 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);
SalMediaDescription *md;
bool_t update_state=TRUE;
if (call==NULL){
ms_warning("No call to accept.");
@ -433,12 +434,21 @@ static void call_accepted(SalOp *op){
if (md) /*make sure re-invite will not propose video again*/
call->params->has_video &= linphone_core_media_description_contains_video_stream(md);
if (call->state==LinphoneCallOutgoingProgress ||
call->state==LinphoneCallOutgoingRinging ||
call->state==LinphoneCallOutgoingEarlyMedia){
linphone_call_set_state(call,LinphoneCallConnected,"Connected");
if (call->referer) linphone_core_notify_refer_state(lc,call->referer,call);
switch (call->state){
case LinphoneCallOutgoingProgress:
case LinphoneCallOutgoingRinging:
case LinphoneCallOutgoingEarlyMedia:
linphone_call_set_state(call,LinphoneCallConnected,"Connected");
if (call->referer) linphone_core_notify_refer_state(lc,call->referer,call);
break;
case LinphoneCallEarlyUpdating:
linphone_call_set_state(call,call->prevstate,"Early update accepted");
update_state=FALSE;
break;
default:
break;
}
if (md && !sal_media_description_empty(md) && !linphone_core_incompatible_security(lc,md)){
linphone_call_update_remote_session_id_and_ver(call);
if (sal_media_description_has_dir(md,SalStreamSendOnly) ||
@ -451,7 +461,7 @@ static void call_accepted(SalOp *op){
ms_free(msg);
}
linphone_core_update_streams (lc,call,md);
linphone_call_set_state(call,LinphoneCallPaused,"Call paused");
if (update_state) linphone_call_set_state(call,LinphoneCallPaused,"Call paused");
if (call->refer_pending)
linphone_core_start_refered_call(lc,call,NULL);
}else if (sal_media_description_has_dir(md,SalStreamRecvOnly)){
@ -464,7 +474,7 @@ static void call_accepted(SalOp *op){
ms_free(msg);
}
linphone_core_update_streams (lc,call,md);
linphone_call_set_state(call,LinphoneCallPausedByRemote,"Call paused by remote");
if (update_state) linphone_call_set_state(call,LinphoneCallPausedByRemote,"Call paused by remote");
}else{
if (call->state!=LinphoneCallUpdating){
if (call->state==LinphoneCallResuming){
@ -485,8 +495,7 @@ static void call_accepted(SalOp *op){
linphone_call_fix_call_parameters(call);
if (!call->current_params->in_conference)
lc->current_call=call;
if (call->prevstate != LinphoneCallIncomingEarlyMedia) /*don't change state in aswer to a SIP UPDATE in early media*/
linphone_call_set_state(call, LinphoneCallStreamsRunning, "Streams running");
if (update_state) linphone_call_set_state(call, LinphoneCallStreamsRunning, "Streams running");
}
}else{
/*send a bye*/
@ -570,7 +579,8 @@ static void call_updated_by_remote(LinphoneCore *lc, LinphoneCall *call, bool_t
if (rmd==NULL)
call->expect_media_in_ack=TRUE;
} else if (is_update){ /*SIP UPDATE case, can occur in early states*/
_linphone_core_accept_call_update(lc,call,NULL,call->state,linphone_call_state_to_string(call->state));
linphone_call_set_state(call, LinphoneCallEarlyUpdatedByRemote, "EarlyUpdatedByRemote");
_linphone_core_accept_call_update(lc,call,NULL,call->prevstate,linphone_call_state_to_string(call->prevstate));
}
}
@ -627,6 +637,8 @@ static void call_updating(SalOp *op, bool_t is_update){
case LinphoneCallRefered:
case LinphoneCallError:
case LinphoneCallReleased:
case LinphoneCallEarlyUpdatedByRemote:
case LinphoneCallEarlyUpdating:
ms_warning("Receiving reINVITE or UPDATE while in state [%s], should not happen.",linphone_call_state_to_string(call->state));
break;
}

View file

@ -924,6 +924,10 @@ const char *linphone_call_state_to_string(LinphoneCallState cs){
return "LinphoneCallUpdating";
case LinphoneCallReleased:
return "LinphoneCallReleased";
case LinphoneCallEarlyUpdatedByRemote:
return "LinphoneCallEarlyUpdatedByRemote";
case LinphoneCallEarlyUpdating:
return "LinphoneCallEarlyUpdating";
}
return "undefined state";
}

View file

@ -3281,15 +3281,20 @@ int linphone_core_start_update_call(LinphoneCore *lc, LinphoneCall *call){
**/
int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params){
int err=0;
LinphoneCallState nextstate;
#if defined(VIDEO_ENABLED) && defined(BUILD_UPNP)
bool_t has_video = FALSE;
#endif
switch(call->state){
case LinphoneCallIncomingEarlyMedia:
case LinphoneCallIncomingReceived:
case LinphoneCallIncomingEarlyMedia:
case LinphoneCallOutgoingRinging:
case LinphoneCallOutgoingEarlyMedia:
nextstate=LinphoneCallEarlyUpdating;
break;
case LinphoneCallStreamsRunning:
/*these states are allowed for linphone_core_update_call()*/
nextstate=LinphoneCallUpdating;
break;
default:
ms_error("linphone_core_update_call() is not allowed in [%s] state",linphone_call_state_to_string(call->state));
@ -3297,7 +3302,7 @@ int linphone_core_update_call(LinphoneCore *lc, LinphoneCall *call, const Linpho
}
if (params!=NULL){
linphone_call_set_state(call,LinphoneCallUpdating,"Updating call");
linphone_call_set_state(call,nextstate,"Updating call");
#if defined(VIDEO_ENABLED) && defined(BUILD_UPNP)
has_video = call->params->has_video;
@ -6413,6 +6418,7 @@ LinphoneCallParams *linphone_core_create_default_call_parameters(LinphoneCore *l
* @param lc the LinphoneCore
* @param call the call for which the parameters are to be build, or NULL in the case where the parameters are to be used for a new outgoing call.
* @return a new LinphoneCallParams
* @ingroup call_control
*/
LinphoneCallParams *linphone_core_create_call_params(LinphoneCore *lc, LinphoneCall *call){
if (!call) return linphone_core_create_default_call_parameters(lc);

View file

@ -638,7 +638,9 @@ typedef enum _LinphoneCallState{
LinphoneCallUpdatedByRemote, /**<The call's parameters change is requested by remote end, used for example when video is added by remote */
LinphoneCallIncomingEarlyMedia, /**<We are proposing early media to an incoming call */
LinphoneCallUpdating, /**<A call update has been initiated by us */
LinphoneCallReleased /**< The call object is no more retained by the core */
LinphoneCallReleased, /**< The call object is no more retained by the core */
LinphoneCallEarlyUpdatedByRemote, /*<The call is updated by remote while not yet answered (early dialog SIP UPDATE received).*/
LinphoneCallEarlyUpdating /*<We are updating the call while not yet answered (early dialog SIP UPDATE sent)*/
} LinphoneCallState;
LINPHONE_PUBLIC const char *linphone_call_state_to_string(LinphoneCallState cs);

View file

@ -119,6 +119,15 @@ public interface LinphoneCall {
*/
public static final State CallReleased = new State(18,"Released");
/**
* The call is updated by remote while not yet answered (SIP UPDATE in early dialog received)
*/
public static final State CallEarlyUpdatedByRemote = new State(19,"EarlyUpdatedByRemote");
/**
* We are updating the call while not yet answered (SIP UPDATE in early dialog sent)
**/
public static final State CallEarlyUpdating = new State(20,"EarlyUpdating");
private State(int value,String stringValue) {
mValue = value;

@ -1 +1 @@
Subproject commit c644583841f98744689096305ae9dc1156043aee
Subproject commit c5b6a6df8c5ccad06e34e6d09410cf8c15d32cf7

2
oRTP

@ -1 +1 @@
Subproject commit 7ded70711a9201591db13f06ab0b69ba4d89f992
Subproject commit 4077e127ee731b0797a9303d55f0d61bcb947bf8

View file

@ -73,6 +73,8 @@ void call_state_changed(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState
case LinphoneCallIncomingEarlyMedia :counters->number_of_LinphoneCallIncomingEarlyMedia++;break;
case LinphoneCallUpdating :counters->number_of_LinphoneCallUpdating++;break;
case LinphoneCallReleased :counters->number_of_LinphoneCallReleased++;break;
case LinphoneCallEarlyUpdating: counters->number_of_LinphoneCallEarlyUpdating++;break;
case LinphoneCallEarlyUpdatedByRemote: counters->number_of_LinphoneCallEarlyUpdatedByRemote++;break;
default:
CU_FAIL("unexpected event");break;
}
@ -1906,7 +1908,9 @@ static void call_with_file_player(void) {
snprintf(hellopath,sizeof(hellopath), "%s/sounds/hello8000.wav", liblinphone_tester_file_prefix);
/*caller uses soundcard*/
/*caller uses files instead of soundcard in order to avoid mixing soundcard input with file played using call's player*/
linphone_core_use_files(pauline->lc,TRUE);
linphone_core_set_play_file(pauline->lc,NULL);
/*callee is recording and plays file*/
linphone_core_use_files(pauline->lc,TRUE);
@ -1963,8 +1967,9 @@ static void call_with_mkv_file_player(void) {
snprintf(hellowav,sizeof(hellowav), "%s/sounds/hello8000.wav", liblinphone_tester_file_prefix);
snprintf(hellomkv,sizeof(hellomkv), "%s/sounds/hello8000.mkv", liblinphone_tester_file_prefix);
/*caller uses soundcard*/
/*caller uses files instead of soundcard in order to avoid mixing soundcard input with file played using call's player*/
linphone_core_use_files(pauline->lc,TRUE);
linphone_core_set_play_file(pauline->lc,NULL);
/*callee is recording and plays file*/
linphone_core_use_files(pauline->lc,TRUE);
linphone_core_set_play_file(pauline->lc,hellowav); /*just to send something but we are not testing what is sent by pauline*/
@ -1985,7 +1990,7 @@ static void call_with_mkv_file_player(void) {
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallEnd,1));
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneCallEnd,1));
CU_ASSERT_TRUE(ms_audio_diff(hellowav,recordpath,&similar,NULL,NULL)==0);
CU_ASSERT_TRUE(similar>0.9);
CU_ASSERT_TRUE(similar>0.6);
CU_ASSERT_TRUE(similar<=1.0);
ms_free(recordpath);
@ -2185,7 +2190,6 @@ static void early_media_call_with_update_base(bool_t media_change){
if (media_change) {
disable_all_audio_codecs_except_one(marie->lc,"pcmu",-1);
disable_all_audio_codecs_except_one(pauline->lc,"pcmu",-1);
}
/*
Marie calls Pauline, and after the call has rung, transitions to an early_media session
@ -2216,26 +2220,23 @@ static void early_media_call_with_update_base(bool_t media_change){
linphone_call_params_set_session_name(pauline_params,UPDATED_SESSION_NAME);
linphone_core_update_call(pauline->lc, pauline_call, pauline_params);
CU_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallEarlyUpdating,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallEarlyUpdatedByRemote,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallOutgoingEarlyMedia,1,2000));
CU_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallIncomingEarlyMedia,1,2000));
/*just to wait 2s*/
liblinphone_tester_check_rtcp(marie, pauline);
wait_for_list(lcs, &marie->stat.number_of_LinphoneCallUpdatedByRemote,100000,2000);
CU_ASSERT_STRING_EQUAL( linphone_call_params_get_session_name(linphone_call_get_remote_params(marie_call))
, UPDATED_SESSION_NAME);
linphone_core_accept_call(pauline->lc, linphone_core_get_current_call(pauline->lc));
CU_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallConnected, 1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallStreamsRunning, 1,1000));
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallOutgoingEarlyMedia,1);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallStreamsRunning,1);
CU_ASSERT_EQUAL(marie->stat.number_of_LinphoneCallConnected,1);
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallIncomingEarlyMedia,1);
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallStreamsRunning,1);
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallConnected,1);
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallUpdating,1);
CU_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallConnected, 1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1,1000));
liblinphone_tester_check_rtcp(marie, pauline);

View file

@ -116,6 +116,8 @@ typedef struct _stats {
int number_of_LinphoneCallIncomingEarlyMedia;
int number_of_LinphoneCallUpdating;
int number_of_LinphoneCallReleased;
int number_of_LinphoneCallEarlyUpdatedByRemote;
int number_of_LinphoneCallEarlyUpdating;
int number_of_LinphoneTransferCallOutgoingInit;
int number_of_LinphoneTransferCallOutgoingProgress;

Binary file not shown.