Commit 260e7e1d authored by jehan's avatar jehan

minimal SIP UPDATE support

parent 36a124d2
......@@ -28,6 +28,9 @@
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.306286573" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
<tool id="org.eclipse.cdt.build.core.settings.holder.391709798" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder">
<option id="org.eclipse.cdt.build.core.settings.holder.incpaths.295320884" name="Include Paths" superClass="org.eclipse.cdt.build.core.settings.holder.incpaths" valueType="includePath">
<listOptionValue builtIn="false" value="/Users/jehanmonnier/workspaces/workspace-macosx/opt/include"/>
</option>
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1702094818" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
<tool id="org.eclipse.cdt.build.core.settings.holder.754828354" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder">
......@@ -36,9 +39,24 @@
</toolChain>
</folderInfo>
<fileInfo id="0.2079208171.2090246372" name="ringback.wav" rcbsApplicability="disable" resourcePath="tester/sounds/ringback.wav" toolsToInvoke=""/>
<folderInfo id="0.2079208171.1778481546" name="/" resourcePath="include">
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.1238844827" name="No ToolChain" superClass="org.eclipse.cdt.build.core.prefbase.toolchain" unusedChildren="">
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.58439860" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs.1252970003"/>
<tool id="org.eclipse.cdt.build.core.settings.holder.899998629" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder.1371414073">
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.1829150855" languageId="org.eclipse.cdt.core.g++" languageName="GNU C++" sourceContentType="org.eclipse.cdt.core.cxxSource,org.eclipse.cdt.core.cxxHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
<tool id="org.eclipse.cdt.build.core.settings.holder.252709365" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder.391709798">
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.551083583" languageId="org.eclipse.cdt.core.gcc" languageName="GNU C" sourceContentType="org.eclipse.cdt.core.cSource,org.eclipse.cdt.core.cHeader" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
<tool id="org.eclipse.cdt.build.core.settings.holder.1236597953" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder.754828354">
<inputType id="org.eclipse.cdt.build.core.settings.holder.inType.714781911" languageId="org.eclipse.cdt.core.assembly" languageName="Assembly" sourceContentType="org.eclipse.cdt.core.asmSource" superClass="org.eclipse.cdt.build.core.settings.holder.inType"/>
</tool>
</toolChain>
</folderInfo>
<sourceEntries>
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="coreapi"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="gtk"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="include"/>
<entry flags="VALUE_WORKSPACE_PATH" kind="sourcePath" name="tester"/>
</sourceEntries>
</configuration>
......
......@@ -246,7 +246,9 @@ static void process_request_event(void *ud, const belle_sip_request_event_t *eve
return;
}else {
ms_error("sal process_request_event not implemented yet for method [%s]",belle_sip_request_get_method(req));
resp=belle_sip_response_create_from_request(req,501);
resp=belle_sip_response_create_from_request(req,405);
belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp)
,BELLE_SIP_HEADER(belle_sip_header_allow_create("INVITE, CANCEL, ACK, BYE, SUBSCRIBE, NOTIFY, MESSAGE, OPTIONS, INFO")));
belle_sip_provider_send_response(sal->prov,resp);
return;
}
......
......@@ -79,6 +79,7 @@ struct SalOp{
belle_sip_listener_callbacks_t callbacks;
belle_sip_client_transaction_t *pending_auth_transaction;
belle_sip_server_transaction_t* pending_server_trans;
belle_sip_server_transaction_t* pending_update_server_trans;
belle_sip_client_transaction_t* pending_client_trans;
SalAuthInfo* auth_info;
belle_sip_dialog_t* dialog;
......
......@@ -226,6 +226,11 @@ static void call_process_response(void *op_base, const belle_sip_response_event_
call_set_error(op,response);
if (op->dialog==NULL) call_set_released(op);
}
} else if ( code >=200
&& code<300
&& strcmp("UPDATE",belle_sip_request_get_method(req))==0) {
handle_sdp_from_response(op,response);
op->base.root->callbacks.call_accepted(op);
}
}
break;
......@@ -384,6 +389,16 @@ static int process_sdp_for_invite(SalOp* op,belle_sip_request_t* invite) {
return err;
}
static void sal_op_reset_descriptions(SalOp *op) {
if (op->base.remote_media){
sal_media_description_unref(op->base.remote_media);
op->base.remote_media=NULL;
}
if (op->result){
sal_media_description_unref(op->result);
op->result=NULL;
}
}
static void process_request_event(void *op_base, const belle_sip_request_event_t *event) {
SalOp* op = (SalOp*)op_base;
belle_sip_server_transaction_t* server_transaction=NULL;
......@@ -408,6 +423,13 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
belle_sip_object_ref(op->pending_server_trans);
}
if (strcmp("UPDATE",method)==0) {
if (op->pending_update_server_trans) belle_sip_object_unref(op->pending_update_server_trans);
/*updating pending update transaction*/
op->pending_update_server_trans=server_transaction;
belle_sip_object_ref(op->pending_update_server_trans);
}
if (!op->dialog) {
set_or_update_dialog(op,belle_sip_provider_create_dialog(op->base.root->prov,BELLE_SIP_TRANSACTION(op->pending_server_trans)));
ms_message("new incoming call from [%s] to [%s]",sal_op_get_from(op),sal_op_get_to(op));
......@@ -455,6 +477,10 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
} else if (strcmp("PRACK",method)==0) {
resp=sal_op_create_response_from_request(op,req,200);
belle_sip_server_transaction_send_response(server_transaction,resp);
} else if (strcmp("UPDATE",method)==0) {
sal_op_reset_descriptions(op);
if (process_sdp_for_invite(op,req)==0)
op->base.root->callbacks.call_updating(op);
} else {
belle_sip_error("Unexpected method [%s] for dialog state BELLE_SIP_DIALOG_EARLY",belle_sip_request_get_method(req));
unsupported_method(server_transaction,req);
......@@ -479,10 +505,6 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
}
}
}
/*FIXME
if (op->reinvite){
op->reinvite=FALSE;
}*/
op->base.root->callbacks.call_ack(op);
} else if(strcmp("BYE",method)==0) {
resp=sal_op_create_response_from_request(op,req,200);
......@@ -492,14 +514,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
/*call end not notified by dialog deletion because transaction can end before dialog*/
} else if(strcmp("INVITE",method)==0) {
/*re-invite*/
if (op->base.remote_media){
sal_media_description_unref(op->base.remote_media);
op->base.remote_media=NULL;
}
if (op->result){
sal_media_description_unref(op->result);
op->result=NULL;
}
sal_op_reset_descriptions(op);
if (process_sdp_for_invite(op,req)==0)
op->base.root->callbacks.call_updating(op);
} else if (strcmp("INFO",method)==0){
......@@ -576,7 +591,7 @@ int sal_call_set_local_media_description(SalOp *op, SalMediaDescription *desc){
static belle_sip_header_allow_t *create_allow(){
belle_sip_header_allow_t* header_allow;
header_allow = belle_sip_header_allow_create("INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO");
header_allow = belle_sip_header_allow_create("INVITE, ACK, CANCEL, OPTIONS, BYE, REFER, NOTIFY, MESSAGE, SUBSCRIBE, INFO, UPDATE");
return header_allow;
}
......@@ -684,14 +699,21 @@ int sal_call_notify_ringing(SalOp *op, bool_t early_media){
int sal_call_accept(SalOp*h){
belle_sip_response_t *response;
belle_sip_header_contact_t* contact_header;
if (!h->pending_server_trans) {
belle_sip_server_transaction_t* transaction;
/*first check if an UPDATE transaction need to be accepted*/
if (h->pending_update_server_trans) {
transaction=h->pending_update_server_trans;
} else if (h->pending_server_trans) {
/*so it must be an invite/re-invite*/
transaction=h->pending_server_trans;
} else {
ms_error("No transaction to accept for op [%p]",h);
return -1;
}
ms_message("Accepting server transaction [%p] on op [%p]", transaction, h);
/* sends a 200 OK */
response = sal_op_create_response_from_request(h,belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(h->pending_server_trans)),200);
response = sal_op_create_response_from_request(h,belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(transaction)),200);
if (response==NULL){
ms_error("Fail to build answer for call");
......@@ -712,7 +734,11 @@ int sal_call_accept(SalOp*h){
handle_offer_answer_response(h,response);
belle_sip_server_transaction_send_response(h->pending_server_trans,response);
belle_sip_server_transaction_send_response(transaction,response);
if (h->pending_update_server_trans) {
belle_sip_object_unref(h->pending_update_server_trans);
h->pending_update_server_trans=NULL;
}
return 0;
}
......@@ -738,11 +764,22 @@ int sal_call_decline(SalOp *op, SalReason reason, const char *redirection /*opti
}
int sal_call_update(SalOp *op, const char *subject){
belle_sip_request_t *reinvite=belle_sip_dialog_create_request(op->dialog,"INVITE");
if (reinvite){
belle_sip_message_add_header(BELLE_SIP_MESSAGE(reinvite),belle_sip_header_create( "Subject", subject));
sal_op_fill_invite(op, reinvite);
return sal_op_send_request(op,reinvite);
belle_sip_request_t *update;
belle_sip_dialog_state_t state=belle_sip_dialog_get_state(op->dialog);
/*check for dialog state*/
if ( state == BELLE_SIP_DIALOG_CONFIRMED) {
update=belle_sip_dialog_create_request(op->dialog,"INVITE");
} else if (state == BELLE_SIP_DIALOG_EARLY) {
update=belle_sip_dialog_create_request(op->dialog,"UPDATE");
} else {
ms_error("Cannot update op [%p] with dialog [%p] in state [%s]",op, op->dialog,belle_sip_dialog_state_to_string(state));
return -1;
}
if (update){
belle_sip_message_add_header(BELLE_SIP_MESSAGE(update),belle_sip_header_create( "Subject", subject));
sal_op_fill_invite(op, update);
return sal_op_send_request(op,update);
}
return -1;
}
......
......@@ -60,6 +60,7 @@ void sal_op_release_impl(SalOp *op){
if (op->pending_client_trans) belle_sip_object_unref(op->pending_client_trans);
if (op->pending_server_trans) belle_sip_object_unref(op->pending_server_trans);
if (op->pending_update_server_trans) belle_sip_object_unref(op->pending_update_server_trans);
if (op->event) belle_sip_object_unref(op->event);
__sal_op_free(op);
return ;
......
......@@ -116,7 +116,7 @@ void linphone_core_update_streams(LinphoneCore *lc, LinphoneCall *call, SalMedia
video_stream_change_camera(call->videostream,lc->video_conf.device );
#endif
}
/*FIXME ZRTP might be restarted in any cases ? */
/*FIXME ZRTP, might be restarted in any cases ? */
ms_message("No need to restart streams, SDP is unchanged.");
goto end;
}else {
......@@ -407,7 +407,8 @@ static void call_accepted(SalOp *op){
linphone_call_fix_call_parameters(call);
if (!call->current_params.in_conference)
lc->current_call=call;
linphone_call_set_state(call, LinphoneCallStreamsRunning, "Streams running");
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");
}
}else{
/*send a bye*/
......@@ -473,7 +474,7 @@ static void call_paused_by_remote(LinphoneCore *lc, LinphoneCall *call){
linphone_call_set_state (call,LinphoneCallPausedByRemote,"Call paused by remote");
}
static void call_updated_by_remote(LinphoneCore *lc, LinphoneCall *call){
static void call_updated_by_remote(LinphoneCore *lc, LinphoneCall *call,bool_t notify_application){
/*first check if media capabilities are compatible*/
SalMediaDescription* md;
linphone_call_make_local_media_description(lc,call);
......@@ -484,16 +485,21 @@ static void call_updated_by_remote(LinphoneCore *lc, LinphoneCall *call){
return;
}
if(lc->vtable.display_status)
lc->vtable.display_status(lc,_("Call is updated by remote."));
call->defer_update=FALSE;
linphone_call_set_state(call, LinphoneCallUpdatedByRemote,"Call updated by remote");
if (call->defer_update==FALSE){
linphone_core_accept_call_update(lc,call,NULL);
if (notify_application) {
if(lc->vtable.display_status)
lc->vtable.display_status(lc,_("Call is updated by remote."));
call->defer_update=FALSE;
linphone_call_set_state(call, LinphoneCallUpdatedByRemote,"Call updated by remote");
if (call->defer_update==FALSE){
linphone_core_accept_call_update(lc,call,NULL);
}
} else { /*SIP UPDATE case*/
/*can be call from any state*/
_linphone_core_accept_call_update(lc,call,NULL);
}
}
/* this callback is called when an incoming re-INVITE modifies the session*/
/* this callback is called when an incoming re-INVITE/ SIP UPDATE modifies the session*/
static void call_updating(SalOp *op){
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
......@@ -512,12 +518,16 @@ static void call_updating(SalOp *op){
call_resumed(lc,call);
}else call_paused_by_remote(lc,call);
break;
/*SIP UPDATE CASE*/
case LinphoneCallOutgoingEarlyMedia:
call_updated_by_remote(lc,call,FALSE);
break;
case LinphoneCallStreamsRunning:
case LinphoneCallConnected:
if (sal_media_description_has_dir(rmd,SalStreamSendOnly) || sal_media_description_has_dir(rmd,SalStreamInactive)){
call_paused_by_remote(lc,call);
}else{
call_updated_by_remote(lc,call);
call_updated_by_remote(lc,call,TRUE);
}
break;
default:
......
......@@ -3231,23 +3231,25 @@ int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call)
linphone_core_update_streams (lc,call,md);
linphone_call_fix_call_parameters(call);
}
linphone_call_set_state(call,LinphoneCallStreamsRunning,"Connected (streams running)");
if (call->state != LinphoneCallOutgoingEarlyMedia) /*don't change the state in case of outgoing early (SIP UPDATE)*/
linphone_call_set_state(call,LinphoneCallStreamsRunning,"Connected (streams running)");
return 0;
}
/**
* @ingroup call_control
* Accept call modifications initiated by other end.
*
*
* This call may be performed in response to a #LinphoneCallUpdatedByRemote state notification.
* When such notification arrives, the application can decide to call linphone_core_defer_update_call() so that it can
* have the time to prompt the user. linphone_call_get_remote_params() can be used to get information about the call parameters
* requested by the other party, such as whether a video stream is requested.
*
*
* When the user accepts or refuse the change, linphone_core_accept_call_update() can be done to answer to the other party.
* If params is NULL, then the same call parameters established before the update request will continue to be used (no change).
* If params is not NULL, then the update will be accepted according to the parameters passed.
* Typical example is when a user accepts to start video, then params should indicate that video stream should be used
* Typical example is when a user accepts to start video, then params should indicate that video stream should be used
* (see linphone_call_params_enable_video()).
* @param lc the linphone core object.
* @param call the LinphoneCall object
......@@ -3255,16 +3257,20 @@ int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call)
* @return 0 if successful, -1 otherwise (actually when this function call is performed outside ot #LinphoneCallUpdatedByRemote state).
**/
int linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params){
SalMediaDescription *remote_desc;
bool_t keep_sdp_version;
#ifdef VIDEO_ENABLED
bool_t old_has_video = call->params.has_video;
#endif
if (call->state!=LinphoneCallUpdatedByRemote){
ms_error("linphone_core_accept_update(): invalid state %s to call this function.",
linphone_call_state_to_string(call->state));
return -1;
}
return _linphone_core_accept_call_update(lc, call, params);
}
int _linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params){
SalMediaDescription *remote_desc;
bool_t keep_sdp_version;
#ifdef VIDEO_ENABLED
bool_t old_has_video = call->params.has_video;
#endif
remote_desc = sal_call_get_remote_media_description(call->op);
keep_sdp_version = lp_config_get_int(lc->config, "sip", "keep_sdp_version", 0);
if (keep_sdp_version &&(remote_desc->session_id == call->remote_session_id) && (remote_desc->session_ver == call->remote_session_ver)) {
......
......@@ -605,7 +605,7 @@ void linphone_tone_description_destroy(LinphoneToneDescription *obj);
LinphoneToneDescription *linphone_core_get_call_error_tone(const LinphoneCore *lc, LinphoneReason reason);
void linphone_core_play_call_error_tone(LinphoneCore *lc, LinphoneReason reason);
void _linphone_core_set_call_error_tone(LinphoneCore *lc, LinphoneReason reason, LinphoneToneID id, const char *audiofile);
int _linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params);
typedef struct _LinphoneConference LinphoneConference;
struct _LinphoneCore
......
......@@ -420,7 +420,7 @@ typedef void (*SalOnCallReceived)(SalOp *op);
typedef void (*SalOnCallRinging)(SalOp *op);
typedef void (*SalOnCallAccepted)(SalOp *op);
typedef void (*SalOnCallAck)(SalOp *op);
typedef void (*SalOnCallUpdating)(SalOp *op);/*< Called when a reINVITE is received*/
typedef void (*SalOnCallUpdating)(SalOp *op);/*< Called when a reINVITE/UPDATE is received*/
typedef void (*SalOnCallTerminated)(SalOp *op, const char *from);
typedef void (*SalOnCallFailure)(SalOp *op, SalError error, SalReason reason, const char *details, int code);
typedef void (*SalOnCallReleased)(SalOp *salop);
......
......@@ -1133,6 +1133,92 @@ static void early_media_call_with_ringing(void){
linphone_core_manager_destroy(pauline);
}
static void early_media_call_with_update_base(bool_t media_change){
char hellopath[256];
LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new("pauline_rc");
MSList* lcs = NULL;
LinphoneCall *marie_call, *pauline_call;
LinphoneCallParams *pauline_params;
lcs = ms_list_append(lcs,marie->lc);
lcs = ms_list_append(lcs,pauline->lc);
if (media_change) {
disable_all_codecs_except_one(marie->lc,"pcmu");
disable_all_codecs_except_one(pauline->lc,"pcmu");
}
/*
Marie calls Pauline, and after the call has rung, transitions to an early_media session
*/
/*use playfile for callee to avoid locking on capture card*/
linphone_core_use_files (pauline->lc,TRUE);
snprintf(hellopath,sizeof(hellopath), "%s/sounds/hello8000.wav", liblinphone_tester_file_prefix);
linphone_core_set_play_file(pauline->lc,hellopath);
marie_call = linphone_core_invite_address(marie->lc, pauline->identity);
CU_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallIncomingReceived,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs, &marie->stat.number_of_LinphoneCallOutgoingRinging,1,1000));
/* send a 183 to initiate the early media */
linphone_core_accept_early_media(pauline->lc, linphone_core_get_current_call(pauline->lc));
CU_ASSERT_TRUE( wait_for_list(lcs, &pauline->stat.number_of_LinphoneCallIncomingEarlyMedia,1,2000) );
CU_ASSERT_TRUE( wait_for_list(lcs, &marie->stat.number_of_LinphoneCallOutgoingEarlyMedia,1,2000) );
pauline_call = linphone_core_get_current_call(pauline->lc);
pauline_params = linphone_call_params_copy(linphone_call_get_current_params(pauline_call));
if (media_change) {
disable_all_codecs_except_one(marie->lc,"pcma");
disable_all_codecs_except_one(pauline->lc,"pcma");
}
#define UPDATED_SESSION_NAME "nouveau nom de session"
linphone_call_params_set_session_name(pauline_params,UPDATED_SESSION_NAME);
linphone_core_update_call(pauline->lc, pauline_call, pauline_params);
/*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_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);
liblinphone_tester_check_rtcp(marie, pauline);
linphone_core_terminate_all_calls(pauline->lc);
CU_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_LinphoneCallEnd,1,1000));
CU_ASSERT_TRUE(wait_for_list(lcs,&marie->stat.number_of_LinphoneCallEnd,1,1000));
ms_list_free(lcs);
linphone_core_manager_destroy(marie);
linphone_core_manager_destroy(pauline);
}
static void early_media_call_with_session_update(void){
early_media_call_with_update_base(FALSE);
}
static void early_media_call_with_codec_update(void){
early_media_call_with_update_base(TRUE);
}
static void simple_call_transfer(void) {
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
......@@ -1612,6 +1698,8 @@ test_t call_tests[] = {
{ "Simple call compatibility mode", simple_call_compatibility_mode },
{ "Early-media call", early_media_call },
{ "Early-media call with ringing", early_media_call_with_ringing },
{ "Early-media call with updated media session", early_media_call_with_session_update},
{ "Early-media call with updated codec", early_media_call_with_codec_update},
{ "Call terminated by caller", call_terminated_by_caller },
{ "Call without SDP", call_with_no_sdp},
{ "Call paused resumed", call_paused_resumed },
......
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