mirror of
https://gitlab.linphone.org/BC/public/linphone-iphone.git
synced 2026-01-17 19:18:06 +00:00
Support for incoming UPDATEs within dialog.
For tests, the possibility to send an UPDATE with linphone_core_update_call() has been added thanks to a $ Added possibility to configure Supported SIP header.
This commit is contained in:
parent
46c932e690
commit
f4a4a6440b
16 changed files with 330 additions and 139 deletions
|
|
@ -29,7 +29,7 @@ Download lastest linphone-deps-win32 zip from
|
|||
http://download.savannah.gnu.org/releases-noredirect/linphone/misc
|
||||
using your browser.
|
||||
|
||||
Download lastest gtk+-2.24.10 win32 _bundle_ from http://www.gtk.org
|
||||
Download gtk+-2.24.10 win32 _bundle_ from http://www.gtk.org, direct link: http://ftp.gnome.org/pub/gnome/binaries/win32/gtk+/2.24/gtk+-bundle_2.24.10-20120208_win32.zip
|
||||
|
||||
Install all these three package in /:
|
||||
|
||||
|
|
|
|||
|
|
@ -534,6 +534,8 @@ void sal_uninit(Sal* sal){
|
|||
belle_sip_object_unref(sal->prov);
|
||||
belle_sip_object_unref(sal->stack);
|
||||
belle_sip_object_unref(sal->listener);
|
||||
if (sal->supported) belle_sip_object_unref(sal->supported);
|
||||
ms_list_free_with_data(sal->supported_tags,ms_free);
|
||||
if (sal->uuid) ms_free(sal->uuid);
|
||||
if (sal->root_ca) ms_free(sal->root_ca);
|
||||
ms_free(sal);
|
||||
|
|
@ -932,10 +934,79 @@ int sal_create_uuid(Sal*ctx, char *uuid, size_t len){
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void make_supported_header(Sal *sal){
|
||||
MSList *it;
|
||||
char *alltags=NULL;
|
||||
size_t buflen=64;
|
||||
size_t written=0;
|
||||
|
||||
if (sal->supported){
|
||||
belle_sip_object_unref(sal->supported);
|
||||
sal->supported=NULL;
|
||||
}
|
||||
for(it=sal->supported_tags;it!=NULL;it=it->next){
|
||||
const char *tag=(const char*)it->data;
|
||||
size_t taglen=strlen(tag);
|
||||
if (alltags==NULL || (written+taglen+1>=buflen)) alltags=ms_realloc(alltags,(buflen=buflen*2));
|
||||
snprintf(alltags+written,buflen-written,it->next ? "%s, " : "%s",tag);
|
||||
}
|
||||
if (alltags){
|
||||
sal->supported=belle_sip_header_create("Supported",alltags);
|
||||
if (sal->supported){
|
||||
belle_sip_object_ref(sal->supported);
|
||||
}
|
||||
ms_free(alltags);
|
||||
}
|
||||
}
|
||||
|
||||
void sal_set_supported_tags(Sal *ctx, const char* tags){
|
||||
ctx->supported_tags=ms_list_free_with_data(ctx->supported_tags,ms_free);
|
||||
if (tags){
|
||||
char *iter;
|
||||
char *buffer=ms_strdup(tags);
|
||||
char *tag;
|
||||
char *context=NULL;
|
||||
iter=buffer;
|
||||
while((tag=strtok_r(iter,", ",&context))!=NULL){
|
||||
iter=NULL;
|
||||
ctx->supported_tags=ms_list_append(ctx->supported_tags,ms_strdup(tag));
|
||||
}
|
||||
ms_free(buffer);
|
||||
}
|
||||
make_supported_header(ctx);
|
||||
}
|
||||
|
||||
const char *sal_get_supported_tags(Sal *ctx){
|
||||
if (ctx->supported){
|
||||
return belle_sip_header_get_unparsed_value(ctx->supported);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void sal_add_supported_tag(Sal *ctx, const char* tag){
|
||||
MSList *elem=ms_list_find_custom(ctx->supported_tags,(MSCompareFunc)strcasecmp,NULL);
|
||||
if (!elem){
|
||||
ctx->supported_tags=ms_list_append(ctx->supported_tags,ms_strdup(tag));
|
||||
make_supported_header(ctx);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void sal_remove_supported_tag(Sal *ctx, const char* tag){
|
||||
MSList *elem=ms_list_find_custom(ctx->supported_tags,(MSCompareFunc)strcasecmp,NULL);
|
||||
if (elem){
|
||||
ms_free(elem->data);
|
||||
ctx->supported_tags=ms_list_remove_link(ctx->supported_tags,elem);
|
||||
make_supported_header(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
belle_sip_response_t* sal_create_response_from_request ( Sal* sal, belle_sip_request_t* req, int code ) {
|
||||
belle_sip_response_t *resp=belle_sip_response_create_from_request(req,code);
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),BELLE_SIP_HEADER(sal->user_agent));
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),sal_make_supported_header(sal));
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(resp),sal->supported);
|
||||
return resp;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,6 +39,8 @@ struct Sal{
|
|||
char *root_ca;
|
||||
char *uuid;
|
||||
int refresher_retry_after; /*retry after value for refresher*/
|
||||
MSList *supported_tags;/*list of char * */
|
||||
belle_sip_header_t *supported;
|
||||
bool_t one_matching_codec;
|
||||
bool_t use_tcp_tls_keep_alive;
|
||||
bool_t nat_helper_enabled;
|
||||
|
|
@ -165,8 +167,6 @@ bool_t sal_op_get_body(SalOp *op, belle_sip_message_t *msg, SalBody *salbody);
|
|||
|
||||
SalReason sal_reason_to_sip_code(SalReason r);
|
||||
|
||||
belle_sip_header_t * sal_make_supported_header(Sal *sal);
|
||||
|
||||
void _sal_op_add_custom_headers(SalOp *op, belle_sip_message_t *msg);
|
||||
|
||||
#endif /* SAL_IMPL_H_ */
|
||||
|
|
|
|||
|
|
@ -185,6 +185,7 @@ static void call_process_response(void *op_base, const belle_sip_response_event_
|
|||
int code = belle_sip_response_get_status_code(response);
|
||||
belle_sip_header_content_type_t *header_content_type=NULL;
|
||||
belle_sip_dialog_t *dialog=belle_sip_response_event_get_dialog(event);
|
||||
const char *method;
|
||||
|
||||
if (!client_transaction) {
|
||||
ms_warning("Discarding stateless response [%i] on op [%p]",code,op);
|
||||
|
|
@ -193,13 +194,13 @@ static void call_process_response(void *op_base, const belle_sip_response_event_
|
|||
req=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction));
|
||||
set_or_update_dialog(op,dialog);
|
||||
dialog_state=dialog ? belle_sip_dialog_get_state(dialog) : BELLE_SIP_DIALOG_NULL;
|
||||
|
||||
method=belle_sip_request_get_method(req);
|
||||
ms_message("Op [%p] receiving call response [%i], dialog is [%p] in state [%s]",op,code,dialog,belle_sip_dialog_state_to_string(dialog_state));
|
||||
|
||||
switch(dialog_state) {
|
||||
case BELLE_SIP_DIALOG_NULL:
|
||||
case BELLE_SIP_DIALOG_EARLY: {
|
||||
if (strcmp("INVITE",belle_sip_request_get_method(req))==0 ) {
|
||||
if (strcmp("INVITE",method)==0 ) {
|
||||
if (op->state == SalOpStateTerminating) {
|
||||
/*check if CANCEL was sent before*/
|
||||
if (strcmp("CANCEL",belle_sip_request_get_method(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(op->pending_client_trans))))!=0) {
|
||||
|
|
@ -238,28 +239,28 @@ static void call_process_response(void *op_base, const belle_sip_response_event_
|
|||
case BELLE_SIP_DIALOG_CONFIRMED: {
|
||||
switch (op->state) {
|
||||
case SalOpStateEarly:/*invite case*/
|
||||
case SalOpStateActive: /*re-invite case*/
|
||||
if (code >=200
|
||||
&& code<300
|
||||
&& strcmp("INVITE",belle_sip_request_get_method(req))==0) {
|
||||
handle_sdp_from_response(op,response);
|
||||
ack=belle_sip_dialog_create_ack(op->dialog,belle_sip_dialog_get_local_seq_number(op->dialog));
|
||||
if (ack==NULL) {
|
||||
ms_error("This call has been already terminated.");
|
||||
return ;
|
||||
case SalOpStateActive: /*re-invite, INFO, UPDATE case*/
|
||||
if (strcmp("INVITE",method)==0){
|
||||
if (code >=200 && code<300) {
|
||||
handle_sdp_from_response(op,response);
|
||||
ack=belle_sip_dialog_create_ack(op->dialog,belle_sip_dialog_get_local_seq_number(op->dialog));
|
||||
if (ack==NULL) {
|
||||
ms_error("This call has been already terminated.");
|
||||
return ;
|
||||
}
|
||||
if (op->sdp_answer){
|
||||
set_sdp(BELLE_SIP_MESSAGE(ack),op->sdp_answer);
|
||||
belle_sip_object_unref(op->sdp_answer);
|
||||
op->sdp_answer=NULL;
|
||||
}
|
||||
belle_sip_dialog_send_ack(op->dialog,ack);
|
||||
op->base.root->callbacks.call_accepted(op); /*INVITE*/
|
||||
op->state=SalOpStateActive;
|
||||
}else if (code >= 300){
|
||||
call_set_error(op,response);
|
||||
}
|
||||
if (op->sdp_answer){
|
||||
set_sdp(BELLE_SIP_MESSAGE(ack),op->sdp_answer);
|
||||
belle_sip_object_unref(op->sdp_answer);
|
||||
op->sdp_answer=NULL;
|
||||
}
|
||||
belle_sip_dialog_send_ack(op->dialog,ack);
|
||||
op->base.root->callbacks.call_accepted(op); /*INVITE*/
|
||||
op->state=SalOpStateActive;
|
||||
} else if (code >= 300 && strcmp("INVITE",belle_sip_request_get_method(req))==0){
|
||||
call_set_error(op,response);
|
||||
} else if (code == 491
|
||||
&& strcmp("INFO",belle_sip_request_get_method(req)) == 0
|
||||
}else if (strcmp("INFO",method)==0){
|
||||
if (code == 491
|
||||
&& (header_content_type = belle_sip_message_get_header_by_type(req,belle_sip_header_content_type_t))
|
||||
&& strcmp("application",belle_sip_header_content_type_get_type(header_content_type))==0
|
||||
&& strcmp("media_control+xml",belle_sip_header_content_type_get_subtype(header_content_type))==0) {
|
||||
|
|
@ -267,8 +268,11 @@ static void call_process_response(void *op_base, const belle_sip_response_event_
|
|||
belle_sip_source_t *s=sal_create_timer(op->base.root,vfu_retry,sal_op_ref(op), retry_in, "vfu request retry");
|
||||
ms_message("Rejected vfu request on op [%p], just retry in [%ui] ms",op,retry_in);
|
||||
belle_sip_object_unref(s);
|
||||
}else {
|
||||
/*ignoring*/
|
||||
}else {
|
||||
/*ignoring*/
|
||||
}
|
||||
}else if (strcmp("UPDATE",method)==0){
|
||||
op->base.root->callbacks.call_accepted(op); /*INVITE*/
|
||||
}
|
||||
break;
|
||||
case SalOpStateTerminating:
|
||||
|
|
@ -419,6 +423,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
|
|||
belle_sip_response_t* resp;
|
||||
belle_sip_header_t* call_info;
|
||||
const char *method=belle_sip_request_get_method(req);
|
||||
bool_t is_update=FALSE;
|
||||
|
||||
if (strcmp("ACK",method)!=0){ /*ACK does'nt create srv transaction*/
|
||||
server_transaction = belle_sip_provider_create_server_transaction(op->base.root->prov,belle_sip_request_event_get_request(event));
|
||||
|
|
@ -490,7 +495,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
|
|||
} 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);
|
||||
op->base.root->callbacks.call_updating(op,TRUE);
|
||||
} 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);
|
||||
|
|
@ -522,11 +527,11 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
|
|||
op->base.root->callbacks.call_terminated(op,op->dir==SalOpDirIncoming?sal_op_get_from(op):sal_op_get_to(op));
|
||||
op->state=SalOpStateTerminating;
|
||||
/*call end not notified by dialog deletion because transaction can end before dialog*/
|
||||
} else if(strcmp("INVITE",method)==0) {
|
||||
} else if(strcmp("INVITE",method)==0 || (is_update=(strcmp("UPDATE",method)==0)) ) {
|
||||
/*re-invite*/
|
||||
sal_op_reset_descriptions(op);
|
||||
if (process_sdp_for_invite(op,req)==0)
|
||||
op->base.root->callbacks.call_updating(op);
|
||||
op->base.root->callbacks.call_updating(op,is_update);
|
||||
} else if (strcmp("INFO",method)==0){
|
||||
if (belle_sip_message_get_body(BELLE_SIP_MESSAGE(req))
|
||||
&& strstr(belle_sip_message_get_body(BELLE_SIP_MESSAGE(req)),"picture_fast_update")) {
|
||||
|
|
@ -564,22 +569,6 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
|
|||
belle_sip_server_transaction_send_response(server_transaction,sal_op_create_response_from_request(op,req,481));
|
||||
} else if (strcmp("MESSAGE",method)==0){
|
||||
sal_process_incoming_message(op,event);
|
||||
} else if (strcmp("UPDATE",method)==0) {
|
||||
|
||||
/*FIXME jehan: It might be better to silently accept UPDATE which do not modify either the number or the nature of streams*/
|
||||
|
||||
/*rfc 3311
|
||||
* 5.2 Receiving an UPDATE
|
||||
* ...
|
||||
* If the UAS cannot change the session parameters without prompting the user, it SHOULD reject
|
||||
* the request with a 504 response.
|
||||
*/
|
||||
resp=sal_op_create_response_from_request(op,req,504);
|
||||
belle_sip_response_set_reason_phrase(resp,"Cannot change the session parameters without prompting the user");
|
||||
/*belle_sip_message_add_header( BELLE_SIP_MESSAGE(resp)
|
||||
,belle_sip_header_create( "Warning", "Cannot change the session parameters without prompting the user"));*/
|
||||
belle_sip_server_transaction_send_response(server_transaction,resp);
|
||||
return;
|
||||
}else{
|
||||
ms_error("unexpected method [%s] for dialog [%p]",belle_sip_request_get_method(req),op->dialog);
|
||||
unsupported_method(server_transaction,req);
|
||||
|
|
@ -796,13 +785,15 @@ int sal_call_decline(SalOp *op, SalReason reason, const char *redirection /*opti
|
|||
return 0;
|
||||
}
|
||||
|
||||
int sal_call_update(SalOp *op, const char *subject){
|
||||
|
||||
int sal_call_update(SalOp *op, const char *subject, bool_t no_user_consent){
|
||||
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");
|
||||
if (no_user_consent)
|
||||
update=belle_sip_dialog_create_request(op->dialog,"UPDATE");
|
||||
else
|
||||
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 {
|
||||
|
|
|
|||
|
|
@ -118,9 +118,7 @@ belle_sip_header_contact_t* sal_op_create_contact(SalOp *op){
|
|||
return contact_header;
|
||||
}
|
||||
|
||||
belle_sip_header_t * sal_make_supported_header(Sal *sal){
|
||||
return belle_sip_header_create("Supported","replaces, outbound");
|
||||
}
|
||||
|
||||
|
||||
static void add_initial_route_set(belle_sip_request_t *request, const MSList *list){
|
||||
const MSList *elem;
|
||||
|
|
@ -201,7 +199,7 @@ belle_sip_request_t* sal_op_build_request(SalOp *op,const char* method) {
|
|||
belle_sip_header_privacy_add_privacy(privacy_header,sal_privacy_to_string(SalPrivacyUser));
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(privacy_header));
|
||||
}
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),sal_make_supported_header(op->base.root));
|
||||
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),op->base.root->supported);
|
||||
return req;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -503,58 +503,53 @@ static void call_ack(SalOp *op){
|
|||
}
|
||||
}
|
||||
|
||||
static void call_accept_update(LinphoneCore *lc, LinphoneCall *call){
|
||||
SalMediaDescription *md;
|
||||
SalMediaDescription *rmd=sal_call_get_remote_media_description(call->op);
|
||||
if (rmd!=NULL && call->ice_session!=NULL) {
|
||||
linphone_core_update_ice_from_remote_media_description(call,rmd);
|
||||
linphone_core_update_local_media_description_from_ice(call->localdesc,call->ice_session);
|
||||
}
|
||||
#ifdef BUILD_UPNP
|
||||
if(call->upnp_session != NULL) {
|
||||
linphone_core_update_upnp_from_remote_media_description(call, rmd);
|
||||
linphone_core_update_local_media_description_from_upnp(call->localdesc,call->upnp_session);
|
||||
}
|
||||
#endif //BUILD_UPNP
|
||||
linphone_call_update_remote_session_id_and_ver(call);
|
||||
sal_call_accept(call->op);
|
||||
md=sal_call_get_final_media_description(call->op);
|
||||
if (md && !sal_media_description_empty(md)){
|
||||
linphone_core_update_streams(lc,call,md);
|
||||
}
|
||||
}
|
||||
|
||||
static void call_resumed(LinphoneCore *lc, LinphoneCall *call){
|
||||
/*when we are resumed, increment session id, because sdp is changed (a=recvonly disapears)*/
|
||||
linphone_call_increment_local_media_description(call);
|
||||
call_accept_update(lc,call);
|
||||
if(lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("We have been resumed."));
|
||||
linphone_call_set_state(call,LinphoneCallStreamsRunning,"Connected (streams running)");
|
||||
_linphone_core_accept_call_update(lc,call,NULL,LinphoneCallStreamsRunning,"Connected (streams running)");
|
||||
}
|
||||
|
||||
static void call_paused_by_remote(LinphoneCore *lc, LinphoneCall *call){
|
||||
/*when we are resumed, increment session id, because sdp is changed (a=recvonly appears)*/
|
||||
linphone_call_increment_local_media_description(call);
|
||||
call_accept_update(lc,call);
|
||||
/* we are being paused */
|
||||
if(lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("We are paused by other party."));
|
||||
linphone_call_set_state (call,LinphoneCallPausedByRemote,"Call paused by remote");
|
||||
_linphone_core_accept_call_update(lc,call,NULL,LinphoneCallPausedByRemote,"Call paused by remote");
|
||||
|
||||
}
|
||||
|
||||
static void call_updated_by_remote(LinphoneCore *lc, LinphoneCall *call,bool_t notify_application){
|
||||
static void call_updated_by_remote(LinphoneCore *lc, LinphoneCall *call, bool_t is_update){
|
||||
/*first check if media capabilities are compatible*/
|
||||
SalMediaDescription* md;
|
||||
linphone_call_make_local_media_description(lc,call);
|
||||
sal_call_set_local_media_description(call->op,call->localdesc);
|
||||
md=sal_call_get_final_media_description(call->op);
|
||||
if (md && (sal_media_description_empty(md) || linphone_core_incompatible_security(lc,md))){
|
||||
sal_call_decline(call->op,SalReasonNotAcceptable,NULL);
|
||||
return;
|
||||
SalMediaDescription *md;
|
||||
SalMediaDescription *rmd=sal_call_get_remote_media_description(call->op);
|
||||
SalMediaDescription *prev_result_desc=call->resultdesc;
|
||||
|
||||
if (rmd!=NULL){
|
||||
if (call->state!=LinphoneCallPaused){
|
||||
/*in paused state, we must stay in paused state.*/
|
||||
linphone_call_make_local_media_description(lc,call);
|
||||
sal_call_set_local_media_description(call->op,call->localdesc);
|
||||
}
|
||||
md=sal_call_get_final_media_description(call->op);
|
||||
if (md && (sal_media_description_empty(md) || linphone_core_incompatible_security(lc,md))){
|
||||
sal_call_decline(call->op,SalReasonNotAcceptable,NULL);
|
||||
return;
|
||||
}
|
||||
if (is_update && prev_result_desc && md){
|
||||
int diff=sal_media_description_equals(prev_result_desc,md);
|
||||
if (diff & (SAL_MEDIA_DESCRIPTION_CRYPTO_CHANGED|SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED)){
|
||||
ms_warning("Cannot accept this update, it is changing parameters that require user approval");
|
||||
sal_call_decline(call->op,SalReasonNotAcceptable,NULL); /*FIXME should send 504 Cannot change the session parameters without prompting the user"*/
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (notify_application) {
|
||||
if (call->state==LinphoneCallStreamsRunning) {
|
||||
/*reINVITE and in-dialogs UPDATE go here*/
|
||||
if(lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("Call is updated by remote."));
|
||||
call->defer_update=FALSE;
|
||||
|
|
@ -562,22 +557,22 @@ static void call_updated_by_remote(LinphoneCore *lc, LinphoneCall *call,bool_t n
|
|||
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);
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
/* this callback is called when an incoming re-INVITE/ SIP UPDATE modifies the session*/
|
||||
static void call_updating(SalOp *op){
|
||||
static void call_updating(SalOp *op, bool_t is_update){
|
||||
LinphoneCore *lc=(LinphoneCore *)sal_get_user_pointer(sal_op_get_sal(op));
|
||||
LinphoneCall *call=(LinphoneCall*)sal_op_get_user_pointer(op);
|
||||
SalMediaDescription *rmd=sal_call_get_remote_media_description(op);
|
||||
|
||||
|
||||
if (rmd==NULL){
|
||||
/* case of a reINVITE without SDP */
|
||||
call_accept_update(lc,call);
|
||||
call->expect_media_in_ack=TRUE;
|
||||
/* case of a reINVITE or UPDATE without SDP */
|
||||
call_updated_by_remote(lc,call,is_update);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -588,19 +583,38 @@ static void call_updating(SalOp *op){
|
|||
}else call_paused_by_remote(lc,call);
|
||||
break;
|
||||
/*SIP UPDATE CASE*/
|
||||
case LinphoneCallOutgoingRinging:
|
||||
case LinphoneCallOutgoingEarlyMedia:
|
||||
call_updated_by_remote(lc,call,FALSE);
|
||||
case LinphoneCallIncomingEarlyMedia:
|
||||
if (is_update) call_updated_by_remote(lc,call,is_update);
|
||||
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,TRUE);
|
||||
call_updated_by_remote(lc,call,is_update);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
call_accept_update(lc,call);
|
||||
case LinphoneCallPaused:
|
||||
call_updated_by_remote(lc,call,is_update);
|
||||
break;
|
||||
case LinphoneCallUpdating:
|
||||
case LinphoneCallPausing:
|
||||
case LinphoneCallResuming:
|
||||
case LinphoneCallUpdatedByRemote:
|
||||
sal_call_decline(call->op,SalReasonNotImplemented,NULL);
|
||||
/*no break*/
|
||||
case LinphoneCallIdle:
|
||||
case LinphoneCallOutgoingInit:
|
||||
case LinphoneCallEnd:
|
||||
case LinphoneCallIncomingReceived:
|
||||
case LinphoneCallOutgoingProgress:
|
||||
case LinphoneCallRefered:
|
||||
case LinphoneCallError:
|
||||
case LinphoneCallReleased:
|
||||
ms_warning("Receiving reINVITE or UPDATE while in state [%s], should not happen.",linphone_call_state_to_string(call->state));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -635,6 +635,7 @@ void linphone_core_message_received(LinphoneCore *lc, SalOp *op, const SalMessag
|
|||
linphone_address_destroy(addr);
|
||||
msg->storage_id=linphone_chat_message_store(msg);
|
||||
linphone_chat_room_message_received(cr,lc,msg);
|
||||
linphone_chat_message_unref(msg);
|
||||
ms_free(cleanfrom);
|
||||
ms_free(from);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1424,7 +1424,7 @@ static void video_stream_event_cb(void *user_pointer, const MSFilter *f, const u
|
|||
case MS_VIDEO_DECODER_FIRST_IMAGE_DECODED:
|
||||
ms_message("First video frame decoded successfully");
|
||||
if (call->nextVideoFrameDecoded._func != NULL)
|
||||
call->nextVideoFrameDecoded._func(call, call->nextVideoFrameDecoded._user_data);
|
||||
call->nextVideoFrameDecoded._func(call, call->nextVideoFrameDecoded._user_data);
|
||||
break;
|
||||
case MS_VIDEO_DECODER_SEND_PLI:
|
||||
case MS_VIDEO_DECODER_SEND_SLI:
|
||||
|
|
@ -2766,7 +2766,7 @@ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){
|
|||
linphone_core_start_update_call(call->core, call);
|
||||
break;
|
||||
case LinphoneCallUpdatedByRemote:
|
||||
linphone_core_start_accept_call_update(call->core, call);
|
||||
linphone_core_start_accept_call_update(call->core, call,call->prevstate,linphone_call_state_to_string(call->prevstate));
|
||||
break;
|
||||
case LinphoneCallOutgoingInit:
|
||||
linphone_call_stop_media_streams_for_ice_gathering(call);
|
||||
|
|
@ -2781,7 +2781,7 @@ static void handle_ice_events(LinphoneCall *call, OrtpEvent *ev){
|
|||
}
|
||||
} else if (evt == ORTP_EVENT_ICE_LOSING_PAIRS_COMPLETED) {
|
||||
if (call->state==LinphoneCallUpdatedByRemote){
|
||||
linphone_core_start_accept_call_update(call->core, call);
|
||||
linphone_core_start_accept_call_update(call->core, call,call->prevstate,linphone_call_state_to_string(call->prevstate));
|
||||
linphone_core_update_ice_state_in_call_stats(call);
|
||||
}
|
||||
} else if (evt == ORTP_EVENT_ICE_RESTART_NEEDED) {
|
||||
|
|
|
|||
|
|
@ -464,6 +464,7 @@ static void sip_config_read(LinphoneCore *lc)
|
|||
sal_enable_sip_update_method(lc->sal,lp_config_get_int(lc->config,"sip","sip_update",1));
|
||||
lc->sip_conf.vfu_with_info=lp_config_get_int(lc->config,"sip","vfu_with_info",1);
|
||||
linphone_core_set_sip_transport_timeout(lc, lp_config_get_int(lc->config, "sip", "transport_timeout", 63000));
|
||||
sal_set_supported_tags(lc->sal,lp_config_get_string(lc->config,"sip","supported","replaces, outbound"));
|
||||
}
|
||||
|
||||
static void rtp_config_read(LinphoneCore *lc)
|
||||
|
|
@ -2853,8 +2854,9 @@ int linphone_core_accept_early_media(LinphoneCore* lc, LinphoneCall* call){
|
|||
|
||||
int linphone_core_start_update_call(LinphoneCore *lc, LinphoneCall *call){
|
||||
const char *subject;
|
||||
bool_t no_user_consent=call->params.no_user_consent;
|
||||
|
||||
linphone_call_make_local_media_description(lc,call);
|
||||
if (!no_user_consent) linphone_call_make_local_media_description(lc,call);
|
||||
#ifdef BUILD_UPNP
|
||||
if(call->upnp_session != NULL) {
|
||||
linphone_core_update_local_media_description_from_upnp(call->localdesc, call->upnp_session);
|
||||
|
|
@ -2862,8 +2864,10 @@ int linphone_core_start_update_call(LinphoneCore *lc, LinphoneCall *call){
|
|||
#endif //BUILD_UPNP
|
||||
if (call->params->in_conference){
|
||||
subject="Conference";
|
||||
}else{
|
||||
}else if (!no_user_consent){
|
||||
subject="Media change";
|
||||
}else{
|
||||
subject="Refreshing";
|
||||
}
|
||||
if (lc->vtable.display_status)
|
||||
lc->vtable.display_status(lc,_("Modifying call parameters..."));
|
||||
|
|
@ -2872,7 +2876,7 @@ int linphone_core_start_update_call(LinphoneCore *lc, LinphoneCall *call){
|
|||
/*give a chance to update the contact address if connectivity has changed*/
|
||||
sal_op_set_contact_address(call->op,sal_op_get_contact_address(call->dest_proxy->op));
|
||||
}else sal_op_set_contact_address(call->op,NULL);
|
||||
return sal_call_update(call->op,subject);
|
||||
return sal_call_update(call->op,subject,no_user_consent);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
@ -2984,7 +2988,7 @@ int linphone_core_defer_call_update(LinphoneCore *lc, LinphoneCall *call){
|
|||
return -1;
|
||||
}
|
||||
|
||||
int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call){
|
||||
int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState next_state, const char *state_info){
|
||||
SalMediaDescription *md;
|
||||
if (call->ice_session != NULL) {
|
||||
if (ice_session_nb_losing_pairs(call->ice_session) > 0) {
|
||||
|
|
@ -3002,8 +3006,7 @@ int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call)
|
|||
linphone_core_update_streams (lc,call,md);
|
||||
linphone_call_fix_call_parameters(call);
|
||||
}
|
||||
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)");
|
||||
linphone_call_set_state(call,next_state,state_info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -3032,10 +3035,10 @@ int linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const
|
|||
linphone_call_state_to_string(call->state));
|
||||
return -1;
|
||||
}
|
||||
return _linphone_core_accept_call_update(lc, call, params);
|
||||
return _linphone_core_accept_call_update(lc, call, params, call->prevstate, linphone_call_state_to_string(call->prevstate));
|
||||
}
|
||||
|
||||
int _linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params){
|
||||
int _linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params, LinphoneCallState next_state, const char *state_info){
|
||||
SalMediaDescription *remote_desc;
|
||||
bool_t keep_sdp_version;
|
||||
#if defined(VIDEO_ENABLED) && defined(BUILD_UPNP)
|
||||
|
|
@ -3048,7 +3051,7 @@ int _linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, cons
|
|||
/* Remote has sent an INVITE with the same SDP as before, so send a 200 OK with the same SDP as before. */
|
||||
ms_warning("SDP version has not changed, send same SDP as before.");
|
||||
sal_call_accept(call->op);
|
||||
linphone_call_set_state(call,LinphoneCallStreamsRunning,"Connected (streams running)");
|
||||
linphone_call_set_state(call,next_state,state_info);
|
||||
return 0;
|
||||
}
|
||||
if (params==NULL){
|
||||
|
|
@ -3086,7 +3089,7 @@ int _linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, cons
|
|||
}
|
||||
#endif //BUILD_UPNP
|
||||
|
||||
linphone_core_start_accept_call_update(lc, call);
|
||||
linphone_core_start_accept_call_update(lc, call, next_state, state_info);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
@ -3413,7 +3416,7 @@ int _linphone_core_pause_call(LinphoneCore *lc, LinphoneCall *call)
|
|||
return -1;
|
||||
}
|
||||
sal_call_set_local_media_description(call->op,call->localdesc);
|
||||
if (sal_call_update(call->op,subject) != 0){
|
||||
if (sal_call_update(call->op,subject,FALSE) != 0){
|
||||
if (lc->vtable.display_warning)
|
||||
lc->vtable.display_warning(lc,_("Could not pause the call"));
|
||||
}
|
||||
|
|
@ -3498,7 +3501,7 @@ int linphone_core_resume_call(LinphoneCore *lc, LinphoneCall *call){
|
|||
sal_call_set_local_media_description(call->op,call->localdesc);
|
||||
sal_media_description_set_dir(call->localdesc,SalStreamSendRecv);
|
||||
if (call->params->in_conference && !call->current_params->in_conference) subject="Conference";
|
||||
if(sal_call_update(call->op,subject) != 0){
|
||||
if ( sal_call_update(call->op,subject,FALSE) != 0){
|
||||
return -1;
|
||||
}
|
||||
linphone_call_set_state(call,LinphoneCallResuming,"Resuming");
|
||||
|
|
@ -6404,6 +6407,29 @@ void linphone_core_set_file_transfer_server(LinphoneCore *core, const char * ser
|
|||
core->file_transfer_server=ms_strdup(server_url);
|
||||
}
|
||||
|
||||
/**
|
||||
* This function controls signaling features supported by the core.
|
||||
* They are typically included in a SIP Supported header.
|
||||
* @param lc the LinphoneCore
|
||||
* @param tag the feature tag name
|
||||
* @ingroup initializing
|
||||
**/
|
||||
void linphone_core_add_supported_tag(LinphoneCore *lc, const char *tag){
|
||||
sal_add_supported_tag(lc->sal,tag);
|
||||
lp_config_set_string(lc->config,"sip","supported",sal_get_supported_tags(lc->sal));
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove a supported tag. @see linphone_core_add_supported_tag()
|
||||
* @param lc the LinphoneCore
|
||||
* @param tag the tag to remove
|
||||
* @ingroup initializing
|
||||
**/
|
||||
void linphone_core_remove_supported_tag(LinphoneCore *lc, const char *tag){
|
||||
sal_remove_supported_tag(lc->sal,tag);
|
||||
lp_config_set_string(lc->config,"sip","supported",sal_get_supported_tags(lc->sal));
|
||||
}
|
||||
|
||||
|
||||
int linphone_payload_type_get_type(const LinphonePayloadType *pt) {
|
||||
return pt->type;
|
||||
|
|
|
|||
|
|
@ -2861,6 +2861,10 @@ LINPHONE_PUBLIC void linphone_core_set_file_transfer_server(LinphoneCore *core,
|
|||
**/
|
||||
LINPHONE_PUBLIC const char ** linphone_core_get_supported_file_formats(LinphoneCore *core);
|
||||
|
||||
LINPHONE_PUBLIC void linphone_core_add_supported_tag(LinphoneCore *core, const char *tag);
|
||||
|
||||
LINPHONE_PUBLIC void linphone_core_remove_supported_tag(LinphoneCore *core, const char *tag);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
|
|
|||
|
|
@ -102,8 +102,9 @@ struct _LinphoneCallParams{
|
|||
bool_t real_early_media; /*send real media even during early media (for outgoing calls)*/
|
||||
bool_t in_conference; /*in conference mode */
|
||||
bool_t low_bandwidth;
|
||||
LinphonePrivacyMask privacy;
|
||||
bool_t no_user_consent;/*when set to TRUE an UPDATE request will be used instead of reINVITE*/
|
||||
uint16_t avpf_rr_interval;
|
||||
LinphonePrivacyMask privacy;
|
||||
};
|
||||
|
||||
BELLE_SIP_DECLARE_VPTR(LinphoneCallParams);
|
||||
|
|
@ -404,7 +405,7 @@ int linphone_core_proceed_with_invite_if_ready(LinphoneCore *lc, LinphoneCall *c
|
|||
int linphone_core_start_invite(LinphoneCore *lc, LinphoneCall *call, const LinphoneAddress* destination/* = NULL if to be taken from the call log */);
|
||||
int linphone_core_restart_invite(LinphoneCore *lc, LinphoneCall *call);
|
||||
int linphone_core_start_update_call(LinphoneCore *lc, LinphoneCall *call);
|
||||
int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call);
|
||||
int linphone_core_start_accept_call_update(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState next_state, const char *state_info);
|
||||
void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call);
|
||||
bool_t linphone_core_incompatible_security(LinphoneCore *lc, SalMediaDescription *md);
|
||||
extern SalCallbacks linphone_sal_callbacks;
|
||||
|
|
@ -656,7 +657,7 @@ LinphoneToneDescription *linphone_core_get_call_error_tone(const LinphoneCore *l
|
|||
void linphone_core_play_call_error_tone(LinphoneCore *lc, LinphoneReason reason);
|
||||
void _linphone_core_set_tone(LinphoneCore *lc, LinphoneReason reason, LinphoneToneID id, const char *audiofile);
|
||||
const char *linphone_core_get_tone_file(const LinphoneCore *lc, LinphoneToneID id);
|
||||
int _linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params);
|
||||
int _linphone_core_accept_call_update(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params, LinphoneCallState next_state, const char *state_info);
|
||||
typedef struct _LinphoneConference LinphoneConference;
|
||||
|
||||
struct _LinphoneCore
|
||||
|
|
|
|||
|
|
@ -307,7 +307,7 @@ int sal_media_description_equals(const SalMediaDescription *md1, const SalMediaD
|
|||
int i;
|
||||
|
||||
if (strcmp(md1->addr, md2->addr) != 0) result |= SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED;
|
||||
if (md1->nb_streams != md2->nb_streams) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
|
||||
if (md1->nb_streams != md2->nb_streams) result |= SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED;
|
||||
if (md1->bandwidth != md2->bandwidth) result |= SAL_MEDIA_DESCRIPTION_CODEC_CHANGED;
|
||||
for(i = 0; i < md1->nb_streams; ++i){
|
||||
result |= sal_stream_description_equals(&md1->streams[i], &md2->streams[i]);
|
||||
|
|
|
|||
|
|
@ -834,7 +834,7 @@ int linphone_upnp_call_process(LinphoneCall *call) {
|
|||
linphone_core_start_update_call(lc, call);
|
||||
break;
|
||||
case LinphoneCallUpdatedByRemote:
|
||||
linphone_core_start_accept_call_update(lc, call);
|
||||
linphone_core_start_accept_call_update(lc, call,call->prevstate,linphone_call_state_to_string(call->prevstate));
|
||||
break;
|
||||
case LinphoneCallOutgoingInit:
|
||||
linphone_core_proceed_with_invite_if_ready(lc, call, NULL);
|
||||
|
|
|
|||
|
|
@ -72,7 +72,9 @@ typedef enum {
|
|||
#define SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED 0x01
|
||||
#define SAL_MEDIA_DESCRIPTION_CODEC_CHANGED 0x02
|
||||
#define SAL_MEDIA_DESCRIPTION_CRYPTO_CHANGED 0x04
|
||||
#define SAL_MEDIA_DESCRIPTION_CHANGED (SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED | SAL_MEDIA_DESCRIPTION_CODEC_CHANGED | SAL_MEDIA_DESCRIPTION_CRYPTO_CHANGED)
|
||||
#define SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED 0x08
|
||||
#define SAL_MEDIA_DESCRIPTION_CHANGED (SAL_MEDIA_DESCRIPTION_NETWORK_CHANGED | SAL_MEDIA_DESCRIPTION_CODEC_CHANGED |\
|
||||
SAL_MEDIA_DESCRIPTION_CRYPTO_CHANGED |SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED)
|
||||
|
||||
const char* sal_transport_to_string(SalTransport transport);
|
||||
SalTransport sal_transport_parse(const char*);
|
||||
|
|
@ -413,7 +415,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/UPDATE is received*/
|
||||
typedef void (*SalOnCallUpdating)(SalOp *op, bool_t is_update);/*< Called when a reINVITE/UPDATE is received*/
|
||||
typedef void (*SalOnCallTerminated)(SalOp *op, const char *from);
|
||||
typedef void (*SalOnCallFailure)(SalOp *op);
|
||||
typedef void (*SalOnCallReleased)(SalOp *salop);
|
||||
|
|
@ -517,6 +519,10 @@ int sal_get_listening_port(Sal *ctx, SalTransport tr);
|
|||
int sal_unlisten_ports(Sal *ctx);
|
||||
int sal_transport_available(Sal *ctx, SalTransport t);
|
||||
void sal_set_dscp(Sal *ctx, int dscp);
|
||||
void sal_set_supported_tags(Sal *ctx, const char* tags);
|
||||
void sal_add_supported_tag(Sal *ctx, const char* tag);
|
||||
void sal_remove_supported_tag(Sal *ctx, const char* tag);
|
||||
const char *sal_get_supported_tags(Sal *ctx);
|
||||
int sal_reset_transports(Sal *ctx);
|
||||
ortp_socket_t sal_get_socket(Sal *ctx);
|
||||
void sal_set_user_agent(Sal *ctx, const char *user_agent);
|
||||
|
|
@ -615,7 +621,7 @@ int sal_call_notify_ringing(SalOp *h, bool_t early_media);
|
|||
/*accept an incoming call or, during a call accept a reINVITE*/
|
||||
int sal_call_accept(SalOp*h);
|
||||
int sal_call_decline(SalOp *h, SalReason reason, const char *redirection /*optional*/);
|
||||
int sal_call_update(SalOp *h, const char *subject);
|
||||
int sal_call_update(SalOp *h, const char *subject, bool_t no_user_consent);
|
||||
SalMediaDescription * sal_call_get_remote_media_description(SalOp *h);
|
||||
SalMediaDescription * sal_call_get_final_media_description(SalOp *h);
|
||||
int sal_call_refer(SalOp *h, const char *refer_to);
|
||||
|
|
|
|||
|
|
@ -2908,6 +2908,72 @@ static void video_call_snapshot(void) {
|
|||
|
||||
#endif
|
||||
|
||||
static void call_with_in_dialog_update(void) {
|
||||
int begin;
|
||||
int leaked_objects;
|
||||
LinphoneCoreManager* marie;
|
||||
LinphoneCoreManager* pauline;
|
||||
LinphoneCallParams *params;
|
||||
|
||||
belle_sip_object_enable_leak_detector(TRUE);
|
||||
begin=belle_sip_object_get_object_count();
|
||||
|
||||
marie = linphone_core_manager_new( "marie_rc");
|
||||
pauline = linphone_core_manager_new( "pauline_rc");
|
||||
CU_ASSERT_TRUE(call(pauline,marie));
|
||||
liblinphone_tester_check_rtcp(marie,pauline);
|
||||
params=linphone_core_create_call_params(marie->lc,linphone_core_get_current_call(marie->lc));
|
||||
params->no_user_consent=TRUE;
|
||||
linphone_core_update_call(marie->lc,linphone_core_get_current_call(marie->lc),params);
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallUpdating,1));
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,2));
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallUpdatedByRemote,1));
|
||||
CU_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,2));
|
||||
end_call(marie,pauline);
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
|
||||
leaked_objects=belle_sip_object_get_object_count()-begin;
|
||||
CU_ASSERT_TRUE(leaked_objects==0);
|
||||
if (leaked_objects>0){
|
||||
belle_sip_object_dump_active_objects();
|
||||
}
|
||||
}
|
||||
|
||||
static void call_with_custom_supported_tags(void) {
|
||||
int begin;
|
||||
int leaked_objects;
|
||||
LinphoneCoreManager* marie;
|
||||
LinphoneCoreManager* pauline;
|
||||
const LinphoneCallParams *remote_params;
|
||||
const char *recv_supported;
|
||||
|
||||
belle_sip_object_enable_leak_detector(TRUE);
|
||||
begin=belle_sip_object_get_object_count();
|
||||
|
||||
marie = linphone_core_manager_new( "marie_rc");
|
||||
pauline = linphone_core_manager_new( "pauline_rc");
|
||||
|
||||
linphone_core_add_supported_tag(marie->lc,"pouet-tag");
|
||||
CU_ASSERT_TRUE(call(pauline,marie));
|
||||
liblinphone_tester_check_rtcp(marie,pauline);
|
||||
remote_params=linphone_call_get_remote_params(linphone_core_get_current_call(pauline->lc));
|
||||
recv_supported=linphone_call_params_get_custom_header(remote_params,"supported");
|
||||
CU_ASSERT_PTR_NOT_NULL(recv_supported);
|
||||
if (recv_supported){
|
||||
CU_ASSERT_TRUE(strstr(recv_supported,"pouet-tag")!=NULL);
|
||||
}
|
||||
end_call(marie,pauline);
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
|
||||
leaked_objects=belle_sip_object_get_object_count()-begin;
|
||||
CU_ASSERT_TRUE(leaked_objects==0);
|
||||
if (leaked_objects>0){
|
||||
belle_sip_object_dump_active_objects();
|
||||
}
|
||||
}
|
||||
|
||||
test_t call_tests[] = {
|
||||
{ "Early declined call", early_declined_call },
|
||||
{ "Call declined", call_declined },
|
||||
|
|
@ -3002,6 +3068,8 @@ test_t call_tests[] = {
|
|||
{ "SAVPF to AVPF call", savpf_to_avpf_call },
|
||||
{ "SAVPF to SAVP call", savpf_to_savp_call },
|
||||
{ "SAVPF to SAVPF call", savpf_to_savpf_call },
|
||||
{ "Call with in-dialog UPDATE request", call_with_in_dialog_update },
|
||||
{ "Call with custom supported tags", call_with_custom_supported_tags }
|
||||
};
|
||||
|
||||
test_suite_t call_test_suite = {
|
||||
|
|
|
|||
|
|
@ -331,23 +331,34 @@ static void text_message_compatibility_mode(void) {
|
|||
}
|
||||
|
||||
static void text_message_with_ack(void) {
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
char* to = linphone_address_as_string(marie->identity);
|
||||
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to);
|
||||
LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu");
|
||||
belle_sip_object_enable_leak_detector(TRUE);
|
||||
int begin=belle_sip_object_get_object_count();
|
||||
int leaked_objects;
|
||||
|
||||
{
|
||||
int dummy=0;
|
||||
wait_for_until(marie->lc,pauline->lc,&dummy,1,100); /*just to have time to purge message stored in the server*/
|
||||
reset_counters(&marie->stat);
|
||||
reset_counters(&pauline->stat);
|
||||
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
|
||||
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
|
||||
char* to = linphone_address_as_string(marie->identity);
|
||||
LinphoneChatRoom* chat_room = linphone_core_create_chat_room(pauline->lc,to);
|
||||
LinphoneChatMessage* message = linphone_chat_room_create_message(chat_room,"Bli bli bli \n blu");
|
||||
{
|
||||
int dummy=0;
|
||||
wait_for_until(marie->lc,pauline->lc,&dummy,1,100); /*just to have time to purge message stored in the server*/
|
||||
reset_counters(&marie->stat);
|
||||
reset_counters(&pauline->stat);
|
||||
}
|
||||
linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,pauline->lc);
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1));
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDelivered,1));
|
||||
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1);
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
leaked_objects=belle_sip_object_get_object_count()-begin;
|
||||
CU_ASSERT_TRUE(leaked_objects==0);
|
||||
if (leaked_objects>0){
|
||||
belle_sip_object_dump_active_objects();
|
||||
}
|
||||
linphone_chat_room_send_message2(chat_room,message,liblinphone_tester_chat_message_state_change,pauline->lc);
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&marie->stat.number_of_LinphoneMessageReceived,1));
|
||||
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneMessageDelivered,1));
|
||||
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneMessageInProgress,1);
|
||||
linphone_core_manager_destroy(marie);
|
||||
linphone_core_manager_destroy(pauline);
|
||||
}
|
||||
|
||||
static void text_message_with_external_body(void) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue