From 95098f055aaaa3c0ab17e6160a0de4bc5897aad5 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 22 Mar 2017 14:42:15 +0100 Subject: [PATCH 1/8] Make LinphoneErrorInfo a belle-sip object. Add new accessors, and make it able to take Reason headers in incoming requests (feature to be tested) --- coreapi/bellesip_sal/sal_impl.h | 1 + coreapi/bellesip_sal/sal_op_call.c | 10 +- coreapi/bellesip_sal/sal_op_events.c | 6 +- coreapi/bellesip_sal/sal_op_impl.c | 29 ++++- coreapi/bellesip_sal/sal_op_message.c | 4 +- coreapi/bellesip_sal/sal_op_publish.c | 2 +- coreapi/bellesip_sal/sal_op_registration.c | 2 +- coreapi/callbacks.c | 3 +- coreapi/chat.c | 8 +- coreapi/error_info.c | 139 +++++++++++++++++++-- coreapi/event.c | 5 +- coreapi/linphonecall.c | 27 ++-- coreapi/linphonecore.c | 3 +- coreapi/linphonecore_jni.cc | 2 +- coreapi/private.h | 28 ++++- coreapi/proxy.c | 7 +- include/linphone/error_info.h | 37 +++++- include/sal/sal.h | 4 +- mediastreamer2 | 2 +- oRTP | 2 +- tester/register_tester.c | 2 +- 21 files changed, 266 insertions(+), 57 deletions(-) diff --git a/coreapi/bellesip_sal/sal_impl.h b/coreapi/bellesip_sal/sal_impl.h index 48e477fde..9ed481d11 100644 --- a/coreapi/bellesip_sal/sal_impl.h +++ b/coreapi/bellesip_sal/sal_impl.h @@ -87,6 +87,7 @@ struct SalOp{ SalOpBase base; const belle_sip_listener_callbacks_t *callbacks; SalErrorInfo error_info; + SalErrorInfo reason_error_info; 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; diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index e3d5571e4..6b4bc13d6 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -150,7 +150,7 @@ static void call_process_io_error(void *user_ctx, const belle_sip_io_error_event if (op->pending_client_trans && (belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(op->pending_client_trans)) == BELLE_SIP_TRANSACTION_INIT)) { - sal_error_info_set(&op->error_info, SalReasonIOError, 503, "IO error", NULL); + sal_error_info_set(&op->error_info, SalReasonIOError, "SIP", 503, "IO error", NULL); op->base.root->callbacks.call_failure(op); if (!op->dialog || belle_sip_dialog_get_state(op->dialog) != BELLE_SIP_DIALOG_CONFIRMED){ @@ -386,7 +386,7 @@ static void call_process_timeout(void *user_ctx, const belle_sip_timeout_event_t if (!op->dialog) { /*call terminated very early*/ - sal_error_info_set(&op->error_info,SalReasonRequestTimeout,408,"Request timeout",NULL); + sal_error_info_set(&op->error_info, SalReasonRequestTimeout, "SIP", 408, "Request timeout", NULL); op->base.root->callbacks.call_failure(op); op->state = SalOpStateTerminating; call_set_released(op); @@ -421,7 +421,7 @@ static void call_process_transaction_terminated(void *user_ctx, const belle_sip_ release_call=TRUE; }else if (op->state == SalOpStateEarly && code < 200){ /*call terminated early*/ - sal_error_info_set(&op->error_info,SalReasonIOError,503,"I/O error",NULL); + sal_error_info_set(&op->error_info, SalReasonIOError, "SIP", 503, "I/O error", NULL); op->state = SalOpStateTerminating; op->base.root->callbacks.call_failure(op); release_call=TRUE; @@ -1004,9 +1004,9 @@ int sal_call_update(SalOp *op, const char *subject, bool_t no_user_consent){ } /*it failed why ?*/ if (belle_sip_dialog_request_pending(op->dialog)) - sal_error_info_set(&op->error_info,SalReasonRequestPending,491,NULL,NULL); + sal_error_info_set(&op->error_info,SalReasonRequestPending, "SIP", 491,NULL,NULL); else - sal_error_info_set(&op->error_info,SalReasonUnknown,500,NULL,NULL); + sal_error_info_set(&op->error_info,SalReasonUnknown, "SIP", 500,NULL,NULL); return -1; } diff --git a/coreapi/bellesip_sal/sal_op_events.c b/coreapi/bellesip_sal/sal_op_events.c index 1d03c09a5..d3198fde9 100644 --- a/coreapi/bellesip_sal/sal_op_events.c +++ b/coreapi/bellesip_sal/sal_op_events.c @@ -52,7 +52,7 @@ static void subscribe_refresher_listener (belle_sip_refresher_t* refresher if (status_code == 503) { /*refresher returns 503 for IO error*/ reason = SalReasonIOError; } - sal_error_info_set(&op->error_info,reason,status_code,reason_phrase,NULL); + sal_error_info_set(&op->error_info, reason, "SIP", status_code,reason_phrase,NULL); op->base.root->callbacks.subscribe_response(op,sss, will_retry); }else if (status_code==0){ op->base.root->callbacks.on_expire(op); @@ -72,7 +72,7 @@ static void subscribe_process_io_error(void *user_ctx, const belle_sip_io_error_ /*this is handling outgoing out-of-dialog notifies*/ if (strcmp(method,"NOTIFY")==0){ SalErrorInfo *ei=&op->error_info; - sal_error_info_set(ei,SalReasonIOError,0,NULL,NULL); + sal_error_info_set(ei,SalReasonIOError, "SIP", 0,NULL,NULL); op->base.root->callbacks.on_notify_response(op); } } @@ -131,7 +131,7 @@ static void subscribe_process_timeout(void *user_ctx, const belle_sip_timeout_ev /*this is handling outgoing out-of-dialog notifies*/ if (strcmp(method,"NOTIFY")==0){ SalErrorInfo *ei=&op->error_info; - sal_error_info_set(ei,SalReasonRequestTimeout,0,NULL,NULL); + sal_error_info_set(ei,SalReasonRequestTimeout, "SIP", 0,NULL,NULL); op->base.root->callbacks.on_notify_response(op); } } diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c index 135b53c4c..d7ddaa959 100644 --- a/coreapi/bellesip_sal/sal_op_impl.c +++ b/coreapi/bellesip_sal/sal_op_impl.c @@ -580,17 +580,22 @@ void sal_error_info_reset(SalErrorInfo *ei){ ms_free(ei->full_string); ei->full_string=NULL; } + if (ei->protocol){ + ms_free(ei->protocol); + ei->protocol = NULL; + } ei->protocol_code=0; ei->reason=SalReasonNone; } -void sal_error_info_set(SalErrorInfo *ei, SalReason reason, int code, const char *status_string, const char *warning){ +void sal_error_info_set(SalErrorInfo *ei, SalReason reason, const char *protocol, int code, const char *status_string, const char *warning){ sal_error_info_reset(ei); - if (reason==SalReasonUnknown) ei->reason=_sal_reason_from_sip_code(code); + if (reason==SalReasonUnknown && strcmp(protocol, "SIP") == 0) ei->reason=_sal_reason_from_sip_code(code); else ei->reason=reason; ei->protocol_code=code; ei->status_string=status_string ? ms_strdup(status_string) : NULL; ei->warnings=warning ? ms_strdup(warning) : NULL; + ei->protocol = protocol ? ms_strdup(protocol) : NULL; if (ei->status_string){ if (ei->warnings) ei->full_string=ms_strdup_printf("%s %s",ei->status_string,ei->warnings); @@ -598,24 +603,36 @@ void sal_error_info_set(SalErrorInfo *ei, SalReason reason, int code, const char } } +void sal_op_set_reason_error_info(SalOp *op, belle_sip_message_t *msg){ + belle_sip_header_reason_t* reason_header = belle_sip_message_get_header_by_type(msg,belle_sip_header_reason_t); + if (reason_header){ + SalErrorInfo *ei=&op->reason_error_info; + const char *protocol = belle_sip_header_reason_get_protocol(reason_header); + int code = belle_sip_header_reason_get_cause(reason_header); + const char *text = belle_sip_header_reason_get_text(reason_header); + sal_error_info_set(ei, SalReasonUnknown, protocol, code, text, NULL); + } +} + void sal_op_set_error_info_from_response(SalOp *op, belle_sip_response_t *response){ int code = belle_sip_response_get_status_code(response); const char *reason_phrase=belle_sip_response_get_reason_phrase(response); - /*Remark: the reason header is to be used mainly in SIP requests, thus the use and prototype of this function should be changed.*/ - belle_sip_header_t* reason_header = belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),"Reason"); belle_sip_header_t *warning=belle_sip_message_get_header(BELLE_SIP_MESSAGE(response),"Warning"); SalErrorInfo *ei=&op->error_info; const char *warnings; warnings=warning ? belle_sip_header_get_unparsed_value(warning) : NULL; - if (warnings==NULL) warnings=reason_header ? belle_sip_header_get_unparsed_value(reason_header) : NULL; - sal_error_info_set(ei,SalReasonUnknown,code,reason_phrase,warnings); + sal_error_info_set(ei,SalReasonUnknown,"SIP", code,reason_phrase,warnings); } const SalErrorInfo *sal_op_get_error_info(const SalOp *op){ return &op->error_info; } +const SalErrorInfo * sal_op_get_reason_error_info(const SalOp *op){ + return &op->reason_error_info; +} + static void unlink_op_with_dialog(SalOp *op, belle_sip_dialog_t* dialog){ belle_sip_dialog_set_application_data(dialog,NULL); sal_op_unref(op); diff --git a/coreapi/bellesip_sal/sal_op_message.c b/coreapi/bellesip_sal/sal_op_message.c index 348e271ec..cfb73763a 100644 --- a/coreapi/bellesip_sal/sal_op_message.c +++ b/coreapi/bellesip_sal/sal_op_message.c @@ -34,12 +34,12 @@ static void process_error( SalOp* op) { static void process_io_error(void *user_ctx, const belle_sip_io_error_event_t *event){ SalOp* op = (SalOp*)user_ctx; - sal_error_info_set(&op->error_info,SalReasonIOError,503,"IO Error",NULL); + sal_error_info_set(&op->error_info,SalReasonIOError, "SIP", 503,"IO Error",NULL); process_error(op); } static void process_timeout(void *user_ctx, const belle_sip_timeout_event_t *event) { SalOp* op=(SalOp*)user_ctx; - sal_error_info_set(&op->error_info,SalReasonRequestTimeout,408,"Request timeout",NULL); + sal_error_info_set(&op->error_info,SalReasonRequestTimeout, "SIP", 408,"Request timeout",NULL); process_error(op); } diff --git a/coreapi/bellesip_sal/sal_op_publish.c b/coreapi/bellesip_sal/sal_op_publish.c index 7e832c6bb..2de596519 100644 --- a/coreapi/bellesip_sal/sal_op_publish.c +++ b/coreapi/bellesip_sal/sal_op_publish.c @@ -36,7 +36,7 @@ static void publish_refresher_listener (belle_sip_refresher_t* refresher sip_etag_string = belle_sip_header_get_unparsed_value(sip_etag); } sal_op_set_entity_tag(op, sip_etag_string); - sal_error_info_set(&op->error_info,SalReasonUnknown,status_code,reason_phrase,NULL); + sal_error_info_set(&op->error_info,SalReasonUnknown, "SIP", status_code,reason_phrase,NULL); sal_op_assign_recv_headers(op,(belle_sip_message_t*)response); op->base.root->callbacks.on_publish_response(op); } diff --git a/coreapi/bellesip_sal/sal_op_registration.c b/coreapi/bellesip_sal/sal_op_registration.c index 72b57b773..1d0ccbb3e 100644 --- a/coreapi/bellesip_sal/sal_op_registration.c +++ b/coreapi/bellesip_sal/sal_op_registration.c @@ -32,7 +32,7 @@ static void register_refresher_listener (belle_sip_refresher_t* refresher /*only take first one for now*/ op->auth_info=sal_auth_info_create((belle_sip_auth_event_t*)(belle_sip_refresher_get_auth_events(refresher)->data)); } - sal_error_info_set(&op->error_info,SalReasonUnknown,status_code,reason_phrase,NULL); + sal_error_info_set(&op->error_info,SalReasonUnknown, "SIP", status_code,reason_phrase,NULL); if (status_code>=200){ sal_op_assign_recv_headers(op,(belle_sip_message_t*)response); } diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index ea1f69d7b..9dbd95dd8 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -818,7 +818,8 @@ static void call_terminated(SalOp *op, const char *from){ break; case LinphoneCallIncomingReceived: case LinphoneCallIncomingEarlyMedia: - sal_error_info_set(&call->non_op_error,SalReasonRequestTimeout,0,"Incoming call cancelled",NULL); + linphone_error_info_set(call->ei, LinphoneReasonNotAnswered, 0, "Incoming call cancelled", NULL); + call->non_op_error = TRUE; break; default: break; diff --git a/coreapi/chat.c b/coreapi/chat.c index cfcfae604..761195ad6 100644 --- a/coreapi/chat.c +++ b/coreapi/chat.c @@ -463,7 +463,7 @@ void _linphone_chat_room_send_message(LinphoneChatRoom *cr, LinphoneChatMessage } if (retval > 0) { - sal_error_info_set((SalErrorInfo *)sal_op_get_error_info(op), SalReasonNotAcceptable, retval, "Unable to encrypt IM", NULL); + sal_error_info_set((SalErrorInfo *)sal_op_get_error_info(op), SalReasonNotAcceptable, "SIP", retval, "Unable to encrypt IM", NULL); store_or_update_chat_message(msg); linphone_chat_message_update_state(msg, LinphoneChatMessageStateNotDelivered); linphone_chat_message_unref(msg); @@ -1656,6 +1656,8 @@ void linphone_chat_message_destroy(LinphoneChatMessage *msg) { static void _linphone_chat_message_destroy(LinphoneChatMessage *msg) { if (msg->op) sal_op_release(msg->op); + if (msg->ei) + linphone_error_info_unref(msg->ei); if (msg->message) ms_free(msg->message); if (msg->external_body_url) @@ -1706,7 +1708,9 @@ static void linphone_chat_message_release(LinphoneChatMessage *msg) { } const LinphoneErrorInfo *linphone_chat_message_get_error_info(const LinphoneChatMessage *msg) { - return linphone_error_info_from_sal_op(msg->op); + if (!msg->ei) ((LinphoneChatMessage*)msg)->ei = linphone_error_info_new(); /*let's do it mutable*/ + linphone_error_info_from_sal_op(msg->ei, msg->op); + return msg->ei; } LinphoneReason linphone_chat_message_get_reason(LinphoneChatMessage *msg) { diff --git a/coreapi/error_info.c b/coreapi/error_info.c index 102c68e10..288b8e793 100644 --- a/coreapi/error_info.c +++ b/coreapi/error_info.c @@ -20,6 +20,49 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "linphone/core.h" #include "private.h" +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneErrorInfo); + +#define STRING_RESET(field) if (field) ms_free(field); field = NULL; + + + +static void error_info_destroy(LinphoneErrorInfo *ei){ + if (ei->protocol) ms_free(ei->protocol); + if (ei->phrase) ms_free(ei->phrase); + if (ei->warnings) ms_free(ei->phrase); + if (ei->full_string) ms_free(ei->full_string); +} + +static void error_info_clone(LinphoneErrorInfo *ei, const LinphoneErrorInfo *other){ + ei->protocol = ms_strdup_safe(other->protocol); + ei->phrase = ms_strdup_safe(other->phrase); + ei->warnings = ms_strdup_safe(other->phrase); + ei->full_string = ms_strdup_safe(other->full_string); +} + +BELLE_SIP_INSTANCIATE_VPTR(LinphoneErrorInfo, belle_sip_object_t, + error_info_destroy, // destroy + error_info_clone, // clone + NULL, // Marshall + FALSE +); + +LinphoneErrorInfo *linphone_error_info_new(void){ + LinphoneErrorInfo *ei = belle_sip_object_new(LinphoneErrorInfo); + return ei; +} + +LinphoneErrorInfo* linphone_error_info_ref ( LinphoneErrorInfo* ei ) { + return (LinphoneErrorInfo*) belle_sip_object_ref(ei); +} + +void linphone_error_info_unref ( LinphoneErrorInfo* ei ) { + belle_sip_object_unref(ei); +} + +void linphone_error_info_set_reason ( LinphoneErrorInfo* ei, LinphoneReason reason ) { + ei->reason = reason; +} const char *linphone_reason_to_string(LinphoneReason err){ switch(err) { @@ -112,23 +155,101 @@ int linphone_reason_to_error_code(LinphoneReason reason) { return 400; } +void linphone_error_info_reset(LinphoneErrorInfo *ei){ + ei->reason = LinphoneReasonNone; + STRING_RESET(ei->protocol); + STRING_RESET(ei->phrase); + STRING_RESET(ei->full_string); + STRING_RESET(ei->warnings); + ei->protocol_code = 0; + if (ei->sub_ei) { + linphone_error_info_unref(ei->sub_ei); + ei->sub_ei = NULL; + } +} + +void linphone_error_info_from_sal(LinphoneErrorInfo *ei, const SalErrorInfo *sei){ + ei->reason = linphone_reason_from_sal(sei->reason); + ei->phrase = ms_strdup_safe(sei->status_string); + ei->full_string = ms_strdup_safe(sei->full_string); + ei->warnings = ms_strdup_safe(sei->warnings); + ei->protocol_code = sei->protocol_code; + ei->protocol = ms_strdup_safe(sei->protocol); +} + +/* If a reason header is provided (in reason_ei), then create a sub LinphoneErrorInfo attached to the first one, unless the reason header + is in the request, in which case no primary error is given.*/ +void linphone_error_info_from_sal_reason_ei(LinphoneErrorInfo *ei, const SalErrorInfo *reason_ei){ + if (ei->reason == LinphoneReasonNone){ + /*no primary error given*/ + linphone_error_info_reset(ei); + linphone_error_info_from_sal(ei, reason_ei); + return; + } + + if (ei->sub_ei){ + if (reason_ei->reason == SalReasonNone){ + linphone_error_info_unref(ei->sub_ei); + ei->sub_ei = NULL; + } + }else{ + if (reason_ei->reason != SalReasonNone){ + ei->sub_ei = linphone_error_info_new(); + } + } + if (reason_ei->reason != SalReasonNone){ + linphone_error_info_from_sal(ei->sub_ei, reason_ei); + } +} + +void linphone_error_info_from_sal_op(LinphoneErrorInfo *ei, const SalOp *op){ + if (op==NULL) { + /*leave previous values in LinphoneErrorInfo, the op may have been released already.*/ + return; + }else{ + const SalErrorInfo *sei; + linphone_error_info_reset(ei); + sei = sal_op_get_error_info(op); + linphone_error_info_from_sal(ei, sei); + sei = sal_op_get_reason_error_info(op); + linphone_error_info_from_sal_reason_ei(ei, sei); + } +} + +void linphone_error_info_set(LinphoneErrorInfo *ei, LinphoneReason reason, int code, const char *status_string, const char *warning){ + linphone_error_info_reset(ei); + ei->reason = reason; + ei->protocol_code = code; + ei->phrase = ms_strdup_safe(status_string); + ei->warnings = ms_strdup_safe(warning); +} + LinphoneReason linphone_error_info_get_reason(const LinphoneErrorInfo *ei) { - const SalErrorInfo *sei = (const SalErrorInfo *)ei; - return linphone_reason_from_sal(sei->reason); + return ei->reason; +} + +const char *linphone_error_info_get_protocol(const LinphoneErrorInfo *ei){ + return ei->protocol; } const char *linphone_error_info_get_phrase(const LinphoneErrorInfo *ei) { - const SalErrorInfo *sei = (const SalErrorInfo *)ei; - return sei->status_string; + return ei->phrase; } -const char *linphone_error_info_get_details(const LinphoneErrorInfo *ei) { - const SalErrorInfo *sei = (const SalErrorInfo *)ei; - return sei->warnings; +/*deprecated, kept for binary compatibility*/ +const char *linphone_error_info_get_details(const LinphoneErrorInfo *ei){ + return linphone_error_info_get_warnings(ei); +} + +const char *linphone_error_info_get_warnings(const LinphoneErrorInfo *ei) { + return ei->warnings; } int linphone_error_info_get_protocol_code(const LinphoneErrorInfo *ei) { - const SalErrorInfo *sei = (const SalErrorInfo *)ei; - return sei->protocol_code; + return ei->protocol_code; +} + +const LinphoneErrorInfo * linphone_error_info_get_sub_error_info(const LinphoneErrorInfo *ei){ + return ei->sub_ei; } diff --git a/coreapi/event.c b/coreapi/event.c index eafea9947..2f331c7be 100644 --- a/coreapi/event.c +++ b/coreapi/event.c @@ -156,7 +156,9 @@ LinphonePublishState linphone_event_get_publish_state(const LinphoneEvent *lev){ } const LinphoneErrorInfo *linphone_event_get_error_info(const LinphoneEvent *lev){ - return linphone_error_info_from_sal_op(lev->op); + if (!lev->ei) ((LinphoneEvent*)lev)->ei = linphone_error_info_new(); + linphone_error_info_from_sal_op(lev->ei, lev->op); + return lev->ei; } LinphoneReason linphone_event_get_reason(const LinphoneEvent *lev){ @@ -393,6 +395,7 @@ LinphoneEvent *linphone_event_ref(LinphoneEvent *lev){ } static void linphone_event_destroy(LinphoneEvent *lev){ + if (lev->ei) linphone_error_info_unref(lev->ei); if (lev->op) sal_op_release(lev->op); if (lev->send_custom_headers) sal_custom_header_free(lev->send_custom_headers); ms_free(lev->name); diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 916d03856..afe792887 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -1000,6 +1000,7 @@ static void port_config_set(LinphoneCall *call, int stream_index, int min_port, static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from, LinphoneAddress *to){ int min_port, max_port; ms_message("New LinphoneCall [%p] initialized (LinphoneCore version: %s)",call,linphone_core_get_version()); + call->ei = linphone_error_info_new(); call->core->send_call_stats_periodical_updates = lp_config_get_int(call->core->config, "misc", "send_call_stats_periodical_updates", 0); call->main_audio_stream_index = LINPHONE_CALL_STATS_AUDIO; call->main_video_stream_index = LINPHONE_CALL_STATS_VIDEO; @@ -1544,9 +1545,8 @@ static void linphone_call_free_media_resources(LinphoneCall *call){ static void linphone_call_set_released(LinphoneCall *call){ if (call->op!=NULL) { /*transfer the last error so that it can be obtained even in Released state*/ - if (call->non_op_error.reason==SalReasonNone){ - const SalErrorInfo *ei=sal_op_get_error_info(call->op); - sal_error_info_set(&call->non_op_error,ei->reason,ei->protocol_code,ei->status_string,ei->warnings); + if (!call->non_op_error){ + linphone_error_info_from_sal_op(call->ei, call->op); } /* so that we cannot have anymore upcalls for SAL concerning this call*/ @@ -1857,7 +1857,7 @@ static void linphone_call_destroy(LinphoneCall *obj){ } if (obj->onhold_file) ms_free(obj->onhold_file); - sal_error_info_reset(&obj->non_op_error); + if (obj->ei) linphone_error_info_unref(obj->ei); } LinphoneCall * linphone_call_ref(LinphoneCall *obj){ @@ -2046,9 +2046,10 @@ LinphoneReason linphone_call_get_reason(const LinphoneCall *call){ } const LinphoneErrorInfo *linphone_call_get_error_info(const LinphoneCall *call){ - if (call->non_op_error.reason!=SalReasonNone){ - return (const LinphoneErrorInfo*)&call->non_op_error; - }else return linphone_error_info_from_sal_op(call->op); + if (!call->non_op_error){ + linphone_error_info_from_sal_op(call->ei, call->op); + } + return call->ei; } void *linphone_call_get_user_data(const LinphoneCall *call) @@ -4325,7 +4326,8 @@ static void linphone_call_lost(LinphoneCall *call){ if (from) ms_free(from); ms_message("LinphoneCall [%p]: %s", call, temp); linphone_core_notify_display_warning(lc, temp); - sal_error_info_set(&call->non_op_error, SalReasonIOError, 503, "IO error", NULL); + call->non_op_error = TRUE; + linphone_error_info_set(call->ei, LinphoneReasonIOError, 503, "Media lost", NULL); linphone_call_terminate(call); linphone_core_play_named_tone(lc, LinphoneToneCallLost); ms_free(temp); @@ -5029,8 +5031,10 @@ int linphone_call_resume(LinphoneCall *call) { static void terminate_call(LinphoneCall *call) { LinphoneCore *lc = linphone_call_get_core(call); - if ((call->state == LinphoneCallIncomingReceived) && (call->non_op_error.reason != SalReasonRequestTimeout)) - call->non_op_error.reason=SalReasonDeclined; + if ((call->state == LinphoneCallIncomingReceived) && (linphone_error_info_get_reason(call->ei) != LinphoneReasonNotAnswered)){ + linphone_error_info_set_reason(call->ei, LinphoneReasonDeclined); + call->non_op_error = TRUE; + } /* Stop ringing */ linphone_core_stop_ringing(lc); @@ -5089,7 +5093,8 @@ int linphone_call_redirect(LinphoneCall *call, const char *redirect_uri) { real_url = linphone_address_as_string(real_parsed_url); sal_call_decline(call->op, SalReasonRedirect, real_url); ms_free(real_url); - sal_error_info_set(&call->non_op_error, SalReasonRedirect, 603, "Call redirected", NULL); + linphone_error_info_set(call->ei, LinphoneReasonMovedPermanently, 302, "Call redirected", NULL); + call->non_op_error = TRUE; terminate_call(call); linphone_address_unref(real_parsed_url); return 0; diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index ca5fa9d64..d4c64e416 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2979,7 +2979,8 @@ void linphone_core_iterate(LinphoneCore *lc){ ms_message("incoming call timeout (%i)",lc->sip_conf.inc_timeout); decline_reason = (lc->current_call != call) ? LinphoneReasonBusy : LinphoneReasonDeclined; call->log->status=LinphoneCallMissed; - sal_error_info_set(&call->non_op_error,SalReasonRequestTimeout,408,"Not answered",NULL); + call->non_op_error = TRUE; + linphone_error_info_set(call->ei, decline_reason, linphone_reason_to_error_code(decline_reason), "Not answered", NULL); linphone_call_decline(call, decline_reason); } } diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 191249d1e..54b9f4146 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -7278,7 +7278,7 @@ JNIEXPORT jstring JNICALL Java_org_linphone_core_ErrorInfoImpl_getPhrase(JNIEnv * Signature: (J)Ljava/lang/String; */ JNIEXPORT jstring JNICALL Java_org_linphone_core_ErrorInfoImpl_getDetails(JNIEnv *env, jobject jobj, jlong ei){ - const char *tmp=linphone_error_info_get_details((const LinphoneErrorInfo*)ei); + const char *tmp=linphone_error_info_get_warnings((const LinphoneErrorInfo*)ei); return tmp ? env->NewStringUTF(tmp) : NULL; } diff --git a/coreapi/private.h b/coreapi/private.h index 9a06306cf..0ff8700cc 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -124,6 +124,8 @@ #ifdef __cplusplus extern "C" { #endif + +#define ms_strdup_safe(str) ((str) ? ms_strdup(str) : NULL) struct _LinphoneCallParams{ belle_sip_object_t base; @@ -230,6 +232,7 @@ struct _LinphoneChatMessage { belle_sip_object_t base; LinphoneChatRoom* chat_room; LinphoneChatMessageCbs *callbacks; + LinphoneErrorInfo *ei; LinphoneChatMessageDir dir; char* message; void* message_state_changed_user_data; @@ -288,7 +291,7 @@ struct _LinphoneCall{ belle_sip_object_t base; void *user_data; struct _LinphoneCore *core; - SalErrorInfo non_op_error; + LinphoneErrorInfo *ei; int af; /*the address family to prefer for RTP path, guessed from signaling path*/ LinphoneCallDir dir; SalMediaDescription *biggestdesc; /*media description with all already proposed streams, used to remember the mapping of streams*/ @@ -370,7 +373,9 @@ struct _LinphoneCall{ bool_t broken; /*set to TRUE when the call is in broken state due to network disconnection or transport */ bool_t defer_notify_incoming; bool_t need_localip_refresh; + bool_t reinvite_on_cancel_response_requested; + bool_t non_op_error; /*set when the LinphoneErrorInfo was set at higher level than sal*/ }; BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneCall); @@ -624,6 +629,7 @@ struct _LinphoneProxyConfig belle_sip_object_t base; void *user_data; struct _LinphoneCore *lc; + LinphoneErrorInfo *ei; char *reg_proxy; char *reg_identity; LinphoneAddress* identity_address; @@ -1101,6 +1107,7 @@ struct _LinphoneCore struct _LinphoneEvent{ belle_sip_object_t base; + LinphoneErrorInfo *ei; LinphoneSubscriptionDir dir; LinphoneCore *lc; SalOp *op; @@ -1514,10 +1521,7 @@ void linphone_xml_xpath_context_init_carddav_ns(xmlparsing_context_t *xml_ctx); char * linphone_timestamp_to_rfc3339_string(time_t timestamp); -static MS2_INLINE const LinphoneErrorInfo *linphone_error_info_from_sal_op(const SalOp *op){ - if (op==NULL) return (LinphoneErrorInfo*)sal_error_info_none(); - return (const LinphoneErrorInfo*)sal_op_get_error_info(op); -} +void linphone_error_info_from_sal_op(LinphoneErrorInfo *ei, const SalOp *op); static MS2_INLINE void payload_type_set_enable(PayloadType *pt,int value) { @@ -1606,7 +1610,7 @@ BELLE_SIP_TYPE_ID(LinphonePresenceService), BELLE_SIP_TYPE_ID(LinphonePresencePerson), BELLE_SIP_TYPE_ID(LinphonePresenceActivity), BELLE_SIP_TYPE_ID(LinphonePresenceNote), -BELLE_SIP_TYPE_ID(LinphoneTunnel), +BELLE_SIP_TYPE_ID(LinphoneErrorInfo) BELLE_SIP_TYPE_ID(LinphoneConferenceParams), BELLE_SIP_TYPE_ID(LinphoneConference), BELLE_SIP_TYPE_ID(LinphoneInfoMessage) @@ -1733,6 +1737,18 @@ void linphone_call_check_ice_session(LinphoneCall *call, IceRole role, bool_t is bool_t linphone_call_state_is_early(LinphoneCallState state); +struct _LinphoneErrorInfo{ + belle_sip_object_t base; + LinphoneReason reason; + char *protocol; /* */ + int protocol_code; /*from SIP response*/ + char *phrase; /*from SIP response*/ + char *warnings; /*from SIP response*/ + char *full_string; /*concatenation of status_string + warnings*/ + struct _LinphoneErrorInfo *sub_ei; +}; +BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneErrorInfo); + #ifdef __cplusplus } #endif diff --git a/coreapi/proxy.c b/coreapi/proxy.c index a522b2101..1968d7896 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -225,6 +225,9 @@ void _linphone_proxy_config_destroy(LinphoneProxyConfig *cfg){ if (cfg->nat_policy != NULL) { linphone_nat_policy_unref(cfg->nat_policy); } + if (cfg->ei){ + linphone_error_info_unref(cfg->ei); + } _linphone_proxy_config_release_ops(cfg); } @@ -1334,7 +1337,9 @@ LinphoneReason linphone_proxy_config_get_error(const LinphoneProxyConfig *cfg) { } const LinphoneErrorInfo *linphone_proxy_config_get_error_info(const LinphoneProxyConfig *cfg){ - return linphone_error_info_from_sal_op(cfg->op); + if (!cfg->ei) ((LinphoneProxyConfig*)cfg)->ei = linphone_error_info_new(); + linphone_error_info_from_sal_op(cfg->ei, cfg->op); + return cfg->ei; } const LinphoneAddress* linphone_proxy_config_get_service_route(const LinphoneProxyConfig* cfg) { diff --git a/include/linphone/error_info.h b/include/linphone/error_info.h index af54bc387..22f5e59fa 100644 --- a/include/linphone/error_info.h +++ b/include/linphone/error_info.h @@ -31,6 +31,30 @@ extern "C" { * @{ */ +/** + * Create an empty LinphoneErrorInfo object. + * The LinphoneErrorInfo object carries these fields: + * - a LinphoneReason enum member giving overall signification of the error reported. + * - the "protocol" name in which the protocol reason code has meaning, for example SIP or Q.850 + * - the "protocol code", an integer referencing the kind of error reported + * - the "phrase", a text phrase describing the error + * - the "warning", the content of warning headers if any + * - a sub "LinphoneErrorInfo" may be provided if a SIP response includes a Reason header (RFC3326). +**/ +LINPHONE_PUBLIC LinphoneErrorInfo *linphone_error_info_new(void); + +/** + * Increment refcount. + * @param[in] ei ErrorInfo object +**/ +LINPHONE_PUBLIC LinphoneErrorInfo *linphone_error_info_ref(LinphoneErrorInfo *ei); + +/** + * Decrement refcount and possibly free the object. + * @param[in] ei ErrorInfo object +**/ +LINPHONE_PUBLIC void linphone_error_info_unref(LinphoneErrorInfo *ei); + /** * Get reason code from the error info. * @param[in] ei ErrorInfo object @@ -48,11 +72,12 @@ LINPHONE_PUBLIC const char * linphone_error_info_get_phrase(const LinphoneErrorI /** * Provides additional information regarding the failure. - * With SIP protocol, the "Reason" and "Warning" headers are returned. + * With SIP protocol, the content of "Warning" headers are returned. * @param[in] ei ErrorInfo object * @return More details about the failure **/ -LINPHONE_PUBLIC const char * linphone_error_info_get_details(const LinphoneErrorInfo *ei); +LINPHONE_PUBLIC const char * linphone_error_info_get_warnings(const LinphoneErrorInfo *ei); + /** * Get the status code from the low level protocol (ex a SIP status code). @@ -61,6 +86,14 @@ LINPHONE_PUBLIC const char * linphone_error_info_get_details(const LinphoneError **/ LINPHONE_PUBLIC int linphone_error_info_get_protocol_code(const LinphoneErrorInfo *ei); +/** + * Assign information to a LinphoneErrorInfo object. + * @param[in] ei ErrorInfo object + */ +LINPHONE_PUBLIC void linphone_error_info_set(LinphoneErrorInfo *ei, LinphoneReason reason, int code, const char *status_string, const char *warning); + +LINPHONE_PUBLIC void linphone_error_info_set_reason(LinphoneErrorInfo *ei, LinphoneReason reason); + /** * @} */ diff --git a/include/sal/sal.h b/include/sal/sal.h index 1e355c722..40ed02341 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -410,6 +410,7 @@ typedef struct SalErrorInfo{ char *status_string; int protocol_code; char *warnings; + char *protocol; char *full_string; /*concatenation of status_string + warnings*/ }SalErrorInfo; @@ -726,8 +727,9 @@ bool_t sal_op_is_idle(SalOp *op); const SalErrorInfo *sal_error_info_none(void); LINPHONE_PUBLIC const SalErrorInfo *sal_op_get_error_info(const SalOp *op); +const SalErrorInfo *sal_op_get_reason_error_info(const SalOp *op); void sal_error_info_reset(SalErrorInfo *ei); -void sal_error_info_set(SalErrorInfo *ei, SalReason reason, int code, const char *status_string, const char *warning); +void sal_error_info_set(SalErrorInfo *ei, SalReason reason, const char *protocol, int code, const char *status_string, const char *warning); /*entity tag used for publish (see RFC 3903)*/ const char *sal_op_get_entity_tag(const SalOp* op); diff --git a/mediastreamer2 b/mediastreamer2 index 237786682..ffdd8375f 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit 2377866823f41056109519fbc362ddd6fc8214e9 +Subproject commit ffdd8375f332e04c0d7642fb1da414124145256e diff --git a/oRTP b/oRTP index 920817911..235e5175b 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 920817911d9287250d9ddf506aede06744faae4b +Subproject commit 235e5175b2befa2d3e5f19cd969b0f3bda5b9b4c diff --git a/tester/register_tester.c b/tester/register_tester.c index ca55e17ee..33819efb7 100644 --- a/tester/register_tester.c +++ b/tester/register_tester.c @@ -465,7 +465,7 @@ static void authenticated_register_with_wrong_credentials_with_params_base(const BC_ASSERT_PTR_NOT_NULL(phrase); if (phrase) BC_ASSERT_STRING_EQUAL(phrase,"Forbidden"); BC_ASSERT_EQUAL(linphone_error_info_get_protocol_code(ei),403, int, "%d"); - BC_ASSERT_PTR_NULL(linphone_error_info_get_details(ei)); + BC_ASSERT_PTR_NULL(linphone_error_info_get_warnings(ei)); } } From 1eba566506dbfa6cdff3490aefe20383ec86edf9 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 22 Mar 2017 14:46:27 +0100 Subject: [PATCH 2/8] fix compilation issue with last commit --- coreapi/private.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/private.h b/coreapi/private.h index 0ff8700cc..dbbb9ccfd 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -1610,7 +1610,7 @@ BELLE_SIP_TYPE_ID(LinphonePresenceService), BELLE_SIP_TYPE_ID(LinphonePresencePerson), BELLE_SIP_TYPE_ID(LinphonePresenceActivity), BELLE_SIP_TYPE_ID(LinphonePresenceNote), -BELLE_SIP_TYPE_ID(LinphoneErrorInfo) +BELLE_SIP_TYPE_ID(LinphoneErrorInfo), BELLE_SIP_TYPE_ID(LinphoneConferenceParams), BELLE_SIP_TYPE_ID(LinphoneConference), BELLE_SIP_TYPE_ID(LinphoneInfoMessage) From ca56844012978da5c795d60716bbe4fa5ad8d3a9 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 22 Mar 2017 15:01:47 +0100 Subject: [PATCH 3/8] fix memory leaks --- tester/call_single_tester.c | 22 +++++++++++++++------- tester/call_video_tester.c | 1 + tester/video_tester.c | 1 + 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index 71f2f8191..6ca3a529a 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -2639,6 +2639,7 @@ static void call_established_with_complex_rejected_operation(void) { LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); bool_t call_ok=FALSE; LinphoneCallParams *params; + LinphoneInfoMessage *info; BC_ASSERT_TRUE((call_ok=call(pauline,marie))); if (call_ok){ @@ -2652,7 +2653,9 @@ static void call_established_with_complex_rejected_operation(void) { linphone_core_enable_payload_type(marie->lc,linphone_core_find_payload_type(marie->lc,"PCMA",8000,1),TRUE); /*enable PCMA*/ /*just to authenticate marie*/ - linphone_call_send_info_message(linphone_core_get_current_call(marie->lc),linphone_core_create_info_message(marie->lc)); + info = linphone_core_create_info_message(marie->lc); + linphone_call_send_info_message(linphone_core_get_current_call(marie->lc), info); + linphone_info_message_unref(info); BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_inforeceived,1)); BC_ASSERT_EQUAL(pauline->stat.number_of_inforeceived,1, int, "%d"); /*to give time for 200ok to arrive*/ @@ -2672,8 +2675,9 @@ static void call_established_with_complex_rejected_operation(void) { check_call_state(marie,LinphoneCallStreamsRunning); linphone_call_update(linphone_core_get_current_call(pauline->lc),linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc))); - - linphone_call_send_info_message(linphone_core_get_current_call(marie->lc),linphone_core_create_info_message(marie->lc)); + info = linphone_core_create_info_message(marie->lc); + linphone_call_send_info_message(linphone_core_get_current_call(marie->lc), info); + linphone_info_message_unref(info); params=linphone_core_create_call_params(marie->lc,linphone_core_get_current_call(marie->lc)); sal_enable_pending_trans_checking(marie->lc->sal,FALSE); /*to allow // transactions*/ @@ -2704,7 +2708,7 @@ static void call_established_with_rejected_info_during_reinvite(void) { BC_ASSERT_TRUE((call_ok=call(pauline,marie))); if (call_ok){ - + LinphoneInfoMessage *info; BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&pauline->stat.number_of_LinphoneCallStreamsRunning,1)); BC_ASSERT_TRUE(wait_for(marie->lc,pauline->lc,&marie->stat.number_of_LinphoneCallStreamsRunning,1)); @@ -2714,15 +2718,18 @@ static void call_established_with_rejected_info_during_reinvite(void) { linphone_core_enable_payload_type(marie->lc,linphone_core_find_payload_type(marie->lc,"PCMA",8000,1),TRUE); /*enable PCMA*/ /*just to authenticate marie*/ - linphone_call_send_info_message(linphone_core_get_current_call(marie->lc),linphone_core_create_info_message(marie->lc)); + info = linphone_core_create_info_message(marie->lc); + linphone_call_send_info_message(linphone_core_get_current_call(marie->lc), info); + linphone_info_message_unref(info); BC_ASSERT_TRUE(wait_for(pauline->lc,marie->lc,&pauline->stat.number_of_inforeceived,1)); BC_ASSERT_EQUAL(pauline->stat.number_of_inforeceived,1, int, "%d"); /*to give time for 200ok to arrive*/ wait_for_until(marie->lc,pauline->lc,NULL,0,1000); //sal_enable_pending_trans_checking(marie->lc->sal,FALSE); /*to allow // transactions*/ - - linphone_call_send_info_message(linphone_core_get_current_call(marie->lc),linphone_core_create_info_message(marie->lc)); + info = linphone_core_create_info_message(marie->lc); + linphone_call_send_info_message(linphone_core_get_current_call(marie->lc),info); + linphone_info_message_unref(info); //sal_set_send_error(marie->lc->sal, -1); /*to avoid 491 pending to be sent*/ @@ -2862,6 +2869,7 @@ static void call_established_with_rejected_reinvite_with_error_base(bool_t trans if (trans_pending) { LinphoneInfoMessage * info = linphone_core_create_info_message(pauline->lc); linphone_call_send_info_message(linphone_core_get_current_call(pauline->lc),info); + linphone_info_message_unref(info); } else sal_enable_unconditional_answer(marie->lc->sal,TRUE); diff --git a/tester/call_video_tester.c b/tester/call_video_tester.c index a573ee340..66b01bc10 100644 --- a/tester/call_video_tester.c +++ b/tester/call_video_tester.c @@ -1441,6 +1441,7 @@ static void multiple_early_media(void) { /*send an INFO in reverse side to check that dialogs are properly established*/ info=linphone_core_create_info_message(marie1->lc); linphone_call_send_info_message(marie1_call,info); + linphone_info_message_unref(info); BC_ASSERT_TRUE(wait_for_list(lcs,&pauline->stat.number_of_inforeceived,1,3000)); } diff --git a/tester/video_tester.c b/tester/video_tester.c index 426921e2e..0526441d7 100644 --- a/tester/video_tester.c +++ b/tester/video_tester.c @@ -503,6 +503,7 @@ static void forked_outgoing_early_media_video_call_with_inactive_audio_test(void /* send an INFO in reverse side to check that dialogs are properly established */ info = linphone_core_create_info_message(marie1->lc); linphone_call_send_info_message(marie1_call, info); + linphone_info_message_unref(info); BC_ASSERT_TRUE(wait_for_list(lcs, &pauline->stat.number_of_inforeceived, 1, 3000)); } From cb0f77fce2a722eef8217ddcd492eb9541694abb Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 22 Mar 2017 15:38:01 +0100 Subject: [PATCH 4/8] Fix build on Windows. --- coreapi/conference.cc | 4 ++-- coreapi/info.c | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/coreapi/conference.cc b/coreapi/conference.cc index 13327cf39..6e44da789 100644 --- a/coreapi/conference.cc +++ b/coreapi/conference.cc @@ -924,7 +924,7 @@ static void _linphone_conference_params_uninit(LinphoneConferenceParams *params) static void _linphone_conference_params_clone(LinphoneConferenceParams *params, const LinphoneConferenceParams *orig); BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneConferenceParams); -BELLE_SIP_DECLARE_VPTR(LinphoneConferenceParams); +BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneConferenceParams); BELLE_SIP_INSTANCIATE_VPTR(LinphoneConferenceParams, belle_sip_object_t, _linphone_conference_params_uninit, // uninit _linphone_conference_params_clone, // clone @@ -983,7 +983,7 @@ struct _LinphoneConference { static void _linphone_conference_uninit(LinphoneConference *conf); BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneConference); -BELLE_SIP_DECLARE_VPTR(LinphoneConference); +BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneConference); BELLE_SIP_INSTANCIATE_VPTR(LinphoneConference, belle_sip_object_t, _linphone_conference_uninit, // uninit NULL, // clone diff --git a/coreapi/info.c b/coreapi/info.c index b626f3f11..ff1c8d876 100644 --- a/coreapi/info.c +++ b/coreapi/info.c @@ -38,7 +38,7 @@ static void _linphone_info_message_uninit(LinphoneInfoMessage *im); static void _linphone_info_message_copy(LinphoneInfoMessage *im, const LinphoneInfoMessage *orig); BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneInfoMessage); -BELLE_SIP_DECLARE_VPTR(LinphoneInfoMessage); +BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneInfoMessage); BELLE_SIP_INSTANCIATE_VPTR(LinphoneInfoMessage, belle_sip_object_t, _linphone_info_message_uninit, // uninit _linphone_info_message_copy, // clone From 195d85fae64b72ef7f2eba736d9cd12a11539a2c Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 22 Mar 2017 15:59:34 +0100 Subject: [PATCH 5/8] Fix installation of linphone++ library on Windows. --- wrappers/cpp/CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/wrappers/cpp/CMakeLists.txt b/wrappers/cpp/CMakeLists.txt index 033d9578b..2059de15c 100644 --- a/wrappers/cpp/CMakeLists.txt +++ b/wrappers/cpp/CMakeLists.txt @@ -47,6 +47,7 @@ set_target_properties(linphone++ PROPERTIES SOVERSION ${LINPHONE_SO_VERSION}) install(TARGETS linphone++ EXPORT LinphoneCxxTargets RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR} LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR} + ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR} ) install(FILES object.hh DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/linphone++ From 7a5bfae02d942540e548b8035f5c5c91e30abc3d Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 22 Mar 2017 17:34:55 +0100 Subject: [PATCH 6/8] add new test (that works) and deprecate LinphoneCall.getCurrentParamsCopy(). --- coreapi/linphonecore_jni.cc | 2 +- .../org/linphone/core/LinphoneCall.java | 10 +++ .../org/linphone/core/LinphoneCallImpl.java | 9 ++- tester/call_video_tester.c | 66 +++++++++++++++++++ 4 files changed, 83 insertions(+), 4 deletions(-) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 54b9f4146..1b86f235c 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -5058,7 +5058,7 @@ extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getRemoteParams(JNIEnv return (jlong) linphone_call_params_copy(linphone_call_get_remote_params((LinphoneCall*)lc)); } -extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getCurrentParamsCopy(JNIEnv *env, jobject thiz, jlong lc){ +extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getCurrentParams(JNIEnv *env, jobject thiz, jlong lc){ return (jlong) linphone_call_params_copy(linphone_call_get_current_params((LinphoneCall*)lc)); } diff --git a/java/common/org/linphone/core/LinphoneCall.java b/java/common/org/linphone/core/LinphoneCall.java index 02a0edf30..76a5c0a38 100644 --- a/java/common/org/linphone/core/LinphoneCall.java +++ b/java/common/org/linphone/core/LinphoneCall.java @@ -201,6 +201,16 @@ public interface LinphoneCall { **/ LinphoneCallParams getRemoteParams(); + /** + * Get call's effective parameters, resulting from SDP offer/answer. + **/ + LinphoneCallParams getCurrentParams(); + + /** + * + * Same as getCurrentParams(), but deprecated. + **/ + @deprecated LinphoneCallParams getCurrentParamsCopy(); void enableCamera(boolean enabled); diff --git a/java/impl/org/linphone/core/LinphoneCallImpl.java b/java/impl/org/linphone/core/LinphoneCallImpl.java index 73320065e..661fde7ef 100644 --- a/java/impl/org/linphone/core/LinphoneCallImpl.java +++ b/java/impl/org/linphone/core/LinphoneCallImpl.java @@ -29,7 +29,7 @@ class LinphoneCallImpl implements LinphoneCall { private native boolean isIncoming(long nativePtr); native private long getRemoteAddress(long nativePtr); native private int getState(long nativePtr); - private native long getCurrentParamsCopy(long nativePtr); + private native long getCurrentParams(long nativePtr); private native long getRemoteParams(long nativePtr); private native void enableCamera(long nativePtr, boolean enabled); private native boolean cameraEnabled(long nativePtr); @@ -84,8 +84,11 @@ class LinphoneCallImpl implements LinphoneCall { public State getState() { return LinphoneCall.State.fromInt(getState(nativePtr)); } - public LinphoneCallParams getCurrentParamsCopy() { - return new LinphoneCallParamsImpl(getCurrentParamsCopy(nativePtr)); + public LinphoneCallParams getCurrentParams() { + return new LinphoneCallParamsImpl(getCurrentParams(nativePtr)); + } + public LinphoneCallParams getCurrentParamsCopy(){ + return getCurrentParams(); } public LinphoneCallParams getRemoteParams() { long remoteParamsPtr = getRemoteParams(nativePtr); diff --git a/tester/call_video_tester.c b/tester/call_video_tester.c index 66b01bc10..30b72a71e 100644 --- a/tester/call_video_tester.c +++ b/tester/call_video_tester.c @@ -827,6 +827,71 @@ static void video_call_using_policy_AVPF_implicit_caller_and_callee(void) { linphone_core_manager_destroy(caller); } +static void video_call_established_by_reinvite_with_implicit_avpf(void) { + LinphoneCoreManager *callee = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager *caller = linphone_core_manager_new(transport_supported(LinphoneTransportTcp) ? "pauline_rc" : "pauline_tcp_rc"); + LinphoneVideoPolicy policy; + LinphoneCall * caller_call, *callee_call; + LinphoneCallParams *params; + + policy.automatically_initiate=FALSE; + policy.automatically_accept=FALSE; + + linphone_core_set_video_policy(callee->lc,&policy); + + policy.automatically_initiate=TRUE; + policy.automatically_accept=TRUE; + linphone_core_set_video_policy(caller->lc,&policy); + + linphone_core_enable_video_display(callee->lc, TRUE); + linphone_core_enable_video_capture(callee->lc, TRUE); + linphone_proxy_config_set_avpf_mode(linphone_core_get_default_proxy_config(callee->lc), LinphoneAVPFEnabled); + + linphone_core_enable_video_display(caller->lc, TRUE); + linphone_core_enable_video_capture(caller->lc, TRUE); + + linphone_core_set_video_device(caller->lc,liblinphone_tester_mire_id); + linphone_core_set_video_device(callee->lc,liblinphone_tester_mire_id); + + caller_call = linphone_core_invite_address(caller->lc, callee->identity); + if (BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&callee->stat.number_of_LinphoneCallIncomingReceived,1))){ + callee_call = linphone_core_get_current_call(callee->lc); + + linphone_core_accept_call(callee->lc, linphone_core_get_current_call(callee->lc)); + BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&callee->stat.number_of_LinphoneCallStreamsRunning,1)); + BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&caller->stat.number_of_LinphoneCallStreamsRunning,1)); + + BC_ASSERT_FALSE(linphone_call_params_video_enabled(linphone_call_get_current_params(callee_call))); + BC_ASSERT_FALSE(linphone_call_params_video_enabled(linphone_call_get_current_params(caller_call))); + + /*then callee adds video*/ + params = linphone_core_create_call_params(callee->lc, callee_call); + linphone_call_params_enable_video(params, TRUE); + linphone_call_update(callee_call, params); + linphone_call_params_unref(params); + BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&callee->stat.number_of_LinphoneCallUpdating,1)); + BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&caller->stat.number_of_LinphoneCallUpdatedByRemote,1)); + BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&callee->stat.number_of_LinphoneCallStreamsRunning,2)); + BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&caller->stat.number_of_LinphoneCallStreamsRunning,2)); + + BC_ASSERT_TRUE(linphone_call_params_video_enabled(linphone_call_get_current_params(callee_call))); + BC_ASSERT_TRUE(linphone_call_params_video_enabled(linphone_call_get_current_params(caller_call))); + + linphone_call_set_next_video_frame_decoded_callback(caller_call,linphone_call_iframe_decoded_cb,caller->lc); + linphone_call_set_next_video_frame_decoded_callback(callee_call,linphone_call_iframe_decoded_cb,callee->lc); + + BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&callee->stat.number_of_IframeDecoded,1)); + BC_ASSERT_TRUE( wait_for(callee->lc,caller->lc,&caller->stat.number_of_IframeDecoded,1)); + + BC_ASSERT_TRUE(media_stream_avpf_enabled((MediaStream*)caller_call->videostream)); + BC_ASSERT_TRUE(media_stream_avpf_enabled((MediaStream*)callee_call->videostream)); + } + + end_call(caller, callee); + linphone_core_manager_destroy(callee); + linphone_core_manager_destroy(caller); +} + static void video_call_base_avpf(LinphoneCoreManager *caller, LinphoneCoreManager *callee, bool_t using_policy, LinphoneMediaEncryption mode, bool_t callee_video_enabled, bool_t caller_video_enabled) { linphone_core_set_avpf_mode(caller->lc, LinphoneAVPFEnabled); linphone_core_set_avpf_mode(callee->lc, LinphoneAVPFEnabled); @@ -1951,6 +2016,7 @@ test_t call_video_tests[] = { TEST_NO_TAG("Simple video call disable implicit AVPF on caller", video_call_disable_implicit_AVPF_on_caller), TEST_NO_TAG("Simple video call AVPF to implicit AVPF", video_call_AVPF_to_implicit_AVPF), TEST_NO_TAG("Simple video call implicit AVPF to AVPF", video_call_implicit_AVPF_to_AVPF), + TEST_NO_TAG("Video added by reINVITE, with implicit AVPF", video_call_established_by_reinvite_with_implicit_avpf), TEST_NO_TAG("Simple video call", video_call), TEST_NO_TAG("Simple video call without rtcp",video_call_without_rtcp), TEST_NO_TAG("Simple ZRTP video call", video_call_zrtp), From c1434a3f7c029fb69f557fca2b5fa1682786da5f Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 22 Mar 2017 21:35:03 +0100 Subject: [PATCH 7/8] fix crash in android version, optimize LinphoneCall.getCurrentParams() --- coreapi/linphonecore_jni.cc | 12 ++++++++++-- java/common/org/linphone/core/LinphoneCall.java | 2 +- java/impl/org/linphone/core/LinphoneCallImpl.java | 12 ++++++++++-- mediastreamer2 | 2 +- 4 files changed, 22 insertions(+), 6 deletions(-) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 1b86f235c..352258055 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -1282,7 +1282,7 @@ public: LinphoneJavaBindings *ljb = (LinphoneJavaBindings *)linphone_core_get_user_data(lc); LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); - statsobj = env->NewObject(ljb->callStatsClass, ljb->callStatsId, (jlong)call, (jlong)stats); + statsobj = env->NewObject(ljb->callStatsClass, ljb->callStatsId, (jlong)stats); callobj = getCall(env, call); env->CallVoidMethod(lcData->listener, ljb->callStatsUpdatedId, lcData->core, callobj, statsobj); handle_possible_java_exception(env, lcData->listener); @@ -3478,6 +3478,14 @@ JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneCallImpl_getStats(JNIEn return stats ? env->NewObject(ljb->callStatsClass, ljb->callStatsId, (jlong)stats) : NULL; } +JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneCallImpl_getCore(JNIEnv* env + ,jobject thiz + ,jlong ptr) { + LinphoneCall *call=(LinphoneCall*)ptr; + LinphoneJavaBindings *ljb = (LinphoneJavaBindings *) linphone_core_get_user_data(linphone_call_get_core(call)); + return ljb->getCore(); +} + extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getCallLog( JNIEnv* env ,jobject thiz ,jlong ptr) { @@ -5059,7 +5067,7 @@ extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getRemoteParams(JNIEnv } extern "C" jlong Java_org_linphone_core_LinphoneCallImpl_getCurrentParams(JNIEnv *env, jobject thiz, jlong lc){ - return (jlong) linphone_call_params_copy(linphone_call_get_current_params((LinphoneCall*)lc)); + return (jlong) linphone_call_params_ref((LinphoneCallParams*)linphone_call_get_current_params((LinphoneCall*)lc)); } extern "C" void Java_org_linphone_core_LinphoneCallImpl_enableCamera(JNIEnv *env, jobject thiz, jlong lc, jboolean b){ diff --git a/java/common/org/linphone/core/LinphoneCall.java b/java/common/org/linphone/core/LinphoneCall.java index 76a5c0a38..b2342a410 100644 --- a/java/common/org/linphone/core/LinphoneCall.java +++ b/java/common/org/linphone/core/LinphoneCall.java @@ -209,8 +209,8 @@ public interface LinphoneCall { /** * * Same as getCurrentParams(), but deprecated. + * @deprecated **/ - @deprecated LinphoneCallParams getCurrentParamsCopy(); void enableCamera(boolean enabled); diff --git a/java/impl/org/linphone/core/LinphoneCallImpl.java b/java/impl/org/linphone/core/LinphoneCallImpl.java index 661fde7ef..c276ce07d 100644 --- a/java/impl/org/linphone/core/LinphoneCallImpl.java +++ b/java/impl/org/linphone/core/LinphoneCallImpl.java @@ -21,8 +21,10 @@ package org.linphone.core; class LinphoneCallImpl implements LinphoneCall { protected final long nativePtr; + boolean ownPtr = false; Object userData; + LinphoneCore mCore; native private void finalize(long nativePtr); native private long getCallLog(long nativePtr); @@ -45,12 +47,14 @@ class LinphoneCallImpl implements LinphoneCall { private native void setListener(long ptr, LinphoneCallListener listener); native private long getDiversionAddress(long nativePtr); native private Object getStats(long nativePtr, int stream_type); + native private LinphoneCore getCore(long nativePtr); /* * This method must always be called from JNI, nothing else. */ private LinphoneCallImpl(long aNativePtr) { nativePtr = aNativePtr; + mCore = getCore(nativePtr); } protected void finalize() throws Throwable { finalize(nativePtr); @@ -65,10 +69,14 @@ class LinphoneCallImpl implements LinphoneCall { } public LinphoneCallStats getAudioStats() { - return (LinphoneCallStats)getStats(nativePtr, 0); + synchronized(mCore){ + return (LinphoneCallStats)getStats(nativePtr, 0); + } } public LinphoneCallStats getVideoStats() { - return (LinphoneCallStats)getStats(nativePtr, 1); + synchronized(mCore){ + return (LinphoneCallStats)getStats(nativePtr, 1); + } } public CallDirection getDirection() { return isIncoming(nativePtr)?CallDirection.Incoming:CallDirection.Outgoing; diff --git a/mediastreamer2 b/mediastreamer2 index ffdd8375f..1f17b3ba2 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit ffdd8375f332e04c0d7642fb1da414124145256e +Subproject commit 1f17b3ba22cb662c1c15655c8248036e7a69baf2 From 4ab81b467f805df37e37d7dbaab844173d418a4f Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Thu, 23 Mar 2017 11:30:54 +0100 Subject: [PATCH 8/8] Optimize call logs fetching. --- coreapi/call_log.c | 105 +++++++++++++++++------------------- tester/call_single_tester.c | 5 +- 2 files changed, 52 insertions(+), 58 deletions(-) diff --git a/coreapi/call_log.c b/coreapi/call_log.c index 71b232679..4087e77ae 100644 --- a/coreapi/call_log.c +++ b/coreapi/call_log.c @@ -37,6 +37,11 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "sqlite3.h" #endif +typedef struct _CallLogStorageResult { + LinphoneCore *core; + bctbx_list_t *result; +} CallLogStorageResult; + /******************************************************************************* * Internal functions * ******************************************************************************/ @@ -401,6 +406,15 @@ void linphone_core_call_log_storage_close(LinphoneCore *lc) { } } +static LinphoneCallLog * find_call_log_by_storage_id(bctbx_list_t *call_logs, unsigned int storage_id) { + bctbx_list_t *item; + for (item = call_logs; item != NULL; item = bctbx_list_next(item)) { + LinphoneCallLog *call_log = bctbx_list_get_data(item); + if (call_log->storage_id == storage_id) return call_log; + } + return NULL; +} + /* DB layout: * | 0 | storage_id * | 1 | from @@ -416,13 +430,20 @@ void linphone_core_call_log_storage_close(LinphoneCore *lc) { * | 11 | refkey */ static int create_call_log(void *data, int argc, char **argv, char **colName) { - bctbx_list_t **list = (bctbx_list_t **)data; + CallLogStorageResult *clsres = (CallLogStorageResult *)data; LinphoneAddress *from; LinphoneAddress *to; LinphoneCallDir dir; LinphoneCallLog *log; unsigned int storage_id = (unsigned int)atoi(argv[0]); + + log = find_call_log_by_storage_id(clsres->core->call_logs, storage_id); + if (log != NULL) { + clsres->result = bctbx_list_append(clsres->result, linphone_call_log_ref(log)); + return 0; + } + from = linphone_address_new(argv[1]); to = linphone_address_new(argv[2]); @@ -449,7 +470,7 @@ static int create_call_log(void *data, int argc, char **argv, char **colName) { } } - *list = bctbx_list_append(*list, log); + clsres->result = bctbx_list_append(clsres->result, log); return 0; error: @@ -463,10 +484,10 @@ error: return 0; } -static void linphone_sql_request_call_log(sqlite3 *db, const char *stmt, bctbx_list_t **list) { +static void linphone_sql_request_call_log(sqlite3 *db, const char *stmt, CallLogStorageResult *clsres) { char* errmsg = NULL; int ret; - ret = sqlite3_exec(db, stmt, create_call_log, list, &errmsg); + ret = sqlite3_exec(db, stmt, create_call_log, clsres, &errmsg); if (ret != SQLITE_OK) { ms_error("linphone_sql_request: statement %s -> error sqlite3_exec(): %s.", stmt, errmsg); sqlite3_free(errmsg); @@ -517,31 +538,13 @@ void linphone_core_store_call_log(LinphoneCore *lc, LinphoneCallLog *log) { } } -static void copy_user_data_from_existing_log(bctbx_list_t *existing_logs, LinphoneCallLog *log) { - while (existing_logs) { - LinphoneCallLog *existing_log = (LinphoneCallLog *)existing_logs->data; - if (existing_log->storage_id == log->storage_id) { - log->user_data = existing_log->user_data; - break; - } - existing_logs = bctbx_list_next(existing_logs); - } -} - -static void copy_user_data_from_existing_logs(bctbx_list_t *existing_logs, bctbx_list_t *new_logs) { - while (new_logs) { - LinphoneCallLog *new_log = (LinphoneCallLog *)new_logs->data; - copy_user_data_from_existing_log(existing_logs, new_log); - new_logs = bctbx_list_next(new_logs); - } -} - const bctbx_list_t *linphone_core_get_call_history(LinphoneCore *lc) { char *buf; uint64_t begin,end; - bctbx_list_t *result = NULL; + CallLogStorageResult clsres; if (!lc || lc->logs_db == NULL) return NULL; + if (lc->call_logs != NULL) return lc->call_logs; if (lc->max_call_logs != LINPHONE_MAX_CALL_HISTORY_UNLIMITED){ buf = sqlite3_mprintf("SELECT * FROM call_history ORDER BY id DESC LIMIT %i", lc->max_call_logs); @@ -549,19 +552,15 @@ const bctbx_list_t *linphone_core_get_call_history(LinphoneCore *lc) { buf = sqlite3_mprintf("SELECT * FROM call_history ORDER BY id DESC"); } + clsres.core = lc; + clsres.result = NULL; begin = ortp_get_cur_time_ms(); - linphone_sql_request_call_log(lc->logs_db, buf, &result); + linphone_sql_request_call_log(lc->logs_db, buf, &clsres); end = ortp_get_cur_time_ms(); ms_message("%s(): completed in %i ms",__FUNCTION__, (int)(end-begin)); sqlite3_free(buf); - if (lc->call_logs) { - copy_user_data_from_existing_logs(lc->call_logs, result); - } - - lc->call_logs = bctbx_list_free_with_data(lc->call_logs, (void (*)(void*))linphone_call_log_unref); - lc->call_logs = result; - + lc->call_logs = clsres.result; return lc->call_logs; } @@ -610,7 +609,7 @@ bctbx_list_t * linphone_core_get_call_history_for_address(LinphoneCore *lc, cons char *buf; char *sipAddress; uint64_t begin,end; - bctbx_list_t *result = NULL; + CallLogStorageResult clsres; if (!lc || lc->logs_db == NULL || addr == NULL) return NULL; @@ -618,43 +617,39 @@ bctbx_list_t * linphone_core_get_call_history_for_address(LinphoneCore *lc, cons sipAddress = linphone_address_as_string_uri_only(addr); buf = sqlite3_mprintf("SELECT * FROM call_history WHERE caller LIKE '%%%q%%' OR callee LIKE '%%%q%%' ORDER BY id DESC", sipAddress, sipAddress); // The '%%%q%%' takes care of the eventual presence of a display name + clsres.core = lc; + clsres.result = NULL; begin = ortp_get_cur_time_ms(); - linphone_sql_request_call_log(lc->logs_db, buf, &result); + linphone_sql_request_call_log(lc->logs_db, buf, &clsres); end = ortp_get_cur_time_ms(); ms_message("%s(): completed in %i ms",__FUNCTION__, (int)(end-begin)); sqlite3_free(buf); ms_free(sipAddress); - if (lc->call_logs) { - copy_user_data_from_existing_logs(lc->call_logs, result); - } - - return result; + return clsres.result; } LinphoneCallLog * linphone_core_get_last_outgoing_call_log(LinphoneCore *lc) { char *buf; uint64_t begin,end; - bctbx_list_t *list = NULL; - LinphoneCallLog* result = NULL; + CallLogStorageResult clsres; + LinphoneCallLog *result = NULL; if (!lc || lc->logs_db == NULL) return NULL; /*since we want to append query parameters depending on arguments given, we use malloc instead of sqlite3_mprintf*/ buf = sqlite3_mprintf("SELECT * FROM call_history WHERE direction = 0 ORDER BY id DESC LIMIT 1"); + clsres.core = lc; + clsres.result = NULL; begin = ortp_get_cur_time_ms(); - linphone_sql_request_call_log(lc->logs_db, buf, &list); + linphone_sql_request_call_log(lc->logs_db, buf, &clsres); end = ortp_get_cur_time_ms(); ms_message("%s(): completed in %i ms",__FUNCTION__, (int)(end-begin)); sqlite3_free(buf); - if (list) { - result = (LinphoneCallLog*)list->data; - } - - if (lc->call_logs && result) { - copy_user_data_from_existing_log(lc->call_logs, result); + if (clsres.result != NULL) { + result = (LinphoneCallLog *)bctbx_list_get_data(clsres.result); } return result; @@ -663,7 +658,7 @@ LinphoneCallLog * linphone_core_get_last_outgoing_call_log(LinphoneCore *lc) { LinphoneCallLog * linphone_core_find_call_log_from_call_id(LinphoneCore *lc, const char *call_id) { char *buf; uint64_t begin,end; - bctbx_list_t *list = NULL; + CallLogStorageResult clsres; LinphoneCallLog* result = NULL; if (!lc || lc->logs_db == NULL) return NULL; @@ -671,18 +666,16 @@ LinphoneCallLog * linphone_core_find_call_log_from_call_id(LinphoneCore *lc, con /*since we want to append query parameters depending on arguments given, we use malloc instead of sqlite3_mprintf*/ buf = sqlite3_mprintf("SELECT * FROM call_history WHERE call_id = '%q' ORDER BY id DESC LIMIT 1", call_id); + clsres.core = lc; + clsres.result = NULL; begin = ortp_get_cur_time_ms(); - linphone_sql_request_call_log(lc->logs_db, buf, &list); + linphone_sql_request_call_log(lc->logs_db, buf, &clsres); end = ortp_get_cur_time_ms(); ms_message("%s(): completed in %i ms",__FUNCTION__, (int)(end-begin)); sqlite3_free(buf); - if (list) { - result = (LinphoneCallLog*)list->data; - } - - if (lc->call_logs && result) { - copy_user_data_from_existing_log(lc->call_logs, result); + if (clsres.result != NULL) { + result = (LinphoneCallLog *)bctbx_list_get_data(clsres.result); } return result; diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index 6ca3a529a..43d260803 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -4908,8 +4908,9 @@ static void call_logs_sqlite_storage(void) { logs = linphone_core_get_call_history_for_address(marie->lc, linphone_proxy_config_get_identity_address(linphone_core_get_default_proxy_config(pauline->lc))); if (BC_ASSERT_TRUE(bctbx_list_size(logs) == 1)) { const char *call_id; - const char *ref_key = linphone_call_log_get_ref_key(call_log); - call_log = logs->data; + const char *ref_key; + call_log = (LinphoneCallLog *)bctbx_list_get_data(logs); + ref_key = linphone_call_log_get_ref_key(call_log); BC_ASSERT_EQUAL(linphone_call_log_get_dir(call_log), LinphoneCallOutgoing, int, "%d"); BC_ASSERT_LOWER(linphone_call_log_get_duration(call_log), 2, int, "%d"); BC_ASSERT_TRUE(linphone_address_equal(