Commit 83268b31 authored by Simon Morlat's avatar Simon Morlat

* fixes for dialog serialization

* fix crash when receiving a NOTIFY after a SUBSCRIBE is terminated
parent 14b83dc6
......@@ -2,6 +2,14 @@ linphone-3.7...??
* multiple SIP transports simualtaneously now allowed
* IP dual stack: can use IPv6 and IPv4 simultaneously
* fully asynchronous behavior: no more lengthly DNS or connections
* +sip.instance parameter (RFC???)
* alias parameter (RFC????)
* better management of network disconnections
* SIP/TLS handled through lightweighted polarssl library (instead of openssl)
* SIP transaction state machines improved (RFC6026)
* Privacy API
* Full support of rich presence
linphone-3.6.1 -- June 17, 2013
* fix memory leak with some video cameras on windows.
......
......@@ -181,6 +181,10 @@ static void process_request_event(void *sal, const belle_sip_request_event_t *ev
if (dialog) {
op=(SalOp*)belle_sip_dialog_get_application_data(dialog);
if (op==NULL && op->state==SalOpStateTerminated){
ms_warning("Receiving request for null or terminated op [%p], ignored",op);
return;
}
}else if (strcmp("INVITE",method)==0) {
op=sal_op_new((Sal*)sal);
op->dir=SalOpDirIncoming;
......
......@@ -128,8 +128,8 @@ void sal_op_message_fill_cbs(SalOp*op);
void sal_op_subscribe_fill_cbs(SalOp*op);
/*call transfer*/
void sal_op_process_refer(SalOp *op, const belle_sip_request_event_t *event);
void sal_op_call_process_notify(SalOp *op, const belle_sip_request_event_t *event);
void sal_op_process_refer(SalOp *op, const belle_sip_request_event_t *event, belle_sip_server_transaction_t *tr);
void sal_op_call_process_notify(SalOp *op, const belle_sip_request_event_t *event, belle_sip_server_transaction_t *tr);
/*create SalAuthInfo by copying username and realm from suth event*/
SalAuthInfo* sal_auth_info_create(belle_sip_auth_event_t* event) ;
void sal_add_pending_auth(Sal *sal, SalOp *op);
......
......@@ -23,10 +23,13 @@ static void call_set_released(SalOp* op){
op->state=SalOpStateTerminated;
op->base.root->callbacks.call_released(op);
}
/*used when the SalOp was ref'd by the dialog*/
static void call_set_released_and_unref(SalOp* op) {
call_set_released(op);
sal_op_unref(op);
}
static void call_set_error(SalOp* op,belle_sip_response_t* response){
SalError error=SalErrorUnknown;
SalReason sr=SalReasonUnknown;
......@@ -41,7 +44,6 @@ static void call_set_error(SalOp* op,belle_sip_response_t* response){
if (reason_header != NULL){
ms_free(reason);
}
call_set_released(op);
}
static void sdp_process(SalOp *h){
......@@ -124,60 +126,28 @@ static void process_dialog_terminated(void *ctx, const belle_sip_dialog_terminat
SalOp* op=(SalOp*)ctx;
if (op->dialog && op->dialog==belle_sip_dialog_terminated_get_dialog(event)) {
belle_sip_transaction_t* trans=belle_sip_dialog_get_last_transaction(op->dialog);
/*belle_sip_transaction_t* trans=belle_sip_dialog_get_last_transaction(op->dialog);*/
ms_message("Dialog [%p] terminated for op [%p]",belle_sip_dialog_terminated_get_dialog(event),op);
switch(belle_sip_dialog_get_previous_state(op->dialog)) {
case BELLE_SIP_DIALOG_CONFIRMED:
if (op->state!=SalOpStateTerminated && op->state!=SalOpStateTerminating) {
/*this is probably a "normal termination from a BYE*/
op->base.root->callbacks.call_terminated(op,op->dir==SalOpDirIncoming?sal_op_get_from(op):sal_op_get_to(op));
op->state=SalOpStateTerminating;
}
break;
case BELLE_SIP_DIALOG_NULL: {
if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(trans,belle_sip_server_transaction_t)) {
/*call declined very early, no need to notify call release*/
break;
}
}
default: {
belle_sip_response_t* response=belle_sip_transaction_get_response(trans);
int code = belle_sip_response_get_status_code(response);
if (BELLE_SIP_OBJECT_IS_INSTANCE_OF(trans,belle_sip_client_transaction_t)) {
switch (code) {
case 487:
call_set_released(op);
break;
case 401:
case 407:
if (op->state!=SalOpStateTerminating) {
/*normal termination for challenged dialog */
break;
}
default:
call_set_error(op,response);
case BELLE_SIP_DIALOG_CONFIRMED:
if (op->state!=SalOpStateTerminated && op->state!=SalOpStateTerminating) {
/*this is probably a "normal termination from a BYE*/
op->base.root->callbacks.call_terminated(op,op->dir==SalOpDirIncoming?sal_op_get_from(op):sal_op_get_to(op));
op->state=SalOpStateTerminating;
}
} else {
sal_op_ref(op); /*to make sure op is still there when call released is scheduled*/
belle_sip_main_loop_do_later(belle_sip_stack_get_main_loop(op->base.root->stack)
,(belle_sip_callback_t) call_set_released_and_unref
, op);
}
}
break;
default:
break;
}
belle_sip_object_unref(op->dialog);
op->dialog=NULL;
sal_op_unref(op);
belle_sip_main_loop_do_later(belle_sip_stack_get_main_loop(op->base.root->stack)
,(belle_sip_callback_t) call_set_released_and_unref
, op);
} else {
ms_error("dialog unknown for op ");
}
ms_message("Dialog [%p] terminated for op [%p]",belle_sip_dialog_terminated_get_dialog(event)
,op);
}
static void handle_sdp_from_response(SalOp* op,belle_sip_response_t* response) {
belle_sdp_session_description_t* sdp;
if ((sdp=belle_sdp_session_description_create(BELLE_SIP_MESSAGE(response)))) {
......@@ -205,21 +175,22 @@ static void call_response_event(void *op_base, const belle_sip_response_event_t
if (!client_transaction) {
ms_warning("Discarding state less response [%i] on op [%p]",code,op);
ms_warning("Discarding stateless response [%i] on op [%p]",code,op);
return;
}
req=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(client_transaction));
set_or_update_dialog(op,belle_sip_response_event_get_dialog(event));
dialog_state=op->dialog?belle_sip_dialog_get_state(op->dialog):BELLE_SIP_DIALOG_NULL;
ms_message("Op [%p] receiving call response [%i], dialog is [%p] in state [%s]",op,code,op->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 ( op->state == SalOpStateTerminating) {
if (op->state == SalOpStateTerminating) {
if (strcmp("CANCEL",belle_sip_request_get_method(belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(op->pending_client_trans))))!=0) {
if (code <200) {
if (code<200) {
cancelling_invite(op);
} else if (code<400) {
sal_op_send_request(op,belle_sip_dialog_create_request(op->dialog,"BYE"));
......@@ -229,32 +200,16 @@ static void call_response_event(void *op_base, const belle_sip_response_event_t
} else {
/*nop, already cancelled*/
}
break;
} else if (code >= 180 && code<300) {
handle_sdp_from_response(op,response);
op->base.root->callbacks.call_ringing(op);
break;
} else if (code>=300){
if (dialog_state==BELLE_SIP_DIALOG_NULL) {
call_set_error(op,response);
break;
} else {
/*nop let process_dialog_terminated manage error reporting*/
}
call_set_error(op,response);
if (op->dialog==NULL) call_set_released(op);
}
} else if (strcmp("CANCEL",belle_sip_request_get_method(req))==0
|| strcmp("BYE",belle_sip_request_get_method(req))==0) {
break;/*200ok for cancel or BYE*/
} else {
/*nop error*/
}
if (code >= 100 && code < 180) {
ms_message("call op [%p] receive [%i]",op,code);
} else {
ms_error("call op [%p] receive an unexpected answer [%i]",op,code);
}
}
break;
case BELLE_SIP_DIALOG_CONFIRMED: {
switch (op->state) {
case SalOpStateEarly:/*invite case*/
......@@ -278,7 +233,9 @@ static void call_response_event(void *op_base, const belle_sip_response_event_t
op->state=SalOpStateActive;
} else {
/*nop*/
if (code >= 300){
call_set_error(op,response);
}
}
break;
case SalOpStateTerminating:
......@@ -290,12 +247,9 @@ static void call_response_event(void *op_base, const belle_sip_response_event_t
break;
}
case BELLE_SIP_DIALOG_TERMINATED: {
/*if (code>=400 && strcmp("INVITE",belle_sip_request_get_method(req))==0){
if (code >= 300){
call_set_error(op,response);
call_set_released(op);
op->state=SalOpStateTerminated;
break;
}*/
}
break;
}
/* no break */
......@@ -366,6 +320,7 @@ static void process_sdp_for_invite(SalOp* op,belle_sip_request_t* invite) {
}else
op->sdp_offering=TRUE;
}
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;
......@@ -383,7 +338,7 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
}
if (strcmp("INVITE",belle_sip_request_get_method(req))==0) {
if (op->pending_server_trans)belle_sip_object_unref(op->pending_server_trans);
if (op->pending_server_trans) belle_sip_object_unref(op->pending_server_trans);
/*updating pending invite transaction*/
op->pending_server_trans=server_transaction;
belle_sip_object_ref(op->pending_server_trans);
......@@ -502,9 +457,9 @@ static void process_request_event(void *op_base, const belle_sip_request_event_t
resp=sal_op_create_response_from_request(op,req,200);
belle_sip_server_transaction_send_response(server_transaction,resp);
}else if (strcmp("REFER",belle_sip_request_get_method(req))==0) {
sal_op_process_refer(op,event);
sal_op_process_refer(op,event,server_transaction);
} else if (strcmp("NOTIFY",belle_sip_request_get_method(req))==0) {
sal_op_call_process_notify(op,event);
sal_op_call_process_notify(op,event,server_transaction);
} else if (strcmp("OPTIONS",belle_sip_request_get_method(req))==0) {
resp=sal_op_create_response_from_request(op,req,200);
belle_sip_server_transaction_send_response(server_transaction,resp);
......@@ -706,15 +661,18 @@ 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");
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);
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);
}
return -1;
}
SalMediaDescription * sal_call_get_remote_media_description(SalOp *h){
return h->base.remote_media;;
}
SalMediaDescription * sal_call_get_final_media_description(SalOp *h){
if (h->base.local_media && h->base.remote_media && !h->result){
sdp_process(h);
......@@ -763,8 +721,8 @@ int sal_call_terminate(SalOp *op){
} else {
/*just schedule call released*/
belle_sip_main_loop_do_later(belle_sip_stack_get_main_loop(op->base.root->stack)
,(belle_sip_callback_t) call_set_released
, op);
,(belle_sip_callback_t) call_set_released
, op);
}
break;
}
......
......@@ -168,14 +168,14 @@ int sal_call_notify_refer_state(SalOp *op, SalOp *newcall){
}
void sal_op_process_refer(SalOp *op, const belle_sip_request_event_t *event){
void sal_op_process_refer(SalOp *op, const belle_sip_request_event_t *event, belle_sip_server_transaction_t *server_transaction){
belle_sip_request_t* req = belle_sip_request_event_get_request(event);
belle_sip_header_refer_to_t *refer_to= belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_refer_to_t);
belle_sip_header_referred_by_t *referred_by= belle_sip_message_get_header_by_type(BELLE_SIP_MESSAGE(req),belle_sip_header_referred_by_t);
belle_sip_server_transaction_t* server_transaction = belle_sip_provider_create_server_transaction(op->base.root->prov,req);
belle_sip_response_t* resp;
belle_sip_uri_t* refer_to_uri;
char* refer_to_uri_str;
ms_message("Receiving REFER request on op [%p]",op);
if (refer_to) {
refer_to_uri=belle_sip_header_address_get_uri(BELLE_SIP_HEADER_ADDRESS(refer_to));
......@@ -200,8 +200,7 @@ void sal_op_process_refer(SalOp *op, const belle_sip_request_event_t *event){
}
void sal_op_call_process_notify(SalOp *op, const belle_sip_request_event_t *event){
belle_sip_server_transaction_t* server_transaction = belle_sip_provider_create_server_transaction(op->base.root->prov,belle_sip_request_event_get_request(event));
void sal_op_call_process_notify(SalOp *op, const belle_sip_request_event_t *event, belle_sip_server_transaction_t* server_transaction){
belle_sip_request_t* req = belle_sip_request_event_get_request(event);
const char* body = belle_sip_message_get_body(BELLE_SIP_MESSAGE(req));
belle_sip_header_t* header_event=belle_sip_message_get_header(BELLE_SIP_MESSAGE(req),"Event");
......
......@@ -31,7 +31,7 @@ SalOp * sal_op_new(Sal *sal){
void sal_op_release(SalOp *op){
op->state=SalOpStateTerminated;
sal_op_set_user_pointer(op,NULL);/*mandatory because releasing op doesn not mean freeing op. Make sure back pointer will not be used later*/
sal_op_set_user_pointer(op,NULL);/*mandatory because releasing op doesn't not mean freeing op. Make sure back pointer will not be used later*/
if (op->refresher) {
belle_sip_refresher_stop(op->refresher);
}
......@@ -292,7 +292,6 @@ SalReason sal_reason_to_sip_code(SalReason r){
case SalReasonUnknown:
ret=400;
break;
case SalReasonBusy:
ret=486;
break;
......@@ -320,6 +319,9 @@ SalReason sal_reason_to_sip_code(SalReason r){
case SalReasonServiceUnavailable:
ret=503;
break;
case SalReasonRequestPending:
ret=491;
break;
}
return ret;
}
......@@ -354,6 +356,10 @@ void sal_compute_sal_errors_from_code(int code ,SalError* sal_err,SalReason* sal
break;
case 487:
break;
case 491:
*sal_err=SalErrorFailure;
*sal_reason=SalReasonRequestPending;
break;
case 600:
*sal_err=SalErrorFailure;
*sal_reason=SalReasonDoNotDisturb;
......
......@@ -47,6 +47,7 @@ void sal_add_presence_info(SalOp *op, belle_sip_message_t *notify, SalPresenceMo
static void presence_process_io_error(void *user_ctx, const belle_sip_io_error_event_t *event){
ms_error("presence_process_io_error not implemented yet");
}
static void presence_process_dialog_terminated(void *ctx, const belle_sip_dialog_terminated_event_t *event) {
SalOp* op= (SalOp*)ctx;
if (op->dialog) {
......
......@@ -35,7 +35,7 @@ static void publish_refresher_listener ( const belle_sip_refresher_t* refresher
}
}
/*presence publish */
int sal_publish_presence(SalOp *op, const char *from, const char *to, SalPresenceModel *presence){
int sal_publish_presence(SalOp *op, const char *from, const char *to, int expires, SalPresenceModel *presence){
belle_sip_request_t *req=NULL;
if(!op->refresher || !belle_sip_refresher_get_transaction(op->refresher)) {
if (from)
......@@ -47,13 +47,13 @@ int sal_publish_presence(SalOp *op, const char *from, const char *to, SalPresenc
req=sal_op_build_request(op,"PUBLISH");
belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),belle_sip_header_create("Event","presence"));
sal_add_presence_info(op,BELLE_SIP_MESSAGE(req),presence);
return sal_op_send_and_create_refresher(op,req,600,publish_refresher_listener);
return sal_op_send_and_create_refresher(op,req,expires,publish_refresher_listener);
} else {
/*update presence status*/
const belle_sip_client_transaction_t* last_publish_trans=belle_sip_refresher_get_transaction(op->refresher);
belle_sip_request_t* last_publish=belle_sip_transaction_get_request(BELLE_SIP_TRANSACTION(last_publish_trans));
sal_add_presence_info(op,BELLE_SIP_MESSAGE(last_publish),presence);
return belle_sip_refresher_refresh(op->refresher,BELLE_SIP_REFRESHER_REUSE_EXPIRES);
return belle_sip_refresher_refresh(op->refresher,expires);
}
}
......
......@@ -646,6 +646,11 @@ static void call_failure(SalOp *op, SalError error, SalReason sr, const char *de
if (lc->vtable.display_status)
lc->vtable.display_status(lc,msg);
break;
case SalReasonRequestPending:
/*restore previous state, the application will decide to resubmit the action if relevant*/
linphone_call_set_state(call,call->prevstate,msg);
return;
break;
default:
if (lc->vtable.display_status)
lc->vtable.display_status(lc,_("Call failed."));
......
......@@ -700,6 +700,7 @@ void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const
LinphoneCore *lc=call->core;
if (call->state!=cstate){
call->prevstate=call->state;
if (call->state==LinphoneCallEnd || call->state==LinphoneCallError){
if (cstate!=LinphoneCallReleased){
ms_warning("Spurious call state change from %s to %s, ignored.",linphone_call_state_to_string(call->state),
......@@ -2585,7 +2586,7 @@ void linphone_call_set_contact_op(LinphoneCall* call) {
if (contact){
sal_op_set_contact(call->op, contact);
#ifndef USE_BELLESIP
ms_free(contact);
ms_free(contact);
#else
linphone_address_destroy(contact);
#endif
......
......@@ -2813,7 +2813,7 @@ void linphone_core_notify_incoming_call(LinphoneCore *lc, LinphoneCall *call){
if (sal_media_description_empty(md) || linphone_core_incompatible_security(lc,md)){
sal_call_decline(call->op,SalReasonMedia,NULL);
linphone_core_del_call(lc,call);
linphone_call_ref(call);
linphone_call_unref(call);
return;
}
}
......@@ -3327,7 +3327,7 @@ int linphone_core_terminate_call(LinphoneCore *lc, LinphoneCall *the_call)
switch (call->state) {
case LinphoneCallReleased:
case LinphoneCallEnd:
ms_warning("No need to terminate a call [%p] in sate [%s]",call,linphone_call_state_to_string(call->state));
ms_warning("No need to terminate a call [%p] in state [%s]",call,linphone_call_state_to_string(call->state));
return -1;
case LinphoneCallIncomingReceived:
case LinphoneCallIncomingEarlyMedia:
......
......@@ -1219,6 +1219,10 @@ LinphoneReason linphone_reason_from_sal(SalReason r){
break;
case SalReasonServiceUnavailable:
ret=LinphoneReasonIOError;
break;
case SalReasonRequestPending:
ret=LinphoneReasonNone;
break;
}
return ret;
}
......
......@@ -163,7 +163,8 @@ struct _LinphoneCall
char localip[LINPHONE_IPADDR_SIZE]; /* our best guess for local ipaddress for this call */
time_t start_time; /*time at which the call was initiated*/
time_t media_start_time; /*time at which it was accepted, media streams established*/
LinphoneCallState state;
LinphoneCallState state;
LinphoneCallState prevstate;
LinphoneCallState transfer_state; /*idle if no transfer*/
LinphoneReason reason;
LinphoneProxyConfig *dest_proxy;
......@@ -384,7 +385,6 @@ struct _LinphoneProxyConfig
char *realm;
char *contact_params;
int expires;
int reg_time;
SalOp *op;
char *type;
struct _SipSetupContext *ssctx;
......@@ -396,6 +396,8 @@ struct _LinphoneProxyConfig
bool_t reg_sendregister;
bool_t publish;
bool_t dial_escape_plus;
bool_t send_publish;
bool_t pad[3];
void* user_data;
time_t deletion_date;
LinphoneReason error;
......
......@@ -252,11 +252,6 @@ void linphone_proxy_config_edit(LinphoneProxyConfig *obj){
sal_unregister(obj->op);
}
}
if (obj->publish_op){
/*we should certainly cancel our publish by some manner*/
sal_op_release(obj->publish_op);
obj->publish_op=NULL;
}
}
void linphone_proxy_config_apply(LinphoneProxyConfig *obj,LinphoneCore *lc)
......@@ -858,7 +853,7 @@ int linphone_proxy_config_send_publish(LinphoneProxyConfig *proxy, LinphonePrese
sal_op_set_from(proxy->publish_op,linphone_proxy_config_get_identity(proxy));
sal_op_set_to(proxy->publish_op,linphone_proxy_config_get_identity(proxy));
}
err=sal_publish_presence(proxy->publish_op,NULL,NULL,(SalPresenceModel *)presence);
err=sal_publish_presence(proxy->publish_op,NULL,NULL,proxy->expires,(SalPresenceModel *)presence);
return err;
}
......@@ -1186,10 +1181,12 @@ void linphone_proxy_config_update(LinphoneProxyConfig *cfg){
if (can_register(cfg)){
linphone_proxy_config_register(cfg);
cfg->commit=FALSE;
if (cfg->publish) cfg->send_publish=TRUE;
}
}
if (cfg->publish && cfg->publish_op==NULL && cfg->state==LinphoneRegistrationOk){
if (cfg->send_publish && (cfg->state==LinphoneRegistrationOk || cfg->state==LinphoneRegistrationCleared)){
linphone_proxy_config_send_publish(cfg,lc->presence_model);
cfg->send_publish=FALSE;
}
}
......
......@@ -273,7 +273,8 @@ typedef enum SalReason{
SalReasonMedia,
SalReasonForbidden,
SalReasonUnknown,
SalReasonServiceUnavailable
SalReasonServiceUnavailable,
SalReasonRequestPending
}SalReason;
const char* sal_reason_to_string(const SalReason reason);
......@@ -538,7 +539,7 @@ int sal_notify_presence(SalOp *op, SalPresenceModel *presence);
int sal_notify_presence_close(SalOp *op);
/*presence publish */
int sal_publish_presence(SalOp *op, const char *from, const char *to, SalPresenceModel *presence);
int sal_publish_presence(SalOp *op, const char *from, const char *to, int expires, SalPresenceModel *presence);
/*ping: main purpose is to obtain its own contact address behind firewalls*/
......
......@@ -336,22 +336,22 @@ static void cancelled_ringing_call(void) {
static void early_declined_call(void) {
LinphoneCoreManager* marie = linphone_core_manager_new( "marie_rc");
LinphoneCoreManager* pauline = linphone_core_manager_new( "pauline_rc");
LinphoneCallLog* in_call;
LinphoneCallLog* out_call_log;
LinphoneCall* out_call;
linphone_core_set_max_calls(marie->lc,0);
out_call = linphone_core_invite(pauline->lc,"marie");
linphone_call_ref(out_call);
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallReleased,1));
CU_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_LinphoneCallError,1));
CU_ASSERT_EQUAL(pauline->stat.number_of_LinphoneCallError,1);
/* FIXME http://git.linphone.org/mantis/view.php?id=757
CU_ASSERT_EQUAL(ms_list_size(linphone_core_get_call_logs(marie->lc)),1);
CU_ASSERT_EQUAL(linphone_call_get_reason(out_call),LinphoneReasonDeclined);
CU_ASSERT_EQUAL(linphone_call_get_reason(out_call),LinphoneReasonBusy);
*/
if (ms_list_size(linphone_core_get_call_logs(marie->lc))>0) {
CU_ASSERT_PTR_NOT_NULL(in_call=(LinphoneCallLog*)(linphone_core_get_call_logs(marie->lc)->data));
CU_ASSERT_EQUAL(linphone_call_log_get_status(in_call),LinphoneCallDeclined);
if (ms_list_size(linphone_core_get_call_logs(pauline->lc))>0) {
CU_ASSERT_PTR_NOT_NULL(out_call_log=(LinphoneCallLog*)(linphone_core_get_call_logs(pauline->lc)->data));
CU_ASSERT_EQUAL(linphone_call_log_get_status(out_call_log),LinphoneCallAborted);
}
linphone_call_unref(out_call);
linphone_core_manager_destroy(marie);
......
......@@ -99,29 +99,29 @@ static LinphoneCore* configure_lc_from(LinphoneCoreVTable* v_table, const char*
if (path==NULL) path=".";
if (path && file){
snprintf(filepath, sizeof(filepath), "%s/%s", path, file);
if (file){
sprintf(filepath, "%s/%s", path, file);
CU_ASSERT_TRUE_FATAL(ortp_file_exist(filepath)==0);
}
lc = linphone_core_new(v_table,NULL,*filepath!='\0' ? filepath : NULL,NULL);
if (path){
#ifndef ANDROID
snprintf(rootcapath, sizeof(rootcapath), "%s/certificates/cacert.pem", path);
snprintf(rootcapath, sizeof(rootcapath), "%s/certificates/cacert.pem", path);
#else
snprintf(rootcapath, sizeof(rootcapath), "%s/cacert.pem", path);
snprintf(rootcapath, sizeof(rootcapath), "%s/cacert.pem", path);
#endif
linphone_core_set_root_ca(lc,rootcapath);
linphone_core_set_root_ca(lc,rootcapath);
sprintf(dnsuserhostspath, "%s/%s", path, userhostsfile);
sal_set_dns_user_hosts_file(lc->sal, dnsuserhostspath);
sprintf(dnsuserhostspath, "%s/%s", path, userhostsfile);
sal_set_dns_user_hosts_file(lc->sal, dnsuserhostspath);
sprintf(ringpath, "%s/%s", path, "oldphone.wav");
sprintf(ringbackpath, "%s/%s", path, "ringback.wav");
linphone_core_set_ring(lc, ringpath);
linphone_core_set_ringback(lc, ringbackpath);
sprintf(ringpath, "%s/%s", path, "oldphone.wav");
sprintf(ringbackpath, "%s/%s", path, "ringback.wav");
linphone_core_set_ring(lc, ringpath);
linphone_core_set_ringback(lc, ringbackpath);
}
return lc;
}
......
37.59.129.74 sip.example.org sipopen.example.org auth.example.org auth1.example.org auth2.example.org
94.23.19.176 sip.example.org sipopen.example.org auth.example.org auth1.example.org auth2.example.org
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