From 0009e277d7ca906e3d3190ba5e1af3253560aab5 Mon Sep 17 00:00:00 2001 From: Sandrine Avakian Date: Mon, 20 Mar 2017 14:14:43 +0100 Subject: [PATCH 01/70] Added linphone_call_set_params to modify SDP header and attributes. Added linphone_call_get_params to get local call params used. Added tests . --- coreapi/callbacks.c | 2 +- coreapi/linphonecall.c | 26 +++- coreapi/private.h | 4 +- tester/call_single_tester.c | 256 ++++++++++++++++++++++++++++++++++++ 4 files changed, 281 insertions(+), 7 deletions(-) diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index ea1f69d7b..59e5d390a 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -748,7 +748,7 @@ static void call_updating(SalOp *op, bool_t is_update){ if (rmd == NULL && lp_config_get_int(call->core->config,"sip","sdp_200_ack_follow_video_policy",0)) { LinphoneCallParams *p=linphone_core_create_call_params(lc, NULL); ms_message("Applying default policy for offering SDP on call [%p]",call); - linphone_call_set_new_params(call, p); + _linphone_call_set_new_params(call, p); linphone_call_params_unref(p); } linphone_call_make_local_media_description(call); diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 916d03856..463163fc2 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -4742,13 +4742,29 @@ LinphonePlayer *linphone_call_get_player(LinphoneCall *call){ return call->player; } -void linphone_call_set_new_params(LinphoneCall *call, const LinphoneCallParams *params){ + +void linphone_call_set_params(LinphoneCall *call, const LinphoneCallParams *params){ + if ( call->state == LinphoneCallOutgoingInit || call->state == LinphoneCallIncomingReceived){ + _linphone_call_set_new_params(call, params); + } + else { + ms_error("linphone_call_set_params() invalid state %s to call this function", linphone_call_state_to_string(call->state)); + } +} + + +void _linphone_call_set_new_params(LinphoneCall *call, const LinphoneCallParams *params){ LinphoneCallParams *cp=NULL; if (params) cp=linphone_call_params_copy(params); if (call->params) linphone_call_params_unref(call->params); call->params=cp; } +const LinphoneCallParams * linphone_call_get_params(LinphoneCall *call){ + return call->params; +} + + static int send_dtmf_handler(void *data, unsigned int revents){ LinphoneCall *call = (LinphoneCall*)data; /*By default we send DTMF RFC2833 if we do not have enabled SIP_INFO but we can also send RFC2833 and SIP_INFO*/ @@ -5174,7 +5190,7 @@ int linphone_call_accept_with_params(LinphoneCall *call, const LinphoneCallParam /* Try to be best-effort in giving real local or routable contact address */ linphone_call_set_contact_op(call); if (params) { - linphone_call_set_new_params(call, params); + _linphone_call_set_new_params(call, params); linphone_call_prepare_ice(call, TRUE); linphone_call_make_local_media_description(call); sal_call_set_local_media_description(call->op, call->localdesc); @@ -5230,7 +5246,7 @@ int linphone_call_accept_early_media_with_params(LinphoneCall *call, const Linph /* If parameters are passed, update the media description */ if (params) { - linphone_call_set_new_params(call, params); + _linphone_call_set_new_params(call, params); linphone_call_make_local_media_description(call); sal_call_set_local_media_description(call->op, call->localdesc); sal_op_set_sent_custom_header(call->op, params->custom_headers); @@ -5303,7 +5319,7 @@ int linphone_call_update(LinphoneCall *call, const LinphoneCallParams *params) { } } #endif /* defined(VIDEO_ENABLED) && defined(BUILD_UPNP) */ - linphone_call_set_new_params(call, params); + _linphone_call_set_new_params(call, params); err = linphone_call_prepare_ice(call, FALSE); if (err == 1) { ms_message("Defer call update to gather ICE candidates"); @@ -5451,7 +5467,7 @@ int _linphone_call_accept_update(LinphoneCall *call, const LinphoneCallParams *p linphone_call_params_enable_video_multicast(call->params, FALSE); } } else { - linphone_call_set_new_params(call, params); + _linphone_call_set_new_params(call, params); } if (call->params->has_video && !linphone_core_video_enabled(lc)) { diff --git a/coreapi/private.h b/coreapi/private.h index 9a06306cf..ee49296f8 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -378,7 +378,9 @@ BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneCall); LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, const LinphoneCallParams *params, LinphoneProxyConfig *cfg); LinphoneCall * linphone_call_new_incoming(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, SalOp *op); -void linphone_call_set_new_params(LinphoneCall *call, const LinphoneCallParams *params); +void _linphone_call_set_new_params(LinphoneCall *call, const LinphoneCallParams *params); +void linphone_call_set_params(LinphoneCall *call, const LinphoneCallParams *params); +const LinphoneCallParams * linphone_call_get_params(LinphoneCall *call); void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const char *message); void linphone_call_set_contact_op(LinphoneCall* call); void linphone_call_set_compatible_incoming_call_parameters(LinphoneCall *call, SalMediaDescription *md); diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index 71f2f8191..54bd80b23 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -1523,6 +1523,260 @@ static void call_with_custom_sdp_attributes(void) { linphone_core_manager_destroy(pauline); } + + + +static void call_with_custom_header_or_sdp_cb(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *message) { + + + const char *value; + if (cstate == LinphoneCallOutgoingInit){ + LinphoneCallParams *params = linphone_call_params_copy(linphone_call_get_params(call)); + linphone_call_params_add_custom_sdp_attribute(params, "working", "maybe"); + linphone_call_set_params(call, params); + linphone_call_params_unref(params); + + } + + else if (cstate == LinphoneCallIncomingReceived){ + const LinphoneCallParams *tparams = linphone_call_get_remote_params(call); + LinphoneCallParams *params = linphone_call_params_copy(tparams); + //Check received params + //SDP + value = linphone_call_params_get_custom_sdp_attribute(params, "working"); + BC_ASSERT_PTR_NOT_NULL(value); + if (value) BC_ASSERT_STRING_EQUAL(value, "maybe"); + //header + value = linphone_call_params_get_custom_header(params, "weather"); + BC_ASSERT_PTR_NOT_NULL(value); + if (value) BC_ASSERT_STRING_EQUAL(value, "thunderstorm"); + //modify SDP + linphone_call_params_add_custom_sdp_attribute(params, "working", "yes"); + linphone_call_set_params(call, params); + linphone_call_params_unref(params); + + } + + + +} + +static void call_caller_with_custom_header_or_sdp_attributes(void) { + LinphoneCoreManager *callee_mgr = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager *caller_mgr = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + LinphoneCall *call_caller = NULL, *call_callee = NULL; + LinphoneCallParams *caller_params; // *callee_params ; + + LinphoneCoreVTable *vtable; + + LinphoneCallTestParams caller_test_params = {0}; + LinphoneCallTestParams callee_test_params = {0}; + + stats initial_caller=caller_mgr->stat; + stats initial_callee=callee_mgr->stat; + bool_t result=FALSE; + bool_t did_receive_call; + + //Create caller params with custom header and custom SDP + caller_params = linphone_core_create_call_params(caller_mgr->lc, NULL); + linphone_call_params_add_custom_header(caller_params, "weather", "thunderstorm"); + linphone_call_params_add_custom_sdp_media_attribute(caller_params, LinphoneStreamTypeAudio, "sleeping", "almost"); + + caller_test_params.base = (LinphoneCallParams*)caller_params; + callee_test_params.base = NULL; + + /* TODO: This should be handled correctly inside the liblinphone library but meanwhile handle this here. */ + linphone_core_manager_wait_for_stun_resolution(caller_mgr); + linphone_core_manager_wait_for_stun_resolution(callee_mgr); + + setup_sdp_handling(&caller_test_params, caller_mgr); + setup_sdp_handling(&callee_test_params, callee_mgr); + + // Assign dedicated callback to vtable for caller and callee + vtable = linphone_core_v_table_new(); + vtable->call_state_changed = call_with_custom_header_or_sdp_cb; + linphone_core_add_listener(callee_mgr->lc, vtable); + linphone_core_add_listener(caller_mgr->lc, vtable); + + //Caller initates the call with INVITE + // caller params not null + BC_ASSERT_PTR_NOT_NULL((call_caller=linphone_core_invite_address_with_params(caller_mgr->lc,callee_mgr->identity,caller_params))); + + BC_ASSERT_PTR_NULL(linphone_call_get_remote_params(call_caller)); /*assert that remote params are NULL when no response is received yet*/ + + // Wait for Incoming received + did_receive_call = wait_for(callee_mgr->lc + ,caller_mgr->lc + ,&callee_mgr->stat.number_of_LinphoneCallIncomingReceived + ,initial_callee.number_of_LinphoneCallIncomingReceived+1); + BC_ASSERT_EQUAL(did_receive_call, !callee_test_params.sdp_simulate_error, int, "%d"); + + linphone_call_params_unref(caller_params); + + sal_default_set_sdp_handling(caller_mgr->lc->sal, SalOpSDPNormal); + sal_default_set_sdp_handling(callee_mgr->lc->sal, SalOpSDPNormal); + + // Wait for Outgoing Progress + if (linphone_core_get_calls_nb(callee_mgr->lc)<=1) + BC_ASSERT_TRUE(linphone_core_inc_invite_pending(callee_mgr->lc)); + BC_ASSERT_EQUAL(caller_mgr->stat.number_of_LinphoneCallOutgoingProgress,initial_caller.number_of_LinphoneCallOutgoingProgress+1, int, "%d"); + + + + + LinphoneCallParams *default_params=linphone_core_create_call_params(callee_mgr->lc,call_callee); + ms_message("Created default call params with video=%i", linphone_call_params_video_enabled(default_params)); + linphone_core_accept_call_with_params(callee_mgr->lc,call_callee,default_params); + linphone_call_params_unref(default_params); + + + BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallConnected,initial_callee.number_of_LinphoneCallConnected+1)); + BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallConnected,initial_caller.number_of_LinphoneCallConnected+1)); + + result = wait_for_until(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_caller.number_of_LinphoneCallStreamsRunning+1, 2000) + && + wait_for_until(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_callee.number_of_LinphoneCallStreamsRunning+1, 2000); + + + + caller_params = linphone_core_create_call_params(caller_mgr->lc, call_caller); + linphone_call_params_clear_custom_sdp_attributes(caller_params); + linphone_call_params_clear_custom_sdp_media_attributes(caller_params, LinphoneStreamTypeAudio); + linphone_call_params_add_custom_sdp_attribute(caller_params, "weather", "sunny"); + linphone_core_update_call(caller_mgr->lc, call_caller, caller_params); + linphone_call_params_unref(caller_params); + + + end_call(caller_mgr, callee_mgr); + + linphone_core_manager_destroy(callee_mgr); + linphone_core_manager_destroy(caller_mgr); +} + + + + +static void call_callee_with_custom_header_or_sdp_cb(LinphoneCore *lc, LinphoneCall *call, LinphoneCallState cstate, const char *message) { + + + const char *value; + if (cstate == LinphoneCallOutgoingInit){ + LinphoneCallParams *params = linphone_call_params_copy(linphone_call_get_params(call)); + linphone_call_params_add_custom_sdp_attribute(params, "working", "maybe"); + linphone_call_set_params(call, params); + linphone_call_params_unref(params); + + } + + else if (cstate == LinphoneCallIncomingReceived){ + const LinphoneCallParams *tparams = linphone_call_get_remote_params(call); + LinphoneCallParams *params = linphone_call_params_copy(tparams); + value = linphone_call_params_get_custom_sdp_attribute(params, "working"); + BC_ASSERT_PTR_NOT_NULL(value); + if (value) BC_ASSERT_STRING_EQUAL(value, "maybe"); + linphone_call_set_params(call, params); + linphone_call_params_unref(params); + + } + +} + + +static void call_callee_with_custom_header_or_sdp_attributes(void) { + LinphoneCoreManager *callee_mgr = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager *caller_mgr = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + LinphoneCall *call_caller = NULL, *call_callee = NULL; + LinphoneCallParams *callee_params, *caller_params ; + + LinphoneCoreVTable *vtable; + const char *value; + LinphoneCallTestParams caller_test_params = {0}; + LinphoneCallTestParams callee_test_params = {0}; + + stats initial_caller=caller_mgr->stat; + stats initial_callee=callee_mgr->stat; + bool_t result=FALSE; + bool_t did_receive_call; + const LinphoneCallParams *caller_remote_params; + + caller_params = linphone_core_create_call_params(caller_mgr->lc, NULL); + + + callee_test_params.base = NULL; + caller_test_params.base = NULL; + + /* TODO: This should be handled correctly inside the liblinphone library but meanwhile handle this here. */ + linphone_core_manager_wait_for_stun_resolution(caller_mgr); + linphone_core_manager_wait_for_stun_resolution(callee_mgr); + + setup_sdp_handling(&caller_test_params, caller_mgr); + setup_sdp_handling(&callee_test_params, callee_mgr); + + // Assign dedicated callback to vtable for caller and callee + vtable = linphone_core_v_table_new(); + vtable->call_state_changed = call_callee_with_custom_header_or_sdp_cb; + linphone_core_add_listener(callee_mgr->lc, vtable); + linphone_core_add_listener(caller_mgr->lc, vtable); + + //Caller initates the call with INVITE + // caller params not null + BC_ASSERT_PTR_NOT_NULL((call_caller=linphone_core_invite_address_with_params(caller_mgr->lc,callee_mgr->identity,caller_params))); + + BC_ASSERT_PTR_NULL(linphone_call_get_remote_params(call_caller)); /*assert that remote params are NULL when no response is received yet*/ + + // Wait for Incoming received + did_receive_call = wait_for(callee_mgr->lc + ,caller_mgr->lc + ,&callee_mgr->stat.number_of_LinphoneCallIncomingReceived + ,initial_callee.number_of_LinphoneCallIncomingReceived+1); + BC_ASSERT_EQUAL(did_receive_call, !callee_test_params.sdp_simulate_error, int, "%d"); + + + + sal_default_set_sdp_handling(caller_mgr->lc->sal, SalOpSDPNormal); + sal_default_set_sdp_handling(callee_mgr->lc->sal, SalOpSDPNormal); + + // Wait for Outgoing Progress + if (linphone_core_get_calls_nb(callee_mgr->lc)<=1) + BC_ASSERT_TRUE(linphone_core_inc_invite_pending(callee_mgr->lc)); + BC_ASSERT_EQUAL(caller_mgr->stat.number_of_LinphoneCallOutgoingProgress,initial_caller.number_of_LinphoneCallOutgoingProgress+1, int, "%d"); + + + //Create callee params with custom header and custom SDP + + + callee_params = linphone_core_create_call_params(callee_mgr->lc,call_callee); + linphone_call_params_add_custom_header(callee_params, "weather", "thunderstorm"); + linphone_call_params_add_custom_sdp_media_attribute(callee_params, LinphoneStreamTypeAudio, "sleeping", "almost"); + linphone_call_params_add_custom_sdp_attribute(callee_params, "working", "yes"); + ms_message("Created default call params with video=%i", linphone_call_params_video_enabled(callee_params)); + linphone_core_accept_call_with_params(callee_mgr->lc,call_callee,callee_params); + linphone_call_params_unref(callee_params); + + + BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallConnected,initial_callee.number_of_LinphoneCallConnected+1)); + BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallConnected,initial_caller.number_of_LinphoneCallConnected+1)); + + result = wait_for_until(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_caller.number_of_LinphoneCallStreamsRunning+1, 2000) + && + wait_for_until(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_callee.number_of_LinphoneCallStreamsRunning+1, 2000); + + caller_remote_params = linphone_call_get_remote_params(call_caller); + value = linphone_call_params_get_custom_sdp_attribute(caller_remote_params, "working"); + BC_ASSERT_PTR_NOT_NULL(value); + if (value) BC_ASSERT_STRING_EQUAL(value, "yes"); + //header + value = linphone_call_params_get_custom_header(caller_remote_params, "weather"); + BC_ASSERT_PTR_NOT_NULL(value); + if (value) BC_ASSERT_STRING_EQUAL(value, "thunderstorm"); + + linphone_call_params_unref(caller_params); + end_call(caller_mgr, callee_mgr); + + linphone_core_manager_destroy(callee_mgr); + linphone_core_manager_destroy(caller_mgr); +} + void call_paused_resumed_base(bool_t multicast, bool_t with_losses) { LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); @@ -5493,6 +5747,8 @@ test_t call_tests[] = { TEST_ONE_TAG("Call with ICE added by reINVITE", ice_added_by_reinvite, "ICE"), TEST_NO_TAG("Call with custom headers", call_with_custom_headers), TEST_NO_TAG("Call with custom SDP attributes", call_with_custom_sdp_attributes), + TEST_NO_TAG("Call caller with custom header or sdp", call_caller_with_custom_header_or_sdp_attributes), + TEST_NO_TAG("Call callee with custom header or sdp", call_callee_with_custom_header_or_sdp_attributes), TEST_NO_TAG("Call established with rejected INFO", call_established_with_rejected_info), TEST_NO_TAG("Call established with rejected RE-INVITE", call_established_with_rejected_reinvite), TEST_NO_TAG("Call established with rejected incoming RE-INVITE", call_established_with_rejected_incoming_reinvite), From 931a13df6c53a8a2cbc1f6cccdeb2510a38bc375 Mon Sep 17 00:00:00 2001 From: Sandrine Avakian Date: Thu, 23 Mar 2017 11:26:44 +0100 Subject: [PATCH 02/70] Modifying linphone_core_notify_notify_presence_received and linphone_core_notify_notify_presence_received_for_uri_or_tel to be public. Declaring them into core.h . --- coreapi/private.h | 2 -- include/linphone/core.h | 22 ++++++++++++++++++++++ 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/coreapi/private.h b/coreapi/private.h index ee49296f8..f4550b6f9 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -1625,8 +1625,6 @@ void linphone_core_notify_display_status(LinphoneCore *lc, const char *message); void linphone_core_notify_display_message(LinphoneCore *lc, const char *message); void linphone_core_notify_display_warning(LinphoneCore *lc, const char *message); void linphone_core_notify_display_url(LinphoneCore *lc, const char *message, const char *url); -void linphone_core_notify_notify_presence_received(LinphoneCore *lc, LinphoneFriend * lf); -void linphone_core_notify_notify_presence_received_for_uri_or_tel(LinphoneCore *lc, LinphoneFriend *lf, const char *uri_or_tel, const LinphonePresenceModel *presence_model); void linphone_core_notify_new_subscription_requested(LinphoneCore *lc, LinphoneFriend *lf, const char *url); void linphone_core_notify_auth_info_requested(LinphoneCore *lc, const char *realm, const char *username, const char *domain); void linphone_core_notify_authentication_requested(LinphoneCore *lc, LinphoneAuthInfo *auth_info, LinphoneAuthMethod method); diff --git a/include/linphone/core.h b/include/linphone/core.h index 568a17672..31dea093e 100644 --- a/include/linphone/core.h +++ b/include/linphone/core.h @@ -5008,6 +5008,28 @@ LINPHONE_PUBLIC LinphonePresencePerson * linphone_core_create_presence_person(Li * @return The created #LinphonePresenceService object. */ LINPHONE_PUBLIC LinphonePresenceService * linphone_core_create_presence_service(LinphoneCore *lc, const char *id, LinphonePresenceBasicStatus basic_status, const char *contact); + + +/** + * Notifies the upper layer that a presence status has been received by calling the appropriate + * callback if one has been set. + * @param[in] lc the #LinphoneCore object. + * @param[in] lf the #LinphoneFriend whose presence information has been received. + */ +LINPHONE_PUBLIC void linphone_core_notify_notify_presence_received(LinphoneCore *lc, LinphoneFriend *lf); + + +/** + * Notifies the upper layer that a presence model change has been received for the uri or + * telephone number given as a parameter, by calling the appropriate callback if one has been set. + * @param[in] lc the #LinphoneCore object. + * @param[in] lf the #LinphoneFriend whose presence information has been received. + * @param[in] uri_or_tel telephone number or sip uri + * @param[in] presence_model the #LinphonePresenceModel that has been modified + */ +LINPHONE_PUBLIC void linphone_core_notify_notify_presence_received_for_uri_or_tel(LinphoneCore *lc, LinphoneFriend *lf, const char *uri_or_tel, const LinphonePresenceModel *presence_model); + + /** * @} From 836329e64ead2b29cccab8253fa26fede91da9b1 Mon Sep 17 00:00:00 2001 From: Sandrine Avakian Date: Thu, 23 Mar 2017 11:39:57 +0100 Subject: [PATCH 03/70] Update ortp and mediastreamer2 --- mediastreamer2 | 2 +- oRTP | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediastreamer2 b/mediastreamer2 index cd3e093c3..1f17b3ba2 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit cd3e093c3282e99496b0eb5387a545e119e868f3 +Subproject commit 1f17b3ba22cb662c1c15655c8248036e7a69baf2 diff --git a/oRTP b/oRTP index 920817911..235e5175b 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 920817911d9287250d9ddf506aede06744faae4b +Subproject commit 235e5175b2befa2d3e5f19cd969b0f3bda5b9b4c From ad337fffefbc372b1098735b1802f3d767fa0a41 Mon Sep 17 00:00:00 2001 From: Sandrine Avakian Date: Mon, 27 Mar 2017 15:27:42 +0200 Subject: [PATCH 04/70] Adding new API int linphone_call_terminate_with_error_info(LinphoneCall *call, const LinphoneErrorInfo *ei) and other functions to handle RFC3326 reason header. --- coreapi/bellesip_sal/sal_op_call.c | 20 +++++++++-- coreapi/bellesip_sal/sal_op_impl.c | 5 ++- coreapi/callbacks.c | 2 +- coreapi/error_info.c | 14 ++++++-- coreapi/factory.c | 6 ++++ coreapi/linphonecall.c | 42 +++++++++++++++++++++-- coreapi/linphonecore.c | 2 +- include/linphone/call.h | 9 ++++- include/linphone/error_info.h | 21 ++++++++++-- include/linphone/factory.h | 5 +++ include/sal/sal.h | 1 + tester/call_single_tester.c | 53 +++++++++++++++++++++++++++++- 12 files changed, 166 insertions(+), 14 deletions(-) diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index 6b4bc13d6..825c01642 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -1039,7 +1039,8 @@ int sal_call_send_dtmf(SalOp *h, char dtmf){ return 0; } -int sal_call_terminate(SalOp *op){ + +int sal_call_terminate_with_error(SalOp *op, const SalErrorInfo *info){ belle_sip_dialog_state_t dialog_state=op->dialog?belle_sip_dialog_get_state(op->dialog):BELLE_SIP_DIALOG_NULL; if (op->state==SalOpStateTerminating || op->state==SalOpStateTerminated) { ms_error("Cannot terminate op [%p] in state [%s]",op,sal_op_state_to_string(op->state)); @@ -1047,10 +1048,19 @@ int sal_call_terminate(SalOp *op){ } switch(dialog_state) { case BELLE_SIP_DIALOG_CONFIRMED: { - sal_op_send_request(op,belle_sip_dialog_create_request(op->dialog,"BYE")); + belle_sip_request_t * req = belle_sip_dialog_create_request(op->dialog,"BYE"); + if (info != NULL){ + belle_sip_header_reason_t* reason = BELLE_SIP_HEADER_REASON(belle_sip_header_reason_new()); + belle_sip_header_reason_set_text(reason, info->status_string); + belle_sip_header_reason_set_protocol(reason,info->protocol); + belle_sip_header_reason_set_cause(reason,info->protocol_code); + belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(reason)); + } + sal_op_send_request(op,req); op->state=SalOpStateTerminating; break; } + case BELLE_SIP_DIALOG_NULL: { if (op->dir == SalOpDirIncoming) { sal_call_decline(op, SalReasonDeclined,NULL); @@ -1085,6 +1095,12 @@ int sal_call_terminate(SalOp *op){ return 0; } + +int sal_call_terminate(SalOp *op){ + return sal_call_terminate_with_error(op, NULL); +} + + bool_t sal_call_autoanswer_asked(SalOp *op){ return op->auto_answer_asked; } diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c index d7ddaa959..a8e263d37 100644 --- a/coreapi/bellesip_sal/sal_op_impl.c +++ b/coreapi/bellesip_sal/sal_op_impl.c @@ -606,7 +606,7 @@ void sal_error_info_set(SalErrorInfo *ei, SalReason reason, const char *protocol 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; + 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); @@ -633,6 +633,9 @@ 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/callbacks.c b/coreapi/callbacks.c index 3ec88f4a8..1d46cd3a0 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -818,7 +818,7 @@ static void call_terminated(SalOp *op, const char *from){ break; case LinphoneCallIncomingReceived: case LinphoneCallIncomingEarlyMedia: - linphone_error_info_set(call->ei, LinphoneReasonNotAnswered, 0, "Incoming call cancelled", NULL); + linphone_error_info_set(call->ei,NULL, LinphoneReasonNotAnswered, 0, "Incoming call cancelled", NULL); call->non_op_error = TRUE; break; default: diff --git a/coreapi/error_info.c b/coreapi/error_info.c index 288b8e793..0311ac497 100644 --- a/coreapi/error_info.c +++ b/coreapi/error_info.c @@ -216,12 +216,20 @@ void linphone_error_info_from_sal_op(LinphoneErrorInfo *ei, const SalOp *op){ } } -void linphone_error_info_set(LinphoneErrorInfo *ei, LinphoneReason reason, int code, const char *status_string, const char *warning){ +void linphone_error_info_set(LinphoneErrorInfo *ei, const char *protocol, 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); + if (protocol != NULL){ + ei->protocol = bctbx_strdup(protocol); + } + else{ + const char* prot = "SIP"; + ei->protocol = bctbx_strdup(prot); + } + + ei->phrase = bctbx_strdup(status_string); + ei->warnings = bctbx_strdup(warning); } diff --git a/coreapi/factory.c b/coreapi/factory.c index 867d6be24..1ac43dc9f 100644 --- a/coreapi/factory.c +++ b/coreapi/factory.c @@ -169,3 +169,9 @@ void linphone_factory_set_msplugins_dir(LinphoneFactory *factory, const char *pa if (factory->msplugins_dir) bctbx_free(factory->msplugins_dir); factory->msplugins_dir = bctbx_strdup(path); } + +LinphoneErrorInfo *linphone_factory_create_error_info(void){ + + return linphone_error_info_new(); + +} diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 8e97cd567..750afb677 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -4327,7 +4327,7 @@ static void linphone_call_lost(LinphoneCall *call){ ms_message("LinphoneCall [%p]: %s", call, temp); linphone_core_notify_display_warning(lc, temp); call->non_op_error = TRUE; - linphone_error_info_set(call->ei, LinphoneReasonIOError, 503, "Media lost", NULL); + linphone_error_info_set(call->ei,NULL, LinphoneReasonIOError, 503, "Media lost", NULL); linphone_call_terminate(call); linphone_core_play_named_tone(lc, LinphoneToneCallLost); ms_free(temp); @@ -5088,6 +5088,44 @@ int linphone_call_terminate(LinphoneCall *call) { return 0; } +static void linphone_call_error_info_to_sal_op(const LinphoneErrorInfo* ei, SalErrorInfo* sei){ + + sei->reason = linphone_error_info_get_reason(ei); + sei->status_string = ms_strdup_safe(ei->phrase); + sei->full_string = ms_strdup_safe(ei->full_string); + sei->warnings = ms_strdup_safe(ei->warnings); + sei->protocol_code = ei->protocol_code; + sei->protocol = ms_strdup_safe(ei->protocol); +} + +int linphone_call_terminate_with_error(LinphoneCall *call , const LinphoneErrorInfo *ei){ + SalErrorInfo sei; + linphone_call_error_info_to_sal_op(ei, &sei); + + ms_message("Terminate call [%p] which is currently in state %s", call, linphone_call_state_to_string(call->state)); + switch (call->state) { + case LinphoneCallReleased: + case LinphoneCallEnd: + case LinphoneCallError: + 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: + return linphone_call_decline(call, LinphoneReasonDeclined); + case LinphoneCallOutgoingInit: + /* In state OutgoingInit, op has to be destroyed */ + sal_op_release(call->op); + call->op = NULL; + break; + default: + sal_call_terminate_with_error(call->op, &sei); + break; + } + terminate_call(call); + return 0; + +} + int linphone_call_redirect(LinphoneCall *call, const char *redirect_uri) { char *real_url = NULL; LinphoneCore *lc; @@ -5109,7 +5147,7 @@ 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); - linphone_error_info_set(call->ei, LinphoneReasonMovedPermanently, 302, "Call redirected", NULL); + linphone_error_info_set(call->ei, NULL, LinphoneReasonMovedPermanently, 302, "Call redirected", NULL); call->non_op_error = TRUE; terminate_call(call); linphone_address_unref(real_parsed_url); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index d4c64e416..576d99095 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2980,7 +2980,7 @@ void linphone_core_iterate(LinphoneCore *lc){ decline_reason = (lc->current_call != call) ? LinphoneReasonBusy : LinphoneReasonDeclined; call->log->status=LinphoneCallMissed; call->non_op_error = TRUE; - linphone_error_info_set(call->ei, decline_reason, linphone_reason_to_error_code(decline_reason), "Not answered", NULL); + linphone_error_info_set(call->ei, NULL, decline_reason, linphone_reason_to_error_code(decline_reason), "Not answered", NULL); linphone_call_decline(call, decline_reason); } } diff --git a/include/linphone/call.h b/include/linphone/call.h index 8d5985274..c1b86fa69 100644 --- a/include/linphone/call.h +++ b/include/linphone/call.h @@ -371,12 +371,19 @@ LINPHONE_PUBLIC int linphone_call_pause(LinphoneCall *call); **/ LINPHONE_PUBLIC int linphone_call_resume(LinphoneCall *call); +/** + * Terminates a call. + * @param[in] call LinphoneCall object + * @return 0 on success, -1 on failure +**/LINPHONE_PUBLIC int linphone_call_terminate(LinphoneCall *call); + + /** * Terminates a call. * @param[in] call LinphoneCall object * @return 0 on success, -1 on failure **/ -LINPHONE_PUBLIC int linphone_call_terminate(LinphoneCall *call); +LINPHONE_PUBLIC int linphone_call_terminate_with_error(LinphoneCall *call, const LinphoneErrorInfo *ei); /** * Redirect the specified call to the given redirect URI. diff --git a/include/linphone/error_info.h b/include/linphone/error_info.h index 22f5e59fa..49980608c 100644 --- a/include/linphone/error_info.h +++ b/include/linphone/error_info.h @@ -69,6 +69,13 @@ LINPHONE_PUBLIC LinphoneReason linphone_error_info_get_reason(const LinphoneErro * @return The error phrase **/ LINPHONE_PUBLIC const char * linphone_error_info_get_phrase(const LinphoneErrorInfo *ei); + +/** + * Get protocol from the error info. + * @param[in] ei ErrorInfo object + * @return The protocol + */ +LINPHONE_PUBLIC const char *linphone_error_info_get_protocol(const LinphoneErrorInfo *ei); /** * Provides additional information regarding the failure. @@ -88,10 +95,20 @@ LINPHONE_PUBLIC int linphone_error_info_get_protocol_code(const LinphoneErrorInf /** * Assign information to a LinphoneErrorInfo object. - * @param[in] ei ErrorInfo object + * @param[in] ei ErrorInfo object + * @param[in] protocol protocol name + * @param[in] reason reason from LinphoneReason enum + * @param[in] code protocol code + * @param[in] status_string description of the reason + * @param[in] warning warning message */ -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(LinphoneErrorInfo *ei, const char *protocol, LinphoneReason reason, int code, const char *status_string, const char *warning); +/** + * Assign reason LinphoneReason to a LinphoneErrorUnfo object. + * @param[in] ei ErrorInfo object + * @param[in] reason reason from LinphoneReason enum + */ LINPHONE_PUBLIC void linphone_error_info_set_reason(LinphoneErrorInfo *ei, LinphoneReason reason); /** diff --git a/include/linphone/factory.h b/include/linphone/factory.h index c24d9005f..f570278da 100644 --- a/include/linphone/factory.h +++ b/include/linphone/factory.h @@ -203,6 +203,11 @@ LINPHONE_PUBLIC char * linphone_factory_get_msplugins_dir(const LinphoneFactory */ LINPHONE_PUBLIC void linphone_factory_set_msplugins_dir(LinphoneFactory *factory, const char *path); +/** + * Creates an object LinphoneErrorInfo. + * @return LinphoneErrorInfo object. + */ +LINPHONE_PUBLIC LinphoneErrorInfo *linphone_factory_create_error_info(void); /** * @} */ diff --git a/include/sal/sal.h b/include/sal/sal.h index 40ed02341..09df18d47 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -757,6 +757,7 @@ int sal_call_set_referer(SalOp *h, SalOp *refered_call); SalOp *sal_call_get_replaces(SalOp *h); int sal_call_send_dtmf(SalOp *h, char dtmf); int sal_call_terminate(SalOp *h); +int sal_call_terminate_with_error(SalOp *op, const SalErrorInfo *info); bool_t sal_call_autoanswer_asked(SalOp *op); void sal_call_send_vfu_request(SalOp *h); int sal_call_is_offerer(const SalOp *h); diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index ab29c52c3..315c49742 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -980,6 +980,56 @@ static void simple_call_compatibility_mode(void) { linphone_core_manager_destroy(pauline); } +static void terminate_call_with_error(void) { + LinphoneCoreManager *callee_mgr = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager *caller_mgr = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + + LinphoneCall* out_call = linphone_core_invite_address(caller_mgr->lc,callee_mgr->identity); + LinphoneCall* call_callee ; + + linphone_call_ref(out_call); + LinphoneErrorInfo *ei = linphone_error_info_new(); + linphone_error_info_set(ei, NULL, LinphoneReasonNone, 200, "Call completed elsewhere", NULL); + + BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallOutgoingInit,1)); + BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &callee_mgr->stat.number_of_LinphoneCallIncomingReceived, 1)); + BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallOutgoingProgress, 1)); + + call_callee = linphone_core_get_current_call(callee_mgr->lc); + BC_ASSERT_PTR_NOT_NULL(call_callee); + + BC_ASSERT_EQUAL( linphone_core_accept_call(callee_mgr->lc,call_callee), 0 , int, "%d"); + BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallConnected,1)); + + + + BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallStreamsRunning, 1)); + + + const LinphoneErrorInfo *rei = ei; + + linphone_call_terminate_with_error(out_call,rei); + BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallEnd,1)); + + BC_ASSERT_PTR_NOT_NULL(rei); + if (rei){ + BC_ASSERT_EQUAL(linphone_error_info_get_protocol_code(rei),200, int, "%d"); + BC_ASSERT_PTR_NOT_NULL(linphone_error_info_get_phrase(rei)); + BC_ASSERT_STRING_EQUAL(linphone_error_info_get_phrase(rei), "Call completed elsewhere"); + BC_ASSERT_STRING_EQUAL(linphone_error_info_get_protocol(ei), "SIP"); + + } + + + BC_ASSERT_EQUAL(caller_mgr->stat.number_of_LinphoneCallEnd,1, int, "%d"); + BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallReleased,1)); + + linphone_error_info_unref(ei); + linphone_call_unref(out_call); + linphone_core_manager_destroy(callee_mgr); + linphone_core_manager_destroy(caller_mgr); +} + static void cancelled_call(void) { LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); @@ -5825,7 +5875,8 @@ test_t call_tests[] = { TEST_NO_TAG("Call with ZRTP configured receiver side only", call_with_zrtp_configured_callee_side), TEST_NO_TAG("Call from plain RTP to ZRTP mandatory should be silent", call_from_plain_rtp_to_zrtp), TEST_NO_TAG("Call ZRTP mandatory to plain RTP should be silent", call_from_zrtp_to_plain_rtp), - TEST_NO_TAG("Call with network reachable down in callback", call_with_network_reachable_down_in_callback) + TEST_NO_TAG("Call with network reachable down in callback", call_with_network_reachable_down_in_callback), + TEST_NO_TAG("Call terminated with reason", terminate_call_with_error) }; test_suite_t call_test_suite = {"Single Call", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, From 5f9ba4ea90c5e8b556c5e51d57cacd092da5fbba Mon Sep 17 00:00:00 2001 From: Sandrine Avakian Date: Mon, 27 Mar 2017 16:05:43 +0200 Subject: [PATCH 05/70] replacing ms_strdup_safe by bctbx_strdup. Adding checks in sal_call_terminate_with_error --- coreapi/linphonecall.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 750afb677..006387f35 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -5091,16 +5091,19 @@ int linphone_call_terminate(LinphoneCall *call) { static void linphone_call_error_info_to_sal_op(const LinphoneErrorInfo* ei, SalErrorInfo* sei){ sei->reason = linphone_error_info_get_reason(ei); - sei->status_string = ms_strdup_safe(ei->phrase); - sei->full_string = ms_strdup_safe(ei->full_string); - sei->warnings = ms_strdup_safe(ei->warnings); + sei->status_string = bctbx_strdup(ei->phrase); + sei->full_string = bctbx_strdup(ei->full_string); + sei->warnings = bctbx_strdup(ei->warnings); sei->protocol_code = ei->protocol_code; - sei->protocol = ms_strdup_safe(ei->protocol); + sei->protocol = bctbx_strdup(ei->protocol); } int linphone_call_terminate_with_error(LinphoneCall *call , const LinphoneErrorInfo *ei){ SalErrorInfo sei; - linphone_call_error_info_to_sal_op(ei, &sei); + if (ei != NULL) + { + linphone_call_error_info_to_sal_op(ei, &sei); + } ms_message("Terminate call [%p] which is currently in state %s", call, linphone_call_state_to_string(call->state)); switch (call->state) { @@ -5118,7 +5121,12 @@ int linphone_call_terminate_with_error(LinphoneCall *call , const LinphoneErrorI call->op = NULL; break; default: - sal_call_terminate_with_error(call->op, &sei); + if (ei == NULL){ + sal_call_terminate(call->op); + } + else{ + sal_call_terminate_with_error(call->op, &sei); + } break; } terminate_call(call); From db0191ec9e97831895677f7704edc966a095c482 Mon Sep 17 00:00:00 2001 From: Sandrine Avakian Date: Thu, 30 Mar 2017 10:47:42 +0200 Subject: [PATCH 06/70] Renaming functions : -linphone_call_error_info_to_sal_op into linphone_error_info_to_sal as there is no LinponeCall object involved here. - linphone_call_terminate_with_error into linphone_call_terminate_with_error_info Fixes in linphone_call_terminate_with_error_info. --- coreapi/linphonecall.c | 14 +++++++------- include/linphone/call.h | 2 +- tester/call_single_tester.c | 11 +++++++---- 3 files changed, 15 insertions(+), 12 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 006387f35..6a74909c5 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -5088,7 +5088,7 @@ int linphone_call_terminate(LinphoneCall *call) { return 0; } -static void linphone_call_error_info_to_sal_op(const LinphoneErrorInfo* ei, SalErrorInfo* sei){ +static void linphone_error_info_to_sal(const LinphoneErrorInfo* ei, SalErrorInfo* sei){ sei->reason = linphone_error_info_get_reason(ei); sei->status_string = bctbx_strdup(ei->phrase); @@ -5098,13 +5098,9 @@ static void linphone_call_error_info_to_sal_op(const LinphoneErrorInfo* ei, SalE sei->protocol = bctbx_strdup(ei->protocol); } -int linphone_call_terminate_with_error(LinphoneCall *call , const LinphoneErrorInfo *ei){ +int linphone_call_terminate_with_error_info(LinphoneCall *call , const LinphoneErrorInfo *ei){ SalErrorInfo sei; - if (ei != NULL) - { - linphone_call_error_info_to_sal_op(ei, &sei); - } - + ms_message("Terminate call [%p] which is currently in state %s", call, linphone_call_state_to_string(call->state)); switch (call->state) { case LinphoneCallReleased: @@ -5121,14 +5117,18 @@ int linphone_call_terminate_with_error(LinphoneCall *call , const LinphoneErrorI call->op = NULL; break; default: + if (ei == NULL){ sal_call_terminate(call->op); } else{ + linphone_error_info_to_sal(ei, &sei); sal_call_terminate_with_error(call->op, &sei); + sal_error_info_reset(&sei); } break; } + terminate_call(call); return 0; diff --git a/include/linphone/call.h b/include/linphone/call.h index c1b86fa69..61e48c807 100644 --- a/include/linphone/call.h +++ b/include/linphone/call.h @@ -383,7 +383,7 @@ LINPHONE_PUBLIC int linphone_call_resume(LinphoneCall *call); * @param[in] call LinphoneCall object * @return 0 on success, -1 on failure **/ -LINPHONE_PUBLIC int linphone_call_terminate_with_error(LinphoneCall *call, const LinphoneErrorInfo *ei); +LINPHONE_PUBLIC int linphone_call_terminate_with_error_info(LinphoneCall *call, const LinphoneErrorInfo *ei); /** * Redirect the specified call to the given redirect URI. diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index 315c49742..9c56c968a 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -981,14 +981,17 @@ static void simple_call_compatibility_mode(void) { } static void terminate_call_with_error(void) { + LinphoneCall* call_callee ; + LinphoneErrorInfo *ei ; + const LinphoneErrorInfo *rei ; LinphoneCoreManager *callee_mgr = linphone_core_manager_new("marie_rc"); LinphoneCoreManager *caller_mgr = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCall* out_call = linphone_core_invite_address(caller_mgr->lc,callee_mgr->identity); - LinphoneCall* call_callee ; + linphone_call_ref(out_call); - LinphoneErrorInfo *ei = linphone_error_info_new(); + ei = linphone_error_info_new(); linphone_error_info_set(ei, NULL, LinphoneReasonNone, 200, "Call completed elsewhere", NULL); BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallOutgoingInit,1)); @@ -1006,9 +1009,9 @@ static void terminate_call_with_error(void) { BC_ASSERT_TRUE(wait_for(caller_mgr->lc, callee_mgr->lc, &caller_mgr->stat.number_of_LinphoneCallStreamsRunning, 1)); - const LinphoneErrorInfo *rei = ei; + rei = ei; - linphone_call_terminate_with_error(out_call,rei); + linphone_call_terminate_with_error_info(out_call,rei); BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallEnd,1)); BC_ASSERT_PTR_NOT_NULL(rei); From 92c8c0e4da40fb440f4a7f761601e5123969e281 Mon Sep 17 00:00:00 2001 From: Sandrine Avakian Date: Mon, 3 Apr 2017 14:31:53 +0200 Subject: [PATCH 07/70] First commit for decline call with reason header support --- coreapi/bellesip_sal/sal_op_call.c | 56 +++++++++++++++++++++++++++--- coreapi/bellesip_sal/sal_op_impl.c | 24 +++++++++++-- coreapi/callbacks.c | 13 ++++++- coreapi/error_info.c | 7 ++++ coreapi/factory.c | 3 +- coreapi/linphonecall.c | 50 +++++++++++++++++++++++--- include/linphone/call.h | 2 ++ include/linphone/error_info.h | 2 ++ include/linphone/factory.h | 3 +- include/sal/sal.h | 3 ++ tester/call_single_tester.c | 43 +++++++++++++++++++++++ 11 files changed, 193 insertions(+), 13 deletions(-) diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index 825c01642..7b347d503 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -511,6 +511,7 @@ static int process_sdp_for_invite(SalOp* op,belle_sip_request_t* invite) { belle_sdp_session_description_t* sdp; int err=0; SalReason reason; + SalErrorInfo sei; if (extract_sdp(op,BELLE_SIP_MESSAGE(invite),&sdp,&reason)==0) { if (sdp){ @@ -527,6 +528,7 @@ static int process_sdp_for_invite(SalOp* op,belle_sip_request_t* invite) { }else err=-1; if (err==-1){ + sal_error_info_set(&sei, reason,"SIP", 0, NULL, NULL); sal_call_decline(op,reason,NULL); } return err; @@ -942,6 +944,17 @@ int sal_call_accept(SalOp*h){ return 0; } +static belle_sip_header_reason_t *sal_call_make_reason_header( const SalErrorInfo *info){ + if (info != NULL){ + belle_sip_header_reason_t* reason = BELLE_SIP_HEADER_REASON(belle_sip_header_reason_new()); + belle_sip_header_reason_set_text(reason, info->status_string); + belle_sip_header_reason_set_protocol(reason,info->protocol); + belle_sip_header_reason_set_cause(reason,info->protocol_code); + return reason; + } + return NULL; +} + int sal_call_decline(SalOp *op, SalReason reason, const char *redirection /*optional*/){ belle_sip_response_t* response; belle_sip_header_contact_t* contact=NULL; @@ -970,6 +983,41 @@ int sal_call_decline(SalOp *op, SalReason reason, const char *redirection /*opti return 0; } +int sal_call_decline_with_error_info(SalOp *op, const SalErrorInfo *info, const char *redirection /*optional*/){ + belle_sip_response_t* response; + belle_sip_header_contact_t* contact=NULL; + int status = info->protocol_code; + belle_sip_transaction_t *trans; + + if (info->reason==SalReasonRedirect){ + if (redirection!=NULL) { + if (strstr(redirection,"sip:")!=0) status=302; + else status=380; + contact= belle_sip_header_contact_new(); + belle_sip_header_address_set_uri(BELLE_SIP_HEADER_ADDRESS(contact),belle_sip_uri_parse(redirection)); + } else { + ms_error("Cannot redirect to null"); + } + } + trans=(belle_sip_transaction_t*)op->pending_server_trans; + if (!trans) trans=(belle_sip_transaction_t*)op->pending_update_server_trans; + if (!trans){ + ms_error("sal_call_decline(): no pending transaction to decline."); + return -1; + } + response = sal_op_create_response_from_request(op,belle_sip_transaction_get_request(trans),status); + belle_sip_header_reason_t* reason_header = sal_call_make_reason_header(info->sub_sei); + if (reason_header) { + belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_HEADER(reason_header)); + } + + if (contact) { + belle_sip_message_add_header(BELLE_SIP_MESSAGE(response),BELLE_SIP_HEADER(contact)); + } + belle_sip_server_transaction_send_response(BELLE_SIP_SERVER_TRANSACTION(trans),response); + return 0; +} + 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; @@ -1041,6 +1089,7 @@ int sal_call_send_dtmf(SalOp *h, char dtmf){ int sal_call_terminate_with_error(SalOp *op, const SalErrorInfo *info){ +// SalErrorInfo sei; belle_sip_dialog_state_t dialog_state=op->dialog?belle_sip_dialog_get_state(op->dialog):BELLE_SIP_DIALOG_NULL; if (op->state==SalOpStateTerminating || op->state==SalOpStateTerminated) { ms_error("Cannot terminate op [%p] in state [%s]",op,sal_op_state_to_string(op->state)); @@ -1050,10 +1099,7 @@ int sal_call_terminate_with_error(SalOp *op, const SalErrorInfo *info){ case BELLE_SIP_DIALOG_CONFIRMED: { belle_sip_request_t * req = belle_sip_dialog_create_request(op->dialog,"BYE"); if (info != NULL){ - belle_sip_header_reason_t* reason = BELLE_SIP_HEADER_REASON(belle_sip_header_reason_new()); - belle_sip_header_reason_set_text(reason, info->status_string); - belle_sip_header_reason_set_protocol(reason,info->protocol); - belle_sip_header_reason_set_cause(reason,info->protocol_code); + belle_sip_header_reason_t* reason = sal_call_make_reason_header(info); belle_sip_message_add_header(BELLE_SIP_MESSAGE(req),BELLE_SIP_HEADER(reason)); } sal_op_send_request(op,req); @@ -1063,6 +1109,7 @@ int sal_call_terminate_with_error(SalOp *op, const SalErrorInfo *info){ case BELLE_SIP_DIALOG_NULL: { if (op->dir == SalOpDirIncoming) { + //sal_error_info_set(&sei, SalReasonDeclined,"SIP", 0, NULL, NULL); sal_call_decline(op, SalReasonDeclined,NULL); op->state=SalOpStateTerminated; } else if (op->pending_client_trans){ @@ -1080,6 +1127,7 @@ int sal_call_terminate_with_error(SalOp *op, const SalErrorInfo *info){ } case BELLE_SIP_DIALOG_EARLY: { if (op->dir == SalOpDirIncoming) { + //sal_error_info_set(&sei, SalReasonDeclined,"SIP", 0, NULL, NULL); sal_call_decline(op, SalReasonDeclined,NULL); op->state=SalOpStateTerminated; } else { diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c index a8e263d37..a9c9c8ca1 100644 --- a/coreapi/bellesip_sal/sal_op_impl.c +++ b/coreapi/bellesip_sal/sal_op_impl.c @@ -561,11 +561,22 @@ const SalErrorInfo *sal_error_info_none(void){ "Ok", 200, NULL, - NULL + NULL, + }; return &none; } +void sal_error_info_init_to_null(SalErrorInfo *sei){ + sei->status_string = NULL; + sei->full_string = NULL; + sei->protocol = NULL; + sei->sub_sei = NULL; + sei->warnings = NULL; + sei->protocol_code=0; + sei->reason=SalReasonNone; +} + void sal_error_info_reset(SalErrorInfo *ei){ if (ei->status_string){ ms_free(ei->status_string); @@ -584,6 +595,10 @@ void sal_error_info_reset(SalErrorInfo *ei){ ms_free(ei->protocol); ei->protocol = NULL; } + if (ei->sub_sei){ + ms_free(ei->sub_sei); + ei->sub_sei = NULL; + } ei->protocol_code=0; ei->reason=SalReasonNone; } @@ -591,7 +606,12 @@ void sal_error_info_reset(SalErrorInfo *ei){ 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 && strcmp(protocol, "SIP") == 0) ei->reason=_sal_reason_from_sip_code(code); - else ei->reason=reason; + else{ + ei->reason=reason; + if (code == 0) { + code = sal_reason_to_sip_code(reason); + } + } ei->protocol_code=code; ei->status_string=status_string ? ms_strdup(status_string) : NULL; ei->warnings=warning ? ms_strdup(warning) : NULL; diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 1d46cd3a0..81618bab6 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -269,6 +269,7 @@ static void call_received(SalOp *h){ LinphoneAddress *from_address_to_search_if_me=NULL; /*address used to know if I'm the caller*/ SalMediaDescription *md; const char * p_asserted_id; + SalErrorInfo sei; /* Look if this INVITE is for a call that has already been notified but broken because of network failure */ replaced_call = look_for_broken_call_to_replace(h, lc); @@ -284,6 +285,8 @@ static void call_received(SalOp *h){ case LinphonePresenceActivityPermanentAbsence: alt_contact = linphone_presence_model_get_contact(lc->presence_model); if (alt_contact != NULL) { + sal_error_info_set(&sei,SalReasonRedirect, "SIP", 0, NULL, NULL); + sal_call_decline_with_error_info(h, SalReasonRedirect,alt_contact); sal_call_decline(h,SalReasonRedirect,alt_contact); ms_free(alt_contact); sal_op_release(h); @@ -297,6 +300,7 @@ static void call_received(SalOp *h){ } if (!linphone_core_can_we_add_call(lc)){/*busy*/ + sal_error_info_set(&sei,SalReasonBusy, "SIP", 0, NULL, NULL); sal_call_decline(h,SalReasonBusy,NULL); sal_op_release(h); return; @@ -333,6 +337,7 @@ static void call_received(SalOp *h){ if (from_address_to_search_if_me && already_a_call_with_remote_address(lc,from_address_to_search_if_me)){ char *addr = linphone_address_as_string(from_addr); ms_warning("Receiving a call while one with same address [%s] is initiated, refusing this one with busy message.",addr); + sal_error_info_set(&sei,SalReasonBusy, "SIP", 0, NULL, NULL); sal_call_decline(h,SalReasonBusy,NULL); sal_op_release(h); linphone_address_unref(from_addr); @@ -351,6 +356,7 @@ static void call_received(SalOp *h){ md=sal_call_get_final_media_description(call->op); if (md){ if (sal_media_description_empty(md) || linphone_core_incompatible_security(lc,md)){ + sal_error_info_set(&sei,SalReasonNotAcceptable, "SIP", 0, NULL, NULL); sal_call_decline(call->op,SalReasonNotAcceptable,NULL); linphone_call_unref(call); return; @@ -678,6 +684,7 @@ static void call_updated_by_remote(LinphoneCore *lc, LinphoneCall *call){ /* this callback is called when an incoming re-INVITE/ SIP UPDATE modifies the session*/ static void call_updated(LinphoneCore *lc, LinphoneCall *call, SalOp *op, bool_t is_update){ + SalErrorInfo sei; SalMediaDescription *rmd=sal_call_get_remote_media_description(op); call->defer_update = lp_config_get_int(lc->config, "sip", "defer_update_default", FALSE); @@ -715,6 +722,7 @@ static void call_updated(LinphoneCore *lc, LinphoneCall *call, SalOp *op, bool_t case LinphoneCallUpdating: case LinphoneCallPausing: case LinphoneCallResuming: + sal_error_info_set(&sei,SalReasonInternalError, "SIP", 0, NULL, NULL); sal_call_decline(call->op,SalReasonInternalError,NULL); /*no break*/ case LinphoneCallIdle: @@ -737,7 +745,8 @@ 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); - + SalErrorInfo sei; + if (!call) { ms_error("call_updating(): call doesn't exist anymore"); return ; @@ -767,6 +776,7 @@ static void call_updating(SalOp *op, bool_t is_update){ md=sal_call_get_final_media_description(call->op); if (md && (sal_media_description_empty(md) || linphone_core_incompatible_security(lc,md))){ + sal_error_info_set(&sei,SalReasonNotAcceptable, "SIP", 0, NULL, NULL); sal_call_decline(call->op,SalReasonNotAcceptable,NULL); return; } @@ -774,6 +784,7 @@ static void call_updating(SalOp *op, bool_t is_update){ int diff=sal_media_description_equals(prev_result_desc,md); if (diff & (SAL_MEDIA_DESCRIPTION_CRYPTO_POLICY_CHANGED|SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED)){ ms_warning("Cannot accept this update, it is changing parameters that require user approval"); + sal_error_info_set(&sei,SalReasonNotAcceptable, "SIP", 0, NULL, NULL); sal_call_decline(call->op,SalReasonNotAcceptable,NULL); /*FIXME should send 504 Cannot change the session parameters without prompting the user"*/ return; } diff --git a/coreapi/error_info.c b/coreapi/error_info.c index 832a8361d..8f9e9cbb4 100644 --- a/coreapi/error_info.c +++ b/coreapi/error_info.c @@ -31,6 +31,7 @@ static void error_info_destroy(LinphoneErrorInfo *ei){ } static void error_info_clone(LinphoneErrorInfo *ei, const LinphoneErrorInfo *other){ + linphone_error_info_set_reason(ei, linphone_error_info_get_reason(other)); ei->protocol = bctbx_strdup(other->protocol); ei->phrase = bctbx_strdup(other->phrase); ei->warnings = bctbx_strdup(other->warnings); @@ -213,6 +214,12 @@ void linphone_error_info_from_sal_op(LinphoneErrorInfo *ei, const SalOp *op){ } } +void linphone_error_info_set_sub_error_info(LinphoneErrorInfo *ei, LinphoneErrorInfo *appended_ei){ + if (appended_ei != NULL){ + ei->sub_ei = appended_ei; + } +} + void linphone_error_info_set(LinphoneErrorInfo *ei, const char *protocol, LinphoneReason reason, int code, const char *status_string, const char *warning){ linphone_error_info_reset(ei); ei->reason = reason; diff --git a/coreapi/factory.c b/coreapi/factory.c index 05d8ad4ce..738dc9db4 100644 --- a/coreapi/factory.c +++ b/coreapi/factory.c @@ -53,6 +53,7 @@ struct _LinphoneFactory { char *cached_ring_resources_dir; char *cached_image_resources_dir; char *cached_msplugins_dir; + LinphoneErrorInfo* ei; }; static void linphone_factory_uninit(LinphoneFactory *obj){ @@ -207,7 +208,7 @@ void linphone_factory_set_msplugins_dir(LinphoneFactory *factory, const char *pa STRING_SET(factory->msplugins_dir, path); } -LinphoneErrorInfo *linphone_factory_create_error_info(void){ +LinphoneErrorInfo *linphone_factory_create_error_info(LinphoneFactory *factory){ return linphone_error_info_new(); diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 504e549f0..02b508247 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -5100,18 +5100,29 @@ int linphone_call_terminate(LinphoneCall *call) { return 0; } -static void linphone_error_info_to_sal(const LinphoneErrorInfo* ei, SalErrorInfo* sei){ - +static void linphone_error_info_fields_to_sal(const LinphoneErrorInfo* ei, SalErrorInfo* sei){ + sei->reason = linphone_error_info_get_reason(ei); sei->status_string = bctbx_strdup(ei->phrase); sei->full_string = bctbx_strdup(ei->full_string); sei->warnings = bctbx_strdup(ei->warnings); sei->protocol_code = ei->protocol_code; sei->protocol = bctbx_strdup(ei->protocol); + +} + +static void linphone_error_info_to_sal(const LinphoneErrorInfo* ei, SalErrorInfo* sei){ + + linphone_error_info_fields_to_sal(ei, sei); + if (ei->sub_ei !=NULL) { + + linphone_error_info_to_sal(ei->sub_ei, sei->sub_sei); + } } int linphone_call_terminate_with_error_info(LinphoneCall *call , const LinphoneErrorInfo *ei){ - SalErrorInfo sei; + SalErrorInfo sei ; + sal_error_info_init_to_null(&sei); ms_message("Terminate call [%p] which is currently in state %s", call, linphone_call_state_to_string(call->state)); switch (call->state) { @@ -5150,6 +5161,7 @@ int linphone_call_redirect(LinphoneCall *call, const char *redirect_uri) { char *real_url = NULL; LinphoneCore *lc; LinphoneAddress *real_parsed_url; + SalErrorInfo sei; if (call->state != LinphoneCallIncomingReceived) { ms_error("Bad state for call redirection."); @@ -5165,6 +5177,7 @@ int linphone_call_redirect(LinphoneCall *call, const char *redirect_uri) { } real_url = linphone_address_as_string(real_parsed_url); + sal_error_info_set(&sei,SalReasonRedirect, "SIP", 0, NULL, NULL); sal_call_decline(call->op, SalReasonRedirect, real_url); ms_free(real_url); linphone_error_info_set(call->ei, NULL, LinphoneReasonMovedPermanently, 302, "Call redirected", NULL); @@ -5175,16 +5188,43 @@ int linphone_call_redirect(LinphoneCall *call, const char *redirect_uri) { } int linphone_call_decline(LinphoneCall * call, LinphoneReason reason) { + SalErrorInfo sei; if ((call->state != LinphoneCallIncomingReceived) && (call->state != LinphoneCallIncomingEarlyMedia)) { ms_error("Cannot decline a call that is in state %s", linphone_call_state_to_string(call->state)); return -1; } - + sal_error_info_set(&sei, linphone_reason_to_sal(reason),"SIP", 0, NULL, NULL); sal_call_decline(call->op, linphone_reason_to_sal(reason), NULL); terminate_call(call); return 0; } + +static const LinphoneErrorInfo* linphone_error_info_get_sub(const LinphoneErrorInfo *ei){ + + return ei->sub_ei; +} + +int linphone_call_decline_with_error(LinphoneCall * call, const LinphoneErrorInfo *ei) { + SalErrorInfo sei; + sal_error_info_init_to_null(&sei); + SalErrorInfo sub_sei; + sal_error_info_init_to_null(&sub_sei); + sei.sub_sei = &sub_sei; + + if ((call->state != LinphoneCallIncomingReceived) && (call->state != LinphoneCallIncomingEarlyMedia)) { + ms_error("Cannot decline a call that is in state %s", linphone_call_state_to_string(call->state)); + return -1; + } + linphone_error_info_to_sal(ei, &sei); + //linphone_error_info_to_sal(ei->sub_ei, &sub_sei); + //sei.sub_sei = &sub_sei; + // check if sub reason exists + + sal_call_decline_with_error_info(call->op, &sei , NULL); + terminate_call(call); + return 0; +} int linphone_call_accept(LinphoneCall *call) { return linphone_call_accept_with_params(call, NULL); } @@ -5779,6 +5819,7 @@ void linphone_call_reinvite_to_recover_from_connection_loss(LinphoneCall *call) } void linphone_call_repair_if_broken(LinphoneCall *call){ + SalErrorInfo sei; if (!call->broken) return; if (!call->core->media_network_reachable) return; @@ -5808,6 +5849,7 @@ void linphone_call_repair_if_broken(LinphoneCall *call){ break; case LinphoneCallUpdatedByRemote: if (sal_call_dialog_request_pending(call->op)) { + sal_error_info_set(&sei, SalReasonServiceUnavailable,"SIP", 0, NULL, NULL); sal_call_decline(call->op, SalReasonServiceUnavailable, NULL); } linphone_call_reinvite_to_recover_from_connection_loss(call); diff --git a/include/linphone/call.h b/include/linphone/call.h index d23c10867..0afd289ca 100644 --- a/include/linphone/call.h +++ b/include/linphone/call.h @@ -401,6 +401,8 @@ LINPHONE_PUBLIC int linphone_call_redirect(LinphoneCall *call, const char *redir * @return 0 on success, -1 on failure **/ LINPHONE_PUBLIC int linphone_call_decline(LinphoneCall * call, LinphoneReason reason); + +LINPHONE_PUBLIC int linphone_call_decline_with_error(LinphoneCall * call, const LinphoneErrorInfo *ei); /** * Accept an incoming call. diff --git a/include/linphone/error_info.h b/include/linphone/error_info.h index 49980608c..61ea9b6e6 100644 --- a/include/linphone/error_info.h +++ b/include/linphone/error_info.h @@ -103,6 +103,8 @@ LINPHONE_PUBLIC int linphone_error_info_get_protocol_code(const LinphoneErrorInf * @param[in] warning warning message */ LINPHONE_PUBLIC void linphone_error_info_set(LinphoneErrorInfo *ei, const char *protocol, LinphoneReason reason, int code, const char *status_string, const char *warning); + +LINPHONE_PUBLIC void linphone_error_info_set_sub_error_info(LinphoneErrorInfo *ei, LinphoneErrorInfo *appended_ei); /** * Assign reason LinphoneReason to a LinphoneErrorUnfo object. diff --git a/include/linphone/factory.h b/include/linphone/factory.h index b4f785ad4..ef26ea7d3 100644 --- a/include/linphone/factory.h +++ b/include/linphone/factory.h @@ -205,9 +205,10 @@ LINPHONE_PUBLIC void linphone_factory_set_msplugins_dir(LinphoneFactory *factory /** * Creates an object LinphoneErrorInfo. + * @param[in] factory LinphoneFactory object * @return LinphoneErrorInfo object. */ -LINPHONE_PUBLIC LinphoneErrorInfo *linphone_factory_create_error_info(void); +LINPHONE_PUBLIC LinphoneErrorInfo *linphone_factory_create_error_info(LinphoneFactory *factory); /** * @} */ diff --git a/include/sal/sal.h b/include/sal/sal.h index 09df18d47..d5eb9d91c 100644 --- a/include/sal/sal.h +++ b/include/sal/sal.h @@ -412,6 +412,7 @@ typedef struct SalErrorInfo{ char *warnings; char *protocol; char *full_string; /*concatenation of status_string + warnings*/ + struct SalErrorInfo *sub_sei; }SalErrorInfo; typedef enum SalPresenceStatus{ @@ -729,6 +730,7 @@ 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_init_to_null(SalErrorInfo *sei); 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)*/ @@ -744,6 +746,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_decline_with_error_info(SalOp *h, const SalErrorInfo* info, const char *redirection /*optional*/); int sal_call_update(SalOp *h, const char *subject, bool_t no_user_consent); void sal_call_cancel_invite(SalOp *op); SalMediaDescription * sal_call_get_remote_media_description(SalOp *h); diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index 9c56c968a..c00065237 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -1189,6 +1189,48 @@ static void call_busy_when_calling_self(void) { linphone_core_manager_destroy(marie); } +static void call_declined_with_error(void) { + LinphoneCoreManager* callee_mgr = linphone_core_manager_new("marie_rc"); + LinphoneCoreManager* caller_mgr = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); + + LinphoneCall* in_call; + LinphoneCall* out_call = linphone_core_invite_address(caller_mgr->lc,callee_mgr->identity); + LinphoneFactory* factory = linphone_factory_get(); + + LinphoneErrorInfo *ei = linphone_factory_create_error_info(factory); + LinphoneErrorInfo *reason_ei = linphone_factory_create_error_info(factory); + + linphone_error_info_set(ei, "SIP", LinphoneReasonUnknown, 603, "Decline", NULL); //ordre des arguments à vérifier + linphone_error_info_set(reason_ei, "hardware", LinphoneReasonUnknown, 66, "J'ai plus de batterie", NULL); + + linphone_error_info_set_sub_error_info(ei, reason_ei); + + linphone_call_ref(out_call); + BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallIncomingReceived,1)); + BC_ASSERT_PTR_NOT_NULL(in_call=linphone_core_get_current_call(callee_mgr->lc)); + if (in_call) { + linphone_call_ref(in_call); + linphone_call_decline_with_error(in_call, ei); + // linphone_call_terminate(in_call); + BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallReleased,1)); + BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallReleased,1)); + BC_ASSERT_EQUAL(callee_mgr->stat.number_of_LinphoneCallEnd,1, int, "%d"); + BC_ASSERT_EQUAL(caller_mgr->stat.number_of_LinphoneCallEnd,1, int, "%d"); + BC_ASSERT_EQUAL(linphone_call_get_reason(in_call),LinphoneReasonDeclined, int, "%d"); + BC_ASSERT_EQUAL(linphone_call_log_get_status(linphone_call_get_call_log(in_call)),LinphoneCallDeclined, int, "%d"); + BC_ASSERT_EQUAL(linphone_call_get_reason(out_call),LinphoneReasonDeclined, int, "%d"); + BC_ASSERT_EQUAL(linphone_call_log_get_status(linphone_call_get_call_log(out_call)),LinphoneCallDeclined, int, "%d"); + + + linphone_call_unref(in_call); + } + linphone_call_unref(out_call); + //linphone_error_info_unref(reason_ei); + linphone_error_info_unref(ei); + + linphone_core_manager_destroy(callee_mgr); + linphone_core_manager_destroy(caller_mgr); +} static void call_declined(void) { LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); @@ -5736,6 +5778,7 @@ static void call_with_network_reachable_down_in_callback(void){ test_t call_tests[] = { TEST_NO_TAG("Early declined call", early_declined_call), TEST_NO_TAG("Call declined", call_declined), + TEST_NO_TAG("Call declined with error", call_declined_with_error), TEST_NO_TAG("Cancelled call", cancelled_call), TEST_NO_TAG("Early cancelled call", early_cancelled_call), TEST_NO_TAG("Call with DNS timeout", call_with_dns_time_out), From ca3e442d9fc38185cab32d0b7fb220fd7cccb65d Mon Sep 17 00:00:00 2001 From: Sandrine Avakian Date: Tue, 4 Apr 2017 14:09:44 +0200 Subject: [PATCH 08/70] Replacing most calls to sal_call_decline with sal_call_decline_with_error_info --- coreapi/bellesip_sal/sal_op_call.c | 23 ++++++++++++++++------- coreapi/bellesip_sal/sal_op_impl.c | 2 +- coreapi/callbacks.c | 24 +++++++++++++++--------- coreapi/linphonecall.c | 18 ++++++++---------- include/linphone/call.h | 8 +++++++- include/linphone/error_info.h | 5 +++++ 6 files changed, 52 insertions(+), 28 deletions(-) diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index 7b347d503..0621232da 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -528,8 +528,10 @@ static int process_sdp_for_invite(SalOp* op,belle_sip_request_t* invite) { }else err=-1; if (err==-1){ + sal_error_info_init_to_null(&sei); sal_error_info_set(&sei, reason,"SIP", 0, NULL, NULL); - sal_call_decline(op,reason,NULL); + sal_call_decline_with_error_info(op, &sei,NULL); + } return err; } @@ -1002,7 +1004,7 @@ int sal_call_decline_with_error_info(SalOp *op, const SalErrorInfo *info, const trans=(belle_sip_transaction_t*)op->pending_server_trans; if (!trans) trans=(belle_sip_transaction_t*)op->pending_update_server_trans; if (!trans){ - ms_error("sal_call_decline(): no pending transaction to decline."); + ms_error("sal_call_decline_with_error_info(): no pending transaction to decline."); return -1; } response = sal_op_create_response_from_request(op,belle_sip_transaction_get_request(trans),status); @@ -1089,7 +1091,16 @@ int sal_call_send_dtmf(SalOp *h, char dtmf){ int sal_call_terminate_with_error(SalOp *op, const SalErrorInfo *info){ -// SalErrorInfo sei; + SalErrorInfo sei; + const SalErrorInfo *p_sei; + if (info == NULL){ + sal_error_info_init_to_null(&sei); + sal_error_info_set(&sei,SalReasonDeclined, "SIP", 0, NULL, NULL); + p_sei = &sei; + } else{ + p_sei = info; + + } belle_sip_dialog_state_t dialog_state=op->dialog?belle_sip_dialog_get_state(op->dialog):BELLE_SIP_DIALOG_NULL; if (op->state==SalOpStateTerminating || op->state==SalOpStateTerminated) { ms_error("Cannot terminate op [%p] in state [%s]",op,sal_op_state_to_string(op->state)); @@ -1109,8 +1120,7 @@ int sal_call_terminate_with_error(SalOp *op, const SalErrorInfo *info){ case BELLE_SIP_DIALOG_NULL: { if (op->dir == SalOpDirIncoming) { - //sal_error_info_set(&sei, SalReasonDeclined,"SIP", 0, NULL, NULL); - sal_call_decline(op, SalReasonDeclined,NULL); + sal_call_decline_with_error_info(op, p_sei, NULL); op->state=SalOpStateTerminated; } else if (op->pending_client_trans){ if (belle_sip_transaction_get_state(BELLE_SIP_TRANSACTION(op->pending_client_trans)) == BELLE_SIP_TRANSACTION_PROCEEDING){ @@ -1127,8 +1137,7 @@ int sal_call_terminate_with_error(SalOp *op, const SalErrorInfo *info){ } case BELLE_SIP_DIALOG_EARLY: { if (op->dir == SalOpDirIncoming) { - //sal_error_info_set(&sei, SalReasonDeclined,"SIP", 0, NULL, NULL); - sal_call_decline(op, SalReasonDeclined,NULL); + sal_call_decline_with_error_info(op, p_sei,NULL); op->state=SalOpStateTerminated; } else { cancelling_invite(op); diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c index a9c9c8ca1..ce7851f82 100644 --- a/coreapi/bellesip_sal/sal_op_impl.c +++ b/coreapi/bellesip_sal/sal_op_impl.c @@ -605,7 +605,7 @@ void sal_error_info_reset(SalErrorInfo *ei){ 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 && strcmp(protocol, "SIP") == 0) ei->reason=_sal_reason_from_sip_code(code); + if (reason==SalReasonUnknown && strcmp(protocol, "SIP") == 0 && code != 0) ei->reason=_sal_reason_from_sip_code(code); else{ ei->reason=reason; if (code == 0) { diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 81618bab6..e6301fb36 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -285,9 +285,9 @@ static void call_received(SalOp *h){ case LinphonePresenceActivityPermanentAbsence: alt_contact = linphone_presence_model_get_contact(lc->presence_model); if (alt_contact != NULL) { + sal_error_info_init_to_null(&sei); sal_error_info_set(&sei,SalReasonRedirect, "SIP", 0, NULL, NULL); - sal_call_decline_with_error_info(h, SalReasonRedirect,alt_contact); - sal_call_decline(h,SalReasonRedirect,alt_contact); + sal_call_decline_with_error_info(h, &sei,alt_contact); ms_free(alt_contact); sal_op_release(h); return; @@ -300,8 +300,9 @@ static void call_received(SalOp *h){ } if (!linphone_core_can_we_add_call(lc)){/*busy*/ + sal_error_info_init_to_null(&sei); sal_error_info_set(&sei,SalReasonBusy, "SIP", 0, NULL, NULL); - sal_call_decline(h,SalReasonBusy,NULL); + sal_call_decline_with_error_info(h, &sei,NULL); sal_op_release(h); return; } @@ -337,8 +338,9 @@ static void call_received(SalOp *h){ if (from_address_to_search_if_me && already_a_call_with_remote_address(lc,from_address_to_search_if_me)){ char *addr = linphone_address_as_string(from_addr); ms_warning("Receiving a call while one with same address [%s] is initiated, refusing this one with busy message.",addr); + sal_error_info_init_to_null(&sei); sal_error_info_set(&sei,SalReasonBusy, "SIP", 0, NULL, NULL); - sal_call_decline(h,SalReasonBusy,NULL); + sal_call_decline_with_error_info(h, &sei,NULL); sal_op_release(h); linphone_address_unref(from_addr); linphone_address_unref(to_addr); @@ -356,8 +358,9 @@ static void call_received(SalOp *h){ md=sal_call_get_final_media_description(call->op); if (md){ if (sal_media_description_empty(md) || linphone_core_incompatible_security(lc,md)){ + sal_error_info_init_to_null(&sei); sal_error_info_set(&sei,SalReasonNotAcceptable, "SIP", 0, NULL, NULL); - sal_call_decline(call->op,SalReasonNotAcceptable,NULL); + sal_call_decline_with_error_info(call->op, &sei,NULL); linphone_call_unref(call); return; } @@ -722,8 +725,9 @@ static void call_updated(LinphoneCore *lc, LinphoneCall *call, SalOp *op, bool_t case LinphoneCallUpdating: case LinphoneCallPausing: case LinphoneCallResuming: + sal_error_info_init_to_null(&sei); sal_error_info_set(&sei,SalReasonInternalError, "SIP", 0, NULL, NULL); - sal_call_decline(call->op,SalReasonInternalError,NULL); + sal_call_decline_with_error_info(call->op, &sei,NULL); /*no break*/ case LinphoneCallIdle: case LinphoneCallOutgoingInit: @@ -776,16 +780,18 @@ static void call_updating(SalOp *op, bool_t is_update){ md=sal_call_get_final_media_description(call->op); if (md && (sal_media_description_empty(md) || linphone_core_incompatible_security(lc,md))){ + sal_error_info_init_to_null(&sei); sal_error_info_set(&sei,SalReasonNotAcceptable, "SIP", 0, NULL, NULL); - sal_call_decline(call->op,SalReasonNotAcceptable,NULL); + sal_call_decline_with_error_info(call->op, &sei,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_POLICY_CHANGED|SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED)){ ms_warning("Cannot accept this update, it is changing parameters that require user approval"); - sal_error_info_set(&sei,SalReasonNotAcceptable, "SIP", 0, NULL, NULL); - sal_call_decline(call->op,SalReasonNotAcceptable,NULL); /*FIXME should send 504 Cannot change the session parameters without prompting the user"*/ + sal_error_info_init_to_null(&sei); + sal_error_info_set(&sei,SalReasonUnknown, "SIP", 504, "Cannot change the session parameters without prompting the user", NULL); + sal_call_decline_with_error_info(call->op, &sei,NULL); return; } } diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 02b508247..6f717c30f 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -5123,7 +5123,8 @@ static void linphone_error_info_to_sal(const LinphoneErrorInfo* ei, SalErrorInfo int linphone_call_terminate_with_error_info(LinphoneCall *call , const LinphoneErrorInfo *ei){ SalErrorInfo sei ; sal_error_info_init_to_null(&sei); - + LinphoneErrorInfo* p_ei = (LinphoneErrorInfo*) ei; + ms_message("Terminate call [%p] which is currently in state %s", call, linphone_call_state_to_string(call->state)); switch (call->state) { case LinphoneCallReleased: @@ -5133,7 +5134,8 @@ int linphone_call_terminate_with_error_info(LinphoneCall *call , const LinphoneE return -1; case LinphoneCallIncomingReceived: case LinphoneCallIncomingEarlyMedia: - return linphone_call_decline(call, LinphoneReasonDeclined); + linphone_error_info_set_reason(p_ei, LinphoneReasonDeclined); + return linphone_call_decline_with_error(call, p_ei); case LinphoneCallOutgoingInit: /* In state OutgoingInit, op has to be destroyed */ sal_op_release(call->op); @@ -5177,8 +5179,9 @@ int linphone_call_redirect(LinphoneCall *call, const char *redirect_uri) { } real_url = linphone_address_as_string(real_parsed_url); + sal_error_info_init_to_null(&sei); sal_error_info_set(&sei,SalReasonRedirect, "SIP", 0, NULL, NULL); - sal_call_decline(call->op, SalReasonRedirect, real_url); + sal_call_decline_with_error_info(call->op, &sei, real_url); ms_free(real_url); linphone_error_info_set(call->ei, NULL, LinphoneReasonMovedPermanently, 302, "Call redirected", NULL); call->non_op_error = TRUE; @@ -5188,12 +5191,10 @@ int linphone_call_redirect(LinphoneCall *call, const char *redirect_uri) { } int linphone_call_decline(LinphoneCall * call, LinphoneReason reason) { - SalErrorInfo sei; if ((call->state != LinphoneCallIncomingReceived) && (call->state != LinphoneCallIncomingEarlyMedia)) { ms_error("Cannot decline a call that is in state %s", linphone_call_state_to_string(call->state)); return -1; } - sal_error_info_set(&sei, linphone_reason_to_sal(reason),"SIP", 0, NULL, NULL); sal_call_decline(call->op, linphone_reason_to_sal(reason), NULL); terminate_call(call); return 0; @@ -5216,10 +5217,6 @@ int linphone_call_decline_with_error(LinphoneCall * call, const LinphoneErrorInf return -1; } linphone_error_info_to_sal(ei, &sei); - //linphone_error_info_to_sal(ei->sub_ei, &sub_sei); - //sei.sub_sei = &sub_sei; - // check if sub reason exists - sal_call_decline_with_error_info(call->op, &sei , NULL); terminate_call(call); @@ -5849,8 +5846,9 @@ void linphone_call_repair_if_broken(LinphoneCall *call){ break; case LinphoneCallUpdatedByRemote: if (sal_call_dialog_request_pending(call->op)) { + sal_error_info_init_to_null(&sei); sal_error_info_set(&sei, SalReasonServiceUnavailable,"SIP", 0, NULL, NULL); - sal_call_decline(call->op, SalReasonServiceUnavailable, NULL); + sal_call_decline_with_error_info(call->op, &sei,NULL); } linphone_call_reinvite_to_recover_from_connection_loss(call); break; diff --git a/include/linphone/call.h b/include/linphone/call.h index 0afd289ca..fef709333 100644 --- a/include/linphone/call.h +++ b/include/linphone/call.h @@ -401,7 +401,13 @@ LINPHONE_PUBLIC int linphone_call_redirect(LinphoneCall *call, const char *redir * @return 0 on success, -1 on failure **/ LINPHONE_PUBLIC int linphone_call_decline(LinphoneCall * call, LinphoneReason reason); - + +/** + * Decline a pending incoming call, with a LinphoneErrorInfo object. + * @param[in] call A LinphoneCall object that must be in the IncomingReceived state + * @param[in] ei LinphoneErrorInfo containing more information on the call rejection. + * @return 0 on success, -1 on failure + */ LINPHONE_PUBLIC int linphone_call_decline_with_error(LinphoneCall * call, const LinphoneErrorInfo *ei); /** diff --git a/include/linphone/error_info.h b/include/linphone/error_info.h index 61ea9b6e6..11d5af65c 100644 --- a/include/linphone/error_info.h +++ b/include/linphone/error_info.h @@ -104,6 +104,11 @@ LINPHONE_PUBLIC int linphone_error_info_get_protocol_code(const LinphoneErrorInf */ LINPHONE_PUBLIC void linphone_error_info_set(LinphoneErrorInfo *ei, const char *protocol, LinphoneReason reason, int code, const char *status_string, const char *warning); +/** + * [linphone_error_info_set_sub_error_info description] + * @param[in] ei LinphoneErrorInfo object to which the other LinphoneErrorInfo will be appended as ei->sub_ei. + * @param[in] appended_ei LinphoneErrorInfo to append + */ LINPHONE_PUBLIC void linphone_error_info_set_sub_error_info(LinphoneErrorInfo *ei, LinphoneErrorInfo *appended_ei); /** From c78fa631f1d1df160b8c489dc26d2ed3855c0b57 Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Tue, 4 Apr 2017 11:21:40 +0200 Subject: [PATCH 09/70] Update media streamer and ortp --- mediastreamer2 | 2 +- oRTP | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/mediastreamer2 b/mediastreamer2 index b937df188..954652074 160000 --- a/mediastreamer2 +++ b/mediastreamer2 @@ -1 +1 @@ -Subproject commit b937df188829f73c3f5db35ff0191aa695f27884 +Subproject commit 954652074fd168323c0846d6d8cd6c5b4d859d75 diff --git a/oRTP b/oRTP index 235e5175b..67c0672e2 160000 --- a/oRTP +++ b/oRTP @@ -1 +1 @@ -Subproject commit 235e5175b2befa2d3e5f19cd969b0f3bda5b9b4c +Subproject commit 67c0672e2680baa85a74d8966b813fac259649df From 9e9ec48cedb6a2be2afc48edca7868bd4a2a4c1f Mon Sep 17 00:00:00 2001 From: Sandrine Avakian Date: Tue, 4 Apr 2017 14:54:47 +0200 Subject: [PATCH 10/70] removing ortp --- oRTP | 1 - 1 file changed, 1 deletion(-) delete mode 160000 oRTP diff --git a/oRTP b/oRTP deleted file mode 160000 index 67c0672e2..000000000 --- a/oRTP +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 67c0672e2680baa85a74d8966b813fac259649df From a5ffae6b0301355bdc4e8ffd1d558fe27868ed7d Mon Sep 17 00:00:00 2001 From: Sandrine Avakian Date: Wed, 5 Apr 2017 16:19:26 +0200 Subject: [PATCH 11/70] Fixing errors in linphone_error_info_set parameter usage induced by merge from master. --- coreapi/bellesip_sal/sal_op_call.c | 1 + coreapi/callbacks.c | 8 ++++---- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index 88d339204..90b078405 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -510,6 +510,7 @@ static int is_media_description_acceptable(SalMediaDescription *md){ static SalReason process_sdp_for_invite(SalOp* op,belle_sip_request_t* invite) { belle_sdp_session_description_t* sdp; SalReason reason = SalReasonNone; + SalErrorInfo sei; if (extract_sdp(op,BELLE_SIP_MESSAGE(invite),&sdp,&reason)==0) { if (sdp){ diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 6737638a4..6fa511fa5 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -312,7 +312,7 @@ static void call_received(SalOp *h){ sal_call_decline_with_error_info(h, &sei,alt_contact); ms_free(alt_contact); ei = linphone_error_info_new(); - linphone_error_info_set(ei, LinphoneReasonMovedPermanently, 302, "Moved permanently", NULL); + linphone_error_info_set(ei, NULL, LinphoneReasonMovedPermanently, 302, "Moved permanently", NULL); linphone_core_report_early_failed_call(lc, LinphoneCallIncoming, from_addr, to_addr, ei); sal_op_release(h); return; @@ -327,7 +327,7 @@ static void call_received(SalOp *h){ if (!linphone_core_can_we_add_call(lc)){/*busy*/ sal_call_decline(h,SalReasonBusy,NULL); ei = linphone_error_info_new(); - linphone_error_info_set(ei, LinphoneReasonBusy, 486, "Busy - too many calls", NULL); + linphone_error_info_set(ei, NULL, LinphoneReasonBusy, 486, "Busy - too many calls", NULL); linphone_core_report_early_failed_call(lc, LinphoneCallIncoming, from_addr, to_addr, ei); sal_op_release(h); return; @@ -347,7 +347,7 @@ static void call_received(SalOp *h){ ms_warning("Receiving a call while one with same address [%s] is initiated, refusing this one with busy message.",addr); sal_call_decline(h,SalReasonBusy,NULL); ei = linphone_error_info_new(); - linphone_error_info_set(ei, LinphoneReasonBusy, 486, "Busy - duplicated call", NULL); + linphone_error_info_set(ei, NULL, LinphoneReasonBusy, 486, "Busy - duplicated call", NULL); linphone_core_report_early_failed_call(lc, LinphoneCallIncoming, from_addr, to_addr, ei); sal_op_release(h); linphone_address_unref(from_addr); @@ -367,7 +367,7 @@ static void call_received(SalOp *h){ if (md){ if (sal_media_description_empty(md) || linphone_core_incompatible_security(lc,md)){ ei = linphone_error_info_new(); - linphone_error_info_set(ei, LinphoneReasonNotAcceptable, 488, "Not acceptable here", NULL); + linphone_error_info_set(ei, NULL, LinphoneReasonNotAcceptable, 488, "Not acceptable here", NULL); linphone_core_report_early_failed_call(lc, LinphoneCallIncoming, linphone_address_ref(from_addr), linphone_address_ref(to_addr), ei); sal_call_decline(call->op,SalReasonNotAcceptable,NULL); linphone_call_unref(call); From 5f084675bd5eb72c9c891746f2d7b58f5b4f9969 Mon Sep 17 00:00:00 2001 From: Sandrine Avakian Date: Thu, 6 Apr 2017 11:27:54 +0200 Subject: [PATCH 12/70] remove unused variable in tests. Moving function for api to error_info.h --- coreapi/error_info.c | 5 +++++ include/linphone/error_info.h | 7 +++++++ tester/call_single_tester.c | 1 - 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/coreapi/error_info.c b/coreapi/error_info.c index b889bbf46..4c9008b60 100644 --- a/coreapi/error_info.c +++ b/coreapi/error_info.c @@ -215,6 +215,11 @@ void linphone_error_info_from_sal_op(LinphoneErrorInfo *ei, const SalOp *op){ } } +LinphoneErrorInfo* linphone_error_info_get_sub(const LinphoneErrorInfo *ei){ + + return ei->sub_ei; +} + void linphone_error_info_set_sub_error_info(LinphoneErrorInfo *ei, LinphoneErrorInfo *appended_ei){ if (appended_ei != NULL){ ei->sub_ei = appended_ei; diff --git a/include/linphone/error_info.h b/include/linphone/error_info.h index 11d5af65c..8336c7ae8 100644 --- a/include/linphone/error_info.h +++ b/include/linphone/error_info.h @@ -62,6 +62,13 @@ LINPHONE_PUBLIC void linphone_error_info_unref(LinphoneErrorInfo *ei); **/ LINPHONE_PUBLIC LinphoneReason linphone_error_info_get_reason(const LinphoneErrorInfo *ei); +/** + * Get pointer to chained LinphoneErrorInfo set in sub_ei. + * @param ei ErrorInfo object + * @return LinphoneErrorInfo pointer defined in the ei object. + */ +LINPHONE_PUBLIC LinphoneErrorInfo* linphone_error_info_get_sub(const LinphoneErrorInfo *ei); + /** * Get textual phrase from the error info. * This is the text that is provided by the peer in the protocol (SIP). diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index 0fa27e694..df66f7849 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -1790,7 +1790,6 @@ static void call_callee_with_custom_header_or_sdp_attributes(void) { stats initial_caller=caller_mgr->stat; stats initial_callee=callee_mgr->stat; - bool_t result=FALSE; bool_t did_receive_call; const LinphoneCallParams *caller_remote_params; From f3bd0a7272dc06487db4a544054dd8820951b368 Mon Sep 17 00:00:00 2001 From: Sandrine Avakian Date: Thu, 6 Apr 2017 11:38:30 +0200 Subject: [PATCH 13/70] Forgotten file from previous commit. --- coreapi/linphonecall.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index ea729df4e..86726209b 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -5257,10 +5257,6 @@ int linphone_call_decline(LinphoneCall * call, LinphoneReason reason) { return 0; } -static const LinphoneErrorInfo* linphone_error_info_get_sub(const LinphoneErrorInfo *ei){ - - return ei->sub_ei; -} int linphone_call_decline_with_error(LinphoneCall * call, const LinphoneErrorInfo *ei) { SalErrorInfo sei; From 95387d37856885d1a143f24be356fe7ff9b28cbf Mon Sep 17 00:00:00 2001 From: Sandrine Avakian Date: Fri, 7 Apr 2017 14:43:24 +0200 Subject: [PATCH 14/70] Fixes with reason header call decline. --- coreapi/bellesip_sal/sal_op_impl.c | 1 + coreapi/error_info.c | 2 +- tester/call_single_tester.c | 31 ++++++++++++++++++++++-------- 3 files changed, 25 insertions(+), 9 deletions(-) diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c index ce7851f82..f859b221e 100644 --- a/coreapi/bellesip_sal/sal_op_impl.c +++ b/coreapi/bellesip_sal/sal_op_impl.c @@ -643,6 +643,7 @@ void sal_op_set_error_info_from_response(SalOp *op, belle_sip_response_t *respon warnings=warning ? belle_sip_header_get_unparsed_value(warning) : NULL; sal_error_info_set(ei,SalReasonUnknown,"SIP", code,reason_phrase,warnings); + sal_op_set_reason_error_info(op, BELLE_SIP_MESSAGE(response)); } const SalErrorInfo *sal_op_get_error_info(const SalOp *op){ diff --git a/coreapi/error_info.c b/coreapi/error_info.c index 4c9008b60..4883a0d5f 100644 --- a/coreapi/error_info.c +++ b/coreapi/error_info.c @@ -222,7 +222,7 @@ LinphoneErrorInfo* linphone_error_info_get_sub(const LinphoneErrorInfo *ei){ void linphone_error_info_set_sub_error_info(LinphoneErrorInfo *ei, LinphoneErrorInfo *appended_ei){ if (appended_ei != NULL){ - ei->sub_ei = appended_ei; + ei->sub_ei = linphone_error_info_ref(appended_ei); } } diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index df66f7849..5acadc44d 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -1193,18 +1193,23 @@ static void call_declined_with_error(void) { LinphoneCoreManager* callee_mgr = linphone_core_manager_new("marie_rc"); LinphoneCoreManager* caller_mgr = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); - LinphoneCall* in_call; + LinphoneCall* in_call = NULL; LinphoneCall* out_call = linphone_core_invite_address(caller_mgr->lc,callee_mgr->identity); LinphoneFactory* factory = linphone_factory_get(); + const LinphoneErrorInfo* rcvd_ei; + const LinphoneErrorInfo* sub_rcvd_ei; LinphoneErrorInfo *ei = linphone_factory_create_error_info(factory); LinphoneErrorInfo *reason_ei = linphone_factory_create_error_info(factory); - + linphone_error_info_set(ei, "SIP", LinphoneReasonUnknown, 603, "Decline", NULL); //ordre des arguments à vérifier linphone_error_info_set(reason_ei, "hardware", LinphoneReasonUnknown, 66, "J'ai plus de batterie", NULL); linphone_error_info_set_sub_error_info(ei, reason_ei); + BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallIncomingReceived,1)); + BC_ASSERT_PTR_NOT_NULL(in_call=linphone_core_get_current_call(callee_mgr->lc)); + linphone_call_ref(out_call); BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallIncomingReceived,1)); BC_ASSERT_PTR_NOT_NULL(in_call=linphone_core_get_current_call(callee_mgr->lc)); @@ -1212,20 +1217,29 @@ static void call_declined_with_error(void) { linphone_call_ref(in_call); linphone_call_decline_with_error(in_call, ei); // linphone_call_terminate(in_call); - BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallReleased,1)); - BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallReleased,1)); - BC_ASSERT_EQUAL(callee_mgr->stat.number_of_LinphoneCallEnd,1, int, "%d"); - BC_ASSERT_EQUAL(caller_mgr->stat.number_of_LinphoneCallEnd,1, int, "%d"); + + BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallEnd,1)); + BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallEnd,1)); + + rcvd_ei = linphone_call_get_error_info(out_call); + sub_rcvd_ei = linphone_error_info_get_sub(rcvd_ei); + BC_ASSERT_STRING_EQUAL(linphone_error_info_get_phrase(rcvd_ei), "Decline"); + BC_ASSERT_STRING_EQUAL(linphone_error_info_get_protocol(rcvd_ei), "SIP"); + BC_ASSERT_STRING_EQUAL(linphone_error_info_get_phrase(sub_rcvd_ei), "J'ai plus de batterie"); + BC_ASSERT_STRING_EQUAL(linphone_error_info_get_protocol(sub_rcvd_ei), "hardware"); + BC_ASSERT_EQUAL(linphone_call_get_reason(in_call),LinphoneReasonDeclined, int, "%d"); BC_ASSERT_EQUAL(linphone_call_log_get_status(linphone_call_get_call_log(in_call)),LinphoneCallDeclined, int, "%d"); BC_ASSERT_EQUAL(linphone_call_get_reason(out_call),LinphoneReasonDeclined, int, "%d"); BC_ASSERT_EQUAL(linphone_call_log_get_status(linphone_call_get_call_log(out_call)),LinphoneCallDeclined, int, "%d"); - + + BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallReleased,1)); + BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallReleased,1)); linphone_call_unref(in_call); } linphone_call_unref(out_call); - //linphone_error_info_unref(reason_ei); + linphone_error_info_unref(reason_ei); linphone_error_info_unref(ei); linphone_core_manager_destroy(callee_mgr); @@ -1778,6 +1792,7 @@ static void call_callee_with_custom_header_or_sdp_cb(LinphoneCore *lc, LinphoneC static void call_callee_with_custom_header_or_sdp_attributes(void) { + int result; LinphoneCoreManager *callee_mgr = linphone_core_manager_new("marie_rc"); LinphoneCoreManager *caller_mgr = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); LinphoneCall *call_caller = NULL, *call_callee = NULL; From 64a18a5b23597c9610703185c71773f7b0ea97d9 Mon Sep 17 00:00:00 2001 From: Sandrine Avakian Date: Tue, 11 Apr 2017 13:28:47 +0200 Subject: [PATCH 15/70] Documenting functions --- include/linphone/call.h | 8 ++++++-- include/linphone/error_info.h | 3 ++- tester/call_single_tester.c | 2 +- 3 files changed, 9 insertions(+), 4 deletions(-) diff --git a/include/linphone/call.h b/include/linphone/call.h index 6614fb16d..9cbe17ad1 100644 --- a/include/linphone/call.h +++ b/include/linphone/call.h @@ -203,9 +203,12 @@ LINPHONE_PUBLIC int linphone_call_take_preview_snapshot(LinphoneCall *call, cons **/ LINPHONE_PUBLIC LinphoneReason linphone_call_get_reason(const LinphoneCall *call); + /** * Returns full details about call errors or termination reasons. -**/ + * @param call LinphoneCall object on which we want the information error + * @return LinphoneErrorInfo object holding the reason error. + */ LINPHONE_PUBLIC const LinphoneErrorInfo *linphone_call_get_error_info(const LinphoneCall *call); /** @@ -381,7 +384,8 @@ LINPHONE_PUBLIC int linphone_call_resume(LinphoneCall *call); /** * Terminates a call. - * @param[in] call LinphoneCall object + * @param[in] call LinphoneCall object + * @param[in] ei LinphoneErrorInfo * @return 0 on success, -1 on failure **/ LINPHONE_PUBLIC int linphone_call_terminate_with_error_info(LinphoneCall *call, const LinphoneErrorInfo *ei); diff --git a/include/linphone/error_info.h b/include/linphone/error_info.h index 8336c7ae8..025a18e66 100644 --- a/include/linphone/error_info.h +++ b/include/linphone/error_info.h @@ -112,7 +112,8 @@ LINPHONE_PUBLIC int linphone_error_info_get_protocol_code(const LinphoneErrorInf LINPHONE_PUBLIC void linphone_error_info_set(LinphoneErrorInfo *ei, const char *protocol, LinphoneReason reason, int code, const char *status_string, const char *warning); /** - * [linphone_error_info_set_sub_error_info description] + * Set the sub_ei in LinphoneErrorInfo to another LinphoneErrorInfo. + * Used when there is more than one reason header. * @param[in] ei LinphoneErrorInfo object to which the other LinphoneErrorInfo will be appended as ei->sub_ei. * @param[in] appended_ei LinphoneErrorInfo to append */ diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index 5acadc44d..a63347a4a 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -1216,13 +1216,13 @@ static void call_declined_with_error(void) { if (in_call) { linphone_call_ref(in_call); linphone_call_decline_with_error(in_call, ei); - // linphone_call_terminate(in_call); BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallEnd,1)); BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallEnd,1)); rcvd_ei = linphone_call_get_error_info(out_call); sub_rcvd_ei = linphone_error_info_get_sub(rcvd_ei); + BC_ASSERT_STRING_EQUAL(linphone_error_info_get_phrase(rcvd_ei), "Decline"); BC_ASSERT_STRING_EQUAL(linphone_error_info_get_protocol(rcvd_ei), "SIP"); BC_ASSERT_STRING_EQUAL(linphone_error_info_get_phrase(sub_rcvd_ei), "J'ai plus de batterie"); From 34c276541ea4cc5a14a66164460d4fe200ab7b61 Mon Sep 17 00:00:00 2001 From: Sandrine Avakian Date: Wed, 12 Apr 2017 10:35:32 +0200 Subject: [PATCH 16/70] Renaming linphone_call_decline_with_error into linphone_call_decline_with_error_info --- coreapi/linphonecall.c | 4 ++-- include/linphone/call.h | 2 +- tester/call_single_tester.c | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 66927da34..4760aee76 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -5192,7 +5192,7 @@ int linphone_call_terminate_with_error_info(LinphoneCall *call , const LinphoneE case LinphoneCallIncomingReceived: case LinphoneCallIncomingEarlyMedia: linphone_error_info_set_reason(p_ei, LinphoneReasonDeclined); - return linphone_call_decline_with_error(call, p_ei); + return linphone_call_decline_with_error_info(call, p_ei); case LinphoneCallOutgoingInit: /* In state OutgoingInit, op has to be destroyed */ sal_op_release(call->op); @@ -5258,7 +5258,7 @@ int linphone_call_decline(LinphoneCall * call, LinphoneReason reason) { } -int linphone_call_decline_with_error(LinphoneCall * call, const LinphoneErrorInfo *ei) { +int linphone_call_decline_with_error_info(LinphoneCall * call, const LinphoneErrorInfo *ei) { SalErrorInfo sei; sal_error_info_init_to_null(&sei); SalErrorInfo sub_sei; diff --git a/include/linphone/call.h b/include/linphone/call.h index 9cbe17ad1..56bd6480a 100644 --- a/include/linphone/call.h +++ b/include/linphone/call.h @@ -412,7 +412,7 @@ LINPHONE_PUBLIC int linphone_call_decline(LinphoneCall * call, LinphoneReason re * @param[in] ei LinphoneErrorInfo containing more information on the call rejection. * @return 0 on success, -1 on failure */ -LINPHONE_PUBLIC int linphone_call_decline_with_error(LinphoneCall * call, const LinphoneErrorInfo *ei); +LINPHONE_PUBLIC int linphone_call_decline_with_error_info(LinphoneCall * call, const LinphoneErrorInfo *ei); /** * Accept an incoming call. diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index d456ad5d4..c2cb29b7e 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -1215,7 +1215,7 @@ static void call_declined_with_error(void) { BC_ASSERT_PTR_NOT_NULL(in_call=linphone_core_get_current_call(callee_mgr->lc)); if (in_call) { linphone_call_ref(in_call); - linphone_call_decline_with_error(in_call, ei); + linphone_call_decline_with_error_info(in_call, ei); BC_ASSERT_TRUE(wait_for(caller_mgr->lc,callee_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallEnd,1)); BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallEnd,1)); From 7532be6692bcd59124c269999516469d7fc3d546 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Fri, 14 Apr 2017 14:53:47 +0200 Subject: [PATCH 17/70] Fix call log removal when using the database storage. --- coreapi/linphonecore.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 4f7149ed6..e942641af 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -4595,8 +4595,8 @@ void linphone_core_remove_call_log(LinphoneCore *lc, LinphoneCallLog *cl) { linphone_core_delete_call_log(lc, cl); } #endif + lc->call_logs = bctbx_list_remove(lc->call_logs, cl); if (!call_logs_sqlite_db_found) { - lc->call_logs = bctbx_list_remove(lc->call_logs, cl); call_logs_write_to_config_file(lc); linphone_call_log_unref(cl); } From 7f57f6828c9f562cb64d4c3dc482af4b5132f502 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Fri, 14 Apr 2017 15:28:58 +0200 Subject: [PATCH 18/70] merge branch with reason header support and new ErrorInfo features. Add JNI and java interfaces. Fix issues. --- coreapi/bellesip_sal/sal_op_call.c | 5 +- coreapi/bellesip_sal/sal_op_impl.c | 11 +-- coreapi/callbacks.c | 14 +-- coreapi/error_info.c | 66 +++++++++---- coreapi/linphonecall.c | 37 ++----- coreapi/linphonecore_jni.cc | 96 +++++++++++++++++++ coreapi/private.h | 1 + include/linphone/error_info.h | 38 +++++++- java/common/org/linphone/core/ErrorInfo.java | 41 ++++++++ .../org/linphone/core/LinphoneCall.java | 15 ++- .../linphone/core/LinphoneCoreFactory.java | 5 + .../impl/org/linphone/core/ErrorInfoImpl.java | 89 ++++++++++++++--- .../org/linphone/core/LinphoneCallImpl.java | 65 ++++++++++--- .../core/LinphoneCoreFactoryImpl.java | 6 ++ tester/call_single_tester.c | 6 +- 15 files changed, 391 insertions(+), 104 deletions(-) diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index 8a53abdab..363ac54b6 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -526,7 +526,7 @@ static SalReason process_sdp_for_invite(SalOp* op,belle_sip_request_t* invite) { } if (reason != SalReasonNone){ - sal_error_info_init_to_null(&sei); + sal_error_info_reset(&sei); sal_error_info_set(&sei, reason,"SIP", 0, NULL, NULL); sal_call_decline_with_error_info(op, &sei,NULL); @@ -1092,10 +1092,9 @@ int sal_call_send_dtmf(SalOp *h, char dtmf){ int sal_call_terminate_with_error(SalOp *op, const SalErrorInfo *info){ - SalErrorInfo sei; + SalErrorInfo sei = { 0 }; const SalErrorInfo *p_sei; if (info == NULL){ - sal_error_info_init_to_null(&sei); sal_error_info_set(&sei,SalReasonDeclined, "SIP", 0, NULL, NULL); p_sei = &sei; } else{ diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c index f859b221e..3db9a73e8 100644 --- a/coreapi/bellesip_sal/sal_op_impl.c +++ b/coreapi/bellesip_sal/sal_op_impl.c @@ -567,16 +567,6 @@ const SalErrorInfo *sal_error_info_none(void){ return &none; } -void sal_error_info_init_to_null(SalErrorInfo *sei){ - sei->status_string = NULL; - sei->full_string = NULL; - sei->protocol = NULL; - sei->sub_sei = NULL; - sei->warnings = NULL; - sei->protocol_code=0; - sei->reason=SalReasonNone; -} - void sal_error_info_reset(SalErrorInfo *ei){ if (ei->status_string){ ms_free(ei->status_string); @@ -601,6 +591,7 @@ void sal_error_info_reset(SalErrorInfo *ei){ } ei->protocol_code=0; ei->reason=SalReasonNone; + ei->sub_sei = NULL; } void sal_error_info_set(SalErrorInfo *ei, SalReason reason, const char *protocol, int code, const char *status_string, const char *warning){ diff --git a/coreapi/callbacks.c b/coreapi/callbacks.c index 26bcad581..ef1d4822d 100644 --- a/coreapi/callbacks.c +++ b/coreapi/callbacks.c @@ -269,7 +269,6 @@ static void call_received(SalOp *h){ LinphoneAddress *from_address_to_search_if_me=NULL; /*address used to know if I'm the caller*/ SalMediaDescription *md; const char * p_asserted_id; - SalErrorInfo sei; LinphoneErrorInfo *ei = NULL; /* Look if this INVITE is for a call that has already been notified but broken because of network failure */ @@ -307,7 +306,7 @@ static void call_received(SalOp *h){ case LinphonePresenceActivityPermanentAbsence: alt_contact = linphone_presence_model_get_contact(lc->presence_model); if (alt_contact != NULL) { - sal_error_info_init_to_null(&sei); + SalErrorInfo sei = { 0 }; sal_error_info_set(&sei,SalReasonRedirect, "SIP", 0, NULL, NULL); sal_call_decline_with_error_info(h, &sei,alt_contact); ms_free(alt_contact); @@ -315,6 +314,7 @@ static void call_received(SalOp *h){ linphone_error_info_set(ei, NULL, LinphoneReasonMovedPermanently, 302, "Moved permanently", NULL); linphone_core_report_early_failed_call(lc, LinphoneCallIncoming, from_addr, to_addr, ei); sal_op_release(h); + sal_error_info_reset(&sei); return; } break; @@ -701,7 +701,7 @@ static void call_updated_by_remote(LinphoneCore *lc, LinphoneCall *call){ /* this callback is called when an incoming re-INVITE/ SIP UPDATE modifies the session*/ static void call_updated(LinphoneCore *lc, LinphoneCall *call, SalOp *op, bool_t is_update){ - SalErrorInfo sei; + SalErrorInfo sei = { 0 }; SalMediaDescription *rmd=sal_call_get_remote_media_description(op); call->defer_update = lp_config_get_int(lc->config, "sip", "defer_update_default", FALSE); @@ -739,7 +739,6 @@ static void call_updated(LinphoneCore *lc, LinphoneCall *call, SalOp *op, bool_t case LinphoneCallUpdating: case LinphoneCallPausing: case LinphoneCallResuming: - sal_error_info_init_to_null(&sei); sal_error_info_set(&sei,SalReasonInternalError, "SIP", 0, NULL, NULL); sal_call_decline_with_error_info(call->op, &sei,NULL); /*no break*/ @@ -756,6 +755,7 @@ static void call_updated(LinphoneCore *lc, LinphoneCall *call, SalOp *op, bool_t ms_warning("Receiving reINVITE or UPDATE while in state [%s], should not happen.",linphone_call_state_to_string(call->state)); break; } + sal_error_info_reset(&sei); } /* this callback is called when an incoming re-INVITE/ SIP UPDATE modifies the session*/ @@ -763,7 +763,7 @@ 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); - SalErrorInfo sei; + SalErrorInfo sei = {0}; if (!call) { ms_error("call_updating(): call doesn't exist anymore"); @@ -794,18 +794,18 @@ static void call_updating(SalOp *op, bool_t is_update){ md=sal_call_get_final_media_description(call->op); if (md && (sal_media_description_empty(md) || linphone_core_incompatible_security(lc,md))){ - sal_error_info_init_to_null(&sei); sal_error_info_set(&sei,SalReasonNotAcceptable, "SIP", 0, NULL, NULL); sal_call_decline_with_error_info(call->op, &sei,NULL); + sal_error_info_reset(&sei); return; } if (is_update && prev_result_desc && md){ int diff=sal_media_description_equals(prev_result_desc,md); if (diff & (SAL_MEDIA_DESCRIPTION_CRYPTO_POLICY_CHANGED|SAL_MEDIA_DESCRIPTION_STREAMS_CHANGED)){ ms_warning("Cannot accept this update, it is changing parameters that require user approval"); - sal_error_info_init_to_null(&sei); sal_error_info_set(&sei,SalReasonUnknown, "SIP", 504, "Cannot change the session parameters without prompting the user", NULL); sal_call_decline_with_error_info(call->op, &sei,NULL); + sal_error_info_reset(&sei); return; } } diff --git a/coreapi/error_info.c b/coreapi/error_info.c index 4883a0d5f..ffe29fed7 100644 --- a/coreapi/error_info.c +++ b/coreapi/error_info.c @@ -59,9 +59,6 @@ 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) { @@ -215,29 +212,30 @@ void linphone_error_info_from_sal_op(LinphoneErrorInfo *ei, const SalOp *op){ } } -LinphoneErrorInfo* linphone_error_info_get_sub(const LinphoneErrorInfo *ei){ - - return ei->sub_ei; +void linphone_error_info_fields_to_sal(const LinphoneErrorInfo* ei, SalErrorInfo* sei){ + sei->reason = linphone_reason_to_sal(linphone_error_info_get_reason(ei)); + sei->status_string = bctbx_strdup(ei->phrase); + sei->full_string = bctbx_strdup(ei->full_string); + sei->warnings = bctbx_strdup(ei->warnings); + sei->protocol_code = ei->protocol_code; + sei->protocol = bctbx_strdup(ei->protocol); } - -void linphone_error_info_set_sub_error_info(LinphoneErrorInfo *ei, LinphoneErrorInfo *appended_ei){ - if (appended_ei != NULL){ - ei->sub_ei = linphone_error_info_ref(appended_ei); + +void linphone_error_info_to_sal(const LinphoneErrorInfo* ei, SalErrorInfo* sei){ + + linphone_error_info_fields_to_sal(ei, sei); + if (ei->sub_ei !=NULL) { + + linphone_error_info_to_sal(ei->sub_ei, sei->sub_sei); } } + void linphone_error_info_set(LinphoneErrorInfo *ei, const char *protocol, LinphoneReason reason, int code, const char *status_string, const char *warning){ linphone_error_info_reset(ei); ei->reason = reason; ei->protocol_code = code; - if (protocol != NULL){ - ei->protocol = bctbx_strdup(protocol); - } - else{ - const char* prot = "SIP"; - ei->protocol = bctbx_strdup(prot); - } - + ei->protocol = bctbx_strdup(protocol ? protocol : "SIP"); ei->phrase = bctbx_strdup(status_string); ei->warnings = bctbx_strdup(warning); } @@ -268,6 +266,36 @@ int linphone_error_info_get_protocol_code(const LinphoneErrorInfo *ei) { return ei->protocol_code; } -const LinphoneErrorInfo * linphone_error_info_get_sub_error_info(const LinphoneErrorInfo *ei){ +LinphoneErrorInfo * linphone_error_info_get_sub_error_info(const LinphoneErrorInfo *ei){ return ei->sub_ei; } + +void linphone_error_info_set_reason(LinphoneErrorInfo *ei, LinphoneReason reason){ + ei->reason = reason; +} + +void linphone_error_info_set_protocol(LinphoneErrorInfo *ei, const char *proto){ + STRING_SET(ei->protocol, proto); +} + +void linphone_error_info_set_protocol_code(LinphoneErrorInfo *ei, int code){ + ei->protocol_code = code; +} + +void linphone_error_info_set_phrase(LinphoneErrorInfo *ei, const char *phrase){ + STRING_SET(ei->phrase, phrase); +} + +void linphone_error_info_set_warnings(LinphoneErrorInfo *ei, const char *warnings){ + STRING_SET(ei->warnings, warnings); +} + +void linphone_error_info_set_sub_error_info(LinphoneErrorInfo *ei, LinphoneErrorInfo *appended_ei){ + if (appended_ei != NULL){ + linphone_error_info_ref(appended_ei); + } + if (ei->sub_ei){ + linphone_error_info_unref(ei->sub_ei); + } + ei->sub_ei = appended_ei; +} diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 4760aee76..683e8286f 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -5157,29 +5157,9 @@ int linphone_call_terminate(LinphoneCall *call) { return 0; } -static void linphone_error_info_fields_to_sal(const LinphoneErrorInfo* ei, SalErrorInfo* sei){ - - sei->reason = linphone_error_info_get_reason(ei); - sei->status_string = bctbx_strdup(ei->phrase); - sei->full_string = bctbx_strdup(ei->full_string); - sei->warnings = bctbx_strdup(ei->warnings); - sei->protocol_code = ei->protocol_code; - sei->protocol = bctbx_strdup(ei->protocol); - -} - -static void linphone_error_info_to_sal(const LinphoneErrorInfo* ei, SalErrorInfo* sei){ - - linphone_error_info_fields_to_sal(ei, sei); - if (ei->sub_ei !=NULL) { - - linphone_error_info_to_sal(ei->sub_ei, sei->sub_sei); - } -} int linphone_call_terminate_with_error_info(LinphoneCall *call , const LinphoneErrorInfo *ei){ - SalErrorInfo sei ; - sal_error_info_init_to_null(&sei); + SalErrorInfo sei={0}; LinphoneErrorInfo* p_ei = (LinphoneErrorInfo*) ei; ms_message("Terminate call [%p] which is currently in state %s", call, linphone_call_state_to_string(call->state)); @@ -5220,7 +5200,7 @@ int linphone_call_redirect(LinphoneCall *call, const char *redirect_uri) { char *real_url = NULL; LinphoneCore *lc; LinphoneAddress *real_parsed_url; - SalErrorInfo sei; + SalErrorInfo sei = {0}; if (call->state != LinphoneCallIncomingReceived) { ms_error("Bad state for call redirection."); @@ -5236,7 +5216,6 @@ int linphone_call_redirect(LinphoneCall *call, const char *redirect_uri) { } real_url = linphone_address_as_string(real_parsed_url); - sal_error_info_init_to_null(&sei); sal_error_info_set(&sei,SalReasonRedirect, "SIP", 0, NULL, NULL); sal_call_decline_with_error_info(call->op, &sei, real_url); ms_free(real_url); @@ -5244,6 +5223,7 @@ int linphone_call_redirect(LinphoneCall *call, const char *redirect_uri) { call->non_op_error = TRUE; terminate_call(call); linphone_address_unref(real_parsed_url); + sal_error_info_reset(&sei); return 0; } @@ -5259,10 +5239,9 @@ int linphone_call_decline(LinphoneCall * call, LinphoneReason reason) { int linphone_call_decline_with_error_info(LinphoneCall * call, const LinphoneErrorInfo *ei) { - SalErrorInfo sei; - sal_error_info_init_to_null(&sei); - SalErrorInfo sub_sei; - sal_error_info_init_to_null(&sub_sei); + SalErrorInfo sei = {0}; + SalErrorInfo sub_sei = {0}; + sei.sub_sei = &sub_sei; if ((call->state != LinphoneCallIncomingReceived) && (call->state != LinphoneCallIncomingEarlyMedia)) { @@ -5869,7 +5848,7 @@ void linphone_call_reinvite_to_recover_from_connection_loss(LinphoneCall *call) } void linphone_call_repair_if_broken(LinphoneCall *call){ - SalErrorInfo sei; + SalErrorInfo sei = {0}; if (!call->broken) return; if (!call->core->media_network_reachable) return; @@ -5899,7 +5878,6 @@ void linphone_call_repair_if_broken(LinphoneCall *call){ break; case LinphoneCallUpdatedByRemote: if (sal_call_dialog_request_pending(call->op)) { - sal_error_info_init_to_null(&sei); sal_error_info_set(&sei, SalReasonServiceUnavailable,"SIP", 0, NULL, NULL); sal_call_decline_with_error_info(call->op, &sei,NULL); } @@ -5923,6 +5901,7 @@ void linphone_call_repair_if_broken(LinphoneCall *call){ call->broken = FALSE; break; } + sal_error_info_reset(&sei); } void linphone_call_refresh_sockets(LinphoneCall *call){ diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 99141e869..672e5690a 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -216,6 +216,10 @@ extern "C" void Java_org_linphone_core_LinphoneCoreFactoryImpl_setLogCollectionP ReleaseStringUTFChars(env, jpath, path); } +extern "C" jlong Java_org_linphone_core_LinphoneCoreFactoryImpl_createErrorInfoNative(JNIEnv* env, jobject thiz){ + return (jlong)linphone_factory_create_error_info(linphone_factory_get()); +} + extern "C" jobjectArray Java_org_linphone_core_LinphoneCoreFactoryImpl_getAllDialPlanNative(JNIEnv *env, jobject thiz) { LinphoneDialPlan *countries; jclass addr_class = env->FindClass("org/linphone/core/DialPlanImpl"); @@ -3691,6 +3695,18 @@ extern "C" jboolean Java_org_linphone_core_LinphoneCallImpl_mediaInProgress( JNI return (jboolean) linphone_call_media_in_progress((LinphoneCall*)ptr); } +extern "C" void Java_org_linphone_core_LinphoneCallImpl_declineWithErrorInfo( JNIEnv* env + ,jobject thiz + ,jlong callptr, jlong eiptr) { + linphone_call_decline_with_error_info((LinphoneCall*)callptr, (LinphoneErrorInfo*)eiptr); +} + +extern "C" void Java_org_linphone_core_LinphoneCallImpl_terminateWithErrorInfo( JNIEnv* env + ,jobject thiz + ,jlong callptr, jlong eiptr) { + linphone_call_terminate_with_error_info((LinphoneCall*)callptr, (LinphoneErrorInfo*)eiptr); +} + //LinphoneFriend extern "C" jlong Java_org_linphone_core_LinphoneFriendImpl_newLinphoneFriend(JNIEnv* env ,jobject thiz @@ -7317,6 +7333,86 @@ JNIEXPORT jstring JNICALL Java_org_linphone_core_ErrorInfoImpl_getPhrase(JNIEnv return tmp ? env->NewStringUTF(tmp) : NULL; } +/* + * Class: org_linphone_core_ErrorInfoImpl + * Method: getProtocol + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_linphone_core_ErrorInfoImpl_getProtocol(JNIEnv *env, jobject jobj, jlong ei){ + const char *tmp=linphone_error_info_get_protocol((const LinphoneErrorInfo*)ei); + return tmp ? env->NewStringUTF(tmp) : NULL; +} + +/* + * Class: org_linphone_core_ErrorInfoImpl + * Method: getSubErrorInfo + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_org_linphone_core_ErrorInfoImpl_getSubErrorInfo(JNIEnv *env, jobject jobj, jlong ei){ + return (jlong)linphone_error_info_get_sub_error_info((LinphoneErrorInfo*)ei); +} + +/* + * Class: org_linphone_core_ErrorInfoImpl + * Method: setReason + * Signature: (JI) + */ +JNIEXPORT void JNICALL Java_org_linphone_core_ErrorInfoImpl_setReason(JNIEnv *env, jobject jobj, jlong ei, jint reason){ + linphone_error_info_set_reason((LinphoneErrorInfo*)ei, (LinphoneReason)reason); +} + +/* + * Class: org_linphone_core_ErrorInfoImpl + * Method: getProtocolCode + * Signature: (JI) + */ +JNIEXPORT void JNICALL Java_org_linphone_core_ErrorInfoImpl_setProtocolCode(JNIEnv *env, jobject jobj, jlong ei, jint code){ + return linphone_error_info_set_protocol_code((LinphoneErrorInfo*)ei, code); +} + +/* + * Class: org_linphone_core_ErrorInfoImpl + * Method: setPhrase + * Signature: (JLjava/lang/String;) + */ +JNIEXPORT void JNICALL Java_org_linphone_core_ErrorInfoImpl_setPhrase(JNIEnv *env, jobject jobj, jlong ei, jstring phrase){ + const char *tmp = GetStringUTFChars(env,phrase); + linphone_error_info_set_phrase((LinphoneErrorInfo*)ei, tmp); + if (phrase) ReleaseStringUTFChars(env, phrase, tmp); +} + +/* + * Class: org_linphone_core_ErrorInfoImpl + * Method: setProtocol + * Signature: (JLjava/lang/String;) + */ +JNIEXPORT void JNICALL Java_org_linphone_core_ErrorInfoImpl_setProtocol(JNIEnv *env, jobject jobj, jlong ei, jstring protocol){ + const char *tmp = GetStringUTFChars(env, protocol); + linphone_error_info_set_protocol((LinphoneErrorInfo*)ei, tmp); + if (protocol) ReleaseStringUTFChars(env, protocol, tmp); +} + + +/* + * Class: org_linphone_core_ErrorInfoImpl + * Method: setWarnings + * Signature: (JLjava/lang/String;) + */ +JNIEXPORT void JNICALL Java_org_linphone_core_ErrorInfoImpl_setWarnings(JNIEnv *env, jobject jobj, jlong ei, jstring warnings){ + const char *tmp = GetStringUTFChars(env, warnings); + linphone_error_info_set_warnings((LinphoneErrorInfo*)ei, tmp); + if (warnings) ReleaseStringUTFChars(env, warnings, tmp); +} + +/* + * Class: org_linphone_core_ErrorInfoImpl + * Method: setSubErrorInfo + * Signature: (JLjava/lang/String;) + */ +JNIEXPORT void JNICALL Java_org_linphone_core_ErrorInfoImpl_setSubErrorInfo(JNIEnv *env, jobject jobj, jlong ei, jlong sub_ei){ + linphone_error_info_set_sub_error_info((LinphoneErrorInfo*)ei, (LinphoneErrorInfo*)sub_ei); +} + /* * Class: org_linphone_core_ErrorInfoImpl * Method: getDetails diff --git a/coreapi/private.h b/coreapi/private.h index 036a44203..8688e5cf0 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -1296,6 +1296,7 @@ LinphoneContent * linphone_content_copy(const LinphoneContent *ref); SalBodyHandler *sal_body_handler_from_content(const LinphoneContent *content); SalReason linphone_reason_to_sal(LinphoneReason reason); LinphoneReason linphone_reason_from_sal(SalReason reason); +void linphone_error_info_to_sal(const LinphoneErrorInfo* ei, SalErrorInfo* sei); LinphoneEvent *linphone_event_new(LinphoneCore *lc, LinphoneSubscriptionDir dir, const char *name, int expires); LinphoneEvent *linphone_event_new_with_op(LinphoneCore *lc, SalOp *op, LinphoneSubscriptionDir dir, const char *name); void linphone_event_unpublish(LinphoneEvent *lev); diff --git a/include/linphone/error_info.h b/include/linphone/error_info.h index 025a18e66..121983924 100644 --- a/include/linphone/error_info.h +++ b/include/linphone/error_info.h @@ -63,11 +63,12 @@ LINPHONE_PUBLIC void linphone_error_info_unref(LinphoneErrorInfo *ei); LINPHONE_PUBLIC LinphoneReason linphone_error_info_get_reason(const LinphoneErrorInfo *ei); /** - * Get pointer to chained LinphoneErrorInfo set in sub_ei. + * Get pointer to chained LinphoneErrorInfo set in sub_ei. + * It corresponds to a Reason header in a received SIP response. * @param ei ErrorInfo object * @return LinphoneErrorInfo pointer defined in the ei object. */ -LINPHONE_PUBLIC LinphoneErrorInfo* linphone_error_info_get_sub(const LinphoneErrorInfo *ei); +LINPHONE_PUBLIC LinphoneErrorInfo* linphone_error_info_get_sub_error_info(const LinphoneErrorInfo *ei); /** * Get textual phrase from the error info. @@ -113,19 +114,48 @@ LINPHONE_PUBLIC void linphone_error_info_set(LinphoneErrorInfo *ei, const char * /** * Set the sub_ei in LinphoneErrorInfo to another LinphoneErrorInfo. - * Used when there is more than one reason header. + * Used when a reason header is to be added in a SIP response. The first level LinphoneErrorInfo defines the SIP response code and phrase, + * the second (sub) LinphoneErroInfo defining the content of the Reason header. * @param[in] ei LinphoneErrorInfo object to which the other LinphoneErrorInfo will be appended as ei->sub_ei. * @param[in] appended_ei LinphoneErrorInfo to append */ LINPHONE_PUBLIC void linphone_error_info_set_sub_error_info(LinphoneErrorInfo *ei, LinphoneErrorInfo *appended_ei); /** - * Assign reason LinphoneReason to a LinphoneErrorUnfo object. + * Assign reason LinphoneReason to a LinphoneErrorInfo object. * @param[in] ei ErrorInfo object * @param[in] reason reason from LinphoneReason enum */ LINPHONE_PUBLIC void linphone_error_info_set_reason(LinphoneErrorInfo *ei, LinphoneReason reason); +/** + * Assign protocol name to a LinphoneErrorInfo object. + * @param[in] ei ErrorInfo object + * @param[in] proto the protocol name + */ +LINPHONE_PUBLIC void linphone_error_info_set_protocol(LinphoneErrorInfo *ei, const char *proto); + +/** + * Assign protocol code to a LinphoneErrorInfo object. + * @param[in] ei ErrorInfo object + * @param[in] code the protocol code + */ +LINPHONE_PUBLIC void linphone_error_info_set_protocol_code(LinphoneErrorInfo *ei, int code); + +/** + * Assign phrase to a LinphoneErrorInfo object. + * @param[in] ei ErrorInfo object + * @param[in] phrase the phrase explaining the error + */ +LINPHONE_PUBLIC void linphone_error_info_set_phrase(LinphoneErrorInfo *ei, const char *phrase); + +/** + * Assign warnings to a LinphoneErrorInfo object. + * @param[in] ei ErrorInfo object + * @param[in] phrase the warnings + */ +LINPHONE_PUBLIC void linphone_error_info_set_warnings(LinphoneErrorInfo *ei, const char *warnings); + /** * @} */ diff --git a/java/common/org/linphone/core/ErrorInfo.java b/java/common/org/linphone/core/ErrorInfo.java index 348f7fd61..6c4e76dc6 100644 --- a/java/common/org/linphone/core/ErrorInfo.java +++ b/java/common/org/linphone/core/ErrorInfo.java @@ -6,6 +6,10 @@ public interface ErrorInfo { * @return the reason. */ Reason getReason(); + /** + * Get the protocol name for which the error code (returned by getProtocolCode()) is meaningful. + **/ + String getProtocol(); /** * Get the protocol code corresponding to the error (typically a SIP status code). * @return the code. @@ -16,9 +20,46 @@ public interface ErrorInfo { * @return the reason phrase. */ String getPhrase(); + /** + * Get content of warning header, if any. + **/ + String getWarnings(); + /** + * Get additional error information, which is provided as a Reason header in SIP response. + **/ + ErrorInfo getSubErrorInfo(); + + /** + * Set Reason enum. + */ + void setReason(Reason r); + /** + * Set the protocol name for which the error code (set by setProtocolCode()) is meaningful. + **/ + void setProtocol(String protocol); + /** + * Set the protocol code corresponding to the error (typically a SIP status code). + * @return the code. + */ + void setProtocolCode(int code); + /** + * Set the reason-phrase provided by the protocol (typically a SIP reason-phrase). + * @return the reason phrase. + */ + void setPhrase(String phrase); + /** + * Set warnings. + **/ + void setWarnings(String warnings); + /** + * Set additional error information, which is provided as a Reason header in SIP response. + **/ + void setSubErrorInfo(ErrorInfo sub_ei); + /** * Get details about the error, if provided by the protocol. For SIP it consists of the content of a Warning or Reason header. * @return details about the error. + * @deprecated */ String getDetails(); } diff --git a/java/common/org/linphone/core/LinphoneCall.java b/java/common/org/linphone/core/LinphoneCall.java index b2342a410..8cb43e796 100644 --- a/java/common/org/linphone/core/LinphoneCall.java +++ b/java/common/org/linphone/core/LinphoneCall.java @@ -391,13 +391,13 @@ public interface LinphoneCall { * Call player enable to stream a media file through a call * @return A player */ - public LinphonePlayer getPlayer(); + LinphonePlayer getPlayer(); /** * Create a new chat room for messaging from a call if not already existing, else return existing one * @return LinphoneChatRoom where messaging can take place. */ - public LinphoneChatRoom getChatRoom() ; + LinphoneChatRoom getChatRoom() ; /** * Set the callbacks associated with the LinphoneCall. @@ -409,4 +409,15 @@ public interface LinphoneCall { * This is an indication - the application remains responsible for answering the call. **/ boolean askedToAutoAnswer(); + + /** + * Decline a pending incoming call providing an ErrorInfo object. + **/ + void declineWithErrorInfo(ErrorInfo ei); + + /** + * Terminate a call providing an ErrorInfo object. + **/ + void terminateWithErrorInfo(ErrorInfo ei); } + diff --git a/java/common/org/linphone/core/LinphoneCoreFactory.java b/java/common/org/linphone/core/LinphoneCoreFactory.java index 5bd3cfe52..98e8e1e0d 100644 --- a/java/common/org/linphone/core/LinphoneCoreFactory.java +++ b/java/common/org/linphone/core/LinphoneCoreFactory.java @@ -188,6 +188,11 @@ abstract public class LinphoneCoreFactory { * Create LinphoneAccountCreator object */ abstract public LinphoneAccountCreator createAccountCreator(LinphoneCore lc, String url); + + /** + * Create ErrorInfo object + */ + abstract public ErrorInfo createErrorInfo(); /** * Array of countries list diff --git a/java/impl/org/linphone/core/ErrorInfoImpl.java b/java/impl/org/linphone/core/ErrorInfoImpl.java index e9b6bd5f3..f49bfdcfb 100644 --- a/java/impl/org/linphone/core/ErrorInfoImpl.java +++ b/java/impl/org/linphone/core/ErrorInfoImpl.java @@ -1,41 +1,102 @@ package org.linphone.core; public class ErrorInfoImpl implements ErrorInfo { - private Reason mReason; - private int mCode; - private String mPhrase; - private String mDetails; + protected long mNativePtr; + + private native void ref(long nativePtr); + private native void unref(long nativePtr); private native int getReason(long nativePtr); + private native String getProtocol(long nativePtr); private native int getProtocolCode(long nativePtr); private native String getPhrase(long nativePtr); - private native String getDetails(long nativePtr); + private native String getWarnings(long nativePtr); + private native long getSubErrorInfo(long nativePtr); + + private native void setReason(long nativePtr, int reason); + private native void setProtocol(long nativePtr, String proto); + private native void setProtocolCode(long nativePtr, int code); + private native void setPhrase(long nativePtr, String phrase); + private native void setWarnings(long nativePtr, String warnings); + private native void setSubErrorInfo(long nativePtr, long other_nativePtr); + + public ErrorInfoImpl(long nativePtr, boolean ownsRef){ + if (!ownsRef) ref(nativePtr); + mNativePtr = nativePtr; + } public ErrorInfoImpl(long nativePtr){ - mReason=Reason.fromInt(getReason(nativePtr)); - mCode=getProtocolCode(nativePtr); - mPhrase=getPhrase(nativePtr); - mDetails=getDetails(nativePtr); + ref(nativePtr); + mNativePtr = nativePtr; } @Override public Reason getReason() { - return mReason; + return Reason.fromInt(getReason(mNativePtr)); + } + + @Override + public String getProtocol() { + return getProtocol(mNativePtr); } @Override public int getProtocolCode() { - return mCode; + return getProtocolCode(mNativePtr); } @Override public String getPhrase() { - return mPhrase; + return getPhrase(mNativePtr); + } + + @Override + public String getWarnings(){ + return getWarnings(mNativePtr); + } + + @Override + public ErrorInfo getSubErrorInfo(){ + long sub_ei = getSubErrorInfo(mNativePtr); + return sub_ei != 0 ? new ErrorInfoImpl(sub_ei, false) : null; + } + + + @Override + public void setReason(Reason reason) { + setReason(mNativePtr, reason.mValue); + } + + @Override + public void setProtocol(String proto) { + setProtocol(mNativePtr, proto); } @Override - public String getDetails() { - return mDetails; + public void setProtocolCode(int code) { + setProtocolCode(mNativePtr, code); } + @Override + public void setPhrase(String phrase) { + setPhrase(mNativePtr, phrase); + } + + @Override + public void setWarnings(String warnings){ + setWarnings(mNativePtr, warnings); + } + + @Override + public void setSubErrorInfo(ErrorInfo ei){ + setSubErrorInfo(mNativePtr, ei != null ? ((ErrorInfoImpl)ei).mNativePtr : 0); + } + + + @Override + public String getDetails() { + return getWarnings(); + } + + } diff --git a/java/impl/org/linphone/core/LinphoneCallImpl.java b/java/impl/org/linphone/core/LinphoneCallImpl.java index c276ce07d..f1338c423 100644 --- a/java/impl/org/linphone/core/LinphoneCallImpl.java +++ b/java/impl/org/linphone/core/LinphoneCallImpl.java @@ -93,20 +93,26 @@ class LinphoneCallImpl implements LinphoneCall { return LinphoneCall.State.fromInt(getState(nativePtr)); } public LinphoneCallParams getCurrentParams() { - return new LinphoneCallParamsImpl(getCurrentParams(nativePtr)); + synchronized(mCore){ + return new LinphoneCallParamsImpl(getCurrentParams(nativePtr)); + } } public LinphoneCallParams getCurrentParamsCopy(){ return getCurrentParams(); } public LinphoneCallParams getRemoteParams() { - long remoteParamsPtr = getRemoteParams(nativePtr); - if (remoteParamsPtr == 0) { - return null; + synchronized(mCore){ + long remoteParamsPtr = getRemoteParams(nativePtr); + if (remoteParamsPtr == 0) { + return null; + } + return new LinphoneCallParamsImpl(remoteParamsPtr); } - return new LinphoneCallParamsImpl(remoteParamsPtr); } public void enableCamera(boolean enabled) { - enableCamera(nativePtr, enabled); + synchronized(mCore){ + enableCamera(nativePtr, enabled); + } } public boolean cameraEnabled() { return cameraEnabled(nativePtr); @@ -200,7 +206,9 @@ class LinphoneCallImpl implements LinphoneCall { private native void takeSnapshot(long nativePtr, String path); public void takeSnapshot(String path) { - takeSnapshot(nativePtr, path); + synchronized(mCore){ + takeSnapshot(nativePtr, path); + } } private native void zoomVideo(long nativePtr, float factor, float cx, float cy); @@ -211,12 +219,16 @@ class LinphoneCallImpl implements LinphoneCall { private native void startRecording(long nativePtr); @Override public void startRecording() { - startRecording(nativePtr); + synchronized(mCore){ + startRecording(nativePtr); + } } private native void stopRecording(long nativePtr); @Override public void stopRecording() { - stopRecording(nativePtr); + synchronized(mCore){ + stopRecording(nativePtr); + } } private native int getTransferState(long nativePtr); @Override @@ -226,7 +238,9 @@ class LinphoneCallImpl implements LinphoneCall { private native int sendInfoMessage(long callPtr, long msgptr); @Override public void sendInfoMessage(LinphoneInfoMessage msg) { - sendInfoMessage(nativePtr,((LinphoneInfoMessageImpl)msg).nativePtr); + synchronized(mCore){ + sendInfoMessage(nativePtr,((LinphoneInfoMessageImpl)msg).nativePtr); + } } private native Object getTransfererCall(long callPtr); @Override @@ -246,7 +260,9 @@ class LinphoneCallImpl implements LinphoneCall { private native long getErrorInfo(long nativePtr); @Override public ErrorInfo getErrorInfo() { - return new ErrorInfoImpl(getErrorInfo(nativePtr)); + synchronized(mCore){ + return new ErrorInfoImpl(getErrorInfo(nativePtr)); + } } @Override public void setUserData(Object obj) { @@ -260,18 +276,24 @@ class LinphoneCallImpl implements LinphoneCall { private native long getPlayer(long callPtr); @Override public LinphonePlayer getPlayer() { - return new LinphonePlayerImpl(getPlayer(nativePtr)); + synchronized(mCore){ + return new LinphonePlayerImpl(getPlayer(nativePtr)); + } } private native Object getChatRoom(long nativePtr); @Override public LinphoneChatRoom getChatRoom() { - return (LinphoneChatRoom)(getChatRoom(nativePtr)); + synchronized(mCore){ + return (LinphoneChatRoom)(getChatRoom(nativePtr)); + } } @Override public void setListener(LinphoneCallListener listener) { - setListener(nativePtr, listener); + synchronized(mCore){ + setListener(nativePtr, listener); + } } public LinphoneAddress getDiversionAddress() { @@ -288,5 +310,20 @@ class LinphoneCallImpl implements LinphoneCall { public boolean askedToAutoAnswer(){ return askedToAutoAnswer(nativePtr); } + + private native void declineWithErrorInfo(long call, long ei); + @Override + public void declineWithErrorInfo(ErrorInfo ei){ + synchronized(mCore){ + declineWithErrorInfo(nativePtr, ((ErrorInfoImpl)ei).mNativePtr); + } + } + private native void terminateWithErrorInfo(long call, long ei); + @Override + public void terminateWithErrorInfo(ErrorInfo ei){ + synchronized(mCore){ + terminateWithErrorInfo(nativePtr, ((ErrorInfoImpl)ei).mNativePtr); + } + } } diff --git a/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java b/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java index d1f7f2952..1c817de3c 100644 --- a/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java +++ b/java/impl/org/linphone/core/LinphoneCoreFactoryImpl.java @@ -255,4 +255,10 @@ public class LinphoneCoreFactoryImpl extends LinphoneCoreFactory { public DialPlan[] getAllDialPlan(){ return getAllDialPlanNative(); } + + private native long createErrorInfoNative(); + @Override + public ErrorInfo createErrorInfo(){ + return new ErrorInfoImpl(createErrorInfoNative(), true); + } } diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index c2cb29b7e..91848203b 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -1221,7 +1221,7 @@ static void call_declined_with_error(void) { BC_ASSERT_TRUE(wait_for(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallEnd,1)); rcvd_ei = linphone_call_get_error_info(out_call); - sub_rcvd_ei = linphone_error_info_get_sub(rcvd_ei); + sub_rcvd_ei = linphone_error_info_get_sub_error_info(rcvd_ei); BC_ASSERT_STRING_EQUAL(linphone_error_info_get_phrase(rcvd_ei), "Decline"); BC_ASSERT_STRING_EQUAL(linphone_error_info_get_protocol(rcvd_ei), "SIP"); @@ -1745,7 +1745,7 @@ static void call_caller_with_custom_header_or_sdp_attributes(void) { result = wait_for_until(callee_mgr->lc,caller_mgr->lc,&caller_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_caller.number_of_LinphoneCallStreamsRunning+1, 2000) && wait_for_until(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_callee.number_of_LinphoneCallStreamsRunning+1, 2000); - + BC_ASSERT_TRUE(result); caller_params = linphone_core_create_call_params(caller_mgr->lc, call_caller); @@ -1870,6 +1870,8 @@ static void call_callee_with_custom_header_or_sdp_attributes(void) { && wait_for_until(callee_mgr->lc,caller_mgr->lc,&callee_mgr->stat.number_of_LinphoneCallStreamsRunning,initial_callee.number_of_LinphoneCallStreamsRunning+1, 2000); + BC_ASSERT_TRUE(result); + caller_remote_params = linphone_call_get_remote_params(call_caller); value = linphone_call_params_get_custom_sdp_attribute(caller_remote_params, "working"); BC_ASSERT_PTR_NOT_NULL(value); From 1877a9366253b3f6d860638ce614285966b9dd2e Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Fri, 14 Apr 2017 15:33:28 +0200 Subject: [PATCH 19/70] Simplified LinphoneAudioRouteEnum to please the wrapper generator --- include/linphone/types.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linphone/types.h b/include/linphone/types.h index 70e80ae8b..d4e1a40ce 100644 --- a/include/linphone/types.h +++ b/include/linphone/types.h @@ -182,8 +182,8 @@ typedef enum _LinphoneAddressFamily { * @ingroup call_control **/ typedef enum _LinphoneAudioRoute { - LinphoneAudioRouteEarpiece = MSAudioRouteEarpiece, - LinphoneAudioRouteSpeaker = MSAudioRouteSpeaker + LinphoneAudioRouteEarpiece, + LinphoneAudioRouteSpeaker } LinphoneAudioRoute; /** From 2c3740e56cd60f25f2b81c63ead4da659d9c2f34 Mon Sep 17 00:00:00 2001 From: Erwan Croze Date: Fri, 14 Apr 2017 15:41:30 +0200 Subject: [PATCH 20/70] Add linphoneCore to proxyConfig on init --- coreapi/proxy.c | 1 + 1 file changed, 1 insertion(+) diff --git a/coreapi/proxy.c b/coreapi/proxy.c index f7d645f82..b4e1a545f 100644 --- a/coreapi/proxy.c +++ b/coreapi/proxy.c @@ -107,6 +107,7 @@ static void linphone_proxy_config_init(LinphoneCore* lc, LinphoneProxyConfig *cf const char *contact_params = lc ? lp_config_get_default_string(lc->config, "proxy", "contact_parameters", NULL) : NULL; const char *contact_uri_params = lc ? lp_config_get_default_string(lc->config, "proxy", "contact_uri_parameters", NULL) : NULL; const char *refkey = lc ? lp_config_get_default_string(lc->config, "proxy", "refkey", NULL) : NULL; + cfg->lc = lc; cfg->expires = lc ? lp_config_get_default_int(lc->config, "proxy", "reg_expires", 3600) : 3600; cfg->reg_sendregister = lc ? lp_config_get_default_int(lc->config, "proxy", "reg_sendregister", 1) : 1; cfg->dial_prefix = dial_prefix ? ms_strdup(dial_prefix) : NULL; From 6ac8f1505f05defa9b16775400392c6e09a41917 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Sat, 15 Apr 2017 13:02:08 +0200 Subject: [PATCH 21/70] fix crashes with new error info --- coreapi/bellesip_sal/sal_op_impl.c | 4 ---- coreapi/linphonecall.c | 24 ++++++++++++++---------- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/coreapi/bellesip_sal/sal_op_impl.c b/coreapi/bellesip_sal/sal_op_impl.c index 3db9a73e8..2ee70a372 100644 --- a/coreapi/bellesip_sal/sal_op_impl.c +++ b/coreapi/bellesip_sal/sal_op_impl.c @@ -585,10 +585,6 @@ void sal_error_info_reset(SalErrorInfo *ei){ ms_free(ei->protocol); ei->protocol = NULL; } - if (ei->sub_sei){ - ms_free(ei->sub_sei); - ei->sub_sei = NULL; - } ei->protocol_code=0; ei->reason=SalReasonNone; ei->sub_sei = NULL; diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index b3e38ada2..e1e0ccf1a 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -5151,7 +5151,6 @@ LinphoneStatus linphone_call_terminate_with_error_info(LinphoneCall *call , cons return -1; case LinphoneCallIncomingReceived: case LinphoneCallIncomingEarlyMedia: - linphone_error_info_set_reason(p_ei, LinphoneReasonDeclined); return linphone_call_decline_with_error_info(call, p_ei); case LinphoneCallOutgoingInit: /* In state OutgoingInit, op has to be destroyed */ @@ -5208,13 +5207,12 @@ LinphoneStatus linphone_call_redirect(LinphoneCall *call, const char *redirect_u } LinphoneStatus linphone_call_decline(LinphoneCall * call, LinphoneReason reason) { - if ((call->state != LinphoneCallIncomingReceived) && (call->state != LinphoneCallIncomingEarlyMedia)) { - ms_error("Cannot decline a call that is in state %s", linphone_call_state_to_string(call->state)); - return -1; - } - sal_call_decline(call->op, linphone_reason_to_sal(reason), NULL); - terminate_call(call); - return 0; + LinphoneStatus status; + LinphoneErrorInfo *ei = linphone_error_info_new(); + linphone_error_info_set(ei, "SIP", reason,linphone_reason_to_error_code(reason), NULL, NULL); + status = linphone_call_decline_with_error_info(call, ei); + + return status; } @@ -5228,8 +5226,14 @@ LinphoneStatus linphone_call_decline_with_error_info(LinphoneCall * call, const ms_error("Cannot decline a call that is in state %s", linphone_call_state_to_string(call->state)); return -1; } - linphone_error_info_to_sal(ei, &sei); - sal_call_decline_with_error_info(call->op, &sei , NULL); + if (ei) { + linphone_error_info_to_sal(ei, &sei); + sal_call_decline_with_error_info(call->op, &sei , NULL); + }else{ + sal_call_decline(call->op, SalReasonDeclined, NULL); + } + sal_error_info_reset(&sei); + sal_error_info_reset(&sub_sei); terminate_call(call); return 0; } From 74b638fc799e5a5f6f311ec822b43f7d60dfec5f Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Sat, 15 Apr 2017 14:17:51 +0200 Subject: [PATCH 22/70] fix crash --- coreapi/bellesip_sal/sal_op_call.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/coreapi/bellesip_sal/sal_op_call.c b/coreapi/bellesip_sal/sal_op_call.c index 363ac54b6..df06c1e8e 100644 --- a/coreapi/bellesip_sal/sal_op_call.c +++ b/coreapi/bellesip_sal/sal_op_call.c @@ -510,7 +510,7 @@ static int is_media_description_acceptable(SalMediaDescription *md){ static SalReason process_sdp_for_invite(SalOp* op,belle_sip_request_t* invite) { belle_sdp_session_description_t* sdp; SalReason reason = SalReasonNone; - SalErrorInfo sei; + SalErrorInfo sei = {0}; if (extract_sdp(op,BELLE_SIP_MESSAGE(invite),&sdp,&reason)==0) { if (sdp){ @@ -526,10 +526,9 @@ static SalReason process_sdp_for_invite(SalOp* op,belle_sip_request_t* invite) { } if (reason != SalReasonNone){ - sal_error_info_reset(&sei); sal_error_info_set(&sei, reason,"SIP", 0, NULL, NULL); sal_call_decline_with_error_info(op, &sei,NULL); - + sal_error_info_reset(&sei); } return reason; } From d1c3da96f2b058c1ecd4cbeb31aae97dcc128ae1 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Sat, 15 Apr 2017 23:32:56 +0200 Subject: [PATCH 23/70] fix memory leak and avoid 3 internal deprecated warnings --- coreapi/linphonecall.c | 2 +- coreapi/linphonecore.c | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index e1e0ccf1a..b0287cc0a 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -5211,7 +5211,7 @@ LinphoneStatus linphone_call_decline(LinphoneCall * call, LinphoneReason reason) LinphoneErrorInfo *ei = linphone_error_info_new(); linphone_error_info_set(ei, "SIP", reason,linphone_reason_to_error_code(reason), NULL, NULL); status = linphone_call_decline_with_error_info(call, ei); - + linphone_error_info_unref(ei); return status; } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index ee791ca70..45a996832 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -6061,15 +6061,15 @@ bool_t linphone_core_get_ring_during_incoming_early_media(const LinphoneCore *lc } static OrtpPayloadType* _linphone_core_find_payload_type(LinphoneCore* lc, const char* type, int rate, int channels) { - OrtpPayloadType* result = find_payload_type_from_list(type, rate, channels, linphone_core_get_audio_codecs(lc)); + OrtpPayloadType* result = find_payload_type_from_list(type, rate, channels, lc->codecs_conf.audio_codecs); if (result) { return result; } else { - result = find_payload_type_from_list(type, rate, 0, linphone_core_get_video_codecs(lc)); + result = find_payload_type_from_list(type, rate, 0, lc->codecs_conf.video_codecs); if (result) { return result; } else { - result = find_payload_type_from_list(type, rate, 0, linphone_core_get_text_codecs(lc)); + result = find_payload_type_from_list(type, rate, 0, lc->codecs_conf.text_codecs); if (result) { return result; } From 313b60c0047dd04ad9698b848347301c5b86f9ad Mon Sep 17 00:00:00 2001 From: Johan Pascal Date: Sun, 16 Apr 2017 18:11:09 +0700 Subject: [PATCH 24/70] zid cache migration moved to bzrtp lib - cache migration is now performed in place not to another file - tester of the migration needs to be fixed --- coreapi/linphonecore.c | 278 ++++++----------------------------- coreapi/private.h | 2 - gtk/main.c | 9 +- include/linphone/core.h | 21 +-- tester/message_tester.c | 38 ++++- tester/zidCacheMigration.xml | 2 + 6 files changed, 88 insertions(+), 262 deletions(-) create mode 100644 tester/zidCacheMigration.xml diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 45a996832..65c6250b9 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -28,7 +28,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #ifdef SQLITE_STORAGE_ENABLED #include "sqlite3_bctbx_vfs.h" -/* we need bzrtp.h to setup the zrtp cache only when SQLITE is enabled */ #include "bzrtp/bzrtp.h" #endif @@ -107,6 +106,7 @@ static void set_media_network_reachable(LinphoneCore* lc,bool_t isReachable); static void linphone_core_run_hooks(LinphoneCore *lc); static void linphone_core_uninit(LinphoneCore *lc); static void linphone_core_zrtp_cache_close(LinphoneCore *lc); +static void linphone_core_zrtp_cache_db_init(LinphoneCore *lc, const char *fileName); #include "enum.h" #include "contact_providers_priv.h" @@ -5787,14 +5787,6 @@ static void linphone_core_uninit(LinphoneCore *lc) bctbx_list_for_each(lc->call_logs,(void (*)(void*))linphone_call_log_unref); lc->call_logs=bctbx_list_free(lc->call_logs); - if(lc->zrtp_secrets_cache != NULL) { - ms_free(lc->zrtp_secrets_cache); - } - - if(lc->zrtp_cache_db_file != NULL) { - ms_free(lc->zrtp_cache_db_file); - } - if(lc->user_certificates_path != NULL) { ms_free(lc->user_certificates_path); } @@ -6215,14 +6207,47 @@ void linphone_core_remove_iterate_hook(LinphoneCore *lc, LinphoneCoreIterateHook } void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file){ - if (lc->zrtp_secrets_cache != NULL) { - ms_free(lc->zrtp_secrets_cache); - } - lc->zrtp_secrets_cache=file ? ms_strdup(file) : NULL; -} + /* shall we perform cache migration ? */ + if (!lp_config_get_int(lc->config,"sip","zrtp_cache_migration_done",FALSE)) { + char *tmpFile = bctbx_malloc(strlen(file)+6); + /* check we have a valid xml cache file given in path */ + FILE *CACHEFD = NULL; + /* load the xml cache */ + if (file != NULL) { + CACHEFD = fopen(file, "rb+"); + xmlDocPtr cacheXml = NULL; + if (CACHEFD) { + size_t cacheSize; + char *cacheString = ms_load_file_content(CACHEFD, &cacheSize); + if (!cacheString) { + ms_warning("Unable to load content of ZRTP ZID cache"); + bctbx_free(tmpFile); + return; + } + cacheString[cacheSize] = '\0'; + cacheSize += 1; + fclose(CACHEFD); + cacheXml = xmlParseDoc((xmlChar*)cacheString); + ms_free(cacheString); + } -const char *linphone_core_get_zrtp_secrets_file(LinphoneCore *lc){ - return lc->zrtp_secrets_cache; + /* create a temporary file for the sqlite base and initialise it */ + sprintf(tmpFile,"%s.tmp", file); + linphone_core_zrtp_cache_db_init(lc, tmpFile); + + /* migrate */ + if (bzrtp_cache_migration((void *)cacheXml, linphone_core_get_zrtp_cache_db(lc), linphone_core_get_identity(lc)) ==0) { + char *bkpFile = bctbx_malloc(strlen(file)+6); + sprintf(bkpFile,"%s.bkp", file); + /* migration went ok, rename the original file and replace it with by the tmp one and set the migration tag in config file */ + if (rename(file, bkpFile)==0 && rename(tmpFile, file)==0) { + lp_config_set_int(lc->config, "sip", "zrtp_cache_migration_done", TRUE); + } + } + } + } else { + linphone_core_zrtp_cache_db_init(lc, file); + } } void *linphone_core_get_zrtp_cache_db(LinphoneCore *lc){ @@ -6243,213 +6268,18 @@ static void linphone_core_zrtp_cache_close(LinphoneCore *lc) { } #ifdef SQLITE_STORAGE_ENABLED -/* this function is called only when the sqlite cache is newly created but still empty(contains tables structures but no data) - * and we have an xml cache - * SQL zid cache associate each local sip:uri its own ZID while XML version used one ZID for the whole device-> use the XML provided ZID - * for the default local sipUri retrieved using linphone_core_get_identity - */ -static void linphone_core_zrtp_cache_migration(LinphoneCore *lc) { - FILE *CACHEFD = NULL; - /* load the xml cache */ - if (lc->zrtp_secrets_cache != NULL) { - CACHEFD = fopen(lc->zrtp_secrets_cache, "rb+"); - if (CACHEFD) { - size_t cacheSize; - xmlDocPtr cacheXml; - char *cacheString = ms_load_file_content(CACHEFD, &cacheSize); - if (!cacheString) { - ms_warning("Unable to load content of ZRTP ZID cache"); - return; - } - cacheString[cacheSize] = '\0'; - cacheSize += 1; - fclose(CACHEFD); - cacheXml = xmlParseDoc((xmlChar*)cacheString); - ms_free(cacheString); - if (cacheXml) { - xmlNodePtr cur; - xmlChar *selfZidHex=NULL; - uint8_t selfZID[12]; - sqlite3 *db = (sqlite3 *)linphone_core_get_zrtp_cache_db(lc); - sqlite3_stmt *sqlStmt = NULL; - const char *selfURI = linphone_core_get_identity(lc); - int ret; - /* parse the cache to get the selfZID and insert it in sqlcache */ - cur = xmlDocGetRootElement(cacheXml); - /* if we found a root element, parse its children node */ - if (cur!=NULL) - { - cur = cur->xmlChildrenNode; - } - selfZidHex = NULL; - while (cur!=NULL) { - if ((!xmlStrcmp(cur->name, (const xmlChar *)"selfZID"))){ /* self ZID found, extract it */ - selfZidHex = xmlNodeListGetString(cacheXml, cur->xmlChildrenNode, 1); - bctbx_str_to_uint8(selfZID, selfZidHex, 24); - break; - } - cur = cur->next; - } - /* did we found a self ZID? */ - if (selfZidHex == NULL) { - ms_warning("ZRTP/LIME cache migration: Failed to parse selfZID"); - return; - } - - /* insert the selfZID in cache, associate it to default local sip:uri in case we have more than one */ - ms_message("ZRTP/LIME cache migration: found selfZID %.24s link it to default URI %s in SQL cache", selfZidHex, selfURI); - xmlFree(selfZidHex); - - ret = sqlite3_prepare_v2(db, "INSERT INTO ziduri (zid,selfuri,peeruri) VALUES(?,?,?);", -1, &sqlStmt, NULL); - if (ret != SQLITE_OK) { - ms_warning("ZRTP/LIME cache migration: Failed to insert selfZID"); - return; - } - sqlite3_bind_blob(sqlStmt, 1, selfZID, 12, SQLITE_TRANSIENT); - sqlite3_bind_text(sqlStmt, 2, selfURI,-1,SQLITE_TRANSIENT); - sqlite3_bind_text(sqlStmt, 3, "self",-1,SQLITE_TRANSIENT); - - ret = sqlite3_step(sqlStmt); - if (ret!=SQLITE_DONE) { - ms_warning("ZRTP/LIME cache migration: Failed to insert selfZID"); - return; - } - sqlite3_finalize(sqlStmt); - - /* loop over all the peer node in the xml cache and get from them : uri(can be more than one), ZID, rs1, rs2, pvs, sndKey, rcvKey, sndSId, rcvSId, sndIndex, rcvIndex, valid */ - /* some of these may be missing(pvs, valid, rs2) but we'll consider them NULL */ - /* aux and pbx secrets were not used, so don't even bother looking for them */ - cur = xmlDocGetRootElement(cacheXml)->xmlChildrenNode; - - while (cur!=NULL) { /* loop on all peer nodes */ - if ((!xmlStrcmp(cur->name, (const xmlChar *)"peer"))) { /* found a peer node, check if there is a sipURI node in it (other nodes are just ignored) */ - int i; - xmlNodePtr peerNodeChildren = cur->xmlChildrenNode; - xmlChar *nodeContent = NULL; - xmlChar *peerZIDString = NULL; - uint8_t peerZID[12]; - uint8_t peerZIDFound=0; - xmlChar *peerUri[128]; /* array to contain all the peer uris found in one node */ - /* hopefully they won't be more than 128(it would mean some peer has more than 128 accounts and we called all of them...) */ - int peerUriIndex=0; /* index of previous array */ - char *zrtpColNames[] = {"rs1", "rs2", "pvs"}; - uint8_t *zrtpColValues[] = {NULL, NULL, NULL}; - size_t zrtpColExpectedLengths[] = {32,32,1}; - size_t zrtpColLengths[] = {0,0,0}; - - char *limeColNames[] = {"sndKey", "rcvKey", "sndSId", "rcvSId", "sndIndex", "rcvIndex", "valid"}; - uint8_t *limeColValues[] = {NULL, NULL, NULL, NULL, NULL, NULL, NULL}; - size_t limeColExpectedLengths[] = {32,32,32,32,4,4,8}; - size_t limeColLengths[] = {0,0,0,0,0,0,0}; - - /* check all the children nodes to retrieve all information we may get */ - while (peerNodeChildren!=NULL && peerUriIndex<128) { - if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)"uri")) { /* found a peer an URI node, get the content */ - peerUri[peerUriIndex] = xmlNodeListGetString(cacheXml, peerNodeChildren->xmlChildrenNode, 1); - peerUriIndex++; - } - - if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)"ZID")) { - peerZIDString = xmlNodeListGetString(cacheXml, peerNodeChildren->xmlChildrenNode, 1); - bctbx_str_to_uint8(peerZID, peerZIDString, 24); - - peerZIDFound=1; - } - - for (i=0; i<3; i++) { - if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)zrtpColNames[i])) { - nodeContent = xmlNodeListGetString(cacheXml, peerNodeChildren->xmlChildrenNode, 1); - zrtpColValues[i] = (uint8_t *)bctbx_malloc(zrtpColExpectedLengths[i]); - bctbx_str_to_uint8(zrtpColValues[i], nodeContent, 2*zrtpColExpectedLengths[i]); - zrtpColLengths[i]=zrtpColExpectedLengths[i]; - } - } - - for (i=0; i<7; i++) { - if (!xmlStrcmp(peerNodeChildren->name, (const xmlChar *)limeColNames[i])) { - nodeContent = xmlNodeListGetString(cacheXml, peerNodeChildren->xmlChildrenNode, 1); - limeColValues[i] = (uint8_t *)bctbx_malloc(limeColExpectedLengths[i]); - bctbx_str_to_uint8(limeColValues[i], nodeContent, 2*limeColExpectedLengths[i]); - limeColLengths[i]=limeColExpectedLengths[i]; - } - } - - peerNodeChildren = peerNodeChildren->next; - xmlFree(nodeContent); - nodeContent=NULL; - } - - if (peerUriIndex>0 && peerZIDFound==1) { /* we found at least an uri in this peer node, extract the keys all other informations */ - /* retrieve all the informations */ - - /* loop over all the uri founds */ - for (i=0; inext; - } - } - } - } -} - - -static void linphone_core_zrtp_cache_db_init(LinphoneCore *lc) { +static void linphone_core_zrtp_cache_db_init(LinphoneCore *lc, const char *fileName) { int ret; const char *errmsg; sqlite3 *db; linphone_core_zrtp_cache_close(lc); - ret = _linphone_sqlite3_open(lc->zrtp_cache_db_file, &db); + ret = _linphone_sqlite3_open(fileName, &db); if (ret != SQLITE_OK) { errmsg = sqlite3_errmsg(db); - ms_error("Error in the opening zrtp_cache_db_file(%s): %s.\n", lc->zrtp_cache_db_file, errmsg); + ms_error("Error in the opening zrtp_cache_db_file(%s): %s.\n", fileName, errmsg); sqlite3_close(db); lc->zrtp_cache_db=NULL; return; @@ -6460,33 +6290,17 @@ static void linphone_core_zrtp_cache_db_init(LinphoneCore *lc) { if (ret == BZRTP_CACHE_SETUP || ret == BZRTP_CACHE_UPDATE) { /* After updating schema, database need to be closed/reopenned */ sqlite3_close(db); - _linphone_sqlite3_open(lc->zrtp_cache_db_file, &db); + _linphone_sqlite3_open(fileName, &db); } lc->zrtp_cache_db = db; - - if (ret == BZRTP_CACHE_SETUP && lc->zrtp_secrets_cache != NULL) { - /* we just created the db and we have an old XML version of the cache : migrate */ - linphone_core_zrtp_cache_migration(lc); - } } #else /* SQLITE_STORAGE_ENABLED */ -static void linphone_core_zrtp_cache_db_init(LinphoneCore *lc) { +static void linphone_core_zrtp_cache_db_init(LinphoneCore *lc, const char *fileName) { ms_warning("Tried to open %s as zrtp_cache_db_file, but SQLITE_STORAGE is not enabled", lc->zrtp_cache_db_file); } #endif /* SQLITE_STORAGE_ENABLED */ -void linphone_core_set_zrtp_cache_database_path(LinphoneCore *lc, const char *path) { - if (lc->zrtp_cache_db_file){ - ms_free(lc->zrtp_cache_db_file); - lc->zrtp_cache_db_file = NULL; - } - if (path) { - lc->zrtp_cache_db_file = ms_strdup(path); - linphone_core_zrtp_cache_db_init(lc); - } -} - void linphone_core_set_user_certificates_path(LinphoneCore *lc, const char* path){ char* new_value; new_value = path?ms_strdup(path):NULL; diff --git a/coreapi/private.h b/coreapi/private.h index 8688e5cf0..ba9ec7cd8 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -1056,7 +1056,6 @@ struct _LinphoneCore struct _EchoTester *ect; LinphoneTaskList hooks; /*tasks periodically executed in linphone_core_iterate()*/ LinphoneConference *conf_ctx; - char* zrtp_secrets_cache; /**< zrtp xml filename cache : obsolete, use zrtp_cache_db now, kept to allow cache migration */ char* user_certificates_path; LinphoneVideoPolicy video_policy; time_t network_last_check; @@ -1091,7 +1090,6 @@ struct _LinphoneCore char *chat_db_file; char *logs_db_file; char *friends_db_file; - char *zrtp_cache_db_file; #ifdef SQLITE_STORAGE_ENABLED sqlite3 *zrtp_cache_db; /**< zrtp sqlite cache, used by both zrtp and lime */ sqlite3 *db; diff --git a/gtk/main.c b/gtk/main.c index 394657281..da0e86220 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -253,8 +253,7 @@ gboolean linphone_gtk_get_audio_assistant_option(void){ static void linphone_gtk_init_liblinphone(const char *config_file, const char *factory_config_file, const char *chat_messages_db_file, - const char *call_logs_db_file, const char *friends_db_file, - const char *zrtp_cache_db_file) { + const char *call_logs_db_file, const char *friends_db_file) { LinphoneCoreVTable vtable={0}; gchar *secrets_file=linphone_gtk_get_config_file(SECRETS_FILE); gchar *user_certificates_dir=linphone_gtk_get_config_file(CERTIFICATES_PATH); @@ -291,7 +290,6 @@ static void linphone_gtk_init_liblinphone(const char *config_file, linphone_core_set_user_agent(the_core,"Linphone", LINPHONE_VERSION); linphone_core_set_waiting_callback(the_core,linphone_gtk_wait,NULL); linphone_core_set_zrtp_secrets_file(the_core,secrets_file); /* XML cache is superseeded by the sqlite one, keep it for migration purpose but it shall be removed in future version */ - if (zrtp_cache_db_file) linphone_core_set_zrtp_cache_database_path(the_core, zrtp_cache_db_file); g_free(secrets_file); linphone_core_set_user_certificates_path(the_core,user_certificates_dir); g_free(user_certificates_dir); @@ -2191,7 +2189,7 @@ int main(int argc, char *argv[]){ const char *icon_name=LINPHONE_ICON_NAME; const char *app_name="Linphone"; LpConfig *factory_config; - char *chat_messages_db_file, *call_logs_db_file, *friends_db_file, *zrtp_cache_db_file; + char *chat_messages_db_file, *call_logs_db_file, *friends_db_file; GError *error=NULL; const char *tmp; const char *resources_dir; @@ -2339,8 +2337,7 @@ core_start: chat_messages_db_file=linphone_gtk_message_storage_get_db_file(NULL); call_logs_db_file = linphone_gtk_call_logs_storage_get_db_file(NULL); friends_db_file = linphone_gtk_friends_storage_get_db_file(NULL); - zrtp_cache_db_file = linphone_gtk_zrtp_cache_get_db_file(NULL); - linphone_gtk_init_liblinphone(config_file, factory_config_file, chat_messages_db_file, call_logs_db_file, friends_db_file, zrtp_cache_db_file); + linphone_gtk_init_liblinphone(config_file, factory_config_file, chat_messages_db_file, call_logs_db_file, friends_db_file); g_free(chat_messages_db_file); g_free(call_logs_db_file); g_free(friends_db_file); diff --git a/include/linphone/core.h b/include/linphone/core.h index 13c6c828a..21a34c234 100644 --- a/include/linphone/core.h +++ b/include/linphone/core.h @@ -3655,18 +3655,8 @@ LINPHONE_PUBLIC void linphone_core_refresh_registers(LinphoneCore* lc); * @param[in] lc #LinphoneCore object * @param[in] file The path to the file to use to store the zrtp secrets cache. * @ingroup initializing - * @deprecated cache is now hold as sqlite db, use linphone_core_set_zrtp_cache_database_path to set path to the db and open it */ -LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file); - -/** - * Get the path to the file storing the zrtp secrets cache. - * @param[in] lc #LinphoneCore object. - * @return The path to the file storing the zrtp secrets cache. - * @ingroup initializing - * @deprecated cache is now hold as sqlite db, use linphone_core_get_zrtp_cache_db to get a pointer to it - */ -LINPHONE_PUBLIC LINPHONE_DEPRECATED const char *linphone_core_get_zrtp_secrets_file(LinphoneCore *lc); +LINPHONE_PUBLIC void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file); /** * Get a pointer to the sqlite db holding zrtp/lime cache @@ -3676,15 +3666,6 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED const char *linphone_core_get_zrtp_secrets_f */ LINPHONE_PUBLIC void *linphone_core_get_zrtp_cache_db(LinphoneCore *lc); -/** - * Sets the database filename where zrtp cache will be stored. - * If the file does not exist, it will be created. - * @ingroup initializing - * @param lc the linphone core - * @param path filesystem path -**/ -LINPHONE_PUBLIC void linphone_core_set_zrtp_cache_database_path(LinphoneCore *lc, const char *path); - /** * Set the path to the directory storing the user's x509 certificates (used by dtls) * @param[in] lc #LinphoneCore object diff --git a/tester/message_tester.c b/tester/message_tester.c index 7540b266a..7404567a0 100644 --- a/tester/message_tester.c +++ b/tester/message_tester.c @@ -883,14 +883,18 @@ static int enable_lime_for_message_test(LinphoneCoreManager *marie, LinphoneCore linphone_core_enable_lime(marie->lc, LinphoneLimeMandatory); linphone_core_enable_lime(pauline->lc, LinphoneLimeMandatory); + /* make sure to not trigger the cache migration function */ + lp_config_set_int(marie->lc->config, "sip", "zrtp_cache_migration_done", TRUE); + lp_config_set_int(pauline->lc->config, "sip", "zrtp_cache_migration_done", TRUE); + /* create temporary cache files: setting the database_path will create and initialise the files */ remove(bc_tester_file("tmpZIDCacheMarie.sqlite")); remove(bc_tester_file("tmpZIDCachePauline.sqlite")); filepath = bc_tester_file("tmpZIDCacheMarie.sqlite"); - linphone_core_set_zrtp_cache_database_path(marie->lc, filepath); + linphone_core_set_zrtp_secrets_file(marie->lc, filepath); bc_free(filepath); filepath = bc_tester_file("tmpZIDCachePauline.sqlite"); - linphone_core_set_zrtp_cache_database_path(pauline->lc, filepath); + linphone_core_set_zrtp_secrets_file(pauline->lc, filepath); bc_free(filepath); /* caches are empty, populate them */ @@ -1397,6 +1401,35 @@ static void lime_transfer_message_without_encryption_2(void) { lime_transfer_message_base(FALSE, FALSE, TRUE, FALSE); } +static void lime_cache_migration(void) { + if (lime_is_available()) { + char *xmlCache_filepath = bc_tester_res("zidCacheMigration.xml"); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); + + if (!linphone_core_lime_available(marie->lc)) { + ms_warning("Lime not available, skiping"); + return; + } + + /* make sure lime is enabled */ + linphone_core_enable_lime(marie->lc, LinphoneLimeMandatory); + + /* make sure to trigger the cache migration function */ + lp_config_set_int(marie->lc->config, "sip", "zrtp_cache_migration_done", FALSE); + + /* set the cache path, it will trigger the migration function */ + /* TODO: copy the resource folder xml file to a writable temporary file as it will be erased by sqlite version */ + linphone_core_set_zrtp_secrets_file(marie->lc, xmlCache_filepath); + + /* perform checks on the new cache */ + /* TODO */ + + /* free memory */ + linphone_core_manager_destroy(marie); + } + +} + static void lime_unit(void) { if (lime_is_available()) { LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); @@ -2367,6 +2400,7 @@ test_t message_tests[] = { TEST_ONE_TAG("Lime transfer message from history", lime_transfer_message_from_history, "LIME"), TEST_ONE_TAG("Lime transfer message without encryption", lime_transfer_message_without_encryption, "LIME"), TEST_ONE_TAG("Lime transfer message without encryption 2", lime_transfer_message_without_encryption_2, "LIME"), + TEST_ONE_TAG("Lime cache migration", lime_cache_migration, "LIME"), TEST_ONE_TAG("Lime unitary", lime_unit, "LIME"), TEST_NO_TAG("Database migration", database_migration), TEST_NO_TAG("History range", history_range), diff --git a/tester/zidCacheMigration.xml b/tester/zidCacheMigration.xml new file mode 100644 index 000000000..2414b6f18 --- /dev/null +++ b/tester/zidCacheMigration.xml @@ -0,0 +1,2 @@ + +00112233445566778899aabb99887766554433221100ffeec4274f13a2b6fa05c15ec93158f930e7264b0a893393376dbc80c6eb1cccdc5asip:bob@sip.linphone.org219d9e445d10d4ed64083c7ccbb83a23bc17a97df0af5de4261f3fe026b05b0b747e72a5cc996413cb9fa6e3d18d8b370436e274cd6ba4efc1a4580340af57cadf2bf38e719fa89e17332cf8d5e774ee70d347baa74d16dee01f306c54789869928ce78b0bfc30427a02b1b668b2b3b0496d5664d7e89b75ed292ee97e3fc850496bcc8959337abe5dda11f388384b349d210612f30824268a3753a7afa52ef6df5866dca76315c4sip:bob2@sip.linphone.orgffeeddccbbaa987654321012858b495dfad483af3c088f26d68c4beebc638bd44feae45aea726a771727235esip:bob@sip.linphone.orgb6aac945057bc4466bfe9a23771c6a1b3b8d72ec3e7d8f30ed63cbc5a9479a25bea5ac3225edd0545b816f061a8190370e3ee5160e75404846a34d1580e0c26317ce70fdf12e500294bcb5f2ffef53096761bb1c912b21e972ae03a5a9f05c477e13a20e15a517700f0be0921f74b96d4b4a0c539d5e14d5cdd8706441874ac075e18caa2cfbbf061533dee20c8116dc2c282cae9adfea689b87bc4c6a4e18a846f12e3e7fea39590987654321fedcba5a5a5a5acb6ecc87d1dd87b23f225eec53a26fc541384917623e0c46abab8c0350c6929e92bb03988e8f0ccfefa37a55fd7c5893bea3bfbb27312f49dd9b10d0e3c15fc72315705a5830b98f68458fcd49623144cb34a667512c4d44686aee125bb8b62294c56eea0dd829379263b6da3f6ac0a95388090f168a3568736ca0bd9f8d595fc319ae0d41183fec90afc412d42253c5b456580f7a463c111c7293623b8631f4sip:bob@sip.linphone.org2c46ddcc15f5779e0000000058f095bf01 From deed93a6508c14f4a863afdf1f941e0c49b17ceb Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Sun, 16 Apr 2017 17:32:07 +0200 Subject: [PATCH 25/70] =?UTF-8?q?Fix=20"grosse=20d=C3=A9chire"=20around=20?= =?UTF-8?q?LinphoneTunnel=20objectization.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- coreapi/linphone_tunnel.cc | 2 +- coreapi/linphonecore.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/coreapi/linphone_tunnel.cc b/coreapi/linphone_tunnel.cc index 845cf9fcf..c82876105 100644 --- a/coreapi/linphone_tunnel.cc +++ b/coreapi/linphone_tunnel.cc @@ -34,7 +34,7 @@ LinphoneTunnel* linphone_core_get_tunnel(const LinphoneCore *lc){ } struct _LinphoneTunnel { - ::belle_sip_object_t *base; + ::belle_sip_object_t base; belledonnecomm::TunnelManager *manager; bctbx_list_t *config_list; }; diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 65c6250b9..be59b169a 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -5582,7 +5582,7 @@ void sip_config_uninit(LinphoneCore *lc) /*now that we are unregisted, there is no more channel using tunnel socket we no longer need the tunnel.*/ #ifdef TUNNEL_ENABLED if (lc->tunnel) { - linphone_tunnel_ref(lc->tunnel); + linphone_tunnel_unref(lc->tunnel); lc->tunnel=NULL; ms_message("Tunnel destroyed."); } From b2d2eb4caa873acf440f242acfe2e0a615816fdb Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Sun, 16 Apr 2017 21:51:16 +0200 Subject: [PATCH 26/70] fix compilation issue --- gtk/main.c | 25 ------------------------- 1 file changed, 25 deletions(-) diff --git a/gtk/main.c b/gtk/main.c index da0e86220..9367c8080 100644 --- a/gtk/main.c +++ b/gtk/main.c @@ -2155,31 +2155,6 @@ static void populate_xdg_data_dirs_envvar(void) { } #define ZRTP_CACHE_CONFIG_FILE ".linphone-zidcache.db" -static char *linphone_gtk_zrtp_cache_get_db_file(const char *filename){ - const int path_max=1024; - char *db_file=NULL; - - db_file=(char *)g_malloc(path_max*sizeof(char)); - if (filename==NULL) filename=ZRTP_CACHE_CONFIG_FILE; - /*try accessing a local file first if exists*/ - if (bctbx_file_exist(ZRTP_CACHE_CONFIG_FILE)==0){ - snprintf(db_file,path_max,"%s",filename); - }else{ -#ifdef _WIN32 - const char *appdata=getenv("APPDATA"); - if (appdata){ - snprintf(db_file,path_max,"%s\\%s",appdata,LINPHONE_CONFIG_DIR); - CreateDirectory(db_file,NULL); - snprintf(db_file,path_max,"%s\\%s\\%s",appdata,LINPHONE_CONFIG_DIR,filename); - } -#else - const char *home=getenv("HOME"); - if (home==NULL) home="."; - snprintf(db_file,path_max,"%s/%s",home,filename); -#endif - } - return db_file; -} int main(int argc, char *argv[]){ char *config_file; From 7ea2d051c15595308efcd769146e33efa519c6c8 Mon Sep 17 00:00:00 2001 From: Johan Pascal Date: Mon, 17 Apr 2017 11:55:12 +0700 Subject: [PATCH 27/70] memory leak --- coreapi/linphonecore.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index be59b169a..6a25d6a48 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -6243,8 +6243,11 @@ void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file){ if (rename(file, bkpFile)==0 && rename(tmpFile, file)==0) { lp_config_set_int(lc->config, "sip", "zrtp_cache_migration_done", TRUE); } + bctbx_free(bkpFile); } + xmlFree(cacheXml); } + bctbx_free(tmpFile); } else { linphone_core_zrtp_cache_db_init(lc, file); } From 5ff61484ea523899dc3859109101c886d6f510fc Mon Sep 17 00:00:00 2001 From: Johan Pascal Date: Mon, 17 Apr 2017 11:56:25 +0700 Subject: [PATCH 28/70] improve zrtp cache migration test --- tester/message_tester.c | 19 +++++++++++++++---- tester/zidCacheMigration.xml | 2 -- 2 files changed, 15 insertions(+), 6 deletions(-) delete mode 100644 tester/zidCacheMigration.xml diff --git a/tester/message_tester.c b/tester/message_tester.c index 7404567a0..c5ee54ef4 100644 --- a/tester/message_tester.c +++ b/tester/message_tester.c @@ -42,6 +42,8 @@ static const char *marie_zid_sqlcache = "BEGIN TRANSACTION; CREATE TABLE IF NOT static const char *pauline_zid_sqlcache = "BEGIN TRANSACTION; CREATE TABLE IF NOT EXISTS ziduri (zuid INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL,zid BLOB NOT NULL DEFAULT '000000000000',selfuri TEXT NOT NULL DEFAULT 'unset',peeruri TEXT NOT NULL DEFAULT 'unset'); INSERT INTO `ziduri` (zuid,zid,selfuri,peeruri) VALUES (1,X'bcb4028bf55e1b7ac4c4edee','%s','self'), (2,X'4ddc8042bee500ad0366bf93','%s','%s'); CREATE TABLE IF NOT EXISTS zrtp (zuid INTEGER NOT NULL DEFAULT 0 UNIQUE,rs1 BLOB DEFAULT NULL,rs2 BLOB DEFAULT NULL,aux BLOB DEFAULT NULL,pbx BLOB DEFAULT NULL,pvs BLOB DEFAULT NULL,FOREIGN KEY(zuid) REFERENCES ziduri(zuid) ON UPDATE CASCADE ON DELETE CASCADE); INSERT INTO `zrtp` (zuid,rs1,rs2,aux,pbx,pvs) VALUES (2,X'f0e0ad4d3d4217ba4048d1553e5ab26fae0b386cdac603f29a66d5f4258e14ef',NULL,NULL,NULL,X'01'); CREATE TABLE IF NOT EXISTS lime (zuid INTEGER NOT NULL DEFAULT 0 UNIQUE,sndKey BLOB DEFAULT NULL,rcvKey BLOB DEFAULT NULL,sndSId BLOB DEFAULT NULL,rcvSId BLOB DEFAULT NULL,sndIndex BLOB DEFAULT NULL,rcvIndex BLOB DEFAULT NULL,valid BLOB DEFAULT NULL,FOREIGN KEY(zuid) REFERENCES ziduri(zuid) ON UPDATE CASCADE ON DELETE CASCADE); INSERT INTO `lime` (zuid,rcvKey,sndKey,rcvSId,sndSId,rcvIndex,sndIndex,valid) VALUES (2,X'97c75a5a92a041b415296beec268efc3373ef4aa8b3d5f301ac7522a7fb4e332',x'3b74b709b961e5ebccb1db6b850ea8c1f490546d6adee2f66b5def7093cead3d',X'e2ebca22ad33071bc37631393bf25fc0a9badeea7bf6dcbcb5d480be7ff8c5ea',X'a2086d195344ec2997bf3de7441d261041cda5d90ed0a0411ab2032e5860ea48',X'33376935',X'7ce32d86',X'0000000000000000'); COMMIT;"; +static const char *xmlCacheMigration = "\n00112233445566778899aabb99887766554433221100ffeec4274f13a2b6fa05c15ec93158f930e7264b0a893393376dbc80c6eb1cccdc5asip:bob@sip.linphone.org219d9e445d10d4ed64083c7ccbb83a23bc17a97df0af5de4261f3fe026b05b0b747e72a5cc996413cb9fa6e3d18d8b370436e274cd6ba4efc1a4580340af57cadf2bf38e719fa89e17332cf8d5e774ee70d347baa74d16dee01f306c54789869928ce78b0bfc30427a02b1b668b2b3b0496d5664d7e89b75ed292ee97e3fc850496bcc8959337abe5dda11f388384b349d210612f30824268a3753a7afa52ef6df5866dca76315c4sip:bob2@sip.linphone.orgffeeddccbbaa987654321012858b495dfad483af3c088f26d68c4beebc638bd44feae45aea726a771727235esip:bob@sip.linphone.orgb6aac945057bc4466bfe9a23771c6a1b3b8d72ec3e7d8f30ed63cbc5a9479a25bea5ac3225edd0545b816f061a8190370e3ee5160e75404846a34d1580e0c26317ce70fdf12e500294bcb5f2ffef53096761bb1c912b21e972ae03a5a9f05c477e13a20e15a517700f0be0921f74b96d4b4a0c539d5e14d5cdd8706441874ac075e18caa2cfbbf061533dee20c8116dc2c282cae9adfea689b87bc4c6a4e18a846f12e3e7fea39590987654321fedcba5a5a5a5acb6ecc87d1dd87b23f225eec53a26fc541384917623e0c46abab8c0350c6929e92bb03988e8f0ccfefa37a55fd7c5893bea3bfbb27312f49dd9b10d0e3c15fc72315705a5830b98f68458fcd49623144cb34a667512c4d44686aee125bb8b62294c56eea0dd829379263b6da3f6ac0a95388090f168a3568736ca0bd9f8d595fc319ae0d41183fec90afc412d42253c5b456580f7a463c111c7293623b8631f4sip:bob@sip.linphone.org2c46ddcc15f5779e0000000058f095bf01"; + void text_message_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from_address, const char *msg) { stats* counters = get_stats(lc); counters->number_of_LinphoneMessageReceivedLegacy++; @@ -1403,7 +1405,17 @@ static void lime_transfer_message_without_encryption_2(void) { static void lime_cache_migration(void) { if (lime_is_available()) { - char *xmlCache_filepath = bc_tester_res("zidCacheMigration.xml"); + char *xmlCache_filepath = bc_tester_file("tmp_zidCacheMigration"); + FILE *xmlCacheFD = NULL; + /* create the temporary cache xml file, it will be turned to sqlite */ + if ((xmlCacheFD = fopen(xmlCache_filepath, "w") ) == NULL) { + BC_ASSERT_PTR_NOT_NULL(xmlCacheFD); + ms_error("Unable to create temporary XML ZID cache file to test cache migration"); + return; + } + fprintf(xmlCacheFD, "%s", xmlCacheMigration); + fclose(xmlCacheFD); + LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); if (!linphone_core_lime_available(marie->lc)) { @@ -1418,16 +1430,15 @@ static void lime_cache_migration(void) { lp_config_set_int(marie->lc->config, "sip", "zrtp_cache_migration_done", FALSE); /* set the cache path, it will trigger the migration function */ - /* TODO: copy the resource folder xml file to a writable temporary file as it will be erased by sqlite version */ linphone_core_set_zrtp_secrets_file(marie->lc, xmlCache_filepath); - /* perform checks on the new cache */ + /* perform checks on the new cache, simple check is ok as deeper ones are performed in the bzrtp migration tester */ /* TODO */ /* free memory */ linphone_core_manager_destroy(marie); + remove(xmlCache_filepath); } - } static void lime_unit(void) { diff --git a/tester/zidCacheMigration.xml b/tester/zidCacheMigration.xml deleted file mode 100644 index 2414b6f18..000000000 --- a/tester/zidCacheMigration.xml +++ /dev/null @@ -1,2 +0,0 @@ - -00112233445566778899aabb99887766554433221100ffeec4274f13a2b6fa05c15ec93158f930e7264b0a893393376dbc80c6eb1cccdc5asip:bob@sip.linphone.org219d9e445d10d4ed64083c7ccbb83a23bc17a97df0af5de4261f3fe026b05b0b747e72a5cc996413cb9fa6e3d18d8b370436e274cd6ba4efc1a4580340af57cadf2bf38e719fa89e17332cf8d5e774ee70d347baa74d16dee01f306c54789869928ce78b0bfc30427a02b1b668b2b3b0496d5664d7e89b75ed292ee97e3fc850496bcc8959337abe5dda11f388384b349d210612f30824268a3753a7afa52ef6df5866dca76315c4sip:bob2@sip.linphone.orgffeeddccbbaa987654321012858b495dfad483af3c088f26d68c4beebc638bd44feae45aea726a771727235esip:bob@sip.linphone.orgb6aac945057bc4466bfe9a23771c6a1b3b8d72ec3e7d8f30ed63cbc5a9479a25bea5ac3225edd0545b816f061a8190370e3ee5160e75404846a34d1580e0c26317ce70fdf12e500294bcb5f2ffef53096761bb1c912b21e972ae03a5a9f05c477e13a20e15a517700f0be0921f74b96d4b4a0c539d5e14d5cdd8706441874ac075e18caa2cfbbf061533dee20c8116dc2c282cae9adfea689b87bc4c6a4e18a846f12e3e7fea39590987654321fedcba5a5a5a5acb6ecc87d1dd87b23f225eec53a26fc541384917623e0c46abab8c0350c6929e92bb03988e8f0ccfefa37a55fd7c5893bea3bfbb27312f49dd9b10d0e3c15fc72315705a5830b98f68458fcd49623144cb34a667512c4d44686aee125bb8b62294c56eea0dd829379263b6da3f6ac0a95388090f168a3568736ca0bd9f8d595fc319ae0d41183fec90afc412d42253c5b456580f7a463c111c7293623b8631f4sip:bob@sip.linphone.org2c46ddcc15f5779e0000000058f095bf01 From e6bc7276b2a2d0d0ea0db2e78a190466d88e6436 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Mon, 17 Apr 2017 12:11:40 +0200 Subject: [PATCH 29/70] allow compilation without bzrtp (with automake) --- CMakeLists.txt | 1 + configure.ac | 35 ++++++++++++++++++++++++++--------- coreapi/linphonecore.c | 20 ++++++++++++-------- 3 files changed, 39 insertions(+), 17 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e4eba9c0c..6bdc928d5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -178,6 +178,7 @@ if(ENABLE_LIME) find_package(BZRTP) endif() set(HAVE_LIME 1) + set(HAVE_BZRTP 1) endif() if(ENABLE_CXX_WRAPPER) find_package(PythonInterp REQUIRED) diff --git a/configure.ac b/configure.ac index 0a61de025..4467a0e55 100644 --- a/configure.ac +++ b/configure.ac @@ -630,7 +630,7 @@ AC_ARG_ENABLE(alsa, [alsa=true] ) -dnl this options are just for passing to mediastreamer2 subproject + AC_ARG_ENABLE(zrtp, [AS_HELP_STRING([--enable-zrtp], [Turn on zrtp support])], [case "${enableval}" in @@ -638,9 +638,22 @@ AC_ARG_ENABLE(zrtp, no) zrtp=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-zrtp) ;; esac], - [zrtp=false] + [zrtp=auto] ) +if test "$zrtp" != "false" ; then + PKG_CHECK_MODULES(LIBBZRTP, libbzrtp >= 1.0.0, found_zrtp=true, found_zrtp=false) + if test "$zrtp$found_zrtp" = "truefalse" ; then + AC_MSG_ERROR("Cound not find bZRTP library.") + fi + if test "$found_zrtp" = "true" ; then + zrtp=true + AC_DEFINE(HAVE_BZRTP, 1, [Defined if bzrtp is available]) + else + zrtp=false + fi +fi + dnl this options are just for passing to mediastreamer2 subproject AC_ARG_ENABLE(dtls, [AS_HELP_STRING([--enable-dtls], [Turn on srtp-dtls support - requires polarssl > 1.4])], @@ -701,18 +714,21 @@ AC_ARG_ENABLE(lime, no) lime=false ;; *) AC_MSG_ERROR(bad value ${enableval} for --enable-lime) ;; esac], - [lime=false] + [lime=auto] ) +if test "$lime" = "true" ; then + if test "$zrtp" = "false" ; then + AC_MSG_ERROR([LIME requires zrtp]) + fi +fi + if test "$lime" != "false" ; then - if test "x$found_polarssl" != "xyes" ; then - if test "$lime" = "true" ; then - AC_MSG_ERROR("LIME requires POLARSSL in version >= 1.3") - fi - lime=false - else + if test "$found_zrtp" = "true" ; then AC_DEFINE(HAVE_LIME, 1, [Defined when LIME support is compiled]) lime=true + else + lime = false fi fi @@ -1091,6 +1107,7 @@ printf "* %-30s %s\n" "Console interface" $console_ui printf "* %-30s %s\n" "Tools" $build_tools printf "* %-30s %s\n" "Sqlite storage" $enable_sqlite_storage printf "* %-30s %s\n" "VCard support" $enable_vcard +printf "* %-30s %s\n" "ZRTP" $zrtp printf "* %-30s %s\n" "IM encryption" $lime printf "* %-30s %s\n" "uPnP support" $build_upnp printf "* %-30s %s\n" "LDAP support" $enable_ldap diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 6a25d6a48..a8c3f2c6f 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -28,7 +28,9 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #ifdef SQLITE_STORAGE_ENABLED #include "sqlite3_bctbx_vfs.h" -#include "bzrtp/bzrtp.h" +# ifdef HAVE_BZRTP +# include "bzrtp/bzrtp.h" +# endif #endif #include @@ -106,7 +108,7 @@ static void set_media_network_reachable(LinphoneCore* lc,bool_t isReachable); static void linphone_core_run_hooks(LinphoneCore *lc); static void linphone_core_uninit(LinphoneCore *lc); static void linphone_core_zrtp_cache_close(LinphoneCore *lc); -static void linphone_core_zrtp_cache_db_init(LinphoneCore *lc, const char *fileName); +void linphone_core_zrtp_cache_db_init(LinphoneCore *lc, const char *fileName); #include "enum.h" #include "contact_providers_priv.h" @@ -6206,6 +6208,7 @@ void linphone_core_remove_iterate_hook(LinphoneCore *lc, LinphoneCoreIterateHook } +#ifdef HAVE_BZRTP void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file){ /* shall we perform cache migration ? */ if (!lp_config_get_int(lc->config,"sip","zrtp_cache_migration_done",FALSE)) { @@ -6252,6 +6255,11 @@ void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file){ linphone_core_zrtp_cache_db_init(lc, file); } } +#else +void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file){ + ms_error("linphone_core_set_zrtp_secrets_file(): no zrtp support in this build."); +} +#endif void *linphone_core_get_zrtp_cache_db(LinphoneCore *lc){ #ifdef SQLITE_STORAGE_ENABLED @@ -6270,9 +6278,9 @@ static void linphone_core_zrtp_cache_close(LinphoneCore *lc) { #endif /* SQLITE_STORAGE_ENABLED */ } -#ifdef SQLITE_STORAGE_ENABLED +#if defined(SQLITE_STORAGE_ENABLED) && defined (HAVE_BZRTP) -static void linphone_core_zrtp_cache_db_init(LinphoneCore *lc, const char *fileName) { +void linphone_core_zrtp_cache_db_init(LinphoneCore *lc, const char *fileName) { int ret; const char *errmsg; sqlite3 *db; @@ -6298,10 +6306,6 @@ static void linphone_core_zrtp_cache_db_init(LinphoneCore *lc, const char *fileN lc->zrtp_cache_db = db; } -#else /* SQLITE_STORAGE_ENABLED */ -static void linphone_core_zrtp_cache_db_init(LinphoneCore *lc, const char *fileName) { - ms_warning("Tried to open %s as zrtp_cache_db_file, but SQLITE_STORAGE is not enabled", lc->zrtp_cache_db_file); -} #endif /* SQLITE_STORAGE_ENABLED */ void linphone_core_set_user_certificates_path(LinphoneCore *lc, const char* path){ From 6d00594bde958f8fa4005c92ff43995aa71be7d0 Mon Sep 17 00:00:00 2001 From: Johan Pascal Date: Mon, 17 Apr 2017 22:28:18 +0700 Subject: [PATCH 30/70] Add ENABLE_ZRTP option to cmake + turn HAVE_BZRTP into HAVE_ZRTP to be in sync with mediastreamer2 define --- CMakeLists.txt | 34 +++++++++++++++++++++++++--------- configure.ac | 2 +- coreapi/linphonecore.c | 10 +++++----- 3 files changed, 31 insertions(+), 15 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 6bdc928d5..a63f9f11d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -45,8 +45,9 @@ option(ENABLE_DOC "Enable documentation generation with Doxygen." YES) option(ENABLE_JAVADOC "Add a target to generate documentation for Java API" NO) option(ENABLE_GTK_UI "Turn on or off compilation of gtk interface." YES) option(ENABLE_LDAP "Enable LDAP support." NO) -option(ENABLE_LIME "Enable Instant Messaging Encryption." YES) option(ENABLE_SQLITE_STORAGE "Turn on compilation sqlite storage, for messages, contacts, history" YES) +option(ENABLE_ZRTP "Buid linphone with ZRTP support" YES) +cmake_dependent_option(ENABLE_LIME "Enable Instant Messaging Encryption." YES "ENABLE_ZRTP;ENABLE_SQLITE_STORAGE" NO) cmake_dependent_option(ENABLE_NOTIFY "Enable libnotify support." YES "ENABLE_GTK_UI;NOT APPLE" NO) option(ENABLE_RELATIVE_PREFIX "Find resources relatively to the installation directory." NO) option(ENABLE_STRICT "Build with strict compile options." YES) @@ -171,14 +172,27 @@ if(ENABLE_NLS) find_package(Gettext REQUIRED) find_package(Intl REQUIRED) endif() +if(ENABLE_ZRTP) + if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS) + include("${EP_bzrtp_CONFIG_DIR}/BZRTPConfig.cmake") + else() + find_package(BZRTP) + endif() + if(NOT BZRTP_FOUND) + message(WARNING "Could not find bzrtp library, linphone will be compiled without ZRTP support.") + set(ENABLE_ZRTP OFF CACHE BOOL "Build linphone with ZRTP support." FORCE) + endif() +endif() if(ENABLE_LIME) - if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS) - include("${EP_bzrtp_CONFIG_DIR}/BZRTPConfig.cmake") - else() - find_package(BZRTP) - endif() - set(HAVE_LIME 1) - set(HAVE_BZRTP 1) + if(BZRTP_FOUND) + set(HAVE_LIME 1) + else() + message(WARNING "LIME enabled but could not find bzrtp library, linphone will be compiled without LIME support.") + set(ENABLE_LIME OFF CACHE BOOL "Enable Instant Messaging Encryption." FORCE) + endif() +endif() +if(BZRTP_FOUND) + set(HAVE_ZRTP 1) endif() if(ENABLE_CXX_WRAPPER) find_package(PythonInterp REQUIRED) @@ -205,9 +219,11 @@ include_directories( set(LINPHONE_INCLUDE_DIRS ${BELLESIP_INCLUDE_DIRS} ${MEDIASTREAMER2_INCLUDE_DIRS} - ${BZRTP_INCLUDE_DIRS} ${BCTOOLBOX_CORE_INCLUDE_DIRS} ) +if (BZRTP_FOUND) + list(APPEND LINPHONE_INCLUDE_DIRS ${BZRTP_INCLUDE_DIRS}) +endif() if(ANDROID) include_directories(${CMAKE_CURRENT_BINARY_DIR}/java) endif() diff --git a/configure.ac b/configure.ac index 4467a0e55..46a0e2b85 100644 --- a/configure.ac +++ b/configure.ac @@ -648,7 +648,7 @@ if test "$zrtp" != "false" ; then fi if test "$found_zrtp" = "true" ; then zrtp=true - AC_DEFINE(HAVE_BZRTP, 1, [Defined if bzrtp is available]) + AC_DEFINE(HAVE_ZRTP, 1, [Defined if bzrtp is available]) else zrtp=false fi diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index a8c3f2c6f..3d9016ef2 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -28,7 +28,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #ifdef SQLITE_STORAGE_ENABLED #include "sqlite3_bctbx_vfs.h" -# ifdef HAVE_BZRTP +# ifdef HAVE_ZRTP # include "bzrtp/bzrtp.h" # endif #endif @@ -6208,7 +6208,7 @@ void linphone_core_remove_iterate_hook(LinphoneCore *lc, LinphoneCoreIterateHook } -#ifdef HAVE_BZRTP +#ifdef HAVE_ZRTP void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file){ /* shall we perform cache migration ? */ if (!lp_config_get_int(lc->config,"sip","zrtp_cache_migration_done",FALSE)) { @@ -6255,11 +6255,11 @@ void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file){ linphone_core_zrtp_cache_db_init(lc, file); } } -#else +#else /* HAVE_ZRTP */ void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file){ ms_error("linphone_core_set_zrtp_secrets_file(): no zrtp support in this build."); } -#endif +#endif /* HAVE_ZRTP */ void *linphone_core_get_zrtp_cache_db(LinphoneCore *lc){ #ifdef SQLITE_STORAGE_ENABLED @@ -6278,7 +6278,7 @@ static void linphone_core_zrtp_cache_close(LinphoneCore *lc) { #endif /* SQLITE_STORAGE_ENABLED */ } -#if defined(SQLITE_STORAGE_ENABLED) && defined (HAVE_BZRTP) +#if defined(SQLITE_STORAGE_ENABLED) && defined (HAVE_ZRTP) void linphone_core_zrtp_cache_db_init(LinphoneCore *lc, const char *fileName) { int ret; From 47485efe7c33ef6aaf684b0db692f44ee7891d00 Mon Sep 17 00:00:00 2001 From: Johan Pascal Date: Tue, 18 Apr 2017 21:38:18 +0700 Subject: [PATCH 31/70] linphone_core_get_zrtp_secrets_file is back --- coreapi/linphonecore.c | 16 +++++++++++++++- coreapi/private.h | 1 + include/linphone/core.h | 8 ++++++++ 3 files changed, 24 insertions(+), 1 deletion(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 3d9016ef2..c0d960fee 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -5789,6 +5789,10 @@ static void linphone_core_uninit(LinphoneCore *lc) bctbx_list_for_each(lc->call_logs,(void (*)(void*))linphone_call_log_unref); lc->call_logs=bctbx_list_free(lc->call_logs); + if(lc->zrtp_secrets_cache != NULL) { + ms_free(lc->zrtp_secrets_cache); + } + if(lc->user_certificates_path != NULL) { ms_free(lc->user_certificates_path); } @@ -6210,6 +6214,12 @@ void linphone_core_remove_iterate_hook(LinphoneCore *lc, LinphoneCoreIterateHook #ifdef HAVE_ZRTP void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file){ + if (lc->zrtp_secrets_cache != NULL) { + ms_free(lc->zrtp_secrets_cache); + } + + lc->zrtp_secrets_cache=file ? ms_strdup(file) : NULL; + /* shall we perform cache migration ? */ if (!lp_config_get_int(lc->config,"sip","zrtp_cache_migration_done",FALSE)) { char *tmpFile = bctbx_malloc(strlen(file)+6); @@ -6239,7 +6249,7 @@ void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file){ linphone_core_zrtp_cache_db_init(lc, tmpFile); /* migrate */ - if (bzrtp_cache_migration((void *)cacheXml, linphone_core_get_zrtp_cache_db(lc), linphone_core_get_identity(lc)) ==0) { + if (bzrtp_cache_migration((void *)cacheXml, linphone_core_get_zrtp_cache_db(lc), linphone_core_get_identity(lc)) == 0) { char *bkpFile = bctbx_malloc(strlen(file)+6); sprintf(bkpFile,"%s.bkp", file); /* migration went ok, rename the original file and replace it with by the tmp one and set the migration tag in config file */ @@ -6261,6 +6271,10 @@ void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file){ } #endif /* HAVE_ZRTP */ +const char *linphone_core_get_zrtp_secrets_file(LinphoneCore *lc){ + return lc->zrtp_secrets_cache; +} + void *linphone_core_get_zrtp_cache_db(LinphoneCore *lc){ #ifdef SQLITE_STORAGE_ENABLED return (void *)lc->zrtp_cache_db; diff --git a/coreapi/private.h b/coreapi/private.h index ba9ec7cd8..e09f98a61 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -1056,6 +1056,7 @@ struct _LinphoneCore struct _EchoTester *ect; LinphoneTaskList hooks; /*tasks periodically executed in linphone_core_iterate()*/ LinphoneConference *conf_ctx; + char* zrtp_secrets_cache; /**< zrtp cache filename */ char* user_certificates_path; LinphoneVideoPolicy video_policy; time_t network_last_check; diff --git a/include/linphone/core.h b/include/linphone/core.h index 21a34c234..c5664bd17 100644 --- a/include/linphone/core.h +++ b/include/linphone/core.h @@ -3658,6 +3658,14 @@ LINPHONE_PUBLIC void linphone_core_refresh_registers(LinphoneCore* lc); */ LINPHONE_PUBLIC void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file); +/** + * Get the path to the file storing the zrtp secrets cache. + * @param[in] lc #LinphoneCore object. + * @return The path to the file storing the zrtp secrets cache. + * @ingroup initializing + */ +LINPHONE_PUBLIC const char *linphone_core_get_zrtp_secrets_file(LinphoneCore *lc); + /** * Get a pointer to the sqlite db holding zrtp/lime cache * @param[in] lc #LinphoneCore object. From be66a259aef3fca631d3050d4cda52166281b107 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 18 Apr 2017 16:42:49 +0200 Subject: [PATCH 32/70] Deprecated LinphoneIntRange, replaced by LinphoneRange --- coreapi/factory.c | 4 +++ coreapi/linphonecore.c | 21 ++++++++++++ coreapi/misc.c | 58 +++++++++++++++++++++----------- coreapi/private.h | 14 +++++++- include/linphone/core.h | 27 +++++++++++++++ include/linphone/factory.h | 7 ++++ include/linphone/misc.h | 44 ++++++++++++++++++++++++ include/linphone/types.h | 8 ++++- include/linphone/wrapper_utils.h | 24 ------------- tester/video_tester.c | 9 +++++ 10 files changed, 170 insertions(+), 46 deletions(-) diff --git a/coreapi/factory.c b/coreapi/factory.c index 2f34ec4ca..e6e7445ad 100644 --- a/coreapi/factory.c +++ b/coreapi/factory.c @@ -216,3 +216,7 @@ LinphoneErrorInfo *linphone_factory_create_error_info(LinphoneFactory *factory){ return linphone_error_info_new(); } + +LinphoneRange *linphone_factory_create_range(LinphoneFactory *factory) { + return linphone_range_new(); +} \ No newline at end of file diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index c0d960fee..d75b3d0e3 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2531,6 +2531,13 @@ LinphoneIntRange linphone_core_get_audio_port_range_2(const LinphoneCore *lc) { return range; } +LinphoneRange *linphone_core_get_audio_ports_range(const LinphoneCore *lc) { + LinphoneRange *range = linphone_range_new(); + range->min = lc->rtp_conf.audio_rtp_min_port; + range->max = lc->rtp_conf.audio_rtp_max_port; + return range; +} + int linphone_core_get_video_port(const LinphoneCore *lc){ return lc->rtp_conf.video_rtp_min_port; } @@ -2548,6 +2555,13 @@ LinphoneIntRange linphone_core_get_video_port_range_2(const LinphoneCore *lc) { return range; } +LinphoneRange *linphone_core_get_video_ports_range(const LinphoneCore *lc) { + LinphoneRange *range = linphone_range_new(); + range->min = lc->rtp_conf.video_rtp_min_port; + range->max = lc->rtp_conf.video_rtp_max_port; + return range; +} + int linphone_core_get_text_port(const LinphoneCore *lc) { return lc->rtp_conf.text_rtp_min_port; } @@ -2565,6 +2579,13 @@ LinphoneIntRange linphone_core_get_text_port_range_2(const LinphoneCore *lc) { return range; } +LinphoneRange *linphone_core_get_text_ports_range(const LinphoneCore *lc) { + LinphoneRange *range = linphone_range_new(); + range->min = lc->rtp_conf.text_rtp_min_port; + range->max = lc->rtp_conf.text_rtp_max_port; + return range; +} + int linphone_core_get_nortp_timeout(const LinphoneCore *lc){ return lc->rtp_conf.nortp_timeout; } diff --git a/coreapi/misc.c b/coreapi/misc.c index 1216559ef..5db955617 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -1780,26 +1780,6 @@ void linphone_call_update_ice_from_remote_media_description(LinphoneCall *call, } } - - -/* Functions to mainpulate the LinphoneIntRange structure */ - -int linphone_int_range_get_min(const LinphoneIntRange *range) { - return range->min; -} - -int linphone_int_range_get_max(const LinphoneIntRange *range) { - return range->max; -} - -void linphone_int_range_set_min(LinphoneIntRange *range, int min) { - range->min = min; -} - -void linphone_int_range_set_max(LinphoneIntRange *range, int max) { - range->max = max; -} - void linphone_core_report_call_log(LinphoneCore *lc, LinphoneCallLog *call_log){ bool_t call_logs_sqlite_db_found = FALSE; @@ -1835,4 +1815,42 @@ void linphone_core_report_early_failed_call(LinphoneCore *lc, LinphoneCallDir di linphone_call_log_unref(l); } +/* Functions to mainpulate the LinphoneRange structure */ +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneRange); + +BELLE_SIP_INSTANCIATE_VPTR(LinphoneRange, belle_sip_object_t, + NULL, // destroy + NULL, // clone + NULL, // marshal + FALSE +); + +LinphoneRange *linphone_range_new() { + LinphoneRange *range = belle_sip_object_new(LinphoneRange); + return range; +} + +LinphoneRange* linphone_range_ref (LinphoneRange* range) { + return (LinphoneRange*) belle_sip_object_ref(range); +} + +void linphone_range_unref (LinphoneRange* range) { + belle_sip_object_unref(range); +} + +int linphone_range_get_min(const LinphoneRange *range) { + return range->min; +} + +int linphone_range_get_max(const LinphoneRange *range) { + return range->max; +} + +void linphone_range_set_min(LinphoneRange *range, int min) { + range->min = min; +} + +void linphone_range_set_max(LinphoneRange *range, int max) { + range->max = max; +} \ No newline at end of file diff --git a/coreapi/private.h b/coreapi/private.h index e09f98a61..8674ce0fb 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -1722,6 +1722,17 @@ BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneImEncryptionEngine); LINPHONE_PUBLIC LinphoneImEncryptionEngine *linphone_im_encryption_engine_new(LinphoneCore *lc); +struct _LinphoneRange { + belle_sip_object_t base; + void *user_data; + int min; + int max; +}; + +BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneRange); + +LinphoneRange *linphone_range_new(void); + /** Belle Sip-based objects need unique ids */ @@ -1771,7 +1782,8 @@ BELLE_SIP_TYPE_ID(LinphoneErrorInfo), BELLE_SIP_TYPE_ID(LinphoneConferenceParams), BELLE_SIP_TYPE_ID(LinphoneConference), BELLE_SIP_TYPE_ID(LinphoneInfoMessage), -BELLE_SIP_TYPE_ID(LinphonePayloadType) +BELLE_SIP_TYPE_ID(LinphonePayloadType), +BELLE_SIP_TYPE_ID(LinphoneRange) BELLE_SIP_DECLARE_TYPES_END diff --git a/include/linphone/core.h b/include/linphone/core.h index c5664bd17..3a8ed777e 100644 --- a/include/linphone/core.h +++ b/include/linphone/core.h @@ -2105,10 +2105,19 @@ LINPHONE_PUBLIC void linphone_core_get_audio_port_range(const LinphoneCore *lc, /** * Overload of linphone_core_get_audio_port_range(). + * @deprecated Use linphone_core_get_audio_ports_range instead * @ingroup network_parameters */ LINPHONE_PUBLIC LinphoneIntRange linphone_core_get_audio_port_range_2(const LinphoneCore *lc); +/** + * Get the audio port range from which is randomly chosen the UDP port used for audio streaming. + * @param[in] lc LinphoneCore object + * @return a LinphoneRange object + * @ingroup network_parameters + */ +LINPHONE_PUBLIC LinphoneRange *linphone_core_get_audio_ports_range(const LinphoneCore *lc); + /** * Gets the UDP port used for video streaming. * @param[in] lc LinphoneCore object @@ -2129,10 +2138,19 @@ LINPHONE_PUBLIC void linphone_core_get_video_port_range(const LinphoneCore *lc, /** * Overload of linphone_core_get_video_port_range(). + * @deprecated Use linphone_core_get_video_ports_range instead * @ingroup network_parameters */ LINPHONE_PUBLIC LinphoneIntRange linphone_core_get_video_port_range_2(const LinphoneCore *lc); +/** + * Get the video port range from which is randomly chosen the UDP port used for video streaming. + * @param[in] lc LinphoneCore object + * @return a LinphoneRange object + * @ingroup network_parameters + */ +LINPHONE_PUBLIC LinphoneRange *linphone_core_get_video_ports_range(const LinphoneCore *lc); + /** * Gets the UDP port used for text streaming. * @param[in] lc LinphoneCore object @@ -2153,10 +2171,19 @@ LINPHONE_PUBLIC void linphone_core_get_text_port_range(const LinphoneCore *lc, i /** * Overload of linphone_core_get_text_port_range(). + * @deprecated Use linphone_core_get_text_ports_range instead * @ingroup network_parameters */ LINPHONE_PUBLIC LinphoneIntRange linphone_core_get_text_port_range_2(const LinphoneCore *lc); +/** + * Get the text port range from which is randomly chosen the UDP port used for text streaming. + * @param[in] lc LinphoneCore object + * @return a LinphoneRange object + * @ingroup network_parameters + */ +LINPHONE_PUBLIC LinphoneRange *linphone_core_get_text_ports_range(const LinphoneCore *lc); + /** * Gets the value of the no-rtp timeout. * diff --git a/include/linphone/factory.h b/include/linphone/factory.h index 8498b9e48..9a3c12f0f 100644 --- a/include/linphone/factory.h +++ b/include/linphone/factory.h @@ -216,6 +216,13 @@ LINPHONE_PUBLIC void linphone_factory_set_msplugins_dir(LinphoneFactory *factory * @return LinphoneErrorInfo object. */ LINPHONE_PUBLIC LinphoneErrorInfo *linphone_factory_create_error_info(LinphoneFactory *factory); + +/** + * Creates an object LinphoneRange. + * @param[in] factory LinphoneFactory object + * @return LinphoneRange object. + */ +LINPHONE_PUBLIC LinphoneRange *linphone_factory_create_range(LinphoneFactory *factory); /** * @} */ diff --git a/include/linphone/misc.h b/include/linphone/misc.h index cb27cbe54..c80d7abf2 100644 --- a/include/linphone/misc.h +++ b/include/linphone/misc.h @@ -159,6 +159,18 @@ LINPHONE_PUBLIC LinphoneTransportType linphone_transport_parse(const char* trans **/ LINPHONE_PUBLIC LinphoneReason linphone_error_code_to_reason(int err); +/** + * Increment refcount. + * @param[in] range LinphoneRange object +**/ +LINPHONE_PUBLIC LinphoneRange *linphone_range_ref(LinphoneRange *range); + +/** + * Decrement refcount and possibly free the object. + * @param[in] range LinphoneRange object +**/ +LINPHONE_PUBLIC void linphone_range_unref(LinphoneRange *range); + /** * Converts a LinphoneReason to an error code. * @param[in] reason A LinphoneReason @@ -167,6 +179,38 @@ LINPHONE_PUBLIC LinphoneReason linphone_error_code_to_reason(int err); */ LINPHONE_PUBLIC int linphone_reason_to_error_code(LinphoneReason reason); +/** + * Gets the lower value of the range + * @param[in] range a LinphoneRange + * @return The lower value + * @ingroup misc + */ +LINPHONE_PUBLIC int linphone_range_get_min(const LinphoneRange *range); + +/** + * Gets the higher value of the range + * @param[in] range a LinphoneRange + * @return The higher value + * @ingroup misc + */ +LINPHONE_PUBLIC int linphone_range_get_max(const LinphoneRange *range); + +/** + * Sets the lower value of the range + * @param[in] range a LinphoneRange + * @param[in] min the value to set + * @ingroup misc + */ +LINPHONE_PUBLIC void linphone_range_set_min(LinphoneRange *range, int min); + +/** + * Sets the higher value of the range + * @param[in] range a LinphoneRange + * @param[in] max the value to set + * @ingroup misc + */ +LINPHONE_PUBLIC void linphone_range_set_max(LinphoneRange *range, int max); + #ifdef __cplusplus } diff --git a/include/linphone/types.h b/include/linphone/types.h index d4e1a40ce..7ee2e82ce 100644 --- a/include/linphone/types.h +++ b/include/linphone/types.h @@ -1181,13 +1181,19 @@ typedef struct _LinphonePayloadType LinphonePayloadType; /** * Structure describing a range of integers - * @ingroup misc + * @deprecated */ typedef struct _LinphoneIntRange { int min; /**< Minimum value */ int max; /**< Maximum value */ } LinphoneIntRange; +/** + * Structure describing a range of integers + * @ingroup misc + */ +typedef struct _LinphoneRange LinphoneRange; + /** * Status code returned by some functions to * notify whether the execution has been succesfully diff --git a/include/linphone/wrapper_utils.h b/include/linphone/wrapper_utils.h index d06d5eab3..5c05a1cc0 100644 --- a/include/linphone/wrapper_utils.h +++ b/include/linphone/wrapper_utils.h @@ -65,30 +65,6 @@ LINPHONE_PUBLIC void linphone_chat_message_resend(LinphoneChatMessage *msg); */ LINPHONE_PUBLIC void *linphone_vcard_get_belcard(LinphoneVcard *vcard); - - -/* Functions to mainpulate the LinphoneIntRange structure */ - -/** - * Get the minimum value of a #LinphoneIntRange. - */ -LINPHONE_PUBLIC int linphone_int_range_get_min(const LinphoneIntRange *range); - -/** - * Get the maximum value of a #LinphoneIntRange. - */ -LINPHONE_PUBLIC int linphone_int_range_get_max(const LinphoneIntRange *range); - -/** - * Set the minimum value of a #LinphoneIntRange. - */ -LINPHONE_PUBLIC void linphone_int_range_set_min(LinphoneIntRange *range, int min); - -/** - * Set the maximum value of a #LinphoneIntRange. - */ -LINPHONE_PUBLIC void linphone_int_range_set_max(LinphoneIntRange *range, int max); - /** * @} */ diff --git a/tester/video_tester.c b/tester/video_tester.c index 0526441d7..bab0f9947 100644 --- a/tester/video_tester.c +++ b/tester/video_tester.c @@ -422,6 +422,7 @@ static void forked_outgoing_early_media_video_call_with_inactive_audio_test(void int dummy = 0; pol.automatically_accept = 1; pol.automatically_initiate = 1; + LinphoneRange *port_range = NULL; linphone_core_enable_video_capture(pauline->lc, TRUE); linphone_core_enable_video_display(pauline->lc, TRUE); @@ -432,7 +433,15 @@ static void forked_outgoing_early_media_video_call_with_inactive_audio_test(void linphone_core_enable_video_display(marie2->lc, TRUE); linphone_core_set_video_policy(marie2->lc, &pol); linphone_core_set_audio_port_range(marie2->lc, 40200, 40300); + port_range = linphone_core_get_audio_ports_range(marie2->lc); + BC_ASSERT_EQUAL(port_range->min, 40200, int, "%i"); + BC_ASSERT_EQUAL(port_range->max, 40300, int, "%i"); + linphone_range_unref(port_range); linphone_core_set_video_port_range(marie2->lc, 40400, 40500); + port_range = linphone_core_get_video_ports_range(marie2->lc); + BC_ASSERT_EQUAL(port_range->min, 40400, int, "%i"); + BC_ASSERT_EQUAL(port_range->max, 40500, int, "%i"); + linphone_range_unref(port_range); lcs = bctbx_list_append(lcs,marie1->lc); lcs = bctbx_list_append(lcs,marie2->lc); From f5c41494d35d03be900a8742f5bd519ebfcc0388 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 28 Mar 2017 15:03:28 +0200 Subject: [PATCH 33/70] Add new LinphoneVideoDefinition object and deprecate API functions handling MSVideoSize structures. --- coreapi/CMakeLists.txt | 1 + coreapi/Makefile.am | 13 +- coreapi/call_params.c | 10 ++ coreapi/factory.c | 85 +++++++++++++ coreapi/linphonecall.c | 8 ++ coreapi/linphonecore.c | 188 ++++++++++++++++++---------- coreapi/private.h | 26 +++- coreapi/video_definition.c | 111 ++++++++++++++++ include/CMakeLists.txt | 1 + include/linphone/Makefile.am | 1 + include/linphone/call_params.h | 20 ++- include/linphone/core.h | 74 +++++++++-- include/linphone/factory.h | 24 ++++ include/linphone/types.h | 6 + include/linphone/video_definition.h | 146 +++++++++++++++++++++ wrappers/cpp/tools.hh | 2 +- 16 files changed, 627 insertions(+), 89 deletions(-) create mode 100644 coreapi/video_definition.c create mode 100644 include/linphone/video_definition.h diff --git a/coreapi/CMakeLists.txt b/coreapi/CMakeLists.txt index 1514fa93a..a0932c85e 100644 --- a/coreapi/CMakeLists.txt +++ b/coreapi/CMakeLists.txt @@ -113,6 +113,7 @@ set(LINPHONE_SOURCE_FILES_C siplogin.c sipsetup.c sqlite3_bctbx_vfs.c + video_definition.c xml2lpc.c xml.c xmlrpc.c diff --git a/coreapi/Makefile.am b/coreapi/Makefile.am index 023e26be0..58cfab40e 100644 --- a/coreapi/Makefile.am +++ b/coreapi/Makefile.am @@ -34,6 +34,7 @@ liblinphone_la_SOURCES=\ carddav.h \ call_log.c \ call_params.c \ + carddav.c \ chat.c \ chat_file_transfer.c \ conference.cc conference_private.h \ @@ -46,6 +47,7 @@ liblinphone_la_SOURCES=\ enum.c enum.h \ error_info.c \ event.c \ + factory.c \ friend.c \ friendlist.c \ im_notif_policy.c \ @@ -63,25 +65,24 @@ liblinphone_la_SOURCES=\ misc.c \ nat_policy.c \ offeranswer.c offeranswer.h\ + payload_type.c \ player.c \ presence.c \ private.h \ proxy.c \ quality_reporting.c quality_reporting.h\ remote_provisioning.c \ + ringtoneplayer.c \ sal.c \ siplogin.c \ sipsetup.c \ + sqlite3_bctbx_vfs.c sqlite3_bctbx_vfs.h\ vcard_private.h \ + vtables.c \ + video_definition.c \ xml2lpc.c xml2lpc.h \ xml.c \ xmlrpc.c \ - vtables.c \ - carddav.c \ - ringtoneplayer.c \ - sqlite3_bctbx_vfs.c sqlite3_bctbx_vfs.h\ - factory.c \ - payload_type.c \ $(GITVERSION_FILE) if BUILD_UPNP diff --git a/coreapi/call_params.c b/coreapi/call_params.c index a4989670d..8715ed049 100644 --- a/coreapi/call_params.c +++ b/coreapi/call_params.c @@ -193,6 +193,10 @@ MSVideoSize linphone_call_params_get_received_video_size(const LinphoneCallParam return cp->recv_vsize; } +const LinphoneVideoDefinition * linphone_call_params_get_received_video_definition(const LinphoneCallParams *cp) { + return cp->recv_vdef; +} + const char *linphone_call_params_get_record_file(const LinphoneCallParams *cp){ return cp->record_file; } @@ -209,6 +213,10 @@ MSVideoSize linphone_call_params_get_sent_video_size(const LinphoneCallParams *c return cp->sent_vsize; } +const LinphoneVideoDefinition * linphone_call_params_get_sent_video_definition(const LinphoneCallParams *cp) { + return cp->sent_vdef; +} + const char *linphone_call_params_get_session_name(const LinphoneCallParams *cp){ return cp->session_name; } @@ -317,6 +325,8 @@ LinphoneCallParams * linphone_call_params_ref(LinphoneCallParams *cp) { } void linphone_call_params_unref(LinphoneCallParams *cp) { + if (cp->sent_vdef != NULL) linphone_video_definition_unref(cp->sent_vdef); + if (cp->recv_vdef != NULL) linphone_video_definition_unref(cp->recv_vdef); belle_sip_object_unref(cp); } diff --git a/coreapi/factory.c b/coreapi/factory.c index e6e7445ad..fa1fcd770 100644 --- a/coreapi/factory.c +++ b/coreapi/factory.c @@ -38,6 +38,9 @@ typedef belle_sip_object_t_vptr_t LinphoneFactory_vptr_t; struct _LinphoneFactory { belle_sip_object_t base; + + bctbx_list_t *supported_video_definitions; + /*these are the directories set by the application*/ char *top_resources_dir; char *data_resources_dir; @@ -56,6 +59,8 @@ struct _LinphoneFactory { }; static void linphone_factory_uninit(LinphoneFactory *obj){ + bctbx_list_free_with_data(obj->supported_video_definitions, (bctbx_list_free_func)linphone_video_definition_unref); + STRING_RESET(obj->top_resources_dir); STRING_RESET(obj->data_resources_dir); STRING_RESET(obj->sound_resources_dir); @@ -87,9 +92,41 @@ static void _linphone_factory_destroying_cb(void) { } } +#define ADD_SUPPORTED_VIDEO_DEFINITION(factory, width, height, name) \ + (factory)->supported_video_definitions = bctbx_list_append((factory)->supported_video_definitions, \ + linphone_video_definition_ref(linphone_video_definition_new(width, height, name))) + +static void initialize_supported_video_definitions(LinphoneFactory *factory) { +#if !defined(__ANDROID__) && !TARGET_OS_IPHONE + ADD_SUPPORTED_VIDEO_DEFINITION(factory, MS_VIDEO_SIZE_1080P_W, MS_VIDEO_SIZE_1080P_H, "1080p"); +#endif +#if !defined(__ANDROID__) && !TARGET_OS_MAC /*limit to most common sizes because mac video API cannot list supported resolutions*/ + ADD_SUPPORTED_VIDEO_DEFINITION(factory, MS_VIDEO_SIZE_UXGA_W, MS_VIDEO_SIZE_UXGA_H, "uxga"); + ADD_SUPPORTED_VIDEO_DEFINITION(factory, MS_VIDEO_SIZE_SXGA_MINUS_W, MS_VIDEO_SIZE_SXGA_MINUS_H, "sxga-"); +#endif + ADD_SUPPORTED_VIDEO_DEFINITION(factory, MS_VIDEO_SIZE_720P_W, MS_VIDEO_SIZE_720P_H, "720p"); +#if !defined(__ANDROID__) && !TARGET_OS_MAC + ADD_SUPPORTED_VIDEO_DEFINITION(factory, MS_VIDEO_SIZE_XGA_W, MS_VIDEO_SIZE_XGA_H, "xga"); +#endif +#if !defined(__ANDROID__) && !TARGET_OS_IPHONE + ADD_SUPPORTED_VIDEO_DEFINITION(factory, MS_VIDEO_SIZE_SVGA_W, MS_VIDEO_SIZE_SVGA_H, "svga"); + ADD_SUPPORTED_VIDEO_DEFINITION(factory, MS_VIDEO_SIZE_4CIF_W, MS_VIDEO_SIZE_4CIF_H, "4cif"); +#endif + ADD_SUPPORTED_VIDEO_DEFINITION(factory, MS_VIDEO_SIZE_VGA_W, MS_VIDEO_SIZE_VGA_H, "vga"); +#if TARGET_OS_IPHONE + ADD_SUPPORTED_VIDEO_DEFINITION(factory, MS_VIDEO_SIZE_IOS_MEDIUM_H, MS_VIDEO_SIZE_IOS_MEDIUM_W, "ios-medium"); +#endif + ADD_SUPPORTED_VIDEO_DEFINITION(factory, MS_VIDEO_SIZE_CIF_W, MS_VIDEO_SIZE_CIF_H, "cif"); +#if !TARGET_OS_MAC || TARGET_OS_IPHONE /* OS_MAC is 1 for iPhone, but we need QVGA */ + ADD_SUPPORTED_VIDEO_DEFINITION(factory, MS_VIDEO_SIZE_QVGA_W, MS_VIDEO_SIZE_QVGA_H, "qvga"); +#endif + ADD_SUPPORTED_VIDEO_DEFINITION(factory, MS_VIDEO_SIZE_QCIF_W, MS_VIDEO_SIZE_QCIF_H, "qcif"); +} + static LinphoneFactory *linphone_factory_new(void){ LinphoneFactory *factory = belle_sip_object_new(LinphoneFactory); factory->top_resources_dir = bctbx_strdup(PACKAGE_DATA_DIR); + initialize_supported_video_definitions(factory); return factory; } @@ -141,6 +178,54 @@ LinphoneVcard *linphone_factory_create_vcard(LinphoneFactory *factory) { return _linphone_vcard_new(); } +LinphoneVideoDefinition * linphone_factory_create_video_definition(const LinphoneFactory *factory, unsigned int width, unsigned int height) { + return linphone_video_definition_ref(linphone_video_definition_new(width, height, NULL)); +} + +LinphoneVideoDefinition * linphone_factory_create_video_definition_from_name(const LinphoneFactory *factory, const char *name) { + unsigned int width = 0; + unsigned int height = 0; + LinphoneVideoDefinition *vdef = linphone_factory_find_supported_video_definition_by_name(factory, name); + if (vdef != NULL) return vdef; + if (sscanf(name, "%ux%u", &width, &height) == 2) { + return linphone_video_definition_new(width, height, NULL); + } + return linphone_video_definition_new(0, 0, NULL); +} + +const bctbx_list_t * linphone_factory_get_supported_video_definitions(const LinphoneFactory *factory) { + return factory->supported_video_definitions; +} + +LinphoneVideoDefinition * linphone_factory_find_supported_video_definition(const LinphoneFactory *factory, unsigned int width, unsigned int height) { + const bctbx_list_t *item; + const bctbx_list_t *supported = linphone_factory_get_supported_video_definitions(factory); + LinphoneVideoDefinition *searched_vdef = linphone_video_definition_new(width, height, NULL); + + for (item = supported; item != NULL; item = bctbx_list_next(item)) { + LinphoneVideoDefinition *svdef = (LinphoneVideoDefinition *)bctbx_list_get_data(item); + if (linphone_video_definition_equals(svdef, searched_vdef)) { + linphone_video_definition_unref(searched_vdef); + return svdef; + } + } + + return searched_vdef; +} + +LinphoneVideoDefinition * linphone_factory_find_supported_video_definition_by_name(const LinphoneFactory *factory, const char *name) { + const bctbx_list_t *item; + const bctbx_list_t *supported = linphone_factory_get_supported_video_definitions(factory); + + for (item = supported; item != NULL; item = bctbx_list_next(item)) { + LinphoneVideoDefinition *svdef = (LinphoneVideoDefinition *)bctbx_list_get_data(item); + if (strcmp(linphone_video_definition_get_name(svdef), name) == 0) { + return svdef; + } + } + return NULL; +} + const char * linphone_factory_get_top_resources_dir(const LinphoneFactory *factory) { return factory->top_resources_dir; } diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index b0287cc0a..ce6e67302 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -1964,6 +1964,10 @@ const LinphoneCallParams * linphone_call_get_current_params(LinphoneCall *call){ #ifdef VIDEO_ENABLED VideoStream *vstream; #endif + if (call->current_params->sent_vdef != NULL) linphone_video_definition_unref(call->current_params->sent_vdef); + call->current_params->sent_vdef = NULL; + if (call->current_params->recv_vdef != NULL) linphone_video_definition_unref(call->current_params->recv_vdef); + call->current_params->recv_vdef = NULL; MS_VIDEO_SIZE_ASSIGN(call->current_params->sent_vsize, UNKNOWN); MS_VIDEO_SIZE_ASSIGN(call->current_params->recv_vsize, UNKNOWN); #ifdef VIDEO_ENABLED @@ -1971,6 +1975,10 @@ const LinphoneCallParams * linphone_call_get_current_params(LinphoneCall *call){ if (vstream != NULL) { call->current_params->sent_vsize = video_stream_get_sent_video_size(vstream); call->current_params->recv_vsize = video_stream_get_received_video_size(vstream); + call->current_params->sent_vdef = linphone_video_definition_ref(linphone_factory_find_supported_video_definition( + linphone_factory_get(), call->current_params->sent_vsize.width, call->current_params->sent_vsize.height)); + call->current_params->recv_vdef = linphone_video_definition_ref(linphone_factory_find_supported_video_definition( + linphone_factory_get(), call->current_params->recv_vsize.width, call->current_params->recv_vsize.height)); call->current_params->sent_fps = video_stream_get_sent_framerate(vstream); call->current_params->received_fps = video_stream_get_received_framerate(vstream); } diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index d75b3d0e3..187a37bf5 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -5130,33 +5130,32 @@ int linphone_core_get_camera_sensor_rotation(LinphoneCore *lc) { return -1; } -static MSVideoSizeDef supported_resolutions[]={ +static MSVideoSizeDef supported_resolutions[] = { #if !defined(__ANDROID__) && !TARGET_OS_IPHONE - { { MS_VIDEO_SIZE_1080P_W, MS_VIDEO_SIZE_1080P_H } , "1080p" }, + { { MS_VIDEO_SIZE_1080P_W, MS_VIDEO_SIZE_1080P_H }, "1080p" }, #endif #if !defined(__ANDROID__) && !TARGET_OS_MAC /*limit to most common sizes because mac video API cannot list supported resolutions*/ - { { MS_VIDEO_SIZE_UXGA_W, MS_VIDEO_SIZE_UXGA_H } , "uxga" }, - { { MS_VIDEO_SIZE_SXGA_MINUS_W, MS_VIDEO_SIZE_SXGA_MINUS_H } , "sxga-" }, + { { MS_VIDEO_SIZE_UXGA_W, MS_VIDEO_SIZE_UXGA_H }, "uxga" }, + { { MS_VIDEO_SIZE_SXGA_MINUS_W, MS_VIDEO_SIZE_SXGA_MINUS_H }, "sxga-" }, #endif - { { MS_VIDEO_SIZE_720P_W, MS_VIDEO_SIZE_720P_H } , "720p" }, + { { MS_VIDEO_SIZE_720P_W, MS_VIDEO_SIZE_720P_H }, "720p" }, #if !defined(__ANDROID__) && !TARGET_OS_MAC - { { MS_VIDEO_SIZE_XGA_W, MS_VIDEO_SIZE_XGA_H } , "xga" }, + { { MS_VIDEO_SIZE_XGA_W, MS_VIDEO_SIZE_XGA_H }, "xga" }, #endif #if !defined(__ANDROID__) && !TARGET_OS_IPHONE - { { MS_VIDEO_SIZE_SVGA_W, MS_VIDEO_SIZE_SVGA_H } , "svga" }, - { { MS_VIDEO_SIZE_4CIF_W, MS_VIDEO_SIZE_4CIF_H } , "4cif" }, + { { MS_VIDEO_SIZE_SVGA_W, MS_VIDEO_SIZE_SVGA_H }, "svga" }, + { { MS_VIDEO_SIZE_4CIF_W, MS_VIDEO_SIZE_4CIF_H }, "4cif" }, #endif - - { { MS_VIDEO_SIZE_VGA_W, MS_VIDEO_SIZE_VGA_H } , "vga" }, + { { MS_VIDEO_SIZE_VGA_W, MS_VIDEO_SIZE_VGA_H }, "vga" }, #if TARGET_OS_IPHONE - { { MS_VIDEO_SIZE_IOS_MEDIUM_H, MS_VIDEO_SIZE_IOS_MEDIUM_W } , "ios-medium" }, + { { MS_VIDEO_SIZE_IOS_MEDIUM_H, MS_VIDEO_SIZE_IOS_MEDIUM_W }, "ios-medium" }, #endif - { { MS_VIDEO_SIZE_CIF_W, MS_VIDEO_SIZE_CIF_H } , "cif" }, + { { MS_VIDEO_SIZE_CIF_W, MS_VIDEO_SIZE_CIF_H }, "cif" }, #if !TARGET_OS_MAC || TARGET_OS_IPHONE /* OS_MAC is 1 for iPhone, but we need QVGA */ - { { MS_VIDEO_SIZE_QVGA_W, MS_VIDEO_SIZE_QVGA_H } , "qvga" }, + { { MS_VIDEO_SIZE_QVGA_W, MS_VIDEO_SIZE_QVGA_H } , "qvga" }, #endif - { { MS_VIDEO_SIZE_QCIF_W, MS_VIDEO_SIZE_QCIF_H } , "qcif" }, - { { 0,0 } , NULL } + { { MS_VIDEO_SIZE_QCIF_W, MS_VIDEO_SIZE_QCIF_H }, "qcif" }, + { { 0, 0 }, NULL } }; const MSVideoSizeDef *linphone_core_get_supported_video_sizes(LinphoneCore *lc){ @@ -5180,69 +5179,82 @@ static MSVideoSize video_size_get_by_name(const char *name){ return null_vsize; } -/* warning: function not reentrant*/ -static const char *video_size_get_name(MSVideoSize vsize){ - MSVideoSizeDef *pdef=supported_resolutions; - static char customsize[64]={0}; - for(;pdef->name!=NULL;pdef++){ - if (pdef->vsize.width==vsize.width && pdef->vsize.height==vsize.height){ - return pdef->name; - } +static bool_t video_definition_supported(const LinphoneVideoDefinition *vdef) { + const bctbx_list_t *item; + const bctbx_list_t *supported_definitions = linphone_factory_get_supported_video_definitions(linphone_factory_get()); + for (item = supported_definitions; item != NULL; item = bctbx_list_next(item)) { + LinphoneVideoDefinition *supported_vdef = (LinphoneVideoDefinition *)bctbx_list_get_data(item); + if (linphone_video_definition_equals(vdef, supported_vdef)) return TRUE; } - if (vsize.width && vsize.height){ - snprintf(customsize,sizeof(customsize)-1,"%ix%i",vsize.width,vsize.height); - return customsize; - } - return NULL; -} - -static bool_t video_size_supported(MSVideoSize vsize){ - if (video_size_get_name(vsize)) return TRUE; - ms_warning("Video resolution %ix%i is not supported in linphone.",vsize.width,vsize.height); + ms_warning("Video definition %ix%i is not supported", linphone_video_definition_get_width(vdef), linphone_video_definition_get_height(vdef)); return FALSE; } -static void update_preview_size(LinphoneCore *lc, MSVideoSize oldvsize, MSVideoSize vsize){ - if (!ms_video_size_equal(oldvsize,vsize) && lc->previewstream!=NULL){ - relaunch_video_preview(lc); - } -} - -void linphone_core_set_preferred_video_size(LinphoneCore *lc, MSVideoSize vsize){ - if (video_size_supported(vsize)){ - MSVideoSize oldvsize=lc->video_conf.preview_vsize; - - if (oldvsize.width==0){ - oldvsize=lc->video_conf.vsize; +void linphone_core_set_preferred_video_definition(LinphoneCore *lc, LinphoneVideoDefinition *vdef) { + if (video_definition_supported(vdef)) { + LinphoneVideoDefinition *oldvdef; + if ((lc->video_conf.vdef == NULL) || linphone_video_definition_is_undefined(lc->video_conf.preview_vdef)) { + oldvdef = lc->video_conf.vdef; + } else { + oldvdef = lc->video_conf.preview_vdef; + } + if ((oldvdef == NULL) || !linphone_video_definition_equals(oldvdef, vdef)) { + lc->video_conf.vdef = linphone_video_definition_ref(vdef); + if (oldvdef != NULL) linphone_video_definition_unref(oldvdef); + if (lc->previewstream != NULL) { + relaunch_video_preview(lc); + } } - lc->video_conf.vsize=vsize; - update_preview_size(lc,oldvsize,vsize); - if (linphone_core_ready(lc)) - lp_config_set_string(lc->config,"video","size",video_size_get_name(vsize)); + if (linphone_core_ready(lc)) { + lp_config_set_string(lc->config, "video", "size", linphone_video_definition_get_name(vdef)); + } } } -void linphone_core_set_preview_video_size(LinphoneCore *lc, MSVideoSize vsize){ - MSVideoSize oldvsize; - if (vsize.width==0 && vsize.height==0){ - /*special case to reset the forced preview size mode*/ - lc->video_conf.preview_vsize=vsize; - if (linphone_core_ready(lc)) - lp_config_set_string(lc->config,"video","preview_size",NULL); +void linphone_core_set_preferred_video_size(LinphoneCore *lc, MSVideoSize vsize) { + linphone_core_set_preferred_video_definition(lc, + linphone_factory_find_supported_video_definition(linphone_factory_get(), vsize.width, vsize.height)); +} + +void linphone_core_set_preview_video_definition(LinphoneCore *lc, LinphoneVideoDefinition *vdef) { + if (!vdef || linphone_video_definition_is_undefined(vdef)) { + /* Reset the forced preview video definition mode */ + if (lc->video_conf.preview_vdef != NULL) linphone_video_definition_unref(lc->video_conf.preview_vdef); + lc->video_conf.preview_vdef = NULL; + if (linphone_core_ready(lc)) { + lp_config_set_string(lc->config, "video", "preview_size", NULL); + } return; } - oldvsize=lc->video_conf.preview_vsize; - lc->video_conf.preview_vsize=vsize; - if (!ms_video_size_equal(oldvsize,vsize) && lc->previewstream!=NULL){ - relaunch_video_preview(lc); + + if (!linphone_video_definition_equals(lc->video_conf.preview_vdef, vdef)) { + LinphoneVideoDefinition *oldvdef = lc->video_conf.preview_vdef; + lc->video_conf.preview_vdef = linphone_video_definition_ref(vdef); + if (oldvdef != NULL) linphone_video_definition_unref(oldvdef); + if (lc->previewstream != NULL) { + relaunch_video_preview(lc); + } + } + if (linphone_core_ready(lc)) { + lp_config_set_string(lc->config, "video", "preview_size", linphone_video_definition_get_name(vdef)); } - if (linphone_core_ready(lc)) - lp_config_set_string(lc->config,"video","preview_size",video_size_get_name(vsize)); } -MSVideoSize linphone_core_get_preview_video_size(const LinphoneCore *lc){ - return lc->video_conf.preview_vsize; +void linphone_core_set_preview_video_size(LinphoneCore *lc, MSVideoSize vsize) { + linphone_core_set_preview_video_definition(lc, + linphone_factory_find_supported_video_definition(linphone_factory_get(), vsize.width, vsize.height)); +} + +const LinphoneVideoDefinition * linphone_core_get_preview_video_definition(const LinphoneCore *lc) { + return lc->video_conf.preview_vdef; +} + +MSVideoSize linphone_core_get_preview_video_size(const LinphoneCore *lc) { + MSVideoSize vsize = { 0 }; + vsize.width = linphone_video_definition_get_width(lc->video_conf.preview_vdef); + vsize.height = linphone_video_definition_get_height(lc->video_conf.preview_vdef); + return vsize; } MSVideoSize linphone_core_get_current_preview_video_size(const LinphoneCore *lc){ @@ -5257,11 +5269,33 @@ MSVideoSize linphone_core_get_current_preview_video_size(const LinphoneCore *lc) return ret; } +LinphoneVideoDefinition * linphone_core_get_current_preview_video_definition(const LinphoneCore *lc) { +#ifdef VIDEO_ENABLED + MSVideoSize vsize; + if (lc->previewstream) { + vsize = video_preview_get_current_size(lc->previewstream); + } + return linphone_factory_find_supported_video_definition(linphone_factory_get(), vsize.width, vsize.height); +#else + ms_error("Video support is disabled"); + return NULL; +#endif +} + void linphone_core_set_preview_video_size_by_name(LinphoneCore *lc, const char *name){ MSVideoSize vsize=video_size_get_by_name(name); linphone_core_set_preview_video_size(lc,vsize); } +void linphone_core_set_preview_video_definition_by_name(LinphoneCore *lc, const char *name) { + LinphoneVideoDefinition *vdef = linphone_factory_find_supported_video_definition_by_name(linphone_factory_get(), name); + if (vdef == NULL) { + ms_error("Video definition '%s' is not supported", name); + } else { + linphone_core_set_preview_video_definition(lc, vdef); + } +} + void linphone_core_set_preferred_video_size_by_name(LinphoneCore *lc, const char *name){ MSVideoSize vsize=video_size_get_by_name(name); MSVideoSize default_vsize={MS_VIDEO_SIZE_CIF_W,MS_VIDEO_SIZE_CIF_H}; @@ -5269,12 +5303,28 @@ void linphone_core_set_preferred_video_size_by_name(LinphoneCore *lc, const char else linphone_core_set_preferred_video_size(lc,default_vsize); } -MSVideoSize linphone_core_get_preferred_video_size(const LinphoneCore *lc){ - return lc->video_conf.vsize; +void linphone_core_set_preferred_video_definition_by_name(LinphoneCore *lc, const char *name) { + LinphoneVideoDefinition *vdef = linphone_factory_find_supported_video_definition_by_name(linphone_factory_get(), name); + if (vdef == NULL) { + ms_error("Video definition '%s' is not supported", name); + } else { + linphone_core_set_preferred_video_definition(lc, vdef); + } +} + +const LinphoneVideoDefinition * linphone_core_get_preferred_video_definition(const LinphoneCore *lc) { + return lc->video_conf.vdef; +} + +MSVideoSize linphone_core_get_preferred_video_size(const LinphoneCore *lc) { + MSVideoSize vsize = { 0 }; + vsize.width = linphone_video_definition_get_width(lc->video_conf.vdef); + vsize.height = linphone_video_definition_get_height(lc->video_conf.vdef); + return vsize; } char * linphone_core_get_preferred_video_size_name(const LinphoneCore *lc) { - return ms_strdup(video_size_get_name(lc->video_conf.vsize)); + return ms_strdup(linphone_video_definition_get_name(lc->video_conf.vdef)); } void linphone_core_set_preferred_framerate(LinphoneCore *lc, float fps){ @@ -5669,11 +5719,13 @@ static void sound_config_uninit(LinphoneCore *lc) static void video_config_uninit(LinphoneCore *lc) { - lp_config_set_string(lc->config,"video","size",video_size_get_name(linphone_core_get_preferred_video_size(lc))); + lp_config_set_string(lc->config,"video","size",linphone_video_definition_get_name(linphone_core_get_preferred_video_definition(lc))); lp_config_set_int(lc->config,"video","display",lc->video_conf.display); lp_config_set_int(lc->config,"video","capture",lc->video_conf.capture); if (lc->video_conf.cams) ms_free((void *)lc->video_conf.cams); + if (lc->video_conf.vdef) linphone_video_definition_unref(lc->video_conf.vdef); + if (lc->video_conf.preview_vdef) linphone_video_definition_unref(lc->video_conf.preview_vdef); } void _linphone_core_codec_config_write(LinphoneCore *lc){ diff --git a/coreapi/private.h b/coreapi/private.h index 8674ce0fb..1d8672cfe 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -139,8 +139,10 @@ struct _LinphoneCallParams{ PayloadType *audio_codec; /*audio codec currently in use */ PayloadType *video_codec; /*video codec currently in use */ PayloadType *text_codec; /*text codec currently in use */ - MSVideoSize sent_vsize; /* Size of the video currently being sent */ - MSVideoSize recv_vsize; /* Size of the video currently being received */ + MSVideoSize sent_vsize; /* DEPRECATED: Size of the video currently being sent */ + MSVideoSize recv_vsize; /* DEPRECATED: Size of the video currently being received */ + LinphoneVideoDefinition *sent_vdef; /* Definition of the video currently being sent */ + LinphoneVideoDefinition *recv_vdef; /* Definition of the video currrently being received */ float received_fps,sent_fps; int down_bw; int up_bw; @@ -929,6 +931,8 @@ typedef struct video_config{ const char **cams; MSVideoSize vsize; MSVideoSize preview_vsize; /*is 0,0 if no forced preview size is set, in which case vsize field above is used.*/ + LinphoneVideoDefinition *vdef; + LinphoneVideoDefinition *preview_vdef; float fps; bool_t capture; bool_t show_local; @@ -1783,7 +1787,8 @@ BELLE_SIP_TYPE_ID(LinphoneConferenceParams), BELLE_SIP_TYPE_ID(LinphoneConference), BELLE_SIP_TYPE_ID(LinphoneInfoMessage), BELLE_SIP_TYPE_ID(LinphonePayloadType), -BELLE_SIP_TYPE_ID(LinphoneRange) +BELLE_SIP_TYPE_ID(LinphoneRange), +BELLE_SIP_TYPE_ID(LinphoneVideoDefinition) BELLE_SIP_DECLARE_TYPES_END @@ -1921,6 +1926,21 @@ BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneErrorInfo); void linphone_core_report_call_log(LinphoneCore *lc, LinphoneCallLog *call_log); void linphone_core_report_early_failed_call(LinphoneCore *lc, LinphoneCallDir dir, LinphoneAddress *from, LinphoneAddress *to, LinphoneErrorInfo *ei); +struct _LinphoneVideoDefinition { + belle_sip_object_t base; + void *user_data; + unsigned int width; /**< The width of the video */ + unsigned int height; /**< The height of the video */ + char *name; /** The name of the video definition */ +}; + +BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneVideoDefinition); + +LinphoneVideoDefinition * linphone_video_definition_new(unsigned int width, unsigned int height, const char *name); + +LinphoneVideoDefinition * linphone_factory_find_supported_video_definition(const LinphoneFactory *factory, unsigned int width, unsigned int height); +LinphoneVideoDefinition * linphone_factory_find_supported_video_definition_by_name(const LinphoneFactory *factory, const char *name); + #ifdef __cplusplus } #endif diff --git a/coreapi/video_definition.c b/coreapi/video_definition.c new file mode 100644 index 000000000..ee68b76d1 --- /dev/null +++ b/coreapi/video_definition.c @@ -0,0 +1,111 @@ +/* +linphone +Copyright (C) 2010-2017 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#include "linphone/factory.h" +#include "linphone/video_definition.h" + +#include "private.h" + + +static void linphone_video_definition_destroy(LinphoneVideoDefinition *vdef) { + if (vdef->name) bctbx_free(vdef->name); +} + +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneVideoDefinition); + +BELLE_SIP_INSTANCIATE_VPTR(LinphoneVideoDefinition, belle_sip_object_t, + (belle_sip_object_destroy_t)linphone_video_definition_destroy, + NULL, // clone + NULL, // marshal + TRUE +); + + +LinphoneVideoDefinition * linphone_video_definition_new(unsigned int width, unsigned int height, const char *name) { + LinphoneVideoDefinition *vdef = belle_sip_object_new(LinphoneVideoDefinition); + vdef->width = width; + vdef->height = height; + if (name == NULL) { + vdef->name = bctbx_strdup_printf("%ux%u", width, height); + } else { + vdef->name = bctbx_strdup(name); + } + return vdef; +} + +LinphoneVideoDefinition * linphone_video_definition_ref(LinphoneVideoDefinition *vdef) { + belle_sip_object_ref(vdef); + return vdef; +} + +void linphone_video_definition_unref(LinphoneVideoDefinition *vdef) { + belle_sip_object_unref(vdef); +} + +void *linphone_video_definition_get_user_data(const LinphoneVideoDefinition *vdef) { + return vdef->user_data; +} + +void linphone_video_definition_set_user_data(LinphoneVideoDefinition *vdef, void *ud) { + vdef->user_data = ud; +} + + +unsigned int linphone_video_definition_get_width(const LinphoneVideoDefinition *vdef) { + return vdef->width; +} + +void linphone_video_definition_set_width(LinphoneVideoDefinition *vdef, unsigned int width) { + vdef->width = width; +} + +unsigned int linphone_video_definition_get_height(const LinphoneVideoDefinition *vdef) { + return vdef->height; +} + +void linphone_video_definition_set_height(LinphoneVideoDefinition *vdef, unsigned int height) { + vdef->height = height; +} + +void linphone_video_definition_set_definition(LinphoneVideoDefinition *vdef, unsigned int width, unsigned int height) { + vdef->width = width; + vdef->height = height; +} + +const char * linphone_video_definition_get_name(const LinphoneVideoDefinition *vdef) { + return vdef->name; +} + +void linphone_video_definition_set_name(LinphoneVideoDefinition *vdef, const char *name) { + if (vdef->name != NULL) bctbx_free(vdef->name); + vdef->name = bctbx_strdup(name); +} + +bool_t linphone_video_definition_equals(const LinphoneVideoDefinition *vdef1, const LinphoneVideoDefinition *vdef2) { + return (((vdef1->width == vdef2->width) && (vdef1->height == vdef2->height)) + || ((vdef1->width == vdef2->height) && (vdef1->height == vdef2->width))); +} + +bool_t linphone_video_definition_strict_equals(const LinphoneVideoDefinition *vdef1, const LinphoneVideoDefinition *vdef2) { + return (vdef1->width == vdef2->width) && (vdef1->height == vdef2->height); +} + +bool_t linphone_video_definition_is_undefined(const LinphoneVideoDefinition *vdef) { + return (vdef->width == 0) || (vdef->height == 0); +} diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 0534b57b1..54094d903 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -60,6 +60,7 @@ set(HEADER_FILES tunnel.h types.h vcard.h + video_definition.h wrapper_utils.h xmlrpc.h diff --git a/include/linphone/Makefile.am b/include/linphone/Makefile.am index 2aaf58f40..316f9b5e5 100644 --- a/include/linphone/Makefile.am +++ b/include/linphone/Makefile.am @@ -40,6 +40,7 @@ linphone_include_HEADERS=\ tunnel.h \ types.h \ vcard.h \ + video_definition.h \ wrapper_utils.h \ xmlrpc.h \ linphonecore.h \ diff --git a/include/linphone/call_params.h b/include/linphone/call_params.h index 838292583..3299b2242 100644 --- a/include/linphone/call_params.h +++ b/include/linphone/call_params.h @@ -132,12 +132,20 @@ LINPHONE_PUBLIC LinphonePrivacyMask linphone_call_params_get_privacy(const Linph */ LINPHONE_PUBLIC float linphone_call_params_get_received_framerate(const LinphoneCallParams *cp); +/** + * Get the definition of the received video. + * @param[in] cp LinphoneCallParams object + * @return The received LinphoneVideoDefinition + */ +LINPHONE_PUBLIC const LinphoneVideoDefinition * linphone_call_params_get_received_video_definition(const LinphoneCallParams *cp); + /** * Get the size of the video that is received. * @param[in] cp LinphoneCallParams object * @return The received video size or MS_VIDEO_SIZE_UNKNOWN if not available. + * @deprecated Use linphone_call_params_get_received_video_definition() instead */ -LINPHONE_PUBLIC MSVideoSize linphone_call_params_get_received_video_size(const LinphoneCallParams *cp); +LINPHONE_PUBLIC LINPHONE_DEPRECATED MSVideoSize linphone_call_params_get_received_video_size(const LinphoneCallParams *cp); /** * Get the path for the audio recording of the call. @@ -160,12 +168,20 @@ LINPHONE_PUBLIC const char * linphone_call_params_get_rtp_profile(const Linphone */ LINPHONE_PUBLIC float linphone_call_params_get_sent_framerate(const LinphoneCallParams *cp); +/** + * Get the definition of the sent video. + * @param[in] cp LinphoneCallParams object + * @return The sent LinphoneVideoDefinition + */ +LINPHONE_PUBLIC const LinphoneVideoDefinition * linphone_call_params_get_sent_video_definition(const LinphoneCallParams *cp); + /** * Gets the size of the video that is sent. * @param[in] cp LinphoneCalParams object * @return The sent video size or MS_VIDEO_SIZE_UNKNOWN if not available. + * @deprecated Use linphone_call_params_get_sent_video_definition() instead */ -LINPHONE_PUBLIC MSVideoSize linphone_call_params_get_sent_video_size(const LinphoneCallParams *cp); +LINPHONE_PUBLIC LINPHONE_DEPRECATED MSVideoSize linphone_call_params_get_sent_video_size(const LinphoneCallParams *cp); /** * Get the session name of the media session (ie in SDP). diff --git a/include/linphone/core.h b/include/linphone/core.h index 3a8ed777e..93fd4f422 100644 --- a/include/linphone/core.h +++ b/include/linphone/core.h @@ -62,6 +62,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "linphone/proxy_config.h" #include "linphone/ringtoneplayer.h" #include "linphone/vcard.h" +#include "linphone/video_definition.h" #include "linphone/xmlrpc.h" @@ -2816,7 +2817,7 @@ LINPHONE_PUBLIC void linphone_core_set_ring_during_incoming_early_media(Linphone /** * Tells whether the ring play is enabled during an incoming early media call. * @param[in] lc #LinphoneCore object - * @ingroup media_paramaters + * @ingroup media_parameters */ LINPHONE_PUBLIC bool_t linphone_core_get_ring_during_incoming_early_media(const LinphoneCore *lc); @@ -3118,8 +3119,18 @@ LINPHONE_PUBLIC const LinphoneVideoPolicy *linphone_core_get_video_policy(const /** * Returns the zero terminated table of supported video resolutions. * @ingroup media_parameters + * @deprecated Use linphone_factory_get_supported_video_definitions() instead **/ -LINPHONE_PUBLIC const MSVideoSizeDef *linphone_core_get_supported_video_sizes(LinphoneCore *lc); +LINPHONE_PUBLIC LINPHONE_DEPRECATED const MSVideoSizeDef *linphone_core_get_supported_video_sizes(LinphoneCore *lc); + +/** + * Set the preferred video definition for the stream that is captured and sent to the remote party. + * All standard video definitions are accepted on the receive path. + * @param[in] lc LinphoneCore object + * @param[in] vdef LinphoneVideoDefinition object + * @ingroup media_parameters + */ +LINPHONE_PUBLIC void linphone_core_set_preferred_video_definition(LinphoneCore *lc, LinphoneVideoDefinition *vdef); /** * Sets the preferred video size. @@ -3127,8 +3138,20 @@ LINPHONE_PUBLIC const MSVideoSizeDef *linphone_core_get_supported_video_sizes(Li * This applies only to the stream that is captured and sent to the remote party, * since we accept all standard video size on the receive path. * @ingroup media_parameters + * @deprecated Use linphone_core_set_preferred_video_definition() instead **/ -LINPHONE_PUBLIC void linphone_core_set_preferred_video_size(LinphoneCore *lc, MSVideoSize vsize); +LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_core_set_preferred_video_size(LinphoneCore *lc, MSVideoSize vsize); + +/** + * Set the video definition for the captured (preview) video. + * This method is for advanced usage where a video capture must be set independently of the definition of the stream actually sent through the call. + * This allows for example to have the preview window in High Definition even if due to bandwidth constraint the sent video definition is small. + * Using this feature increases the CPU consumption, since a rescaling will be done internally. + * @param[in] lc LinphoneCore object + * @param[in] vdef LinphoneVideoDefinition object + * @ingroup media_parameters + */ +LINPHONE_PUBLIC void linphone_core_set_preview_video_definition(LinphoneCore *lc, LinphoneVideoDefinition *vdef); /** * Sets the video size for the captured (preview) video. @@ -3138,25 +3161,47 @@ LINPHONE_PUBLIC void linphone_core_set_preferred_video_size(LinphoneCore *lc, MS * @ingroup media_parameters * @param lc the linphone core * @param vsize the video resolution choosed for capuring and previewing. It can be (0,0) to not request any specific preview size and let the core optimize the processing. + * @deprecated Use linphone_core_set_preview_video_definition() instead **/ -LINPHONE_PUBLIC void linphone_core_set_preview_video_size(LinphoneCore *lc, MSVideoSize vsize); +LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_core_set_preview_video_size(LinphoneCore *lc, MSVideoSize vsize); /** * Sets the preview video size by its name. See linphone_core_set_preview_video_size() for more information about this feature. * * Video resolution names are: qcif, svga, cif, vga, 4cif, svga ... * @ingroup media_parameters + * @deprecated Use linphone_factory_create_video_definition_from_name() and linphone_core_set_preview_video_definition() instead **/ LINPHONE_PUBLIC void linphone_core_set_preview_video_size_by_name(LinphoneCore *lc, const char *name); +/** + * Get the definition of the captured video. + * @param[in] lc LinphoneCore object + * @return The captured LinphoneVideoDefinition if it was previously set by linphone_core_set_preview_video_definition(), otherwise a 0x0 LinphoneVideoDefinition. + * @see linphone_core_set_preview_video_definition() + * @ingroup media_parameters + */ +LINPHONE_PUBLIC const LinphoneVideoDefinition * linphone_core_get_preview_video_definition(const LinphoneCore *lc); + /** * Returns video size for the captured video if it was previously set by linphone_core_set_preview_video_size(), otherwise returns a 0,0 size. * @see linphone_core_set_preview_video_size() * @ingroup media_parameters * @param lc the core * @return a MSVideoSize + * @deprecated Use linphone_core_get_preview_video_definition() instead **/ -LINPHONE_PUBLIC MSVideoSize linphone_core_get_preview_video_size(const LinphoneCore *lc); +LINPHONE_PUBLIC LINPHONE_DEPRECATED MSVideoSize linphone_core_get_preview_video_size(const LinphoneCore *lc); + +/** + * Get the effective video definition provided by the camera for the captured video. + * When preview is disabled or not yet started this function returns a 0x0 video definition. + * @param[in] lc LinphoneCore object + * @return The captured LinphoneVideoDefinition + * @ingroup media_parameters + * @see linphone_core_set_preview_video_definition() + */ +LINPHONE_PUBLIC LinphoneVideoDefinition * linphone_core_get_current_preview_video_definition(const LinphoneCore *lc); /** * Returns the effective video size for the captured video as provided by the camera. @@ -3165,20 +3210,30 @@ LINPHONE_PUBLIC MSVideoSize linphone_core_get_preview_video_size(const LinphoneC * @ingroup media_parameters * @param lc the core * @return a MSVideoSize + * @deprecated Use linphone_core_get_current_preview_video_definition() instead **/ -LINPHONE_PUBLIC MSVideoSize linphone_core_get_current_preview_video_size(const LinphoneCore *lc); +LINPHONE_PUBLIC LINPHONE_DEPRECATED MSVideoSize linphone_core_get_current_preview_video_size(const LinphoneCore *lc); + +/** + * Get the preferred video definition for the stream that is captured and sent to the remote party. + * @param[in] lc LinphoneCore object + * @return The preferred LinphoneVideoDefinition + * @ingroup media_parameters + */ +LINPHONE_PUBLIC const LinphoneVideoDefinition * linphone_core_get_preferred_video_definition(const LinphoneCore *lc); /** * Returns the current preferred video size for sending. - * * @ingroup media_parameters + * @deprecated Use linphone_core_get_preferred_video_definition() instead **/ -LINPHONE_PUBLIC MSVideoSize linphone_core_get_preferred_video_size(const LinphoneCore *lc); +LINPHONE_PUBLIC LINPHONE_DEPRECATED MSVideoSize linphone_core_get_preferred_video_size(const LinphoneCore *lc); /** * Get the name of the current preferred video size for sending. * @param[in] lc #LinphoneCore object. * @return A string containing the name of the current preferred video size (to be freed with ms_free()). + * @deprecated Use linphone_core_get_preferred_video_defintion() and linphone_video_definition_get_name() instead */ LINPHONE_PUBLIC char * linphone_core_get_preferred_video_size_name(const LinphoneCore *lc); @@ -3189,6 +3244,7 @@ LINPHONE_PUBLIC char * linphone_core_get_preferred_video_size_name(const Linphon * that it takes the name of the video resolution as input. * Video resolution names are: qcif, svga, cif, vga, 4cif, svga ... * @ingroup media_parameters + * @deprecated Use linphone_factory_create_video_definition_from_name() and linphone_core_set_preferred_video_definition() instead **/ LINPHONE_PUBLIC void linphone_core_set_preferred_video_size_by_name(LinphoneCore *lc, const char *name); @@ -4140,7 +4196,7 @@ LINPHONE_PUBLIC const char ** linphone_core_get_supported_file_formats(LinphoneC * @see linphone_core_get_supported_file_formats * @param lc A #LinphoneCore object * @param fmt The format extension (wav, mkv). - * @ingroup media_paramaters + * @ingroup media_parameters **/ LINPHONE_PUBLIC bool_t linphone_core_file_format_supported(LinphoneCore *lc, const char *fmt); diff --git a/include/linphone/factory.h b/include/linphone/factory.h index 9a3c12f0f..40f784374 100644 --- a/include/linphone/factory.h +++ b/include/linphone/factory.h @@ -125,6 +125,30 @@ LINPHONE_PUBLIC LinphoneCallCbs * linphone_factory_create_call_cbs(const Linphon */ LINPHONE_PUBLIC LinphoneVcard *linphone_factory_create_vcard(LinphoneFactory *factory); +/** + * Create a LinphoneVideoDefinition from a given width and height + * @param[in] factory LinphoneFactory singleton object + * @param[in] width The width of the created video definition + * @param[in] height The height of the created video definition + * @return A new LinphoneVideoDefinition object + */ +LINPHONE_PUBLIC LinphoneVideoDefinition * linphone_factory_create_video_definition(const LinphoneFactory *factory, unsigned int width, unsigned int height); + +/** + * Create a LinphoneVideoDefinition from a given standard definition name + * @param[in] factory LinphoneFactory singleton object + * @param[in] name The standard definition name of the video definition to create + * @return A new LinphoneVideoDefinition object + */ +LINPHONE_PUBLIC LinphoneVideoDefinition * linphone_factory_create_video_definition_from_name(const LinphoneFactory *factory, const char *name); + +/** + * Get the list of standard video definitions supported by Linphone. + * @param[in] factory LinphoneFactory singleton object + * @return \bctbx_list{LinphoneVideoDefinition} + */ +LINPHONE_PUBLIC const bctbx_list_t * linphone_factory_get_supported_video_definitions(const LinphoneFactory *factory); + /** * Get the top directory where the resources are located. * @param[in] factory LinphoneFactory object diff --git a/include/linphone/types.h b/include/linphone/types.h index 7ee2e82ce..4fb6244b1 100644 --- a/include/linphone/types.h +++ b/include/linphone/types.h @@ -1105,6 +1105,12 @@ typedef enum _LinphoneUpnpState { */ typedef struct _LinphoneVcard LinphoneVcard; +/** + * The LinphoneVideoDefinition object represents a video definition, eg. its width and its height. + * @ingroup media_parameters + */ +typedef struct _LinphoneVideoDefinition LinphoneVideoDefinition; + /** * Structure describing policy regarding video streams establishments. * @ingroup media_parameters diff --git a/include/linphone/video_definition.h b/include/linphone/video_definition.h new file mode 100644 index 000000000..5d5bb6220 --- /dev/null +++ b/include/linphone/video_definition.h @@ -0,0 +1,146 @@ +/* +video_definition.h +Copyright (C) 2010-2017 Belledonne Communications SARL + +This program is free software; you can redistribute it and/or +modify it under the terms of the GNU General Public License +as published by the Free Software Foundation; either version 2 +of the License, or (at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ + +#ifndef LINPHONE_VIDEO_DEFINITION_H_ +#define LINPHONE_VIDEO_DEFINITION_H_ + + +#include "linphone/types.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +/** + * @addtogroup media_parameters + * @{ + */ + +/** + * Acquire a reference to the video definition. + * @param[in] vdef LinphoneVideoDefinition object. + * @return The same LinphoneVideoDefinition object. +**/ +LINPHONE_PUBLIC LinphoneVideoDefinition * linphone_video_definition_ref(LinphoneVideoDefinition *vdef); + +/** + * Release reference to the video definition. + * @param[in] vdef LinphoneVideoDefinition object. +**/ +LINPHONE_PUBLIC void linphone_video_definition_unref(LinphoneVideoDefinition *vdef); + +/** + * Retrieve the user pointer associated with the video definition. + * @param[in] vdef LinphoneVideoDefinition object. + * @return The user pointer associated with the video definition. +**/ +LINPHONE_PUBLIC void *linphone_video_definition_get_user_data(const LinphoneVideoDefinition *vdef); + +/** + * Assign a user pointer to the video definition. + * @param[in] vdef LinphoneVideoDefinition object. + * @param[in] ud The user pointer to associate with the video definition. +**/ +LINPHONE_PUBLIC void linphone_video_definition_set_user_data(LinphoneVideoDefinition *vdef, void *ud); + +/** + * Get the width of the video definition. + * @param[in] vdef LinphoneVideoDefinition object + * @return The width of the video definition + */ +LINPHONE_PUBLIC unsigned int linphone_video_definition_get_width(const LinphoneVideoDefinition *vdef); + +/** + * Set the width of the video definition. + * @param[in] vdef LinphoneVideoDefinition object + * @param[in] width The width of the video definition + */ +LINPHONE_PUBLIC void linphone_video_definition_set_width(LinphoneVideoDefinition *vdef, unsigned int width); + +/** + * Get the height of the video definition. + * @param[in] vdef LinphoneVideoDefinition object + * @return The height of the video definition + */ +LINPHONE_PUBLIC unsigned int linphone_video_definition_get_height(const LinphoneVideoDefinition *vdef); + +/** + * Set the height of the video definition. + * @param[in] vdef LinphoneVideoDefinition object + * @param[in] height The height of the video definition + */ +LINPHONE_PUBLIC void linphone_video_definition_set_height(LinphoneVideoDefinition *vdef, unsigned int height); + +/** + * Set the width and the height of the video definition. + * @param[in] vdef LinphoneVideoDefinition object + * @param[in] width The width of the video definition + * @param[in] height The height of the video definition + */ +void linphone_video_definition_set_definition(LinphoneVideoDefinition *vdef, unsigned int width, unsigned int height); + +/** + * Get the name of the video definition. + * @param[in] vdef LinphoneVideoDefinition object + * @return The name of the video definition + */ +LINPHONE_PUBLIC const char * linphone_video_definition_get_name(const LinphoneVideoDefinition *vdef); + +/** + * Set the name of the video definition. + * @param[in] vdef LinphoneVideoDefinition object + * @param[in] name The name of the video definition + */ +LINPHONE_PUBLIC void linphone_video_definition_set_name(LinphoneVideoDefinition *vdef, const char *name); + +/** + * Tells whether two LinphoneVideoDefinition objects are equal (the widths and the heights are the same but can be switched). + * @param[in] vdef1 LinphoneVideoDefinition object + * @param[in] vdef2 LinphoneVideoDefinition object + * @return A boolean value telling whether the two LinphoneVideoDefinition objects are equal. + */ +bool_t linphone_video_definition_equals(const LinphoneVideoDefinition *vdef1, const LinphoneVideoDefinition *vdef2); + +/** + * Tells whether two LinphoneVideoDefinition objects are strictly equal (the widths are the same and the heights are the same). + * @param[in] vdef1 LinphoneVideoDefinition object + * @param[in] vdef2 LinphoneVideoDefinition object + * @return A boolean value telling whether the two LinphoneVideoDefinition objects are strictly equal. + */ +bool_t linphone_video_definition_strict_equals(const LinphoneVideoDefinition *vdef1, const LinphoneVideoDefinition *vdef2); + +/** + * Tells whether a LinphoneVideoDefinition is undefined. + * @param[in] vdef LinphoneVideoDefinition object + * @return A boolean value telling whether the LinphoneVideoDefinition is undefined. + */ +bool_t linphone_video_definition_is_undefined(const LinphoneVideoDefinition *vdef); + +/** + * @} + */ + + +#ifdef __cplusplus +} +#endif + +#endif /* LINPHONE_VIDEO_DEFINITION_H_ */ diff --git a/wrappers/cpp/tools.hh b/wrappers/cpp/tools.hh index f46e398eb..175af14cf 100644 --- a/wrappers/cpp/tools.hh +++ b/wrappers/cpp/tools.hh @@ -100,7 +100,7 @@ namespace linphone { static std::list bctbxListToCppList(const ::bctbx_list_t *bctbxList) { std::list cppList; for(const bctbx_list_t *it = bctbx_list_first_elem(bctbxList); it != NULL; it = bctbx_list_next(it)) { - cppList->push_back(T(it->data)); + cppList.push_back(T(it->data)); } return cppList; } From be6603fd94901ee6afbebe0accd4dcd078ffca13 Mon Sep 17 00:00:00 2001 From: Erwan Croze Date: Thu, 13 Apr 2017 15:11:54 +0200 Subject: [PATCH 34/70] Add new xml file loading for dynamic conf --- coreapi/account_creator.c | 37 ++++++++++++++++ coreapi/linphonecore_jni.cc | 16 +++++++ coreapi/lpconfig.c | 43 ++++++++++++++++--- coreapi/remote_provisioning.c | 22 +--------- include/linphone/account_creator.h | 9 +++- include/linphone/lpconfig.h | 11 ++++- java/common/org/linphone/core/LpConfig.java | 22 ++++++---- java/impl/org/linphone/core/LpConfigImpl.java | 18 +++++--- 8 files changed, 134 insertions(+), 44 deletions(-) diff --git a/coreapi/account_creator.c b/coreapi/account_creator.c index 574baf34f..cb859f163 100644 --- a/coreapi/account_creator.c +++ b/coreapi/account_creator.c @@ -19,6 +19,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "linphone/account_creator.h" #include "linphone/core.h" +#include "linphone/lpconfig.h" #include "private.h" #if !_WIN32 #include "regex.h" @@ -107,6 +108,42 @@ static bool_t is_matching_regex(const char *entry, const char* regex) { #endif } +LinphoneProxyConfig * linphone_account_creator_configure_proxy_config(const LinphoneAccountCreator *creator) { + LinphoneAuthInfo *info; + LinphoneProxyConfig *cfg = linphone_core_create_proxy_config(creator->core); + char *identity_str = _get_identity(creator); + LinphoneAddress *identity = linphone_address_new(identity_str); + ms_free(identity_str); + + linphone_proxy_config_set_identity_address(cfg, identity); + if (creator->phone_country_code) { + linphone_proxy_config_set_dial_prefix(cfg, creator->phone_country_code); + } else if (creator->phone_number) { + int dial_prefix_number = linphone_dial_plan_lookup_ccc_from_e164(creator->phone_number); + char buff[4]; + snprintf(buff, sizeof(buff), "%d", dial_prefix_number); + linphone_proxy_config_set_dial_prefix(cfg, buff); + } + + info = linphone_auth_info_new(linphone_address_get_username(identity), // username + NULL, //user id + creator->password, // passwd + creator->password ? NULL : creator->ha1, // ha1 + !creator->password && creator->ha1 ? linphone_address_get_domain(identity) : NULL, // realm - assumed to be domain + linphone_address_get_domain(identity) // domain + ); + linphone_core_add_auth_info(creator->core, info); + linphone_address_unref(identity); + + if (linphone_core_add_proxy_config(creator->core, cfg) != -1) { + linphone_core_set_default_proxy(creator->core, cfg); + return cfg; + } + + linphone_core_remove_auth_info(creator->core, info); + return NULL; +} + LinphoneProxyConfig * linphone_account_creator_configure(const LinphoneAccountCreator *creator) { LinphoneAuthInfo *info; LinphoneProxyConfig *cfg = creator->proxy_cfg; diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index 672e5690a..ae08613cd 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -6000,6 +6000,13 @@ extern "C" void Java_org_linphone_core_LpConfigImpl_sync(JNIEnv *env, jobject th lp_config_sync(lp); } +extern "C" void Java_org_linphone_core_LpConfigImpl_loadXmlFile(JNIEnv *env, jobject thiz, jlong lpc, jstring jfilename) { + const char *filename = GetStringUTFChars(env, jfilename); + LpConfig *lp = (LpConfig *)lpc; + linphone_config_load_from_xml_file(lp, filename, NULL); + ReleaseStringUTFChars(env, jfilename, filename); +} + extern "C" void Java_org_linphone_core_LpConfigImpl_delete(JNIEnv *env, jobject thiz, jlong lpc) { LpConfig *lp = (LpConfig *)lpc; lp_config_destroy(lp); @@ -8748,6 +8755,15 @@ extern "C" jint Java_org_linphone_core_LinphoneAccountCreatorImpl_updatePassword return status; } +extern "C" jobject Java_org_linphone_core_LinphoneAccountCreatorImpl_configureProxyConfig(JNIEnv *env, jobject thiz, jlong ptr) { + LinphoneAccountCreator *account_creator = (LinphoneAccountCreator *)ptr; + LinphoneProxyConfig *lpc = linphone_account_creator_configure(account_creator); + LinphoneCore *lc = account_creator->core; + LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc); + LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table); + return getProxy(env, lpc, lcData->core); +} + extern "C" jobject Java_org_linphone_core_LinphoneAccountCreatorImpl_configure(JNIEnv *env, jobject thiz, jlong ptr) { LinphoneAccountCreator *account_creator = (LinphoneAccountCreator *)ptr; LinphoneProxyConfig *lpc = linphone_account_creator_configure(account_creator); diff --git a/coreapi/lpconfig.c b/coreapi/lpconfig.c index 1e55d02d9..1c87904d6 100644 --- a/coreapi/lpconfig.c +++ b/coreapi/lpconfig.c @@ -27,6 +27,7 @@ #include "private.h" #include "bctoolbox/vfs.h" #include "belle-sip/object.h" +#include "xml2lpc.h" #include #include @@ -402,7 +403,7 @@ LpConfig * linphone_config_new_from_buffer(const char *buffer){ static int _linphone_config_init_from_files(LinphoneConfig *lpconfig, const char *config_filename, const char *factory_config_filename) { lpconfig->g_bctbx_vfs = bctbx_vfs_get_default(); - + if (config_filename!=NULL){ if(ortp_file_exist(config_filename) == 0) { lpconfig->filename=lp_realpath(config_filename, NULL); @@ -480,6 +481,34 @@ LinphoneStatus linphone_config_read_file(LpConfig *lpconfig, const char *filenam return -1; } +char* linphone_config_load_from_xml_file(LpConfig *lpc, const char *filename, void* ctx) { + xml2lpc_context *context = NULL; + char* path = lp_realpath(filename, NULL); + char* error_msg = NULL; + + if (path) { + int result = -1; + context = xml2lpc_context_new(NULL, ctx); + result = xml2lpc_set_xml_string(context, path); + if (result == 0) { + result = xml2lpc_convert(context, lpc); + if (result == 0) { + // if the remote provisioning added a proxy config and none was set before, set it + if (lp_config_has_section(lpc, "proxy_0") && lp_config_get_int(lpc, "sip", "default_proxy", -1) == -1){ + lp_config_set_int(lpc, "sip", "default_proxy", 0); + } + lp_config_sync(lpc); + } else { + error_msg = "xml to lpc failed"; + } + } else { + error_msg = "invalid xml"; + } + } + if (context) xml2lpc_context_destroy(context); + return error_msg; +} + void lp_item_set_value(LpItem *item, const char *value){ if (item->value != value) { char *prev_value=item->value; @@ -758,14 +787,14 @@ void linphone_config_set_skip_flag_for_section(LpConfig *lpconfig, const char *s void lp_item_write(LpItem *item, LpConfig *lpconfig){ int ret =-1 ; - if (item->is_comment){ + if (item->is_comment){ ret =bctbx_file_fprintf(lpconfig->pFile, 0, "%s\n",item->value); } else if (item->value && item->value[0] != '\0' ){ ret =bctbx_file_fprintf(lpconfig->pFile, 0, "%s=%s\n",item->key,item->value); } - + else { ms_warning("Not writing item %s to file, it is empty", item->key); } @@ -792,7 +821,7 @@ void lp_section_write(LpSection *sec,LpConfig *lpconfig){ bctbx_list_for_each2(sec->items, (void (*)(void*, void*))lp_item_write, (void *)lpconfig); if (bctbx_file_fprintf(lpconfig->pFile, 0, "\n")< 0) ms_error("lp_section_write : write error"); - + } LinphoneStatus linphone_config_sync(LpConfig *lpconfig){ @@ -811,7 +840,7 @@ LinphoneStatus linphone_config_sync(LpConfig *lpconfig){ lpconfig->readonly = TRUE; return -1; } - + bctbx_list_for_each2(lpconfig->sections,(void (*)(void *,void*))lp_section_write,(void *)lpconfig); bctbx_file_close(pFile); @@ -1018,7 +1047,7 @@ LinphoneStatus linphone_config_read_relative_file(const LpConfig *lpconfig, cons if(bctbx_file_read(pFile, data, 1, (off_t)max_length) < 0){ ms_error("%s could not be loaded.", realfilepath); goto err; - + } bctbx_file_close(pFile); @@ -1109,7 +1138,7 @@ int linphone_config_has_entry(const LpConfig *lpconfig, const char *section, con return lp_section_find_item(sec,key) != NULL; } else return FALSE; - + } BELLE_SIP_INSTANCIATE_VPTR( diff --git a/coreapi/remote_provisioning.c b/coreapi/remote_provisioning.c index 0bb40595b..9da88531a 100644 --- a/coreapi/remote_provisioning.c +++ b/coreapi/remote_provisioning.c @@ -18,6 +18,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "private.h" #include "xml2lpc.h" +#include "linphone/lpconfig.h" #define XML2LPC_CALLBACK_BUFFER_SIZE 1024 @@ -34,27 +35,8 @@ static void xml2lpc_callback(void *ctx, xml2lpc_log_level level, const char *fmt } static void linphone_remote_provisioning_apply(LinphoneCore *lc, const char *xml) { - xml2lpc_context *context = xml2lpc_context_new(xml2lpc_callback, lc); - int result = xml2lpc_set_xml_string(context, xml); - char * error_msg = NULL; - if (result == 0) { - LpConfig * lpc = linphone_core_get_config(lc); - result = xml2lpc_convert(context, lpc); - if (result == 0) { - // if the remote provisioning added a proxy config and none was set before, set it - if (lp_config_has_section(lpc, "proxy_0") && lp_config_get_int(lpc, "sip", "default_proxy", -1) == -1){ - lp_config_set_int(lpc, "sip", "default_proxy", 0); - } - lp_config_sync(lpc); + char* error_msg = linphone_config_load_from_xml_file(linphone_core_get_config(lc), xml, lc); - } else { - error_msg = "xml to lpc failed"; - } - } else { - error_msg = "invalid xml"; - } - - xml2lpc_context_destroy(context); linphone_configuring_terminated(lc ,error_msg ? LinphoneConfiguringFailed : LinphoneConfiguringSuccessful , error_msg); diff --git a/include/linphone/account_creator.h b/include/linphone/account_creator.h index a4bfca7c4..81fe0aca7 100644 --- a/include/linphone/account_creator.h +++ b/include/linphone/account_creator.h @@ -491,12 +491,19 @@ LINPHONE_PUBLIC void linphone_account_creator_cbs_set_update_account(LinphoneAcc /************************** End Account Creator Cbs **************************/ +/** + * + * @param[in] creator LinphoneAccountCreator object + * @return A LinphoneProxyConfig object if successful, NULL otherwise + **/ +LINPHONE_PUBLIC LinphoneProxyConfig * linphone_account_creator_create_proxy_config(const LinphoneAccountCreator *creator); + /** * Configure an account (create a proxy config and authentication info for it). * @param[in] creator LinphoneAccountCreator object * @return A LinphoneProxyConfig object if successful, NULL otherwise **/ -LINPHONE_PUBLIC LinphoneProxyConfig * linphone_account_creator_configure(const LinphoneAccountCreator *creator); +LINPHONE_DEPRECATED LINPHONE_PUBLIC LinphoneProxyConfig * linphone_account_creator_configure(const LinphoneAccountCreator *creator); /** * @} diff --git a/include/linphone/lpconfig.h b/include/linphone/lpconfig.h index d178dab2d..3f8893e65 100644 --- a/include/linphone/lpconfig.h +++ b/include/linphone/lpconfig.h @@ -82,6 +82,15 @@ LINPHONE_PUBLIC LinphoneConfig * linphone_config_new_with_factory(const char *co */ LINPHONE_PUBLIC LinphoneStatus linphone_config_read_file(LinphoneConfig *lpconfig, const char *filename); +/** + * Reads a xml config file and fill the LinphoneConfig with the read config dynamic values. + * @ingroup misc + * @param lpconfig The LinphoneConfig object to fill with the content of the file + * @param filename The filename of the config file to read to fill the LinphoneConfig + * @param ctx The context given to xml2lpc callback + */ +LINPHONE_PUBLIC char* linphone_config_load_from_xml_file(LpConfig *lpc, const char *filename, void* ctx); + /** * Retrieves a configuration item as a string, given its section, key, and default value. * @@ -198,7 +207,7 @@ LINPHONE_PUBLIC int linphone_config_has_entry(const LinphoneConfig *lpconfig, co * @param[in] key **/ LINPHONE_PUBLIC void linphone_config_clean_entry(LinphoneConfig *lpconfig, const char *section, const char *key); - + /** * Returns the list of sections' names in the LinphoneConfig. * @param[in] lpconfig The LinphoneConfig object diff --git a/java/common/org/linphone/core/LpConfig.java b/java/common/org/linphone/core/LpConfig.java index 4ddc7b2d5..ec925626b 100644 --- a/java/common/org/linphone/core/LpConfig.java +++ b/java/common/org/linphone/core/LpConfig.java @@ -21,12 +21,12 @@ package org.linphone.core; /** * The LpConfig object is used to manipulate a configuration file. - * + * *
  * The format of the configuration file is a .ini like format:
  * - sections are defined in []
  * - each section contains a sequence of key=value pairs.
- * 
+ *
  * Example:
  * [sound]
  * echocanceler=1
@@ -47,7 +47,7 @@ public interface LpConfig {
 	 * @param value the value of the setting
 	 */
 	void setInt(String section, String key, int value);
-	
+
 	/**
 	 * Sets an float config item
 	 * @param section the section in the lpconfig
@@ -80,7 +80,7 @@ public interface LpConfig {
 	 * @param max the max of the range
 	 */
 	void setIntRange(String section, String key, int min, int max);
-	
+
 	/**
 	 * Gets a int from the config
 	 * @param section the section in the lpconfig
@@ -89,7 +89,7 @@ public interface LpConfig {
 	 * @return the value of the setting or the default value if not set
 	 */
 	int getInt(String section, String key, int defaultValue);
-	
+
 	/**
 	 * Gets a float from the config
 	 * @param section the section in the lpconfig
@@ -98,7 +98,7 @@ public interface LpConfig {
 	 * @return the value of the setting or the default value if not set
 	 */
 	float getFloat(String section, String key, float defaultValue);
-	
+
 	/**
 	 * Gets a boolean from the config
 	 * @param section the section in the lpconfig
@@ -107,7 +107,7 @@ public interface LpConfig {
 	 * @return the value of the setting or the default value if not set
 	 */
 	boolean getBool(String section, String key, boolean defaultValue);
-	
+
 	/**
 	 * Gets a string from the config
 	 * @param section the section in the lpconfig
@@ -116,7 +116,7 @@ public interface LpConfig {
 	 * @return the value of the setting or the default value if not set
 	 */
 	String getString(String section, String key, String defaultValue);
-	
+
 	/**
 	 * Gets a int range from the config
 	 * @param section the section in the lpconfig
@@ -129,4 +129,10 @@ public interface LpConfig {
 	 * Synchronize LpConfig with file
 	 */
 	void sync();
+
+	/**
+	 * Load the value of the given xml file
+	 * @param fileName the name of the xml file
+	 */
+	void loadXmlFile(String fileName);
 }
diff --git a/java/impl/org/linphone/core/LpConfigImpl.java b/java/impl/org/linphone/core/LpConfigImpl.java
index a8d6d6b04..285795f38 100644
--- a/java/impl/org/linphone/core/LpConfigImpl.java
+++ b/java/impl/org/linphone/core/LpConfigImpl.java
@@ -22,40 +22,40 @@ class LpConfigImpl implements LpConfig {
 
 	private long nativePtr;
 	boolean ownPtr = false;
-	
+
 	public LpConfigImpl(long ptr) {
 		nativePtr = ptr;
 	}
-	
+
 	private native long newLpConfigImpl(String file);
 	private native long newLpConfigImplFromBuffer(String buffer);
 	private native void delete(long ptr);
-	
+
 	@Deprecated
 	public LpConfigImpl(String file) {
 		nativePtr = newLpConfigImpl(file);
 		ownPtr = true;
 	}
-	
+
 	private LpConfigImpl() {
 		nativePtr = -1;
 		ownPtr = false;
 	}
-	
+
 	public static LpConfigImpl fromFile(String file) {
 		LpConfigImpl impl = new LpConfigImpl();
 		impl.nativePtr = impl.newLpConfigImpl(file);
 		impl.ownPtr = true;
 		return impl;
 	}
-	
+
 	public static LpConfigImpl fromBuffer(String buffer) {
 		LpConfigImpl impl = new LpConfigImpl();
 		impl.nativePtr = impl.newLpConfigImplFromBuffer(buffer);
 		impl.ownPtr = true;
 		return impl;
 	}
-	
+
 	protected void finalize() throws Throwable {
 		if(ownPtr) {
 			delete(nativePtr);
@@ -128,4 +128,8 @@ class LpConfigImpl implements LpConfig {
 		return getIntRange(nativePtr, section, key, defaultMin, defaultMax);
 	}
 
+	private native void loadXmlFile(long ptr, String fileName);
+	public void loadXmlFile(String fileName) {
+		loadXmlFile(nativePtr, fileName);
+	}
 }

From 59c56393f6c625a9ba112e6f5aca4f2a0c0e08f0 Mon Sep 17 00:00:00 2001
From: Erwan Croze 
Date: Thu, 13 Apr 2017 16:21:24 +0200
Subject: [PATCH 35/70] Add new rcfile for test

---
 coreapi/linphonecore_jni.cc        | 11 +---------
 coreapi/lpconfig.c                 |  4 ++--
 coreapi/remote_provisioning.c      |  2 +-
 include/linphone/lpconfig.h        |  3 ++-
 tester/CMakeLists.txt              |  1 +
 tester/Makefile.am                 |  1 +
 tester/proxy_config_tester.c       | 13 ++++++++++--
 tester/rcfiles/assistant_create.rc | 32 ++++++++++++++++++++++++++++++
 8 files changed, 51 insertions(+), 16 deletions(-)
 create mode 100644 tester/rcfiles/assistant_create.rc

diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc
index ae08613cd..d757b7a70 100644
--- a/coreapi/linphonecore_jni.cc
+++ b/coreapi/linphonecore_jni.cc
@@ -6003,7 +6003,7 @@ extern "C" void Java_org_linphone_core_LpConfigImpl_sync(JNIEnv *env, jobject th
 extern "C" void Java_org_linphone_core_LpConfigImpl_loadXmlFile(JNIEnv *env, jobject thiz, jlong lpc, jstring jfilename) {
 	const char *filename = GetStringUTFChars(env, jfilename);
 	LpConfig *lp = (LpConfig *)lpc;
-	linphone_config_load_from_xml_file(lp, filename, NULL);
+	linphone_config_load_from_xml_file(lp, filename, NULL, NULL);
 	ReleaseStringUTFChars(env, jfilename, filename);
 }
 
@@ -8755,15 +8755,6 @@ extern "C" jint Java_org_linphone_core_LinphoneAccountCreatorImpl_updatePassword
     return status;
 }
 
-extern "C" jobject Java_org_linphone_core_LinphoneAccountCreatorImpl_configureProxyConfig(JNIEnv *env, jobject thiz, jlong ptr) {
-	LinphoneAccountCreator *account_creator = (LinphoneAccountCreator *)ptr;
-	LinphoneProxyConfig  *lpc = linphone_account_creator_configure(account_creator);
-	LinphoneCore *lc = account_creator->core;
-	LinphoneCoreVTable *table = linphone_core_get_current_vtable(lc);
-	LinphoneCoreData* lcData = (LinphoneCoreData*)linphone_core_v_table_get_user_data(table);
-	return getProxy(env, lpc, lcData->core);
-}
-
 extern "C" jobject Java_org_linphone_core_LinphoneAccountCreatorImpl_configure(JNIEnv *env, jobject thiz, jlong ptr) {
 	LinphoneAccountCreator *account_creator = (LinphoneAccountCreator *)ptr;
 	LinphoneProxyConfig  *lpc = linphone_account_creator_configure(account_creator);
diff --git a/coreapi/lpconfig.c b/coreapi/lpconfig.c
index 1c87904d6..2a1c85520 100644
--- a/coreapi/lpconfig.c
+++ b/coreapi/lpconfig.c
@@ -481,14 +481,14 @@ LinphoneStatus linphone_config_read_file(LpConfig *lpconfig, const char *filenam
 	return -1;
 }
 
-char* linphone_config_load_from_xml_file(LpConfig *lpc, const char *filename, void* ctx) {
+char* linphone_config_load_from_xml_file(LpConfig *lpc, const char *filename, void* lc, void* ctx) {
 	xml2lpc_context *context = NULL;
 	char* path = lp_realpath(filename, NULL);
 	char* error_msg = NULL;
 
 	if (path) {
 		int result = -1;
-		context = xml2lpc_context_new(NULL, ctx);
+		context = xml2lpc_context_new(ctx, lc);
 		result = xml2lpc_set_xml_string(context, path);
 		if (result == 0) {
 			result = xml2lpc_convert(context, lpc);
diff --git a/coreapi/remote_provisioning.c b/coreapi/remote_provisioning.c
index 9da88531a..daadf4163 100644
--- a/coreapi/remote_provisioning.c
+++ b/coreapi/remote_provisioning.c
@@ -35,7 +35,7 @@ static void xml2lpc_callback(void *ctx, xml2lpc_log_level level, const char *fmt
 }
 
 static void linphone_remote_provisioning_apply(LinphoneCore *lc, const char *xml) {
-	char* error_msg = linphone_config_load_from_xml_file(linphone_core_get_config(lc), xml, lc);
+	char* error_msg = linphone_config_load_from_xml_file(linphone_core_get_config(lc), xml, lc, xml2lpc_callback);
 
 	linphone_configuring_terminated(lc
 									,error_msg ? LinphoneConfiguringFailed : LinphoneConfiguringSuccessful
diff --git a/include/linphone/lpconfig.h b/include/linphone/lpconfig.h
index 3f8893e65..72b06213d 100644
--- a/include/linphone/lpconfig.h
+++ b/include/linphone/lpconfig.h
@@ -87,9 +87,10 @@ LINPHONE_PUBLIC LinphoneStatus linphone_config_read_file(LinphoneConfig *lpconfi
  * @ingroup misc
  * @param lpconfig The LinphoneConfig object to fill with the content of the file
  * @param filename The filename of the config file to read to fill the LinphoneConfig
+ * @param lc LinphoneCore to share with xml2lpc
  * @param ctx The context given to xml2lpc callback
  */
-LINPHONE_PUBLIC char* linphone_config_load_from_xml_file(LpConfig *lpc, const char *filename, void* ctx);
+LINPHONE_PUBLIC char* linphone_config_load_from_xml_file(LpConfig *lpc, const char *filename, void* lc, void* ctx);
 
 /**
  * Retrieves a configuration item as a string, given its section, key, and default value.
diff --git a/tester/CMakeLists.txt b/tester/CMakeLists.txt
index e90af0224..dd24b205a 100644
--- a/tester/CMakeLists.txt
+++ b/tester/CMakeLists.txt
@@ -78,6 +78,7 @@ set(CERTIFICATE_FILES ${CERTIFICATE_ALT_FILES} ${CERTIFICATE_CN_FILES} ${CERTIFI
 
 set(RC_FILES
 	rcfiles/account_creator_rc
+	rcfiles/assistant_create.rc
 	rcfiles/carddav_rc
 	rcfiles/conference_focus_rc
 	rcfiles/empty_rc
diff --git a/tester/Makefile.am b/tester/Makefile.am
index efe2837ed..98634b009 100644
--- a/tester/Makefile.am
+++ b/tester/Makefile.am
@@ -35,6 +35,7 @@ CERTIFICATE_FILES = $(CERTIFICATE_ALT_FILES) $(CERTIFICATE_CN_FILES) $(CERTIFICA
 
 RCFILES = \
 					rcfiles/account_creator_rc\
+					rcfiles/assistant_create.rc\
 					rcfiles/carddav_rc\
 					rcfiles/empty_rc\
 					rcfiles/friends_rc\
diff --git a/tester/proxy_config_tester.c b/tester/proxy_config_tester.c
index 6f38c30e6..322034cbc 100644
--- a/tester/proxy_config_tester.c
+++ b/tester/proxy_config_tester.c
@@ -68,7 +68,7 @@ static void phone_normalization_with_proxy(void) {
 	BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+33 (0) 1 23 45 67 89"), "+33123456789");
 	BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+90 (903) 1234567"), "+909031234567");
 	BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "0033123456789"), "0033123456789");
-	
+
 	linphone_proxy_config_set_dial_prefix(proxy, "33");
 	BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "123456789"), "+33123456789");
 	BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, " 0123456789"), "+33123456789");
@@ -179,11 +179,20 @@ static void sip_uri_normalization(void) {
 	SIP_URI_CHECK("Ù¡", expected); //test that no more invalid memory writes are made (valgrind only)
 }
 
+static void load_dynamic_proxy_config(void) {
+	LinphoneProxyConfig *proxy;
+
+	//Load file
+
+	proxy = linphone_proxy_config_new();
+}
+
 test_t proxy_config_tests[] = {
 	TEST_NO_TAG("Phone normalization without proxy", phone_normalization_without_proxy),
 	TEST_NO_TAG("Phone normalization with proxy", phone_normalization_with_proxy),
 	TEST_NO_TAG("Phone normalization with dial escape plus", phone_normalization_with_dial_escape_plus),
-	TEST_NO_TAG("SIP URI normalization", sip_uri_normalization)
+	TEST_NO_TAG("SIP URI normalization", sip_uri_normalization),
+	TEST_NO_TAG("Load new default value for proxy config", load_dynamic_proxy_config)
 };
 
 test_suite_t proxy_config_test_suite = {"Proxy config", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each,
diff --git a/tester/rcfiles/assistant_create.rc b/tester/rcfiles/assistant_create.rc
new file mode 100644
index 000000000..a4f42a809
--- /dev/null
+++ b/tester/rcfiles/assistant_create.rc
@@ -0,0 +1,32 @@
+
+
+
+	
+ 1 + 0 + 0 + sip:voip-metrics@sip.linphone.org;transport=tls + 1 + 180 + 31536000 + sip:?@sip.linphone.org + 1 + push_notification + sip.linphone.org +
+ +
+ sips:rls@sip.linphone.org +
+ +
+ sip.linphone.org + -1 + 1 + -1 + 64 + 1 + ^[a-z0-9+_.\-]*$ + https://sip3.linphone.org:444/wizard.php +
+
From 273c896336fca5626e658f6168856eb8f4e1bb27 Mon Sep 17 00:00:00 2001 From: Erwan Croze Date: Tue, 18 Apr 2017 17:19:44 +0200 Subject: [PATCH 36/70] Fix load of xml file --- coreapi/lpconfig.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/lpconfig.c b/coreapi/lpconfig.c index 2a1c85520..12d14b65b 100644 --- a/coreapi/lpconfig.c +++ b/coreapi/lpconfig.c @@ -489,7 +489,7 @@ char* linphone_config_load_from_xml_file(LpConfig *lpc, const char *filename, vo if (path) { int result = -1; context = xml2lpc_context_new(ctx, lc); - result = xml2lpc_set_xml_string(context, path); + result = xml2lpc_set_xml_file(context, path); if (result == 0) { result = xml2lpc_convert(context, lpc); if (result == 0) { From 05b045cb6714a09ce55eb2fce0f609d992e91edd Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 18 Apr 2017 17:28:46 +0200 Subject: [PATCH 37/70] Added missing set_user_data and get_user_data to LinphoneRange + created LinphoneTransports to replace LinphoneSipTransports --- coreapi/linphonecore.c | 130 ++++++++++++++++++++++++++------- coreapi/misc.c | 14 +++- coreapi/private.h | 16 ++++- include/linphone/core.h | 150 +++++++++++++++++++++++++++++++++------ include/linphone/misc.h | 26 +++++-- include/linphone/types.h | 21 +++--- 6 files changed, 292 insertions(+), 65 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 187a37bf5..184d94244 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2523,14 +2523,6 @@ void linphone_core_get_audio_port_range(const LinphoneCore *lc, int *min_port, i *max_port = lc->rtp_conf.audio_rtp_max_port; } -LinphoneIntRange linphone_core_get_audio_port_range_2(const LinphoneCore *lc) { - LinphoneIntRange range = { - .min = lc->rtp_conf.audio_rtp_min_port, - .max = lc->rtp_conf.audio_rtp_max_port - }; - return range; -} - LinphoneRange *linphone_core_get_audio_ports_range(const LinphoneCore *lc) { LinphoneRange *range = linphone_range_new(); range->min = lc->rtp_conf.audio_rtp_min_port; @@ -2547,14 +2539,6 @@ void linphone_core_get_video_port_range(const LinphoneCore *lc, int *min_port, i *max_port = lc->rtp_conf.video_rtp_max_port; } -LinphoneIntRange linphone_core_get_video_port_range_2(const LinphoneCore *lc) { - LinphoneIntRange range = { - .min = lc->rtp_conf.video_rtp_min_port, - .max = lc->rtp_conf.video_rtp_max_port - }; - return range; -} - LinphoneRange *linphone_core_get_video_ports_range(const LinphoneCore *lc) { LinphoneRange *range = linphone_range_new(); range->min = lc->rtp_conf.video_rtp_min_port; @@ -2571,14 +2555,6 @@ void linphone_core_get_text_port_range(const LinphoneCore *lc, int *min_port, in *max_port = lc->rtp_conf.text_rtp_max_port; } -LinphoneIntRange linphone_core_get_text_port_range_2(const LinphoneCore *lc) { - LinphoneIntRange range = { - .min = lc->rtp_conf.text_rtp_min_port, - .max = lc->rtp_conf.text_rtp_max_port - }; - return range; -} - LinphoneRange *linphone_core_get_text_ports_range(const LinphoneCore *lc) { LinphoneRange *range = linphone_range_new(); range->min = lc->rtp_conf.text_rtp_min_port; @@ -2787,6 +2763,72 @@ bool_t linphone_core_sip_transport_supported(const LinphoneCore *lc, LinphoneTra return sal_transport_available(lc->sal,(SalTransport)tp); } +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneTransports); + +BELLE_SIP_INSTANCIATE_VPTR(LinphoneTransports, belle_sip_object_t, + NULL, // destroy + NULL, // clone + NULL, // marshal + FALSE +); + +LinphoneTransports *linphone_transports_new(LinphoneCore *lc) { + LinphoneTransports *transports = belle_sip_object_new(LinphoneTransports); + transports->udp_port = 0; + transports->tcp_port = 0; + transports->tls_port = 0; + transports->dtls_port = 0; + return transports; +} + +LinphoneTransports* linphone_transports_ref(LinphoneTransports* transports) { + return (LinphoneTransports*) belle_sip_object_ref(transports); +} + +void linphone_transports_unref (LinphoneTransports* transports) { + belle_sip_object_unref(transports); +} + +void *linphone_transports_get_user_data(const LinphoneTransports *transports) { + return transports->user_data; +} + +void linphone_transports_set_user_data(LinphoneTransports *transports, void *data) { + transports->user_data = data; +} + +int linphone_transports_get_udp_port(const LinphoneTransports* transports) { + return transports->udp_port; +} + +int linphone_transports_get_tcp_port(const LinphoneTransports* transports) { + return transports->tcp_port; +} + +int linphone_transports_get_tls_port(const LinphoneTransports* transports) { + return transports->tls_port; +} + +int linphone_transports_get_dtls_port(const LinphoneTransports* transports) { + return transports->dtls_port; +} + +void linphone_transports_set_udp_port(LinphoneTransports *transports, int port) { + transports->udp_port = port; +} + +void linphone_transports_set_tcp_port(LinphoneTransports *transports, int port) { + transports->tcp_port = port; +} + +void linphone_transports_set_tls_port(LinphoneTransports *transports, int port) { + transports->tls_port = port; +} + +void linphone_transports_set_dtls_port(LinphoneTransports *transports, int port) { + transports->dtls_port = port; +} + LinphoneStatus linphone_core_set_sip_transports(LinphoneCore *lc, const LinphoneSipTransports * tr_config /*config to be saved*/){ LinphoneSipTransports tr=*tr_config; @@ -2821,17 +2863,57 @@ LinphoneStatus linphone_core_set_sip_transports(LinphoneCore *lc, const Linphone return _linphone_core_apply_transports(lc); } +LinphoneStatus linphone_core_set_transports(LinphoneCore *lc, const LinphoneTransports * transports){ + if (transports->udp_port == lc->sip_conf.transports.udp_port && + transports->tcp_port == lc->sip_conf.transports.tcp_port && + transports->tls_port == lc->sip_conf.transports.tls_port && + transports->dtls_port == lc->sip_conf.transports.dtls_port) { + return 0; + } + lc->sip_conf.transports.udp_port = transports->udp_port; + lc->sip_conf.transports.tcp_port = transports->tcp_port; + lc->sip_conf.transports.tls_port = transports->tls_port; + lc->sip_conf.transports.dtls_port = transports->dtls_port; + + if (linphone_core_ready(lc)) { + lp_config_set_int(lc->config,"sip", "sip_port", transports->udp_port); + lp_config_set_int(lc->config,"sip", "sip_tcp_port", transports->tcp_port); + lp_config_set_int(lc->config,"sip", "sip_tls_port", transports->tls_port); + } + + if (lc->sal == NULL) return 0; + return _linphone_core_apply_transports(lc); +} + LinphoneStatus linphone_core_get_sip_transports(LinphoneCore *lc, LinphoneSipTransports *tr){ memcpy(tr,&lc->sip_conf.transports,sizeof(*tr)); return 0; } +LinphoneTransports *linphone_core_get_transports(LinphoneCore *lc){ + LinphoneTransports *transports = linphone_transports_new(lc); + transports->udp_port = lc->sip_conf.transports.udp_port; + transports->tcp_port = lc->sip_conf.transports.tcp_port; + transports->tls_port = lc->sip_conf.transports.tls_port; + transports->dtls_port = lc->sip_conf.transports.dtls_port; + return transports; +} + void linphone_core_get_sip_transports_used(LinphoneCore *lc, LinphoneSipTransports *tr){ tr->udp_port=sal_get_listening_port(lc->sal,SalTransportUDP); tr->tcp_port=sal_get_listening_port(lc->sal,SalTransportTCP); tr->tls_port=sal_get_listening_port(lc->sal,SalTransportTLS); } +LinphoneTransports *linphone_core_get_transports_used(LinphoneCore *lc){ + LinphoneTransports *transports = linphone_transports_new(lc); + transports->udp_port = sal_get_listening_port(lc->sal, SalTransportUDP); + transports->tcp_port = sal_get_listening_port(lc->sal, SalTransportTCP); + transports->tls_port = sal_get_listening_port(lc->sal, SalTransportTLS); + transports->dtls_port = sal_get_listening_port(lc->sal, SalTransportDTLS); + return transports; +} + void linphone_core_set_sip_port(LinphoneCore *lc,int port) { LinphoneSipTransports tr; memset(&tr,0,sizeof(tr)); diff --git a/coreapi/misc.c b/coreapi/misc.c index 5db955617..fa295f6c7 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -1828,17 +1828,27 @@ BELLE_SIP_INSTANCIATE_VPTR(LinphoneRange, belle_sip_object_t, LinphoneRange *linphone_range_new() { LinphoneRange *range = belle_sip_object_new(LinphoneRange); + range->min = 0; + range->max = 0; return range; } -LinphoneRange* linphone_range_ref (LinphoneRange* range) { +LinphoneRange* linphone_range_ref(LinphoneRange* range) { return (LinphoneRange*) belle_sip_object_ref(range); } -void linphone_range_unref (LinphoneRange* range) { +void linphone_range_unref(LinphoneRange* range) { belle_sip_object_unref(range); } +void *linphone_range_get_user_data(const LinphoneRange *range) { + return range->user_data; +} + +void linphone_range_set_user_data(LinphoneRange *range, void *data) { + range->user_data = data; +} + int linphone_range_get_min(const LinphoneRange *range) { return range->min; } diff --git a/coreapi/private.h b/coreapi/private.h index 1d8672cfe..537337cf5 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -1737,6 +1737,19 @@ BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneRange); LinphoneRange *linphone_range_new(void); +struct _LinphoneTransports { + belle_sip_object_t base; + void *user_data; + int udp_port; /**< SIP/UDP port */ + int tcp_port; /**< SIP/TCP port */ + int dtls_port; /**< SIP/DTLS port */ + int tls_port; /**< SIP/TLS port */ +}; + +BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneTransports); + +LINPHONE_PUBLIC LinphoneTransports *linphone_transports_new(LinphoneCore *lc); + /** Belle Sip-based objects need unique ids */ @@ -1788,7 +1801,8 @@ BELLE_SIP_TYPE_ID(LinphoneConference), BELLE_SIP_TYPE_ID(LinphoneInfoMessage), BELLE_SIP_TYPE_ID(LinphonePayloadType), BELLE_SIP_TYPE_ID(LinphoneRange), -BELLE_SIP_TYPE_ID(LinphoneVideoDefinition) +BELLE_SIP_TYPE_ID(LinphoneVideoDefinition), +BELLE_SIP_TYPE_ID(LinphoneTransports) BELLE_SIP_DECLARE_TYPES_END diff --git a/include/linphone/core.h b/include/linphone/core.h index 93fd4f422..559973ab2 100644 --- a/include/linphone/core.h +++ b/include/linphone/core.h @@ -2104,13 +2104,6 @@ LINPHONE_PUBLIC int linphone_core_get_audio_port(const LinphoneCore *lc); */ LINPHONE_PUBLIC void linphone_core_get_audio_port_range(const LinphoneCore *lc, int *min_port, int *max_port); -/** - * Overload of linphone_core_get_audio_port_range(). - * @deprecated Use linphone_core_get_audio_ports_range instead - * @ingroup network_parameters - */ -LINPHONE_PUBLIC LinphoneIntRange linphone_core_get_audio_port_range_2(const LinphoneCore *lc); - /** * Get the audio port range from which is randomly chosen the UDP port used for audio streaming. * @param[in] lc LinphoneCore object @@ -2137,13 +2130,6 @@ LINPHONE_PUBLIC int linphone_core_get_video_port(const LinphoneCore *lc); */ LINPHONE_PUBLIC void linphone_core_get_video_port_range(const LinphoneCore *lc, int *min_port, int *max_port); -/** - * Overload of linphone_core_get_video_port_range(). - * @deprecated Use linphone_core_get_video_ports_range instead - * @ingroup network_parameters - */ -LINPHONE_PUBLIC LinphoneIntRange linphone_core_get_video_port_range_2(const LinphoneCore *lc); - /** * Get the video port range from which is randomly chosen the UDP port used for video streaming. * @param[in] lc LinphoneCore object @@ -2170,13 +2156,6 @@ LINPHONE_PUBLIC int linphone_core_get_text_port(const LinphoneCore *lc); */ LINPHONE_PUBLIC void linphone_core_get_text_port_range(const LinphoneCore *lc, int *min_port, int *max_port); -/** - * Overload of linphone_core_get_text_port_range(). - * @deprecated Use linphone_core_get_text_ports_range instead - * @ingroup network_parameters - */ -LINPHONE_PUBLIC LinphoneIntRange linphone_core_get_text_port_range_2(const LinphoneCore *lc); - /** * Get the text port range from which is randomly chosen the UDP port used for text streaming. * @param[in] lc LinphoneCore object @@ -2324,6 +2303,8 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED int linphone_core_get_sip_port(LinphoneCore * @param[in] transports A LinphoneSipTransports structure giving the ports to use * @return 0 * @ingroup network_parameters + * @deprecated Use linphone_core_set_transports instead + * @donotwrap **/ LINPHONE_PUBLIC LinphoneStatus linphone_core_set_sip_transports(LinphoneCore *lc, const LinphoneSipTransports *transports); @@ -2335,6 +2316,7 @@ LINPHONE_PUBLIC LinphoneStatus linphone_core_set_sip_transports(LinphoneCore *lc * @param[out] transports A #LinphoneSipTransports structure that will receive the configured ports * @return 0 * @ingroup network_parameters + * @deprecated * @donotwrap **/ LINPHONE_PUBLIC LinphoneStatus linphone_core_get_sip_transports(LinphoneCore *lc, LinphoneSipTransports *transports); @@ -2346,10 +2328,136 @@ LINPHONE_PUBLIC LinphoneStatus linphone_core_get_sip_transports(LinphoneCore *lc * @param[in] lc LinphoneCore object * @param[out] tr A #LinphoneSipTransports structure that will receive the ports being used * @ingroup network_parameters + * @deprecated Use linphone_core_get_transports_used instead * @donotwrap **/ LINPHONE_PUBLIC void linphone_core_get_sip_transports_used(LinphoneCore *lc, LinphoneSipTransports *tr); +/** + * Sets the ports to be used for each of transport (UDP or TCP) + * A zero value port for a given transport means the transport + * is not used. A value of LC_SIP_TRANSPORT_RANDOM (-1) means the port is to be choosen randomly by the system. + * @param[in] lc LinphoneCore object + * @param[in] transports A LinphoneSipTransports structure giving the ports to use + * @return 0 + * @ingroup network_parameters +**/ +LINPHONE_PUBLIC LinphoneStatus linphone_core_set_transports(LinphoneCore *lc, const LinphoneTransports *transports); + +/** + * Retrieves the port configuration used for each transport (udp, tcp, tls). + * A zero value port for a given transport means the transport + * is not used. A value of LC_SIP_TRANSPORT_RANDOM (-1) means the port is to be chosen randomly by the system. + * @param[in] lc LinphoneCore object + * @return A #LinphoneTransports structure with the configured ports + * @ingroup network_parameters +**/ +LINPHONE_PUBLIC LinphoneTransports *linphone_core_get_transports(LinphoneCore *lc); + +/** + * Retrieves the real port number assigned for each sip transport (udp, tcp, tls). + * A zero value means that the transport is not activated. + * If LC_SIP_TRANSPORT_RANDOM was passed to linphone_core_set_sip_transports(), the random port choosed by the system is returned. + * @param[in] lc LinphoneCore object + * @return A #LinphoneTransports structure with the ports being used + * @ingroup network_parameters +**/ +LINPHONE_PUBLIC LinphoneTransports *linphone_core_get_transports_used(LinphoneCore *lc); + +/** + * Increment refcount. + * @param[in] transports LinphoneTransports object + * @ingroup network_parameters +**/ +LINPHONE_PUBLIC LinphoneTransports *linphone_transports_ref(LinphoneTransports *transports); + +/** + * Decrement refcount and possibly free the object. + * @param[in] transports LinphoneTransports object + * @ingroup network_parameters +**/ +LINPHONE_PUBLIC void linphone_transports_unref(LinphoneTransports *transports); + +/** + * Gets the user data in the LinphoneTransports object + * @param[in] transports the LinphoneTransports + * @return the user data + * @ingroup network_parameters +*/ +LINPHONE_PUBLIC void *linphone_transports_get_user_data(const LinphoneTransports *transports); + +/** + * Sets the user data in the LinphoneTransports object + * @param[in] transports the LinphoneTransports object + * @param[in] data the user data + * @ingroup network_parameters +*/ +LINPHONE_PUBLIC void linphone_transports_set_user_data(LinphoneTransports *transports, void *data); + +/** + * Gets the UDP port in the LinphoneTransports object + * @param[in] transports the LinphoneTransports object + * @return the UDP port + * @ingroup network_parameters + */ +LINPHONE_PUBLIC int linphone_transports_get_udp_port(const LinphoneTransports* transports); + +/** + * Gets the TCP port in the LinphoneTransports object + * @param[in] transports the LinphoneTransports object + * @return the TCP port + * @ingroup network_parameters + */ +LINPHONE_PUBLIC int linphone_transports_get_tcp_port(const LinphoneTransports* transports); + +/** + * Gets the TLS port in the LinphoneTransports object + * @param[in] transports the LinphoneTransports object + * @return the TLS port + * @ingroup network_parameters + */ +LINPHONE_PUBLIC int linphone_transports_get_tls_port(const LinphoneTransports* transports); + +/** + * Gets the DTLS port in the LinphoneTransports object + * @param[in] transports the LinphoneTransports object + * @return the DTLS port + * @ingroup network_parameters + */ +LINPHONE_PUBLIC int linphone_transports_get_dtls_port(const LinphoneTransports* transports); + +/** + * Sets the UDP port in the LinphoneTransports object + * @param[in] transports the LinphoneTransports object + * @param[in] port the UDP port + * @ingroup network_parameters + */ +LINPHONE_PUBLIC void linphone_transports_set_udp_port(LinphoneTransports *transports, int port); + +/** + * Sets the TCP port in the LinphoneTransports object + * @param[in] transports the LinphoneTransports object + * @param[in] port the TCP port + * @ingroup network_parameters + */ +LINPHONE_PUBLIC void linphone_transports_set_tcp_port(LinphoneTransports *transports, int port); + +/** + * Sets the TLS port in the LinphoneTransports object + * @param[in] transports the LinphoneTransports object + * @param[in] port the TLS port + * @ingroup network_parameters + */ +LINPHONE_PUBLIC void linphone_transports_set_tls_port(LinphoneTransports *transports, int port); + +/** + * Sets the DTLS port in the LinphoneTransports object + * @param[in] transports the LinphoneTransports object + * @param[in] port the DTLS port + * @ingroup network_parameters + */ +LINPHONE_PUBLIC void linphone_transports_set_dtls_port(LinphoneTransports *transports, int port); + /** * Tells whether the given transport type is supported by the library. * @param[in] lc LinphoneCore object diff --git a/include/linphone/misc.h b/include/linphone/misc.h index c80d7abf2..6f04e1c2a 100644 --- a/include/linphone/misc.h +++ b/include/linphone/misc.h @@ -159,6 +159,14 @@ LINPHONE_PUBLIC LinphoneTransportType linphone_transport_parse(const char* trans **/ LINPHONE_PUBLIC LinphoneReason linphone_error_code_to_reason(int err); +/** + * Converts a LinphoneReason to an error code. + * @param[in] reason A LinphoneReason + * @return The error code corresponding to the specified LinphoneReason + * @ingroup misc + */ +LINPHONE_PUBLIC int linphone_reason_to_error_code(LinphoneReason reason); + /** * Increment refcount. * @param[in] range LinphoneRange object @@ -172,12 +180,18 @@ LINPHONE_PUBLIC LinphoneRange *linphone_range_ref(LinphoneRange *range); LINPHONE_PUBLIC void linphone_range_unref(LinphoneRange *range); /** - * Converts a LinphoneReason to an error code. - * @param[in] reason A LinphoneReason - * @return The error code corresponding to the specified LinphoneReason - * @ingroup misc - */ -LINPHONE_PUBLIC int linphone_reason_to_error_code(LinphoneReason reason); + * Gets the user data in the LinphoneRange object + * @param[in] range the LinphoneRange + * @return the user data +*/ +LINPHONE_PUBLIC void *linphone_range_get_user_data(const LinphoneRange *range); + +/** + * Sets the user data in the LinphoneRange object + * @param[in] range the LinphoneRange object + * @param[in] data the user data +*/ +LINPHONE_PUBLIC void linphone_range_set_user_data(LinphoneRange *range, void *data); /** * Gets the lower value of the range diff --git a/include/linphone/types.h b/include/linphone/types.h index 4fb6244b1..301e08da8 100644 --- a/include/linphone/types.h +++ b/include/linphone/types.h @@ -972,7 +972,8 @@ typedef struct _LinphoneRingtonePlayer LinphoneRingtonePlayer; * Linphone core SIP transport ports. * Special values #LC_SIP_TRANSPORT_RANDOM, #LC_SIP_TRANSPORT_RANDOM, #LC_SIP_TRANSPORT_DONTBIND can be used. * Use with #linphone_core_set_sip_transports - * @ingroup initializing + * @deprecated + * @donotwrap */ typedef struct _LinphoneSipTransports { int udp_port; /**< SIP/UDP port */ @@ -981,6 +982,14 @@ typedef struct _LinphoneSipTransports { int tls_port; /**< SIP/TLS port */ } LinphoneSipTransports; +/** + * Linphone core SIP transport ports. + * Special values #LC_SIP_TRANSPORT_RANDOM, #LC_SIP_TRANSPORT_RANDOM, #LC_SIP_TRANSPORT_DONTBIND can be used. + * Use with #linphone_core_set_sip_transports + * @ingroup initializing + */ +typedef struct _LinphoneTransports LinphoneTransports; + /** * Old name of LinphoneSipTransports * @deprecated @@ -1184,16 +1193,6 @@ typedef struct _LsdPlayer LsdPlayer; */ typedef struct _LinphonePayloadType LinphonePayloadType; - -/** - * Structure describing a range of integers - * @deprecated - */ -typedef struct _LinphoneIntRange { - int min; /**< Minimum value */ - int max; /**< Maximum value */ -} LinphoneIntRange; - /** * Structure describing a range of integers * @ingroup misc From cbd6248ea0fa50d49e859f96205cf472ec3d7826 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 18 Apr 2017 17:49:54 +0200 Subject: [PATCH 38/70] Fixed tester compilation --- tester/proxy_config_tester.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tester/proxy_config_tester.c b/tester/proxy_config_tester.c index 322034cbc..fe71778c6 100644 --- a/tester/proxy_config_tester.c +++ b/tester/proxy_config_tester.c @@ -179,20 +179,20 @@ static void sip_uri_normalization(void) { SIP_URI_CHECK("Ù¡", expected); //test that no more invalid memory writes are made (valgrind only) } -static void load_dynamic_proxy_config(void) { +/*static void load_dynamic_proxy_config(void) { LinphoneProxyConfig *proxy; //Load file proxy = linphone_proxy_config_new(); -} +}*/ test_t proxy_config_tests[] = { TEST_NO_TAG("Phone normalization without proxy", phone_normalization_without_proxy), TEST_NO_TAG("Phone normalization with proxy", phone_normalization_with_proxy), TEST_NO_TAG("Phone normalization with dial escape plus", phone_normalization_with_dial_escape_plus), TEST_NO_TAG("SIP URI normalization", sip_uri_normalization), - TEST_NO_TAG("Load new default value for proxy config", load_dynamic_proxy_config) + //TEST_NO_TAG("Load new default value for proxy config", load_dynamic_proxy_config) }; test_suite_t proxy_config_test_suite = {"Proxy config", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each, From 21a04409aa018ba0a690d8978a4105f0d9994896 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 18 Apr 2017 18:02:34 +0200 Subject: [PATCH 39/70] Fix automatic wrapper generation. --- include/linphone/misc.h | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/linphone/misc.h b/include/linphone/misc.h index 6f04e1c2a..f4e074afa 100644 --- a/include/linphone/misc.h +++ b/include/linphone/misc.h @@ -170,12 +170,14 @@ LINPHONE_PUBLIC int linphone_reason_to_error_code(LinphoneReason reason); /** * Increment refcount. * @param[in] range LinphoneRange object + * @ingroup misc **/ LINPHONE_PUBLIC LinphoneRange *linphone_range_ref(LinphoneRange *range); /** * Decrement refcount and possibly free the object. * @param[in] range LinphoneRange object + * @ingroup misc **/ LINPHONE_PUBLIC void linphone_range_unref(LinphoneRange *range); From 173ac0e6651d3f0b7d348f9a0a47e6b38e4c4402 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 18 Apr 2017 18:06:40 +0200 Subject: [PATCH 40/70] Updated some tests in Register suite to use new LinphoneTransports object + Fixed wrapper generation for linphone_range_set/get_user_data methods --- include/linphone/misc.h | 2 ++ tester/register_tester.c | 60 ++++++++++++++++++++++++++++++++-------- 2 files changed, 51 insertions(+), 11 deletions(-) diff --git a/include/linphone/misc.h b/include/linphone/misc.h index f4e074afa..1c05c2dc6 100644 --- a/include/linphone/misc.h +++ b/include/linphone/misc.h @@ -185,6 +185,7 @@ LINPHONE_PUBLIC void linphone_range_unref(LinphoneRange *range); * Gets the user data in the LinphoneRange object * @param[in] range the LinphoneRange * @return the user data + * @ingroup misc */ LINPHONE_PUBLIC void *linphone_range_get_user_data(const LinphoneRange *range); @@ -192,6 +193,7 @@ LINPHONE_PUBLIC void *linphone_range_get_user_data(const LinphoneRange *range); * Sets the user data in the LinphoneRange object * @param[in] range the LinphoneRange object * @param[in] data the user data + * @ingroup misc */ LINPHONE_PUBLIC void linphone_range_set_user_data(LinphoneRange *range, void *data); diff --git a/tester/register_tester.c b/tester/register_tester.c index 33819efb7..c5417ee63 100644 --- a/tester/register_tester.c +++ b/tester/register_tester.c @@ -69,7 +69,7 @@ static void register_with_refresh_base_3(LinphoneCore* lc ,const char* domain ,const char* route ,bool_t late_auth_info - ,LCSipTransports transport + ,LinphoneTransports *transport ,LinphoneRegistrationState expected_final_state) { int retry=0; char* addr; @@ -84,7 +84,7 @@ static void register_with_refresh_base_3(LinphoneCore* lc counters = get_stats(lc); reset_counters(counters); - linphone_core_set_sip_transports(lc,&transport); + linphone_core_set_transports(lc, transport); proxy_cfg = linphone_proxy_config_new(); @@ -141,12 +141,17 @@ static void register_with_refresh_base_2(LinphoneCore* lc ,const char* domain ,const char* route ,bool_t late_auth_info - ,LCSipTransports transport) { + ,LinphoneTransports *transport) { register_with_refresh_base_3(lc, refresh, domain, route, late_auth_info, transport,LinphoneRegistrationOk ); } static void register_with_refresh_base(LinphoneCore* lc, bool_t refresh,const char* domain,const char* route) { - LCSipTransports transport = {5070,5070,0,5071}; + LinphoneTransports *transport = linphone_transports_new(lc); + linphone_transports_set_udp_port(transport, 5070); + linphone_transports_set_tcp_port(transport, 5070); + linphone_transports_set_tls_port(transport, 5071); + linphone_transports_set_dtls_port(transport, 0); register_with_refresh_base_2(lc,refresh,domain,route,FALSE,transport); + linphone_transports_unref(transport); } static void register_with_refresh(LinphoneCoreManager* lcm, bool_t refresh,const char* domain,const char* route) { @@ -281,10 +286,13 @@ static void simple_tcp_register(void){ static void simple_tcp_register_compatibility_mode(void){ char route[256]; LinphoneCoreManager* lcm; - LCSipTransports transport = {0,5070,0,0}; + LinphoneTransports *transport = NULL; sprintf(route,"sip:%s",test_route); lcm = create_lcm(); + transport = linphone_transports_new(lcm->lc); + linphone_transports_set_tcp_port(transport, 5070); register_with_refresh_base_2(lcm->lc,FALSE,test_domain,route,FALSE,transport); + linphone_transports_unref(transport); linphone_core_manager_destroy(lcm); } @@ -356,14 +364,19 @@ static void authenticated_register_with_late_credentials(void){ LinphoneCoreManager *lcm; stats* counters; char route[256]; - LCSipTransports transport = {5070,5070,0,5071}; + LinphoneTransports *transport = NULL; sprintf(route,"sip:%s",test_route); lcm = linphone_core_manager_new(NULL); + transport = linphone_transports_new(lcm->lc); + linphone_transports_set_udp_port(transport, 5070); + linphone_transports_set_tcp_port(transport, 5070); + linphone_transports_set_dtls_port(transport, 5071); counters = get_stats(lcm->lc); register_with_refresh_base_2(lcm->lc,FALSE,auth_domain,route,TRUE,transport); + linphone_transports_unref(transport); BC_ASSERT_EQUAL(counters->number_of_auth_info_requested,1, int, "%d"); linphone_core_manager_destroy(lcm); } @@ -412,7 +425,7 @@ static void authenticated_register_with_provided_credentials(void){ static void authenticated_register_with_wrong_late_credentials(void){ LinphoneCoreManager *lcm; stats* counters; - LCSipTransports transport = {5070,5070,0,5071}; + LinphoneTransports *transport = NULL; char route[256]; const char* saved_test_passwd=test_password; char* wrong_passwd="mot de pass tout pourri"; @@ -422,9 +435,15 @@ static void authenticated_register_with_wrong_late_credentials(void){ sprintf(route,"sip:%s",test_route); lcm = linphone_core_manager_new(NULL); + transport = linphone_transports_new(lcm->lc); + linphone_transports_set_udp_port(transport, 5070); + linphone_transports_set_tcp_port(transport, 5070); + linphone_transports_set_tls_port(transport, 5071); + linphone_transports_set_dtls_port(transport, 0); counters = get_stats(lcm->lc); register_with_refresh_base_3(lcm->lc,FALSE,auth_domain,route,TRUE,transport,LinphoneRegistrationFailed); + linphone_transports_unref(transport); BC_ASSERT_EQUAL(counters->number_of_auth_info_requested,2, int, "%d"); BC_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationFailed,2, int, "%d"); BC_ASSERT_EQUAL(counters->number_of_LinphoneRegistrationProgress,2, int, "%d"); @@ -435,11 +454,16 @@ static void authenticated_register_with_wrong_late_credentials(void){ static void authenticated_register_with_wrong_credentials_with_params_base(const char* user_agent,LinphoneCoreManager *lcm) { stats* counters; - LCSipTransports transport = {5070,5070,0,5071}; + LinphoneTransports *transport = linphone_transports_new(lcm->lc); LinphoneAuthInfo *info=linphone_auth_info_new(test_username,NULL,"wrong passwd",NULL,auth_domain,NULL); /*create authentication structure from identity*/ char route[256]; sprintf(route,"sip:%s",test_route); + transport = linphone_transports_new(lcm->lc); + linphone_transports_set_udp_port(transport, 5070); + linphone_transports_set_tcp_port(transport, 5070); + linphone_transports_set_tls_port(transport, 5071); + linphone_transports_set_dtls_port(transport, 0); sal_set_refresher_retry_after(lcm->lc->sal,500); if (user_agent) { @@ -449,6 +473,7 @@ static void authenticated_register_with_wrong_credentials_with_params_base(const linphone_auth_info_unref(info); counters = get_stats(lcm->lc); register_with_refresh_base_3(lcm->lc,TRUE,auth_domain,route,FALSE,transport,LinphoneRegistrationFailed); + linphone_transports_unref(transport); //BC_ASSERT_EQUAL(counters->number_of_auth_info_requested,3, int, "%d"); register_with_refresh_base_3 does not alow to precisely check number of number_of_auth_info_requested /*wait for retry*/ BC_ASSERT_TRUE(wait_for(lcm->lc,lcm->lc,&counters->number_of_auth_info_requested,4)); @@ -666,12 +691,17 @@ static void proxy_transport_change_with_wrong_port(void) { LinphoneProxyConfig* proxy_config; LinphoneAuthInfo *info=linphone_auth_info_new(test_username,NULL,test_password,NULL,auth_domain,NULL); /*create authentication structure from identity*/ char route[256]; - LCSipTransports transport= {LC_SIP_TRANSPORT_RANDOM,LC_SIP_TRANSPORT_RANDOM,LC_SIP_TRANSPORT_RANDOM,LC_SIP_TRANSPORT_RANDOM}; + LinphoneTransports *transport= linphone_transports_new(lcm->lc); sprintf(route,"sip:%s",test_route); + linphone_transports_set_udp_port(transport, LC_SIP_TRANSPORT_RANDOM); + linphone_transports_set_tcp_port(transport, LC_SIP_TRANSPORT_RANDOM); + linphone_transports_set_tls_port(transport, LC_SIP_TRANSPORT_RANDOM); + linphone_transports_set_dtls_port(transport, LC_SIP_TRANSPORT_RANDOM); linphone_core_add_auth_info(lcm->lc,info); /*add authentication info to LinphoneCore*/ linphone_auth_info_unref(info); register_with_refresh_base_3(lcm->lc, FALSE, auth_domain, "sip2.linphone.org:5987", 0,transport,LinphoneRegistrationProgress); + linphone_transports_unref(transport); proxy_config = linphone_core_get_default_proxy_config(lcm->lc); linphone_proxy_config_edit(proxy_config); @@ -697,12 +727,17 @@ static void proxy_transport_change_with_wrong_port_givin_up(void) { LinphoneProxyConfig* proxy_config; LinphoneAuthInfo *info=linphone_auth_info_new(test_username,NULL,test_password,NULL,auth_domain,NULL); /*create authentication structure from identity*/ char route[256]; - LCSipTransports transport= {LC_SIP_TRANSPORT_RANDOM,LC_SIP_TRANSPORT_RANDOM,LC_SIP_TRANSPORT_RANDOM,LC_SIP_TRANSPORT_RANDOM}; + LinphoneTransports *transport = linphone_transports_new(lcm->lc); sprintf(route,"sip:%s",test_route); + linphone_transports_set_udp_port(transport, LC_SIP_TRANSPORT_RANDOM); + linphone_transports_set_tcp_port(transport, LC_SIP_TRANSPORT_RANDOM); + linphone_transports_set_tls_port(transport, LC_SIP_TRANSPORT_RANDOM); + linphone_transports_set_dtls_port(transport, LC_SIP_TRANSPORT_RANDOM); linphone_core_add_auth_info(lcm->lc,info); /*add authentication info to LinphoneCore*/ linphone_auth_info_unref(info); register_with_refresh_base_3(lcm->lc, FALSE, auth_domain, "sip2.linphone.org:5987", 0,transport,LinphoneRegistrationProgress); + linphone_transports_unref(transport); proxy_config = linphone_core_get_default_proxy_config(lcm->lc); linphone_proxy_config_edit(proxy_config); @@ -980,12 +1015,15 @@ static void tls_wildcard_register(void){ static void redirect(void){ char route[256]; LinphoneCoreManager* lcm; - LCSipTransports transport = {-1,0,0,0}; + LinphoneTransports *transport = NULL; sprintf(route,"sip:%s:5064",test_route); lcm = create_lcm(); if (lcm) { + transport = linphone_transports_new(lcm->lc); + linphone_transports_set_udp_port(transport, -1); linphone_core_set_user_agent(lcm->lc,"redirect",NULL); register_with_refresh_base_2(lcm->lc,FALSE,test_domain,route,FALSE,transport); + linphone_transports_unref(transport); linphone_core_manager_destroy(lcm); } } From 2780bb6905fde54268e592d3d93b18e573effaff Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Tue, 18 Apr 2017 18:14:06 +0200 Subject: [PATCH 41/70] Remove declaration of function that is not defined. --- include/linphone/account_creator.h | 7 ------- 1 file changed, 7 deletions(-) diff --git a/include/linphone/account_creator.h b/include/linphone/account_creator.h index 81fe0aca7..5dd48f1a6 100644 --- a/include/linphone/account_creator.h +++ b/include/linphone/account_creator.h @@ -491,13 +491,6 @@ LINPHONE_PUBLIC void linphone_account_creator_cbs_set_update_account(LinphoneAcc /************************** End Account Creator Cbs **************************/ -/** - * - * @param[in] creator LinphoneAccountCreator object - * @return A LinphoneProxyConfig object if successful, NULL otherwise - **/ -LINPHONE_PUBLIC LinphoneProxyConfig * linphone_account_creator_create_proxy_config(const LinphoneAccountCreator *creator); - /** * Configure an account (create a proxy config and authentication info for it). * @param[in] creator LinphoneAccountCreator object From ec5eb75511a0d80f70d422e6d1f05c05c476f20a Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 18 Apr 2017 18:15:03 +0200 Subject: [PATCH 42/70] Fixed leak of LinphoneTransports in Register tester --- tester/register_tester.c | 1 - 1 file changed, 1 deletion(-) diff --git a/tester/register_tester.c b/tester/register_tester.c index c5417ee63..aadb06312 100644 --- a/tester/register_tester.c +++ b/tester/register_tester.c @@ -459,7 +459,6 @@ static void authenticated_register_with_wrong_credentials_with_params_base(const char route[256]; sprintf(route,"sip:%s",test_route); - transport = linphone_transports_new(lcm->lc); linphone_transports_set_udp_port(transport, 5070); linphone_transports_set_tcp_port(transport, 5070); linphone_transports_set_tls_port(transport, 5071); From 31cc2ad6e1791abcb48101e47e7078b3e6c10433 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 18 Apr 2017 18:27:41 +0200 Subject: [PATCH 43/70] Updated two more tests in Register suite to test linphone_core_get_transports and linphone_core_get_transports_used --- tester/register_tester.c | 36 ++++++++++++++++++------------------ 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/tester/register_tester.c b/tester/register_tester.c index aadb06312..b5159d48c 100644 --- a/tester/register_tester.c +++ b/tester/register_tester.c @@ -576,30 +576,32 @@ static void transport_change(void){ LinphoneCore* lc; int register_ok; stats* counters ; - LCSipTransports sip_tr; - LCSipTransports sip_tr_orig; + LinphoneTransports *sip_tr; + LinphoneTransports *sip_tr_orig; int number_of_udp_proxy=0; int total_number_of_proxies; lcm=configure_lcm(); if (lcm) { - memset(&sip_tr,0,sizeof(sip_tr)); lc=lcm->lc; + sip_tr = linphone_transports_new(lc); counters = get_stats(lc); register_ok=counters->number_of_LinphoneRegistrationOk; number_of_udp_proxy=get_number_of_udp_proxy(lc); total_number_of_proxies=(int)bctbx_list_size(linphone_core_get_proxy_config_list(lc)); - linphone_core_get_sip_transports(lc,&sip_tr_orig); + sip_tr_orig = linphone_core_get_transports(lc); - sip_tr.udp_port=sip_tr_orig.udp_port; + sip_tr->udp_port = sip_tr_orig->udp_port; /*keep only udp*/ - linphone_core_set_sip_transports(lc,&sip_tr); + linphone_core_set_transports(lc, sip_tr); BC_ASSERT_TRUE(wait_for(lc,lc,&counters->number_of_LinphoneRegistrationOk,register_ok+number_of_udp_proxy)); BC_ASSERT_TRUE(wait_for(lc,lc,&counters->number_of_LinphoneRegistrationFailed,total_number_of_proxies-number_of_udp_proxy)); + linphone_transports_unref(sip_tr); + linphone_transports_unref(sip_tr_orig); linphone_core_manager_destroy(lcm); } } @@ -607,20 +609,18 @@ static void transport_change(void){ static void transport_dont_bind(void){ LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc"); stats* counters = &pauline->stat; - LCSipTransports tr; + LinphoneTransports *tr = linphone_transports_new(pauline->lc); + linphone_transports_set_tcp_port(tr, LC_SIP_TRANSPORT_DONTBIND); + linphone_transports_set_tls_port(tr, LC_SIP_TRANSPORT_DONTBIND); - memset(&tr, 0, sizeof(tr)); - tr.udp_port = 0; - tr.tcp_port = LC_SIP_TRANSPORT_DONTBIND; - tr.tls_port = LC_SIP_TRANSPORT_DONTBIND; - - linphone_core_set_sip_transports(pauline->lc, &tr); + linphone_core_set_transports(pauline->lc, tr); BC_ASSERT_TRUE(wait_for_until(pauline->lc,pauline->lc,&counters->number_of_LinphoneRegistrationOk,2,15000)); - memset(&tr, 0, sizeof(tr)); - linphone_core_get_sip_transports_used(pauline->lc, &tr); - BC_ASSERT_EQUAL(tr.udp_port, 0, int, "%i"); - BC_ASSERT_EQUAL(tr.tcp_port, LC_SIP_TRANSPORT_DONTBIND, int, "%i"); - BC_ASSERT_EQUAL(tr.tls_port, LC_SIP_TRANSPORT_DONTBIND, int, "%i"); + linphone_transports_unref(tr); + tr = linphone_core_get_transports_used(pauline->lc); + BC_ASSERT_EQUAL(tr->udp_port, 0, int, "%i"); + BC_ASSERT_EQUAL(tr->tcp_port, LC_SIP_TRANSPORT_DONTBIND, int, "%i"); + BC_ASSERT_EQUAL(tr->tls_port, LC_SIP_TRANSPORT_DONTBIND, int, "%i"); + linphone_transports_unref(tr); linphone_core_manager_destroy(pauline); } From a160392f8ec0ba9d16ff663fbcf0d51e273a0ed2 Mon Sep 17 00:00:00 2001 From: Johan Pascal Date: Tue, 18 Apr 2017 23:46:12 +0700 Subject: [PATCH 44/70] Remove dependence on bzrtp in linphonecore - use mediastreamer wrappers to access bzrtp cache functions --- coreapi/linphonecore.c | 48 ++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 21 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 184d94244..27de7fe7e 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -28,9 +28,6 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #ifdef SQLITE_STORAGE_ENABLED #include "sqlite3_bctbx_vfs.h" -# ifdef HAVE_ZRTP -# include "bzrtp/bzrtp.h" -# endif #endif #include @@ -6367,7 +6364,6 @@ void linphone_core_remove_iterate_hook(LinphoneCore *lc, LinphoneCoreIterateHook } -#ifdef HAVE_ZRTP void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file){ if (lc->zrtp_secrets_cache != NULL) { ms_free(lc->zrtp_secrets_cache); @@ -6382,6 +6378,7 @@ void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file){ FILE *CACHEFD = NULL; /* load the xml cache */ if (file != NULL) { + int ret=0; CACHEFD = fopen(file, "rb+"); xmlDocPtr cacheXml = NULL; if (CACHEFD) { @@ -6404,15 +6401,23 @@ void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file){ linphone_core_zrtp_cache_db_init(lc, tmpFile); /* migrate */ - if (bzrtp_cache_migration((void *)cacheXml, linphone_core_get_zrtp_cache_db(lc), linphone_core_get_identity(lc)) == 0) { - char *bkpFile = bctbx_malloc(strlen(file)+6); - sprintf(bkpFile,"%s.bkp", file); - /* migration went ok, rename the original file and replace it with by the tmp one and set the migration tag in config file */ - if (rename(file, bkpFile)==0 && rename(tmpFile, file)==0) { - lp_config_set_int(lc->config, "sip", "zrtp_cache_migration_done", TRUE); - } - bctbx_free(bkpFile); + char *bkpFile = bctbx_malloc(strlen(file)+6); + sprintf(bkpFile,"%s.bkp", file); + + if ((ret = ms_zrtp_cache_migration((void *)cacheXml, linphone_core_get_zrtp_cache_db(lc), linphone_core_get_identity(lc))) == 0) { + ms_message("LIME/ZRTP cache migration successfull, obsolete xml file kept as backup in %s", bkpFile); + } else { + ms_error("LIME/ZRTP cache migration failed(returned -%x), start with a fresh cache, old one kept as backup in %s", -ret, bkpFile); } + + /* rename the newly created sqlite3 file in to the given file name */ + rename(file, bkpFile); + if (rename(tmpFile, file)==0) { /* set the flag if we were able to set the sqlite file in the correct place (even if migration failed) */ + lp_config_set_int(lc->config, "sip", "zrtp_cache_migration_done", TRUE); + } + + /* clean up */ + bctbx_free(bkpFile); xmlFree(cacheXml); } bctbx_free(tmpFile); @@ -6420,11 +6425,6 @@ void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file){ linphone_core_zrtp_cache_db_init(lc, file); } } -#else /* HAVE_ZRTP */ -void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char* file){ - ms_error("linphone_core_set_zrtp_secrets_file(): no zrtp support in this build."); -} -#endif /* HAVE_ZRTP */ const char *linphone_core_get_zrtp_secrets_file(LinphoneCore *lc){ return lc->zrtp_secrets_cache; @@ -6447,9 +6447,9 @@ static void linphone_core_zrtp_cache_close(LinphoneCore *lc) { #endif /* SQLITE_STORAGE_ENABLED */ } -#if defined(SQLITE_STORAGE_ENABLED) && defined (HAVE_ZRTP) void linphone_core_zrtp_cache_db_init(LinphoneCore *lc, const char *fileName) { +#ifdef SQLITE_STORAGE_ENABLED int ret; const char *errmsg; sqlite3 *db; @@ -6465,17 +6465,23 @@ void linphone_core_zrtp_cache_db_init(LinphoneCore *lc, const char *fileName) { return; } - ret = bzrtp_initCache((void *)db); /* this may perform an update, check return value */ + ret = ms_zrtp_initCache((void *)db); /* this may perform an update, check return value */ - if (ret == BZRTP_CACHE_SETUP || ret == BZRTP_CACHE_UPDATE) { + if (ret == MSZRTP_CACHE_SETUP || ret == MSZRTP_CACHE_UPDATE) { /* After updating schema, database need to be closed/reopenned */ sqlite3_close(db); _linphone_sqlite3_open(fileName, &db); + } else if(ret != 0) { /* something went wrong */ + ms_error("Zrtp cache failed to initialise(returned -%x), run cacheless", -ret); + sqlite3_close(db); + lc->zrtp_cache_db = NULL; + return; } + /* everything ok, set the db pointer into core */ lc->zrtp_cache_db = db; -} #endif /* SQLITE_STORAGE_ENABLED */ +} void linphone_core_set_user_certificates_path(LinphoneCore *lc, const char* path){ char* new_value; From 68b4de89f107abcc5850b1ea6dc2b595beb840fe Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Tue, 18 Apr 2017 19:00:18 +0200 Subject: [PATCH 45/70] Fixed linphone_transports_new method + created LinphoneVideoActivationPolicy to replace LinphoneVideoPolicy --- coreapi/factory.c | 8 ++++++ coreapi/linphonecore.c | 54 +++++++++++++++++++++++++++++++++++--- coreapi/private.h | 16 +++++++++-- include/linphone/core.h | 52 ++++++++++++++++++++++++++++++++++++ include/linphone/factory.h | 14 ++++++++++ include/linphone/types.h | 8 ++++++ tester/call_video_tester.c | 5 ++-- tester/register_tester.c | 20 +++++++------- tester/video_tester.c | 11 ++++---- 9 files changed, 166 insertions(+), 22 deletions(-) diff --git a/coreapi/factory.c b/coreapi/factory.c index fa1fcd770..3ec5a770c 100644 --- a/coreapi/factory.c +++ b/coreapi/factory.c @@ -304,4 +304,12 @@ LinphoneErrorInfo *linphone_factory_create_error_info(LinphoneFactory *factory){ LinphoneRange *linphone_factory_create_range(LinphoneFactory *factory) { return linphone_range_new(); +} + +LinphoneTransports *linphone_factory_create_transports(LinphoneFactory *factory) { + return linphone_transports_new(); +} + +LinphoneVideoActivationPolicy *linphone_factory_create_video_activation_policy(LinphoneFactory *factory) { + return linphone_video_activation_policy_new(); } \ No newline at end of file diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 27de7fe7e..c549730e5 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -2769,7 +2769,7 @@ BELLE_SIP_INSTANCIATE_VPTR(LinphoneTransports, belle_sip_object_t, FALSE ); -LinphoneTransports *linphone_transports_new(LinphoneCore *lc) { +LinphoneTransports *linphone_transports_new() { LinphoneTransports *transports = belle_sip_object_new(LinphoneTransports); transports->udp_port = 0; transports->tcp_port = 0; @@ -2888,7 +2888,7 @@ LinphoneStatus linphone_core_get_sip_transports(LinphoneCore *lc, LinphoneSipTra } LinphoneTransports *linphone_core_get_transports(LinphoneCore *lc){ - LinphoneTransports *transports = linphone_transports_new(lc); + LinphoneTransports *transports = linphone_transports_new(); transports->udp_port = lc->sip_conf.transports.udp_port; transports->tcp_port = lc->sip_conf.transports.tcp_port; transports->tls_port = lc->sip_conf.transports.tls_port; @@ -2903,7 +2903,7 @@ void linphone_core_get_sip_transports_used(LinphoneCore *lc, LinphoneSipTranspor } LinphoneTransports *linphone_core_get_transports_used(LinphoneCore *lc){ - LinphoneTransports *transports = linphone_transports_new(lc); + LinphoneTransports *transports = linphone_transports_new(); transports->udp_port = sal_get_listening_port(lc->sal, SalTransportUDP); transports->tcp_port = sal_get_listening_port(lc->sal, SalTransportTCP); transports->tls_port = sal_get_listening_port(lc->sal, SalTransportTLS); @@ -4920,6 +4920,54 @@ const LinphoneVideoPolicy *linphone_core_get_video_policy(const LinphoneCore *lc return &lc->video_policy; } +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneVideoActivationPolicy); + +BELLE_SIP_INSTANCIATE_VPTR(LinphoneVideoActivationPolicy, belle_sip_object_t, + NULL, // destroy + NULL, // clone + NULL, // marshal + FALSE +); + +LinphoneVideoActivationPolicy *linphone_video_activation_policy_new() { + LinphoneVideoActivationPolicy *policy = belle_sip_object_new(LinphoneVideoActivationPolicy); + policy->automatically_accept = FALSE; + policy->automatically_initiate = FALSE; + return policy; +} + +LinphoneVideoActivationPolicy* linphone_video_activation_policy_ref(LinphoneVideoActivationPolicy* policy) { + return (LinphoneVideoActivationPolicy*) belle_sip_object_ref(policy); +} + +void linphone_video_activation_policy_unref(LinphoneVideoActivationPolicy* policy) { + belle_sip_object_unref(policy); +} + +void *linphone_video_activation_policy_get_user_data(const LinphoneVideoActivationPolicy *policy) { + return policy->user_data; +} + +void linphone_video_activation_policy_set_user_data(LinphoneVideoActivationPolicy *policy, void *data) { + policy->user_data = data; +} + +void linphone_core_set_video_activation_policy(LinphoneCore *lc, const LinphoneVideoActivationPolicy *policy) { + lc->video_policy.automatically_accept = policy->automatically_accept; + lc->video_policy.automatically_initiate = policy->automatically_initiate; + if (linphone_core_ready(lc)) { + lp_config_set_int(lc->config, "video", "automatically_initiate", policy->automatically_initiate); + lp_config_set_int(lc->config, "video", "automatically_accept", policy->automatically_accept); + } +} + +LinphoneVideoActivationPolicy *linphone_core_get_video_activation_policy(const LinphoneCore *lc){ + LinphoneVideoActivationPolicy *policy = linphone_video_activation_policy_new(); + policy->automatically_accept = lc->video_policy.automatically_accept; + policy->automatically_initiate = lc->video_policy.automatically_initiate; + return policy; +} + void linphone_core_enable_video_preview(LinphoneCore *lc, bool_t val){ lc->video_conf.show_local=val; if (linphone_core_ready(lc)) diff --git a/coreapi/private.h b/coreapi/private.h index 537337cf5..023acc490 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -1748,7 +1748,18 @@ struct _LinphoneTransports { BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneTransports); -LINPHONE_PUBLIC LinphoneTransports *linphone_transports_new(LinphoneCore *lc); +LinphoneTransports *linphone_transports_new(void); + +struct _LinphoneVideoActivationPolicy { + belle_sip_object_t base; + void *user_data; + bool_t automatically_initiate; /**stat; stats initial_callee_stat=callee->stat; - const LinphoneVideoPolicy *video_policy; + LinphoneVideoActivationPolicy *video_policy; LinphoneCall *call_obj; bool_t video_added = FALSE; @@ -233,7 +233,7 @@ bool_t request_video(LinphoneCoreManager* caller,LinphoneCoreManager* callee, bo BC_ASSERT_TRUE(wait_for(caller->lc,callee->lc,&callee->stat.number_of_LinphoneCallStreamsRunning,initial_callee_stat.number_of_LinphoneCallStreamsRunning+1)); BC_ASSERT_TRUE(wait_for(caller->lc,callee->lc,&caller->stat.number_of_LinphoneCallStreamsRunning,initial_caller_stat.number_of_LinphoneCallStreamsRunning+1)); - video_policy = linphone_core_get_video_policy(caller->lc); + video_policy = linphone_core_get_video_activation_policy(caller->lc); if (video_policy->automatically_accept || accept_with_params) { video_added = BC_ASSERT_TRUE(linphone_call_params_video_enabled(linphone_call_get_current_params(linphone_core_get_current_call(callee->lc)))); video_added = @@ -243,6 +243,7 @@ bool_t request_video(LinphoneCoreManager* caller,LinphoneCoreManager* callee, bo BC_ASSERT_FALSE(linphone_call_params_video_enabled(linphone_call_get_current_params(linphone_core_get_current_call(callee->lc)))); BC_ASSERT_FALSE(linphone_call_params_video_enabled(linphone_call_get_current_params(linphone_core_get_current_call(caller->lc)))); } + linphone_video_activation_policy_unref(video_policy); if (linphone_core_get_media_encryption(caller->lc) != LinphoneMediaEncryptionNone && linphone_core_get_media_encryption(callee->lc) != LinphoneMediaEncryptionNone) { const LinphoneCallParams* call_param; diff --git a/tester/register_tester.c b/tester/register_tester.c index b5159d48c..6989c8b1c 100644 --- a/tester/register_tester.c +++ b/tester/register_tester.c @@ -145,7 +145,7 @@ static void register_with_refresh_base_2(LinphoneCore* lc register_with_refresh_base_3(lc, refresh, domain, route, late_auth_info, transport,LinphoneRegistrationOk ); } static void register_with_refresh_base(LinphoneCore* lc, bool_t refresh,const char* domain,const char* route) { - LinphoneTransports *transport = linphone_transports_new(lc); + LinphoneTransports *transport = linphone_transports_new(); linphone_transports_set_udp_port(transport, 5070); linphone_transports_set_tcp_port(transport, 5070); linphone_transports_set_tls_port(transport, 5071); @@ -289,7 +289,7 @@ static void simple_tcp_register_compatibility_mode(void){ LinphoneTransports *transport = NULL; sprintf(route,"sip:%s",test_route); lcm = create_lcm(); - transport = linphone_transports_new(lcm->lc); + transport = linphone_transports_new(); linphone_transports_set_tcp_port(transport, 5070); register_with_refresh_base_2(lcm->lc,FALSE,test_domain,route,FALSE,transport); linphone_transports_unref(transport); @@ -369,7 +369,7 @@ static void authenticated_register_with_late_credentials(void){ sprintf(route,"sip:%s",test_route); lcm = linphone_core_manager_new(NULL); - transport = linphone_transports_new(lcm->lc); + transport = linphone_transports_new(); linphone_transports_set_udp_port(transport, 5070); linphone_transports_set_tcp_port(transport, 5070); linphone_transports_set_dtls_port(transport, 5071); @@ -435,7 +435,7 @@ static void authenticated_register_with_wrong_late_credentials(void){ sprintf(route,"sip:%s",test_route); lcm = linphone_core_manager_new(NULL); - transport = linphone_transports_new(lcm->lc); + transport = linphone_transports_new(); linphone_transports_set_udp_port(transport, 5070); linphone_transports_set_tcp_port(transport, 5070); linphone_transports_set_tls_port(transport, 5071); @@ -454,7 +454,7 @@ static void authenticated_register_with_wrong_late_credentials(void){ static void authenticated_register_with_wrong_credentials_with_params_base(const char* user_agent,LinphoneCoreManager *lcm) { stats* counters; - LinphoneTransports *transport = linphone_transports_new(lcm->lc); + LinphoneTransports *transport = linphone_transports_new(); LinphoneAuthInfo *info=linphone_auth_info_new(test_username,NULL,"wrong passwd",NULL,auth_domain,NULL); /*create authentication structure from identity*/ char route[256]; @@ -584,7 +584,7 @@ static void transport_change(void){ lcm=configure_lcm(); if (lcm) { lc=lcm->lc; - sip_tr = linphone_transports_new(lc); + sip_tr = linphone_transports_new(); counters = get_stats(lc); register_ok=counters->number_of_LinphoneRegistrationOk; @@ -609,7 +609,7 @@ static void transport_change(void){ static void transport_dont_bind(void){ LinphoneCoreManager *pauline = linphone_core_manager_new("pauline_tcp_rc"); stats* counters = &pauline->stat; - LinphoneTransports *tr = linphone_transports_new(pauline->lc); + LinphoneTransports *tr = linphone_transports_new(); linphone_transports_set_tcp_port(tr, LC_SIP_TRANSPORT_DONTBIND); linphone_transports_set_tls_port(tr, LC_SIP_TRANSPORT_DONTBIND); @@ -690,7 +690,7 @@ static void proxy_transport_change_with_wrong_port(void) { LinphoneProxyConfig* proxy_config; LinphoneAuthInfo *info=linphone_auth_info_new(test_username,NULL,test_password,NULL,auth_domain,NULL); /*create authentication structure from identity*/ char route[256]; - LinphoneTransports *transport= linphone_transports_new(lcm->lc); + LinphoneTransports *transport= linphone_transports_new(); sprintf(route,"sip:%s",test_route); linphone_transports_set_udp_port(transport, LC_SIP_TRANSPORT_RANDOM); linphone_transports_set_tcp_port(transport, LC_SIP_TRANSPORT_RANDOM); @@ -726,7 +726,7 @@ static void proxy_transport_change_with_wrong_port_givin_up(void) { LinphoneProxyConfig* proxy_config; LinphoneAuthInfo *info=linphone_auth_info_new(test_username,NULL,test_password,NULL,auth_domain,NULL); /*create authentication structure from identity*/ char route[256]; - LinphoneTransports *transport = linphone_transports_new(lcm->lc); + LinphoneTransports *transport = linphone_transports_new(); sprintf(route,"sip:%s",test_route); linphone_transports_set_udp_port(transport, LC_SIP_TRANSPORT_RANDOM); linphone_transports_set_tcp_port(transport, LC_SIP_TRANSPORT_RANDOM); @@ -1018,7 +1018,7 @@ static void redirect(void){ sprintf(route,"sip:%s:5064",test_route); lcm = create_lcm(); if (lcm) { - transport = linphone_transports_new(lcm->lc); + transport = linphone_transports_new(); linphone_transports_set_udp_port(transport, -1); linphone_core_set_user_agent(lcm->lc,"redirect",NULL); register_with_refresh_base_2(lcm->lc,FALSE,test_domain,route,FALSE,transport); diff --git a/tester/video_tester.c b/tester/video_tester.c index bab0f9947..2921d6bf7 100644 --- a/tester/video_tester.c +++ b/tester/video_tester.c @@ -414,24 +414,25 @@ static void forked_outgoing_early_media_video_call_with_inactive_audio_test(void LinphoneCallParams *pauline_params; LinphoneCallParams *marie1_params; LinphoneCallParams *marie2_params; - LinphoneVideoPolicy pol; + LinphoneVideoActivationPolicy *pol = linphone_video_activation_policy_new(); LinphoneCall *marie1_call; LinphoneCall *marie2_call; LinphoneCall *pauline_call; LinphoneInfoMessage *info; int dummy = 0; - pol.automatically_accept = 1; - pol.automatically_initiate = 1; + pol->automatically_accept = TRUE; + pol->automatically_initiate = TRUE; LinphoneRange *port_range = NULL; linphone_core_enable_video_capture(pauline->lc, TRUE); linphone_core_enable_video_display(pauline->lc, TRUE); linphone_core_enable_video_capture(marie1->lc, TRUE); linphone_core_enable_video_display(marie1->lc, TRUE); - linphone_core_set_video_policy(marie1->lc, &pol); + linphone_core_set_video_activation_policy(marie1->lc, pol); linphone_core_enable_video_capture(marie2->lc, TRUE); linphone_core_enable_video_display(marie2->lc, TRUE); - linphone_core_set_video_policy(marie2->lc, &pol); + linphone_core_set_video_activation_policy(marie2->lc, pol); + linphone_video_activation_policy_unref(pol); linphone_core_set_audio_port_range(marie2->lc, 40200, 40300); port_range = linphone_core_get_audio_ports_range(marie2->lc); BC_ASSERT_EQUAL(port_range->min, 40200, int, "%i"); From d53a2f4f054bcf0649bfa44b3d32c64f1828af98 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 19 Apr 2017 12:05:05 +0200 Subject: [PATCH 46/70] Fix crashes related to LinphoneVideoDefinition. --- coreapi/call_params.c | 8 +++++--- coreapi/linphonecall.c | 6 +++--- coreapi/linphonecore.c | 3 ++- 3 files changed, 10 insertions(+), 7 deletions(-) diff --git a/coreapi/call_params.c b/coreapi/call_params.c index 8715ed049..b1bbf7d20 100644 --- a/coreapi/call_params.c +++ b/coreapi/call_params.c @@ -325,8 +325,6 @@ LinphoneCallParams * linphone_call_params_ref(LinphoneCallParams *cp) { } void linphone_call_params_unref(LinphoneCallParams *cp) { - if (cp->sent_vdef != NULL) linphone_video_definition_unref(cp->sent_vdef); - if (cp->recv_vdef != NULL) linphone_video_definition_unref(cp->recv_vdef); belle_sip_object_unref(cp); } @@ -358,6 +356,8 @@ static void _linphone_call_params_uninit(LinphoneCallParams *cp){ if (cp->custom_sdp_media_attributes[i]) sal_custom_sdp_attribute_free(cp->custom_sdp_media_attributes[i]); } if (cp->session_name) ms_free(cp->session_name); + if (cp->sent_vdef != NULL) linphone_video_definition_unref(cp->sent_vdef); + if (cp->recv_vdef != NULL) linphone_video_definition_unref(cp->recv_vdef); } static void _linphone_call_params_clone(LinphoneCallParams *dst, const LinphoneCallParams *src) { @@ -369,7 +369,9 @@ static void _linphone_call_params_clone(LinphoneCallParams *dst, const LinphoneC belle_sip_object_t tmp = dst->base; memcpy(dst, src, sizeof(LinphoneCallParams)); dst->base = tmp; - + + if (src->sent_vdef) dst->sent_vdef = linphone_video_definition_ref(src->sent_vdef); + if (src->recv_vdef) dst->recv_vdef = linphone_video_definition_ref(src->recv_vdef); if (src->record_file) dst->record_file=ms_strdup(src->record_file); if (src->session_name) dst->session_name=ms_strdup(src->session_name); /* diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index ce6e67302..3ce529cac 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -1964,13 +1964,13 @@ const LinphoneCallParams * linphone_call_get_current_params(LinphoneCall *call){ #ifdef VIDEO_ENABLED VideoStream *vstream; #endif + MS_VIDEO_SIZE_ASSIGN(call->current_params->sent_vsize, UNKNOWN); + MS_VIDEO_SIZE_ASSIGN(call->current_params->recv_vsize, UNKNOWN); +#ifdef VIDEO_ENABLED if (call->current_params->sent_vdef != NULL) linphone_video_definition_unref(call->current_params->sent_vdef); call->current_params->sent_vdef = NULL; if (call->current_params->recv_vdef != NULL) linphone_video_definition_unref(call->current_params->recv_vdef); call->current_params->recv_vdef = NULL; - MS_VIDEO_SIZE_ASSIGN(call->current_params->sent_vsize, UNKNOWN); - MS_VIDEO_SIZE_ASSIGN(call->current_params->recv_vsize, UNKNOWN); -#ifdef VIDEO_ENABLED vstream = call->videostream; if (vstream != NULL) { call->current_params->sent_vsize = video_stream_get_sent_video_size(vstream); diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index c549730e5..2742294c5 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -5846,7 +5846,8 @@ static void sound_config_uninit(LinphoneCore *lc) static void video_config_uninit(LinphoneCore *lc) { - lp_config_set_string(lc->config,"video","size",linphone_video_definition_get_name(linphone_core_get_preferred_video_definition(lc))); + const LinphoneVideoDefinition *vdef = linphone_core_get_preferred_video_definition(lc); + lp_config_set_string(lc->config,"video","size",vdef ? linphone_video_definition_get_name(vdef) : NULL); lp_config_set_int(lc->config,"video","display",lc->video_conf.display); lp_config_set_int(lc->config,"video","capture",lc->video_conf.capture); if (lc->video_conf.cams) From 33f261bc82384b463e647f013a6d1529b27f42cc Mon Sep 17 00:00:00 2001 From: Jehan Monnier Date: Wed, 19 Apr 2017 12:27:05 +0200 Subject: [PATCH 47/70] remove direct build dependency on BZRTP unless LIME enabled --- CMakeLists.txt | 24 +++++------------------- 1 file changed, 5 insertions(+), 19 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index a63f9f11d..caca495c3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -46,8 +46,7 @@ option(ENABLE_JAVADOC "Add a target to generate documentation for Java API" NO) option(ENABLE_GTK_UI "Turn on or off compilation of gtk interface." YES) option(ENABLE_LDAP "Enable LDAP support." NO) option(ENABLE_SQLITE_STORAGE "Turn on compilation sqlite storage, for messages, contacts, history" YES) -option(ENABLE_ZRTP "Buid linphone with ZRTP support" YES) -cmake_dependent_option(ENABLE_LIME "Enable Instant Messaging Encryption." YES "ENABLE_ZRTP;ENABLE_SQLITE_STORAGE" NO) +cmake_dependent_option(ENABLE_LIME "Enable Instant Messaging Encryption." YES "ENABLE_SQLITE_STORAGE" NO) cmake_dependent_option(ENABLE_NOTIFY "Enable libnotify support." YES "ENABLE_GTK_UI;NOT APPLE" NO) option(ENABLE_RELATIVE_PREFIX "Find resources relatively to the installation directory." NO) option(ENABLE_STRICT "Build with strict compile options." YES) @@ -172,27 +171,14 @@ if(ENABLE_NLS) find_package(Gettext REQUIRED) find_package(Intl REQUIRED) endif() -if(ENABLE_ZRTP) +if(ENABLE_LIME) + #bzrtp is only required for LIME if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS) include("${EP_bzrtp_CONFIG_DIR}/BZRTPConfig.cmake") else() - find_package(BZRTP) + find_package(BZRTP REQUIRED) endif() - if(NOT BZRTP_FOUND) - message(WARNING "Could not find bzrtp library, linphone will be compiled without ZRTP support.") - set(ENABLE_ZRTP OFF CACHE BOOL "Build linphone with ZRTP support." FORCE) - endif() -endif() -if(ENABLE_LIME) - if(BZRTP_FOUND) - set(HAVE_LIME 1) - else() - message(WARNING "LIME enabled but could not find bzrtp library, linphone will be compiled without LIME support.") - set(ENABLE_LIME OFF CACHE BOOL "Enable Instant Messaging Encryption." FORCE) - endif() -endif() -if(BZRTP_FOUND) - set(HAVE_ZRTP 1) + set(HAVE_LIME 1) endif() if(ENABLE_CXX_WRAPPER) find_package(PythonInterp REQUIRED) From 9adce33173d32bd8aa561f34c22d3556490fd28a Mon Sep 17 00:00:00 2001 From: Erwan Croze Date: Wed, 19 Apr 2017 13:35:22 +0200 Subject: [PATCH 48/70] Rename new create proxy config of account creator --- coreapi/account_creator.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coreapi/account_creator.c b/coreapi/account_creator.c index cb859f163..e10b26772 100644 --- a/coreapi/account_creator.c +++ b/coreapi/account_creator.c @@ -108,7 +108,7 @@ static bool_t is_matching_regex(const char *entry, const char* regex) { #endif } -LinphoneProxyConfig * linphone_account_creator_configure_proxy_config(const LinphoneAccountCreator *creator) { +LinphoneProxyConfig * linphone_account_creator_create_proxy_config(const LinphoneAccountCreator *creator) { LinphoneAuthInfo *info; LinphoneProxyConfig *cfg = linphone_core_create_proxy_config(creator->core); char *identity_str = _get_identity(creator); From b6f74357e01c289d97e3afa2dbc46bce45d7cca8 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 19 Apr 2017 14:28:17 +0200 Subject: [PATCH 49/70] delete JNI weak refs when the java object (LinphoneFriend or LinphoneChatMessage) is finalized. This will avoid a periodic weak ref overflow. --- coreapi/linphonecore_jni.cc | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index d757b7a70..cd4dc2163 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -4191,7 +4191,11 @@ extern "C" void Java_org_linphone_core_LinphoneFriendImpl_finalize(JNIEnv* env ,jobject thiz ,jlong ptr) { LinphoneFriend *lfriend=(LinphoneFriend*)ptr; + jobject wref = (jobject)linphone_friend_get_user_data(lfriend); linphone_friend_set_user_data(lfriend,NULL); + if (wref){ + env->DeleteWeakGlobalRef(wref); + } linphone_friend_unref(lfriend); } @@ -4727,7 +4731,11 @@ extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_setListener(JNIEn extern "C" void Java_org_linphone_core_LinphoneChatMessageImpl_unref(JNIEnv* env ,jobject thiz ,jlong ptr) { + jobject wref = (jobject)linphone_chat_message_get_user_data((LinphoneChatMessage*)ptr); linphone_chat_message_set_user_data((LinphoneChatMessage*)ptr, NULL); + if (wref){ + env->DeleteWeakGlobalRef(wref); + } linphone_chat_message_unref((LinphoneChatMessage*)ptr); } From 401128331335ce4f089385a153bbb2adc32f49c1 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 19 Apr 2017 14:50:15 +0200 Subject: [PATCH 50/70] Add linphone_video_definition_clone(). --- coreapi/factory.c | 4 ++-- coreapi/video_definition.c | 3 +++ include/linphone/video_definition.h | 7 +++++++ 3 files changed, 12 insertions(+), 2 deletions(-) diff --git a/coreapi/factory.c b/coreapi/factory.c index 3ec5a770c..5601a620b 100644 --- a/coreapi/factory.c +++ b/coreapi/factory.c @@ -206,7 +206,7 @@ LinphoneVideoDefinition * linphone_factory_find_supported_video_definition(const LinphoneVideoDefinition *svdef = (LinphoneVideoDefinition *)bctbx_list_get_data(item); if (linphone_video_definition_equals(svdef, searched_vdef)) { linphone_video_definition_unref(searched_vdef); - return svdef; + return linphone_video_definition_clone(svdef); } } @@ -220,7 +220,7 @@ LinphoneVideoDefinition * linphone_factory_find_supported_video_definition_by_na for (item = supported; item != NULL; item = bctbx_list_next(item)) { LinphoneVideoDefinition *svdef = (LinphoneVideoDefinition *)bctbx_list_get_data(item); if (strcmp(linphone_video_definition_get_name(svdef), name) == 0) { - return svdef; + return linphone_video_definition_clone(svdef); } } return NULL; diff --git a/coreapi/video_definition.c b/coreapi/video_definition.c index ee68b76d1..57329d154 100644 --- a/coreapi/video_definition.c +++ b/coreapi/video_definition.c @@ -66,6 +66,9 @@ void linphone_video_definition_set_user_data(LinphoneVideoDefinition *vdef, void vdef->user_data = ud; } +LinphoneVideoDefinition * linphone_video_definition_clone(const LinphoneVideoDefinition *vdef) { + return linphone_video_definition_new(linphone_video_definition_get_width(vdef), linphone_video_definition_get_height(vdef), linphone_video_definition_get_name(vdef)); +} unsigned int linphone_video_definition_get_width(const LinphoneVideoDefinition *vdef) { return vdef->width; diff --git a/include/linphone/video_definition.h b/include/linphone/video_definition.h index 5d5bb6220..c89b545d7 100644 --- a/include/linphone/video_definition.h +++ b/include/linphone/video_definition.h @@ -61,6 +61,13 @@ LINPHONE_PUBLIC void *linphone_video_definition_get_user_data(const LinphoneVide **/ LINPHONE_PUBLIC void linphone_video_definition_set_user_data(LinphoneVideoDefinition *vdef, void *ud); +/** + * Clone a video definition. + * @param[in] vdef LinphoneVideoDefinition object to be cloned + * @return The new clone of the video definition + */ +LINPHONE_PUBLIC LinphoneVideoDefinition * linphone_video_definition_clone(const LinphoneVideoDefinition *vdef); + /** * Get the width of the video definition. * @param[in] vdef LinphoneVideoDefinition object From b10240dc4975d256f1f694f9a52edebc63d95c0a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Wed, 19 Apr 2017 14:59:49 +0200 Subject: [PATCH 51/70] Fix crash while parsing XML documentation --- include/linphone/core.h | 1 + 1 file changed, 1 insertion(+) diff --git a/include/linphone/core.h b/include/linphone/core.h index f5631047e..81b14c284 100644 --- a/include/linphone/core.h +++ b/include/linphone/core.h @@ -3209,6 +3209,7 @@ LINPHONE_PUBLIC bool_t linphone_core_video_display_enabled(LinphoneCore *lc); * This policy defines whether: * - video shall be initiated by default for outgoing calls * - video shall be accepter by default for incoming calls + * * @param[in] lc LinphoneCore object * @param[in] policy The video policy to use * @ingroup media_parameters From 379a7df153e62d24937e858ce38e26859910838d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Wed, 19 Apr 2017 15:03:23 +0200 Subject: [PATCH 52/70] Add LINPHONE_DEPRECATED on functions which are marked as deprecated in their documentation --- include/linphone/core.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/include/linphone/core.h b/include/linphone/core.h index 81b14c284..d6d8ac3ec 100644 --- a/include/linphone/core.h +++ b/include/linphone/core.h @@ -3215,7 +3215,7 @@ LINPHONE_PUBLIC bool_t linphone_core_video_display_enabled(LinphoneCore *lc); * @ingroup media_parameters * @deprecated **/ -LINPHONE_PUBLIC void linphone_core_set_video_policy(LinphoneCore *lc, const LinphoneVideoPolicy *policy); +LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_core_set_video_policy(LinphoneCore *lc, const LinphoneVideoPolicy *policy); /** * Get the default policy for video. @@ -3225,7 +3225,7 @@ LINPHONE_PUBLIC void linphone_core_set_video_policy(LinphoneCore *lc, const Linp * @ingroup media_parameters * @deprecated **/ -LINPHONE_PUBLIC const LinphoneVideoPolicy *linphone_core_get_video_policy(const LinphoneCore *lc); +LINPHONE_PUBLIC LINPHONE_DEPRECATED const LinphoneVideoPolicy *linphone_core_get_video_policy(const LinphoneCore *lc); /** * Increment refcount. From 1dcd17198ee56ef54a5bb03b477575e83c29892d Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Wed, 19 Apr 2017 15:35:47 +0200 Subject: [PATCH 53/70] Fix wrong logic in linphone_core_set_preferred_video_definition(). --- coreapi/linphonecore.c | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 2742294c5..0620e2107 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -5319,20 +5319,15 @@ static bool_t video_definition_supported(const LinphoneVideoDefinition *vdef) { void linphone_core_set_preferred_video_definition(LinphoneCore *lc, LinphoneVideoDefinition *vdef) { if (video_definition_supported(vdef)) { - LinphoneVideoDefinition *oldvdef; - if ((lc->video_conf.vdef == NULL) || linphone_video_definition_is_undefined(lc->video_conf.preview_vdef)) { - oldvdef = lc->video_conf.vdef; - } else { - oldvdef = lc->video_conf.preview_vdef; - } - if ((oldvdef == NULL) || !linphone_video_definition_equals(oldvdef, vdef)) { - lc->video_conf.vdef = linphone_video_definition_ref(vdef); - if (oldvdef != NULL) linphone_video_definition_unref(oldvdef); - if (lc->previewstream != NULL) { - relaunch_video_preview(lc); - } + LinphoneVideoDefinition *oldvdef = lc->video_conf.vdef; + lc->video_conf.vdef = linphone_video_definition_ref(vdef); + + if ((lc->previewstream != NULL) && (lc->video_conf.preview_vdef == NULL) + && (oldvdef != NULL) && !linphone_video_definition_equals(oldvdef, vdef)) { + relaunch_video_preview(lc); } + if (oldvdef != NULL) linphone_video_definition_unref(oldvdef); if (linphone_core_ready(lc)) { lp_config_set_string(lc->config, "video", "size", linphone_video_definition_get_name(vdef)); } From 83b94af9a4fa3a78292511976edd0c2c19a41149 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 19 Apr 2017 15:31:20 +0200 Subject: [PATCH 54/70] LinphoneCallStats is now a belle_sip_object. BREAKS BINARY COMPATIBILITY --- CMakeLists.txt | 2 +- configure.ac | 2 +- coreapi/linphonecall.c | 177 +++++++++++++++++++++----- coreapi/misc.c | 50 ++++---- coreapi/private.h | 42 +++++- coreapi/quality_reporting.c | 20 ++- daemon/commands/audio-stream-stats.cc | 2 +- daemon/daemon.cc | 16 +-- daemon/daemon.h | 3 +- gtk/incall_view.c | 36 ++++-- include/linphone/call.h | 10 +- include/linphone/call_stats.h | 60 +++++---- tester/call_multicast_tester.c | 9 +- tester/call_single_tester.c | 89 ++++++++----- tester/complex_sip_case_tester.c | 15 ++- tester/tester.c | 29 ++++- tester/video_tester.c | 42 ++++-- 17 files changed, 426 insertions(+), 178 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index caca495c3..ddf41d3ae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ ############################################################################ cmake_minimum_required(VERSION 3.0) -project(linphone VERSION 3.11.1 LANGUAGES C CXX) +project(linphone VERSION 3.11.2 LANGUAGES C CXX) set(LINPHONE_MAJOR_VERSION ${PROJECT_VERSION_MAJOR}) diff --git a/configure.ac b/configure.ac index 46a0e2b85..f1180465b 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ dnl Process this file with autoconf to produce a configure script. -AC_INIT([linphone],[3.11.1],[linphone-developers@nongnu.org]) +AC_INIT([linphone],[3.11.2],[linphone-developers@nongnu.org]) AC_CANONICAL_SYSTEM AC_CONFIG_SRCDIR([coreapi/linphonecore.c]) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 3ce529cac..7444fd23b 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -1106,9 +1106,9 @@ static void linphone_call_init_common(LinphoneCall *call, LinphoneAddress *from, linphone_core_get_text_port_range(call->core, &min_port, &max_port); port_config_set(call,call->main_text_stream_index,min_port,max_port); - linphone_call_init_stats(&call->stats[LINPHONE_CALL_STATS_AUDIO], LINPHONE_CALL_STATS_AUDIO); - linphone_call_init_stats(&call->stats[LINPHONE_CALL_STATS_VIDEO], LINPHONE_CALL_STATS_VIDEO); - linphone_call_init_stats(&call->stats[LINPHONE_CALL_STATS_TEXT], LINPHONE_CALL_STATS_TEXT); + linphone_call_init_stats(call->audio_stats, LINPHONE_CALL_STATS_AUDIO); + linphone_call_init_stats(call->video_stats, LINPHONE_CALL_STATS_VIDEO); + linphone_call_init_stats(call->text_stats, LINPHONE_CALL_STATS_TEXT); } void linphone_call_init_stats(LinphoneCallStats *stats, int type) { @@ -1307,6 +1307,9 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr call->dir=LinphoneCallOutgoing; call->core=lc; call->dest_proxy=cfg; + call->audio_stats = linphone_call_stats_new(); + call->video_stats = linphone_call_stats_new(); + call->text_stats = linphone_call_stats_new(); linphone_call_outgoing_select_ip_version(call,to,cfg); linphone_call_get_local_ip(call, to); call->params = linphone_call_params_copy(params); @@ -1489,6 +1492,9 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro LinphoneNatPolicy *nat_policy = NULL; int i; call->dir=LinphoneCallIncoming; + call->audio_stats = linphone_call_stats_new(); + call->video_stats = linphone_call_stats_new(); + call->text_stats = linphone_call_stats_new(); sal_op_set_user_pointer(op,call); call->op=op; call->core=lc; @@ -1613,9 +1619,9 @@ static void linphone_call_free_media_resources(LinphoneCall *call){ for (i = 0; i < SAL_MEDIA_DESCRIPTION_MAX_STREAMS; ++i){ ms_media_stream_sessions_uninit(&call->sessions[i]); } - linphone_call_stats_uninit(&call->stats[LINPHONE_CALL_STATS_AUDIO]); - linphone_call_stats_uninit(&call->stats[LINPHONE_CALL_STATS_VIDEO]); - linphone_call_stats_uninit(&call->stats[LINPHONE_CALL_STATS_TEXT]); + linphone_call_stats_uninit(call->audio_stats); + linphone_call_stats_uninit(call->video_stats); + linphone_call_stats_uninit(call->text_stats); } /* @@ -1872,6 +1878,18 @@ static void linphone_call_destroy(LinphoneCall *obj){ if (obj->audiostream || obj->videostream){ linphone_call_free_media_resources(obj); } + if (obj->audio_stats) { + linphone_call_stats_unref(obj->audio_stats); + obj->audio_stats = NULL; + } + if (obj->video_stats) { + linphone_call_stats_unref(obj->video_stats); + obj->video_stats = NULL; + } + if (obj->text_stats) { + linphone_call_stats_unref(obj->text_stats); + obj->text_stats = NULL; + } if (obj->op!=NULL) { sal_op_release(obj->op); obj->op=NULL; @@ -3907,9 +3925,9 @@ void linphone_call_delete_ice_session(LinphoneCall *call){ if (call->audiostream != NULL) call->audiostream->ms.ice_check_list = NULL; if (call->videostream != NULL) call->videostream->ms.ice_check_list = NULL; if (call->textstream != NULL) call->textstream->ms.ice_check_list = NULL; - call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateNotActivated; - call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateNotActivated; - call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateNotActivated; + call->audio_stats->ice_state = LinphoneIceStateNotActivated; + call->video_stats->ice_state = LinphoneIceStateNotActivated; + call->text_stats->ice_state = LinphoneIceStateNotActivated; } } @@ -3934,7 +3952,15 @@ static void linphone_call_log_fill_stats(LinphoneCallLog *log, MediaStream *st){ static void update_rtp_stats(LinphoneCall *call, int stream_index) { if (call->sessions[stream_index].rtp_session) { const rtp_stats_t *stats = rtp_session_get_stats(call->sessions[stream_index].rtp_session); - memcpy(&call->stats[stream_index].rtp_stats, stats, sizeof(*stats)); + LinphoneCallStats *call_stats = NULL; + if (stream_index == call->main_audio_stream_index) { + call_stats = call->audio_stats; + } else if (stream_index == call->main_video_stream_index) { + call_stats = call->video_stats; + } else { + call_stats = call->text_stats; + } + if (call_stats) memcpy(&(call_stats->rtp_stats), stats, sizeof(*stats)); } } @@ -4202,26 +4228,47 @@ static MediaStream *linphone_call_get_stream(LinphoneCall *call, LinphoneStreamT return NULL; } -const LinphoneCallStats *linphone_call_get_stats(LinphoneCall *call, LinphoneStreamType type){ +static void _linphone_call_stats_clone(LinphoneCallStats *dst, const LinphoneCallStats *src) { + /* + * Save the belle_sip_object_t part, copy the entire structure and restore the belle_sip_object_t part + */ + belle_sip_object_t tmp = dst->base; + memcpy(dst, src, sizeof(LinphoneCallStats)); + dst->base = tmp; + + dst->received_rtcp = NULL; + dst->sent_rtcp = NULL; +} + +LinphoneCallStats *linphone_call_get_stats(LinphoneCall *call, LinphoneStreamType type){ if ((int)type >=0 && type<=LinphoneStreamTypeText){ - LinphoneCallStats *stats = &call->stats[type]; + LinphoneCallStats *stats = NULL; + LinphoneCallStats *stats_copy = linphone_call_stats_new(); + if (type == LinphoneStreamTypeAudio) { + stats = call->audio_stats; + } else if (type == LinphoneStreamTypeVideo) { + stats = call->video_stats; + } else if (type == LinphoneStreamTypeText) { + stats = call->text_stats; + } MediaStream *ms = linphone_call_get_stream(call, type); - if (ms) update_local_stats(stats, ms); - return stats; + if (ms && stats) update_local_stats(stats, ms); + _linphone_call_stats_clone(stats_copy, stats); + return stats_copy; } ms_error("Invalid stream type %i", (int)type); return NULL; } -const LinphoneCallStats *linphone_call_get_audio_stats(LinphoneCall *call) { +LinphoneCallStats *linphone_call_get_audio_stats(LinphoneCall *call) { return linphone_call_get_stats(call, LinphoneStreamTypeAudio); } -const LinphoneCallStats *linphone_call_get_video_stats(LinphoneCall *call) { +LinphoneCallStats *linphone_call_get_video_stats(LinphoneCall *call) { return linphone_call_get_stats(call, LinphoneStreamTypeVideo); } -const LinphoneCallStats *linphone_call_get_text_stats(LinphoneCall *call) { +LinphoneCallStats *linphone_call_get_text_stats(LinphoneCall *call) { return linphone_call_get_stats(call, LinphoneStreamTypeText); } @@ -4231,12 +4278,42 @@ static bool_t ice_in_progress(LinphoneCallStats *stats){ bool_t linphone_call_media_in_progress(LinphoneCall *call){ bool_t ret=FALSE; - if (ice_in_progress(&call->stats[LINPHONE_CALL_STATS_AUDIO]) || ice_in_progress(&call->stats[LINPHONE_CALL_STATS_VIDEO]) || ice_in_progress(&call->stats[LINPHONE_CALL_STATS_TEXT])) + if (ice_in_progress(call->audio_stats) || ice_in_progress(call->video_stats) || ice_in_progress(call->text_stats)) ret=TRUE; /*TODO: could check zrtp state, upnp state*/ return ret; } +BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneCallStats); + +BELLE_SIP_INSTANCIATE_VPTR(LinphoneCallStats, belle_sip_object_t, + NULL, // destroy + _linphone_call_stats_clone, // clone + NULL, // marshal + FALSE +); + +LinphoneCallStats *linphone_call_stats_new() { + LinphoneCallStats *stats = belle_sip_object_new(LinphoneCallStats); + return stats; +} + +LinphoneCallStats* linphone_call_stats_ref(LinphoneCallStats* stats) { + return (LinphoneCallStats*) belle_sip_object_ref(stats); +} + +void linphone_call_stats_unref(LinphoneCallStats* stats) { + belle_sip_object_unref(stats); +} + +void *linphone_call_stats_get_user_data(const LinphoneCallStats *stats) { + return stats->user_data; +} + +void linphone_call_stats_set_user_data(LinphoneCallStats *stats, void *data) { + stats->user_data = data; +} + LinphoneStreamType linphone_call_stats_get_type(const LinphoneCallStats *stats) { return stats->type; } @@ -4355,6 +4432,10 @@ float linphone_call_stats_get_jitter_buffer_size_ms(const LinphoneCallStats *sta return stats->jitter_stats.jitter_buffer_size_ms; } +float linphone_call_stats_get_round_trip_delay(const LinphoneCallStats *stats) { + return stats->round_trip_delay; +} + void linphone_call_start_recording(LinphoneCall *call){ if (!call->params->record_file){ ms_error("linphone_call_start_recording(): no output file specified. Use linphone_call_params_set_record_file()."); @@ -4375,7 +4456,16 @@ void linphone_call_stop_recording(LinphoneCall *call){ static void report_bandwidth_for_stream(LinphoneCall *call, MediaStream *ms, LinphoneStreamType type){ bool_t active = ms ? (media_stream_get_state(ms) == MSStreamStarted) : FALSE; - LinphoneCallStats *stats = &call->stats[type]; + LinphoneCallStats *stats = NULL; + if (type == LinphoneStreamTypeAudio) { + stats = call->audio_stats; + } else if (type == LinphoneStreamTypeAudio) { + stats = call->video_stats; + } else if (type == LinphoneStreamTypeAudio) { + stats = call->text_stats; + } else { + return; + } stats->download_bandwidth=(active) ? (float)(media_stream_get_down_bw(ms)*1e-3) : 0.f; stats->upload_bandwidth=(active) ? (float)(media_stream_get_up_bw(ms)*1e-3) : 0.f; @@ -4401,18 +4491,18 @@ static void report_bandwidth(LinphoneCall *call, MediaStream *as, MediaStream *v "\tRTP audio=[d=%5.1f,u=%5.1f], video=[d=%5.1f,u=%5.1f], text=[d=%5.1f,u=%5.1f] kbits/sec\n" "\tRTCP audio=[d=%5.1f,u=%5.1f], video=[d=%5.1f,u=%5.1f], text=[d=%5.1f,u=%5.1f] kbits/sec", call, - call->stats[LINPHONE_CALL_STATS_AUDIO].download_bandwidth, - call->stats[LINPHONE_CALL_STATS_AUDIO].upload_bandwidth, - call->stats[LINPHONE_CALL_STATS_VIDEO].download_bandwidth, - call->stats[LINPHONE_CALL_STATS_VIDEO].upload_bandwidth, - call->stats[LINPHONE_CALL_STATS_TEXT].download_bandwidth, - call->stats[LINPHONE_CALL_STATS_TEXT].upload_bandwidth, - call->stats[LINPHONE_CALL_STATS_AUDIO].rtcp_download_bandwidth, - call->stats[LINPHONE_CALL_STATS_AUDIO].rtcp_upload_bandwidth, - call->stats[LINPHONE_CALL_STATS_VIDEO].rtcp_download_bandwidth, - call->stats[LINPHONE_CALL_STATS_VIDEO].rtcp_upload_bandwidth, - call->stats[LINPHONE_CALL_STATS_TEXT].rtcp_download_bandwidth, - call->stats[LINPHONE_CALL_STATS_TEXT].rtcp_upload_bandwidth + call->audio_stats->download_bandwidth, + call->audio_stats->upload_bandwidth, + call->video_stats->download_bandwidth, + call->video_stats->upload_bandwidth, + call->text_stats->download_bandwidth, + call->text_stats->upload_bandwidth, + call->audio_stats->rtcp_download_bandwidth, + call->audio_stats->rtcp_upload_bandwidth, + call->video_stats->rtcp_download_bandwidth, + call->video_stats->rtcp_upload_bandwidth, + call->text_stats->rtcp_download_bandwidth, + call->text_stats->rtcp_upload_bandwidth ); } @@ -4545,7 +4635,14 @@ void linphone_call_stats_uninit(LinphoneCallStats *stats){ } void linphone_call_notify_stats_updated_with_stream_index(LinphoneCall *call, int stream_index){ - LinphoneCallStats *stats = &call->stats[stream_index]; + LinphoneCallStats *stats = NULL; + if (stream_index == call->main_audio_stream_index) { + stats = call->audio_stats; + } else if (stream_index == call->main_video_stream_index) { + stats = call->video_stats; + } else { + stats = call->text_stats; + } if (stats->updated){ switch(stats->updated) { case LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE: @@ -4615,13 +4712,25 @@ void linphone_call_handle_stream_events(LinphoneCall *call, int stream_index){ while((evq = linphone_call_get_event_queue(call, stream_index)) != NULL && NULL != (ev=ortp_ev_queue_get(evq))){ OrtpEventType evt=ortp_event_get_type(ev); OrtpEventData *evd=ortp_event_get_data(ev); - int stats_index = stream_index == call->main_audio_stream_index ? LINPHONE_CALL_STATS_AUDIO : (stream_index == call->main_video_stream_index ? LINPHONE_CALL_STATS_VIDEO : LINPHONE_CALL_STATS_TEXT); + int stats_index; + LinphoneCallStats *stats = NULL; + + if (stream_index == call->main_audio_stream_index) { + stats_index = LINPHONE_CALL_STATS_AUDIO; + stats = call->audio_stats; + } else if (stream_index == call->main_video_stream_index) { + stats_index = LINPHONE_CALL_STATS_VIDEO; + stats = call->video_stats; + } else { + stats_index = LINPHONE_CALL_STATS_TEXT; + stats = call->text_stats; + } /*and yes the MediaStream must be taken at each iteration, because it may have changed due to the handling of events * in this loop*/ ms = linphone_call_get_media_stream(call, stream_index); - if (ms) linphone_call_stats_fill(&call->stats[stats_index],ms,ev); + if (ms) linphone_call_stats_fill(stats,ms,ev); linphone_call_notify_stats_updated_with_stream_index(call,stats_index); if (evt == ORTP_EVENT_ZRTP_ENCRYPTION_CHANGED){ diff --git a/coreapi/misc.c b/coreapi/misc.c index fa295f6c7..9f5f216a3 100644 --- a/coreapi/misc.c +++ b/coreapi/misc.c @@ -548,19 +548,19 @@ static void linphone_core_add_local_ice_candidates(LinphoneCall *call, int famil if ((ice_check_list_state(audio_cl) != ICL_Completed) && (ice_check_list_candidates_gathered(audio_cl) == FALSE)) { ice_add_local_candidate(audio_cl, "host", family, addr, call->media_ports[call->main_audio_stream_index].rtp_port, 1, NULL); ice_add_local_candidate(audio_cl, "host", family, addr, call->media_ports[call->main_audio_stream_index].rtcp_port, 2, NULL); - call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateInProgress; + call->audio_stats->ice_state = LinphoneIceStateInProgress; } if (linphone_core_video_enabled(call->core) && (video_cl != NULL) && (ice_check_list_state(video_cl) != ICL_Completed) && (ice_check_list_candidates_gathered(video_cl) == FALSE)) { ice_add_local_candidate(video_cl, "host", family, addr, call->media_ports[call->main_video_stream_index].rtp_port, 1, NULL); ice_add_local_candidate(video_cl, "host", family, addr, call->media_ports[call->main_video_stream_index].rtcp_port, 2, NULL); - call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateInProgress; + call->video_stats->ice_state = LinphoneIceStateInProgress; } if (call->params->realtimetext_enabled && (text_cl != NULL) && (ice_check_list_state(text_cl) != ICL_Completed) && (ice_check_list_candidates_gathered(text_cl) == FALSE)) { ice_add_local_candidate(text_cl, "host", family, addr, call->media_ports[call->main_text_stream_index].rtp_port, 1, NULL); ice_add_local_candidate(text_cl, "host", family, addr, call->media_ports[call->main_text_stream_index].rtcp_port, 2, NULL); - call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateInProgress; + call->text_stats->ice_state = LinphoneIceStateInProgress; } } @@ -697,14 +697,14 @@ void linphone_call_update_ice_state_in_call_stats(LinphoneCall *call) { if (ice_check_list_state(audio_check_list) == ICL_Completed) { switch (ice_check_list_selected_valid_candidate_type(audio_check_list)) { case ICT_HostCandidate: - call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateHostConnection; + call->audio_stats->ice_state = LinphoneIceStateHostConnection; break; case ICT_ServerReflexiveCandidate: case ICT_PeerReflexiveCandidate: - call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateReflexiveConnection; + call->audio_stats->ice_state = LinphoneIceStateReflexiveConnection; break; case ICT_RelayedCandidate: - call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateRelayConnection; + call->audio_stats->ice_state = LinphoneIceStateRelayConnection; break; case ICT_CandidateInvalid: case ICT_CandidateTypeMax: @@ -712,22 +712,22 @@ void linphone_call_update_ice_state_in_call_stats(LinphoneCall *call) { break; } } else { - call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateFailed; + call->audio_stats->ice_state = LinphoneIceStateFailed; } - }else call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateNotActivated; + }else call->audio_stats->ice_state = LinphoneIceStateNotActivated; if (call->params->has_video && (video_check_list != NULL)) { if (ice_check_list_state(video_check_list) == ICL_Completed) { switch (ice_check_list_selected_valid_candidate_type(video_check_list)) { case ICT_HostCandidate: - call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateHostConnection; + call->video_stats->ice_state = LinphoneIceStateHostConnection; break; case ICT_ServerReflexiveCandidate: case ICT_PeerReflexiveCandidate: - call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateReflexiveConnection; + call->video_stats->ice_state = LinphoneIceStateReflexiveConnection; break; case ICT_RelayedCandidate: - call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateRelayConnection; + call->video_stats->ice_state = LinphoneIceStateRelayConnection; break; case ICT_CandidateInvalid: case ICT_CandidateTypeMax: @@ -735,22 +735,22 @@ void linphone_call_update_ice_state_in_call_stats(LinphoneCall *call) { break; } } else { - call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateFailed; + call->video_stats->ice_state = LinphoneIceStateFailed; } - }else call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateNotActivated; + }else call->video_stats->ice_state = LinphoneIceStateNotActivated; if (call->params->realtimetext_enabled && (text_check_list != NULL)) { if (ice_check_list_state(text_check_list) == ICL_Completed) { switch (ice_check_list_selected_valid_candidate_type(text_check_list)) { case ICT_HostCandidate: - call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateHostConnection; + call->text_stats->ice_state = LinphoneIceStateHostConnection; break; case ICT_ServerReflexiveCandidate: case ICT_PeerReflexiveCandidate: - call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateReflexiveConnection; + call->text_stats->ice_state = LinphoneIceStateReflexiveConnection; break; case ICT_RelayedCandidate: - call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateRelayConnection; + call->text_stats->ice_state = LinphoneIceStateRelayConnection; break; case ICT_CandidateInvalid: case ICT_CandidateTypeMax: @@ -758,28 +758,28 @@ void linphone_call_update_ice_state_in_call_stats(LinphoneCall *call) { break; } } else { - call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateFailed; + call->text_stats->ice_state = LinphoneIceStateFailed; } - }else call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateNotActivated; + }else call->text_stats->ice_state = LinphoneIceStateNotActivated; } else if (session_state == IS_Running) { - call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateInProgress; + call->audio_stats->ice_state = LinphoneIceStateInProgress; if (call->params->has_video && (video_check_list != NULL)) { - call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateInProgress; + call->video_stats->ice_state = LinphoneIceStateInProgress; } if (call->params->realtimetext_enabled && (text_check_list != NULL)) { - call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateInProgress; + call->text_stats->ice_state = LinphoneIceStateInProgress; } } else { - call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state = LinphoneIceStateFailed; + call->audio_stats->ice_state = LinphoneIceStateFailed; if (call->params->has_video && (video_check_list != NULL)) { - call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state = LinphoneIceStateFailed; + call->video_stats->ice_state = LinphoneIceStateFailed; } if (call->params->realtimetext_enabled && (text_check_list != NULL)) { - call->stats[LINPHONE_CALL_STATS_TEXT].ice_state = LinphoneIceStateFailed; + call->text_stats->ice_state = LinphoneIceStateFailed; } } ms_message("Call [%p] New ICE state: audio: [%s] video: [%s] text: [%s]", call, - linphone_ice_state_to_string(call->stats[LINPHONE_CALL_STATS_AUDIO].ice_state), linphone_ice_state_to_string(call->stats[LINPHONE_CALL_STATS_VIDEO].ice_state), linphone_ice_state_to_string(call->stats[LINPHONE_CALL_STATS_TEXT].ice_state)); + linphone_ice_state_to_string(call->audio_stats->ice_state), linphone_ice_state_to_string(call->video_stats->ice_state), linphone_ice_state_to_string(call->text_stats->ice_state)); } void linphone_call_stop_ice_for_inactive_streams(LinphoneCall *call, SalMediaDescription *desc) { diff --git a/coreapi/private.h b/coreapi/private.h index 023acc490..1d4a0b08e 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -351,7 +351,9 @@ struct _LinphoneCall{ OrtpEvQueue *videostream_app_evq; OrtpEvQueue *textstream_app_evq; CallCallbackObj nextVideoFrameDecoded; - LinphoneCallStats stats[3]; /* audio, video, text */ + LinphoneCallStats *audio_stats; + LinphoneCallStats *video_stats; + LinphoneCallStats *text_stats; #ifdef BUILD_UPNP UpnpSession *upnp_session; #endif //BUILD_UPNP @@ -1761,6 +1763,41 @@ BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneVideoActivationPolicy); LinphoneVideoActivationPolicy *linphone_video_activation_policy_new(void); +/** + * The LinphoneCallStats objects carries various statistic informations regarding quality of audio or video streams. + * + * To receive these informations periodically and as soon as they are computed, the application is invited to place a #LinphoneCoreCallStatsUpdatedCb callback in the LinphoneCoreVTable structure + * it passes for instantiating the LinphoneCore object (see linphone_core_new() ). + * + * At any time, the application can access last computed statistics using linphone_call_get_audio_stats() or linphone_call_get_video_stats(). +**/ +struct _LinphoneCallStats { + belle_sip_object_t base; + void *user_data; + LinphoneStreamType type; /**< Type of the stream which the stats refer to */ + jitter_stats_t jitter_stats; /**log->reporting.reports[stats_type]; reporting_content_metrics_t * metrics = NULL; - LinphoneCallStats stats = call->stats[stats_type]; + LinphoneCallStats *stats = NULL; mblk_t *block = NULL; int report_interval; + if (stats_type == 0) { + stats = call->audio_stats; + } else if (stats_type == 1) { + stats = call->video_stats; + } else { + stats = call->text_stats; + } + if (! media_report_enabled(call,stats_type)) return; report_interval = linphone_proxy_config_get_quality_reporting_interval(call->dest_proxy); - if (stats.updated == LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE) { + if (stats->updated == LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE) { metrics = &report->remote_metrics; - block = stats.received_rtcp; - } else if (stats.updated == LINPHONE_CALL_STATS_SENT_RTCP_UPDATE) { + block = stats->received_rtcp; + } else if (stats->updated == LINPHONE_CALL_STATS_SENT_RTCP_UPDATE) { metrics = &report->local_metrics; - block = stats.sent_rtcp; + block = stats->sent_rtcp; } do{ if (rtcp_is_XR(block) && (rtcp_XR_get_block_type(block) == RTCP_XR_VOIP_METRICS)){ @@ -617,7 +625,7 @@ void linphone_reporting_on_rtcp_update(LinphoneCall *call, SalStreamType stats_t // for local mos rating, we'll use the quality indicator directly // because rtcp XR might not be enabled - if (stats.updated == LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE){ + if (stats->updated == LINPHONE_CALL_STATS_RECEIVED_RTCP_UPDATE){ metrics->quality_estimates.moslq = (rtcp_XR_voip_metrics_get_mos_lq(block)==127) ? 127 : rtcp_XR_voip_metrics_get_mos_lq(block) / 10.f; metrics->quality_estimates.moscq = (rtcp_XR_voip_metrics_get_mos_cq(block)==127) ? diff --git a/daemon/commands/audio-stream-stats.cc b/daemon/commands/audio-stream-stats.cc index 4845dbb7b..7393b2cdd 100644 --- a/daemon/commands/audio-stream-stats.cc +++ b/daemon/commands/audio-stream-stats.cc @@ -61,5 +61,5 @@ void AudioStreamStatsCommand::exec(Daemon *app, const string& args) { return; } - app->sendResponse(Response(AudioStreamStatsResponse(app, stream->stream, &stream->stats, false).getBody(), Response::Ok)); + app->sendResponse(Response(AudioStreamStatsResponse(app, stream->stream, stream->stats, false).getBody(), Response::Ok)); } diff --git a/daemon/daemon.cc b/daemon/daemon.cc index 01f44e7c4..907972976 100644 --- a/daemon/daemon.cc +++ b/daemon/daemon.cc @@ -141,13 +141,13 @@ DtmfResponse::DtmfResponse(Daemon *daemon, LinphoneCall *call, int dtmf) { } static ostream &printCallStatsHelper(ostream &ostr, const LinphoneCallStats *stats, const string &prefix) { - ostr << prefix << "ICE state: " << ice_state_str[stats->ice_state] << "\n"; - ostr << prefix << "RoundTripDelay: " << stats->round_trip_delay << "\n"; - ostr << prefix << "Jitter: " << stats->jitter_stats.jitter << "\n"; + ostr << prefix << "ICE state: " << ice_state_str[linphone_call_stats_get_ice_state(stats)] << "\n"; + ostr << prefix << "RoundTripDelay: " << linphone_call_stats_get_round_trip_delay(stats) << "\n"; +// ostr << prefix << "Jitter: " << stats->jitter_stats.jitter << "\n"; // ostr << prefix << "MaxJitter: " << stats->jitter_stats.max_jitter << "\n"; // ostr << prefix << "SumJitter: " << stats->jitter_stats.sum_jitter << "\n"; // ostr << prefix << "MaxJitterTs: " << stats->jitter_stats.max_jitter_ts << "\n"; - ostr << prefix << "JitterBufferSizeMs: " << stats->jitter_stats.jitter_buffer_size_ms << "\n"; + ostr << prefix << "JitterBufferSizeMs: " << linphone_call_stats_get_jitter_buffer_size_ms(stats) << "\n"; ostr << prefix << "Received-InterarrivalJitter: " << linphone_call_stats_get_receiver_interarrival_jitter(stats) << "\n"; ostr << prefix << "Received-FractionLost: " << linphone_call_stats_get_receiver_loss_rate(stats) << "\n"; @@ -199,14 +199,14 @@ AudioStreamStatsResponse::AudioStreamStatsResponse(Daemon* daemon, AudioStream* ostr << "Event-type: audio-stream-stats\n"; ostr << "Id: " << daemon->updateAudioStreamId(stream) << "\n"; ostr << "Type: "; - if (stats->type == LINPHONE_CALL_STATS_AUDIO) { + if (linphone_call_stats_get_type(stats) == LINPHONE_CALL_STATS_AUDIO) { ostr << "Audio"; } else { ostr << "Video"; } ostr << "\n"; } else { - prefix = ((stats->type == LINPHONE_CALL_STATS_AUDIO) ? "Audio-" : "Video-"); + prefix = ((linphone_call_stats_get_type(stats) == LINPHONE_CALL_STATS_AUDIO) ? "Audio-" : "Video-"); } printCallStatsHelper(ostr, stats, prefix); @@ -547,9 +547,9 @@ void Daemon::iterateStreamStats() { while (it->second->queue && (NULL != (ev=ortp_ev_queue_get(it->second->queue)))){ OrtpEventType evt=ortp_event_get_type(ev); if (evt == ORTP_EVENT_RTCP_PACKET_RECEIVED || evt == ORTP_EVENT_RTCP_PACKET_EMITTED) { - linphone_call_stats_fill(&it->second->stats, &it->second->stream->ms, ev); + linphone_call_stats_fill(it->second->stats, &it->second->stream->ms, ev); if (mUseStatsEvents) mEventQueue.push(new AudioStreamStatsResponse(this, - it->second->stream, &it->second->stats, true)); + it->second->stream, it->second->stats, true)); } ortp_event_destroy(ev); } diff --git a/daemon/daemon.h b/daemon/daemon.h index 7a23b5587..12a32c358 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -191,11 +191,10 @@ private: struct AudioStreamAndOther { AudioStream *stream; OrtpEvQueue *queue; - LinphoneCallStats stats; + LinphoneCallStats *stats; AudioStreamAndOther(AudioStream *as) : stream(as) { queue = ortp_ev_queue_new(); rtp_session_register_event_queue(as->ms.sessions.rtp_session, queue); - memset(&stats, 0, sizeof(stats)); } ~AudioStreamAndOther() { rtp_session_unregister_event_queue(stream->ms.sessions.rtp_session, queue); diff --git a/gtk/incall_view.c b/gtk/incall_view.c index b3055f238..6c7edd939 100644 --- a/gtk/incall_view.c +++ b/gtk/incall_view.c @@ -243,8 +243,10 @@ static const char *upnp_state_to_string(LinphoneUpnpState ice_state){ } static void _refresh_call_stats(GtkWidget *callstats, LinphoneCall *call){ - const LinphoneCallStats *as=linphone_call_get_audio_stats(call); - const LinphoneCallStats *vs=linphone_call_get_video_stats(call); + LinphoneUpnpState upnp_state; + LinphoneIceState ice_state; + LinphoneCallStats *as=linphone_call_get_audio_stats(call); + LinphoneCallStats *vs=linphone_call_get_video_stats(call); const char *audio_media_connectivity = _("Direct or through server"); const char *video_media_connectivity = _("Direct or through server"); const LinphoneCallParams *curparams=linphone_call_get_current_params(call); @@ -256,7 +258,7 @@ static void _refresh_call_stats(GtkWidget *callstats, LinphoneCall *call){ gtk_label_set_markup(GTK_LABEL(linphone_gtk_get_widget(callstats,"rtp_profile")),tmp); g_free(tmp); tmp=g_strdup_printf(_("download: %f\nupload: %f (kbit/s)"), - as->download_bandwidth,as->upload_bandwidth); + linphone_call_stats_get_download_bandwidth(as),linphone_call_stats_get_upload_bandwidth(as)); gtk_label_set_markup(GTK_LABEL(linphone_gtk_get_widget(callstats,"audio_bandwidth_usage")),tmp); g_free(tmp); if (has_video){ @@ -267,7 +269,7 @@ static void _refresh_call_stats(GtkWidget *callstats, LinphoneCall *call){ gtk_label_set_markup(GTK_LABEL(linphone_gtk_get_widget(callstats,"video_size_recv")),size_r); gtk_label_set_markup(GTK_LABEL(linphone_gtk_get_widget(callstats,"video_size_sent")),size_s); - tmp=g_strdup_printf(_("download: %f\nupload: %f (kbit/s)"),vs->download_bandwidth,vs->upload_bandwidth); + tmp=g_strdup_printf(_("download: %f\nupload: %f (kbit/s)"),linphone_call_stats_get_download_bandwidth(vs),linphone_call_stats_get_upload_bandwidth(vs)); g_free(size_r); g_free(size_s); } else { @@ -275,27 +277,33 @@ static void _refresh_call_stats(GtkWidget *callstats, LinphoneCall *call){ } gtk_label_set_markup(GTK_LABEL(linphone_gtk_get_widget(callstats,"video_bandwidth_usage")),tmp); if (tmp) g_free(tmp); - if(as->upnp_state != LinphoneUpnpStateNotAvailable && as->upnp_state != LinphoneUpnpStateIdle) { - audio_media_connectivity = upnp_state_to_string(as->upnp_state); - } else if(as->ice_state != LinphoneIceStateNotActivated) { - audio_media_connectivity = ice_state_to_string(as->ice_state); + upnp_state = linphone_call_stats_get_upnp_state(as); + ice_state = linphone_call_stats_get_ice_state(as); + if(upnp_state != LinphoneUpnpStateNotAvailable && upnp_state != LinphoneUpnpStateIdle) { + audio_media_connectivity = upnp_state_to_string(upnp_state); + } else if(ice_state != LinphoneIceStateNotActivated) { + audio_media_connectivity = ice_state_to_string(ice_state); } gtk_label_set_text(GTK_LABEL(linphone_gtk_get_widget(callstats,"audio_media_connectivity")),audio_media_connectivity); if (has_video){ - if(vs->upnp_state != LinphoneUpnpStateNotAvailable && vs->upnp_state != LinphoneUpnpStateIdle) { - video_media_connectivity = upnp_state_to_string(vs->upnp_state); - } else if(vs->ice_state != LinphoneIceStateNotActivated) { - video_media_connectivity = ice_state_to_string(vs->ice_state); + upnp_state = linphone_call_stats_get_upnp_state(vs); + ice_state = linphone_call_stats_get_ice_state(vs); + if(upnp_state != LinphoneUpnpStateNotAvailable && upnp_state != LinphoneUpnpStateIdle) { + video_media_connectivity = upnp_state_to_string(upnp_state); + } else if(ice_state != LinphoneIceStateNotActivated) { + video_media_connectivity = ice_state_to_string(ice_state); } }else video_media_connectivity=NULL; gtk_label_set_text(GTK_LABEL(linphone_gtk_get_widget(callstats,"video_media_connectivity")),video_media_connectivity); - if (as->round_trip_delay>0){ - tmp=g_strdup_printf(_("%.3f seconds"),as->round_trip_delay); + if (linphone_call_stats_get_round_trip_delay(as)>0){ + tmp=g_strdup_printf(_("%.3f seconds"),linphone_call_stats_get_round_trip_delay(as)); gtk_label_set_text(GTK_LABEL(linphone_gtk_get_widget(callstats,"round_trip_time")),tmp); g_free(tmp); } + linphone_call_stats_unref(as); + linphone_call_stats_unref(vs); } static gboolean refresh_call_stats(GtkWidget *callstats){ diff --git a/include/linphone/call.h b/include/linphone/call.h index 24d28ce5e..bbe04ae08 100644 --- a/include/linphone/call.h +++ b/include/linphone/call.h @@ -834,17 +834,17 @@ LINPHONE_PUBLIC void linphone_call_ogl_render(LinphoneCall *call, bool_t is_prev LINPHONE_PUBLIC LinphoneStatus linphone_call_send_info_message(LinphoneCall *call, const LinphoneInfoMessage *info); /** - * Return call statistics for a particular stream type. + * Return a copy of the call statistics for a particular stream type. * @param call the call * @param type the stream type **/ -LINPHONE_PUBLIC const LinphoneCallStats *linphone_call_get_stats(LinphoneCall *call, LinphoneStreamType type); +LINPHONE_PUBLIC LinphoneCallStats *linphone_call_get_stats(LinphoneCall *call, LinphoneStreamType type); -LINPHONE_PUBLIC const LinphoneCallStats *linphone_call_get_audio_stats(LinphoneCall *call); +LINPHONE_PUBLIC LinphoneCallStats *linphone_call_get_audio_stats(LinphoneCall *call); -LINPHONE_PUBLIC const LinphoneCallStats *linphone_call_get_video_stats(LinphoneCall *call); +LINPHONE_PUBLIC LinphoneCallStats *linphone_call_get_video_stats(LinphoneCall *call); -LINPHONE_PUBLIC const LinphoneCallStats *linphone_call_get_text_stats(LinphoneCall *call); +LINPHONE_PUBLIC LinphoneCallStats *linphone_call_get_text_stats(LinphoneCall *call); /** * Add a listener in order to be notified of LinphoneCall events. Once an event is received, registred LinphoneCallCbs are diff --git a/include/linphone/call_stats.h b/include/linphone/call_stats.h index 11044c1c6..a5bd96c48 100644 --- a/include/linphone/call_stats.h +++ b/include/linphone/call_stats.h @@ -40,33 +40,34 @@ extern "C" { #define LINPHONE_CALL_STATS_PERIODICAL_UPDATE (1 << 2) /**< Every seconds LinphoneCallStats object has been updated */ /** - * The LinphoneCallStats objects carries various statistic informations regarding quality of audio or video streams. - * - * To receive these informations periodically and as soon as they are computed, the application is invited to place a #LinphoneCoreCallStatsUpdatedCb callback in the LinphoneCoreVTable structure - * it passes for instantiating the LinphoneCore object (see linphone_core_new() ). - * - * At any time, the application can access last computed statistics using linphone_call_get_audio_stats() or linphone_call_get_video_stats(). + * Increment refcount. + * @param[in] stats LinphoneCallStats object + * @ingroup misc **/ -struct _LinphoneCallStats { - LinphoneStreamType type; /**< Type of the stream which the stats refer to */ - jitter_stats_t jitter_stats; /**lc)); BC_ASSERT_GREATER(linphone_core_manager_get_max_audio_down_bw(pauline),70,int,"%i"); - BC_ASSERT_LOWER((int)linphone_call_get_audio_stats(linphone_core_get_current_call(pauline->lc))->download_bandwidth, 90, int, "%i"); + BC_ASSERT_LOWER((int)linphone_call_stats_get_download_bandwidth(stats), 90, int, "%i"); + linphone_call_stats_unref(stats); + stats = linphone_call_get_audio_stats(linphone_core_get_current_call(pauline2->lc)); BC_ASSERT_GREATER(linphone_core_manager_get_max_audio_down_bw(pauline2),70,int,"%i"); - BC_ASSERT_LOWER((int)linphone_call_get_audio_stats(linphone_core_get_current_call(pauline2->lc))->download_bandwidth,90, int, "%i"); + BC_ASSERT_LOWER((int)linphone_call_stats_get_download_bandwidth(stats),90, int, "%i"); + linphone_call_stats_unref(stats); BC_ASSERT_TRUE(linphone_call_params_audio_multicast_enabled(linphone_call_get_current_params(linphone_core_get_current_call(pauline->lc)))); BC_ASSERT_TRUE(linphone_call_params_audio_multicast_enabled(linphone_call_get_current_params(linphone_core_get_current_call(marie->lc)))); diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index 87ff0cfef..ac001c86a 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -112,13 +112,18 @@ void call_stats_updated(LinphoneCore *lc, LinphoneCall *call, const LinphoneCall if (lstats->updated & LINPHONE_CALL_STATS_PERIODICAL_UPDATE ) { int tab_size = sizeof (counters->audio_download_bandwidth)/sizeof(int); int index = (counters->current_bandwidth_index[lstats->type]++) % tab_size; + LinphoneCallStats *audio_stats, *video_stats; + audio_stats = linphone_call_get_audio_stats(call); + video_stats = linphone_call_get_video_stats(call); if (lstats->type == LINPHONE_CALL_STATS_AUDIO) { - counters->audio_download_bandwidth[index] = (int)linphone_call_get_audio_stats(call)->download_bandwidth; - counters->audio_upload_bandwidth[index] = (int)linphone_call_get_audio_stats(call)->upload_bandwidth; + counters->audio_download_bandwidth[index] = (int)audio_stats->download_bandwidth; + counters->audio_upload_bandwidth[index] = (int)audio_stats->upload_bandwidth; } else { - counters->video_download_bandwidth[index] = (int)linphone_call_get_video_stats(call)->download_bandwidth; - counters->video_upload_bandwidth[index] = (int)linphone_call_get_video_stats(call)->upload_bandwidth; + counters->video_download_bandwidth[index] = (int)video_stats->download_bandwidth; + counters->video_upload_bandwidth[index] = (int)video_stats->upload_bandwidth; } + linphone_call_stats_unref(audio_stats); + linphone_call_stats_unref(video_stats); } } @@ -179,6 +184,7 @@ void liblinphone_tester_check_rtcp(LinphoneCoreManager* caller, LinphoneCoreMana LinphoneCall *c1,*c2; MSTimeSpec ts; int max_time_to_wait; + LinphoneCallStats *audio_stats1, *video_stats1, *audio_stats2, *video_stats2; c1=linphone_core_get_current_call(caller->lc); c2=linphone_core_get_current_call(callee->lc); @@ -195,46 +201,58 @@ void liblinphone_tester_check_rtcp(LinphoneCoreManager* caller, LinphoneCoreMana max_time_to_wait = 5000; do { - if (linphone_call_get_audio_stats(c1)->round_trip_delay > 0.0 - && linphone_call_get_audio_stats(c2)->round_trip_delay > 0.0 - && (!linphone_call_log_video_enabled(linphone_call_get_call_log(c1)) || linphone_call_get_video_stats(c1)->round_trip_delay>0.0) - && (!linphone_call_log_video_enabled(linphone_call_get_call_log(c2)) || linphone_call_get_video_stats(c2)->round_trip_delay>0.0)) { + audio_stats1 = linphone_call_get_audio_stats(c1); + video_stats1 = linphone_call_get_video_stats(c1); + audio_stats2 = linphone_call_get_audio_stats(c2); + video_stats2 = linphone_call_get_video_stats(c2); + if (audio_stats1->round_trip_delay > 0.0 + && audio_stats2->round_trip_delay > 0.0 + && (!linphone_call_log_video_enabled(linphone_call_get_call_log(c1)) || video_stats1->round_trip_delay>0.0) + && (!linphone_call_log_video_enabled(linphone_call_get_call_log(c2)) || video_stats2->round_trip_delay>0.0)) { break; } + linphone_call_stats_unref(audio_stats1); + linphone_call_stats_unref(audio_stats2); + if (video_stats1) linphone_call_stats_unref(video_stats1); + if (video_stats2) linphone_call_stats_unref(video_stats2); wait_for_until(caller->lc,callee->lc,NULL,0,20); /*just to sleep while iterating*/ }while (!liblinphone_tester_clock_elapsed(&ts,max_time_to_wait)); + audio_stats1 = linphone_call_get_audio_stats(c1); + video_stats1 = linphone_call_get_video_stats(c1); + audio_stats2 = linphone_call_get_audio_stats(c2); + video_stats2 = linphone_call_get_video_stats(c2); if (linphone_core_rtcp_enabled(caller->lc) && linphone_core_rtcp_enabled(callee->lc)) { BC_ASSERT_GREATER(caller->stat.number_of_rtcp_received, 1, int, "%i"); BC_ASSERT_GREATER(callee->stat.number_of_rtcp_received, 1, int, "%i"); - BC_ASSERT_GREATER(linphone_call_get_audio_stats(c1)->round_trip_delay,0.0,float,"%f"); - BC_ASSERT_GREATER(linphone_call_get_audio_stats(c2)->round_trip_delay,0.0,float,"%f"); + BC_ASSERT_GREATER(audio_stats1->round_trip_delay,0.0,float,"%f"); + BC_ASSERT_GREATER(audio_stats2->round_trip_delay,0.0,float,"%f"); if (linphone_call_log_video_enabled(linphone_call_get_call_log(c1))) { - BC_ASSERT_GREATER(linphone_call_get_video_stats(c1)->round_trip_delay,0.0,float,"%f"); + BC_ASSERT_GREATER(video_stats1->round_trip_delay,0.0,float,"%f"); } if (linphone_call_log_video_enabled(linphone_call_get_call_log(c2))) { - BC_ASSERT_GREATER(linphone_call_get_video_stats(c2)->round_trip_delay,0.0,float,"%f"); + BC_ASSERT_GREATER(video_stats2->round_trip_delay,0.0,float,"%f"); } } else { if (linphone_core_rtcp_enabled(caller->lc)) { - BC_ASSERT_EQUAL(linphone_call_get_audio_stats(c1)->rtp_stats.sent_rtcp_packets, 0, unsigned long long, "%llu"); - BC_ASSERT_EQUAL(linphone_call_get_audio_stats(c2)->rtp_stats.recv_rtcp_packets, 0, unsigned long long, "%llu"); + BC_ASSERT_EQUAL(audio_stats1->rtp_stats.sent_rtcp_packets, 0, unsigned long long, "%llu"); + BC_ASSERT_EQUAL(audio_stats2->rtp_stats.recv_rtcp_packets, 0, unsigned long long, "%llu"); if (linphone_call_log_video_enabled(linphone_call_get_call_log(c1))) { - BC_ASSERT_EQUAL(linphone_call_get_video_stats(c1)->rtp_stats.sent_rtcp_packets, 0, unsigned long long, "%llu"); + BC_ASSERT_EQUAL(video_stats1->rtp_stats.sent_rtcp_packets, 0, unsigned long long, "%llu"); } if (linphone_call_log_video_enabled(linphone_call_get_call_log(c2))) { - BC_ASSERT_EQUAL(linphone_call_get_video_stats(c2)->rtp_stats.recv_rtcp_packets, 0, unsigned long long, "%llu"); + BC_ASSERT_EQUAL(video_stats2->rtp_stats.recv_rtcp_packets, 0, unsigned long long, "%llu"); } } if (linphone_core_rtcp_enabled(callee->lc)) { - BC_ASSERT_EQUAL(linphone_call_get_audio_stats(c2)->rtp_stats.sent_rtcp_packets, 0, unsigned long long, "%llu"); - BC_ASSERT_EQUAL(linphone_call_get_audio_stats(c1)->rtp_stats.recv_rtcp_packets, 0, unsigned long long, "%llu"); + BC_ASSERT_EQUAL(audio_stats2->rtp_stats.sent_rtcp_packets, 0, unsigned long long, "%llu"); + BC_ASSERT_EQUAL(audio_stats1->rtp_stats.recv_rtcp_packets, 0, unsigned long long, "%llu"); if (linphone_call_log_video_enabled(linphone_call_get_call_log(c1))) { - BC_ASSERT_EQUAL(linphone_call_get_video_stats(c1)->rtp_stats.recv_rtcp_packets, 0, unsigned long long, "%llu"); + BC_ASSERT_EQUAL(video_stats1->rtp_stats.recv_rtcp_packets, 0, unsigned long long, "%llu"); } if (linphone_call_log_video_enabled(linphone_call_get_call_log(c2))) { - BC_ASSERT_EQUAL(linphone_call_get_video_stats(c2)->rtp_stats.sent_rtcp_packets, 0, unsigned long long, "%llu"); + BC_ASSERT_EQUAL(video_stats2->rtp_stats.sent_rtcp_packets, 0, unsigned long long, "%llu"); } } @@ -3353,6 +3371,7 @@ void check_media_direction(LinphoneCoreManager* mgr, LinphoneCall *call, bctbx_l if (video_dir != LinphoneMediaDirectionInvalid){ int current_recv_iframe = mgr->stat.number_of_IframeDecoded; int expected_recv_iframe=0; + LinphoneCallStats *stats = linphone_call_get_video_stats(call); if (video_dir != LinphoneMediaDirectionInactive){ BC_ASSERT_TRUE(linphone_call_params_video_enabled(params)); @@ -3360,24 +3379,23 @@ void check_media_direction(LinphoneCoreManager* mgr, LinphoneCall *call, bctbx_l linphone_call_set_next_video_frame_decoded_callback(call,linphone_call_iframe_decoded_cb,mgr->lc); linphone_call_send_vfu_request(call); } - switch (video_dir) { case LinphoneMediaDirectionInactive: - BC_ASSERT_LOWER((int)linphone_call_get_video_stats(call)->upload_bandwidth, 5, int, "%i"); + BC_ASSERT_LOWER((int)stats->upload_bandwidth, 5, int, "%i"); break; case LinphoneMediaDirectionSendOnly: expected_recv_iframe = 0; - BC_ASSERT_LOWER((int)linphone_call_get_video_stats(call)->download_bandwidth, 5, int, "%i"); + BC_ASSERT_LOWER((int)stats->download_bandwidth, 5, int, "%i"); break; case LinphoneMediaDirectionRecvOnly: - BC_ASSERT_LOWER((int)linphone_call_get_video_stats(call)->upload_bandwidth, 5, int, "%i"); + BC_ASSERT_LOWER((int)stats->upload_bandwidth, 5, int, "%i"); case LinphoneMediaDirectionSendRecv: expected_recv_iframe = 1; break; default: break; } - + linphone_call_stats_unref(stats); BC_ASSERT_TRUE(wait_for_list(lcs, &mgr->stat.number_of_IframeDecoded,current_recv_iframe + expected_recv_iframe,10000)); } #endif @@ -3719,6 +3737,7 @@ static void call_with_paused_no_sdp_on_resume(void) { LinphoneCoreManager* marie; LinphoneCoreManager* pauline; LinphoneCall* call_marie = NULL; + LinphoneCallStats *stats; bool_t call_ok; marie = linphone_core_manager_new( "marie_rc"); @@ -3756,7 +3775,9 @@ static void call_with_paused_no_sdp_on_resume(void) { wait_for_until(marie->lc, pauline->lc, &dummy, 1, 3000); BC_ASSERT_GREATER(linphone_core_manager_get_max_audio_down_bw(marie),70,int,"%i"); - BC_ASSERT_TRUE(linphone_call_get_audio_stats(linphone_core_get_current_call(pauline->lc))->download_bandwidth>70); + stats = linphone_call_get_audio_stats(linphone_core_get_current_call(pauline->lc)); + BC_ASSERT_TRUE(stats->download_bandwidth>70); + linphone_call_stats_unref(stats); end_call(marie,pauline); end: @@ -4569,8 +4590,8 @@ static void custom_rtp_modifier(bool_t pauseResumeTest, bool_t recordTest) { // Now we want to ensure that all sent RTP packets actually go through our RTP transport modifier and thus no packet leave without being processed (by any operation we might want to do on it) { - const LinphoneCallStats *marie_stats = linphone_call_get_audio_stats(call_marie); - const LinphoneCallStats *pauline_stats = linphone_call_get_audio_stats(call_pauline); + LinphoneCallStats *marie_stats = linphone_call_get_audio_stats(call_marie); + LinphoneCallStats *pauline_stats = linphone_call_get_audio_stats(call_pauline); rtp_stats_t marie_rtp_stats = *linphone_call_stats_get_rtp_stats(marie_stats); rtp_stats_t pauline_rtp_stats = *linphone_call_stats_get_rtp_stats(pauline_stats); ms_message("Marie sent %i RTP packets and received %i (for real)", (int)marie_rtp_stats.packet_sent, (int)marie_rtp_stats.packet_recv); @@ -4580,6 +4601,8 @@ static void custom_rtp_modifier(bool_t pauseResumeTest, bool_t recordTest) { // There can be a small difference between the number of packets received in the modifier and the number processed in reception because the processing is asynchronous BC_ASSERT_TRUE(data_pauline->packetReceivedCount - pauline_rtp_stats.packet_recv < 20); BC_ASSERT_TRUE(data_pauline->packetSentCount == pauline_rtp_stats.packet_sent); + linphone_call_stats_unref(marie_stats); + linphone_call_stats_unref(pauline_stats); } end: @@ -5649,7 +5672,7 @@ static bool_t quick_call(LinphoneCoreManager *m1, LinphoneCoreManager *m2){ static void call_with_encryption_mandatory(bool_t caller_has_encryption_mandatory){ LinphoneCoreManager* marie = linphone_core_manager_new("marie_rc"); LinphoneCoreManager* pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc"); - + LinphoneCallStats *marie_stats, *pauline_stats; /*marie doesn't support ZRTP at all*/ marie->lc->zrtp_not_available_simulation=1; @@ -5670,8 +5693,12 @@ static void call_with_encryption_mandatory(bool_t caller_has_encryption_mandator BC_ASSERT_EQUAL(linphone_call_get_audio_stats(linphone_core_get_current_call(pauline->lc))->rtp_stats.packet_sent, 0, int, "%i"); #endif /*however we can trust packet_recv from the other party instead */ - BC_ASSERT_EQUAL((int)linphone_call_get_audio_stats(linphone_core_get_current_call(marie->lc))->rtp_stats.packet_recv, 0, int, "%i"); - BC_ASSERT_EQUAL((int)linphone_call_get_audio_stats(linphone_core_get_current_call(pauline->lc))->rtp_stats.packet_recv, 0, int, "%i"); + marie_stats = linphone_call_get_audio_stats(linphone_core_get_current_call(marie->lc)); + pauline_stats = linphone_call_get_audio_stats(linphone_core_get_current_call(pauline->lc)); + BC_ASSERT_EQUAL((int)marie_stats->rtp_stats.packet_recv, 0, int, "%i"); + BC_ASSERT_EQUAL((int)pauline_stats->rtp_stats.packet_recv, 0, int, "%i"); + linphone_call_stats_unref(marie_stats); + linphone_call_stats_unref(pauline_stats); end_call(marie, pauline); end: diff --git a/tester/complex_sip_case_tester.c b/tester/complex_sip_case_tester.c index 3e2a566af..f50996b5a 100644 --- a/tester/complex_sip_case_tester.c +++ b/tester/complex_sip_case_tester.c @@ -26,21 +26,30 @@ #if HAVE_SIPP void check_rtcp(LinphoneCall *call) { MSTimeSpec ts; + LinphoneCallStats *audio_stats, *video_stats; linphone_call_ref(call); liblinphone_tester_clock_start(&ts); do { - if (linphone_call_get_audio_stats(call)->round_trip_delay > 0.0 && (!linphone_call_log_video_enabled(linphone_call_get_call_log(call)) || linphone_call_get_video_stats(call)->round_trip_delay > 0.0)) { + audio_stats = linphone_call_get_audio_stats(call); + video_stats = linphone_call_get_video_stats(call); + if (linphone_call_stats_get_round_trip_delay(audio_stats) > 0.0 && (!linphone_call_log_video_enabled(linphone_call_get_call_log(call)) || linphone_call_stats_get_round_trip_delay(video_stats) > 0.0)) { break; } + linphone_call_stats_unref(audio_stats); + if (video_stats) linphone_call_stats_unref(video_stats); wait_for_until(call->core, NULL, NULL, 0, 20); /*just to sleep while iterating*/ } while (!liblinphone_tester_clock_elapsed(&ts, 15000)); - BC_ASSERT_GREATER(linphone_call_get_audio_stats(call)->round_trip_delay, 0.0, float, "%f"); + audio_stats = linphone_call_get_audio_stats(call); + BC_ASSERT_GREATER(linphone_call_stats_get_round_trip_delay(audio_stats), 0.0, float, "%f"); if (linphone_call_log_video_enabled(linphone_call_get_call_log(call))) { - BC_ASSERT_GREATER(linphone_call_get_video_stats(call)->round_trip_delay, 0.0, float, "%f"); + video_stats = linphone_call_get_video_stats(call); + BC_ASSERT_GREATER(linphone_call_stats_get_round_trip_delay(video_stats), 0.0, float, "%f"); + linphone_call_stats_unref(video_stats); } + linphone_call_stats_unref(audio_stats); linphone_call_unref(call); } diff --git a/tester/tester.c b/tester/tester.c index 363e84b4e..40f8b43b9 100644 --- a/tester/tester.c +++ b/tester/tester.c @@ -677,6 +677,7 @@ void liblinphone_tester_uninit(void) { static void check_ice_from_rtp(LinphoneCall *c1, LinphoneCall *c2, LinphoneStreamType stream_type) { MediaStream *ms; + LinphoneCallStats *stats; switch (stream_type) { case LinphoneStreamTypeAudio: ms=&c1->audiostream->ms; @@ -693,7 +694,8 @@ static void check_ice_from_rtp(LinphoneCall *c1, LinphoneCall *c2, LinphoneStrea return; } - if (linphone_call_get_audio_stats(c1)->ice_state == LinphoneIceStateHostConnection && media_stream_started(ms)) { + stats = linphone_call_get_audio_stats(c1); + if (stats->ice_state == LinphoneIceStateHostConnection && media_stream_started(ms)) { struct sockaddr_storage remaddr; socklen_t remaddrlen = sizeof(remaddr); char ip[NI_MAXHOST] = { 0 }; @@ -718,6 +720,7 @@ static void check_ice_from_rtp(LinphoneCall *c1, LinphoneCall *c2, LinphoneStrea BC_ASSERT_STRING_EQUAL(ip, expected_addr); } } + linphone_call_stats_unref(stats); } bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee, LinphoneIceState state) { @@ -747,13 +750,17 @@ bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee, Linph liblinphone_tester_clock_start(&ts); do{ if ((c1 != NULL) && (c2 != NULL)) { - if (linphone_call_get_audio_stats(c1)->ice_state==state && - linphone_call_get_audio_stats(c2)->ice_state==state ){ + LinphoneCallStats *stats1 = linphone_call_get_audio_stats(c1); + LinphoneCallStats *stats2 = linphone_call_get_audio_stats(c2); + if (stats1->ice_state==state && + stats2->ice_state==state){ audio_success=TRUE; check_ice_from_rtp(c1,c2,LinphoneStreamTypeAudio); check_ice_from_rtp(c2,c1,LinphoneStreamTypeAudio); break; } + linphone_call_stats_unref(stats1); + linphone_call_stats_unref(stats2); linphone_core_iterate(caller->lc); linphone_core_iterate(callee->lc); } @@ -765,13 +772,17 @@ bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee, Linph liblinphone_tester_clock_start(&ts); do{ if ((c1 != NULL) && (c2 != NULL)) { - if (linphone_call_get_video_stats(c1)->ice_state==state && - linphone_call_get_video_stats(c2)->ice_state==state ){ + LinphoneCallStats *stats1 = linphone_call_get_video_stats(c1); + LinphoneCallStats *stats2 = linphone_call_get_video_stats(c2); + if (stats1->ice_state==state && + stats2->ice_state==state){ video_success=TRUE; check_ice_from_rtp(c1,c2,LinphoneStreamTypeVideo); check_ice_from_rtp(c2,c1,LinphoneStreamTypeVideo); break; } + linphone_call_stats_unref(stats1); + linphone_call_stats_unref(stats2); linphone_core_iterate(caller->lc); linphone_core_iterate(callee->lc); } @@ -783,13 +794,17 @@ bool_t check_ice(LinphoneCoreManager* caller, LinphoneCoreManager* callee, Linph liblinphone_tester_clock_start(&ts); do{ if ((c1 != NULL) && (c2 != NULL)) { - if (linphone_call_get_text_stats(c1)->ice_state==state && - linphone_call_get_text_stats(c2)->ice_state==state ){ + LinphoneCallStats *stats1 = linphone_call_get_text_stats(c1); + LinphoneCallStats *stats2 = linphone_call_get_text_stats(c2); + if (stats1->ice_state==state && + stats2->ice_state==state){ text_success=TRUE; check_ice_from_rtp(c1,c2,LinphoneStreamTypeText); check_ice_from_rtp(c2,c1,LinphoneStreamTypeText); break; } + linphone_call_stats_unref(stats1); + linphone_call_stats_unref(stats2); linphone_core_iterate(caller->lc); linphone_core_iterate(callee->lc); } diff --git a/tester/video_tester.c b/tester/video_tester.c index 2921d6bf7..54fccaea6 100644 --- a/tester/video_tester.c +++ b/tester/video_tester.c @@ -481,18 +481,32 @@ static void forked_outgoing_early_media_video_call_with_inactive_audio_test(void BC_ASSERT_PTR_NOT_NULL(marie2_call); if (pauline_call && marie1_call && marie2_call) { + LinphoneCallStats *pauline_audio_stats, *marie1_audio_stats, *marie2_audio_stats; + LinphoneCallStats *pauline_video_stats, *marie1_video_stats, *marie2_video_stats; linphone_call_set_next_video_frame_decoded_callback(pauline_call, linphone_call_iframe_decoded_cb, pauline->lc); /* wait a bit that streams are established */ wait_for_list(lcs, &dummy, 1, 3000); - BC_ASSERT_EQUAL(linphone_call_get_audio_stats(pauline_call)->download_bandwidth, 0, float, "%f"); - BC_ASSERT_EQUAL(linphone_call_get_audio_stats(marie1_call)->download_bandwidth, 0, float, "%f"); - BC_ASSERT_EQUAL(linphone_call_get_audio_stats(marie2_call)->download_bandwidth, 0, float, "%f"); - BC_ASSERT_LOWER(linphone_call_get_video_stats(pauline_call)->download_bandwidth, 11, float, "%f"); /* because of stun packets*/ - BC_ASSERT_GREATER(linphone_call_get_video_stats(marie1_call)->download_bandwidth, 0, float, "%f"); - BC_ASSERT_GREATER(linphone_call_get_video_stats(marie2_call)->download_bandwidth, 0, float, "%f"); + pauline_audio_stats = linphone_call_get_audio_stats(pauline_call); + marie1_audio_stats = linphone_call_get_audio_stats(marie1_call); + marie2_audio_stats = linphone_call_get_audio_stats(marie2_call); + pauline_video_stats = linphone_call_get_video_stats(pauline_call); + marie1_video_stats = linphone_call_get_video_stats(marie1_call); + marie2_video_stats = linphone_call_get_video_stats(marie2_call); + BC_ASSERT_EQUAL(pauline_audio_stats->download_bandwidth, 0, float, "%f"); + BC_ASSERT_EQUAL(marie1_audio_stats->download_bandwidth, 0, float, "%f"); + BC_ASSERT_EQUAL(marie2_audio_stats->download_bandwidth, 0, float, "%f"); + BC_ASSERT_LOWER(pauline_video_stats->download_bandwidth, 11, float, "%f"); /* because of stun packets*/ + BC_ASSERT_GREATER(marie1_video_stats->download_bandwidth, 0, float, "%f"); + BC_ASSERT_GREATER(marie2_video_stats->download_bandwidth, 0, float, "%f"); BC_ASSERT_GREATER(marie1->stat.number_of_IframeDecoded, 1, int, "%i"); BC_ASSERT_GREATER(marie2->stat.number_of_IframeDecoded, 1, int, "%i"); + linphone_call_stats_unref(pauline_audio_stats); + linphone_call_stats_unref(marie1_audio_stats); + linphone_call_stats_unref(marie2_audio_stats); + linphone_call_stats_unref(pauline_video_stats); + linphone_call_stats_unref(marie1_video_stats); + linphone_call_stats_unref(marie2_video_stats); linphone_call_params_set_audio_direction(marie1_params, LinphoneMediaDirectionSendRecv); linphone_call_accept_with_params(linphone_core_get_current_call(marie1->lc), marie1_params); @@ -504,11 +518,19 @@ static void forked_outgoing_early_media_video_call_with_inactive_audio_test(void /*wait a bit that streams are established*/ wait_for_list(lcs, &dummy, 1, 3000); - BC_ASSERT_GREATER(linphone_call_get_audio_stats(pauline_call)->download_bandwidth, 71, float, "%f"); - BC_ASSERT_GREATER(linphone_call_get_audio_stats(marie1_call)->download_bandwidth, 71, float, "%f"); - BC_ASSERT_GREATER(linphone_call_get_video_stats(pauline_call)->download_bandwidth, 0, float, "%f"); - BC_ASSERT_GREATER(linphone_call_get_video_stats(marie1_call)->download_bandwidth, 0, float, "%f"); + pauline_audio_stats = linphone_call_get_audio_stats(pauline_call); + marie1_audio_stats = linphone_call_get_audio_stats(marie1_call); + pauline_video_stats = linphone_call_get_video_stats(pauline_call); + marie1_video_stats = linphone_call_get_video_stats(marie1_call); + BC_ASSERT_GREATER(pauline_audio_stats->download_bandwidth, 71, float, "%f"); + BC_ASSERT_GREATER(marie1_audio_stats->download_bandwidth, 71, float, "%f"); + BC_ASSERT_GREATER(pauline_video_stats->download_bandwidth, 0, float, "%f"); + BC_ASSERT_GREATER(marie1_video_stats->download_bandwidth, 0, float, "%f"); BC_ASSERT_GREATER(pauline->stat.number_of_IframeDecoded, 1, int, "%i"); + linphone_call_stats_unref(pauline_audio_stats); + linphone_call_stats_unref(marie1_audio_stats); + linphone_call_stats_unref(pauline_video_stats); + linphone_call_stats_unref(marie1_video_stats); /* send an INFO in reverse side to check that dialogs are properly established */ info = linphone_core_create_info_message(marie1->lc); From f796ef33b21f4b115a7a212bc38f8807b7db8959 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 19 Apr 2017 16:28:17 +0200 Subject: [PATCH 55/70] LinphoneCallStats is now unowned to prevent leak when linphone_call_get_stats method will be wrapped --- coreapi/linphonecall.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 7444fd23b..968315939 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -1307,9 +1307,9 @@ LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddr call->dir=LinphoneCallOutgoing; call->core=lc; call->dest_proxy=cfg; - call->audio_stats = linphone_call_stats_new(); - call->video_stats = linphone_call_stats_new(); - call->text_stats = linphone_call_stats_new(); + call->audio_stats = linphone_call_stats_ref(linphone_call_stats_new()); + call->video_stats = linphone_call_stats_ref(linphone_call_stats_new()); + call->text_stats = linphone_call_stats_ref(linphone_call_stats_new()); linphone_call_outgoing_select_ip_version(call,to,cfg); linphone_call_get_local_ip(call, to); call->params = linphone_call_params_copy(params); @@ -1492,9 +1492,9 @@ LinphoneCall * linphone_call_new_incoming(LinphoneCore *lc, LinphoneAddress *fro LinphoneNatPolicy *nat_policy = NULL; int i; call->dir=LinphoneCallIncoming; - call->audio_stats = linphone_call_stats_new(); - call->video_stats = linphone_call_stats_new(); - call->text_stats = linphone_call_stats_new(); + call->audio_stats = linphone_call_stats_ref(linphone_call_stats_new()); + call->video_stats = linphone_call_stats_ref(linphone_call_stats_new()); + call->text_stats = linphone_call_stats_ref(linphone_call_stats_new()); sal_op_set_user_pointer(op,call); call->op=op; call->core=lc; @@ -4290,7 +4290,7 @@ BELLE_SIP_INSTANCIATE_VPTR(LinphoneCallStats, belle_sip_object_t, NULL, // destroy _linphone_call_stats_clone, // clone NULL, // marshal - FALSE + TRUE ); LinphoneCallStats *linphone_call_stats_new() { From e7637881d0cb1eb182dc929cbc68f8bdd017be6d Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 19 Apr 2017 16:46:30 +0200 Subject: [PATCH 56/70] Updated linphonecore_jni.cc to reflect latest changes made to LinphoneCallStats --- coreapi/linphonecall.c | 8 ++++++++ coreapi/linphonecore_jni.cc | 35 +++++++++++++++++++++-------------- include/linphone/call_stats.h | 12 ++++++++++++ 3 files changed, 41 insertions(+), 14 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 968315939..d4f554a8f 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -4362,6 +4362,14 @@ float linphone_call_stats_get_receiver_loss_rate(const LinphoneCallStats *stats) return 100.0f * report_block_get_fraction_lost(rrb) / 256.0f; } +float linphone_call_stats_get_local_loss_rate(const LinphoneCallStats *stats) { + return stats->local_loss_rate; +} + +float linphone_call_stats_get_local_late_rate(const LinphoneCallStats *stats) { + return stats->local_late_rate; +} + float linphone_call_stats_get_sender_interarrival_jitter(const LinphoneCallStats *stats) { const report_block_t *srb = NULL; diff --git a/coreapi/linphonecore_jni.cc b/coreapi/linphonecore_jni.cc index cd4dc2163..c3083289d 100644 --- a/coreapi/linphonecore_jni.cc +++ b/coreapi/linphonecore_jni.cc @@ -3423,23 +3423,27 @@ extern "C" jboolean Java_org_linphone_core_LinphoneCallLogImpl_wasConference(JNI /* CallStats */ extern "C" jint Java_org_linphone_core_LinphoneCallStatsImpl_getMediaType(JNIEnv *env, jobject thiz, jlong stats_ptr) { - return (jint)((LinphoneCallStats *)stats_ptr)->type; + LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr; + return (jint)linphone_call_stats_get_type(stats); } extern "C" jint Java_org_linphone_core_LinphoneCallStatsImpl_getIceState(JNIEnv *env, jobject thiz, jlong stats_ptr) { - return (jint)((LinphoneCallStats *)stats_ptr)->ice_state; + LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr; + return (jint)linphone_call_stats_get_ice_state(stats); } extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getDownloadBandwidth(JNIEnv *env, jobject thiz, jlong stats_ptr) { - return (jfloat)((LinphoneCallStats *)stats_ptr)->download_bandwidth; + LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr; + return (jfloat)linphone_call_stats_get_download_bandwidth(stats); } extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getUploadBandwidth(JNIEnv *env, jobject thiz, jlong stats_ptr) { - return (jfloat)((LinphoneCallStats *)stats_ptr)->upload_bandwidth; + LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr; + return (jfloat)linphone_call_stats_get_upload_bandwidth(stats); } extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getSenderLossRate(JNIEnv *env, jobject thiz, jlong stats_ptr) { - const LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr; + LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr; return (jfloat) linphone_call_stats_get_sender_loss_rate(stats); } extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getReceiverLossRate(JNIEnv *env, jobject thiz, jlong stats_ptr) { - const LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr; + LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr; return (jfloat) linphone_call_stats_get_receiver_loss_rate(stats); } extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getSenderInterarrivalJitter(JNIEnv *env, jobject thiz, jlong stats_ptr) { @@ -3451,28 +3455,31 @@ extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getReceiverIntera return (jfloat) linphone_call_stats_get_receiver_interarrival_jitter(stats); } extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getRoundTripDelay(JNIEnv *env, jobject thiz, jlong stats_ptr) { - return (jfloat)((LinphoneCallStats *)stats_ptr)->round_trip_delay; + LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr; + return (jfloat)linphone_call_stats_get_round_trip_delay(stats); } extern "C" jlong Java_org_linphone_core_LinphoneCallStatsImpl_getLatePacketsCumulativeNumber(JNIEnv *env, jobject thiz, jlong stats_ptr) { LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr; return (jlong) linphone_call_stats_get_late_packets_cumulative_number(stats); } extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getJitterBufferSize(JNIEnv *env, jobject thiz, jlong stats_ptr) { - return (jfloat)((LinphoneCallStats *)stats_ptr)->jitter_stats.jitter_buffer_size_ms; + LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr; + return (jfloat)linphone_call_stats_get_jitter_buffer_size_ms(stats); } extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getLocalLossRate(JNIEnv *env, jobject thiz,jlong stats_ptr) { - const LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr; - return stats->local_loss_rate; + LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr; + return linphone_call_stats_get_local_loss_rate(stats); } extern "C" jfloat Java_org_linphone_core_LinphoneCallStatsImpl_getLocalLateRate(JNIEnv *env, jobject thiz, jlong stats_ptr) { - const LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr; - return stats->local_late_rate; + LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr; + return linphone_call_stats_get_local_late_rate(stats); } extern "C" jint Java_org_linphone_core_LinphoneCallStatsImpl_getIpFamilyOfRemote(JNIEnv *env, jobject thiz, jlong stats_ptr) { - return (jint) ((LinphoneCallStats *)stats_ptr)->rtp_remote_family; + LinphoneCallStats *stats = (LinphoneCallStats *)stats_ptr; + return (jint) linphone_call_stats_get_ip_family_of_remote(stats); } /*payloadType*/ @@ -3509,7 +3516,7 @@ JNIEXPORT jobject JNICALL Java_org_linphone_core_LinphoneCallImpl_getStats(JNIEn ,jlong ptr, jint type) { LinphoneCall *call=(LinphoneCall*)ptr; LinphoneJavaBindings *ljb = (LinphoneJavaBindings *) linphone_core_get_user_data(linphone_call_get_core(call)); - const LinphoneCallStats *stats = linphone_call_get_stats(call, (LinphoneStreamType)type); + LinphoneCallStats *stats = linphone_call_get_stats(call, (LinphoneStreamType)type); return stats ? env->NewObject(ljb->callStatsClass, ljb->callStatsId, (jlong)stats) : NULL; } diff --git a/include/linphone/call_stats.h b/include/linphone/call_stats.h index a5bd96c48..ff2074dba 100644 --- a/include/linphone/call_stats.h +++ b/include/linphone/call_stats.h @@ -88,6 +88,18 @@ LINPHONE_PUBLIC float linphone_call_stats_get_sender_loss_rate(const LinphoneCal **/ LINPHONE_PUBLIC float linphone_call_stats_get_receiver_loss_rate(const LinphoneCallStats *stats); +/** + * Get the local loss rate since last report + * @return The local loss rate +**/ +LINPHONE_PUBLIC float linphone_call_stats_get_local_loss_rate(const LinphoneCallStats *stats); + +/** + * Gets the local late rate since last report + * @return The local late rate +**/ +LINPHONE_PUBLIC float linphone_call_stats_get_local_late_rate(const LinphoneCallStats *stats); + /** * Gets the local interarrival jitter * @param[in] stats LinphoneCallStats object From e32dd9cf0509caed05b6a318d8e1b4b7732f517b Mon Sep 17 00:00:00 2001 From: Erwan Croze Date: Wed, 19 Apr 2017 16:48:51 +0200 Subject: [PATCH 57/70] Fix account_creator and account_creator_tester --- coreapi/account_creator.c | 32 ++++++++++++++++++++++----- coreapi/private.h | 11 ++++++++-- tester/account_creator_tester.c | 38 +++++++++++++++++++++++++++++++++ 3 files changed, 74 insertions(+), 7 deletions(-) diff --git a/coreapi/account_creator.c b/coreapi/account_creator.c index e10b26772..a9d71dfae 100644 --- a/coreapi/account_creator.c +++ b/coreapi/account_creator.c @@ -836,11 +836,33 @@ LinphoneAccountCreatorStatus linphone_account_creator_activate_account_linphone( } request = linphone_xml_rpc_request_new_with_args(LinphoneXmlRpcArgString, "activate_phone_account", - LinphoneXmlRpcArgString, creator->phone_number, - LinphoneXmlRpcArgString, creator->username ? creator->username : creator->phone_number, - LinphoneXmlRpcArgString, creator->activation_code, - linphone_proxy_config_get_domain(creator->proxy_cfg), - LinphoneXmlRpcArgNone); + LinphoneXmlRpcArgString, creator->phone_number, + LinphoneXmlRpcArgString, creator->username ? creator->username : creator->phone_number, + LinphoneXmlRpcArgString, creator->activation_code, + linphone_proxy_config_get_domain(creator->proxy_cfg), + LinphoneXmlRpcArgNone); + + linphone_xml_rpc_request_set_user_data(request, creator); + linphone_xml_rpc_request_cbs_set_response(linphone_xml_rpc_request_get_callbacks(request), _activate_account_cb_custom); + linphone_xml_rpc_session_send_request(creator->xmlrpc_session, request); + linphone_xml_rpc_request_unref(request); + return LinphoneAccountCreatorStatusRequestOk; +} + +LinphoneAccountCreatorStatus linphone_account_creator_activate_email_account_linphone(LinphoneAccountCreator *creator) { + LinphoneXmlRpcRequest *request; + if (!creator->activation_code) { + if (creator->cbs->is_account_activated_response_cb != NULL) { + creator->cbs->is_account_activated_response_cb(creator, LinphoneAccountCreatorStatusMissingArguments, "Missing required parameters"); + } + return LinphoneAccountCreatorStatusMissingArguments; + } + + request = linphone_xml_rpc_request_new_with_args(LinphoneXmlRpcArgString, "activate_email_account", + LinphoneXmlRpcArgString, creator->username, + LinphoneXmlRpcArgString, creator->activation_code, + linphone_proxy_config_get_domain(creator->proxy_cfg), + LinphoneXmlRpcArgNone); linphone_xml_rpc_request_set_user_data(request, creator); linphone_xml_rpc_request_cbs_set_response(linphone_xml_rpc_request_get_callbacks(request), _activate_account_cb_custom); diff --git a/coreapi/private.h b/coreapi/private.h index 1d4a0b08e..1e4f375d5 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -394,7 +394,7 @@ 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*/ @@ -1525,12 +1525,19 @@ LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_is_account LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_create_account_linphone(LinphoneAccountCreator *creator); /** - * Send an XML-RPC request to activate a Linphone account. + * Send an XML-RPC request to activate a Linphone account with phone number. * @param[in] creator LinphoneAccountCreator object * @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise **/ LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_activate_account_linphone(LinphoneAccountCreator *creator); +/** + * Send an XML-RPC request to activate a Linphone account with email. + * @param[in] creator LinphoneAccountCreator object + * @return LinphoneAccountCreatorStatusRequestOk if the request has been sent, LinphoneAccountCreatorStatusRequestFailed otherwise +**/ +LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_activate_email_account_linphone(LinphoneAccountCreator *creator); + /** * Send an XML-RPC request to test the validation of a Linphone account. * @param[in] creator LinphoneAccountCreator object diff --git a/tester/account_creator_tester.c b/tester/account_creator_tester.c index 108b10521..118187e8d 100644 --- a/tester/account_creator_tester.c +++ b/tester/account_creator_tester.c @@ -493,6 +493,28 @@ static void server_delete_account_test(void) { wait_for_until(marie->lc, NULL, &stats->cb_done, 1, TIMEOUT_REQUEST); + linphone_account_creator_unref(creator); + + creator = _linphone_account_creator_new(marie->lc, XMLRPC_URL); + cbs = linphone_account_creator_get_callbacks(creator); + + linphone_account_creator_cbs_set_user_data(cbs, stats); + account_creator_reset_cb_done(cbs); + linphone_account_creator_service_set_user_data( + linphone_account_creator_get_service(creator), + (void*)LinphoneAccountCreatorStatusRequestOk); + linphone_account_creator_set_username(creator, "XXXTESTuser_3"); + linphone_account_creator_set_email(creator, "user_1@linphone.org"); + linphone_account_creator_set_password(creator, "password"); + + BC_ASSERT_EQUAL( + delete_account_cb(creator), + LinphoneAccountCreatorStatusRequestOk, + LinphoneAccountCreatorStatus, + "%i"); + + wait_for_until(marie->lc, NULL, &stats->cb_done, 1, TIMEOUT_REQUEST); + ms_free(stats); linphone_account_creator_unref(creator); linphone_core_manager_destroy(marie); @@ -996,6 +1018,10 @@ static void server_activate_account_not_activated(void) { (void*)LinphoneAccountCreatorStatusAccountActivated); linphone_account_creator_cbs_set_activate_account(cbs, account_creator_cb); + linphone_account_creator_service_set_activate_account_cb( + linphone_account_creator_get_service(creator), + linphone_account_creator_activate_email_account_linphone); + BC_ASSERT_EQUAL( linphone_account_creator_activate_account(creator), LinphoneAccountCreatorStatusRequestOk, @@ -1026,6 +1052,9 @@ static void server_activate_account_already_activated(void) { linphone_account_creator_get_service(creator), (void*)LinphoneAccountCreatorStatusAccountAlreadyActivated); linphone_account_creator_cbs_set_activate_account(cbs, account_creator_cb); + linphone_account_creator_service_set_activate_account_cb( + linphone_account_creator_get_service(creator), + linphone_account_creator_activate_email_account_linphone); BC_ASSERT_EQUAL( linphone_account_creator_activate_account(creator), @@ -1055,6 +1084,9 @@ static void server_activate_non_existent_account(void) { linphone_account_creator_get_service(creator), (void*)LinphoneAccountCreatorStatusAccountNotActivated); linphone_account_creator_cbs_set_activate_account(cbs, account_creator_cb); + linphone_account_creator_service_set_activate_account_cb( + linphone_account_creator_get_service(creator), + linphone_account_creator_activate_email_account_linphone); BC_ASSERT_EQUAL( linphone_account_creator_activate_account(creator), @@ -1099,6 +1131,9 @@ static void server_activate_account_with_email_activated_arg_username_missing(vo linphone_account_creator_get_service(creator), (void*)LinphoneAccountCreatorStatusMissingArguments); linphone_account_creator_cbs_set_activate_account(cbs, account_creator_cb); + linphone_account_creator_service_set_activate_account_cb( + linphone_account_creator_get_service(creator), + linphone_account_creator_activate_email_account_linphone); BC_ASSERT_EQUAL( linphone_account_creator_activate_account(creator), @@ -1125,6 +1160,9 @@ static void server_activate_account_with_email_activated_arg_activation_code_mis linphone_account_creator_get_service(creator), (void*)LinphoneAccountCreatorStatusMissingArguments); linphone_account_creator_cbs_set_activate_account(cbs, account_creator_cb); + linphone_account_creator_service_set_activate_account_cb( + linphone_account_creator_get_service(creator), + linphone_account_creator_activate_email_account_linphone); BC_ASSERT_EQUAL( linphone_account_creator_activate_account(creator), From 05a9cf1279d6e26acc7f804849e5a29af458de62 Mon Sep 17 00:00:00 2001 From: Simon Morlat Date: Wed, 19 Apr 2017 16:55:02 +0200 Subject: [PATCH 58/70] fix zrtp bug --- coreapi/linphonecall.c | 2 +- tester/call_single_tester.c | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index d4f554a8f..1c4337e6d 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -4749,7 +4749,7 @@ void linphone_call_handle_stream_events(LinphoneCall *call, int stream_index){ } } else if (evt == ORTP_EVENT_ZRTP_SAS_READY) { if (stream_index == call->main_audio_stream_index) - linphone_call_audiostream_auth_token_ready(call, evd->info.zrtp_sas.sas, evd->info.zrtp_sas.verified); + linphone_call_audiostream_auth_token_ready(call, evd->info.zrtp_info.sas, evd->info.zrtp_info.verified); } else if (evt == ORTP_EVENT_DTLS_ENCRYPTION_CHANGED) { if (stream_index == call->main_audio_stream_index) linphone_call_audiostream_encryption_changed(call, evd->info.dtls_stream_encrypted); diff --git a/tester/call_single_tester.c b/tester/call_single_tester.c index ac001c86a..1e48d2d6d 100644 --- a/tester/call_single_tester.c +++ b/tester/call_single_tester.c @@ -2722,6 +2722,8 @@ static void _call_base_with_configfile(LinphoneMediaEncryption mode, bool_t enab BC_ASSERT_PTR_NOT_NULL(marie_token); if (marie_token && pauline_token){ BC_ASSERT_STRING_EQUAL(pauline_token, marie_token); + BC_ASSERT_TRUE(strlen(pauline_token)>0); + BC_ASSERT_TRUE(strlen(marie_token)>0); } if (!plays_nothing) liblinphone_tester_check_rtcp(pauline,marie); } From 101adaeab8d0f39b5523a68d5d67ae594274ca89 Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Wed, 19 Apr 2017 16:56:21 +0200 Subject: [PATCH 59/70] feat(coreapi/linphonecore): provide a `linphone_core_preview_ogl_render` function --- coreapi/linphonecall.c | 56 ++++++++++++++++++----------------------- coreapi/linphonecore.c | 28 +++++++++++++++------ include/linphone/call.h | 7 +++--- include/linphone/core.h | 15 ++++++++--- 4 files changed, 60 insertions(+), 46 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index 1c4337e6d..b7d5917fb 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -4326,7 +4326,7 @@ float linphone_call_stats_get_sender_loss_rate(const LinphoneCallStats *stats) { /* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */ if (stats->sent_rtcp->b_cont != NULL) msgpullup(stats->sent_rtcp, -1); - + do{ if (rtcp_is_SR(stats->sent_rtcp)) srb = rtcp_SR_get_report_block(stats->sent_rtcp, 0); @@ -4348,7 +4348,7 @@ float linphone_call_stats_get_receiver_loss_rate(const LinphoneCallStats *stats) /* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */ if (stats->received_rtcp->b_cont != NULL) msgpullup(stats->received_rtcp, -1); - + do{ if (rtcp_is_RR(stats->received_rtcp)) rrb = rtcp_RR_get_report_block(stats->received_rtcp, 0); @@ -4372,7 +4372,7 @@ float linphone_call_stats_get_local_late_rate(const LinphoneCallStats *stats) { float linphone_call_stats_get_sender_interarrival_jitter(const LinphoneCallStats *stats) { const report_block_t *srb = NULL; - + if (!stats || !stats->sent_rtcp) return 0.0; /* Perform msgpullup() to prevent crashes in rtcp_is_SR() or rtcp_is_RR() if the RTCP packet is composed of several mblk_t structure */ @@ -4474,14 +4474,14 @@ static void report_bandwidth_for_stream(LinphoneCall *call, MediaStream *ms, Lin } else { return; } - + stats->download_bandwidth=(active) ? (float)(media_stream_get_down_bw(ms)*1e-3) : 0.f; stats->upload_bandwidth=(active) ? (float)(media_stream_get_up_bw(ms)*1e-3) : 0.f; stats->rtcp_download_bandwidth=(active) ? (float)(media_stream_get_rtcp_down_bw(ms)*1e-3) : 0.f; stats->rtcp_upload_bandwidth=(active) ? (float)(media_stream_get_rtcp_up_bw(ms)*1e-3) : 0.f; stats->rtp_remote_family=(active) ? (ortp_stream_is_ipv6(&ms->sessions.rtp_session->rtp.gs) ? LinphoneAddressFamilyInet6 : LinphoneAddressFamilyInet) : LinphoneAddressFamilyUnspec; - + if (call->core->send_call_stats_periodical_updates){ if (active) update_local_stats(stats, ms); stats->updated |= LINPHONE_CALL_STATS_PERIODICAL_UPDATE; @@ -4815,7 +4815,7 @@ void linphone_call_background_tasks(LinphoneCall *call, bool_t one_second_elapse void linphone_call_log_completed(LinphoneCall *call){ LinphoneCore *lc=call->core; - + call->log->duration= _linphone_call_compute_duration(call); /*store duration since connected*/ call->log->error_info = linphone_error_info_ref((LinphoneErrorInfo*)linphone_call_get_error_info(call)); @@ -4938,7 +4938,7 @@ LinphonePlayer *linphone_call_get_player(LinphoneCall *call){ return call->player; } - + void linphone_call_set_params(LinphoneCall *call, const LinphoneCallParams *params){ if ( call->state == LinphoneCallOutgoingInit || call->state == LinphoneCallIncomingReceived){ _linphone_call_set_new_params(call, params); @@ -4948,7 +4948,7 @@ void linphone_call_set_params(LinphoneCall *call, const LinphoneCallParams *para } } - + void _linphone_call_set_new_params(LinphoneCall *call, const LinphoneCallParams *params){ LinphoneCallParams *cp=NULL; if (params) cp=linphone_call_params_copy(params); @@ -5262,11 +5262,11 @@ LinphoneStatus linphone_call_terminate(LinphoneCall *call) { return linphone_call_terminate_with_error_info(call, NULL); } - + LinphoneStatus linphone_call_terminate_with_error_info(LinphoneCall *call , const LinphoneErrorInfo *ei){ SalErrorInfo sei={0}; LinphoneErrorInfo* p_ei = (LinphoneErrorInfo*) ei; - + ms_message("Terminate call [%p] which is currently in state %s", call, linphone_call_state_to_string(call->state)); switch (call->state) { case LinphoneCallReleased: @@ -5283,7 +5283,7 @@ LinphoneStatus linphone_call_terminate_with_error_info(LinphoneCall *call , cons call->op = NULL; break; default: - + if (ei == NULL){ sal_call_terminate(call->op); } @@ -5297,7 +5297,7 @@ LinphoneStatus linphone_call_terminate_with_error_info(LinphoneCall *call , cons terminate_call(call); return 0; - + } LinphoneStatus linphone_call_redirect(LinphoneCall *call, const char *redirect_uri) { @@ -5339,14 +5339,14 @@ LinphoneStatus linphone_call_decline(LinphoneCall * call, LinphoneReason reason) linphone_error_info_unref(ei); return status; } - - + + LinphoneStatus linphone_call_decline_with_error_info(LinphoneCall * call, const LinphoneErrorInfo *ei) { SalErrorInfo sei = {0}; SalErrorInfo sub_sei = {0}; - + sei.sub_sei = &sub_sei; - + if ((call->state != LinphoneCallIncomingReceived) && (call->state != LinphoneCallIncomingEarlyMedia)) { ms_error("Cannot decline a call that is in state %s", linphone_call_state_to_string(call->state)); return -1; @@ -5653,12 +5653,12 @@ LinphoneStatus linphone_call_defer_update(LinphoneCall *call) { ms_error("linphone_call_defer_update() not done in state LinphoneCallUpdatedByRemote"); return -1; } - + if (call->expect_media_in_ack) { ms_error("linphone_call_defer_update() is not possible during a late offer incoming reINVITE (INVITE without SDP)"); return -1; } - + call->defer_update=TRUE; return 0; } @@ -5869,7 +5869,7 @@ int linphone_call_start_invite(LinphoneCall *call, const LinphoneAddress *destin linphone_call_ref(call); /* Take a ref because sal_call() may destroy the call if no SIP transport is available */ err = sal_call(call->op, from, real_url); - + if (err < 0) { if ((call->state != LinphoneCallError) && (call->state != LinphoneCallReleased)) { /* sal_call() may invoke call_failure() and call_released() SAL callbacks synchronously, @@ -6064,20 +6064,14 @@ void linphone_call_replace_op(LinphoneCall *call, SalOp *op) { sal_op_release(oldop); } -void linphone_call_ogl_render(LinphoneCall *call, bool_t is_preview) { +void linphone_call_ogl_render(const LinphoneCall *call) { + #ifdef VIDEO_ENABLED + VideoStream *stream = call->videostream; - if (!stream) - return; + if (stream && stream->output && ms_filter_get_id(stream->output) == MS_OGL_ID) + ms_filter_call_method(stream->output, MS_OGL_RENDER, NULL); - if (!is_preview) { - if (stream->output && ms_filter_get_id(stream->output) == MS_OGL_ID) - ms_filter_call_method(stream->output, MS_OGL_RENDER, NULL); - - return; - } - - if (stream->output2 && ms_filter_get_id(stream->output2) == MS_OGL_ID) - ms_filter_call_method(stream->output2, MS_OGL_RENDER, NULL); + #endif } void linphone_call_add_callbacks(LinphoneCall *call, LinphoneCallCbs *cbs) { diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 0620e2107..1aceead89 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -36,13 +36,14 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include #include #include -#include "mediastreamer2/mediastream.h" -#include "mediastreamer2/msfactory.h" -#include "mediastreamer2/mseventqueue.h" -#include "mediastreamer2/msvolume.h" -#include "mediastreamer2/msequalizer.h" #include "mediastreamer2/dtmfgen.h" +#include "mediastreamer2/mediastream.h" +#include "mediastreamer2/msequalizer.h" +#include "mediastreamer2/mseventqueue.h" +#include "mediastreamer2/msfactory.h" #include "mediastreamer2/msjpegwriter.h" +#include "mediastreamer2/msogl.h" +#include "mediastreamer2/msvolume.h" #ifdef INET6 #ifndef _WIN32 @@ -2861,7 +2862,7 @@ LinphoneStatus linphone_core_set_sip_transports(LinphoneCore *lc, const Linphone } LinphoneStatus linphone_core_set_transports(LinphoneCore *lc, const LinphoneTransports * transports){ - if (transports->udp_port == lc->sip_conf.transports.udp_port && + if (transports->udp_port == lc->sip_conf.transports.udp_port && transports->tcp_port == lc->sip_conf.transports.tcp_port && transports->tls_port == lc->sip_conf.transports.tls_port && transports->dtls_port == lc->sip_conf.transports.dtls_port) { @@ -5321,7 +5322,7 @@ void linphone_core_set_preferred_video_definition(LinphoneCore *lc, LinphoneVide if (video_definition_supported(vdef)) { LinphoneVideoDefinition *oldvdef = lc->video_conf.vdef; lc->video_conf.vdef = linphone_video_definition_ref(vdef); - + if ((lc->previewstream != NULL) && (lc->video_conf.preview_vdef == NULL) && (oldvdef != NULL) && !linphone_video_definition_equals(oldvdef, vdef)) { relaunch_video_preview(lc); @@ -5459,6 +5460,19 @@ float linphone_core_get_preferred_framerate(LinphoneCore *lc){ return lc->video_conf.fps; } +void linphone_core_preview_ogl_render(const LinphoneCore *lc) { + #ifdef VIDEO_ENABLED + + LinphoneCall *call = linphone_core_get_current_call(lc); + VideoStream *stream; + + if (call && (stream = call->videostream) && stream->output2 && ms_filter_get_id(stream->output2) == MS_OGL_ID) + ms_filter_call_method(stream->output2, MS_OGL_RENDER, NULL); + else if ((stream = lc->previewstream) && stream->output && ms_filter_get_id(stream->output) == MS_OGL_ID) + ms_filter_call_method(stream->output, MS_OGL_RENDER, NULL); + + #endif +} void linphone_core_set_use_files(LinphoneCore *lc, bool_t yesno){ lc->use_files=yesno; diff --git a/include/linphone/call.h b/include/linphone/call.h index bbe04ae08..bef02c5a1 100644 --- a/include/linphone/call.h +++ b/include/linphone/call.h @@ -381,11 +381,11 @@ LINPHONE_PUBLIC LinphoneStatus linphone_call_resume(LinphoneCall *call); * @return 0 on success, -1 on failure **/LINPHONE_PUBLIC LinphoneStatus linphone_call_terminate(LinphoneCall *call); - + /** * Terminates a call. * @param[in] call LinphoneCall object - * @param[in] ei LinphoneErrorInfo + * @param[in] ei LinphoneErrorInfo * @return 0 on success, -1 on failure **/ LINPHONE_PUBLIC LinphoneStatus linphone_call_terminate_with_error_info(LinphoneCall *call, const LinphoneErrorInfo *ei); @@ -820,9 +820,8 @@ LINPHONE_PUBLIC bool_t linphone_call_media_in_progress(LinphoneCall *call); /** * Call generic OpenGL render for a given call. * @param call The call. - * @is_preview If true the preview is displayed otherwise it's the input stream. */ -LINPHONE_PUBLIC void linphone_call_ogl_render(LinphoneCall *call, bool_t is_preview); +LINPHONE_PUBLIC void linphone_call_ogl_render(const LinphoneCall *call); diff --git a/include/linphone/core.h b/include/linphone/core.h index d6d8ac3ec..15f52e6da 100644 --- a/include/linphone/core.h +++ b/include/linphone/core.h @@ -3209,7 +3209,7 @@ LINPHONE_PUBLIC bool_t linphone_core_video_display_enabled(LinphoneCore *lc); * This policy defines whether: * - video shall be initiated by default for outgoing calls * - video shall be accepter by default for incoming calls - * + * * @param[in] lc LinphoneCore object * @param[in] policy The video policy to use * @ingroup media_parameters @@ -3428,6 +3428,13 @@ LINPHONE_PUBLIC void linphone_core_set_preferred_framerate(LinphoneCore *lc, flo **/ LINPHONE_PUBLIC float linphone_core_get_preferred_framerate(LinphoneCore *lc); +/** + * Call generic OpenGL render for a given core. + * @param lc The core. + * @ingroup media_parameters + */ +LINPHONE_PUBLIC void linphone_core_preview_ogl_render(const LinphoneCore *lc); + /** * Controls video preview enablement. * @param[in] lc LinphoneCore object @@ -5119,8 +5126,8 @@ LINPHONE_PUBLIC LinphonePresencePerson * linphone_core_create_presence_person(Li * @return The created #LinphonePresenceService object. */ LINPHONE_PUBLIC LinphonePresenceService * linphone_core_create_presence_service(LinphoneCore *lc, const char *id, LinphonePresenceBasicStatus basic_status, const char *contact); - - + + /** * Notifies the upper layer that a presence status has been received by calling the appropriate * callback if one has been set. @@ -5139,7 +5146,7 @@ LINPHONE_PUBLIC void linphone_core_notify_notify_presence_received(LinphoneCore * @param[in] presence_model the #LinphonePresenceModel that has been modified */ LINPHONE_PUBLIC void linphone_core_notify_notify_presence_received_for_uri_or_tel(LinphoneCore *lc, LinphoneFriend *lf, const char *uri_or_tel, const LinphonePresenceModel *presence_model); - + /** From fba1e7ccb12cd83865b736d873bcd8ac28e73920 Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Wed, 19 Apr 2017 18:14:28 +0200 Subject: [PATCH 60/70] Fixed missing bandwidth information for video/text since rework --- coreapi/linphonecall.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/coreapi/linphonecall.c b/coreapi/linphonecall.c index b7d5917fb..2d90b81e8 100644 --- a/coreapi/linphonecall.c +++ b/coreapi/linphonecall.c @@ -4467,9 +4467,9 @@ static void report_bandwidth_for_stream(LinphoneCall *call, MediaStream *ms, Lin LinphoneCallStats *stats = NULL; if (type == LinphoneStreamTypeAudio) { stats = call->audio_stats; - } else if (type == LinphoneStreamTypeAudio) { + } else if (type == LinphoneStreamTypeVideo) { stats = call->video_stats; - } else if (type == LinphoneStreamTypeAudio) { + } else if (type == LinphoneStreamTypeText) { stats = call->text_stats; } else { return; From 740eac982a2f15c93d30499a8972a8c9d5144f4f Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Thu, 20 Apr 2017 11:19:07 +0200 Subject: [PATCH 61/70] fix(coreapi/linphonecore): fix preview ogl render, use now output2 --- coreapi/linphonecore.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 1aceead89..8eb7f8148 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -5464,12 +5464,10 @@ void linphone_core_preview_ogl_render(const LinphoneCore *lc) { #ifdef VIDEO_ENABLED LinphoneCall *call = linphone_core_get_current_call(lc); - VideoStream *stream; + VideoStream *stream = call ? call->videostream : lc->previewstream; - if (call && (stream = call->videostream) && stream->output2 && ms_filter_get_id(stream->output2) == MS_OGL_ID) + if (stream && stream->output2 && ms_filter_get_id(stream->output2) == MS_OGL_ID) ms_filter_call_method(stream->output2, MS_OGL_RENDER, NULL); - else if ((stream = lc->previewstream) && stream->output && ms_filter_get_id(stream->output) == MS_OGL_ID) - ms_filter_call_method(stream->output, MS_OGL_RENDER, NULL); #endif } From e71cdfa71379526a7dde7e747b76a9e844e7eebf Mon Sep 17 00:00:00 2001 From: Sylvain Berfini Date: Thu, 20 Apr 2017 11:38:37 +0200 Subject: [PATCH 62/70] Added getter/setter for LinphoneVideoActivationPolicy object --- coreapi/linphonecore.c | 16 ++++++++++++++++ include/linphone/core.h | 32 ++++++++++++++++++++++++++++++++ 2 files changed, 48 insertions(+) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 8eb7f8148..3957d1910 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -4953,6 +4953,22 @@ void linphone_video_activation_policy_set_user_data(LinphoneVideoActivationPolic policy->user_data = data; } +bool_t linphone_video_activation_policy_get_automatically_accept(const LinphoneVideoActivationPolicy *policy) { + return policy->automatically_accept; +} + +bool_t linphone_video_activation_policy_get_automatically_initiate(const LinphoneVideoActivationPolicy *policy) { + return policy->automatically_initiate; +} + +void linphone_video_activation_policy_set_automatically_accept(LinphoneVideoActivationPolicy *policy, bool_t enable) { + policy->automatically_accept = enable; +} + +void linphone_video_activation_policy_set_automatically_initiate(LinphoneVideoActivationPolicy *policy, bool_t enable) { + policy->automatically_initiate = enable; +} + void linphone_core_set_video_activation_policy(LinphoneCore *lc, const LinphoneVideoActivationPolicy *policy) { lc->video_policy.automatically_accept = policy->automatically_accept; lc->video_policy.automatically_initiate = policy->automatically_initiate; diff --git a/include/linphone/core.h b/include/linphone/core.h index 15f52e6da..2ba7899e7 100644 --- a/include/linphone/core.h +++ b/include/linphone/core.h @@ -3257,6 +3257,38 @@ LINPHONE_PUBLIC void *linphone_video_activation_policy_get_user_data(const Linph */ LINPHONE_PUBLIC void linphone_video_activation_policy_set_user_data(LinphoneVideoActivationPolicy *policy, void *data); +/** + * Gets the value for the automatically accept video policy + * @param[in] policy the LinphoneVideoActivationPolicy object + * @return whether or not to automatically accept video requests is enabled + * @ingroup media_parameters +*/ +LINPHONE_PUBLIC bool_t linphone_video_activation_policy_get_automatically_accept(const LinphoneVideoActivationPolicy *policy); + +/** + * Gets the value for the automatically initiate video policy + * @param[in] policy the LinphoneVideoActivationPolicy object + * @return whether or not to automatically initiate video calls is enabled + * @ingroup media_parameters +*/ +LINPHONE_PUBLIC bool_t linphone_video_activation_policy_get_automatically_initiate(const LinphoneVideoActivationPolicy *policy); + +/** + * Sets the value for the automatically accept video policy + * @param[in] policy the LinphoneVideoActivationPolicy object + * @param[in] enable whether or not to enable automatically accept video requests + * @ingroup media_parameters +*/ +LINPHONE_PUBLIC void linphone_video_activation_policy_set_automatically_accept(LinphoneVideoActivationPolicy *policy, bool_t enable); + +/** + * Sets the value for the automatically initiate video policy + * @param[in] policy the LinphoneVideoActivationPolicy object + * @param[in] enable whether or not to enable automatically initiate video calls + * @ingroup media_parameters +*/ +LINPHONE_PUBLIC void linphone_video_activation_policy_set_automatically_initiate(LinphoneVideoActivationPolicy *policy, bool_t enable); + /** * Sets the default policy for video. * This policy defines whether: From b7610d5d0b950596d11e813eea371cd798ad0545 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Thu, 20 Apr 2017 14:40:23 +0200 Subject: [PATCH 63/70] Fix definition of video preview. --- coreapi/linphonecore.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/coreapi/linphonecore.c b/coreapi/linphonecore.c index 3957d1910..2d546440a 100644 --- a/coreapi/linphonecore.c +++ b/coreapi/linphonecore.c @@ -4812,7 +4812,13 @@ static void toggle_video_preview(LinphoneCore *lc, bool_t val){ if (val){ if (lc->previewstream==NULL){ const char *display_filter=linphone_core_get_video_display_filter(lc); - MSVideoSize vsize=lc->video_conf.preview_vsize.width!=0 ? lc->video_conf.preview_vsize : lc->video_conf.vsize; + MSVideoSize vsize = { 0 }; + const LinphoneVideoDefinition *vdef = linphone_core_get_preview_video_definition(lc); + if (!vdef || linphone_video_definition_is_undefined(vdef)) { + vdef = linphone_core_get_preferred_video_definition(lc); + } + vsize.width = linphone_video_definition_get_width(vdef); + vsize.height = linphone_video_definition_get_height(vdef); lc->previewstream=video_preview_new(lc->factory); video_preview_set_size(lc->previewstream,vsize); if (display_filter) From 0442579dea809c1a80bdfcb40f993858c4c020d3 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Thu, 20 Apr 2017 15:26:25 +0200 Subject: [PATCH 64/70] Add missing symbol exports. --- coreapi/private.h | 6 +++--- include/linphone/video_definition.h | 8 ++++---- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/coreapi/private.h b/coreapi/private.h index 1e4f375d5..423a0d4f2 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -415,8 +415,8 @@ void linphone_call_notify_info_message_received(LinphoneCall *call, const Linpho LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, const LinphoneCallParams *params, LinphoneProxyConfig *cfg); LinphoneCall * linphone_call_new_incoming(struct _LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, SalOp *op); void _linphone_call_set_new_params(LinphoneCall *call, const LinphoneCallParams *params); -void linphone_call_set_params(LinphoneCall *call, const LinphoneCallParams *params); -const LinphoneCallParams * linphone_call_get_params(LinphoneCall *call); +LINPHONE_PUBLIC void linphone_call_set_params(LinphoneCall *call, const LinphoneCallParams *params); +LINPHONE_PUBLIC const LinphoneCallParams * linphone_call_get_params(LinphoneCall *call); void linphone_call_set_state(LinphoneCall *call, LinphoneCallState cstate, const char *message); void linphone_call_set_contact_op(LinphoneCall* call); void linphone_call_set_compatible_incoming_call_parameters(LinphoneCall *call, SalMediaDescription *md); @@ -1757,7 +1757,7 @@ struct _LinphoneTransports { BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneTransports); -LinphoneTransports *linphone_transports_new(void); +LINPHONE_PUBLIC LinphoneTransports *linphone_transports_new(void); struct _LinphoneVideoActivationPolicy { belle_sip_object_t base; diff --git a/include/linphone/video_definition.h b/include/linphone/video_definition.h index c89b545d7..f33973778 100644 --- a/include/linphone/video_definition.h +++ b/include/linphone/video_definition.h @@ -102,7 +102,7 @@ LINPHONE_PUBLIC void linphone_video_definition_set_height(LinphoneVideoDefinitio * @param[in] width The width of the video definition * @param[in] height The height of the video definition */ -void linphone_video_definition_set_definition(LinphoneVideoDefinition *vdef, unsigned int width, unsigned int height); +LINPHONE_PUBLIC void linphone_video_definition_set_definition(LinphoneVideoDefinition *vdef, unsigned int width, unsigned int height); /** * Get the name of the video definition. @@ -124,7 +124,7 @@ LINPHONE_PUBLIC void linphone_video_definition_set_name(LinphoneVideoDefinition * @param[in] vdef2 LinphoneVideoDefinition object * @return A boolean value telling whether the two LinphoneVideoDefinition objects are equal. */ -bool_t linphone_video_definition_equals(const LinphoneVideoDefinition *vdef1, const LinphoneVideoDefinition *vdef2); +LINPHONE_PUBLIC bool_t linphone_video_definition_equals(const LinphoneVideoDefinition *vdef1, const LinphoneVideoDefinition *vdef2); /** * Tells whether two LinphoneVideoDefinition objects are strictly equal (the widths are the same and the heights are the same). @@ -132,14 +132,14 @@ bool_t linphone_video_definition_equals(const LinphoneVideoDefinition *vdef1, co * @param[in] vdef2 LinphoneVideoDefinition object * @return A boolean value telling whether the two LinphoneVideoDefinition objects are strictly equal. */ -bool_t linphone_video_definition_strict_equals(const LinphoneVideoDefinition *vdef1, const LinphoneVideoDefinition *vdef2); +LINPHONE_PUBLIC bool_t linphone_video_definition_strict_equals(const LinphoneVideoDefinition *vdef1, const LinphoneVideoDefinition *vdef2); /** * Tells whether a LinphoneVideoDefinition is undefined. * @param[in] vdef LinphoneVideoDefinition object * @return A boolean value telling whether the LinphoneVideoDefinition is undefined. */ -bool_t linphone_video_definition_is_undefined(const LinphoneVideoDefinition *vdef); +LINPHONE_PUBLIC bool_t linphone_video_definition_is_undefined(const LinphoneVideoDefinition *vdef); /** * @} From f14445134245adcc7841514e08824a29b44d5e39 Mon Sep 17 00:00:00 2001 From: Erwan Croze Date: Fri, 21 Apr 2017 10:58:25 +0200 Subject: [PATCH 65/70] Some change on Account_creator --- coreapi/account_creator.c | 104 ++++++++++------------------- coreapi/private.h | 3 +- include/linphone/account_creator.h | 19 +++++- 3 files changed, 53 insertions(+), 73 deletions(-) diff --git a/coreapi/account_creator.c b/coreapi/account_creator.c index a9d71dfae..d9f4912ef 100644 --- a/coreapi/account_creator.c +++ b/coreapi/account_creator.c @@ -47,7 +47,7 @@ static unsigned int validate_uri(const char* username, const char* domain, const LinphoneAddress* addr; int status = 0; LinphoneProxyConfig* proxy = linphone_proxy_config_new(); - linphone_proxy_config_set_identity(proxy, "sip:userame@domain.com"); + linphone_proxy_config_set_identity(proxy, "sip:?@domain.com"); if (username) { addr = linphone_proxy_config_normalize_sip_uri(proxy, username); @@ -113,8 +113,19 @@ LinphoneProxyConfig * linphone_account_creator_create_proxy_config(const Linphon LinphoneProxyConfig *cfg = linphone_core_create_proxy_config(creator->core); char *identity_str = _get_identity(creator); LinphoneAddress *identity = linphone_address_new(identity_str); - ms_free(identity_str); + char *route = NULL; + char *domain = NULL; + ms_free(identity_str); + if (creator->display_name) { + linphone_address_set_display_name(identity, creator->display_name); + } + if (creator->route) { + route = ms_strdup_printf("%s", creator->route); + } + if (creator->domain) { + domain = ms_strdup_printf("%s;transport=%s", creator->domain, linphone_transport_to_string(creator->transport)); + } linphone_proxy_config_set_identity_address(cfg, identity); if (creator->phone_country_code) { linphone_proxy_config_set_dial_prefix(cfg, creator->phone_country_code); @@ -124,6 +135,13 @@ LinphoneProxyConfig * linphone_account_creator_create_proxy_config(const Linphon snprintf(buff, sizeof(buff), "%d", dial_prefix_number); linphone_proxy_config_set_dial_prefix(cfg, buff); } + if (linphone_proxy_config_get_server_addr(cfg) == NULL) + linphone_proxy_config_set_server_addr(cfg, domain); + if (linphone_proxy_config_get_route(cfg) == NULL) + linphone_proxy_config_set_route(cfg, route); + + linphone_proxy_config_enable_publish(cfg, FALSE); + linphone_proxy_config_enable_register(cfg, TRUE); info = linphone_auth_info_new(linphone_address_get_username(identity), // username NULL, //user id @@ -145,74 +163,7 @@ LinphoneProxyConfig * linphone_account_creator_create_proxy_config(const Linphon } LinphoneProxyConfig * linphone_account_creator_configure(const LinphoneAccountCreator *creator) { - LinphoneAuthInfo *info; - LinphoneProxyConfig *cfg = creator->proxy_cfg; - char *identity_str = _get_identity(creator); - LinphoneAddress *identity = linphone_address_new(identity_str); - char *route = NULL; - char *domain = NULL; - ms_free(identity_str); - if (creator->display_name) { - linphone_address_set_display_name(identity, creator->display_name); - } - if (creator->route) { - route = ms_strdup_printf("%s", creator->route); - } - if (creator->domain) { - domain = ms_strdup_printf("%s", creator->domain); - } - linphone_proxy_config_set_identity_address(cfg, identity); - if (creator->phone_country_code) { - linphone_proxy_config_set_dial_prefix(cfg, creator->phone_country_code); - } else if (creator->phone_number) { - int dial_prefix_number = linphone_dial_plan_lookup_ccc_from_e164(creator->phone_number); - char buff[4]; - snprintf(buff, sizeof(buff), "%d", dial_prefix_number); - linphone_proxy_config_set_dial_prefix(cfg, buff); - } - if (linphone_proxy_config_get_server_addr(cfg) == NULL) - linphone_proxy_config_set_server_addr(cfg, domain); - if (linphone_proxy_config_get_route(cfg) == NULL) - linphone_proxy_config_set_route(cfg, route); - - linphone_proxy_config_enable_publish(cfg, FALSE); - linphone_proxy_config_enable_register(cfg, TRUE); - - if (linphone_proxy_config_get_realm(cfg) != NULL - && strcmp(linphone_proxy_config_get_realm(cfg), "sip.linphone.org") == 0) { - linphone_proxy_config_enable_avpf(cfg, TRUE); - // If account created on sip.linphone.org, we configure linphone to use TLS by default - if (linphone_core_sip_transport_supported(creator->core, LinphoneTransportTls)) { - LinphoneAddress *addr = linphone_address_new(linphone_proxy_config_get_server_addr(cfg)); - char *tmp; - linphone_address_set_transport(addr, LinphoneTransportTls); - tmp = linphone_address_as_string(addr); - linphone_proxy_config_set_server_addr(cfg, tmp); - linphone_proxy_config_set_route(cfg, tmp); - ms_free(tmp); - linphone_address_unref(addr); - } - linphone_core_set_stun_server(creator->core, "stun.linphone.org"); - linphone_core_set_firewall_policy(creator->core, LinphonePolicyUseIce); - } - - info = linphone_auth_info_new(linphone_address_get_username(identity), // username - NULL, //user id - creator->password, // passwd - creator->password ? NULL : creator->ha1, // ha1 - !creator->password && creator->ha1 ? linphone_address_get_domain(identity) : NULL, // realm - assumed to be domain - linphone_address_get_domain(identity) // domain - ); - linphone_core_add_auth_info(creator->core, info); - linphone_address_unref(identity); - - if (linphone_core_add_proxy_config(creator->core, cfg) != -1) { - linphone_core_set_default_proxy(creator->core, cfg); - return cfg; - } - - linphone_core_remove_auth_info(creator->core, info); - return NULL; + return linphone_account_creator_create_proxy_config(creator); } /************************** End Misc **************************/ @@ -347,6 +298,7 @@ LinphoneAccountCreator * _linphone_account_creator_new(LinphoneCore *core, const creator->service = linphone_core_get_account_creator_service(core); creator->cbs = linphone_account_creator_cbs_new(); creator->core = core; + creator->transport = LinphoneTransportTcp; creator->xmlrpc_session = (xmlrpc_url) ? linphone_xml_rpc_session_new(core, xmlrpc_url) : NULL; if (domain) { linphone_account_creator_set_domain(creator, domain); @@ -568,6 +520,18 @@ const char * linphone_account_creator_get_domain(const LinphoneAccountCreator *c return creator->domain; } +LinphoneAccountCreatorStatus linphone_account_creator_set_transport(LinphoneAccountCreator *creator, LinphoneTransportType transport) { + if (!linphone_core_sip_transport_supported(creator->core, transport)) { + return LinphoneAccountCreatorStatusRequestFailed; + } + creator->transport = transport; + return LinphoneAccountCreatorStatusRequestOk; +} + +LinphoneTransportType linphone_account_creator_get_transport(const LinphoneAccountCreator *creator) { + return creator->transport; +} + LinphoneAccountCreatorStatus linphone_account_creator_set_route(LinphoneAccountCreator *creator, const char *route) { if (!route || linphone_proxy_config_set_route(creator->proxy_cfg, route) != 0) return LinphoneAccountCreatorStatusRequestFailed; diff --git a/coreapi/private.h b/coreapi/private.h index 423a0d4f2..d6e83f35c 100644 --- a/coreapi/private.h +++ b/coreapi/private.h @@ -1495,9 +1495,10 @@ struct _LinphoneAccountCreator { /* Misc */ char *language; /**< User language */ char *activation_code; /**< Account validation code */ + char *domain; /**< Domain */ + LinphoneTransportType transport; /**< Transport used */ /* Deprecated */ - char *domain; char *route; }; diff --git a/include/linphone/account_creator.h b/include/linphone/account_creator.h index 5dd48f1a6..6e54e6b25 100644 --- a/include/linphone/account_creator.h +++ b/include/linphone/account_creator.h @@ -279,14 +279,29 @@ LINPHONE_PUBLIC const char * linphone_account_creator_get_email(const LinphoneAc * @param[in] domain The domain to set * @return LinphoneAccountCreatorStatusRequestOk if everything is OK, or a specific error otherwise. **/ -LINPHONE_DEPRECATED LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_set_domain(LinphoneAccountCreator *creator, const char *domain); +LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_set_domain(LinphoneAccountCreator *creator, const char *domain); /** * Get the domain. * @param[in] creator LinphoneAccountCreator object * @return The domain of the LinphoneAccountCreator **/ -LINPHONE_DEPRECATED LINPHONE_PUBLIC const char * linphone_account_creator_get_domain(const LinphoneAccountCreator *creator); +LINPHONE_PUBLIC const char * linphone_account_creator_get_domain(const LinphoneAccountCreator *creator); + +/** + * Set Transport + * @param[in] creator LinphoneAccountCreator object + * @param[in] transport The transport to set + * @return LinphoneAccountCreatorStatusRequestOk if everything is OK, or a specific error otherwise. +**/ +LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_set_transport(LinphoneAccountCreator *creator, LinphoneTransportType transport); + +/** + * get Transport + * @param[in] creator LinphoneAccountCreator object + * @return The transport of LinphoneAccountCreator +**/ +LINPHONE_PUBLIC LinphoneTransportType linphone_account_creator_get_transport(const LinphoneAccountCreator *creator); /** * Set the route. From 99aa481b51c47d69f0b0295ca6d476fc0ed91f1b Mon Sep 17 00:00:00 2001 From: Erwan Croze Date: Fri, 21 Apr 2017 11:10:39 +0200 Subject: [PATCH 66/70] Add new enum to account_creator --- coreapi/account_creator.c | 12 ++++++------ include/linphone/account_creator.h | 8 ++++---- include/linphone/types.h | 18 ++++++++++++++++++ 3 files changed, 28 insertions(+), 10 deletions(-) diff --git a/coreapi/account_creator.c b/coreapi/account_creator.c index d9f4912ef..7c048b17b 100644 --- a/coreapi/account_creator.c +++ b/coreapi/account_creator.c @@ -507,25 +507,25 @@ const char * linphone_account_creator_get_email(const LinphoneAccountCreator *cr return creator->email; } -LinphoneAccountCreatorStatus linphone_account_creator_set_domain(LinphoneAccountCreator *creator, const char *domain) { +LinphoneAccountCreatorDomainStatus linphone_account_creator_set_domain(LinphoneAccountCreator *creator, const char *domain) { if (domain && validate_uri(NULL, domain, NULL) != 0) { - return LinphoneAccountCreatorStatusRequestFailed; + return LinphoneAccountCreatorDomainInvalid; } set_string(&creator->domain, domain, TRUE); - return LinphoneAccountCreatorStatusRequestOk; + return LinphoneAccountCreatorDomainOk; } const char * linphone_account_creator_get_domain(const LinphoneAccountCreator *creator) { return creator->domain; } -LinphoneAccountCreatorStatus linphone_account_creator_set_transport(LinphoneAccountCreator *creator, LinphoneTransportType transport) { +LinphoneAccountCreatorTransportStatus linphone_account_creator_set_transport(LinphoneAccountCreator *creator, LinphoneTransportType transport) { if (!linphone_core_sip_transport_supported(creator->core, transport)) { - return LinphoneAccountCreatorStatusRequestFailed; + return LinphoneAccountCreatorTransportUnsupported; } creator->transport = transport; - return LinphoneAccountCreatorStatusRequestOk; + return LinphoneAccountCreatorTransportOk; } LinphoneTransportType linphone_account_creator_get_transport(const LinphoneAccountCreator *creator) { diff --git a/include/linphone/account_creator.h b/include/linphone/account_creator.h index 6e54e6b25..a9eff7f2b 100644 --- a/include/linphone/account_creator.h +++ b/include/linphone/account_creator.h @@ -277,9 +277,9 @@ LINPHONE_PUBLIC const char * linphone_account_creator_get_email(const LinphoneAc * Set the domain. * @param[in] creator LinphoneAccountCreator object * @param[in] domain The domain to set - * @return LinphoneAccountCreatorStatusRequestOk if everything is OK, or a specific error otherwise. + * @return LinphoneAccountCreatorDomainOk if everything is OK, or a specific error otherwise. **/ -LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_set_domain(LinphoneAccountCreator *creator, const char *domain); +LINPHONE_PUBLIC LinphoneAccountCreatorDomainStatus linphone_account_creator_set_domain(LinphoneAccountCreator *creator, const char *domain); /** * Get the domain. @@ -292,9 +292,9 @@ LINPHONE_PUBLIC const char * linphone_account_creator_get_domain(const LinphoneA * Set Transport * @param[in] creator LinphoneAccountCreator object * @param[in] transport The transport to set - * @return LinphoneAccountCreatorStatusRequestOk if everything is OK, or a specific error otherwise. + * @return LinphoneAccountCreatorTransportOk if everything is OK, or a specific error otherwise. **/ -LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_set_transport(LinphoneAccountCreator *creator, LinphoneTransportType transport); +LINPHONE_PUBLIC LinphoneAccountCreatorTransportStatus linphone_account_creator_set_transport(LinphoneAccountCreator *creator, LinphoneTransportType transport); /** * get Transport diff --git a/include/linphone/types.h b/include/linphone/types.h index 0fd749bfd..2fd84800b 100644 --- a/include/linphone/types.h +++ b/include/linphone/types.h @@ -117,6 +117,24 @@ typedef enum _LinphoneAccountCreatorActivationCodeStatus { LinphoneAccountCreatorActivationCodeStatusInvalidCharacters /**< Contain invalid characters */ } LinphoneAccountCreatorActivationCodeStatus; +/** + * Enum describing Domain checking + * @ingroup account_creator +**/ +typedef enum _LinphoneAccountCreatorDomainStatus { + LinphoneAccountCreatorDomainOk, /**< Domain ok */ + LinphoneAccountCreatorDomainInvalid /**< Domain invalid */ +} LinphoneAccountCreatorDomainStatus; + +/** + * Enum describing Transport checking + * @ingroup account_creator +**/ +typedef enum _LinphoneAccountCreatorTransportStatus { + LinphoneAccountCreatorTransportOk, /**< Transport ok */ + LinphoneAccountCreatorTransportUnsupported /**< Transport invalid */ +} LinphoneAccountCreatorTransportStatus; + /** * Enum describing the status of server request. * @ingroup account_creator_request From 1b2ed9e0883efe1eb52e39a2b7e67e7d0840cb87 Mon Sep 17 00:00:00 2001 From: Ghislain MARY Date: Fri, 21 Apr 2017 11:26:25 +0200 Subject: [PATCH 67/70] Simplify LinphoneConfig.cmake.in. --- cmake/LinphoneConfig.cmake.in | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/cmake/LinphoneConfig.cmake.in b/cmake/LinphoneConfig.cmake.in index 25ab6cc6e..264b8331a 100644 --- a/cmake/LinphoneConfig.cmake.in +++ b/cmake/LinphoneConfig.cmake.in @@ -45,11 +45,7 @@ if(@ENABLE_SHARED@) set(LINPHONE_LIBRARIES ${LINPHONE_TARGETNAME}) else() set(LINPHONE_TARGETNAME linphone-static) - get_target_property(LINPHONE_LIBRARIES ${LINPHONE_TARGETNAME} LOCATION) - get_target_property(LINPHONE_LINK_LIBRARIES ${LINPHONE_TARGETNAME} INTERFACE_LINK_LIBRARIES) - if(LINPHONE_LINK_LIBRARIES) - list(APPEND LINPHONE_LIBRARIES ${LINPHONE_LINK_LIBRARIES}) - endif() + bc_set_libraries_from_static_target(LINPHONE_LIBRARIES ${LINPHONE_TARGETNAME}) endif() get_target_property(LINPHONE_INCLUDE_DIRS ${LINPHONE_TARGETNAME} INTERFACE_INCLUDE_DIRECTORIES) if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS) From cc244afc0867464323a52d5741e0ac39a6796d14 Mon Sep 17 00:00:00 2001 From: Erwan Croze Date: Fri, 21 Apr 2017 14:00:53 +0200 Subject: [PATCH 68/70] Add new create proxy config in account creator --- include/linphone/account_creator.h | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/include/linphone/account_creator.h b/include/linphone/account_creator.h index a9eff7f2b..bf5e5fc5a 100644 --- a/include/linphone/account_creator.h +++ b/include/linphone/account_creator.h @@ -506,11 +506,18 @@ LINPHONE_PUBLIC void linphone_account_creator_cbs_set_update_account(LinphoneAcc /************************** End Account Creator Cbs **************************/ +/** + * Create and configure a proxy config and a authentication info for an account creator + * @param[in] creator LinphoneAccountCreator object + * @return A LinphoneProxyConfig object if successful, NULL otherwise +**/ +LINPHONE_PUBLIC LinphoneProxyConfig * linphone_account_creator_create_proxy_config(const LinphoneAccountCreator *creator); + /** * Configure an account (create a proxy config and authentication info for it). * @param[in] creator LinphoneAccountCreator object * @return A LinphoneProxyConfig object if successful, NULL otherwise - **/ +**/ LINPHONE_DEPRECATED LINPHONE_PUBLIC LinphoneProxyConfig * linphone_account_creator_configure(const LinphoneAccountCreator *creator); /** From 1867815979f8dda9376939d96686b48bda0b52d1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Thu, 20 Apr 2017 10:34:45 +0200 Subject: [PATCH 69/70] Add a brief to each documentation group --- coreapi/help/doxygen.dox | 200 ++++++++++++++++++++++----------------- 1 file changed, 114 insertions(+), 86 deletions(-) diff --git a/coreapi/help/doxygen.dox b/coreapi/help/doxygen.dox index db7af3a0b..38002841c 100644 --- a/coreapi/help/doxygen.dox +++ b/coreapi/help/doxygen.dox @@ -30,11 +30,13 @@ */ /** - * @defgroup initializing Initializing liblinphone + * @defgroup initializing Initializing + * @brief Initializing liblinphone. **/ /** - * @defgroup call_control Placing and receiving calls + * @defgroup call_control Call control + * @brief Placing and receiving calls. * * The #LinphoneCall object represents an incoming or outgoing call managed by the #LinphoneCore. * Outgoing calls can be created using linphone_core_invite() or linphone_core_invite_address(), while incoming calls are notified to the application @@ -45,32 +47,40 @@ **/ /** - * @defgroup call_misc Obtaining information about a running call: sound volumes, quality indicators + * @defgroup call_misc Call misc + * @brief Obtaining information about a running call: sound volumes, quality indicators. * * When a call is running, it is possible to retrieve in real time current measured volumes and quality indicator. * **/ /** - * @defgroup media_parameters Controlling media parameters - * Multicast - *
Call using rtp multicast addresses are supported for both audio and video with some limitations. Limitations are, no stun, no ice, no encryption. - *
  • Incoming call with multicast address are automatically accepted. The called party switches in a media receive only mode.
  • - *
  • Outgoing call willing to send media to a multicast address can activate multicast using \link linphone_core_enable_video_multicast\endlink or - *\link linphone_core_enable_audio_multicast\endlink . The calling party switches in a media listen send only mode.
  • - *
+ * @defgroup media_parameters Media parameters + * @brief Controlling media parameters. + * + * Multicast + * + * Call using rtp multicast addresses are supported for both audio and video with some limitations. Limitations are, no stun, no ice, no encryption. + * - Incoming call with multicast address are automatically accepted. The called party switches in a media receive only mode. + * - Outgoing call willing to send media to a multicast address can activate multicast using linphone_core_enable_video_multicast() + * or linphone_core_enable_audio_multicast(). The calling party switches in a media listen send only mode. **/ /** - * @defgroup proxies Managing proxies - *User registration is controled by #LinphoneProxyConfig settings.
Each #LinphoneProxyConfig object can be configured with registration informations - *like \link linphone_proxy_config_set_server_addr() proxy address \endlink , \link linphone_proxy_config_set_identity() user id \endlink, \link linphone_proxy_config_expires() refresh period \endlink, and so on. - *
A created proxy config using linphone_proxy_config_new(), once configured, must be added to #LinphoneCore using function linphone_core_add_proxy_config(). - *
It is recommended to set a default \link #LinphoneProxyConfig proxy config \endlink using function linphone_core_set_default_proxy(). Once done, if \link #LinphoneProxyConfig a proxy config \endlink has been configured with attribute \link linphone_proxy_config_enable_register() enable register \endlink , next call to linphone_core_iterate() triggers a SIP register. - *
Registration status is reported by LinphoneCoreRegistrationStateChangedCb. - *
- *
This pseudo code demonstrates basic registration operations: - *
\code + * @defgroup proxies Proxies + * @brief Managing proxies. + * + * User registration is controled by #LinphoneProxyConfig settings.
Each #LinphoneProxyConfig object can be configured with registration informations + * like \link linphone_proxy_config_set_server_addr() proxy address \endlink , \link linphone_proxy_config_set_identity() user id \endlink, \link linphone_proxy_config_expires() + * refresh period \endlink, and so on. + *
A created proxy config using linphone_proxy_config_new(), once configured, must be added to #LinphoneCore using function linphone_core_add_proxy_config(). + *
It is recommended to set a default \link #LinphoneProxyConfig proxy config \endlink using function linphone_core_set_default_proxy(). Once done, if \link #LinphoneProxyConfig + * a proxy config \endlink has been configured with attribute \link linphone_proxy_config_enable_register() enable register \endlink , next call to linphone_core_iterate() triggers + * a SIP register. + *
Registration status is reported by LinphoneCoreRegistrationStateChangedCb. + *
+ *
This pseudo code demonstrates basic registration operations: + *
\code * * LinphoneProxyConfig* proxy_cfg; * /*create proxy config*/ @@ -119,90 +129,102 @@ **/ /** - * @defgroup network_parameters Controlling network parameters (ports, mtu...) + * @defgroup network_parameters Network parameters + * @brief Controlling network parameters (ports, mtu...). **/ /** - * @defgroup authentication Managing authentication: userid and passwords + * @defgroup authentication Authentication + * @brief Managing authentication: userid and passwords. **/ /** -* @defgroup buddy_list Managing Buddies and buddy list and presence -Buddies and buddy list -
Each buddy is represented by a #LinphoneFriend object created by function linphone_friend_new(). -Buddy configuration parameters like \link linphone_friend_set_addr() sip uri \endlink or \link linphone_friend_set_inc_subscribe_policy() status publication \endlink policy for this \link #LinphoneFriend friend \endlink are configurable for each buddy. -
Here under a typical buddy creation: -
-\code -LinphoneFriend* my_friend=linphone_friend_new_with_addr("sip:joe@sip.linphone.org"); /*creates friend object for buddy joe*/ -linphone_friend_enable_subscribes(my_friend,TRUE); /*configure this friend to emit SUBSCRIBE message after being added to LinphoneCore*/ -linphone_friend_set_inc_subscribe_policy(my_friend,LinphoneSPAccept); /* accept Incoming subscription request for this friend*/ -\endcode -\link #LinphoneFriend friends \endlink status changes are reported by callback LinphoneCoreVTable.notify_presence_recv -\code -static void notify_presence_recv_updated (struct _LinphoneCore *lc, LinphoneFriend *friend) { - const LinphoneAddress* friend_address = linphone_friend_get_address(friend); - printf("New state state [%s] for user id [%s] \n" - ,linphone_online_status_to_string(linphone_friend_get_status(friend)) - ,linphone_address_as_string (friend_address)); -} -\endcode -
Once created a buddy can be added to the buddy list using function linphone_core_add_friend() . Added friends will be notified about \link linphone_core_set_presence_info() local status changes \endlink -
-Any subsequente modifications to #LinphoneFriend must be first started by a call to function linphone_friend_edit() and validated by function linphone_friend_done() -\code -linphone_friend_edit(my_friend); /* start editing friend */ -linphone_friend_enable_subscribes(my_friend,FALSE); /*disable subscription for this friend*/ -linphone_friend_done(my_friend); /*commit changes triggering an UNSUBSCRIBE message*/ -\endcode - - - Publishing presence status -
Local presence status can be changed using function linphone_core_set_presence_model() .New status is propagated to all friends \link linphone_core_add_friend() previously added \endlink to #LinphoneCore. - -Handling incoming subscription request -
New incoming subscription requests are process according to \link linphone_friend_set_inc_subscribe_policy() the incoming subscription policy state \endlink for subscription initiated by \link linphone_core_add_friend() members of the buddy list. \endlink -
For incoming request comming from an unknown buddy, the call back LinphoneCoreVTable.new_subscription_request is invoked. - -
A complete tutorial can be found at : \ref buddy_tutorials "Registration tutorial" - - + * @defgroup buddy_list Buddy list + * @brief Managing Buddies and buddy list and presence. + * + * Buddies and buddy list + *
Each buddy is represented by a #LinphoneFriend object created by function linphone_friend_new(). + * Buddy configuration parameters like \link linphone_friend_set_addr() sip uri \endlink or \link linphone_friend_set_inc_subscribe_policy() status publication \endlink policy for + * this * \link #LinphoneFriend friend \endlink are configurable for each buddy. + *
Here under a typical buddy creation: + *
+ * \code + * LinphoneFriend* my_friend=linphone_friend_new_with_addr("sip:joe@sip.linphone.org"); /*creates friend object for buddy joe*/ + * linphone_friend_enable_subscribes(my_friend,TRUE); /*configure this friend to emit SUBSCRIBE message after being added to LinphoneCore*/ + * linphone_friend_set_inc_subscribe_policy(my_friend,LinphoneSPAccept); /* accept Incoming subscription request for this friend*/ + * \endcode + * \link #LinphoneFriend friends \endlink status changes are reported by callback LinphoneCoreVTable.notify_presence_recv + * \code + * static void notify_presence_recv_updated (struct _LinphoneCore *lc, LinphoneFriend *friend) { + * const LinphoneAddress* friend_address = linphone_friend_get_address(friend); + * printf("New state state [%s] for user id [%s] \n" + * ,linphone_online_status_to_string(linphone_friend_get_status(friend)) + * ,linphone_address_as_string (friend_address)); + * } + * \endcode + *
Once created a buddy can be added to the buddy list using function linphone_core_add_friend() . Added friends will be notified about \link linphone_core_set_presence_info() local status changes \endlink + *
+ * Any subsequente modifications to #LinphoneFriend must be first started by a call to function linphone_friend_edit() and validated by function linphone_friend_done() + * \code + * linphone_friend_edit(my_friend); /* start editing friend */ + * linphone_friend_enable_subscribes(my_friend,FALSE); /*disable subscription for this friend*/ + * linphone_friend_done(my_friend); /*commit changes triggering an UNSUBSCRIBE message*/ + * \endcode + * + * + * Publishing presence status + *
Local presence status can be changed using function linphone_core_set_presence_model() .New status is propagated to all friends \link linphone_core_add_friend() previously added \endlink to #LinphoneCore. + * + * Handling incoming subscription request + *
New incoming subscription requests are process according to \link linphone_friend_set_inc_subscribe_policy() the incoming subscription policy state \endlink for subscription initiated by \link linphone_core_add_friend() members of the buddy list. \endlink + *
For incoming request comming from an unknown buddy, the call back LinphoneCoreVTable.new_subscription_request is invoked. + * + *
A complete tutorial can be found at : \ref buddy_tutorials "Registration tutorial" + * + * **/ /** -* @defgroup chatroom Chat room and Messaging - Exchanging text messages -
Messages are sent using #LinphoneChatRoom object. First step is to create a \link linphone_core_get_chat_room() chat room \endlink -from a peer sip uri. -\code -LinphoneChatRoom* chat_room = linphone_core_get_chat_room(lc,"sip:joe@sip.linphone.org"); -\endcode - -
Once created, messages are sent using function linphone_chat_room_send_message(). -\code -linphone_chat_room_send_message(chat_room,"Hello world"); /*sending message*/ -\endcode -
Incoming message are received from call back LinphoneCoreVTable.text_received -\code -void text_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message) { - printf(" Message [%s] received from [%s] \n",message,linphone_address_as_string (from)); -} -\endcode -
A complete tutorial can be found at : \ref chatroom_tuto "Chat room tutorial" + * @defgroup chatroom Chatroom + * @brief Chat room and Messaging. + * + * Exchanging text messages + *
Messages are sent using #LinphoneChatRoom object. First step is to create a \link linphone_core_get_chat_room() chat room \endlink + * from a peer sip uri. + * \code + * LinphoneChatRoom* chat_room = linphone_core_get_chat_room(lc,"sip:joe@sip.linphone.org"); + * \endcode + * + *
Once created, messages are sent using function linphone_chat_room_send_message(). + * \code + * linphone_chat_room_send_message(chat_room,"Hello world"); /*sending message*/ + * \endcode + *
Incoming message are received from call back LinphoneCoreVTable.text_received + * \code + * void text_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddress *from, const char *message) { + * printf(" Message [%s] received from [%s] \n",message,linphone_address_as_string (from)); + * } + * \endcode + *
A complete tutorial can be found at : \ref chatroom_tuto "Chat room tutorial" **/ /** - * @defgroup call_logs Managing call logs + * @defgroup call_logs Call logs + * @brief Managing call logs. **/ /** - * @defgroup linphone_address SIP address parser API. + * @defgroup linphone_address Linphone address + * @brief SIP address parser API. + * This api is useful for manipulating SIP addresses ('from' or 'to' headers). **/ /** - * @defgroup conferencing Making an audio conference. + * @defgroup conferencing Conferencing + * @brief Making an audio conference. + * * This API allows to create a conference entirely managed by the client. No server capabilities are required. * The way such conference is created is by doing the following:
* The application shall makes "normal" calls to several destinations (using linphone_core_invite() ), one after another. @@ -224,12 +246,15 @@ void text_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddre /** - * @defgroup event_api Managing generic subscriptions and publishes + * @defgroup event_api Event api + * @brief Managing generic subscriptions and publishes. + * * The LinphoneEvent api allows application to control subscriptions, receive notifications and make publish to peers, in a generic manner. */ /** - * @defgroup misc Miscenalleous: logs, version strings, config storage + * @defgroup misc Misc + * @brief Miscenalleous: logs, version strings, config storage. **/ /** @@ -244,6 +269,7 @@ void text_received(LinphoneCore *lc, LinphoneChatRoom *room, const LinphoneAddre /** * @defgroup IOS IOS * @ingroup port + * *
Multitasking
Liblinphone for IOS natively supports multitasking assuming application follows multitasking guides provided by Apple. First step is to declare application as multitasked. It means adding background mode for both audio and voip to Info.plist file. @@ -464,7 +490,9 @@ I/lib/Could not find decoder for SILK */ /** - * @defgroup wrapper Wrapper utilities + * @defgroup wrapper + * @brief Wrapper utilities. + * * These functions are used by automatic API wrapper generators and should not * be used by C API users. */ From 9add72c20e02da146c4c87882d3834c345ab6695 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fran=C3=A7ois=20Grisez?= Date: Fri, 21 Apr 2017 14:28:34 +0200 Subject: [PATCH 70/70] =?UTF-8?q?C++=20wrapper:=C2=A0add=20doxygen=20docst?= =?UTF-8?q?rings=20in=20the=20API?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- coreapi/help/Doxyfile.in | 2 +- tools/genapixml.py | 7 +++ tools/metadoc.py | 84 ++++++++++++++++++++++++++++++ wrappers/cpp/CMakeLists.txt | 1 + wrappers/cpp/abstractapi.py | 4 ++ wrappers/cpp/class_header.mustache | 14 +++++ wrappers/cpp/genwrapper.py | 4 ++ 7 files changed, 115 insertions(+), 1 deletion(-) create mode 100644 tools/metadoc.py diff --git a/coreapi/help/Doxyfile.in b/coreapi/help/Doxyfile.in index 169f6cf2a..40d2bf95a 100644 --- a/coreapi/help/Doxyfile.in +++ b/coreapi/help/Doxyfile.in @@ -177,7 +177,7 @@ SHORT_NAMES = NO # description.) # The default value is: NO. -JAVADOC_AUTOBRIEF = NO +JAVADOC_AUTOBRIEF = YES # If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first # line (until the first dot) of a Qt-style comment as the brief description. If diff --git a/tools/genapixml.py b/tools/genapixml.py index 8549e8e25..f2c1fd555 100755 --- a/tools/genapixml.py +++ b/tools/genapixml.py @@ -23,6 +23,7 @@ import string import sys import xml.etree.ElementTree as ET import xml.dom.minidom as minidom +import metadoc class CObject: @@ -31,6 +32,7 @@ class CObject: self.briefDescription = '' self.detailedDescription = None self.deprecated = False + self.briefDoc = None class CEnumValue(CObject): @@ -381,6 +383,7 @@ class Project: if deprecatedNode is not None: ev.deprecated = True ev.briefDescription = ''.join(node.find('./briefdescription').itertext()).strip() + ev.briefDoc = metadoc.Description(node.find('./briefdescription')) ev.detailedDescription = self.__cleanDescription(node.find('./detaileddescription')) return ev @@ -392,6 +395,7 @@ class Project: if deprecatedNode is not None: e.deprecated = True e.briefDescription = ''.join(node.find('./briefdescription').itertext()).strip() + e.briefDoc = metadoc.Description(node.find('./briefdescription')) e.detailedDescription = self.__cleanDescription(node.find('./detaileddescription')) enumvalues = node.findall("enumvalue[@prot='public']") for enumvalue in enumvalues: @@ -414,6 +418,7 @@ class Project: if deprecatedNode is not None: sm.deprecated = True sm.briefDescription = ''.join(node.find('./briefdescription').itertext()).strip() + sm.briefDoc = metadoc.Description(node.find('./briefdescription')) sm.detailedDescription = self.__cleanDescription(node.find('./detaileddescription')) return sm @@ -423,6 +428,7 @@ class Project: if deprecatedNode is not None: s.deprecated = True s.briefDescription = ''.join(node.find('./briefdescription').itertext()).strip() + s.briefDoc = metadoc.Description(node.find('./briefdescription')) s.detailedDescription = self.__cleanDescription(node.find('./detaileddescription')) structmembers = node.findall("sectiondef/memberdef[@kind='variable'][@prot='public']") for structmember in structmembers: @@ -561,6 +567,7 @@ class Project: if deprecatedNode is not None: f.deprecated = True f.briefDescription = ''.join(node.find('./briefdescription').itertext()).strip() + f.briefDoc = metadoc.Description(node.find('./briefdescription')) f.detailedDescription = self.__cleanDescription(node.find('./detaileddescription')) if f.briefDescription == '' and ''.join(f.detailedDescription.itertext()).strip() == '': return None diff --git a/tools/metadoc.py b/tools/metadoc.py new file mode 100644 index 000000000..eb4b6e9d2 --- /dev/null +++ b/tools/metadoc.py @@ -0,0 +1,84 @@ +#!/usr/bin/python + +# Copyright (C) 2017 Belledonne Communications SARL +# +# This program is free software; you can redistribute it and/or +# modify it under the terms of the GNU General Public License +# as published by the Free Software Foundation; either version 2 +# of the License, or (at your option) any later version. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + + +class Nil: + pass + + +class Reference: + def __init__(self, name): + self.cObjectName = name + + +class Paragraph: + def __init__(self, node=None): + self.parts = [] + if node is not None: + self.parse_doxygen_node(node) + + def parse_doxygen_node(self, node): + for partNode in node.iter(): + text = partNode.text + if text is not None: + self.parts.append(text) + if partNode is not node: + tail = partNode.tail + if tail is not None: + self.parts.append(tail) + + +class Description: + def __init__(self, node=None): + self.paragraphs = [] + if node is not None: + self.parse_doxygen_node(node) + + def parse_doxygen_node(self, node): + for paraNode in node.findall('./para'): + self.paragraphs.append(Paragraph(paraNode)) + + +class Translator: + def translate(self, description): + lines = [] + for para in description.paragraphs: + if para is not description.paragraphs[0]: + lines.append('') + lines.append(''.join(para.parts)) + + self._tag_as_brief(lines) + + translatedDoc = {'lines': []} + for line in lines: + translatedDoc['lines'].append({'line': line}) + + return translatedDoc + + +class DoxygenCppTranslator(Translator): + def _tag_as_brief(self, lines): + if len(lines) > 0: + lines[0] = '@brief ' + lines[0] + + +class SandcastleCSharpTranslator(Translator): + def _tag_as_brief(self, lines): + if len(lines) > 0: + lines[0] = '' + lines[0] + lines[-1] = lines[-1] + '' diff --git a/wrappers/cpp/CMakeLists.txt b/wrappers/cpp/CMakeLists.txt index 2ff57dd1f..d397d96c0 100644 --- a/wrappers/cpp/CMakeLists.txt +++ b/wrappers/cpp/CMakeLists.txt @@ -23,6 +23,7 @@ add_custom_command(OUTPUT include/linphone++/linphone.hh src/linphone++.cc COMMAND ${PYTHON_EXECUTABLE} "${CMAKE_CURRENT_SOURCE_DIR}/genwrapper.py" "${PROJECT_BINARY_DIR}/coreapi/help/doc/xml" DEPENDS ${PROJECT_SOURCE_DIR}/tools/genapixml.py + "${PROJECT_SOURCE_DIR}/tools/metadoc.py" abstractapi.py genwrapper.py class_header.mustache diff --git a/wrappers/cpp/abstractapi.py b/wrappers/cpp/abstractapi.py index 8f2bf6b44..868320285 100644 --- a/wrappers/cpp/abstractapi.py +++ b/wrappers/cpp/abstractapi.py @@ -586,6 +586,7 @@ class CParser(object): name = EnumName() name.from_camel_case(nameStr, namespace=self.namespace.name) enum = Enum(name) + enum.briefDescription = cenum.briefDoc self.namespace.add_child(enum) for cEnumValue in cenum.values: @@ -619,6 +620,7 @@ class CParser(object): name = ClassName() name.from_camel_case(cclass.name, namespace=self.namespace.name) _class = Class(name) + _class.briefDescription = cclass.briefDoc _class.refcountable = self._class_is_refcountable(cclass) for cproperty in cclass.properties.values(): @@ -686,6 +688,7 @@ class CParser(object): raise Error('{0} is not a listener'.format(cclass.name)) listener = Interface(name) + listener.briefDescription = cclass.briefDoc for property in cclass.properties.values(): if property.name != 'user_data': @@ -733,6 +736,7 @@ class CParser(object): raise BlacklistedException('{0} is blacklisted'.format(name.to_c())); method = Method(name, type=type) + method.briefDescription = cfunction.briefDoc method.deprecated = cfunction.deprecated method.returnType = self.parse_type(cfunction.returnArgument) diff --git a/wrappers/cpp/class_header.mustache b/wrappers/cpp/class_header.mustache index b228eb93f..e6c447914 100644 --- a/wrappers/cpp/class_header.mustache +++ b/wrappers/cpp/class_header.mustache @@ -84,10 +84,24 @@ namespace linphone { {{#methods}} + {{#doc}} + /** + {{#lines}} + * {{{line}}} + {{/lines}} + */ + {{/doc}} {{{prototype}}} {{/methods}} {{#staticMethods}} + {{#doc}} + /** + {{#lines}} + * {{{line}}} + {{/lines}} + */ + {{/doc}} {{{prototype}}} {{/staticMethods}} diff --git a/wrappers/cpp/genwrapper.py b/wrappers/cpp/genwrapper.py index f15046540..34ffd641d 100755 --- a/wrappers/cpp/genwrapper.py +++ b/wrappers/cpp/genwrapper.py @@ -26,6 +26,7 @@ import errno sys.path.insert(0, os.path.join(os.path.dirname(__file__), '..', '..', 'tools')) import genapixml as CApi import abstractapi as AbsApi +import metadoc class CppTranslator(object): @@ -240,6 +241,9 @@ class CppTranslator(object): methodDict['implPrototype'] = '{implReturn} {longname}({implParams}){const}'.format(**methodElems) methodDict['sourceCode' ] = self._generate_source_code(method, usedNamespace=namespace) + t = metadoc.DoxygenCppTranslator() + methodDict['doc'] = t.translate(method.briefDescription) if method.briefDescription is not None else None + return methodDict def _generate_source_code(self, method, usedNamespace=None):