mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-29 00:59:20 +00:00
minimal SIP UPDATE support
This commit is contained in:
parent
36a124d277
commit
260e7e1d5c
10 changed files with 208 additions and 45 deletions
18
.cproject
18
.cproject
|
|
@ -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;
|
||||
belle_sip_server_transaction_t* transaction;
|
||||
|
||||
if (!h->pending_server_trans) {
|
||||
/*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 },
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue