Commit 3a9141c6 authored by Sylvain Berfini's avatar Sylvain Berfini 🎩

Merge branch 'release/4.3'

parents 839b3a54 0bcc8921
############################################################################
# CMakeLists.txt
# Copyright (C) 2014 Belledonne Communications, Grenoble France
# Copyright (C) 2010-2019 Belledonne Communications, Grenoble France
#
############################################################################
#
......@@ -20,7 +20,7 @@
#
############################################################################
cmake_minimum_required(VERSION 3.1)
cmake_minimum_required(VERSION 3.11) # we need CMake 3.11 for defining 'package_source' target as custom target
project(linphone VERSION 4.3.0 LANGUAGES C CXX)
......
......@@ -9,11 +9,13 @@ or instant messaging capabilities to an application.
# License
Copyright © Belledonne Communications, all rights reserved.
Copyright © Belledonne Communications
Liblinphone is dual licensed:
- under a GNU GPLv3 license for free (see LICENSE.txt file for details)
- under a proprietary license, for closed source projects. Contact sales@belledonne-communications.com for costs and other service information.
Liblinphone is dual licensed, and is available either :
- under a [GNU/GPLv3 license](https://www.gnu.org/licenses/gpl-3.0.en.html), for free (open source). Please make sure that you understand and agree with the terms of this license before using it (see LICENSE.txt file for details).
- under a proprietary license, for a fee, to be used in closed source applications. Contact [Belledonne Communications](https://www.linphone.org/contact) for any question about costs and services.
# Documentation
......
############################################################################
# CMakeLists.txt
# Copyright (C) 2017-2018 Belledonne Communications, Grenoble France
# Copyright (C) 2010-2019 Belledonne Communications, Grenoble France
#
############################################################################
#
......@@ -22,33 +22,13 @@
if(NOT CPACK_PACKAGE_NAME)
set(CPACK_PACKAGE_NAME "liblinphone")
ENDIF()
set(CPACK_RESOURCE_FILE_LICENSE "${CMAKE_CURRENT_SOURCE_DIR}/../LICENSE.txt")
set(CPACK_PACKAGE_VERSION_MAJOR ${PROJECT_VERSION_MAJOR})
set(CPACK_PACKAGE_VERSION_MINOR ${PROJECT_VERSION_MINOR})
set(CPACK_PACKAGE_VERSION_PATCH ${PROJECT_VERSION_PATCH})
set(CPACK_PACKAGE_FILE_NAME ${CPACK_PACKAGE_NAME}-${PROJECT_VERSION})
endif()
set(CPACK_SOURCE_GENERATOR "TGZ")
set(CPACK_SOURCE_IGNORE_FILES
"${CMAKE_BINARY_DIR}"
"^${PROJECT_SOURCE_DIR}/.git*"
)
bc_project_build_version(${PROJECT_VERSION} PROJECT_VERSION_BUILD)
if(PROJECT_VERSION_BUILD)
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-${PROJECT_VERSION_BUILD}")
endif()
message("-- Package file name is ${CPACK_PACKAGE_FILE_NAME}" )
set(CPACK_SOURCE_PACKAGE_FILE_NAME ${CPACK_PACKAGE_FILE_NAME})
bc_generate_rpm_specfile("rpm/liblinphone.spec.cmake" "${PROJECT_SOURCE_DIR}/liblinphone.spec")
include(CPack)
set(BC_SPECFILE_NAME "liblinphone.spec")
bc_make_package_source_target()
......@@ -2,6 +2,7 @@
%define _prefix @CMAKE_INSTALL_PREFIX@
%define pkg_prefix @BC_PACKAGE_NAME_PREFIX@
%define package_name @CPACK_PACKAGE_NAME@-${FULL_VERSION}
# re-define some directories for older RPMBuild versions which don't. This messes up the doc/ dir
# taken from https://fedoraproject.org/wiki/Packaging:RPMMacros?rd=Packaging/RPMMacros
......@@ -9,21 +10,16 @@
%define _datadir %{_datarootdir}
%define _docdir %{_datadir}/doc
%define build_number @PROJECT_VERSION_BUILD@
%if %{build_number}
%define build_number_ext -%{build_number}
%endif
Name: @CPACK_PACKAGE_NAME@
Version: @PROJECT_VERSION@
Release: %{build_number}%{?dist}
Version: ${RPM_VERSION}
Release: ${RPM_RELEASE}%{?dist}
Summary: Phone anywhere in the whole world by using the Internet
Group: Applications/Communications
License: GPL
URL: http://www.linphone.org
Source0: %{name}-%{version}%{?build_number_ext}.tar.gz
Source0: %{package_name}.tar.gz
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
Requires: %{pkg_prefix}bctoolbox
......@@ -61,7 +57,7 @@ develop programs using the liblinphone library.
%custom_debug_package
%prep
%setup -n %{name}-%{version}%{?build_number_ext}
%setup -n %{package_name}
%build
%{expand:%%%cmake_name} . -DCMAKE_BUILD_TYPE=@CMAKE_BUILD_TYPE@ -DCMAKE_PREFIX_PATH:PATH=%{_prefix} @RPM_ALL_CMAKE_OPTIONS@
......@@ -93,7 +89,7 @@ rm -rf $RPM_BUILD_ROOT
%files
%defattr(-,root,root)
%doc ChangeLog.md COPYING README.md
%doc ChangeLog.md LICENSE.txt README.md
%if @ENABLE_DAEMON@ || @ENABLE_CONSOLE_UI@ || @ENABLE_TOOLS@
%{_bindir}/*
%endif
......
This diff is collapsed.
......@@ -47,6 +47,7 @@ struct _LinphoneAccountCreatorService {
LinphoneAccountCreatorRequestFunc recover_account_request_cb; /**< Request to recover account */
LinphoneAccountCreatorRequestFunc update_account_request_cb; /**< Request to update account */
LinphoneAccountCreatorRequestFunc login_linphone_account_request_cb; /**< Request to get password & algorithm from confirmation key */
};
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneAccountCreatorService);
......@@ -70,6 +71,8 @@ struct _LinphoneAccountCreatorCbs {
LinphoneAccountCreatorCbsStatusCb recover_account_response_cb; /**< Response of recover_account request */
LinphoneAccountCreatorCbsStatusCb update_account_response_cb; /**< Response of update_account request */
LinphoneAccountCreatorCbsStatusCb login_linphone_account_response_cb; /** < Response of login_linphone_account request */
};
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneAccountCreatorCbs);
......@@ -203,6 +206,13 @@ LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_is_account
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_update_password_linphone(LinphoneAccountCreator *creator);
/**
* Send an XML-RPC request to get the password & algorithm of an account using the confirmation key
* @param[in] creator LinphoneAccountCreator object
* @return LinphoneAccountCreatorStatusRequestOk if everything is OK, or a specific error otherwise.
**/
LINPHONE_PUBLIC LinphoneAccountCreatorStatus linphone_account_creator_login_linphone_account_linphone(LinphoneAccountCreator *creator);
#ifdef __cplusplus
}
#endif
......
......@@ -152,6 +152,14 @@ void linphone_account_creator_service_set_update_account_cb(LinphoneAccountCreat
service->update_account_request_cb = cb;
}
LinphoneAccountCreatorRequestFunc linphone_account_creator_service_get_login_linphone_account_cb(const LinphoneAccountCreatorService *service) {
return service->login_linphone_account_request_cb;
}
void linphone_account_creator_service_set_login_linphone_account_cb(LinphoneAccountCreatorService *service, LinphoneAccountCreatorRequestFunc cb) {
service->login_linphone_account_request_cb = cb;
}
/************************** End Account Creator service **************************/
void linphone_core_set_account_creator_service(LinphoneCore *lc, LinphoneAccountCreatorService *service) {
......
......@@ -78,7 +78,25 @@ static bool_t realm_match(const char *realm1, const char *realm2){
return FALSE;
}
static const LinphoneAuthInfo *find_auth_info(LinphoneCore *lc, const char *username, const char *realm, const char *domain, bool_t ignore_realm){
/* Check if the LinphoneAuthInfo candidate is compatible with the requested algorithm. */
static bool_t check_algorithm_compatibility(const LinphoneAuthInfo *ai, const char *algorithm){
const char *ai_algorithm = linphone_auth_info_get_algorithm(ai);
if (algorithm == NULL) return TRUE;
if (linphone_auth_info_get_password(ai) != NULL){
/* We have the clear text password, so if the user didn't requested a specific algorithm, we can satisfy all algorithms.*/
if (ai_algorithm == NULL) return TRUE;
}else{
/* If we don't have the clear text password but the ha1, and if algorithm is empty in LinphoneAuthInfo
* for backward compatibility, we assume it is MD5. */
if (ai_algorithm == NULL && strcasecmp(algorithm, "MD5") == 0) return TRUE;
}
/* In all other cases, algorithm must match. */
if (ai_algorithm && strcasecmp(algorithm, ai_algorithm) == 0) return TRUE; /* algorithm do match */
return FALSE;
}
static const LinphoneAuthInfo *find_auth_info(LinphoneCore *lc, const char *username, const char *realm, const char *domain, const char *algorithm, bool_t ignore_realm){
bctbx_list_t *elem;
const LinphoneAuthInfo *ret=NULL;
......@@ -87,6 +105,10 @@ static const LinphoneAuthInfo *find_auth_info(LinphoneCore *lc, const char *user
if (username && linphone_auth_info_get_username(pinfo) && strcmp(username, linphone_auth_info_get_username(pinfo))==0)
{
if (!check_algorithm_compatibility(pinfo, algorithm)) {
continue;
}
if (realm && domain){
if (linphone_auth_info_get_realm(pinfo) && realm_match(realm, linphone_auth_info_get_realm(pinfo))
&& linphone_auth_info_get_domain(pinfo) && strcmp(domain, linphone_auth_info_get_domain(pinfo))==0) {
......@@ -123,19 +145,19 @@ const LinphoneAuthInfo *_linphone_core_find_tls_auth_info(LinphoneCore *lc) {
return NULL;
}
const LinphoneAuthInfo *_linphone_core_find_auth_info(LinphoneCore *lc, const char *realm, const char *username, const char *domain, bool_t ignore_realm){
const LinphoneAuthInfo *_linphone_core_find_auth_info(LinphoneCore *lc, const char *realm, const char *username, const char *domain, const char *algorithm, bool_t ignore_realm){
const LinphoneAuthInfo *ai=NULL;
if (realm){
ai=find_auth_info(lc,username,realm,NULL, FALSE);
ai=find_auth_info(lc,username,realm,NULL, algorithm, FALSE);
if (ai==NULL && domain){
ai=find_auth_info(lc,username,realm,domain, FALSE);
ai=find_auth_info(lc,username,realm,domain, algorithm, FALSE);
}
}
if (ai == NULL && domain != NULL) {
ai=find_auth_info(lc,username,NULL,domain, ignore_realm);
ai=find_auth_info(lc,username,NULL,domain, algorithm, ignore_realm);
}
if (ai==NULL){
ai=find_auth_info(lc,username,NULL,NULL, ignore_realm);
ai=find_auth_info(lc,username,NULL,NULL, algorithm, ignore_realm);
}
if (ai) ms_message("linphone_core_find_auth_info(): returning auth info username=%s, realm=%s", linphone_auth_info_get_username(ai) ? linphone_auth_info_get_username(ai) : "", linphone_auth_info_get_realm(ai) ? linphone_auth_info_get_realm(ai) : "");
......@@ -143,7 +165,7 @@ const LinphoneAuthInfo *_linphone_core_find_auth_info(LinphoneCore *lc, const ch
}
const LinphoneAuthInfo *linphone_core_find_auth_info(LinphoneCore *lc, const char *realm, const char *username, const char *domain){
return _linphone_core_find_auth_info(lc, realm, username, domain, TRUE);
return _linphone_core_find_auth_info(lc, realm, username, domain, NULL, TRUE);
}
/*the auth info is expected to be in the core's list*/
......@@ -200,7 +222,7 @@ void linphone_core_add_auth_info(LinphoneCore *lc, const LinphoneAuthInfo *info)
for (const auto &op : pendingAuths) {
LinphoneAuthInfo *ai;
const SalAuthInfo *req_sai=op->getAuthRequested();
ai=(LinphoneAuthInfo*)_linphone_core_find_auth_info(lc, req_sai->realm, req_sai->username, req_sai->domain, FALSE);
ai=(LinphoneAuthInfo*)_linphone_core_find_auth_info(lc, req_sai->realm, req_sai->username, req_sai->domain, req_sai->algorithm, FALSE);
if (ai){
SalAuthInfo sai;
bctbx_list_t* proxy;
......@@ -270,3 +292,16 @@ void linphone_core_clear_all_auth_info(LinphoneCore *lc){
bctbx_list_free(lc->auth_info);
lc->auth_info=NULL;
}
void linphone_auth_info_fill_belle_sip_event(const LinphoneAuthInfo *auth_info, belle_sip_auth_event *event) {
if (auth_info) {
const char *auth_username = linphone_auth_info_get_username(auth_info);
const char *auth_password = linphone_auth_info_get_password(auth_info);
const char *auth_ha1 = linphone_auth_info_get_ha1(auth_info);
const char *auth_algo = linphone_auth_info_get_algorithm(auth_info);
belle_sip_auth_event_set_username(event, auth_username);
belle_sip_auth_event_set_passwd(event, auth_password);
belle_sip_auth_event_set_ha1(event, auth_ha1);
belle_sip_auth_event_set_algorithm(event, auth_algo);
}
}
......@@ -402,7 +402,7 @@ belle_sdp_session_description_t * media_description_to_sdp ( const SalMediaDescr
} else inet6=0;
belle_sdp_session_description_set_version ( session_desc,belle_sdp_version_create ( 0 ) );
origin = belle_sdp_origin_create ( desc->username
origin = belle_sdp_origin_create ( belle_sip_uri_to_escaped_username(desc->username)
,desc->session_id
,desc->session_ver
,"IN"
......
......@@ -363,16 +363,20 @@ static void auth_failure(SalOp *op, SalAuthInfo* info) {
LinphoneAuthInfo *ai = NULL;
if (info != NULL) {
ai = (LinphoneAuthInfo*)_linphone_core_find_auth_info(lc, info->realm, info->username, info->domain, TRUE);
ai = (LinphoneAuthInfo*)_linphone_core_find_auth_info(lc, info->realm, info->username, info->domain, info->algorithm, TRUE);
if (ai){
LinphoneAuthMethod method = info->mode == SalAuthModeHttpDigest ? LinphoneAuthHttpDigest : LinphoneAuthTls;
LinphoneAuthInfo *auth_info = linphone_core_create_auth_info(lc, info->username, NULL, NULL, NULL, info->realm, info->domain);
ms_message("%s/%s/%s/%s authentication fails.", info->realm, info->username, info->domain, info->mode == SalAuthModeHttpDigest ? "HttpDigest" : "Tls");
/*ask again for password if auth info was already supplied but apparently not working*/
linphone_core_notify_authentication_requested(lc, auth_info, method);
if (method == LinphoneAuthHttpDigest){
/*ask again for password if auth info was already supplied but apparently not working*/
L_GET_PRIVATE_FROM_C_OBJECT(lc)->getAuthStack().pushAuthRequested(AuthInfo::toCpp(ai)->getSharedFromThis());
}else{
linphone_core_notify_authentication_requested(lc, auth_info, method);
// Deprecated
linphone_core_notify_auth_info_requested(lc, info->realm, info->username, info->domain);
}
linphone_auth_info_unref(auth_info);
// Deprecated
linphone_core_notify_auth_info_requested(lc, info->realm, info->username, info->domain);
}
}
}
......@@ -402,8 +406,11 @@ static void register_failure(SalOp *op){
if ((ei->reason == SalReasonServiceUnavailable || ei->reason == SalReasonIOError)
&& linphone_proxy_config_get_state(cfg) == LinphoneRegistrationOk) {
linphone_proxy_config_set_state(cfg,LinphoneRegistrationProgress,"Service unavailable, retrying");
} else if (ei->protocol_code == 401 || ei->protocol_code == 407){
/* Do nothing. There will be an auth_requested() callback. If the callback doesn't provide an AuthInfo, then
* the proxy config will transition to the failed state.*/
} else {
linphone_proxy_config_set_state(cfg,LinphoneRegistrationFailed,details);
linphone_proxy_config_set_state(cfg,LinphoneRegistrationFailed, details);
}
if (cfg->presence_publish_event){
/*prevent publish to be sent now until registration gets successful*/
......@@ -545,26 +552,21 @@ static bool_t fill_auth_info(LinphoneCore *lc, SalAuthInfo* sai) {
if (sai->mode == SalAuthModeTls) {
ai = (LinphoneAuthInfo*)_linphone_core_find_tls_auth_info(lc);
} else {
ai = (LinphoneAuthInfo*)_linphone_core_find_auth_info(lc,sai->realm,sai->username,sai->domain, FALSE);
ai = (LinphoneAuthInfo*)_linphone_core_find_auth_info(lc,sai->realm,sai->username,sai->domain, sai->algorithm, FALSE);
}
if (ai) {
if (sai->mode == SalAuthModeHttpDigest) {
/*
* Compare algorithm of server(sai) with algorithm of client(ai), if they are not correspondant,
* exit. The default algorithm is MD5 if it's NULL.
*/
if (sai->algorithm && linphone_auth_info_get_algorithm(ai)) {
if (strcasecmp(linphone_auth_info_get_algorithm(ai), sai->algorithm))
return TRUE;
} else if (
(linphone_auth_info_get_algorithm(ai) && strcasecmp(linphone_auth_info_get_algorithm(ai), "MD5")) ||
(sai->algorithm && strcasecmp(sai->algorithm, "MD5"))
)
return TRUE;
sai->userid = ms_strdup(linphone_auth_info_get_userid(ai) ? linphone_auth_info_get_userid(ai) : linphone_auth_info_get_username(ai));
sai->password = linphone_auth_info_get_passwd(ai)?ms_strdup(linphone_auth_info_get_passwd(ai)) : NULL;
sai->ha1 = linphone_auth_info_get_ha1(ai) ? ms_strdup(linphone_auth_info_get_ha1(ai)) : NULL;
AuthStack & as = L_GET_PRIVATE_FROM_C_OBJECT(lc)->getAuthStack();
/* We have to construct the auth info as it was originally requested in auth_requested() below,
* so that the matching is made correctly.
*/
as.authFound(AuthInfo::create(sai->username, "", "", "", sai->realm, sai->domain));
} else if (sai->mode == SalAuthModeTls) {
if (linphone_auth_info_get_tls_cert(ai) && linphone_auth_info_get_tls_key(ai)) {
sal_certificates_chain_parse(sai, linphone_auth_info_get_tls_cert(ai), SAL_CERTIFICATE_RAW_FORMAT_PEM);
......@@ -577,9 +579,10 @@ static bool_t fill_auth_info(LinphoneCore *lc, SalAuthInfo* sai) {
}
}
if (sai->realm && !linphone_auth_info_get_realm(ai)){
if (sai->realm && (!linphone_auth_info_get_realm(ai) || !linphone_auth_info_get_algorithm(ai))) {
/*if realm was not known, then set it so that ha1 may eventually be calculated and clear text password dropped*/
linphone_auth_info_set_realm(ai, sai->realm);
linphone_auth_info_set_algorithm(ai, sai->algorithm);
linphone_core_write_auth_info(lc, ai);
}
return TRUE;
......@@ -597,10 +600,17 @@ static bool_t auth_requested(Sal* sal, SalAuthInfo* sai) {
} else {
LinphoneAuthMethod method = sai->mode == SalAuthModeHttpDigest ? LinphoneAuthHttpDigest : LinphoneAuthTls;
LinphoneAuthInfo *ai = linphone_core_create_auth_info(lc, sai->username, NULL, NULL, NULL, sai->realm, sai->domain);
linphone_core_notify_authentication_requested(lc, ai, method);
if (method == LinphoneAuthHttpDigest){
/* Request app for new authentication information, but later. */
L_GET_PRIVATE_FROM_C_OBJECT(lc)->getAuthStack().pushAuthRequested(AuthInfo::toCpp(ai)->getSharedFromThis());
}else{
linphone_core_notify_authentication_requested(lc, ai, method);
// Deprecated callback
linphone_core_notify_auth_info_requested(lc, sai->realm, sai->username, sai->domain);
}
linphone_auth_info_unref(ai);
// Deprecated
linphone_core_notify_auth_info_requested(lc, sai->realm, sai->username, sai->domain);
if (fill_auth_info(lc, sai)) {
return TRUE;
}
......@@ -671,6 +681,7 @@ static void info_received(SalOp *op, SalBodyHandler *body_handler) {
static void subscribe_response(SalOp *op, SalSubscribeStatus status, int will_retry){
LinphoneEvent *lev=(LinphoneEvent*)op->getUserPointer();
LinphoneCore *lc=(LinphoneCore *)op->getSal()->getUserPointer();
if (lev==NULL) return;
......@@ -679,7 +690,7 @@ static void subscribe_response(SalOp *op, SalSubscribeStatus status, int will_re
}else if (status==SalSubscribePending){
linphone_event_set_state(lev,LinphoneSubscriptionPending);
}else{
if (will_retry){
if (will_retry && linphone_core_get_global_state(lc) != LinphoneGlobalShutdown ){
linphone_event_set_state(lev,LinphoneSubscriptionOutgoingProgress);
}
else linphone_event_set_state(lev,LinphoneSubscriptionError);
......
......@@ -475,9 +475,7 @@ static void process_auth_requested_from_carddav_request(void *data, belle_sip_au
const char *domain = belle_generic_uri_get_host(uri);
if (cdc->auth_info) {
belle_sip_auth_event_set_username(event, linphone_auth_info_get_username(cdc->auth_info));
belle_sip_auth_event_set_passwd(event, linphone_auth_info_get_passwd(cdc->auth_info));
belle_sip_auth_event_set_ha1(event, linphone_auth_info_get_ha1(cdc->auth_info));
linphone_auth_info_fill_belle_sip_event(cdc->auth_info, event);
} else {
LinphoneCore *lc = cdc->friend_list->lc;
const bctbx_list_t *auth_infos = linphone_core_get_auth_info_list(lc);
......@@ -487,9 +485,7 @@ static void process_auth_requested_from_carddav_request(void *data, belle_sip_au
LinphoneAuthInfo *auth_info = (LinphoneAuthInfo *)auth_infos->data;
if (linphone_auth_info_get_domain(auth_info) && strcmp(domain, linphone_auth_info_get_domain(auth_info)) == 0) {
if (!linphone_auth_info_get_realm(auth_info) || strcmp(realm, linphone_auth_info_get_realm(auth_info)) == 0) {
belle_sip_auth_event_set_username(event, linphone_auth_info_get_username(auth_info));
belle_sip_auth_event_set_passwd(event, linphone_auth_info_get_passwd(auth_info));
belle_sip_auth_event_set_ha1(event, linphone_auth_info_get_ha1(auth_info));
linphone_auth_info_fill_belle_sip_event(auth_info, event);
cdc->auth_info = linphone_auth_info_clone(auth_info);
break;
}
......
......@@ -205,6 +205,8 @@ void __linphone_friend_do_subscribe(LinphoneFriend *fr){
linphone_configure_op(lc,fr->outsub,addr,NULL,TRUE);
fr->outsub->subscribe(lp_config_get_int(lc->config,"sip","subscribe_expires",600));
fr->subscribe_active=TRUE;
} else {
ms_error("Can't send a SUBSCRIBE for friend [%p] without an address!", fr);
}
}
......@@ -214,6 +216,7 @@ LinphoneFriend * linphone_friend_new(void){
obj->subscribe = TRUE;
obj->vcard = NULL;
obj->storage_id = 0;
obj->rc_index = -1;
return obj;
}
......@@ -804,7 +807,7 @@ void linphone_friend_update_subscribes(LinphoneFriend *fr, bool_t only_when_regi
}
}
if (can_subscribe && fr->subscribe && fr->subscribe_active==FALSE){
ms_message("Sending a new SUBSCRIBE");
ms_message("Sending a new SUBSCRIBE for friend [%p]", fr);
__linphone_friend_do_subscribe(fr);
}else if (can_subscribe && fr->subscribe_active && !fr->subscribe){
linphone_friend_unsubscribe(fr);
......@@ -1072,11 +1075,6 @@ LinphoneSubscribePolicy __policy_str_to_enum(const char* pol){
return LinphoneSPWait;
}
LinphoneProxyConfig *__index_to_proxy(LinphoneCore *lc, int index){
if (index>=0) return (LinphoneProxyConfig*)bctbx_list_nth_data(lc->sip_conf.proxies,index);
else return NULL;
}
LinphoneFriend * linphone_friend_new_from_config_file(LinphoneCore *lc, int index){
const char *tmp;
char item[50];
......@@ -1107,25 +1105,36 @@ LinphoneFriend * linphone_friend_new_from_config_file(LinphoneCore *lc, int inde
linphone_friend_send_subscribe(lf,!!a);
a = lp_config_get_int(config, item, "presence_received", 0);
lf->presence_received = (bool_t)a;
lf->rc_index = index;
linphone_friend_set_ref_key(lf,lp_config_get_string(config,item,"refkey",NULL));
return lf;
}
const char *__policy_enum_to_str(LinphoneSubscribePolicy pol){
switch(pol){
case LinphoneSPAccept:
return "accept";
break;
case LinphoneSPDeny:
return "deny";
break;
case LinphoneSPWait:
return "wait";
break;
int linphone_friend_get_rc_index(const LinphoneFriend *lf) {
return lf->rc_index;
}
void linphone_friend_remove(LinphoneFriend *lf) {
if (!lf) return;
if (lf->friend_list) {
linphone_friend_list_remove_friend(lf->friend_list, lf);
}
if (lf->rc_index >= 0) {
LinphoneCore *lc = lf->lc;
if (lc) {
LinphoneConfig *config = linphone_core_get_config(lc);
if (config) {
char section[50];
sprintf(section, "friend_%i", lf->rc_index);
linphone_config_clean_section(config, section);
linphone_config_sync(config);
lf->rc_index = -1;
}
}
}
ms_warning("Invalid policy enum value.");
return "wait";
}
LinphoneCore *linphone_friend_get_core(const LinphoneFriend *fr){
......@@ -1192,6 +1201,7 @@ bool_t linphone_friend_create_vcard(LinphoneFriend *fr, const char *name) {
linphone_vcard_set_full_name(vcard, name);
linphone_friend_set_vcard(fr, vcard);
linphone_vcard_unref(vcard);
ms_debug("VCard created for friend [%p]", fr);
return TRUE;
}
......
......@@ -483,6 +483,14 @@ void linphone_core_cbs_set_chat_room_state_changed (LinphoneCoreCbs *cbs, Linpho
cbs->vtable->chat_room_state_changed = cb;
}
LinphoneCoreCbsChatRoomSubjectChangedCb linphone_core_cbs_get_chat_room_subject_changed (LinphoneCoreCbs *cbs) {
return cbs->vtable->chat_room_subject_changed;
}
void linphone_core_cbs_set_chat_room_subject_changed (LinphoneCoreCbs *cbs, LinphoneCoreCbsChatRoomSubjectChangedCb cb) {
cbs->vtable->chat_room_subject_changed = cb;
}
LinphoneCoreCbsQrcodeFoundCb linphone_core_cbs_get_qrcode_found(LinphoneCoreCbs *cbs) {
return cbs->vtable->qrcode_found;
}
......@@ -800,6 +808,12 @@ static int log_collection_upload_on_send_body(belle_sip_user_body_handler_t *bh,
#else
FILE *log_file = fopen(log_filename, "r");
#endif
if (!log_file) {
ms_error("Couldn't open log file [%s], errno [%s], aborting log upload", log_filename, strerror(errno));
*size=0;
return BELLE_SIP_STOP;
}
if (fseek(log_file, (long)offset, SEEK_SET)) {
ms_error("Cannot seek file [%s] at position [%lu] errno [%s]",log_filename,(unsigned long)offset,strerror(errno));
......@@ -1005,6 +1019,16 @@ void linphone_core_upload_log_collection(LinphoneCore *core) {
belle_http_request_t *req;
char *name;
uri = belle_generic_uri_parse(linphone_core_get_log_collection_upload_server_url(core));
if (uri == NULL || !belle_generic_uri_get_host(uri)) {
ms_error("Invalid log upload server URL: %s", linphone_core_get_log_collection_upload_server_url(core));
linphone_core_notify_log_collection_upload_state_changed(core, LinphoneCoreLogCollectionUploadStateNotDelivered, "Invalid log upload server URL");
if (uri) {
belle_sip_object_unref(uri);
}
return;
}
core->log_collection_upload_information = linphone_core_create_content(core);
#ifdef HAVE_ZLIB
linphone_content_set_type(core->log_collection_upload_information, "application");
......@@ -1022,10 +1046,13 @@ void linphone_core_upload_log_collection(LinphoneCore *core) {
core->log_collection_upload_information = NULL;
ms_error("prepare_log_collection_file_to_upload(): error.");
linphone_core_notify_log_collection_upload_state_changed(core, LinphoneCoreLogCollectionUploadStateNotDelivered, "Error while preparing log collection upload");
if (uri) {
belle_sip_object_unref(uri);
}
return;
}
linphone_content_set_size(core->log_collection_upload_information, get_size_of_file_to_upload(name));
uri = belle_generic_uri_parse(linphone_core_get_log_collection_upload_server_url(core));
req = belle_http_request_create("POST", uri, NULL, NULL, NULL);
cbs.process_response = process_response_from_post_file_log_collection;
cbs.process_io_error = process_io_error_upload_log_collection;
......@@ -2388,6 +2415,7 @@ static void _linphone_core_init_account_creator_service(LinphoneCore *lc) {
service->is_account_linked_request_cb = linphone_account_creator_is_account_linked_linphone;
service->recover_account_request_cb = linphone_account_creator_recover_phone_account_linphone;
service->update_account_request_cb = linphone_account_creator_update_password_linphone;
service->login_linphone_account_request_cb = linphone_account_creator_login_linphone_account_linphone;
linphone_core_set_account_creator_service(lc, service);
}
......@@ -3678,15 +3706,17 @@ static bctbx_list_t *make_routes_for_proxy(LinphoneProxyConfig *proxy, const Lin
proxy_routes_iterator = bctbx_list_next(proxy_routes_iterator);
}
if (srv_route){
ret=bctbx_list_append(ret,sal_address_clone(L_GET_PRIVATE_FROM_C_OBJECT(srv_route)->getInternalAddress()));
ret = bctbx_list_append(ret, sal_address_clone(L_GET_PRIVATE_FROM_C_OBJECT(srv_route)->getInternalAddress()));
}
if (ret==NULL){
if (ret == NULL) {
/*if the proxy address matches the domain part of the destination, then use the same transport
* as the one used for registration. This is done by forcing a route to this proxy.*/
SalAddress *proxy_addr=sal_address_new(linphone_proxy_config_get_addr(proxy));
if (strcmp(sal_address_get_domain(proxy_addr),linphone_address_get_domain(dest))==0){
ret=bctbx_list_append(ret,proxy_addr);
}else sal_address_unref(proxy_addr);
SalAddress *proxy_addr = sal_address_new(linphone_proxy_config_get_addr(proxy));
const char *proxy_addr_domain = sal_address_get_domain(proxy_addr);
const char *linphone_addr_domain = linphone_address_get_domain(dest);
if (proxy_addr_domain && linphone_addr_domain && strcmp(proxy_addr_domain, linphone_addr_domain) == 0) {
ret = bctbx_list_append(ret,proxy_addr);
} else sal_address_unref(proxy_addr);
}
return ret;
}
......@@ -3728,6 +3758,10 @@ LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const L
LinphoneProxyConfig *found_noreg_cfg=NULL;
LinphoneProxyConfig *default_cfg=lc->default_proxy;
if (!uri) {
ms_error("Cannot look for proxy for NULL uri, returning default");
return default_cfg;
}
if (linphone_address_get_domain(uri) == NULL) {
ms_message("Cannot look for proxy for uri [%p] that has no domain set, returning default", uri);
return default_cfg;
......
......@@ -219,9 +219,9 @@ static int is_a_comment(const char *str){
LpSection *linphone_config_find_section(const LpConfig *lpconfig, const char *name){
LpSection *sec;
bctbx_list_t *elem;
bctbx_list_t *elem = lpconfig->sections;
/*printf("Looking for section %s\n",name);*/
for (elem=lpconfig->sections;elem!=NULL;elem=bctbx_list_next(elem)){
for (;elem!=NULL;elem=bctbx_list_next(elem)){
sec=(LpSection*)elem->data;
if (strcmp(sec->name,name)==0){
/*printf("Section %s found\n",name);*/
......@@ -752,7 +752,7 @@ bool_t linphone_config_get_skip_flag_for_section(const LpConfig *lpconfig, const
}
void linphone_config_set_string(LpConfig *lpconfig,const char *section, const char *key, const char *value){
LpItem *item;
LpItem *item;
LpSection *sec=linphone_config_find_section(lpconfig,section);
if (sec!=NULL){
item=lp_section_find_item(sec,key);
......
......@@ -32,7 +32,21 @@
using namespace LinphonePrivate;
extern const char *__policy_enum_to_str(LinphoneSubscribePolicy pol);
const char *__policy_enum_to_str(LinphoneSubscribePolicy pol){
switch(pol){
case LinphoneSPAccept:
return "accept";
break;
case LinphoneSPDeny:
return "deny";
break;
case LinphoneSPWait:
return "wait";
break;
}
ms_warning("Invalid policy enum value.");
return "wait";
}
struct _LinphonePresenceNote {
belle_sip_object_t base;
......
......@@ -126,7 +126,8 @@ LINPHONE_PUBLIC void linphone_call_params_set_no_user_consent(LinphoneCallParams
void _linphone_core_uninit(LinphoneCore *lc);
void linphone_core_write_auth_info(LinphoneCore *lc, LinphoneAuthInfo *ai);
const LinphoneAuthInfo *_linphone_core_find_tls_auth_info(LinphoneCore *lc);
const LinphoneAuthInfo *_linphone_core_find_auth_info(LinphoneCore *lc, const char *realm, const char *username, const char *domain, bool_t ignore_realm);
const LinphoneAuthInfo *_linphone_core_find_auth_info(LinphoneCore *lc, const char *realm, const char *username, const char *domain, const char *algorithm, bool_t ignore_realm);
void linphone_auth_info_fill_belle_sip_event(const LinphoneAuthInfo *auth_info, belle_sip_auth_event *event);
void linphone_core_update_proxy_register(LinphoneCore *lc);
const char *linphone_core_get_nat_address_resolved(LinphoneCore *lc);
......@@ -264,7 +265,6 @@ LINPHONE_PUBLIC bool_t _linphone_call_stats_rtcp_received_via_mux (const Linphon
bool_t linphone_core_media_description_contains_video_stream(const SalMediaDescription *md);
void linphone_core_send_initial_subscribes(LinphoneCore *lc);
LinphoneFriend * linphone_friend_new_from_config_file(struct _LinphoneCore *lc, int index);
void linphone_proxy_config_update(LinphoneProxyConfig *cfg);
LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const LinphoneAddress *uri);
......@@ -456,6 +456,8 @@ void linphone_nat_policy_save_to_config(const LinphoneNatPolicy *policy);
void linphone_core_create_im_notif_policy(LinphoneCore *lc);
LINPHONE_PUBLIC LinphoneFriend * linphone_friend_new_from_config_file(LinphoneCore *lc, int index);
LINPHONE_PUBLIC int linphone_friend_get_rc_index(const LinphoneFriend *lf);
/*****************************************************************************
* REMOTE PROVISIONING FUNCTIONS *
......@@ -562,6 +564,7 @@ void linphone_core_notify_friend_list_removed(LinphoneCore *lc, LinphoneFriendLi
void linphone_core_notify_call_created(LinphoneCore *lc, LinphoneCall *call);
void linphone_core_notify_version_update_check_result_received(LinphoneCore *lc, LinphoneVersionUpdateCheckResult result, const char *version, const char *url);