linphonecore.c 372.59 KiB
/*
 * Copyright (c) 2010-2022 Belledonne Communications SARL.
 * This file is part of Liblinphone
 * (see https://gitlab.linphone.org/BC/public/liblinphone).
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Affero General Public License as
 * published by the Free Software Foundation, either version 3 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 Affero General Public License for more details.
 * You should have received a copy of the GNU Affero General Public License
 * along with this program. If not, see <http://www.gnu.org/licenses/>.
#include <math.h>
#include <sstream>
#include <sys/stat.h>
#include <sys/types.h>
#ifdef INET6
#ifndef _WIN32
#include <netdb.h>
#endif
#endif
#ifdef HAVE_SQLITE
#include "sqlite3_bctbx_vfs.h"
#endif
#ifdef __APPLE__
#include "TargetConditionals.h"
#endif
#ifdef __ANDROID__
#include "android/api-level.h"
#endif
#include "bctoolbox/charconv.h"
#include "bctoolbox/defs.h"
#include "bctoolbox/regex.h"
#include "belr/grammarbuilder.h"
#include <ortp/telephonyevents.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/msqrcodereader.h"
#include "mediastreamer2/msvolume.h"
#include <mediastreamer2/dtls_srtp.h>
#include <mediastreamer2/zrtp.h>
#include "account/account.h"
#include "call/call.h"
#include "chat/modifier/file-transfer-chat-message-modifier.h"
#include "conference.h"
#include "content/file-transfer-content.h"
#include "linphone/api/c-content.h"
#include "linphone/api/c-recorder-params.h"
#include "linphone/api/c-recorder.h"
7172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140
#include "linphone/core.h" #include "linphone/core_utils.h" #include "linphone/logging.h" #include "linphone/lpconfig.h" #include "linphone/sipsetup.h" #include "local_conference.h" #include "logger/logger.h" #include "logging-private.h" #include "private.h" #include "quality_reporting.h" #include "remote_conference.h" #ifdef HAVE_ADVANCED_IM #include "chat/chat-room/client-group-chat-room-p.h" #include "chat/chat-room/client-group-to-basic-chat-room.h" #include "chat/chat-room/server-group-chat-room-p.h" #include "conference/handlers/local-conference-list-event-handler.h" #include "conference/handlers/remote-conference-event-handler.h" #include "conference/handlers/remote-conference-list-event-handler.h" #endif #include "conference/conference-info.h" #include "conference/conference-scheduler.h" #include "conference/params/media-session-params-p.h" #include "conference/session/media-session-p.h" #include "conference/session/media-session.h" #include "content/content-manager.h" #include "content/content-type.h" #include "core/core-p.h" #include "event/event-publish.h" #include "sal/sal.h" #ifdef HAVE_CONFIG_H #include "config.h" #include "gitversion.h" #endif // For migration purpose. #include "address/address.h" #include "c-wrapper/c-wrapper.h" #include "utils/payload-type-handler.h" #ifdef HAVE_ZLIB #define COMPRESSED_LOG_COLLECTION_EXTENSION "gz" #ifdef _WIN32 #include <fcntl.h> #include <io.h> #ifndef fileno #define fileno _fileno #endif #define unlink _unlink #define SET_BINARY_MODE(file) setmode(fileno(file), O_BINARY) #else #define SET_BINARY_MODE(file) #endif #include <zlib.h> #else #define COMPRESSED_LOG_COLLECTION_EXTENSION "txt" #endif #define LOG_COLLECTION_DEFAULT_PATH "." #define LOG_COLLECTION_DEFAULT_PREFIX "linphone" #define LOG_COLLECTION_DEFAULT_MAX_FILE_SIZE (10 * 1024 * 1024) /*#define UNSTANDART_GSM_11K 1*/ static const char *liblinphone_version = #ifdef LIBLINPHONE_GIT_VERSION LIBLINPHONE_GIT_VERSION #else LIBLINPHONE_VERSION #endif ;
141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
inline OrtpLogLevel operator|=(OrtpLogLevel a, OrtpLogLevel b) { int ia = static_cast<int>(a); int ib = static_cast<int>(b); return static_cast<OrtpLogLevel>(ia |= ib); } static OrtpLogFunc liblinphone_user_log_func = bctbx_logv_out; /*by default, user log handler = stdout*/ static OrtpLogFunc liblinphone_current_log_func = NULL; /*can be either logcolection or user_log*/ static LinphoneLogCollectionState liblinphone_log_collection_state = LinphoneLogCollectionDisabled; static char *liblinphone_log_collection_path = NULL; static char *liblinphone_log_collection_prefix = NULL; static size_t liblinphone_log_collection_max_file_size = LOG_COLLECTION_DEFAULT_MAX_FILE_SIZE; static ortp_mutex_t liblinphone_log_collection_mutex; static FILE *liblinphone_log_collection_file = NULL; static size_t liblinphone_log_collection_file_size = 0; static bool_t liblinphone_serialize_logs = FALSE; static void set_sip_network_reachable(LinphoneCore *lc, bool_t isReachable, time_t curtime); static void set_media_network_reachable(LinphoneCore *lc, bool_t isReachable); static void linphone_core_run_hooks(LinphoneCore *lc); static void linphone_core_zrtp_cache_close(LinphoneCore *lc); void linphone_core_zrtp_cache_db_init(LinphoneCore *lc, const char *fileName); static LinphoneStatus _linphone_core_set_sip_transports(LinphoneCore *lc, const LinphoneSipTransports *tr_config, bool_t applyIt); bool_t linphone_core_sound_resources_need_locking(LinphoneCore *lc, const LinphoneCallParams *params); #include "contact_providers_priv.h" #include "enum.h" static void toggle_video_preview(LinphoneCore *lc, bool_t val); /* relative path where is stored local ring*/ #define LOCAL_RING_WAV "oldphone-mono.wav" #define LOCAL_RING_MKV "notes_of_the_optimistic.mkv" /* same for remote ring (ringback)*/ #define REMOTE_RING_WAV "ringback.wav" #define HOLD_MUSIC_WAV "toy-mono.wav" #define HOLD_MUSIC_MKV "dont_wait_too_long.mkv" using namespace std; using namespace LinphonePrivate; extern Sal::Callbacks linphone_sal_callbacks; static void _linphone_core_cbs_uninit(LinphoneCoreCbs *cbs); typedef belle_sip_object_t_vptr_t LinphoneCoreCbs_vptr_t; BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneCoreCbs); BELLE_SIP_INSTANCIATE_VPTR(LinphoneCoreCbs, belle_sip_object_t, _linphone_core_cbs_uninit, // destroy NULL, // clone NULL, // Marshall FALSE); LinphoneCoreCbs *_linphone_core_cbs_new(void) { LinphoneCoreCbs *obj = belle_sip_object_new(LinphoneCoreCbs); obj->vtable = ms_new0(LinphoneCoreVTable, 1); obj->autorelease = TRUE; return obj; } static void _linphone_core_cbs_uninit(LinphoneCoreCbs *cbs) { if (cbs->autorelease) ms_free(cbs->vtable); } void _linphone_core_cbs_set_v_table(LinphoneCoreCbs *cbs, LinphoneCoreVTable *vtable, bool_t autorelease) { ms_free(cbs->vtable); cbs->vtable = vtable;
211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280
cbs->autorelease = autorelease; } LinphoneCoreCbs *linphone_core_cbs_ref(LinphoneCoreCbs *cbs) { return (LinphoneCoreCbs *)belle_sip_object_ref(cbs); } void linphone_core_cbs_unref(LinphoneCoreCbs *cbs) { belle_sip_object_unref(cbs); } void linphone_core_cbs_set_user_data(LinphoneCoreCbs *cbs, void *user_data) { cbs->vtable->user_data = user_data; } void *linphone_core_cbs_get_user_data(const LinphoneCoreCbs *cbs) { return cbs->vtable->user_data; } LinphoneCoreCbs *linphone_core_get_current_callbacks(const LinphoneCore *lc) { return lc->current_cbs; } LinphoneCoreCbsGlobalStateChangedCb linphone_core_cbs_get_global_state_changed(LinphoneCoreCbs *cbs) { return cbs->vtable->global_state_changed; } void linphone_core_cbs_set_global_state_changed(LinphoneCoreCbs *cbs, LinphoneCoreCbsGlobalStateChangedCb cb) { cbs->vtable->global_state_changed = cb; } LinphoneCoreCbsRegistrationStateChangedCb linphone_core_cbs_get_registration_state_changed(LinphoneCoreCbs *cbs) { return cbs->vtable->registration_state_changed; } void linphone_core_cbs_set_registration_state_changed(LinphoneCoreCbs *cbs, LinphoneCoreCbsRegistrationStateChangedCb cb) { cbs->vtable->registration_state_changed = cb; } void linphone_core_cbs_set_conference_info_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsConferenceInfoReceivedCb cb) { cbs->vtable->conference_info_received = cb; } LinphoneCoreCbsConferenceInfoReceivedCb linphone_core_cbs_get_conference_info_received(LinphoneCoreCbs *cbs) { return cbs->vtable->conference_info_received; } void linphone_core_cbs_set_push_notification_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsPushNotificationReceivedCb cb) { cbs->vtable->push_notification_received = cb; } LinphoneCoreCbsPushNotificationReceivedCb linphone_core_cbs_get_push_notification_received(LinphoneCoreCbs *cbs) { return cbs->vtable->push_notification_received; } LinphoneCoreCbsPreviewDisplayErrorOccurredCb linphone_core_cbs_get_preview_display_error_occurred(const LinphoneCoreCbs *cbs) { return cbs->vtable->preview_display_error_occurred; } void linphone_core_cbs_set_preview_display_error_occurred(LinphoneCoreCbs *cbs, LinphoneCoreCbsPreviewDisplayErrorOccurredCb cb) { cbs->vtable->preview_display_error_occurred = cb; } LinphoneCoreCbsCallStateChangedCb linphone_core_cbs_get_call_state_changed(LinphoneCoreCbs *cbs) { return cbs->vtable->call_state_changed; }
281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350
void linphone_core_cbs_set_call_state_changed(LinphoneCoreCbs *cbs, LinphoneCoreCbsCallStateChangedCb cb) { cbs->vtable->call_state_changed = cb; } LinphoneCoreCbsNotifyPresenceReceivedCb linphone_core_cbs_get_notify_presence_received(LinphoneCoreCbs *cbs) { return cbs->vtable->notify_presence_received; } void linphone_core_cbs_set_notify_presence_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsNotifyPresenceReceivedCb cb) { cbs->vtable->notify_presence_received = cb; } LinphoneCoreCbsNotifyPresenceReceivedForUriOrTelCb linphone_core_cbs_get_notify_presence_received_for_uri_or_tel(LinphoneCoreCbs *cbs) { return cbs->vtable->notify_presence_received_for_uri_or_tel; } void linphone_core_cbs_set_notify_presence_received_for_uri_or_tel( LinphoneCoreCbs *cbs, LinphoneCoreCbsNotifyPresenceReceivedForUriOrTelCb cb) { cbs->vtable->notify_presence_received_for_uri_or_tel = cb; } LinphoneCoreCbsNewSubscriptionRequestedCb linphone_core_cbs_get_new_subscription_requested(LinphoneCoreCbs *cbs) { return cbs->vtable->new_subscription_requested; } void linphone_core_cbs_set_new_subscription_requested(LinphoneCoreCbs *cbs, LinphoneCoreCbsNewSubscriptionRequestedCb cb) { cbs->vtable->new_subscription_requested = cb; } LinphoneCoreCbsAuthenticationRequestedCb linphone_core_cbs_get_authentication_requested(LinphoneCoreCbs *cbs) { return cbs->vtable->authentication_requested; } void linphone_core_cbs_set_authentication_requested(LinphoneCoreCbs *cbs, LinphoneCoreCbsAuthenticationRequestedCb cb) { cbs->vtable->authentication_requested = cb; } LinphoneCoreCbsCallLogUpdatedCb linphone_core_cbs_get_call_log_updated(LinphoneCoreCbs *cbs) { return cbs->vtable->call_log_updated; } void linphone_core_cbs_set_call_log_updated(LinphoneCoreCbs *cbs, LinphoneCoreCbsCallLogUpdatedCb cb) { cbs->vtable->call_log_updated = cb; } LinphoneCoreCbsCallIdUpdatedCb linphone_core_cbs_get_call_id_updated(LinphoneCoreCbs *cbs) { return cbs->vtable->call_id_updated; } void linphone_core_cbs_set_call_id_updated(LinphoneCoreCbs *cbs, LinphoneCoreCbsCallIdUpdatedCb cb) { cbs->vtable->call_id_updated = cb; } LinphoneCoreCbsChatRoomSessionStateChangedCb linphone_core_cbs_get_chat_room_session_state_changed(LinphoneCoreCbs *cbs) { return cbs->vtable->chat_room_session_state_changed; } void linphone_core_cbs_set_chat_room_session_state_changed(LinphoneCoreCbs *cbs, LinphoneCoreCbsChatRoomSessionStateChangedCb cb) { cbs->vtable->chat_room_session_state_changed = cb; } LinphoneCoreCbsChatRoomReadCb linphone_core_cbs_get_chat_room_read(LinphoneCoreCbs *cbs) { return cbs->vtable->chat_room_read; }
351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420
void linphone_core_cbs_set_chat_room_read(LinphoneCoreCbs *cbs, LinphoneCoreCbsChatRoomReadCb cb) { cbs->vtable->chat_room_read = cb; } LinphoneCoreCbsMessageReceivedCb linphone_core_cbs_get_message_sent(LinphoneCoreCbs *cbs) { return cbs->vtable->message_sent; } void linphone_core_cbs_set_message_sent(LinphoneCoreCbs *cbs, LinphoneCoreCbsMessageReceivedCb cb) { cbs->vtable->message_sent = cb; } LinphoneCoreCbsMessageReceivedCb linphone_core_cbs_get_message_received(LinphoneCoreCbs *cbs) { return cbs->vtable->message_received; } void linphone_core_cbs_set_message_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsMessageReceivedCb cb) { cbs->vtable->message_received = cb; } LinphoneCoreCbsNewMessageReactionCb linphone_core_cbs_get_new_message_reaction(LinphoneCoreCbs *cbs) { return cbs->vtable->new_message_reaction; } void linphone_core_cbs_set_new_message_reaction(LinphoneCoreCbs *cbs, LinphoneCoreCbsNewMessageReactionCb cb) { cbs->vtable->new_message_reaction = cb; } LinphoneCoreCbsReactionRemovedCb linphone_core_cbs_get_reaction_removed(LinphoneCoreCbs *cbs) { return cbs->vtable->reaction_removed; } void linphone_core_cbs_set_reaction_removed(LinphoneCoreCbs *cbs, LinphoneCoreCbsReactionRemovedCb cb) { cbs->vtable->reaction_removed = cb; } LinphoneCoreCbsMessagesReceivedCb linphone_core_cbs_get_messages_received(LinphoneCoreCbs *cbs) { return cbs->vtable->messages_received; } void linphone_core_cbs_set_messages_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsMessagesReceivedCb cb) { cbs->vtable->messages_received = cb; } LinphoneCoreCbsMessageReceivedUnableDecryptCb linphone_core_cbs_get_message_received_unable_decrypt(LinphoneCoreCbs *cbs) { return cbs->vtable->message_received_unable_decrypt; } void linphone_core_cbs_set_message_received_unable_decrypt(LinphoneCoreCbs *cbs, LinphoneCoreCbsMessageReceivedUnableDecryptCb cb) { cbs->vtable->message_received_unable_decrypt = cb; } LinphoneCoreCbsIsComposingReceivedCb linphone_core_cbs_get_is_composing_received(LinphoneCoreCbs *cbs) { return cbs->vtable->is_composing_received; } void linphone_core_cbs_set_is_composing_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsIsComposingReceivedCb cb) { cbs->vtable->is_composing_received = cb; } LinphoneCoreCbsDtmfReceivedCb linphone_core_cbs_get_dtmf_received(LinphoneCoreCbs *cbs) { return cbs->vtable->dtmf_received; } void linphone_core_cbs_set_dtmf_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsDtmfReceivedCb cb) { cbs->vtable->dtmf_received = cb; }
421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490
LinphoneCoreCbsReferReceivedCb linphone_core_cbs_get_refer_received(LinphoneCoreCbs *cbs) { return cbs->vtable->refer_received; } void linphone_core_cbs_set_refer_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsReferReceivedCb cb) { cbs->vtable->refer_received = cb; } LinphoneCoreCbsCallGoClearAckSentCb linphone_core_cbs_get_call_goclear_ack_sent(LinphoneCoreCbs *cbs) { return cbs->vtable->call_goclear_ack_sent; } void linphone_core_cbs_set_call_goclear_ack_sent(LinphoneCoreCbs *cbs, LinphoneCoreCbsCallGoClearAckSentCb cb) { cbs->vtable->call_goclear_ack_sent = cb; } LinphoneCoreCbsCallEncryptionChangedCb linphone_core_cbs_get_call_encryption_changed(LinphoneCoreCbs *cbs) { return cbs->vtable->call_encryption_changed; } void linphone_core_cbs_set_call_encryption_changed(LinphoneCoreCbs *cbs, LinphoneCoreCbsCallEncryptionChangedCb cb) { cbs->vtable->call_encryption_changed = cb; } LinphoneCoreCbsCallSendMasterKeyChangedCb linphone_core_cbs_get_call_send_master_key_changed(LinphoneCoreCbs *cbs) { return cbs->vtable->call_send_master_key_changed; } void linphone_core_cbs_set_call_send_master_key_changed(LinphoneCoreCbs *cbs, LinphoneCoreCbsCallSendMasterKeyChangedCb cb) { cbs->vtable->call_send_master_key_changed = cb; } LinphoneCoreCbsCallReceiveMasterKeyChangedCb linphone_core_cbs_get_call_receive_master_key_changed(LinphoneCoreCbs *cbs) { return cbs->vtable->call_receive_master_key_changed; } void linphone_core_cbs_set_call_receive_master_key_changed(LinphoneCoreCbs *cbs, LinphoneCoreCbsCallReceiveMasterKeyChangedCb cb) { cbs->vtable->call_receive_master_key_changed = cb; } LinphoneCoreCbsTransferStateChangedCb linphone_core_cbs_get_transfer_state_changed(LinphoneCoreCbs *cbs) { return cbs->vtable->transfer_state_changed; } void linphone_core_cbs_set_transfer_state_changed(LinphoneCoreCbs *cbs, LinphoneCoreCbsTransferStateChangedCb cb) { cbs->vtable->transfer_state_changed = cb; } LinphoneCoreCbsBuddyInfoUpdatedCb linphone_core_cbs_get_buddy_info_updated(LinphoneCoreCbs *cbs) { return cbs->vtable->buddy_info_updated; } void linphone_core_cbs_set_buddy_info_updated(LinphoneCoreCbs *cbs, LinphoneCoreCbsBuddyInfoUpdatedCb cb) { cbs->vtable->buddy_info_updated = cb; } LinphoneCoreCbsCallStatsUpdatedCb linphone_core_cbs_get_call_stats_updated(LinphoneCoreCbs *cbs) { return cbs->vtable->call_stats_updated; } void linphone_core_cbs_set_call_stats_updated(LinphoneCoreCbs *cbs, LinphoneCoreCbsCallStatsUpdatedCb cb) { cbs->vtable->call_stats_updated = cb; } LinphoneCoreCbsInfoReceivedCb linphone_core_cbs_get_info_received(LinphoneCoreCbs *cbs) { return cbs->vtable->info_received; }
491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560
void linphone_core_cbs_set_info_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsInfoReceivedCb cb) { cbs->vtable->info_received = cb; } LinphoneCoreCbsSubscriptionStateChangedCb linphone_core_cbs_get_subscription_state_changed(LinphoneCoreCbs *cbs) { return cbs->vtable->subscription_state_changed; } void linphone_core_cbs_set_subscription_state_changed(LinphoneCoreCbs *cbs, LinphoneCoreCbsSubscriptionStateChangedCb cb) { cbs->vtable->subscription_state_changed = cb; } LinphoneCoreCbsNotifySentCb linphone_core_cbs_get_notify_sent(LinphoneCoreCbs *cbs) { return cbs->vtable->notify_sent; } void linphone_core_cbs_set_notify_sent(LinphoneCoreCbs *cbs, LinphoneCoreCbsNotifySentCb cb) { cbs->vtable->notify_sent = cb; } LinphoneCoreCbsNotifyReceivedCb linphone_core_cbs_get_notify_received(LinphoneCoreCbs *cbs) { return cbs->vtable->notify_received; } void linphone_core_cbs_set_notify_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsNotifyReceivedCb cb) { cbs->vtable->notify_received = cb; } LinphoneCoreCbsSubscribeReceivedCb linphone_core_cbs_get_subscribe_received(LinphoneCoreCbs *cbs) { return cbs->vtable->subscribe_received; } void linphone_core_cbs_set_subscribe_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsSubscribeReceivedCb cb) { cbs->vtable->subscribe_received = cb; } LinphoneCoreCbsPublishStateChangedCb linphone_core_cbs_get_rpublish_state_changed(LinphoneCoreCbs *cbs) { return cbs->vtable->publish_state_changed; } void linphone_core_cbs_set_publish_state_changed(LinphoneCoreCbs *cbs, LinphoneCoreCbsPublishStateChangedCb cb) { cbs->vtable->publish_state_changed = cb; } LinphoneCoreCbsPublishReceivedCb linphone_core_cbs_get_publish_received(LinphoneCoreCbs *cbs) { return cbs->vtable->publish_received; } void linphone_core_cbs_set_publish_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsPublishReceivedCb cb) { cbs->vtable->publish_received = cb; } LinphoneCoreCbsConfiguringStatusCb linphone_core_cbs_get_configuring_status(LinphoneCoreCbs *cbs) { return cbs->vtable->configuring_status; } void linphone_core_cbs_set_configuring_status(LinphoneCoreCbs *cbs, LinphoneCoreCbsConfiguringStatusCb cb) { cbs->vtable->configuring_status = cb; } LinphoneCoreCbsNetworkReachableCb linphone_core_cbs_get_network_reachable(LinphoneCoreCbs *cbs) { return cbs->vtable->network_reachable; } void linphone_core_cbs_set_network_reachable(LinphoneCoreCbs *cbs, LinphoneCoreCbsNetworkReachableCb cb) { cbs->vtable->network_reachable = cb; }
561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630
LinphoneCoreCbsLogCollectionUploadStateChangedCb linphone_core_cbs_log_collection_upload_state_changed(LinphoneCoreCbs *cbs) { return cbs->vtable->log_collection_upload_state_changed; } void linphone_core_cbs_set_log_collection_upload_state_changed(LinphoneCoreCbs *cbs, LinphoneCoreCbsLogCollectionUploadStateChangedCb cb) { cbs->vtable->log_collection_upload_state_changed = cb; } LinphoneCoreCbsLogCollectionUploadProgressIndicationCb linphone_core_cbs_get_rlog_collection_upload_progress_indication(LinphoneCoreCbs *cbs) { return cbs->vtable->log_collection_upload_progress_indication; } void linphone_core_cbs_set_log_collection_upload_progress_indication( LinphoneCoreCbs *cbs, LinphoneCoreCbsLogCollectionUploadProgressIndicationCb cb) { cbs->vtable->log_collection_upload_progress_indication = cb; } LinphoneCoreCbsFriendListCreatedCb linphone_core_cbs_get_friend_list_created(LinphoneCoreCbs *cbs) { return cbs->vtable->friend_list_created; } void linphone_core_cbs_set_friend_list_created(LinphoneCoreCbs *cbs, LinphoneCoreCbsFriendListCreatedCb cb) { cbs->vtable->friend_list_created = cb; } LinphoneCoreCbsFriendListRemovedCb linphone_core_cbs_get_friend_list_removed(LinphoneCoreCbs *cbs) { return cbs->vtable->friend_list_removed; } void linphone_core_cbs_set_friend_list_removed(LinphoneCoreCbs *cbs, LinphoneCoreCbsFriendListRemovedCb cb) { cbs->vtable->friend_list_removed = cb; } LinphoneCoreCbsCallCreatedCb linphone_core_cbs_get_call_created(LinphoneCoreCbs *cbs) { return cbs->vtable->call_created; } void linphone_core_cbs_set_call_created(LinphoneCoreCbs *cbs, LinphoneCoreCbsCallCreatedCb cb) { cbs->vtable->call_created = cb; } LinphoneCoreCbsVersionUpdateCheckResultReceivedCb linphone_core_cbs_get_version_update_check_result_received(LinphoneCoreCbs *cbs) { return cbs->vtable->version_update_check_result_received; } void linphone_core_cbs_set_version_update_check_result_received(LinphoneCoreCbs *cbs, LinphoneCoreCbsVersionUpdateCheckResultReceivedCb cb) { cbs->vtable->version_update_check_result_received = cb; } LinphoneCoreCbsConferenceStateChangedCb linphone_core_cbs_get_conference_state_changed(LinphoneCoreCbs *cbs) { return cbs->vtable->conference_state_changed; } void linphone_core_cbs_set_conference_state_changed(LinphoneCoreCbs *cbs, LinphoneCoreCbsConferenceStateChangedCb cb) { cbs->vtable->conference_state_changed = cb; } LinphoneCoreCbsChatRoomStateChangedCb linphone_core_cbs_get_chat_room_state_changed(LinphoneCoreCbs *cbs) { return cbs->vtable->chat_room_state_changed; } void linphone_core_cbs_set_chat_room_state_changed(LinphoneCoreCbs *cbs, LinphoneCoreCbsChatRoomStateChangedCb cb) { cbs->vtable->chat_room_state_changed = cb; }
631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700
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; } LinphoneCoreCbsChatRoomEphemeralMessageDeleteCb linphone_core_cbs_get_chat_room_ephemeral_message_deleted(LinphoneCoreCbs *cbs) { return cbs->vtable->chat_room_ephemeral_message_deleted; } void linphone_core_cbs_set_chat_room_ephemeral_message_deleted(LinphoneCoreCbs *cbs, LinphoneCoreCbsChatRoomEphemeralMessageDeleteCb cb) { cbs->vtable->chat_room_ephemeral_message_deleted = cb; } LinphoneCoreCbsImeeUserRegistrationCb linphone_core_cbs_get_imee_user_registration(LinphoneCoreCbs *cbs) { return cbs->vtable->imee_user_registration; } void linphone_core_cbs_set_imee_user_registration(LinphoneCoreCbs *cbs, LinphoneCoreCbsImeeUserRegistrationCb cb) { cbs->vtable->imee_user_registration = cb; } LinphoneCoreCbsQrcodeFoundCb linphone_core_cbs_get_qrcode_found(LinphoneCoreCbs *cbs) { return cbs->vtable->qrcode_found; } void linphone_core_cbs_set_qrcode_found(LinphoneCoreCbs *cbs, LinphoneCoreCbsQrcodeFoundCb cb) { cbs->vtable->qrcode_found = cb; } LinphoneCoreCbsFirstCallStartedCb linphone_core_cbs_get_first_call_started(LinphoneCoreCbs *cbs) { return cbs->vtable->first_call_started; } void linphone_core_cbs_set_first_call_started(LinphoneCoreCbs *cbs, LinphoneCoreCbsFirstCallStartedCb cb) { cbs->vtable->first_call_started = cb; } LinphoneCoreCbsLastCallEndedCb linphone_core_cbs_get_last_call_ended(LinphoneCoreCbs *cbs) { return cbs->vtable->last_call_ended; } void linphone_core_cbs_set_last_call_ended(LinphoneCoreCbs *cbs, LinphoneCoreCbsLastCallEndedCb cb) { cbs->vtable->last_call_ended = cb; } LinphoneCoreCbsAudioDeviceChangedCb linphone_core_cbs_get_audio_device_changed(LinphoneCoreCbs *cbs) { return cbs->vtable->audio_device_changed; } void linphone_core_cbs_set_audio_device_changed(LinphoneCoreCbs *cbs, LinphoneCoreCbsAudioDeviceChangedCb cb) { cbs->vtable->audio_device_changed = cb; } LinphoneCoreCbsAudioDevicesListUpdatedCb linphone_core_cbs_get_audio_devices_list_updated(LinphoneCoreCbs *cbs) { return cbs->vtable->audio_devices_list_updated; } void linphone_core_cbs_set_audio_devices_list_updated(LinphoneCoreCbs *cbs, LinphoneCoreCbsAudioDevicesListUpdatedCb cb) { cbs->vtable->audio_devices_list_updated = cb; } void linphone_core_cbs_set_ec_calibration_result(LinphoneCoreCbs *cbs, LinphoneCoreCbsEcCalibrationResultCb cb) { cbs->vtable->ec_calibration_result = cb; }
701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770
void linphone_core_cbs_set_ec_calibration_audio_init(LinphoneCoreCbs *cbs, LinphoneCoreCbsEcCalibrationAudioInitCb cb) { cbs->vtable->ec_calibration_audio_init = cb; } void linphone_core_cbs_set_ec_calibration_audio_uninit(LinphoneCoreCbs *cbs, LinphoneCoreCbsEcCalibrationAudioUninitCb cb) { cbs->vtable->ec_calibration_audio_uninit = cb; } LinphoneCoreCbsChatRoomExhumedCb linphone_core_cbs_get_chat_room_exhumed(LinphoneCoreCbs *cbs) { return cbs->vtable->chat_room_exhumed; } void linphone_core_cbs_set_chat_room_exhumed(LinphoneCoreCbs *cbs, LinphoneCoreCbsChatRoomExhumedCb cb) { cbs->vtable->chat_room_exhumed = cb; } LinphoneCoreCbsAccountRegistrationStateChangedCb linphone_core_cbs_get_account_registration_state_changed(LinphoneCoreCbs *cbs) { return cbs->vtable->account_registration_state_changed; } void linphone_core_cbs_set_account_registration_state_changed(LinphoneCoreCbs *cbs, LinphoneCoreCbsAccountRegistrationStateChangedCb cb) { cbs->vtable->account_registration_state_changed = cb; } void linphone_core_cbs_set_new_alert_triggered(LinphoneCoreCbs *cbs, LinphoneCoreCbsNewAlertTriggeredCb alert_cb) { cbs->vtable->new_alert_triggered = alert_cb; } LinphoneCoreCbsNewAlertTriggeredCb linphone_core_cbs_get_new_alert_triggered(LinphoneCoreCbs *cbs) { return cbs->vtable->new_alert_triggered; } void lc_callback_obj_init(LCCallbackObj *obj, LinphoneCoreCbFunc func, void *ud) { obj->_func = func; obj->_user_data = ud; } int lc_callback_obj_invoke(LCCallbackObj *obj, LinphoneCore *lc) { if (obj->_func != NULL) obj->_func(lc, obj->_user_data); return 0; } int linphone_core_get_current_call_duration(const LinphoneCore *lc) { LinphoneCall *call = linphone_core_get_current_call((LinphoneCore *)lc); if (call) return linphone_call_get_duration(call); return -1; } const LinphoneAddress *linphone_core_get_current_call_remote_address(struct _LinphoneCore *lc) { LinphoneCall *call = linphone_core_get_current_call(lc); if (call == NULL) return NULL; return linphone_call_get_remote_address(call); } static void linphone_core_log_collection_handler(const char *domain, OrtpLogLevel level, const char *fmt, va_list args); void _linphone_core_set_log_handler(OrtpLogFunc logfunc) { liblinphone_user_log_func = logfunc; if (liblinphone_current_log_func == linphone_core_log_collection_handler) { ms_message("There is already a log collection handler, keep it"); } else { bctbx_set_log_handler(liblinphone_current_log_func = liblinphone_user_log_func); } } void linphone_core_set_log_handler(OrtpLogFunc logfunc) { _linphone_core_set_log_handler(logfunc); }
771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840
void linphone_core_set_log_file(FILE *file) { if (file == NULL) file = stdout; _linphone_core_set_log_handler(NULL); bctbx_set_log_file(file); /*gather everythings*/ } void linphone_core_set_log_level(OrtpLogLevel loglevel) { LinphoneLoggingService *log_service = linphone_logging_service_get(); linphone_logging_service_set_log_level(log_service, _bctbx_log_level_to_linphone_log_level(loglevel)); } void linphone_core_set_log_level_mask(unsigned int mask) { LinphoneLoggingService *log_service = linphone_logging_service_get(); linphone_logging_service_set_log_level_mask(log_service, _bctbx_log_mask_to_linphone_log_mask(mask)); } unsigned int linphone_core_get_log_level_mask(void) { LinphoneLoggingService *log_service = linphone_logging_service_get(); return linphone_logging_service_get_log_level_mask(log_service); } static int _open_log_collection_file_with_idx(int idx) { struct stat statbuf; char *log_filename; log_filename = ortp_strdup_printf( "%s/%s%d.log", liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH, liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX, idx); liblinphone_log_collection_file = fopen(log_filename, "a"); ortp_free(log_filename); if (liblinphone_log_collection_file == NULL) return -1; fstat(fileno(liblinphone_log_collection_file), &statbuf); if ((size_t)statbuf.st_size > liblinphone_log_collection_max_file_size) { fclose(liblinphone_log_collection_file); return -1; } liblinphone_log_collection_file_size = (size_t)statbuf.st_size; return 0; } static void _rotate_log_collection_files(void) { char *log_filename1; char *log_filename2; log_filename1 = ortp_strdup_printf( "%s/%s1.log", liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH, liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX); log_filename2 = ortp_strdup_printf( "%s/%s2.log", liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH, liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX); unlink(log_filename1); rename(log_filename2, log_filename1); ortp_free(log_filename1); ortp_free(log_filename2); } static void _open_log_collection_file(void) { if (_open_log_collection_file_with_idx(1) < 0) { if (_open_log_collection_file_with_idx(2) < 0) { _rotate_log_collection_files(); _open_log_collection_file_with_idx(2); } } } static void _close_log_collection_file(void) { if (liblinphone_log_collection_file) { fclose(liblinphone_log_collection_file);
841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910
liblinphone_log_collection_file = NULL; liblinphone_log_collection_file_size = 0; } } #if (!__ANDROID__ && !__APPLE__) || (__ANDROID__ && __ANDROID_API__ < 21) static const char *getprogname() { #if defined(__GLIBC__) return program_invocation_short_name; #else // not known yet on windows return ""; #endif } #endif static void linphone_core_log_collection_handler(const char *domain, OrtpLogLevel level, const char *fmt, va_list args) { const char *lname = "undef"; char *msg; struct timeval tp; struct tm *lt; time_t tt; int ret; if (liblinphone_user_log_func != NULL && liblinphone_user_log_func != linphone_core_log_collection_handler) { #ifndef _WIN32 va_list args_copy; va_copy(args_copy, args); liblinphone_user_log_func(domain, level, fmt, args_copy); va_end(args_copy); #else /* This works on 32 bits, luckily. */ /* TODO: va_copy is available in Visual Studio 2013. */ liblinphone_user_log_func(domain, level, fmt, args); #endif } ortp_gettimeofday(&tp, NULL); tt = (time_t)tp.tv_sec; lt = localtime((const time_t *)&tt); if ((level & ORTP_DEBUG) != 0) { lname = "DEBUG"; } else if ((level & ORTP_MESSAGE) != 0) { lname = "MESSAGE"; } else if ((level & ORTP_WARNING) != 0) { lname = "WARNING"; } else if ((level & ORTP_ERROR) != 0) { lname = "ERROR"; } else if ((level & ORTP_FATAL) != 0) { lname = "FATAL"; } else { ortp_fatal("Bad level !"); } msg = ortp_strdup_vprintf(fmt, args); if (liblinphone_log_collection_file == NULL) { ortp_mutex_lock(&liblinphone_log_collection_mutex); _open_log_collection_file(); ortp_mutex_unlock(&liblinphone_log_collection_mutex); } if (liblinphone_log_collection_file) { ortp_mutex_lock(&liblinphone_log_collection_mutex); ret = fprintf(liblinphone_log_collection_file, "%i-%.2i-%.2i %.2i:%.2i:%.2i:%.3i [%s/%s] %s %s\n", 1900 + lt->tm_year, lt->tm_mon + 1, lt->tm_mday, lt->tm_hour, lt->tm_min, lt->tm_sec, (int)(tp.tv_usec / 1000), getprogname(), domain, lname, msg); fflush(liblinphone_log_collection_file); if (ret > 0) { liblinphone_log_collection_file_size += (size_t)ret;
911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980
if (liblinphone_log_collection_file_size > liblinphone_log_collection_max_file_size) { _close_log_collection_file(); _open_log_collection_file(); } } ortp_mutex_unlock(&liblinphone_log_collection_mutex); } ortp_free(msg); } const char *linphone_core_get_log_collection_path(void) { if (liblinphone_log_collection_path != NULL) { return liblinphone_log_collection_path; } return LOG_COLLECTION_DEFAULT_PATH; } void linphone_core_set_log_collection_path(const char *path) { if (liblinphone_log_collection_path != NULL) { ms_free(liblinphone_log_collection_path); liblinphone_log_collection_path = NULL; } if (path != NULL) { bool_t log_enabled = (linphone_core_log_collection_enabled() != LinphoneLogCollectionDisabled); if (log_enabled) { ortp_mutex_lock(&liblinphone_log_collection_mutex); _close_log_collection_file(); } liblinphone_log_collection_path = ms_strdup(path); if (log_enabled) { _open_log_collection_file(); ortp_mutex_unlock(&liblinphone_log_collection_mutex); } } } const char *linphone_core_get_log_collection_prefix(void) { if (liblinphone_log_collection_prefix != NULL) { return liblinphone_log_collection_prefix; } return LOG_COLLECTION_DEFAULT_PREFIX; } void linphone_core_set_log_collection_prefix(const char *prefix) { if (liblinphone_log_collection_prefix != NULL) { ms_free(liblinphone_log_collection_prefix); liblinphone_log_collection_prefix = NULL; } if (prefix != NULL) { bool_t log_enabled = (linphone_core_log_collection_enabled() != LinphoneLogCollectionDisabled); if (log_enabled) { ortp_mutex_lock(&liblinphone_log_collection_mutex); _close_log_collection_file(); } liblinphone_log_collection_prefix = ms_strdup(prefix); if (log_enabled) { _open_log_collection_file(); ortp_mutex_unlock(&liblinphone_log_collection_mutex); } } } size_t linphone_core_get_log_collection_max_file_size(void) { return liblinphone_log_collection_max_file_size; } void linphone_core_set_log_collection_max_file_size(size_t size) { liblinphone_log_collection_max_file_size = size; }
981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050
const char *linphone_core_get_log_collection_upload_server_url(LinphoneCore *core) { return linphone_config_get_string(core->config, "misc", "log_collection_upload_server_url", NULL); } void linphone_core_set_log_collection_upload_server_url(LinphoneCore *core, const char *server_url) { linphone_config_set_string(core->config, "misc", "log_collection_upload_server_url", server_url); } LinphoneLogCollectionState linphone_core_log_collection_enabled(void) { return liblinphone_log_collection_state; } void linphone_core_enable_log_collection(LinphoneLogCollectionState state) { if (liblinphone_log_collection_state == state) return; liblinphone_log_collection_state = state; if (state != LinphoneLogCollectionDisabled) { ortp_mutex_init(&liblinphone_log_collection_mutex, NULL); if (state == LinphoneLogCollectionEnabledWithoutPreviousLogHandler) { liblinphone_user_log_func = NULL; /*remove user log handler*/ } bctbx_set_log_handler(liblinphone_current_log_func = linphone_core_log_collection_handler); } else { bctbx_set_log_handler(liblinphone_user_log_func); /*restaure */ } } static void clean_log_collection_upload_context(LinphoneCore *lc) { char *filename = ms_strdup_printf( "%s/%s_log.%s", liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH, liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX, COMPRESSED_LOG_COLLECTION_EXTENSION); unlink(filename); ms_free(filename); if (lc && lc->log_collection_upload_information) { linphone_content_unref(lc->log_collection_upload_information); lc->log_collection_upload_information = NULL; } } static void process_io_error_upload_log_collection(void *data, BCTBX_UNUSED(const belle_sip_io_error_event_t *event)) { LinphoneCore *core = (LinphoneCore *)data; ms_error("I/O Error during log collection upload to %s", linphone_core_get_log_collection_upload_server_url(core)); linphone_core_notify_log_collection_upload_state_changed(core, LinphoneCoreLogCollectionUploadStateNotDelivered, "I/O Error"); clean_log_collection_upload_context(core); } static void process_auth_requested_upload_log_collection(void *data, BCTBX_UNUSED(belle_sip_auth_event_t *event)) { LinphoneCore *core = (LinphoneCore *)data; /* get default identity from core to try to provide credentials */ LinphoneAddress *address = linphone_address_new(linphone_core_get_identity(core)); /* Notes: When connecting to the trace server, the user is already registered on the flexisip server * the requested auth info shall thus be present in linphone core * This request will thus not use the auth requested callback to get the information * - Stored auth information in linphone core are indexed by username/domain */ linphone_core_fill_belle_sip_auth_event(core, event, linphone_address_get_username(address), linphone_address_get_domain(address)); linphone_address_unref(address); } /** * Callback called when posting a log collection file to server (following rcs5.1 recommendation) * @param[in] bh The body handler * @param[in] msg The belle sip message * @param[in] data The user data associated with the handler, contains the LinphoneCore object * @param[in] offset The current position in the input buffer * @param[in] buffer The ouput buffer where to copy the data to be uploaded
1051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120
* @param[in,out] size The size in byte of the data requested, as output it will contain the effective copied size */ static int log_collection_upload_on_send_body(BCTBX_UNUSED(belle_sip_user_body_handler_t *bh), BCTBX_UNUSED(belle_sip_message_t *msg), void *data, size_t offset, uint8_t *buffer, size_t *size) { LinphoneCore *core = (LinphoneCore *)data; /* If we've not reach the end of file yet, fill the buffer with more data */ if (offset < linphone_content_get_size(core->log_collection_upload_information)) { char *log_filename = ms_strdup_printf( "%s/%s_log.%s", liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH, liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX, COMPRESSED_LOG_COLLECTION_EXTENSION); #ifdef HAVE_ZLIB FILE *log_file = fopen(log_filename, "rb"); #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)); } else { *size = fread(buffer, 1, *size, log_file); } fclose(log_file); ms_free(log_filename); return BELLE_SIP_CONTINUE; } else { *size = 0; return BELLE_SIP_STOP; } } /** * Callback called during upload of a log collection to server. * It is just forwarding the call and some parameters to the vtable defined callback. */ static void log_collection_upload_on_progress(BCTBX_UNUSED(belle_sip_body_handler_t *bh), BCTBX_UNUSED(belle_sip_message_t *msg), void *data, size_t offset, size_t total) { LinphoneCore *core = (LinphoneCore *)data; linphone_core_notify_log_collection_upload_progress_indication(core, offset, total); } /** * Callback function called when we have a response from server during the upload of the log collection to the server * (rcs5.1 recommandation) Note: The first post is empty and the server shall reply a 204 (No content) message, this * will trigger a new post request to the server to upload the file. The server response to this second post is * processed by this same function * * @param[in] data The user-defined pointer associated with the request, it contains the LinphoneCore object * @param[in] event The response from server */ static void process_response_from_post_file_log_collection(void *data, const belle_http_response_event_t *event) { LinphoneCore *core = (LinphoneCore *)data; /* Check the answer code */
1121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190
if (event->response) { int code = belle_http_response_get_status_code(event->response); if (code == 204) { /* This is the reply to the first post to the server - an empty file */ /* Start uploading the file */ belle_http_request_listener_callbacks_t cbs = {0}; belle_http_request_listener_t *l; belle_generic_uri_t *uri; belle_http_request_t *req; belle_sip_multipart_body_handler_t *bh; char *ua; char *first_part_header; belle_sip_user_body_handler_t *first_part_bh; linphone_core_notify_log_collection_upload_state_changed( core, LinphoneCoreLogCollectionUploadStateInProgress, "In progress"); /* Temporary storage for the Content-disposition header value */ first_part_header = belle_sip_strdup_printf("form-data; name=\"File\"; filename=\"%s\"", linphone_content_get_name(core->log_collection_upload_information)); /* Create a user body handler to take care of the file and add the content disposition and content-type * headers */ first_part_bh = belle_sip_user_body_handler_new(linphone_content_get_size(core->log_collection_upload_information), NULL, NULL, NULL, log_collection_upload_on_send_body, NULL, core); belle_sip_body_handler_add_header((belle_sip_body_handler_t *)first_part_bh, belle_sip_header_create("Content-disposition", first_part_header)); belle_sip_free(first_part_header); belle_sip_body_handler_add_header( (belle_sip_body_handler_t *)first_part_bh, (belle_sip_header_t *)belle_sip_header_content_type_create( linphone_content_get_type(core->log_collection_upload_information), linphone_content_get_subtype(core->log_collection_upload_information))); /* Insert it in a multipart body handler which will manage the boundaries of multipart message */ bh = belle_sip_multipart_body_handler_new(log_collection_upload_on_progress, core, (belle_sip_body_handler_t *)first_part_bh, NULL); ua = ms_strdup_printf("%s/%s", linphone_core_get_user_agent(core), linphone_core_get_version()); uri = belle_generic_uri_parse(linphone_core_get_log_collection_upload_server_url(core)); req = belle_http_request_create("POST", uri, belle_sip_header_create("User-Agent", ua), NULL); ms_free(ua); belle_sip_message_set_body_handler(BELLE_SIP_MESSAGE(req), BELLE_SIP_BODY_HANDLER(bh)); cbs.process_response = process_response_from_post_file_log_collection; cbs.process_io_error = process_io_error_upload_log_collection; cbs.process_auth_requested = process_auth_requested_upload_log_collection; l = belle_http_request_listener_create_from_callbacks(&cbs, core); belle_sip_object_data_set( BELLE_SIP_OBJECT(req), "http_request_listener", l, belle_sip_object_unref); // Ensure the listener object is destroyed when the request is destroyed belle_http_provider_send_request(core->http_provider, req, l); } else if (code == 200) { /* The file has been uploaded correctly, get the server reply */ const char *body = belle_sip_message_get_body((belle_sip_message_t *)event->response); FileTransferChatMessageModifier fileTransferModifier = FileTransferChatMessageModifier(NULL); FileTransferContent *content = new FileTransferContent(); fileTransferModifier.parseFileTransferXmlIntoContent(body, content); string fileUrl = content->getFileUrl(); if (!fileUrl.empty()) { const char *url = fileUrl.c_str(); linphone_core_notify_log_collection_upload_state_changed( core, LinphoneCoreLogCollectionUploadStateDelivered, url); } delete content; clean_log_collection_upload_context(core); } else { ms_error("Unexpected HTTP response code %i during log collection upload to %s", code, linphone_core_get_log_collection_upload_server_url(core)); linphone_core_notify_log_collection_upload_state_changed(
1191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260
core, LinphoneCoreLogCollectionUploadStateNotDelivered, "Unexpected HTTP response"); clean_log_collection_upload_context(core); } } } #ifdef HAVE_ZLIB #define COMPRESS_FILE_PTR gzFile #define COMPRESS_OPEN gzopen #define COMPRESS_CLOSE gzclose #else #define COMPRESS_FILE_PTR FILE * #define COMPRESS_OPEN fopen #define COMPRESS_CLOSE fclose #endif /** * If zlib is not available the two log files are simply concatenated. */ static int compress_file(FILE *input_file, COMPRESS_FILE_PTR output_file) { char buffer[131072]; /* 128kB */ size_t bytes; size_t total_bytes = 0; while ((bytes = fread(buffer, 1, sizeof(buffer), input_file)) > 0) { #ifdef HAVE_ZLIB int res = gzwrite(output_file, buffer, (unsigned int)bytes); if (res < 0) return 0; total_bytes += (size_t)res; #else total_bytes += fwrite(buffer, 1, bytes, output_file); #endif } return (int)total_bytes; } static int prepare_log_collection_file_to_upload(const char *filename) { char *input_filename = NULL; char *output_filename = NULL; FILE *input_file = NULL; COMPRESS_FILE_PTR output_file = NULL; int ret = 0; ortp_mutex_lock(&liblinphone_log_collection_mutex); output_filename = ms_strdup_printf( "%s/%s", liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH, filename); output_file = COMPRESS_OPEN(output_filename, "wb"); if (output_file == NULL) goto error; input_filename = ms_strdup_printf( "%s/%s1.log", liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH, liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX); input_file = fopen(input_filename, "rb"); if (input_file == NULL) goto error; ret = compress_file(input_file, output_file); if (ret <= 0) goto error; fclose(input_file); ms_free(input_filename); input_filename = ms_strdup_printf( "%s/%s2.log", liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH, liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX); input_file = fopen(input_filename, "rb"); if (input_file != NULL) { ret = compress_file(input_file, output_file); if (ret <= 0) goto error; } error: if (input_file != NULL) fclose(input_file); if (output_file != NULL) COMPRESS_CLOSE(output_file);
1261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330
if (input_filename != NULL) ms_free(input_filename); if (output_filename != NULL) ms_free(output_filename); ortp_mutex_unlock(&liblinphone_log_collection_mutex); return ret; } static size_t get_size_of_file_to_upload(const char *filename) { struct stat statbuf; char *output_filename = ms_strdup_printf( "%s/%s", liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH, filename); FILE *output_file = fopen(output_filename, "rb"); fstat(fileno(output_file), &statbuf); fclose(output_file); ms_free(output_filename); return (size_t)statbuf.st_size; } void linphone_core_upload_log_collection(LinphoneCore *core) { if ((core->log_collection_upload_information == NULL) && (linphone_core_get_log_collection_upload_server_url(core) != NULL) && (liblinphone_log_collection_state != LinphoneLogCollectionDisabled)) { /* open a transaction with the server and send an empty request(RCS5.1 section 3.5.4.8.3.1) */ belle_http_request_listener_callbacks_t cbs = {0}; belle_http_request_listener_t *l; belle_generic_uri_t *uri; 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"); linphone_content_set_subtype(core->log_collection_upload_information, "gzip"); #else linphone_content_set_type(core->log_collection_upload_information, "text"); linphone_content_set_subtype(core->log_collection_upload_information, "plain"); #endif name = ms_strdup_printf("%s_log.%s", liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX, COMPRESSED_LOG_COLLECTION_EXTENSION); linphone_content_set_name(core->log_collection_upload_information, name); if (prepare_log_collection_file_to_upload(name) <= 0) { linphone_content_unref(core->log_collection_upload_information); 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)); 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; cbs.process_auth_requested = process_auth_requested_upload_log_collection;
1331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400
l = belle_http_request_listener_create_from_callbacks(&cbs, core); belle_sip_object_data_set( BELLE_SIP_OBJECT(req), "http_request_listener", l, belle_sip_object_unref); // Ensure the listener object is destroyed when the request is destroyed belle_http_provider_send_request(core->http_provider, req, l); ms_free(name); } else { const char *msg = NULL; ms_warning("Could not upload log collection: log_collection_upload_information=%p, server_url=%s, " "log_collection_state=%d", core->log_collection_upload_information, linphone_core_get_log_collection_upload_server_url(core), liblinphone_log_collection_state); if (core->log_collection_upload_information != NULL) { msg = "Log collection upload already in progress"; } else if (linphone_core_get_log_collection_upload_server_url(core) == NULL) { msg = "Log collection upload server not set"; } else if (liblinphone_log_collection_state == LinphoneLogCollectionDisabled) { msg = "Log collection is disabled"; } else { msg = "Unknown error"; } linphone_core_notify_log_collection_upload_state_changed(core, LinphoneCoreLogCollectionUploadStateNotDelivered, msg); } } char *linphone_core_compress_log_collection(void) { char *filename = NULL; if (liblinphone_log_collection_state == LinphoneLogCollectionDisabled) return NULL; filename = ms_strdup_printf("%s_log.%s", liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX, COMPRESSED_LOG_COLLECTION_EXTENSION); if (prepare_log_collection_file_to_upload(filename) <= 0) { ms_free(filename); return NULL; } ms_free(filename); return ms_strdup_printf( "%s/%s_log.%s", liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH, liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX, COMPRESSED_LOG_COLLECTION_EXTENSION); } void linphone_core_reset_log_collection(void) { char *filename; ortp_mutex_lock(&liblinphone_log_collection_mutex); _close_log_collection_file(); clean_log_collection_upload_context(NULL); filename = ms_strdup_printf( "%s/%s1.log", liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH, liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX); unlink(filename); ms_free(filename); filename = ms_strdup_printf( "%s/%s2.log", liblinphone_log_collection_path ? liblinphone_log_collection_path : LOG_COLLECTION_DEFAULT_PATH, liblinphone_log_collection_prefix ? liblinphone_log_collection_prefix : LOG_COLLECTION_DEFAULT_PREFIX); unlink(filename); ms_free(filename); liblinphone_log_collection_file = NULL; liblinphone_log_collection_file_size = 0; liblinphone_log_collection_max_file_size = LOG_COLLECTION_DEFAULT_MAX_FILE_SIZE; /*also reset size*/ ortp_mutex_unlock(&liblinphone_log_collection_mutex); } void linphone_core_enable_logs(FILE *file) { if (file == NULL) file = stdout; linphone_core_set_log_file(file); linphone_core_set_log_level(ORTP_MESSAGE); }
1401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470
void linphone_core_enable_logs_with_cb(OrtpLogFunc logfunc) { _linphone_core_set_log_handler(logfunc); linphone_core_set_log_level(ORTP_MESSAGE); } void linphone_core_disable_logs(void) { linphone_core_set_log_level(ORTP_ERROR); } void linphone_core_serialize_logs(void) { liblinphone_serialize_logs = TRUE; } static void net_config_read(LinphoneCore *lc) { int tmp; const char *tmpstr; LpConfig *config = lc->config; const char *nat_policy_ref; nat_policy_ref = linphone_config_get_string(lc->config, "net", "nat_policy_ref", NULL); if (nat_policy_ref != NULL) { LinphoneNatPolicy *nat_policy = NULL; /* CAUTION: the nat_policy_ref meaning in default values is different than in usual [nat_policy_%i] section. * This is not consistent and error-prone. * Normally, the nat_policy_ref refers to a "ref" entry within a [nat_policy_%i] section. */ if (linphone_config_has_section(lc->config, nat_policy_ref)) { /* Odd method - to be deprecated, inconsistent */ nat_policy = linphone_core_create_nat_policy_from_config(lc, nat_policy_ref); } else { /* Usual method */ nat_policy = linphone_core_create_nat_policy_from_ref(lc, nat_policy_ref); } if (nat_policy) { linphone_core_set_nat_policy(lc, nat_policy); linphone_nat_policy_unref(nat_policy); } else { bctbx_warning("Failed to create nat policy from ref [%s]", nat_policy_ref); } } if (lc->nat_policy == NULL) { /*this will create a default nat policy according to deprecated config keys, or an empty nat policy otherwise*/ linphone_core_set_firewall_policy(lc, linphone_core_get_firewall_policy(lc)); } lc->net_conf.nat_address_ip = NULL; tmp = linphone_config_get_int(config, "net", "download_bw", 0); linphone_core_set_download_bandwidth(lc, tmp); tmp = linphone_config_get_int(config, "net", "upload_bw", 0); linphone_core_set_upload_bandwidth(lc, tmp); tmp = linphone_config_get_int(config, "net", "expected_bw", 0); linphone_core_set_expected_bandwidth(lc, tmp); tmpstr = linphone_config_get_string(lc->config, "net", "nat_address", NULL); if (tmpstr != NULL && (strlen(tmpstr) < 1)) tmpstr = NULL; linphone_core_set_nat_address(lc, tmpstr); tmp = linphone_config_get_int(lc->config, "net", "nat_sdp_only", 0); lc->net_conf.nat_sdp_only = !!tmp; tmp = linphone_config_get_int(lc->config, "net", "mtu", 1300); linphone_core_set_mtu(lc, tmp); tmp = linphone_config_get_int(lc->config, "net", "download_ptime", -1); if (tmp != -1 && linphone_core_get_download_ptime(lc) != 0) { /*legacy parameter*/ linphone_core_set_download_ptime(lc, tmp); } tmp = linphone_config_get_int(lc->config, "net", "dns_srv_enabled", 1); linphone_core_enable_dns_srv(lc, !!tmp); tmp = linphone_config_get_int(lc->config, "net", "dns_search_enabled", 1);
1471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540
linphone_core_enable_dns_search(lc, !!tmp); // Update existing friend list subscribe state, otherwise change won't be applied until next core creation. bool subscribe_enabled = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->isFriendListSubscriptionEnabled(); L_GET_PRIVATE_FROM_C_OBJECT(lc)->enableFriendListsSubscription(subscribe_enabled); } static void build_sound_devices_table(LinphoneCore *lc) { const char **devices; const char **old; size_t ndev; int i; const bctbx_list_t *elem = ms_snd_card_manager_get_list(ms_factory_get_snd_card_manager(lc->factory)); ndev = bctbx_list_size(elem); devices = reinterpret_cast<const char **>(ms_malloc((ndev + 1) * sizeof(const char *))); for (i = 0; elem != NULL; elem = elem->next, i++) { devices[i] = ms_snd_card_get_string_id((MSSndCard *)elem->data); } devices[ndev] = NULL; old = lc->sound_conf.cards; lc->sound_conf.cards = devices; if (old != NULL) ms_free((void *)old); L_GET_PRIVATE_FROM_C_OBJECT(lc)->computeAudioDevicesList(); } static string get_default_local_ring(LinphoneCore *lc) { if (linphone_core_file_format_supported(lc, "mkv")) { return static_cast<PlatformHelpers *>(lc->platform_helper)->getRingResource(LOCAL_RING_MKV); } return static_cast<PlatformHelpers *>(lc->platform_helper)->getRingResource(LOCAL_RING_WAV); } static string get_default_onhold_music(LinphoneCore *lc) { if (linphone_core_file_format_supported(lc, "mkv")) { return static_cast<PlatformHelpers *>(lc->platform_helper)->getSoundResource(HOLD_MUSIC_MKV); } return static_cast<PlatformHelpers *>(lc->platform_helper)->getSoundResource(HOLD_MUSIC_WAV); } static void sound_config_read(LinphoneCore *lc) { int tmp; const char *tmpbuf; const char *devid; const char *tmpstr; #ifdef __linux__ /*alsadev let the user use custom alsa device within linphone*/ devid = linphone_config_get_string(lc->config, "sound", "alsadev", NULL); if (devid) { MSSndCard *card; const char *delim = ","; size_t l = strlen(devid); char *d = reinterpret_cast<char *>(malloc(l + 1)); char *i; memcpy(d, devid, l + 1); for (l = 0, i = strpbrk(d + l, delim); i; i = strpbrk(d + l, delim)) { char s = *i; *i = '\0'; card = ms_alsa_card_new_custom(d + l, d + l); ms_snd_card_manager_add_card(ms_factory_get_snd_card_manager(lc->factory), card); *i = s; l = (size_t)(i - d) + 1; } if (d[l] != '\0') { card = ms_alsa_card_new_custom(d + l, d + l); ms_snd_card_manager_add_card(ms_factory_get_snd_card_manager(lc->factory), card); } free(d); }
1541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610
tmp = linphone_config_get_int(lc->config, "sound", "alsa_forced_rate", -1); if (tmp > 0) ms_alsa_card_set_forced_sample_rate(tmp); #endif /* retrieve all sound devices */ build_sound_devices_table(lc); #if TARGET_OS_IPHONE tmpbuf = "AQ: Audio Queue Device"; tmpstr = "AU: Audio Unit Receiver"; #else tmpbuf = NULL; tmpstr = NULL; #endif devid = linphone_config_get_string(lc->config, "sound", "playback_dev_id", tmpstr); linphone_core_set_playback_device(lc, devid); devid = linphone_config_get_string(lc->config, "sound", "ringer_dev_id", tmpbuf); linphone_core_set_ringer_device(lc, devid); devid = linphone_config_get_string(lc->config, "sound", "capture_dev_id", tmpstr); linphone_core_set_capture_device(lc, devid); devid = linphone_config_get_string(lc->config, "sound", "media_dev_id", NULL); linphone_core_set_media_device(lc, devid); // Wait to have restored previous sound cards to notify list has been updated // Otherwise app won't be able to change audio device in callback linphone_core_notify_audio_devices_list_updated(lc); /* tmp=linphone_config_get_int(lc->config,"sound","play_lev",80); linphone_core_set_play_level(lc,tmp); tmp=linphone_config_get_int(lc->config,"sound","ring_lev",80); linphone_core_set_ring_level(lc,tmp); tmp=linphone_config_get_int(lc->config,"sound","rec_lev",80); linphone_core_set_rec_level(lc,tmp); tmpbuf=linphone_config_get_string(lc->config,"sound","source","m"); linphone_core_set_sound_source(lc,tmpbuf[0]); */ bool_t default_native_ringing_value = FALSE; #ifdef __ANDROID__ default_native_ringing_value = TRUE; #endif lc->native_ringing_enabled = !!linphone_config_get_int(lc->config, "sound", "use_native_ringing", default_native_ringing_value); tmpbuf = linphone_config_get_string(lc->config, "sound", "local_ring", NULL); if (tmpbuf) { if (bctbx_file_exist(tmpbuf) == 0) { linphone_core_set_ring(lc, tmpbuf); } else { string soundResource = static_cast<PlatformHelpers *>(lc->platform_helper)->getSoundResource(tmpbuf); if (bctbx_file_exist(soundResource.c_str()) == 0) linphone_core_set_ring(lc, soundResource.c_str()); else ms_warning("'%s' ring file does not exist", tmpbuf); } } else { #ifdef __ANDROID__ // Null ring value is allowed, it means using the native ringtone if lc->native_ringing_enabled == true if (!lc->native_ringing_enabled) { ms_warning( "Native ringing has been disabled but no ringtone has been defined in sound config, using default one"); linphone_core_set_ring(lc, get_default_local_ring(lc).c_str()); } #else linphone_core_set_ring(lc, get_default_local_ring(lc).c_str()); #endif } string defaultRemoteRing = static_cast<PlatformHelpers *>(lc->platform_helper)->getSoundResource(REMOTE_RING_WAV);
1611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680
tmpbuf = linphone_config_get_string(lc->config, "sound", "remote_ring", defaultRemoteRing.c_str()); if (bctbx_file_exist(tmpbuf) == -1) { if (tmpbuf && strstr(tmpbuf, ".wav") != NULL) { string soundResource = static_cast<PlatformHelpers *>(lc->platform_helper)->getSoundResource(tmpbuf); if (bctbx_file_exist(soundResource.c_str()) == 0) defaultRemoteRing = soundResource; } tmpbuf = defaultRemoteRing.c_str(); } else if (strstr(tmpbuf, ".wav") == NULL) { /* It currently uses old sound files, so replace them */ tmpbuf = defaultRemoteRing.c_str(); } linphone_core_set_ringback(lc, tmpbuf); tmpbuf = linphone_config_get_string(lc->config, "sound", "hold_music", NULL); if (tmpbuf) { if (bctbx_file_exist(tmpbuf) == 0) { linphone_core_set_play_file(lc, tmpbuf); } else { string soundResource = static_cast<PlatformHelpers *>(lc->platform_helper)->getSoundResource(tmpbuf); if (bctbx_file_exist(soundResource.c_str()) == 0) linphone_core_set_play_file(lc, soundResource.c_str()); else ms_warning("'%s' on-hold music file does not exist", tmpbuf); } } else { linphone_core_set_play_file(lc, get_default_onhold_music(lc).c_str()); } lc->sound_conf.latency = 0; #if !TARGET_OS_IPHONE tmp = TRUE; #else tmp = FALSE; /* on iOS we have builtin echo cancellation.*/ #endif tmp = linphone_config_get_int(lc->config, "sound", "echocancellation", tmp); linphone_core_enable_echo_cancellation(lc, !!tmp); linphone_core_set_echo_canceller_filter_name(lc, linphone_core_get_echo_canceller_filter_name(lc)); linphone_core_enable_echo_limiter(lc, !!linphone_config_get_int(lc->config, "sound", "echolimiter", 0)); linphone_core_enable_agc(lc, !!linphone_config_get_int(lc->config, "sound", "agc", 0)); linphone_core_set_playback_gain_db(lc, linphone_config_get_float(lc->config, "sound", "playback_gain_db", 0)); linphone_core_enable_mic(lc, TRUE); linphone_core_set_mic_gain_db(lc, linphone_config_get_float(lc->config, "sound", "mic_gain_db", 0)); linphone_core_set_disable_record_on_mute( lc, linphone_config_get_bool(lc->config, "sound", "disable_record_on_mute", FALSE)); linphone_core_set_remote_ringback_tone(lc, linphone_config_get_string(lc->config, "sound", "ringback_tone", NULL)); /*just parse requested stream feature once at start to print out eventual errors*/ linphone_core_get_audio_features(lc); } static int _linphone_core_tls_postcheck_callback(void *data, const bctbx_x509_certificate_t *peer_cert) { LinphoneCore *lc = (LinphoneCore *)data; const char *tls_certificate_subject_regexp = linphone_config_get_string(lc->config, "sip", "tls_certificate_subject_regexp", NULL); int ret = 0; if (tls_certificate_subject_regexp) { ret = -1; /*the purpose of this handling is to a peer certificate for which there is no single subject matching the regexp * given in the "tls_certificate_subject_regexp" property. */ bctbx_list_t *subjects = bctbx_x509_certificate_get_subjects(peer_cert); bctbx_list_t *elem; for (elem = subjects; elem != NULL; elem = elem->next) { const char *subject = (const char *)elem->data; ms_message("_linphone_core_tls_postcheck_callback: subject=%s", subject); if (bctbx_is_matching_regex(subject, tls_certificate_subject_regexp)) { ret = 0; ms_message("_linphone_core_tls_postcheck_callback(): successful by matching '%s'", subject); break; } }
1681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750
bctbx_list_free_with_data(subjects, bctbx_free); } if (ret == -1) { ms_message("_linphone_core_tls_postcheck_callback(): postcheck failed, nothing matched."); } return ret; } static void certificates_config_read(LinphoneCore *lc) { string rootCaPath = static_cast<PlatformHelpers *>(lc->platform_helper)->getDataResource("rootca.pem"); const char *rootca = linphone_config_get_string(lc->config, "sip", "root_ca", nullptr); // If rootca is not existing anymore, we try data_resources_dir/rootca.pem else default from belle-sip if (!rootca || ((bctbx_file_exist(rootca) != 0) && !bctbx_directory_exists(rootca))) { // Check root_ca_path if ((bctbx_file_exist(rootCaPath.c_str()) == 0) || bctbx_directory_exists(rootCaPath.c_str())) rootca = rootCaPath.c_str(); else rootca = nullptr; } if (rootca) linphone_core_set_root_ca(lc, rootca); // else use default value from belle-sip linphone_core_verify_server_certificates(lc, !!linphone_config_get_int(lc->config, "sip", "verify_server_certs", TRUE)); linphone_core_verify_server_cn(lc, !!linphone_config_get_int(lc->config, "sip", "verify_server_cn", TRUE)); lc->sal->setTlsPostcheckCallback(_linphone_core_tls_postcheck_callback, lc); } static void bodyless_config_read(LinphoneCore *lc) { // Clean previous friend lists linphone_core_clear_bodyless_friend_lists(lc); bctbx_list_t *bodyless_lists = linphone_config_get_string_list(lc->config, "sip", "bodyless_lists", NULL); while (bodyless_lists) { char *name = (char *)bctbx_list_get_data(bodyless_lists); bodyless_lists = bctbx_list_next(bodyless_lists); LinphoneAddress *addr = linphone_address_new(name); if (!addr) { bctbx_free(name); continue; } ms_message("Found bodyless friend list %s", name); bctbx_free(name); LinphoneFriendList *friendList = linphone_core_create_friend_list(lc); linphone_friend_list_set_subscription_bodyless(friendList, TRUE); // Must be set first to avoid writting database. linphone_friend_list_set_rls_address(friendList, addr); linphone_friend_list_set_display_name(friendList, linphone_address_get_display_name(addr) ? linphone_address_get_display_name(addr) : linphone_address_get_username(addr)); if (!linphone_friend_list_subscriptions_enabled(friendList)) { ms_warning("Newly created bodyless friend list [%p](%s) subscriptions are disabled...", friendList, linphone_friend_list_get_display_name(friendList)); } linphone_address_unref(addr); linphone_core_add_friend_list(lc, friendList); linphone_friend_list_unref(friendList); } } void linphone_core_invalidate_friends_maps(LinphoneCore *lc) { bctbx_list_t *elem; for (elem = lc->friends_lists; elem != NULL; elem = bctbx_list_next(elem)) { LinphoneFriendList *list = (LinphoneFriendList *)bctbx_list_get_data(elem); ms_message("Invalidating friends maps for list [%p]", list); linphone_friend_list_invalidate_friends_maps(list); }
1751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820
} static void sip_config_read(LinphoneCore *lc) { char *contact; const char *tmpstr; LinphoneSipTransports tr; int i, tmp; int ipv6_default = TRUE; if (linphone_config_get_int(lc->config, "sip", "session_expires_value", 0) > 0) { lc->sal->setSessionTimersEnabled(linphone_core_get_session_expires_enabled(lc)); lc->sal->setSessionTimersValue(linphone_core_get_session_expires_value(lc)); lc->sal->setSessionTimersMin(linphone_core_get_session_expires_min_value(lc)); lc->sal->setSessionTimersRefresher(linphone_core_get_session_expires_refresher_value(lc)); } lc->sal->useNoInitialRoute(!!linphone_config_get_int(lc->config, "sip", "use_no_initial_route", 0)); lc->sal->useRport(!!linphone_config_get_int(lc->config, "sip", "use_rport", 1)); L_GET_CPP_PTR_FROM_C_OBJECT(lc)->setSpecs(linphone_config_get_string(lc->config, "sip", "linphone_specs", "")); if (!linphone_config_get_int(lc->config, "sip", "ipv6_migration_done", FALSE) && linphone_config_has_entry(lc->config, "sip", "use_ipv6")) { linphone_config_clean_entry(lc->config, "sip", "use_ipv6"); linphone_config_set_int(lc->config, "sip", "ipv6_migration_done", TRUE); ms_message("IPV6 settings migration done."); } lc->sip_conf.ipv6_enabled = !!linphone_config_get_int(lc->config, "sip", "use_ipv6", ipv6_default); memset(&tr, 0, sizeof(tr)); #if TARGET_OS_MAC /*OSX + IOS*/ || defined(__ANDROID__) tr.udp_port = linphone_config_get_int(lc->config, "sip", "sip_port", LC_SIP_TRANSPORT_DONTBIND); tr.tcp_port = linphone_config_get_int(lc->config, "sip", "sip_tcp_port", LC_SIP_TRANSPORT_DONTBIND); #else tr.udp_port = linphone_config_get_int(lc->config, "sip", "sip_port", 5060); tr.tcp_port = linphone_config_get_int(lc->config, "sip", "sip_tcp_port", 5060); #endif /*we are not listening inbound connection for tls, port has no meaning*/ tr.tls_port = linphone_config_get_int(lc->config, "sip", "sip_tls_port", LC_SIP_TRANSPORT_RANDOM); Sal::setWellKnownPort(linphone_config_get_int(lc->config, "sip", "sip_well_known_port", 5060)); Sal::setTLSWellKnownPort(linphone_config_get_int(lc->config, "sip", "sip_tls_well_known_port", 5061)); certificates_config_read(lc); /*setting the dscp must be done before starting the transports, otherwise it is not taken into effect*/ lc->sal->setDscp(linphone_core_get_sip_dscp(lc)); /*set transport configuration, but do not apply it (do not open sockets). It will be done from * linphone_core_start().*/ _linphone_core_set_sip_transports(lc, &tr, FALSE); tmpstr = linphone_config_get_string(lc->config, "sip", "contact", NULL); if (tmpstr == NULL || linphone_core_set_primary_contact(lc, tmpstr) == -1) { const char *hostname = NULL; const char *username = NULL; char *system_username = NULL; #if !defined(LINPHONE_WINDOWS_UNIVERSAL) && \ !defined(LINPHONE_WINDOWS_PHONE) // Using getenv is forbidden on Windows 10 and Windows Phone hostname = getenv("HOST"); #if defined _WIN32 system_username = getenv("USERNAME"); #else system_username = getenv("USER"); #endif // if defined _WIN32 if (system_username) { char *utf8_username = bctbx_locale_to_utf8(system_username);
1821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890
system_username = belle_sip_uri_to_escaped_username( utf8_username); // Currently, only Windows can have special characters but we try escaping in all case // to be plateform independent bctbx_free(utf8_username); } username = system_username; if (hostname == NULL) hostname = getenv("HOSTNAME"); #endif if (hostname == NULL) hostname = "unknown-host"; if (username == NULL) { username = "linphone"; } contact = ortp_strdup_printf("sip:%s@%s", username, hostname); linphone_core_set_primary_contact(lc, contact); ms_free(contact); bctbx_free(system_username); } tmp = linphone_config_get_int(lc->config, "sip", "guess_hostname", 1); linphone_core_set_guess_hostname(lc, !!tmp); #if defined(__ANDROID__) || TARGET_OS_IPHONE tmp = linphone_config_get_int(lc->config, "sip", "inc_timeout", 45); #else tmp = linphone_config_get_int(lc->config, "sip", "inc_timeout", 30); #endif linphone_core_set_inc_timeout(lc, tmp); tmp = linphone_config_get_int(lc->config, "sip", "push_incoming_call_timeout", 15); lc->sip_conf.push_incoming_call_timeout = tmp; tmp = linphone_config_get_int(lc->config, "sip", "in_call_timeout", 0); linphone_core_set_in_call_timeout(lc, tmp); tmp = linphone_config_get_int(lc->config, "sip", "delayed_timeout", 4); linphone_core_set_delayed_timeout(lc, tmp); tmp = linphone_config_get_int(lc->config, "app", "auto_download_incoming_files_max_size", -1); linphone_core_set_max_size_for_auto_download_incoming_files(lc, tmp); bool_t auto_send_ringing = linphone_config_get_bool(lc->config, "sip", "auto_send_ringing", TRUE); linphone_core_enable_auto_send_ringing(lc, auto_send_ringing); bool_t auto_download_voice_recordings = linphone_config_get_bool(lc->config, "app", "auto_download_incoming_voice_recordings", TRUE); linphone_core_set_auto_download_voice_recordings_enabled(lc, auto_download_voice_recordings); bool_t auto_download_icalendars = linphone_config_get_bool(lc->config, "app", "auto_download_incoming_icalendars", TRUE); linphone_core_set_auto_download_icalendars_enabled(lc, auto_download_icalendars); tmp = linphone_config_get_int(lc->config, "app", "sender_name_hidden_in_forward_message", 0); linphone_core_enable_sender_name_hidden_in_forward_message(lc, !!tmp); tmp = linphone_config_get_int(lc->config, "app", "use_callkit", 0); L_GET_CPP_PTR_FROM_C_OBJECT(lc)->soundcardEnableCallkit(!!tmp); /*In case of remote provisionning, function sip_config_read is initialy called in core_init, then in state * ConfiguringSuccessfull*/ /*Accordingly, to avoid proxy_config to be added twice, it is mandatory to reset proxy config list from * LinphoneCore*/ /*We assume, lc->config contains an accurate list of proxy_config, so no need to keep it from LinphoneCore */ /*Consequence in case of remote provisionning, linphone_core_add_proxy function should not be called before state * GlobalOn*/ linphone_core_clear_proxy_config(lc); /* get proxies config */ for (i = 0;; i++) { LinphoneProxyConfig *cfg = linphone_proxy_config_new_from_config_file(lc, i); if (cfg != NULL) {
1891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960
linphone_core_add_proxy_config(lc, cfg); linphone_proxy_config_unref(cfg); } else { break; } } /* get the default proxy */ tmp = linphone_config_get_int(lc->config, "sip", "default_proxy", -1); linphone_core_set_default_proxy_index(lc, tmp); /* In case of remote provisioning, recompute the phone numbers in case the dial prefix of the default proxy config * has changed */ linphone_core_invalidate_friends_maps(lc); /* read authentication information */ for (i = 0;; i++) { LinphoneAuthInfo *ai = linphone_auth_info_new_from_config_file(lc->config, i); if (ai != NULL) { linphone_core_add_auth_info(lc, ai); linphone_auth_info_unref(ai); } else { break; } } /*this is to filter out unsupported encryption schemes*/ linphone_core_set_media_encryption(lc, linphone_core_get_media_encryption(lc)); /*enable the reconnection to the primary server when it is up again asap*/ lc->sal->enableReconnectToPrimaryAsap(!!linphone_config_get_int(lc->config, "sip", "reconnect_to_primary_asap", 0)); /*for tuning or test*/ lc->sip_conf.sdp_200_ack = !!linphone_config_get_int(lc->config, "sip", "sdp_200_ack", 0); bool_t register_only_when_network_is_up = !!linphone_config_get_int(lc->config, "sip", "register_only_when_network_is_up", 1); linphone_core_set_register_only_when_network_is_up(lc, register_only_when_network_is_up); lc->sip_conf.register_only_when_upnp_is_ok = !!linphone_config_get_int(lc->config, "sip", "register_only_when_upnp_is_ok", 1); lc->sip_conf.ping_with_options = !!linphone_config_get_int(lc->config, "sip", "ping_with_options", 0); lc->sip_conf.auto_net_state_mon = !!linphone_config_get_int(lc->config, "sip", "auto_net_state_mon", 1); lc->sip_conf.keepalive_period = (unsigned int)linphone_config_get_int(lc->config, "sip", "keepalive_period", 30000); lc->sip_conf.tcp_tls_keepalive = !!linphone_config_get_int(lc->config, "sip", "tcp_tls_keepalive", 30000); linphone_core_enable_keep_alive(lc, (lc->sip_conf.keepalive_period > 0)); lc->sal->useOneMatchingCodecPolicy(!!linphone_config_get_int(lc->config, "sip", "only_one_codec", 0)); lc->sal->useDates(!!linphone_config_get_int(lc->config, "sip", "put_date", 0)); lc->sal->enableSipUpdateMethod(!!linphone_config_get_int(lc->config, "sip", "sip_update", 1)); lc->sip_conf.vfu_with_info = !!linphone_config_get_int(lc->config, "sip", "vfu_with_info", 1); linphone_core_set_sip_transport_timeout(lc, linphone_config_get_int(lc->config, "sip", "transport_timeout", 63000)); lc->sal->setSupportedTags( linphone_config_get_string(lc->config, "sip", "supported", "replaces, outbound, gruu, path")); LinphoneSupportLevel level_100rel = linphone_core_get_tag_100rel_support_level(lc); if (level_100rel != LinphoneSupportLevelNoSupport) { linphone_core_add_supported_tag(lc, "100rel"); } lc->sip_conf.save_auth_info = !!linphone_config_get_int(lc->config, "sip", "save_auth_info", 1); lc->sal->setUnreliableConnectionTimeout( linphone_config_get_int(lc->config, "sip", "unreliable_connection_timeout", 120)); bool_t record_aware = linphone_config_get_bool(lc->config, "app", "record_aware", FALSE); linphone_core_set_record_aware_enabled(lc, record_aware); linphone_core_create_im_notif_policy(lc); bodyless_config_read(lc); } static void rtp_config_read(LinphoneCore *lc) { int min_port, max_port; int jitt_comp; int nortp_timeout;
1961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030
bool_t rtp_no_xmit_on_audio_mute; bool_t adaptive_jitt_comp_enabled; const char *tmp; int tmp_int; if (linphone_config_get_range(lc->config, "rtp", "audio_rtp_port", &min_port, &max_port, -1, -1) == TRUE) { if (min_port <= 0 && min_port != -1) min_port = 1; if (max_port > 65535) max_port = 65535; linphone_core_set_audio_port_range(lc, min_port, max_port); } else { min_port = linphone_config_get_int(lc->config, "rtp", "audio_rtp_port", -1); linphone_core_set_audio_port(lc, min_port); } if (linphone_config_get_range(lc->config, "rtp", "video_rtp_port", &min_port, &max_port, -1, -1) == TRUE) { if (min_port <= 0 && min_port != -1) min_port = 1; if (max_port > 65535) max_port = 65535; linphone_core_set_video_port_range(lc, min_port, max_port); } else { min_port = linphone_config_get_int(lc->config, "rtp", "video_rtp_port", -1); linphone_core_set_video_port(lc, min_port); } if (linphone_config_get_range(lc->config, "rtp", "text_rtp_port", &min_port, &max_port, -1, -1) == TRUE) { if (min_port <= 0 && min_port != -1) min_port = 1; if (max_port > 65535) max_port = 65535; linphone_core_set_text_port_range(lc, min_port, max_port); } else { min_port = linphone_config_get_int(lc->config, "rtp", "text_rtp_port", -1); linphone_core_set_text_port(lc, min_port); } jitt_comp = linphone_config_get_int(lc->config, "rtp", "audio_jitt_comp", 60); linphone_core_set_audio_jittcomp(lc, jitt_comp); jitt_comp = linphone_config_get_int(lc->config, "rtp", "video_jitt_comp", 60); if (jitt_comp == 0) jitt_comp = 60; linphone_core_set_video_jittcomp(lc, jitt_comp); nortp_timeout = linphone_config_get_int(lc->config, "rtp", "nortp_timeout", 30); linphone_core_set_nortp_timeout(lc, nortp_timeout); rtp_no_xmit_on_audio_mute = !!linphone_config_get_int(lc->config, "rtp", "rtp_no_xmit_on_audio_mute", FALSE); linphone_core_set_rtp_no_xmit_on_audio_mute(lc, rtp_no_xmit_on_audio_mute); adaptive_jitt_comp_enabled = !!linphone_config_get_int(lc->config, "rtp", "audio_adaptive_jitt_comp_enabled", TRUE); linphone_core_enable_audio_adaptive_jittcomp(lc, adaptive_jitt_comp_enabled); adaptive_jitt_comp_enabled = !!linphone_config_get_int(lc->config, "rtp", "video_adaptive_jitt_comp_enabled", TRUE); linphone_core_enable_video_adaptive_jittcomp(lc, adaptive_jitt_comp_enabled); lc->rtp_conf.disable_upnp = linphone_config_get_int(lc->config, "rtp", "disable_upnp", FALSE); linphone_core_set_avpf_mode( lc, static_cast<LinphoneAVPFMode>(linphone_config_get_int(lc->config, "rtp", "avpf", LinphoneAVPFDisabled))); if ((tmp = linphone_config_get_string(lc->config, "rtp", "audio_multicast_addr", NULL))) linphone_core_set_audio_multicast_addr(lc, tmp); else { if (lc->rtp_conf.audio_multicast_addr) bctbx_free(lc->rtp_conf.audio_multicast_addr); lc->rtp_conf.audio_multicast_addr = ms_strdup("224.1.2.3"); } if ((tmp_int = linphone_config_get_int(lc->config, "rtp", "audio_multicast_enabled", -1)) > -1) linphone_core_enable_audio_multicast(lc, !!tmp_int); if ((tmp_int = linphone_config_get_int(lc->config, "rtp", "audio_multicast_ttl", -1)) > 0) linphone_core_set_audio_multicast_ttl(lc, tmp_int); else lc->rtp_conf.audio_multicast_ttl = 1; /*local network*/ if ((tmp = linphone_config_get_string(lc->config, "rtp", "video_multicast_addr", NULL))) linphone_core_set_video_multicast_addr(lc, tmp); else { if (lc->rtp_conf.video_multicast_addr) bctbx_free(lc->rtp_conf.video_multicast_addr); lc->rtp_conf.video_multicast_addr = ms_strdup("224.1.2.3"); } if ((tmp_int = linphone_config_get_int(lc->config, "rtp", "video_multicast_ttl", -1)) > -1) linphone_core_set_video_multicast_ttl(lc, tmp_int); else lc->rtp_conf.video_multicast_ttl = 1; /*local network*/ if ((tmp_int = linphone_config_get_int(lc->config, "rtp", "video_multicast_enabled", -1)) > 0) linphone_core_enable_video_multicast(lc, !!tmp_int);
2031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100
} static PayloadType *find_payload( const bctbx_list_t *default_list, const char *mime_type, int clock_rate, int channels, const char *recv_fmtp) { PayloadType *candidate = NULL; PayloadType *it; const bctbx_list_t *elem; for (elem = default_list; elem != NULL; elem = elem->next) { it = (PayloadType *)elem->data; if (it != NULL && strcasecmp(mime_type, it->mime_type) == 0 && (clock_rate == it->clock_rate || clock_rate <= 0) && (channels == it->channels || channels <= 0)) { if ((recv_fmtp && it->recv_fmtp && strstr(recv_fmtp, it->recv_fmtp) != NULL) || (recv_fmtp == NULL && it->recv_fmtp == NULL)) { /*exact match*/ if (recv_fmtp) payload_type_set_recv_fmtp(it, recv_fmtp); return it; } else { if (candidate) { if (it->recv_fmtp == NULL) candidate = it; } else candidate = it; } } } if (candidate && recv_fmtp) { payload_type_set_recv_fmtp(candidate, recv_fmtp); } return candidate; } static PayloadType *find_payload_type_from_list(const char *type, int rate, int channels, const bctbx_list_t *from) { const bctbx_list_t *elem; for (elem = from; elem != NULL; elem = elem->next) { PayloadType *pt = (PayloadType *)elem->data; if ((strcasecmp(type, payload_type_get_mime(pt)) == 0) && (rate == LINPHONE_FIND_PAYLOAD_IGNORE_RATE || rate == pt->clock_rate) && (channels == LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS || channels == pt->channels)) { return pt; } } return NULL; } static bool_t linphone_core_codec_supported(LinphoneCore *lc, SalStreamType type, const char *mime) { if (type == SalVideo && lc->codecs_conf.dont_check_video_codec_support) { return TRUE; } else if (type == SalAudio && lc->codecs_conf.dont_check_audio_codec_support) { return TRUE; } else if (type == SalText) { return TRUE; } if (type == SalVideo) { if (lc->video_conf.capture && !lc->video_conf.display) { return ms_factory_has_encoder(lc->factory, mime); } if (lc->video_conf.display && !lc->video_conf.capture) { return ms_factory_has_decoder(lc->factory, mime); } } return ms_factory_codec_supported(lc->factory, mime); } static bool_t get_codec(LinphoneCore *lc, SalStreamType type, int index, PayloadType **ret) { char codeckey[50]; const char *mime, *fmtp; int rate, channels, enabled, bitrate; PayloadType *pt; LpConfig *config = lc->config; *ret = NULL;
2101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170
snprintf(codeckey, 50, "%s_codec_%i", type == SalAudio ? "audio" : type == SalVideo ? "video" : "text", index); mime = linphone_config_get_string(config, codeckey, "mime", NULL); if (mime == NULL || strlen(mime) == 0) return FALSE; rate = linphone_config_get_int(config, codeckey, "rate", 8000); bitrate = linphone_config_get_int(config, codeckey, "bitrate", 0); fmtp = linphone_config_get_string(config, codeckey, "recv_fmtp", NULL); channels = linphone_config_get_int(config, codeckey, "channels", 0); enabled = linphone_config_get_int(config, codeckey, "enabled", 1); mime = linphone_config_get_string(config, codeckey, "mime", NULL); if (!linphone_core_codec_supported(lc, type, mime)) { ms_warning("Codec %s/%i read from conf is not supported by mediastreamer2, ignored.", mime, rate); return TRUE; } pt = find_payload(type == SalAudio ? lc->default_audio_codecs : type == SalVideo ? lc->default_video_codecs : lc->default_text_codecs, mime, rate, channels, fmtp); if (!pt) { bctbx_list_t **default_list = (type == SalAudio) ? &lc->default_audio_codecs : type == SalVideo ? &lc->default_video_codecs : &lc->default_text_codecs; if (type == SalAudio) ms_warning("Codec %s/%i/%i read from conf is not in the default list.", mime, rate, channels); else if (type == SalVideo) ms_warning("Codec %s/%i read from conf is not in the default list.", mime, rate); else ms_warning("Codec %s read from conf is not in the default list.", mime); pt = payload_type_new(); pt->type = (type == SalAudio) ? PAYLOAD_AUDIO_PACKETIZED : type == SalVideo ? PAYLOAD_VIDEO : PAYLOAD_TEXT; pt->mime_type = ortp_strdup(mime); pt->clock_rate = rate; pt->channels = channels; payload_type_set_number(pt, -1); /*dynamic assignment*/ payload_type_set_recv_fmtp(pt, fmtp); *default_list = bctbx_list_append(*default_list, pt); } if (bitrate > 0) { pt->normal_bitrate = bitrate; pt->flags |= PAYLOAD_TYPE_BITRATE_OVERRIDE; } if (enabled) payload_type_set_enable(pt, TRUE); else payload_type_set_enable(pt, FALSE); *ret = pt; return TRUE; } static SalStreamType payload_type_get_stream_type(const PayloadType *pt) { switch (pt->type) { case PAYLOAD_AUDIO_PACKETIZED: case PAYLOAD_AUDIO_CONTINUOUS: return SalAudio; break; case PAYLOAD_VIDEO: return SalVideo; break; case PAYLOAD_TEXT: return SalText; break; } return SalOther; } /*this function merges the payload types from the codec default list with the list read from configuration file. * If a new codec becomes supported in Liblinphone or if the list from configuration file is empty or incomplete, all * the supported codecs are added automatically. This 'l' list is entirely rewritten.*/ static bctbx_list_t *add_missing_supported_codecs(LinphoneCore *lc, const bctbx_list_t *default_list, bctbx_list_t *l) { const bctbx_list_t *elem; ::PayloadType *last_seen = NULL; for (elem = default_list; elem != NULL; elem = elem->next) { bctbx_list_t *elem2 = bctbx_list_find(l, elem->data);
2171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240
if (!elem2) { PayloadType *pt = (PayloadType *)elem->data; /*this codec from default list should be inserted in the list, with respect to the default_list order*/ if (!linphone_core_codec_supported(lc, payload_type_get_stream_type(pt), pt->mime_type)) continue; if (!last_seen) { l = bctbx_list_prepend(l, pt); } else { const bctbx_list_t *after = bctbx_list_find(l, last_seen); l = bctbx_list_insert(l, after->next, pt); } last_seen = pt; ms_message("Supported codec %s/%i fmtp=%s automatically added to codec list.", pt->mime_type, pt->clock_rate, pt->recv_fmtp ? pt->recv_fmtp : ""); } else { last_seen = (PayloadType *)elem2->data; } } return l; } /* * This function adds missing codecs, if required by configuration. * This 'l' list is entirely rewritten if required. */ static bctbx_list_t * handle_missing_codecs(LinphoneCore *lc, const bctbx_list_t *default_list, bctbx_list_t *l, MSFormatType ft) { const char *name = "unknown"; switch (ft) { case MSAudio: name = "add_missing_audio_codecs"; break; case MSVideo: name = "add_missing_video_codecs"; break; case MSText: name = "add_missing_text_codecs"; break; case MSUnknownMedia: break; } if (linphone_config_get_int(lc->config, "misc", name, 1)) return add_missing_supported_codecs(lc, default_list, l); return l; } static bctbx_list_t *codec_append_if_new(bctbx_list_t *l, PayloadType *pt) { bctbx_list_t *elem; for (elem = l; elem != NULL; elem = elem->next) { PayloadType *ept = (PayloadType *)elem->data; if (pt == ept) return l; } l = bctbx_list_append(l, pt); return l; } static void codecs_config_read(LinphoneCore *lc) { int i; PayloadType *pt; bctbx_list_t *audio_codecs = NULL; bctbx_list_t *video_codecs = NULL; bctbx_list_t *text_codecs = NULL; lc->codecs_conf.dyn_pt = 96; /*in rtp io mode, we don't transcode audio, thus we can support a format for which we have no encoder nor decoder.*/ lc->codecs_conf.dont_check_audio_codec_support = linphone_config_get_int(lc->config, "sound", "rtp_io", FALSE); /*in rtp io mode, we don't transcode video, thus we can support a format for which we have no encoder nor decoder.*/ lc->codecs_conf.dont_check_video_codec_support =
2241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310
linphone_config_get_int(lc->config, "video", "rtp_io", FALSE) || linphone_config_get_int(lc->config, "video", "dont_check_codecs", FALSE); for (i = 0; get_codec(lc, SalAudio, i, &pt); i++) { if (pt) { audio_codecs = codec_append_if_new(audio_codecs, pt); } } audio_codecs = handle_missing_codecs(lc, lc->default_audio_codecs, audio_codecs, MSAudio); for (i = 0; get_codec(lc, SalVideo, i, &pt); i++) { if (pt) { video_codecs = codec_append_if_new(video_codecs, pt); } } video_codecs = handle_missing_codecs(lc, lc->default_video_codecs, video_codecs, MSVideo); for (i = 0; get_codec(lc, SalText, i, &pt); i++) { if (pt) { text_codecs = codec_append_if_new(text_codecs, pt); } } text_codecs = add_missing_supported_codecs(lc, lc->default_text_codecs, text_codecs); linphone_core_set_audio_codecs(lc, audio_codecs); linphone_core_set_video_codecs(lc, video_codecs); linphone_core_set_text_codecs(lc, text_codecs); linphone_core_update_allocated_audio_bandwidth(lc); } static void build_video_devices_table(LinphoneCore *lc) { const bctbx_list_t *elem; int i; size_t ndev; const char **devices; if (lc->video_conf.cams) ms_free((void *)lc->video_conf.cams); /* retrieve all video devices */ elem = ms_web_cam_manager_get_list(ms_factory_get_web_cam_manager(lc->factory)); ndev = bctbx_list_size(elem); devices = reinterpret_cast<const char **>(ms_malloc((ndev + 1) * sizeof(const char *))); for (i = 0; elem != NULL; elem = elem->next, i++) { devices[i] = ms_web_cam_get_string_id((MSWebCam *)elem->data); } devices[ndev] = NULL; lc->video_conf.cams = devices; } #ifndef _MSC_VER #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif // _MSC_VER static void video_config_read(LinphoneCore *lc) { #ifdef VIDEO_ENABLED int automatic_video = 1; const char *str; LinphoneVideoPolicy vpol; memset(&vpol, 0, sizeof(LinphoneVideoPolicy)); build_video_devices_table(lc); str = linphone_config_get_string(lc->config, "video", "device", NULL); linphone_core_set_video_device(lc, str); str = linphone_config_get_string(lc->config, "video", "size", "vga"); if (str && str[0] != 0) linphone_core_set_preferred_video_definition_by_name(lc, str); str = linphone_config_get_string(lc->config, "video", "preview_size", NULL); if (str && str[0] != 0) linphone_core_set_preview_video_definition_by_name(lc, str); linphone_core_set_preferred_framerate(lc, linphone_config_get_float(lc->config, "video", "framerate", 0));
2311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380
#if defined(__ANDROID__) || TARGET_OS_IPHONE automatic_video = 0; #endif vpol.automatically_initiate = !!linphone_config_get_int(lc->config, "video", "automatically_initiate", automatic_video); vpol.automatically_accept = !!linphone_config_get_int(lc->config, "video", "automatically_accept", automatic_video); linphone_core_enable_video_capture(lc, !!linphone_config_get_int(lc->config, "video", "capture", 1)); linphone_core_enable_video_display(lc, !!linphone_config_get_int(lc->config, "video", "display", 1)); linphone_core_enable_video_preview(lc, !!linphone_config_get_int(lc->config, "video", "show_local", 0)); linphone_core_enable_self_view(lc, !!linphone_config_get_int(lc->config, "video", "self_view", 1)); linphone_core_enable_video_source_reuse(lc, !!linphone_config_get_int(lc->config, "video", "reuse_source", 0)); linphone_core_set_video_policy(lc, &vpol); lc->video_conf.retransmission_on_nack_enabled = !!linphone_config_get_int(lc->config, "video", "retransmission_on_nack_enabled", 0); #endif } #ifndef _MSC_VER #pragma GCC diagnostic pop #endif // _MSC_VER static void read_friends_from_rc(LinphoneCore *lc) { LinphoneFriend *lf = NULL; LpConfig *config = lc->config; char item[50]; int i = 0; do { sprintf(item, "friend_%i", i); lf = linphone_friend_new_from_config_file(lc, i++); if (lf) { linphone_core_add_friend(lc, lf); linphone_friend_unref(lf); } } while (linphone_config_has_section(config, item)); } static void ui_config_read(LinphoneCore *lc) { if (!lc->friends_db) { read_friends_from_rc(lc); } #ifndef HAVE_DB_STORAGE lc->call_logs = linphone_core_read_call_logs_from_config_file(lc); #endif } bool_t linphone_core_tunnel_available(void) { #ifdef TUNNEL_ENABLED return TRUE; #else return FALSE; #endif } void linphone_core_enable_adaptive_rate_control(LinphoneCore *lc, bool_t enabled) { linphone_config_set_int(lc->config, "net", "adaptive_rate_control", (int)enabled); } bool_t linphone_core_adaptive_rate_control_enabled(const LinphoneCore *lc) { return !!linphone_config_get_int(lc->config, "net", "adaptive_rate_control", TRUE); } void linphone_core_set_adaptive_rate_algorithm(LinphoneCore *lc, const char *algorithm) { if (strcasecmp(algorithm, "basic") != 0 && strcasecmp(algorithm, "advanced") != 0) { ms_warning("Unsupported adaptive rate algorithm [%s] on core [%p], using advanced", algorithm, lc); linphone_core_set_adaptive_rate_algorithm(lc, "advanced"); return; } linphone_config_set_string(lc->config, "net", "adaptive_rate_algorithm", algorithm); }
2381238223832384238523862387238823892390239123922393239423952396239723982399240024012402240324042405240624072408240924102411241224132414241524162417241824192420242124222423242424252426242724282429243024312432243324342435243624372438243924402441244224432444244524462447244824492450
const char *linphone_core_get_adaptive_rate_algorithm(const LinphoneCore *lc) { const char *saved_value = linphone_config_get_string(lc->config, "net", "adaptive_rate_algorithm", "advanced"); if (strcasecmp(saved_value, "basic") != 0 && strcasecmp(saved_value, "advanced") != 0) { ms_warning("Unsupported adaptive rate algorithm [%s] on core [%p]", saved_value, lc); } return saved_value; } bool_t linphone_core_rtcp_enabled(const LinphoneCore *lc) { return !!linphone_config_get_int(lc->config, "rtp", "rtcp_enabled", TRUE); } void linphone_core_set_download_bandwidth(LinphoneCore *lc, int bw) { lc->net_conf.download_bw = bw; linphone_core_update_allocated_audio_bandwidth(lc); if (linphone_core_ready(lc)) linphone_config_set_int(lc->config, "net", "download_bw", bw); } void linphone_core_set_upload_bandwidth(LinphoneCore *lc, int bw) { lc->net_conf.upload_bw = bw; linphone_core_update_allocated_audio_bandwidth(lc); if (linphone_core_ready(lc)) linphone_config_set_int(lc->config, "net", "upload_bw", bw); } void linphone_core_set_expected_bandwidth(LinphoneCore *lc, int bw) { ms_factory_set_expected_bandwidth(lc->factory, bw * 1000); // In linphone we use kbits/s, in ms2 bits/s if (linphone_core_ready(lc)) linphone_config_set_int(lc->config, "net", "expected_bw", bw); } void linphone_core_set_sip_transport_timeout(LinphoneCore *lc, int timeout_ms) { lc->sal->setTransportTimeout(timeout_ms); if (linphone_core_ready(lc)) linphone_config_set_int(lc->config, "sip", "transport_timeout", timeout_ms); } int linphone_core_get_sip_transport_timeout(LinphoneCore *lc) { return lc->sal->getTransportTimeout(); } bool_t linphone_core_get_dns_set_by_app(LinphoneCore *lc) { return lc->dns_set_by_app; } void linphone_core_set_dns_servers_app(LinphoneCore *lc, const bctbx_list_t *servers) { lc->dns_set_by_app = (servers != NULL); linphone_core_set_dns_servers(lc, servers); } void linphone_core_set_dns_servers(LinphoneCore *lc, const bctbx_list_t *servers) { lc->sal->setDnsServers(servers); } void linphone_core_enable_dns_srv(LinphoneCore *lc, bool_t enable) { lc->sal->enableDnsSrv(!!enable); if (linphone_core_ready(lc)) linphone_config_set_int(lc->config, "net", "dns_srv_enabled", enable ? 1 : 0); } bool_t linphone_core_dns_srv_enabled(const LinphoneCore *lc) { return lc->sal->dnsSrvEnabled(); } void linphone_core_enable_dns_search(LinphoneCore *lc, bool_t enable) { lc->sal->enableDnsSearch(!!enable); if (linphone_core_ready(lc)) linphone_config_set_int(lc->config, "net", "dns_search_enabled", enable ? 1 : 0); } bool_t linphone_core_dns_search_enabled(const LinphoneCore *lc) { return lc->sal->dnsSearchEnabled(); }
2451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520
int linphone_core_get_download_bandwidth(const LinphoneCore *lc) { return lc->net_conf.download_bw; } int linphone_core_get_upload_bandwidth(const LinphoneCore *lc) { return lc->net_conf.upload_bw; } void linphone_core_set_download_ptime(LinphoneCore *lc, int ptime) { linphone_config_set_int(lc->config, "rtp", "download_ptime", ptime); } int linphone_core_get_download_ptime(LinphoneCore *lc) { return linphone_config_get_int(lc->config, "rtp", "download_ptime", 0); } void linphone_core_set_upload_ptime(LinphoneCore *lc, int ptime) { linphone_config_set_int(lc->config, "rtp", "upload_ptime", ptime); } int linphone_core_get_upload_ptime(LinphoneCore *lc) { return linphone_config_get_int(lc->config, "rtp", "upload_ptime", 0); } const char *linphone_core_get_version(void) { return liblinphone_version; } static void linphone_core_register_payload_type(LinphoneCore *lc, const PayloadType *const_pt, const char *recv_fmtp, bool_t enabled) { bctbx_list_t **codec_list = const_pt->type == PAYLOAD_VIDEO ? &lc->default_video_codecs : const_pt->type == PAYLOAD_TEXT ? &lc->default_text_codecs : &lc->default_audio_codecs; PayloadType *pt = payload_type_clone(const_pt); int number = -1; payload_type_set_enable(pt, enabled); if (recv_fmtp != NULL) payload_type_set_recv_fmtp(pt, recv_fmtp); /*Set a number to the payload type from the statically defined (RFC3551) profile, if not static, -1 is returned and the payload type number will be determined dynamically later, at call time.*/ payload_type_set_number( pt, (number = rtp_profile_find_payload_number(&av_profile, pt->mime_type, pt->clock_rate, pt->channels))); ms_message("Codec %s/%i fmtp=[%s] number=%i, default enablement: %i) added to the list of possible codecs.", pt->mime_type, pt->clock_rate, pt->recv_fmtp ? pt->recv_fmtp : "", number, (int)payload_type_enabled(pt)); *codec_list = bctbx_list_append(*codec_list, pt); } static void linphone_core_register_static_payloads(LinphoneCore *lc) { RtpProfile *prof = &av_profile; int i; for (i = 0; i < RTP_PROFILE_MAX_PAYLOADS; ++i) { PayloadType *pt = rtp_profile_get_payload(prof, i); if (pt) { #ifndef VIDEO_ENABLED if (pt->type == PAYLOAD_VIDEO) continue; #endif if (find_payload_type_from_list(pt->mime_type, pt->clock_rate, pt->type == PAYLOAD_VIDEO || pt->type == PAYLOAD_TEXT ? LINPHONE_FIND_PAYLOAD_IGNORE_CHANNELS : pt->channels, pt->type == PAYLOAD_VIDEO ? lc->default_video_codecs : pt->type == PAYLOAD_TEXT ? lc->default_text_codecs : lc->default_audio_codecs) == NULL) { linphone_core_register_payload_type(lc, pt, NULL, FALSE); } } } }
2521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590
static void linphone_core_free_payload_types(LinphoneCore *lc) { bctbx_list_free_with_data(lc->default_audio_codecs, (void (*)(void *))payload_type_destroy); bctbx_list_free_with_data(lc->default_video_codecs, (void (*)(void *))payload_type_destroy); bctbx_list_free_with_data(lc->default_text_codecs, (void (*)(void *))payload_type_destroy); lc->default_audio_codecs = NULL; lc->default_video_codecs = NULL; lc->default_text_codecs = NULL; } void linphone_core_set_state(LinphoneCore *lc, LinphoneGlobalState gstate, const char *message) { lc->state = gstate; linphone_core_notify_global_state_changed(lc, gstate, message); } static void misc_config_read(LinphoneCore *lc) { LpConfig *config = lc->config; lc->max_call_logs = linphone_config_get_int(config, "misc", "history_max_size", LINPHONE_MAX_CALL_HISTORY_SIZE); lc->max_calls = linphone_config_get_int(config, "misc", "max_calls", NB_MAX_CALLS); if (lc->user_certificates_path) bctbx_free(lc->user_certificates_path); lc->user_certificates_path = bctbx_strdup( linphone_config_get_string(config, "misc", "user_certificates_path", linphone_factory_get_data_dir(linphone_factory_get(), lc->system_context))); lc->send_call_stats_periodical_updates = !!linphone_config_get_int(config, "misc", "send_call_stats_periodical_updates", 0); const char *contacts_vcard_list_uri = linphone_config_get_string(lc->config, "misc", "contacts-vcard-list", NULL); if (contacts_vcard_list_uri) { if (lc->base_contacts_list_for_synchronization) linphone_friend_list_unref(lc->base_contacts_list_for_synchronization); lc->base_contacts_list_for_synchronization = linphone_core_get_friend_list_by_name(lc, contacts_vcard_list_uri); if (!lc->base_contacts_list_for_synchronization) { // The name (display_name) will be set when the synchronisation is done. lc->base_contacts_list_for_synchronization = linphone_core_create_friend_list(lc); } else linphone_friend_list_ref(lc->base_contacts_list_for_synchronization); linphone_friend_list_set_type(lc->base_contacts_list_for_synchronization, LinphoneFriendListTypeVCard4); linphone_friend_list_synchronize_friends_from_server(lc->base_contacts_list_for_synchronization); } } void linphone_core_reload_ms_plugins(LinphoneCore *lc, const char *path) { if (path) ms_factory_set_plugins_dir(lc->factory, path); ms_factory_init_plugins(lc->factory); codecs_config_read(lc); } static void _linphone_core_read_config(LinphoneCore *lc) { sip_setup_register_all(lc->factory); sound_config_read(lc); net_config_read(lc); rtp_config_read(lc); codecs_config_read(lc); sip_config_read(lc); video_config_read(lc); // autoreplier_config_init(&lc->autoreplier_conf); misc_config_read(lc); ui_config_read(lc); #ifdef TUNNEL_ENABLED if (lc->tunnel) { linphone_tunnel_configure(lc->tunnel); } #endif { LinphoneDigestAuthenticationPolicy *policy = linphone_digest_authentication_policy_new_from_config(lc->config); linphone_core_set_digest_authentication_policy(lc, policy);
2591259225932594259525962597259825992600260126022603260426052606260726082609261026112612261326142615261626172618261926202621262226232624262526262627262826292630263126322633263426352636263726382639264026412642264326442645264626472648264926502651265226532654265526562657265826592660
linphone_digest_authentication_policy_unref(policy); } lc->auto_net_state_mon = lc->sip_conf.auto_net_state_mon; } static void linphone_core_reload_lime(LinphoneCore *lc) { if (linphone_core_lime_x3dh_available(lc)) { bool limeEnabled = linphone_config_get_bool(lc->config, "lime", "enabled", TRUE); if (linphone_core_lime_x3dh_enabled(lc)) { linphone_core_enable_lime_x3dh(lc, FALSE); } if (limeEnabled) { linphone_core_enable_lime_x3dh(lc, TRUE); } } } void linphone_core_load_config_from_xml(LinphoneCore *lc, const char *xml_uri) { // As for today assume the URI is a local file const char *error = linphone_config_load_from_xml_file(lc->config, xml_uri); if (error) { bctbx_error("Couldn't load config from xml: %s", error); return; } // To apply any changes to LIME configuration linphone_core_reload_lime(lc); } void linphone_configuring_terminated(LinphoneCore *lc, LinphoneConfiguringState state, const char *message) { linphone_core_notify_configuring_status(lc, state, message); if (state == LinphoneConfiguringSuccessful) { if (linphone_core_is_provisioning_transient(lc)) { linphone_core_set_provisioning_uri(lc, NULL); } _linphone_core_read_config(lc); // To apply any changes to LIME configuration linphone_core_reload_lime(lc); } if (lc->provisioning_http_listener) { belle_sip_object_unref(lc->provisioning_http_listener); lc->provisioning_http_listener = NULL; } _linphone_core_apply_transports(lc); // This will create SIP sockets. L_GET_PRIVATE_FROM_C_OBJECT(lc)->initEphemeralMessages(); L_GET_PRIVATE_FROM_C_OBJECT(lc)->reloadLdapList(); linphone_core_set_state(lc, LinphoneGlobalOn, "On"); } static int linphone_core_serialization_ref = 0; static void linphone_core_activate_log_serialization_if_needed(void) { if (liblinphone_serialize_logs == TRUE) { linphone_core_serialization_ref++; if (linphone_core_serialization_ref == 1) ortp_set_log_thread_id(ortp_thread_self()); } } static void linphone_core_deactivate_log_serialization_if_needed(void) { if (liblinphone_serialize_logs == TRUE) { --linphone_core_serialization_ref; if (linphone_core_serialization_ref == 0) ortp_set_log_thread_id(0); } }
2661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730
static void linphone_core_register_default_codecs(LinphoneCore *lc) { const char *aac_fmtp162248, *aac_fmtp3244; bool_t opus_enabled = TRUE; /*default enabled audio codecs, in order of preference*/ #if defined(__arm__) || defined(_M_ARM) /*hack for opus, that needs to be disabed by default on ARM single processor, otherwise there is no cpu left for * video processing*/ // if (ms_get_cpu_count()==1) opus_enabled=FALSE; if (ms_factory_get_cpu_count(lc->factory) == 1) opus_enabled = FALSE; #endif linphone_core_register_payload_type(lc, &payload_type_opus, "useinbandfec=1", opus_enabled); linphone_core_register_payload_type(lc, &payload_type_silk_wb, NULL, TRUE); linphone_core_register_payload_type(lc, &payload_type_speex_wb, "vbr=on", TRUE); linphone_core_register_payload_type(lc, &payload_type_speex_nb, "vbr=on", TRUE); linphone_core_register_payload_type(lc, &payload_type_pcmu8000, NULL, TRUE); linphone_core_register_payload_type(lc, &payload_type_pcma8000, NULL, TRUE); /* Text codecs in order or preference (RED first (more robust), then T140) */ linphone_core_register_payload_type(lc, &payload_type_t140_red, NULL, TRUE); linphone_core_register_payload_type(lc, &payload_type_t140, NULL, TRUE); /*other audio codecs, not enabled by default, in order of preference*/ linphone_core_register_payload_type(lc, &payload_type_gsm, NULL, FALSE); linphone_core_register_payload_type(lc, &payload_type_g722, NULL, FALSE); linphone_core_register_payload_type(lc, &payload_type_ilbc, "mode=30", FALSE); linphone_core_register_payload_type(lc, &payload_type_amr, "octet-align=1", FALSE); linphone_core_register_payload_type(lc, &payload_type_amrwb, "octet-align=1", FALSE); linphone_core_register_payload_type(lc, &payload_type_g729, "annexb=yes", TRUE); /* For AAC, we use a config value to determine if we ought to support SBR. Since it is not offically supported * for the mpeg4-generic mime type, setting this flag to 1 will break compatibility with other clients. */ if (linphone_config_get_int(lc->config, "misc", "aac_use_sbr", FALSE)) { ms_message("Using SBR for AAC"); aac_fmtp162248 = "config=F8EE2000; constantDuration=512; indexDeltaLength=3; indexLength=3; mode=AAC-hbr; " "profile-level-id=76; sizeLength=13; streamType=5; SBR-enabled=1"; aac_fmtp3244 = "config=F8E82000; constantDuration=512; indexDeltaLength=3; indexLength=3; mode=AAC-hbr; " "profile-level-id=76; sizeLength=13; streamType=5; SBR-enabled=1"; } else { aac_fmtp162248 = "config=F8EE2000; constantDuration=512; indexDeltaLength=3; indexLength=3; mode=AAC-hbr; " "profile-level-id=76; sizeLength=13; streamType=5"; aac_fmtp3244 = "config=F8E82000; constantDuration=512; indexDeltaLength=3; indexLength=3; mode=AAC-hbr; " "profile-level-id=76; sizeLength=13; streamType=5"; } linphone_core_register_payload_type(lc, &payload_type_aaceld_16k, aac_fmtp162248, FALSE); linphone_core_register_payload_type(lc, &payload_type_aaceld_22k, aac_fmtp162248, FALSE); linphone_core_register_payload_type(lc, &payload_type_aaceld_32k, aac_fmtp3244, FALSE); linphone_core_register_payload_type(lc, &payload_type_aaceld_44k, aac_fmtp3244, FALSE); linphone_core_register_payload_type(lc, &payload_type_aaceld_48k, aac_fmtp162248, FALSE); linphone_core_register_payload_type(lc, &payload_type_isac, NULL, FALSE); linphone_core_register_payload_type(lc, &payload_type_speex_uwb, "vbr=on", FALSE); linphone_core_register_payload_type(lc, &payload_type_silk_nb, NULL, FALSE); linphone_core_register_payload_type(lc, &payload_type_silk_mb, NULL, FALSE); linphone_core_register_payload_type(lc, &payload_type_silk_swb, NULL, FALSE); linphone_core_register_payload_type(lc, &payload_type_g726_16, NULL, FALSE); linphone_core_register_payload_type(lc, &payload_type_g726_24, NULL, FALSE); linphone_core_register_payload_type(lc, &payload_type_g726_32, NULL, FALSE); linphone_core_register_payload_type(lc, &payload_type_g726_40, NULL, FALSE); linphone_core_register_payload_type(lc, &payload_type_aal2_g726_16, NULL, FALSE); linphone_core_register_payload_type(lc, &payload_type_aal2_g726_24, NULL, FALSE); linphone_core_register_payload_type(lc, &payload_type_aal2_g726_32, NULL, FALSE); linphone_core_register_payload_type(lc, &payload_type_aal2_g726_40, NULL, FALSE); linphone_core_register_payload_type(lc, &payload_type_codec2, NULL, FALSE); linphone_core_register_payload_type(lc, &payload_type_bv16, NULL, FALSE); #ifdef VIDEO_ENABLED /*default enabled video codecs, in order of preference*/ linphone_core_register_payload_type(lc, &payload_type_av1, NULL, TRUE); linphone_core_register_payload_type(lc, &payload_type_vp8, NULL, TRUE); linphone_core_register_payload_type(lc, &payload_type_h264, "profile-level-id=42801F", TRUE); linphone_core_register_payload_type(lc, &payload_type_h265, NULL, TRUE);
2731273227332734273527362737273827392740274127422743274427452746274727482749275027512752275327542755275627572758275927602761276227632764276527662767276827692770277127722773277427752776277727782779278027812782278327842785278627872788278927902791279227932794279527962797279827992800
linphone_core_register_payload_type(lc, &payload_type_mp4v, "profile-level-id=3", TRUE); linphone_core_register_payload_type(lc, &payload_type_h263_1998, "CIF=1;QCIF=1", FALSE); linphone_core_register_payload_type(lc, &payload_type_h263, NULL, FALSE); #endif /*register all static payload types declared in av_profile of oRTP, if not already declared above*/ linphone_core_register_static_payloads(lc); } static void linphone_core_internal_notify_received(LinphoneCore *lc, LinphoneEvent *lev, const char *notified_event, const LinphoneContent *body) { if (strcmp(notified_event, "Presence") == 0) { for (const bctbx_list_t *it = linphone_core_get_friends_lists(lc); it; it = bctbx_list_next(it)) { LinphoneFriendList *list = reinterpret_cast<LinphoneFriendList *>(bctbx_list_get_data(it)); if (list->event != lev) continue; ms_message("Notify presence for list %p", list); linphone_friend_list_notify_presence_received(list, lev, body); } } else if (strcmp(notified_event, "conference") == 0) { #ifdef HAVE_ADVANCED_IM const auto ev = Event::toCpp(lev)->getSharedFromThis(); const auto resourceAddr = ev->getResource(); const auto resourceAddrUri = resourceAddr->asStringUriOnly(); const bctbx_list_t *elem; for (elem = linphone_core_get_proxy_config_list(lc); elem != NULL; elem = elem->next) { LinphoneProxyConfig *proxy = (LinphoneProxyConfig *)elem->data; const char *factoryUri = linphone_proxy_config_get_conference_factory_uri(proxy); if (factoryUri && (strcmp(resourceAddrUri.c_str(), factoryUri) == 0)) { L_GET_PRIVATE_FROM_C_OBJECT(lc)->remoteListEventHandler->notifyReceived( ev, body ? L_GET_CPP_PTR_FROM_C_OBJECT(body) : nullptr); return; } } const auto fromAddr = ev->getFrom(); LinphonePrivate::ConferenceId conferenceId = LinphonePrivate::ConferenceId(resourceAddr, fromAddr); shared_ptr<AbstractChatRoom> chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(conferenceId); shared_ptr<MediaConference::Conference> audioVideoConference = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findAudioVideoConference(conferenceId); Content content = body ? *L_GET_CPP_PTR_FROM_C_OBJECT(body) : Content(); if (chatRoom) { shared_ptr<ClientGroupChatRoom> cgcr; if (chatRoom->getCapabilities() & ChatRoom::Capabilities::Proxy) cgcr = static_pointer_cast<ClientGroupChatRoom>( static_pointer_cast<ClientGroupToBasicChatRoom>(chatRoom)->getProxiedChatRoom()); else cgcr = static_pointer_cast<ClientGroupChatRoom>(chatRoom); if (body && linphone_content_is_multipart(body)) { L_GET_PRIVATE(cgcr)->multipartNotifyReceived(ev, content); } else { L_GET_PRIVATE(cgcr)->notifyReceived(ev, content); } } else if (audioVideoConference) { shared_ptr<MediaConference::RemoteConference> conference = static_pointer_cast<MediaConference::RemoteConference>(audioVideoConference); if (body && linphone_content_is_multipart(body)) { conference->multipartNotifyReceived(ev, content); } else { conference->notifyReceived(ev, content); } } #else ms_message("Advanced IM such as group chat is disabled!"); #endif } }
2801280228032804280528062807280828092810281128122813281428152816281728182819282028212822282328242825282628272828282928302831283228332834283528362837283828392840284128422843284428452846284728482849285028512852285328542855285628572858285928602861286228632864286528662867286828692870
#ifndef _MSC_VER #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif // _MSC_VER static void _linphone_core_conference_subscribe_received(LinphoneCore *lc, LinphoneEvent *lev, const LinphoneContent *body) { #ifdef HAVE_ADVANCED_IM if (body && linphone_event_get_custom_header(lev, "Content-Disposition") && strcasecmp(linphone_event_get_custom_header(lev, "Content-Disposition"), "recipient-list") == 0) { // List subscription auto evSub = dynamic_pointer_cast<EventSubscribe>(Event::toCpp(lev)->getSharedFromThis()); L_GET_PRIVATE_FROM_C_OBJECT(lc)->localListEventHandler->subscribeReceived(evSub, body); return; } const LinphoneAddress *resource = linphone_event_get_resource(lev); const std::shared_ptr<Address> conferenceAddress = Address::toCpp(const_cast<LinphoneAddress *>(resource))->getSharedFromThis(); LinphonePrivate::ConferenceId conferenceId = LinphonePrivate::ConferenceId(conferenceAddress, conferenceAddress); shared_ptr<AbstractChatRoom> chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(conferenceId); shared_ptr<MediaConference::Conference> audioVideoConference = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findAudioVideoConference(conferenceId); auto evSub = dynamic_pointer_cast<EventSubscribe>(Event::toCpp(lev)->getSharedFromThis()); if (chatRoom) static_pointer_cast<ServerGroupChatRoom>(chatRoom)->subscribeReceived(evSub); else if (audioVideoConference) static_pointer_cast<MediaConference::LocalConference>(audioVideoConference)->subscribeReceived(evSub); else linphone_event_deny_subscription(lev, LinphoneReasonDeclined); #else // !HAVE_ADVANCED_IM linphone_event_deny_subscription(lev, LinphoneReasonNotAcceptable); ms_warning("Advanced IM such as group chat is disabled!"); #endif // HAVE_ADVANCED_IM } #ifndef _MSC_VER #pragma GCC diagnostic pop #endif // _MSC_VER static void linphone_core_internal_subscribe_received(LinphoneCore *lc, LinphoneEvent *lev, BCTBX_UNUSED(const char *subscribe_event), const LinphoneContent *body) { if (strcmp(linphone_event_get_name(lev), "conference") == 0) { _linphone_core_conference_subscribe_received(lc, lev, body); } } #ifndef _MSC_VER #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif // _MSC_VER static void _linphone_core_conference_subscription_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state) { #ifdef HAVE_ADVANCED_IM auto evSub = dynamic_pointer_cast<EventSubscribe>(Event::toCpp(lev)->getSharedFromThis()); if (!linphone_core_conference_server_enabled(lc)) { /* Liblinphone in a client application. */ auto handler = evSub->getProperty("event-handler-private").getValue<RemoteConferenceEventHandler *>(); if (handler) { switch (state) { case LinphoneSubscriptionError: case LinphoneSubscriptionTerminated: handler->invalidateSubscription(); break; default: break; } } } else { /* This has to be done only when running as server */ const auto &conferenceAddress = evSub->getResource();
2871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940
LinphonePrivate::ConferenceId conferenceId = LinphonePrivate::ConferenceId(conferenceAddress, conferenceAddress); shared_ptr<AbstractChatRoom> chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(conferenceId); shared_ptr<MediaConference::Conference> audioVideoConference = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findAudioVideoConference(conferenceId); if (chatRoom) L_GET_PRIVATE(static_pointer_cast<ServerGroupChatRoom>(chatRoom))->subscriptionStateChanged(evSub, state); else if (audioVideoConference) static_pointer_cast<MediaConference::LocalConference>(audioVideoConference) ->subscriptionStateChanged(evSub, state); } #else ms_warning("Advanced IM such as group chat is disabled!"); #endif } #ifndef _MSC_VER #pragma GCC diagnostic pop #endif // _MSC_VER static void linphone_core_internal_subscription_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphoneSubscriptionState state) { if (strcasecmp(linphone_event_get_name(lev), "Presence") == 0) { linphone_friend_list_subscription_state_changed(lc, lev, state); } else if (strcmp(linphone_event_get_name(lev), "conference") == 0) { _linphone_core_conference_subscription_state_changed(lc, lev, state); } } static void linphone_core_internal_publish_state_changed(LinphoneCore *lc, LinphoneEvent *lev, LinphonePublishState state) { if (strcasecmp(linphone_event_get_name(lev), "Presence") == 0) { const bctbx_list_t *accs = linphone_core_get_account_list(lc); const bctbx_list_t *item; for (item = accs; item != NULL; item = bctbx_list_next(item)) { LinphoneAccount *acc = (LinphoneAccount *)bctbx_list_get_data(item); if (Account::toCpp(acc)->getPresencePublishEvent()->toC() == lev) { Account::toCpp(acc)->notifyPublishStateChanged(state); break; } } } } void linphone_core_set_account_creator_url(LinphoneCore *lc, const char *url) { linphone_config_set_string(lc->config, "account_creator", "url", url); } const char *linphone_core_get_account_creator_url(LinphoneCore *lc) { return linphone_config_get_string(lc->config, "account_creator", "url", NULL); } void linphone_core_set_account_creator_backend(LinphoneCore *lc, LinphoneAccountCreatorBackend backend) { linphone_config_set_int(lc->config, "account_creator", "backend", (int)backend); } LinphoneAccountCreatorBackend linphone_core_get_account_creator_backend(const LinphoneCore *lc) { return (LinphoneAccountCreatorBackend)linphone_config_get_int(lc->config, "account_creator", "backend", (int)LinphoneAccountCreatorBackendXMLRPC); } static void _linphone_core_init_account_creator_service(LinphoneCore *lc) { LinphoneAccountCreatorService *service = linphone_account_creator_service_new(); #ifdef HAVE_FLEXIAPI if (linphone_core_get_account_creator_backend(lc) == LinphoneAccountCreatorBackendXMLRPC) { #endif linphone_account_creator_service_set_constructor_cb(service, linphone_account_creator_constructor_linphone_xmlrpc); linphone_account_creator_service_set_destructor_cb(service, NULL);
2941294229432944294529462947294829492950295129522953295429552956295729582959296029612962296329642965296629672968296929702971297229732974297529762977297829792980298129822983298429852986298729882989299029912992299329942995299629972998299930003001300230033004300530063007300830093010
linphone_account_creator_service_set_is_account_exist_cb( service, linphone_account_creator_is_account_exist_linphone_xmlrpc); linphone_account_creator_service_set_activate_account_cb( service, linphone_account_creator_activate_phone_account_linphone_xmlrpc); linphone_account_creator_service_set_is_account_activated_cb( service, linphone_account_creator_is_account_activated_linphone_xmlrpc); linphone_account_creator_service_set_link_account_cb( service, linphone_account_creator_link_phone_number_with_account_linphone_xmlrpc); linphone_account_creator_service_set_activate_alias_cb( service, linphone_account_creator_activate_phone_number_link_linphone_xmlrpc); linphone_account_creator_service_set_is_account_linked_cb( service, linphone_account_creator_is_account_linked_linphone_xmlrpc); linphone_account_creator_service_set_update_account_cb( service, linphone_account_creator_update_password_linphone_xmlrpc); linphone_account_creator_service_set_confirmation_key_cb( service, linphone_account_creator_get_confirmation_key_linphone_xmlrpc); // XMLRPC specific endpoints linphone_account_creator_service_set_create_account_cb(service, linphone_account_creator_create_account_linphone_xmlrpc); linphone_account_creator_service_set_recover_account_cb( service, linphone_account_creator_recover_phone_account_linphone_xmlrpc); linphone_account_creator_service_set_is_alias_used_cb( service, linphone_account_creator_is_phone_number_used_linphone_xmlrpc); linphone_account_creator_service_set_login_linphone_account_cb( service, linphone_account_creator_login_linphone_account_linphone_xmlrpc); #ifdef HAVE_FLEXIAPI } else { linphone_account_creator_service_set_constructor_cb(service, NULL); linphone_account_creator_service_set_destructor_cb(service, NULL); linphone_account_creator_service_set_is_account_exist_cb(service, linphone_account_creator_is_account_exist_flexiapi); linphone_account_creator_service_set_activate_account_cb( service, linphone_account_creator_activate_phone_account_flexiapi); linphone_account_creator_service_set_is_account_activated_cb( service, linphone_account_creator_is_account_activated_flexiapi); linphone_account_creator_service_set_link_account_cb( service, linphone_account_creator_link_phone_number_with_account_flexiapi); linphone_account_creator_service_set_activate_alias_cb( service, linphone_account_creator_activate_phone_number_link_flexiapi); linphone_account_creator_service_set_is_account_linked_cb(service, linphone_account_creator_is_account_linked_flexiapi); linphone_account_creator_service_set_update_account_cb(service, linphone_account_creator_update_password_flexiapi); linphone_account_creator_service_set_is_alias_used_cb(service, linphone_account_creator_is_phone_number_used_flexiapi); // FlexiAPI specific endpoints linphone_account_creator_service_set_send_token_cb(service, linphone_account_creator_send_token_flexiapi); linphone_account_creator_service_set_account_creation_request_token_cb( service, linphone_account_creator_account_creation_request_token_flexiapi); linphone_account_creator_service_set_account_creation_token_using_request_token_cb( service, linphone_account_creator_account_creation_token_using_request_token_flexiapi); linphone_account_creator_service_set_create_account_cb( service, linphone_account_creator_create_account_with_token_flexiapi); linphone_account_creator_service_set_recover_account_cb( service, linphone_account_creator_recover_phone_account_flexiapi); linphone_account_creator_service_set_login_linphone_account_cb( service, linphone_account_creator_login_linphone_account_flexiapi); } #endif linphone_core_set_account_creator_service(lc, service); } bool_t linphone_core_is_push_notification_available(LinphoneCore *core) { bctbx_list_t *accounts = (bctbx_list_t *)linphone_core_get_account_list(core); for (; accounts != NULL; accounts = accounts->next) { LinphoneAccount *account = (LinphoneAccount *)accounts->data;
3011301230133014301530163017301830193020302130223023302430253026302730283029303030313032303330343035303630373038303930403041304230433044304530463047304830493050305130523053305430553056305730583059306030613062306330643065306630673068306930703071307230733074307530763077307830793080
if (!linphone_account_params_is_push_notification_available(linphone_account_get_params(account))) return FALSE; } // Check that at least prid is available to consider push notifications as available const char *prid = linphone_push_notification_config_get_prid(core->push_config); return (prid != NULL && strcmp(prid, "") != 0); } const LinphonePushNotificationConfig *linphone_core_get_push_notification_config(const LinphoneCore *core) { return core->push_config; } void linphone_core_set_push_notification_config(LinphoneCore *core, LinphonePushNotificationConfig *config) { if (core->push_config) { linphone_push_notification_config_unref(core->push_config); core->push_config = NULL; } if (config) { core->push_config = linphone_push_notification_config_ref(config); } } void linphone_core_update_push_notification_information(LinphoneCore *core, const char *param, const char *prid) { linphone_push_notification_config_set_param(core->push_config, param); linphone_push_notification_config_set_prid(core->push_config, prid); bctbx_list_t *accounts = (bctbx_list_t *)linphone_core_get_account_list(core); for (; accounts != NULL; accounts = accounts->next) { LinphoneAccount *account = (LinphoneAccount *)accounts->data; LinphoneAccountParams *newParams = linphone_account_params_clone(linphone_account_get_params(account)); LinphonePushNotificationConfig *push_cfg = linphone_account_params_get_push_notification_config(newParams); linphone_push_notification_config_set_param(push_cfg, param); linphone_push_notification_config_set_prid(push_cfg, prid); linphone_account_set_params(account, newParams); linphone_account_params_unref(newParams); } ms_message("Push notification information updated: param [%s], prid [%s]", param, prid); } void linphone_core_set_push_notification_enabled(LinphoneCore *core, bool_t enable) { linphone_core_enable_push_notification(core, enable); } void linphone_core_enable_push_notification(LinphoneCore *core, bool_t enable) { if (core->push_notification_enabled != enable) { linphone_config_set_int(core->config, "net", "push_notification", enable); core->push_notification_enabled = enable; bctbx_list_t *accounts = (bctbx_list_t *)linphone_core_get_account_list(core); for (; accounts != NULL; accounts = accounts->next) { Account *account = Account::toCpp((LinphoneAccount *)accounts->data); if (account->getAccountParams()->isPushNotificationAvailable()) { account->setNeedToRegister(true); } } } } bool_t linphone_core_is_push_notification_enabled(LinphoneCore *core) { return linphone_core_push_notification_enabled(core); } bool_t linphone_core_push_notification_enabled(LinphoneCore *core) { return core->push_notification_enabled; } void linphone_core_did_register_for_remote_push(LinphoneCore *lc, void *device_token) { getPlatformHelpers(lc)->didRegisterForRemotePush(device_token); } void linphone_core_did_register_for_remote_push_with_stringified_token(LinphoneCore *lc, const char *device_token_str) {
3081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150
getPlatformHelpers(lc)->didRegisterForRemotePushWithStringifiedToken(device_token_str); } void linphone_core_set_auto_iterate_enabled(LinphoneCore *core, bool_t enable) { linphone_core_enable_auto_iterate(core, enable); } void linphone_core_enable_auto_iterate(LinphoneCore *core, bool_t enable) { linphone_config_set_int(core->config, "misc", "auto_iterate", enable); core->auto_iterate_enabled = enable; getPlatformHelpers(core)->enableAutoIterate(enable); } bool_t linphone_core_is_auto_iterate_enabled(const LinphoneCore *core) { return linphone_core_auto_iterate_enabled(core); } bool_t linphone_core_auto_iterate_enabled(const LinphoneCore *core) { return core->auto_iterate_enabled; } int linphone_core_get_auto_iterate_foreground_schedule(const LinphoneCore *core) { return linphone_config_get_int(core->config, "misc", "auto_iterate_foreground_schedule", 20); } void linphone_core_set_auto_iterate_foreground_schedule(LinphoneCore *core, int schedule) { linphone_config_set_int(core->config, "misc", "auto_iterate_foreground_schedule", schedule); } int linphone_core_get_auto_iterate_background_schedule(const LinphoneCore *core) { return linphone_config_get_int(core->config, "misc", "auto_iterate_background_schedule", 500); } void linphone_core_set_auto_iterate_background_schedule(LinphoneCore *core, int schedule) { linphone_config_set_int(core->config, "misc", "auto_iterate_background_schedule", schedule); } void linphone_core_set_vibration_on_incoming_call_enabled(LinphoneCore *core, bool_t enable) { linphone_core_enable_vibration_on_incoming_call(core, enable); } void linphone_core_enable_vibration_on_incoming_call(LinphoneCore *core, bool_t enable) { linphone_config_set_int(core->config, "misc", "vibrate_on_incoming_call", enable); core->vibrate_on_incoming_call = enable; } bool_t linphone_core_is_vibration_on_incoming_call_enabled(LinphoneCore *core) { return linphone_core_vibration_on_incoming_call_enabled(core); } bool_t linphone_core_vibration_on_incoming_call_enabled(LinphoneCore *core) { return core->vibrate_on_incoming_call; } static void linphone_core_init(LinphoneCore *lc, LinphoneCoreCbs *cbs, LpConfig *config, void *userdata, BCTBX_UNUSED(void *system_context), bool_t automatically_start) { LinphoneFactory *lfactory = linphone_factory_get(); LinphoneCoreCbs *internal_cbs = _linphone_core_cbs_new(); const char *msplugins_dir; const char *image_resources_dir; bctbx_init_logger(FALSE); if (!linphone_config_get_bool(config, "logging", "disable_stdout", FALSE) && liblinphone_user_log_func && liblinphone_current_log_func == NULL) { bctbx_set_log_handler(liblinphone_current_log_func = liblinphone_user_log_func); /*default value*/ }
3151315231533154315531563157315831593160316131623163316431653166316731683169317031713172317331743175317631773178317931803181318231833184318531863187318831893190319131923193319431953196319731983199320032013202320332043205320632073208320932103211321232133214321532163217321832193220
ms_message("Initializing LinphoneCore %s", linphone_core_get_version()); lc->is_unreffing = FALSE; lc->supported_encryptions = NULL; lc->config = linphone_config_ref(config); lc->data = userdata; // We need the Sal on the Android platform helper init lc->sal = std::make_shared<LinphonePrivate::Sal>(nullptr); #if defined(PACKAGE_NAME) && defined(LIBLINPHONE_VERSION) lc->sal->setUserAgent( linphone_config_get_string(lc->config, "sip", "user_agent", PACKAGE_NAME "/" LIBLINPHONE_VERSION)); #else lc->sal->setUserAgent(linphone_config_get_string(lc->config, "sip", "user_agent", "Unknown")); #endif lc->sal->setRefresherRetryAfter(linphone_config_get_int(lc->config, "sip", "refresher_retry_after", 60000)); lc->sal->setHttpProxyHost(L_C_TO_STRING(linphone_core_get_http_proxy_host(lc))); lc->sal->setHttpProxyPort(linphone_core_get_http_proxy_port(lc)); lc->sal->setUserPointer(lc); lc->sal->setCallbacks(&linphone_sal_callbacks); bool_t push_notification_default = FALSE; bool_t auto_iterate_default = FALSE; bool_t vibration_incoming_call_default = FALSE; #if __ANDROID__ || TARGET_OS_IPHONE auto_iterate_default = TRUE; #endif #if __ANDROID__ push_notification_default = TRUE; vibration_incoming_call_default = TRUE; #endif lc->push_notification_enabled = !!linphone_config_get_int(lc->config, "net", "push_notification", push_notification_default); lc->auto_iterate_enabled = !!linphone_config_get_int(lc->config, "misc", "auto_iterate", auto_iterate_default); lc->vibrate_on_incoming_call = !!linphone_config_get_int(lc->config, "misc", "vibrate_on_incoming_call", vibration_incoming_call_default); lc->push_config = linphone_push_notification_config_new(); linphone_core_enable_empty_chatrooms_deletion( lc, linphone_config_get_bool(lc->config, "misc", "empty_chat_room_deletion", TRUE)); #ifdef __ANDROID__ if (system_context) { JNIEnv *env = ms_get_jni_env(); if (lc->system_context) { env->DeleteGlobalRef((jobject)lc->system_context); } lc->system_context = (jobject)env->NewGlobalRef((jobject)system_context); } if (lc->system_context) { lc->platform_helper = LinphonePrivate::createAndroidPlatformHelpers(lc->cppPtr, lc->system_context); } else ms_fatal("You must provide the Android's app context when creating the core!"); #elif TARGET_OS_IPHONE if (system_context) { lc->system_context = system_context; } if (lc->platform_helper == NULL) { lc->platform_helper = LinphonePrivate::createIosPlatformHelpers(lc->cppPtr, lc->system_context); } #elif TARGET_OS_OSX if (lc->platform_helper == NULL) { lc->platform_helper = LinphonePrivate::createMacPlatformHelpers(lc->cppPtr, lc->system_context); } #endif if (lc->platform_helper == NULL) lc->platform_helper = new LinphonePrivate::GenericPlatformHelpers(lc->cppPtr);
3221322232233224322532263227322832293230323132323233323432353236323732383239324032413242324332443245324632473248324932503251325232533254325532563257325832593260326132623263326432653266326732683269327032713272327332743275327632773278327932803281328232833284328532863287328832893290
getPlatformHelpers(lc)->start(lc->cppPtr); msplugins_dir = linphone_factory_get_msplugins_dir(lfactory); image_resources_dir = linphone_factory_get_image_resources_dir(lfactory); // MS Factory MUST be created after Android context has been set, otherwise no camera will be detected ! // The ms2 factory must survive to linphone_core_stop(), otherwise it invalidates resources created by // LinphonePlayer/LinphoneRecorder. if (!lc->factory) { lc->factory = ms_factory_new_with_voip_and_directories(msplugins_dir, image_resources_dir); } lc->sal->setFactory(lc->factory); belr::GrammarLoader::get().addPath( std::string(linphone_factory_get_top_resources_dir(lfactory)).append("/belr/grammars")); linphone_task_list_init(&lc->hooks); _linphone_core_init_account_creator_service(lc); linphone_core_cbs_set_notify_received(internal_cbs, linphone_core_internal_notify_received); linphone_core_cbs_set_subscribe_received(internal_cbs, linphone_core_internal_subscribe_received); linphone_core_cbs_set_subscription_state_changed(internal_cbs, linphone_core_internal_subscription_state_changed); linphone_core_cbs_set_publish_state_changed(internal_cbs, linphone_core_internal_publish_state_changed); if (lc->vtable_refs == NULL) { // Do not add a new listener upon restart _linphone_core_add_callbacks(lc, internal_cbs, TRUE); } belle_sip_object_unref(internal_cbs); if (cbs != NULL) { _linphone_core_add_callbacks(lc, cbs, FALSE); } ortp_init(); linphone_core_activate_log_serialization_if_needed(); linphone_core_register_default_codecs(lc); linphone_core_register_offer_answer_providers(lc); /* Get the mediastreamer2 event queue */ /* This allows to run event's callback in linphone_core_iterate() */ lc->msevq = ms_factory_create_event_queue(lc->factory); #ifdef TUNNEL_ENABLED lc->tunnel = linphone_core_tunnel_new(lc); #endif lc->network_last_status = FALSE; lc->sip_network_state.global_state = FALSE; lc->sip_network_state.user_state = TRUE; lc->media_network_state.global_state = FALSE; lc->media_network_state.user_state = TRUE; /* Create the http provider in dual stack mode if ipv6 enabled for sip (ipv4 and ipv6. * If this creates problem, we may need to implement parallel ipv6/ ipv4 http requests in belle-sip. * ipv6 config value is read later in fonction sip_config_read*/ int use_ipv6_for_sip = linphone_config_get_int(lc->config, "sip", "use_ipv6", TRUE); /* TLS transports is always enabled, TCP can be disabled using the https_only flag in the configuration */ uint8_t transports = BELLE_SIP_HTTP_TRANSPORT_TLS; if (linphone_config_get_bool(lc->config, "sip", "https_only", FALSE) == FALSE) { transports |= BELLE_SIP_HTTP_TRANSPORT_TCP; } lc->http_provider = belle_sip_stack_create_http_provider_with_transports( reinterpret_cast<belle_sip_stack_t *>(lc->sal->getStackImpl()), (use_ipv6_for_sip ? "::0" : "0.0.0.0"), transports); lc->http_crypto_config = belle_tls_crypto_config_new(); belle_http_provider_set_tls_crypto_config(lc->http_provider, lc->http_crypto_config);
3291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360
// certificates_config_read(lc); // This will be done below in _linphone_core_read_config() lc->ringtoneplayer = linphone_ringtoneplayer_new(); lc->qrcode_rect.h = 0; lc->qrcode_rect.w = 0; lc->qrcode_rect.x = 0; lc->qrcode_rect.y = 0; lc->vcard_context = linphone_vcard_context_new(); linphone_core_initialize_supported_content_types(lc); lc->bw_controller = ms_bandwidth_controller_new(); getPlatformHelpers(lc)->setDnsServers(); LinphoneFriendList *list = linphone_core_create_friend_list(lc); linphone_friend_list_set_display_name(list, "_default"); linphone_core_add_friend_list(lc, list); linphone_friend_list_unref(list); lc->presence_model = linphone_presence_model_new(); linphone_presence_model_set_basic_status(lc->presence_model, LinphonePresenceBasicStatusOpen); _linphone_core_read_config(lc); linphone_core_set_state(lc, LinphoneGlobalReady, "Ready"); if (automatically_start) { linphone_core_start(lc); } } LinphoneStatus linphone_core_start(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); try { if (lc->state == LinphoneGlobalShutdown) { // Force change of status to LinphoneGlobalOff, otherwise restarting it will fail bctbx_warning("Core was shutDown, forcing to off"); _linphone_core_stop_async_end(lc); } switch (lc->state) { case LinphoneGlobalShutdown: bctbx_error("Can't start a Core that is shutdown, wait for Off state"); return -1; case LinphoneGlobalOff: bctbx_warning("Core was Off, before starting it again we need to init it"); linphone_core_init(lc, NULL, lc->config, lc->data, NULL, FALSE); // Decrement refs to avoid leaking linphone_config_unref(lc->config); linphone_core_deactivate_log_serialization_if_needed(); bctbx_uninit_logger(); break; case LinphoneGlobalReady: break; case LinphoneGlobalStartup: bctbx_warning("Core was startUp, skipping... (wait for On state)"); return -1; case LinphoneGlobalConfiguring: bctbx_warning("Core was Configuring, skipping... (wait for On state)"); return -1; case LinphoneGlobalOn: bctbx_warning("Core was On, skipping... "); return -1; } if (!getPlatformHelpers(lc)->getSharedCoreHelpers()->canCoreStart()) { bctbx_warning("Core [%p] can't start", lc); return -1;
3361336233633364336533663367336833693370337133723373337433753376337733783379338033813382338333843385338633873388338933903391339233933394339533963397339833993400340134023403340434053406340734083409341034113412341334143415341634173418341934203421342234233424342534263427342834293430
} linphone_core_set_state(lc, LinphoneGlobalStartup, "Starting up"); L_GET_PRIVATE_FROM_C_OBJECT(lc)->init(); lc->conference_version = ms_strdup(L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(lc)->conferenceVersionAsString())); lc->groupchat_version = ms_strdup(L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(lc)->groupChatVersionAsString())); lc->ephemeral_version = ms_strdup(L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(lc)->ephemeralVersionAsString())); // to give a chance to change uuid before starting const char *uuid = linphone_config_get_string(lc->config, "misc", "uuid", NULL); if (!uuid) { string uuid = lc->sal->createUuid(); linphone_config_set_string(lc->config, "misc", "uuid", uuid.c_str()); } else if (strcmp(uuid, "0") != 0) /*to allow to disable sip.instance*/ lc->sal->setUuid(uuid); if (!lc->sal->getRootCa().empty()) { belle_tls_crypto_config_set_root_ca(lc->http_crypto_config, lc->sal->getRootCa().c_str()); belle_http_provider_set_tls_crypto_config(lc->http_provider, lc->http_crypto_config); } bool autoNetworkStateMonitoringEnabled = !!lc->auto_net_state_mon; if (!autoNetworkStateMonitoringEnabled) { bctbx_warning("Automatic network state monitoring is disabled by configuration (auto_net_state_mon=0). " "This is not recommended."); bctbx_warning( "In this mode, apps must use linphone_core_set_network_reachable() and linphone_core_set_dns_servers() " "to notify the LinphoneCore of network availability and provide the DNS server list."); } getPlatformHelpers(lc)->onLinphoneCoreStart(autoNetworkStateMonitoringEnabled); linphone_core_set_state(lc, LinphoneGlobalConfiguring, "Configuring"); const char *remote_provisioning_uri = linphone_core_get_provisioning_uri(lc); if (remote_provisioning_uri) { bctbx_list_t *raw_headers = linphone_core_get_provisioning_headers(lc); bctbx_list_t *remote_provisioning_headers = linphone_remote_provisioning_split_headers(raw_headers); if (linphone_remote_provisioning_download_and_apply(lc, remote_provisioning_uri, remote_provisioning_headers) == -1) linphone_configuring_terminated(lc, LinphoneConfiguringFailed, "Bad URI"); if (remote_provisioning_headers) { bctbx_list_free_with_data(remote_provisioning_headers, (bctbx_list_free_func)bctbx_free); } if (raw_headers) { bctbx_list_free_with_data(raw_headers, (bctbx_list_free_func)bctbx_free); } } else { linphone_configuring_terminated(lc, LinphoneConfiguringSkipped, NULL); } /* There should not be further actions below this line. * Indeed, linphone_configuring_terminated() shall perform the actions that comes after configuration. * It may be called directly, as above, or asynchronously after the remote provisioning is completed. * */ return 0; } catch (const CorePrivate::DatabaseConnectionFailure &e) { bctbx_error("%s", e.what()); return -2; } } LinphoneCore *_linphone_core_new_with_config(LinphoneCoreCbs *cbs, struct _LpConfig *config, void *userdata, void *system_context, bool_t automatically_start, bool_t main_core) { LinphoneCore *core = L_INIT(Core); Core::create(core); core->is_main_core = main_core;
3431343234333434343534363437343834393440344134423443344434453446344734483449345034513452345334543455345634573458345934603461346234633464346534663467346834693470347134723473347434753476347734783479348034813482348334843485348634873488348934903491349234933494349534963497349834993500
linphone_core_init(core, cbs, config, userdata, system_context, automatically_start); return core; } LinphoneCore *_linphone_core_new_with_config( LinphoneCoreCbs *cbs, struct _LpConfig *config, void *userdata, void *system_context, bool_t automatically_start) { return _linphone_core_new_with_config(cbs, config, userdata, system_context, automatically_start, TRUE); } LinphoneCore *_linphone_core_new_shared_with_config(LinphoneCoreCbs *cbs, struct _LpConfig *config, void *userdata, void *system_context, bool_t automatically_start, const char *app_group_id, bool_t main_core) { bctbx_message("[SHARED] Creating %s Shared Core", main_core ? "Main" : "Executor"); linphone_config_set_string(config, "shared_core", "app_group_id", app_group_id); LinphoneCore *core = _linphone_core_new_with_config(cbs, config, userdata, system_context, automatically_start, main_core); // allow ios app extension to mark msg as read without being registered core->send_imdn_if_unregistered = !main_core; getPlatformHelpers(core)->getSharedCoreHelpers()->registerSharedCoreMsgCallback(); return core; } static LinphoneCore *_linphone_core_new_with_config_and_start(const LinphoneCoreVTable *vtable, LinphoneConfig *config, void *userdata, bool_t automatically_start) { LinphoneCoreCbs *cbs = linphone_factory_create_core_cbs(linphone_factory_get()); LinphoneCoreVTable *local_vtable = linphone_core_v_table_new(); LinphoneCore *core = NULL; if (vtable != NULL) *local_vtable = *vtable; _linphone_core_cbs_set_v_table(cbs, local_vtable, TRUE); core = _linphone_core_new_with_config(cbs, config, userdata, NULL, automatically_start); linphone_core_cbs_unref(cbs); return core; } LinphoneCore * linphone_core_new_with_config(const LinphoneCoreVTable *vtable, struct _LpConfig *config, void *userdata) { return _linphone_core_new_with_config_and_start(vtable, config, userdata, TRUE); } LinphoneCore *linphone_core_new(const LinphoneCoreVTable *vtable, const char *config_path, const char *factory_config_path, void *userdata) { LinphoneConfig *config = linphone_config_new_with_factory(config_path, factory_config_path); LinphoneCore *lc = _linphone_core_new_with_config_and_start(vtable, config, userdata, TRUE); linphone_config_unref(config); return lc; } LinphoneCore *linphone_core_ref(LinphoneCore *lc) { belle_sip_object_ref(BELLE_SIP_OBJECT(lc)); return lc; } void linphone_core_unref(LinphoneCore *lc) { belle_sip_object_unref(BELLE_SIP_OBJECT(lc)); } static bctbx_list_t *ortp_payloads_to_linphone_payloads(const bctbx_list_t *ortp_payloads, LinphoneCore *lc) { bctbx_list_t *linphone_payloads = NULL; for (; ortp_payloads != NULL; ortp_payloads = bctbx_list_next(ortp_payloads)) { LinphonePayloadType *pt = linphone_payload_type_new(lc, (OrtpPayloadType *)ortp_payloads->data); linphone_payloads = bctbx_list_append(linphone_payloads, pt); }
3501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570
return linphone_payloads; } static void sort_ortp_pt_list(bctbx_list_t **ortp_pt_list, const bctbx_list_t *linphone_pt_list) { bctbx_list_t *new_list = NULL; const bctbx_list_t *it; for (it = bctbx_list_first_elem(linphone_pt_list); it; it = bctbx_list_next(it)) { OrtpPayloadType *ortp_pt = linphone_payload_type_get_ortp_pt((LinphonePayloadType *)it->data); bctbx_list_t *elem = bctbx_list_find(*ortp_pt_list, ortp_pt); if (elem) { *ortp_pt_list = bctbx_list_unlink(*ortp_pt_list, elem); new_list = bctbx_list_concat(new_list, elem); } } *ortp_pt_list = bctbx_list_concat(new_list, *ortp_pt_list); } bctbx_list_t *linphone_core_get_audio_payload_types(LinphoneCore *lc) { return ortp_payloads_to_linphone_payloads(lc->codecs_conf.audio_codecs, lc); } void linphone_core_set_audio_payload_types(LinphoneCore *lc, const bctbx_list_t *payload_types) { sort_ortp_pt_list(&lc->codecs_conf.audio_codecs, payload_types); } bctbx_list_t *linphone_core_get_video_payload_types(LinphoneCore *lc) { return ortp_payloads_to_linphone_payloads(lc->codecs_conf.video_codecs, lc); } void linphone_core_set_video_payload_types(LinphoneCore *lc, const bctbx_list_t *payload_types) { sort_ortp_pt_list(&lc->codecs_conf.video_codecs, payload_types); } bctbx_list_t *linphone_core_get_text_payload_types(LinphoneCore *lc) { return ortp_payloads_to_linphone_payloads(lc->codecs_conf.text_codecs, lc); } void linphone_core_set_text_payload_types(LinphoneCore *lc, const bctbx_list_t *payload_types) { sort_ortp_pt_list(&lc->codecs_conf.text_codecs, payload_types); } const bctbx_list_t *linphone_core_get_audio_codecs(const LinphoneCore *lc) { return lc->codecs_conf.audio_codecs; } const bctbx_list_t *linphone_core_get_video_codecs(const LinphoneCore *lc) { return lc->codecs_conf.video_codecs; } const bctbx_list_t *linphone_core_get_text_codecs(const LinphoneCore *lc) { return lc->codecs_conf.text_codecs; } LinphoneStatus linphone_core_set_primary_contact(LinphoneCore *lc, const char *contact) { CoreLogContextualizer logContextualizer(lc); LinphoneAddress *ctt; if (lc->sip_conf.contact != NULL && strcmp(lc->sip_conf.contact, contact) == 0) { /* changing for the same contact: no need to do anything */ return 0; } if ((ctt = linphone_address_new(contact)) == 0) { ms_error("Bad contact url: %s", contact); return -1; } if (lc->sip_conf.contact != NULL) ms_free(lc->sip_conf.contact); lc->sip_conf.contact = ms_strdup(contact); linphone_config_set_string(lc->config, "sip", "contact", lc->sip_conf.contact);
3571357235733574357535763577357835793580358135823583358435853586358735883589359035913592359335943595359635973598359936003601360236033604360536063607360836093610361136123613361436153616361736183619362036213622362336243625362636273628362936303631363236333634363536363637363836393640
/* clean the guessed contact, we have to regenerate it */ if (lc->sip_conf.guessed_contact != NULL) { ms_free(lc->sip_conf.guessed_contact); lc->sip_conf.guessed_contact = NULL; } linphone_address_unref(ctt); return 0; } static void update_primary_contact(LinphoneCore *lc) { char *guessed = NULL; char tmp[LINPHONE_IPADDR_SIZE]; int port; LinphoneAddress *url; if (lc->sip_conf.guessed_contact != NULL) { ms_free(lc->sip_conf.guessed_contact); lc->sip_conf.guessed_contact = NULL; } url = linphone_address_new(lc->sip_conf.contact); if (!url) { ms_error("Could not parse identity contact !"); url = linphone_address_new("sip:unknown@unkwownhost"); } linphone_core_get_local_ip(lc, AF_UNSPEC, NULL, tmp); if (strcmp(tmp, "127.0.0.1") == 0 || strcmp(tmp, "::1") == 0) { ms_warning("Local loopback network only !"); lc->sip_conf.loopback_only = TRUE; } else lc->sip_conf.loopback_only = FALSE; linphone_address_set_domain(url, tmp); port = linphone_core_get_sip_port(lc); if (port > 0) linphone_address_set_port(url, port); /*if there is no listening socket the primary contact is somewhat useless, it won't work. But we prefer to return something in all cases. It at least shows username and ip address.*/ guessed = linphone_address_as_string(url); lc->sip_conf.guessed_contact = guessed; linphone_address_unref(url); } const char *linphone_core_get_primary_contact(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); char *identity; if (lc->sip_conf.guess_hostname) { if (lc->sip_conf.guessed_contact == NULL || lc->sip_conf.loopback_only) { update_primary_contact(lc); } identity = lc->sip_conf.guessed_contact; } else { identity = lc->sip_conf.contact; } return identity; } void linphone_core_set_guess_hostname(LinphoneCore *lc, bool_t val) { lc->sip_conf.guess_hostname = val; } bool_t linphone_core_get_guess_hostname(LinphoneCore *lc) { return lc->sip_conf.guess_hostname; } LinphoneAddress *linphone_core_get_primary_contact_parsed(LinphoneCore *lc) { return linphone_address_new(linphone_core_get_primary_contact(lc)); } LinphoneAddress *linphone_core_create_primary_contact_parsed(LinphoneCore *lc) { return linphone_address_new(linphone_core_get_primary_contact(lc)); }
3641364236433644364536463647364836493650365136523653365436553656365736583659366036613662366336643665366636673668366936703671367236733674367536763677367836793680368136823683368436853686368736883689369036913692369336943695369636973698369937003701370237033704370537063707370837093710
LinphoneStatus linphone_core_set_audio_codecs(LinphoneCore *lc, bctbx_list_t *codecs) { CoreLogContextualizer logContextualizer(lc); if (lc->codecs_conf.audio_codecs != NULL) bctbx_list_free(lc->codecs_conf.audio_codecs); lc->codecs_conf.audio_codecs = codecs; _linphone_core_codec_config_write(lc); linphone_core_update_allocated_audio_bandwidth(lc); return 0; } LinphoneStatus linphone_core_set_video_codecs(LinphoneCore *lc, bctbx_list_t *codecs) { CoreLogContextualizer logContextualizer(lc); if (lc->codecs_conf.video_codecs != NULL) bctbx_list_free(lc->codecs_conf.video_codecs); lc->codecs_conf.video_codecs = codecs; _linphone_core_codec_config_write(lc); return 0; } LinphoneStatus linphone_core_set_text_codecs(LinphoneCore *lc, bctbx_list_t *codecs) { CoreLogContextualizer logContextualizer(lc); if (lc->codecs_conf.text_codecs != NULL) bctbx_list_free(lc->codecs_conf.text_codecs); lc->codecs_conf.text_codecs = codecs; _linphone_core_codec_config_write(lc); return 0; } void linphone_core_enable_generic_comfort_noise(LinphoneCore *lc, bool_t enabled) { linphone_config_set_int(lc->config, "misc", "use_cn", enabled); } bool_t linphone_core_generic_comfort_noise_enabled(const LinphoneCore *lc) { return !!linphone_config_get_int(lc->config, "misc", "use_cn", FALSE); } const bctbx_list_t *linphone_core_get_friend_list(const LinphoneCore *lc) { bctbx_list_t *lists = lc->friends_lists; if (lists) { LinphoneFriendList *list = (LinphoneFriendList *)lists->data; if (list) { return list->friends; } } return NULL; } const bctbx_list_t *linphone_core_get_friends_lists(const LinphoneCore *lc) { return lc->friends_lists; } LinphoneFriendList *linphone_core_get_default_friend_list(const LinphoneCore *lc) { if (lc && lc->friends_lists) { return (LinphoneFriendList *)lc->friends_lists->data; } return NULL; } LinphoneFriendList *linphone_core_get_friend_list_by_name(const LinphoneCore *lc, const char *name) { if (!lc) return NULL; LinphoneFriendList *ret = NULL; bctbx_list_t *list_copy = lc->friends_lists; while (list_copy) { LinphoneFriendList *list = (LinphoneFriendList *)list_copy->data; const char *list_name = linphone_friend_list_get_display_name(list); if (list_name && strcmp(name, list_name) == 0) { ret = list; break; } list_copy = list_copy->next;
3711371237133714371537163717371837193720372137223723372437253726372737283729373037313732373337343735373637373738373937403741374237433744374537463747374837493750375137523753375437553756375737583759376037613762376337643765376637673768376937703771377237733774377537763777377837793780
} return ret; } void linphone_core_remove_friend_list(LinphoneCore *lc, LinphoneFriendList *list) { bctbx_list_t *elem = bctbx_list_find(lc->friends_lists, list); if (elem == NULL) return; linphone_core_remove_friends_list_from_db(lc, list); linphone_core_notify_friend_list_removed(lc, list); list->lc = NULL; linphone_friend_list_unref(list); lc->friends_lists = bctbx_list_erase_link(lc->friends_lists, elem); } void linphone_core_clear_bodyless_friend_lists(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); bctbx_list_t *copy = bctbx_list_copy(linphone_core_get_friends_lists((const LinphoneCore *)lc)); for (auto it = copy; it; it = bctbx_list_next(it)) { LinphoneFriendList *friends = (LinphoneFriendList *)bctbx_list_get_data(it); if (linphone_friend_list_is_subscription_bodyless(friends)) linphone_core_remove_friend_list(lc, (LinphoneFriendList *)bctbx_list_get_data(it)); } bctbx_list_free(copy); } void linphone_core_add_friend_list(LinphoneCore *lc, LinphoneFriendList *list) { CoreLogContextualizer logContextualizer(lc); if (!list->lc) { list->lc = lc; } lc->friends_lists = bctbx_list_append(lc->friends_lists, linphone_friend_list_ref(list)); linphone_core_store_friends_list_in_db(lc, list); linphone_core_notify_friend_list_created(lc, list); } const bctbx_list_t *linphone_core_find_contacts_by_char(LinphoneCore *core, const char *filter, bool_t sip_only) { CoreLogContextualizer logContextualizer(core); // Get sipuri from filter if possible bctbx_list_t *list = NULL, *_list = NULL; LinphoneAddress *addr = linphone_core_interpret_url(core, (sip_only) ? filter : ""); bctbx_list_t *listFriendsList = (bctbx_list_t *)linphone_core_get_friends_lists(core); bctbx_list_t *listFriend = (listFriendsList != NULL) ? (bctbx_list_t *)linphone_friend_list_get_friends((LinphoneFriendList *)listFriendsList->data) : NULL; if (addr != NULL) list = bctbx_list_new(addr); while (listFriend != NULL && listFriend->data != NULL) { LinphoneAddress *buff = (LinphoneAddress *)linphone_friend_get_address((LinphoneFriend *)listFriend->data); if (buff != NULL) { bctbx_list_t *new_list = bctbx_list_new(buff); if (list == NULL) { _list = list = new_list; } else { if (_list == NULL) _list = list; _list->next = new_list; _list = _list->next; } } listFriend = listFriend->next; } return list; } void linphone_core_enable_audio_adaptive_jittcomp(LinphoneCore *lc, bool_t val) { lc->rtp_conf.audio_adaptive_jitt_comp_enabled = val; }
3781378237833784378537863787378837893790379137923793379437953796379737983799380038013802380338043805380638073808380938103811381238133814381538163817381838193820382138223823382438253826382738283829383038313832383338343835383638373838383938403841384238433844384538463847384838493850
bool_t linphone_core_audio_adaptive_jittcomp_enabled(LinphoneCore *lc) { return lc->rtp_conf.audio_adaptive_jitt_comp_enabled; } int linphone_core_get_audio_jittcomp(LinphoneCore *lc) { return lc->rtp_conf.audio_jitt_comp; } void linphone_core_enable_video_adaptive_jittcomp(LinphoneCore *lc, bool_t val) { lc->rtp_conf.video_adaptive_jitt_comp_enabled = val; } bool_t linphone_core_video_adaptive_jittcomp_enabled(LinphoneCore *lc) { return lc->rtp_conf.video_adaptive_jitt_comp_enabled; } int linphone_core_get_video_jittcomp(LinphoneCore *lc) { return lc->rtp_conf.video_jitt_comp; } int linphone_core_get_audio_port(const LinphoneCore *lc) { return lc->rtp_conf.audio_rtp_min_port; } void linphone_core_get_audio_port_range(const LinphoneCore *lc, int *min_port, int *max_port) { *min_port = lc->rtp_conf.audio_rtp_min_port; *max_port = lc->rtp_conf.audio_rtp_max_port; } 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; } void linphone_core_get_video_port_range(const LinphoneCore *lc, int *min_port, int *max_port) { *min_port = lc->rtp_conf.video_rtp_min_port; *max_port = lc->rtp_conf.video_rtp_max_port; } 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; } void linphone_core_get_text_port_range(const LinphoneCore *lc, int *min_port, int *max_port) { *min_port = lc->rtp_conf.text_rtp_min_port; *max_port = lc->rtp_conf.text_rtp_max_port; } 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) {
3851385238533854385538563857385838593860386138623863386438653866386738683869387038713872387338743875387638773878387938803881388238833884388538863887388838893890389138923893389438953896389738983899390039013902390339043905390639073908390939103911391239133914391539163917391839193920
return lc->rtp_conf.nortp_timeout; } bool_t linphone_core_get_rtp_no_xmit_on_audio_mute(const LinphoneCore *lc) { return lc->rtp_conf.rtp_no_xmit_on_audio_mute; } static void apply_jitter_value(LinphoneCore *lc, int value, MSFormatType stype) { for (const auto &call : L_GET_CPP_PTR_FROM_C_OBJECT(lc)->getCalls()) { MediaStream *ms = (stype == MSAudio) ? call->getMediaStream(LinphoneStreamTypeAudio) : call->getMediaStream(LinphoneStreamTypeVideo); if (ms) { RtpSession *s = ms->sessions.rtp_session; if (s) { if (value > 0) { ms_message("Jitter buffer size set to [%i] ms on call [%p]", value, call.get()); rtp_session_set_jitter_compensation(s, value); rtp_session_enable_jitter_buffer(s, TRUE); } else if (value == 0) { ms_warning("Jitter buffer is disabled per application request on call [%p]", call.get()); rtp_session_enable_jitter_buffer(s, FALSE); } } } } } void linphone_core_set_audio_jittcomp(LinphoneCore *lc, int milliseconds) { lc->rtp_conf.audio_jitt_comp = milliseconds; apply_jitter_value(lc, milliseconds, MSAudio); } void linphone_core_set_video_jittcomp(LinphoneCore *lc, int milliseconds) { lc->rtp_conf.video_jitt_comp = milliseconds; apply_jitter_value(lc, milliseconds, MSVideo); } void linphone_core_set_rtp_no_xmit_on_audio_mute(LinphoneCore *lc, bool_t rtp_no_xmit_on_audio_mute) { lc->rtp_conf.rtp_no_xmit_on_audio_mute = rtp_no_xmit_on_audio_mute; } void linphone_core_set_audio_port(LinphoneCore *lc, int port) { lc->rtp_conf.audio_rtp_min_port = lc->rtp_conf.audio_rtp_max_port = port; } void linphone_core_set_audio_port_range(LinphoneCore *lc, int min_port, int max_port) { lc->rtp_conf.audio_rtp_min_port = min_port; lc->rtp_conf.audio_rtp_max_port = max_port; } void linphone_core_set_video_port(LinphoneCore *lc, int port) { lc->rtp_conf.video_rtp_min_port = lc->rtp_conf.video_rtp_max_port = port; } void linphone_core_set_video_port_range(LinphoneCore *lc, int min_port, int max_port) { lc->rtp_conf.video_rtp_min_port = min_port; lc->rtp_conf.video_rtp_max_port = max_port; } void linphone_core_set_text_port(LinphoneCore *lc, int port) { lc->rtp_conf.text_rtp_min_port = lc->rtp_conf.text_rtp_max_port = port; } void linphone_core_set_text_port_range(LinphoneCore *lc, int min_port, int max_port) { lc->rtp_conf.text_rtp_min_port = min_port; lc->rtp_conf.text_rtp_max_port = max_port; } void linphone_core_set_nortp_timeout(LinphoneCore *lc, int nortp_timeout) { lc->rtp_conf.nortp_timeout = nortp_timeout;
3921392239233924392539263927392839293930393139323933393439353936393739383939394039413942394339443945394639473948394939503951395239533954395539563957395839593960396139623963396439653966396739683969397039713972397339743975397639773978397939803981398239833984398539863987398839893990
} bool_t linphone_core_get_use_info_for_dtmf(LinphoneCore *lc) { return !!linphone_config_get_int(lc->config, "sip", "use_info", 0); } void linphone_core_set_use_info_for_dtmf(LinphoneCore *lc, bool_t use_info) { if (linphone_core_ready(lc)) { linphone_config_set_int(lc->config, "sip", "use_info", use_info); } } bool_t linphone_core_get_use_rfc2833_for_dtmf(LinphoneCore *lc) { return !!linphone_config_get_int(lc->config, "sip", "use_rfc2833", 1); } void linphone_core_set_use_rfc2833_for_dtmf(LinphoneCore *lc, bool_t use_rfc2833) { if (linphone_core_ready(lc)) { linphone_config_set_int(lc->config, "sip", "use_rfc2833", use_rfc2833); } } int linphone_core_get_sip_port(LinphoneCore *lc) { LinphoneSipTransports tr; linphone_core_get_sip_transports_used(lc, &tr); return tr.udp_port > 0 ? tr.udp_port : (tr.tcp_port > 0 ? tr.tcp_port : tr.tls_port); } static char _ua_name[64] = "Linphone"; static char _ua_version[64] = LIBLINPHONE_VERSION; void linphone_core_set_user_agent(LinphoneCore *lc, const char *name, const char *ver) { CoreLogContextualizer logContextualizer(lc); ostringstream ua_string; ua_string << (name ? name : ""); if (ver) ua_string << "/" << ver; linphone_config_set_string(lc->config, "sip", "user_agent", ua_string.str().c_str()); if (lc->sal) { lc->sal->setUserAgent(ua_string.str()); } } const char *linphone_core_get_user_agent(LinphoneCore *lc) { return lc->sal->getUserAgent().c_str(); } const char *linphone_core_get_user_agent_name(void) { return _ua_name; } const char *linphone_core_get_user_agent_version(void) { return _ua_version; } static bool_t transports_unchanged(const LinphoneSipTransports *tr1, const LinphoneSipTransports *tr2) { return tr2->udp_port == tr1->udp_port && tr2->tcp_port == tr1->tcp_port && tr2->dtls_port == tr1->dtls_port && tr2->tls_port == tr1->tls_port; } static void __linphone_core_invalidate_registers(LinphoneCore *lc) { const bctbx_list_t *elem = linphone_core_get_account_list(lc); for (; elem != NULL; elem = elem->next) { LinphoneAccount *acc = (LinphoneAccount *)elem->data; if (linphone_account_params_get_register_enabled(linphone_account_get_params(acc))) { /*this will force a re-registration at next iterate*/ Account::toCpp(acc)->setNeedToRegister(true); } } } int _linphone_core_apply_transports(LinphoneCore *lc) {
3991399239933994399539963997399839994000400140024003400440054006400740084009401040114012401340144015401640174018401940204021402240234024402540264027402840294030403140324033403440354036403740384039404040414042404340444045404640474048404940504051405240534054405540564057405840594060
std::shared_ptr<Sal> sal = lc->sal; const char *anyaddr; LinphoneSipTransports *tr = &lc->sip_conf.transports; const char *listening_address; /*first of all invalidate all current registrations so that we can register again with new transports*/ __linphone_core_invalidate_registers(lc); if (lc->sip_conf.ipv6_enabled) anyaddr = "::0"; else anyaddr = "0.0.0.0"; sal->unlistenPorts(); listening_address = linphone_config_get_string(lc->config, "sip", "bind_address", anyaddr); if (linphone_core_get_http_proxy_host(lc)) { sal->setHttpProxyHost(linphone_core_get_http_proxy_host(lc)); sal->setHttpProxyPort(linphone_core_get_http_proxy_port(lc)); } if (lc->tunnel && linphone_tunnel_sip_enabled(lc->tunnel) && linphone_tunnel_get_activated(lc->tunnel)) { sal->setListenPort(anyaddr, tr->udp_port, SalTransportUDP, TRUE); } else { if (tr->udp_port != 0) { sal->setListenPort(listening_address, tr->udp_port, SalTransportUDP, FALSE); } if (tr->tcp_port != 0) { sal->setListenPort(listening_address, tr->tcp_port, SalTransportTCP, FALSE); } if (linphone_core_sip_transport_supported(lc, LinphoneTransportTls)) { if (tr->tls_port != 0) sal->setListenPort(listening_address, tr->tls_port, SalTransportTLS, FALSE); } } return 0; } bool_t linphone_core_sip_transport_supported(const LinphoneCore *lc, LinphoneTransportType tp) { return !!lc->sal->isTransportAvailable((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() { 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; }
4061406240634064406540664067406840694070407140724073407440754076407740784079408040814082408340844085408640874088408940904091409240934094409540964097409840994100410141024103410441054106410741084109411041114112411341144115411641174118411941204121412241234124412541264127412841294130
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; } static LinphoneStatus _linphone_core_set_sip_transports(LinphoneCore *lc, const LinphoneSipTransports *tr_config, bool_t applyIt) { LinphoneSipTransports tr = *tr_config; if (linphone_config_get_int(lc->config, "sip", "sip_random_port", 0) == 1) { /*legacy random mode*/ if (tr.udp_port > 0) { tr.udp_port = LC_SIP_TRANSPORT_RANDOM; } if (tr.tcp_port > 0) { tr.tcp_port = LC_SIP_TRANSPORT_RANDOM; } if (tr.tls_port > 0) { tr.tls_port = LC_SIP_TRANSPORT_RANDOM; } } if (tr.udp_port == 0 && tr.tcp_port == 0 && tr.tls_port == 0) { tr.udp_port = 5060; } if (transports_unchanged(&tr, &lc->sip_conf.transports)) return 0; memcpy(&lc->sip_conf.transports, &tr, sizeof(tr)); if (linphone_core_ready(lc)) { linphone_config_set_int(lc->config, "sip", "sip_port", tr_config->udp_port); linphone_config_set_int(lc->config, "sip", "sip_tcp_port", tr_config->tcp_port); linphone_config_set_int(lc->config, "sip", "sip_tls_port", tr_config->tls_port); } if (lc->sal == NULL || !applyIt) return 0; return _linphone_core_apply_transports(lc); } LinphoneStatus linphone_core_set_sip_transports(LinphoneCore *lc, const LinphoneSipTransports *tr_config /*config to be saved*/) { return _linphone_core_set_sip_transports(lc, tr_config, TRUE);
4131413241334134413541364137413841394140414141424143414441454146414741484149415041514152415341544155415641574158415941604161416241634164416541664167416841694170417141724173417441754176417741784179418041814182418341844185418641874188418941904191419241934194419541964197419841994200
} 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)) { linphone_config_set_int(lc->config, "sip", "sip_port", transports->udp_port); linphone_config_set_int(lc->config, "sip", "sip_tcp_port", transports->tcp_port); linphone_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(); 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 = lc->sal->getListeningPort(SalTransportUDP); tr->tcp_port = lc->sal->getListeningPort(SalTransportTCP); tr->tls_port = lc->sal->getListeningPort(SalTransportTLS); } LinphoneTransports *linphone_core_get_transports_used(LinphoneCore *lc) { LinphoneTransports *transports = linphone_transports_new(); transports->udp_port = lc->sal->getListeningPort(SalTransportUDP); transports->tcp_port = lc->sal->getListeningPort(SalTransportTCP); transports->tls_port = lc->sal->getListeningPort(SalTransportTLS); transports->dtls_port = lc->sal->getListeningPort(SalTransportDTLS); return transports; } void linphone_core_set_sip_port(LinphoneCore *lc, int port) { LinphoneSipTransports tr; memset(&tr, 0, sizeof(tr)); tr.udp_port = port; linphone_core_set_sip_transports(lc, &tr); } bool_t linphone_core_ipv6_enabled(LinphoneCore *lc) { return lc->sip_conf.ipv6_enabled; } void linphone_core_enable_ipv6(LinphoneCore *lc, bool_t val) { CoreLogContextualizer logContextualizer(lc); if (lc->sip_conf.ipv6_enabled != val) { lc->sip_conf.ipv6_enabled = val; if (lc->sal) { /* we need to update the sip stack */
4201420242034204420542064207420842094210421142124213421442154216421742184219422042214222422342244225422642274228422942304231423242334234423542364237423842394240424142424243424442454246424742484249425042514252425342544255425642574258425942604261426242634264426542664267426842694270
_linphone_core_apply_transports(lc); } /*update the localip immediately for the network monitor to avoid to "discover" later that we switched to ipv6*/ linphone_core_get_local_ip(lc, AF_INET, NULL, lc->localip4); if (val) linphone_core_get_local_ip(lc, AF_INET6, NULL, lc->localip6); if (linphone_core_ready(lc)) { linphone_config_set_int(lc->config, "sip", "use_ipv6", (int)val); } } } bool_t linphone_core_retransmission_on_nack_enabled(LinphoneCore *lc) { return lc->video_conf.retransmission_on_nack_enabled; } void linphone_core_enable_retransmission_on_nack(LinphoneCore *lc, bool_t val) { if (lc->video_conf.retransmission_on_nack_enabled != val) { lc->video_conf.retransmission_on_nack_enabled = val; if (linphone_core_ready(lc)) { linphone_config_set_int(lc->config, "video", "retransmission_on_nack_enabled", (int)val); } } } bool_t linphone_core_wifi_only_enabled(LinphoneCore *lc) { return (bool_t)linphone_config_get_int(lc->config, "net", "wifi_only", 0); } void linphone_core_enable_wifi_only(LinphoneCore *lc, bool_t val) { if (linphone_core_ready(lc)) { linphone_config_set_int(lc->config, "net", "wifi_only", (int)val); getPlatformHelpers(lc)->onWifiOnlyEnabled(!!val); } } bool_t linphone_core_content_encoding_supported(const LinphoneCore *lc, const char *content_encoding) { const char *handle_content_encoding = linphone_config_get_string(lc->config, "sip", "handle_content_encoding", "deflate"); return (strcmp(handle_content_encoding, content_encoding) == 0) && lc->sal->isContentEncodingAvailable(content_encoding); } static void notify_network_reachable_change(LinphoneCore *lc) { if (!lc->network_reachable_to_be_notified) return; lc->network_reachable_to_be_notified = FALSE; linphone_core_notify_network_reachable(lc, lc->sip_network_state.global_state); if (lc->sip_network_state.global_state) linphone_core_resolve_stun_server(lc); } static void proxy_update(LinphoneCore *lc) { bctbx_list_t *elem, *next; bctbx_list_for_each(lc->sip_conf.proxies, (void (*)(void *)) & linphone_proxy_config_update); for (elem = lc->sip_conf.deleted_proxies; elem != NULL; elem = next) { LinphoneProxyConfig *cfg = (LinphoneProxyConfig *)elem->data; next = elem->next; if (ms_time(NULL) - Account::toCpp(cfg->account)->getDeletionDate() > 32) { lc->sip_conf.deleted_proxies = bctbx_list_erase_link(lc->sip_conf.deleted_proxies, elem); ms_message("Proxy config for [%s] is definitely removed from core.", linphone_proxy_config_get_addr(cfg)); bctbx_list_t *remove_account = bctbx_list_find(lc->sip_conf.deleted_accounts, cfg->account); if (remove_account != NULL) { LinphoneAccount *account = (LinphoneAccount *)remove_account->data; lc->sip_conf.deleted_accounts = bctbx_list_erase_link(lc->sip_conf.deleted_accounts, remove_account); linphone_account_unref(account); } Account::toCpp(cfg->account)->releaseOps();
4271427242734274427542764277427842794280428142824283428442854286428742884289429042914292429342944295429642974298429943004301430243034304430543064307430843094310431143124313431443154316431743184319432043214322432343244325432643274328432943304331433243334334433543364337433843394340
linphone_proxy_config_unref(cfg); } } } static void assign_buddy_info(LinphoneCore *lc, BuddyInfo *info) { LinphoneFriend *lf = linphone_core_get_friend_by_address(lc, info->sip_uri); if (lf != NULL) { lf->info = info; ms_message("%s has a BuddyInfo assigned with image %p", info->sip_uri, info->image_data); linphone_core_notify_buddy_info_updated(lc, lf); } else { ms_warning("Could not any friend with uri %s", info->sip_uri); } } static void analyze_buddy_lookup_results(LinphoneCore *lc, LinphoneProxyConfig *cfg) { bctbx_list_t *elem; SipSetupContext *ctx = linphone_proxy_config_get_sip_setup_context(cfg); for (elem = lc->bl_reqs; elem != NULL; elem = bctbx_list_next(elem)) { BuddyLookupRequest *req = (BuddyLookupRequest *)elem->data; if (req->status == BuddyLookupDone || req->status == BuddyLookupFailure) { if (req->results != NULL) { BuddyInfo *i = (BuddyInfo *)req->results->data; bctbx_list_free(req->results); req->results = NULL; assign_buddy_info(lc, i); } sip_setup_context_buddy_lookup_free(ctx, req); elem->data = NULL; } } /*purge completed requests */ while ((elem = bctbx_list_find(lc->bl_reqs, NULL)) != NULL) { lc->bl_reqs = bctbx_list_erase_link(lc->bl_reqs, elem); } } static void linphone_core_grab_buddy_infos(LinphoneCore *lc, LinphoneProxyConfig *cfg) { const bctbx_list_t *elem; SipSetupContext *ctx = linphone_proxy_config_get_sip_setup_context(cfg); for (elem = linphone_core_get_friend_list(lc); elem != NULL; elem = elem->next) { LinphoneFriend *lf = (LinphoneFriend *)elem->data; if (lf->info == NULL) { if (linphone_core_lookup_known_proxy(lc, lf->uri) == cfg) { if (linphone_address_get_username(lf->uri) != NULL) { BuddyLookupRequest *req; char *tmp = linphone_address_as_string_uri_only(lf->uri); req = sip_setup_context_create_buddy_lookup_request(ctx); buddy_lookup_request_set_key(req, tmp); buddy_lookup_request_set_max_results(req, 1); sip_setup_context_buddy_lookup_submit(ctx, req); lc->bl_reqs = bctbx_list_append(lc->bl_reqs, req); ms_free(tmp); } } } } } static void linphone_core_do_plugin_tasks(LinphoneCore *lc) { LinphoneProxyConfig *cfg = linphone_core_get_default_proxy_config(lc); if (cfg) { if (lc->bl_refresh) { SipSetupContext *ctx = linphone_proxy_config_get_sip_setup_context(cfg); if (ctx && (sip_setup_context_get_capabilities(ctx) & SIP_SETUP_CAP_BUDDY_LOOKUP)) { linphone_core_grab_buddy_infos(lc, cfg); lc->bl_refresh = FALSE; } }
4341434243434344434543464347434843494350435143524353435443554356435743584359436043614362436343644365436643674368436943704371437243734374437543764377437843794380438143824383438443854386438743884389439043914392439343944395439643974398439944004401440244034404440544064407440844094410
if (lc->bl_reqs) analyze_buddy_lookup_results(lc, cfg); } } void linphone_core_iterate(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); uint64_t curtime_ms = ms_get_cur_time_ms(); /*monotonic time*/ time_t current_real_time = ms_time(NULL); int64_t diff_time; bool one_second_elapsed = false; if (lc->prevtime_ms == 0) { lc->prevtime_ms = curtime_ms; } if ((diff_time = (int64_t)(curtime_ms - lc->prevtime_ms)) >= 1000) { one_second_elapsed = true; if (diff_time > 3000) { /*since monotonic time doesn't increment while machine is sleeping, we don't want to catchup too much*/ lc->prevtime_ms = curtime_ms; } else { lc->prevtime_ms += 1000; } } if (lc->iterate_thread_id == 0) { lc->iterate_thread_id = bctbx_thread_self(); } if (lc->ecc != NULL) { LinphoneEcCalibratorStatus ecs = ec_calibrator_get_status(lc->ecc); if (ecs != LinphoneEcCalibratorInProgress) { if (lc->ecc->cb) lc->ecc->cb(lc, ecs, lc->ecc->delay, lc->ecc->cb_data); if (ecs == LinphoneEcCalibratorDone) { int len = linphone_config_get_int(lc->config, "sound", "ec_tail_len", 0); int margin = len / 2; linphone_config_set_int(lc->config, "sound", "ec_delay", MAX(lc->ecc->delay - margin, 0)); } else if (ecs == LinphoneEcCalibratorFailed) { linphone_config_set_int(lc->config, "sound", "ec_delay", -1); /*use default value from soundcard*/ } else if (ecs == LinphoneEcCalibratorDoneNoEcho) { linphone_core_enable_echo_cancellation(lc, FALSE); } ec_calibrator_destroy(lc->ecc); lc->ecc = NULL; } } if (lc->preview_finished) { lc->preview_finished = 0; linphone_ringtoneplayer_stop(lc->ringtoneplayer); lc_callback_obj_invoke(&lc->preview_finished_cb, lc); } if (lc->sal) lc->sal->iterate(); if (lc->msevq) ms_event_queue_pump(lc->msevq); if (linphone_core_get_global_state(lc) == LinphoneGlobalConfiguring) // Avoid registration before getting remote configuration results return; proxy_update(lc); /* We have to iterate for each call */ L_GET_PRIVATE_FROM_C_OBJECT(lc)->iterateCalls(current_real_time, one_second_elapsed); if (linphone_core_video_preview_enabled(lc)) { if (lc->previewstream == NULL && !L_GET_PRIVATE_FROM_C_OBJECT(lc)->hasCalls()) toggle_video_preview(lc, TRUE); #ifdef VIDEO_ENABLED if (lc->previewstream) video_stream_iterate(lc->previewstream); #endif } else {
4411441244134414441544164417441844194420442144224423442444254426442744284429443044314432443344344435443644374438443944404441444244434444444544464447444844494450445144524453445444554456445744584459446044614462446344644465446644674468446944704471447244734474447544764477447844794480
if (lc->previewstream != NULL) toggle_video_preview(lc, FALSE); } linphone_core_run_hooks(lc); linphone_core_do_plugin_tasks(lc); if (lc->sip_network_state.global_state && lc->netup_time != 0 && (current_real_time - lc->netup_time) >= 2) { /*not do that immediately, take your time.*/ linphone_core_send_initial_subscribes(lc); } if (one_second_elapsed) { bctbx_list_t *elem = NULL; if (linphone_config_needs_commit(lc->config)) { linphone_core_config_sync(lc); } for (elem = lc->friends_lists; elem != NULL; elem = bctbx_list_next(elem)) { LinphoneFriendList *list = (LinphoneFriendList *)elem->data; if (list->dirty_friends_to_update && list->type == LinphoneFriendListTypeCardDAV) { linphone_friend_list_update_dirty_friends(list); } } } if (liblinphone_serialize_logs == TRUE) { ortp_logv_flush(); } /* When doing asynchronous core stop, the core goes to LinphoneGlobalShutdown state Then linphone_core_iterate() needs to be called until synchronous tasks are done Then the stop is finished and the status is changed to LinphoneGlobalOff */ if (lc->state == LinphoneGlobalShutdown) { if (L_GET_PRIVATE_FROM_C_OBJECT(lc)->isShutdownDone()) { _linphone_core_stop_async_end(lc); } } } LinphoneAddress *linphone_core_interpret_url(LinphoneCore *lc, const char *url) { CoreLogContextualizer logContextualizer(lc); return linphone_core_interpret_url_2(lc, url, TRUE); } LinphoneAddress *linphone_core_interpret_url_2(LinphoneCore *lc, const char *url, bool_t apply_international_prefix) { CoreLogContextualizer logContextualizer(lc); if (!url) return NULL; LinphoneAccount *account = linphone_core_get_default_account(lc); LinphoneAddress *result = NULL; if (apply_international_prefix && linphone_account_is_phone_number(account, url)) { char *normalized_number = linphone_account_normalize_phone_number(account, url); if (normalized_number) { result = linphone_account_normalize_sip_uri(account, normalized_number); ms_free(normalized_number); } else { result = linphone_account_normalize_sip_uri(account, url); } } else { result = linphone_account_normalize_sip_uri(account, url); } return result; } const char *linphone_core_get_identity(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); LinphoneProxyConfig *proxy = linphone_core_get_default_proxy_config(lc); const char *from; if (proxy != NULL) { from = linphone_proxy_config_get_identity(proxy); } else from = linphone_core_get_primary_contact(lc);
4481448244834484448544864487448844894490449144924493449444954496449744984499450045014502450345044505450645074508450945104511451245134514451545164517451845194520452145224523452445254526452745284529453045314532453345344535453645374538453945404541454245434544454545464547454845494550
return from; } const char *linphone_core_get_route(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); LinphoneProxyConfig *proxy = linphone_core_get_default_proxy_config(lc); const char *route = NULL; if (proxy != NULL) { route = linphone_proxy_config_get_route(proxy); } return route; } LinphoneCall * linphone_core_start_refered_call(BCTBX_UNUSED(LinphoneCore *lc), LinphoneCall *call, const LinphoneCallParams *params) { shared_ptr<LinphonePrivate::Call> referredCall = Call::toCpp(call)->startReferredCall(params ? L_GET_CPP_PTR_FROM_C_OBJECT(params) : nullptr); return referredCall->toC(); } /* returns the ideal route set for making an operation through this proxy. The list must be freed as well as the SalAddress content rfc3608 6.1. Procedures at the UA /.../ For example, some devices will use locally-configured explicit loose routing to reach a next-hop proxy, and others will use a default outbound-proxy routing rule. However, for the result to function, the combination MUST provide valid routing in the local environment. In general, the service route set is appended to any locally configured route needed to egress the access proxy chain. Systems designers must match the service routing policy of their nodes with the basic SIP routing policy in order to get a workable system. */ static bctbx_list_t *make_routes_for_proxy(LinphoneProxyConfig *proxy, const LinphoneAddress *dest) { bctbx_list_t *ret = NULL; const bctbx_list_t *proxy_routes = linphone_proxy_config_get_routes(proxy); bctbx_list_t *proxy_routes_iterator = (bctbx_list_t *)proxy_routes; const LinphoneAddress *srv_route = linphone_proxy_config_get_service_route(proxy); while (proxy_routes_iterator) { const char *local_route = (const char *)bctbx_list_get_data(proxy_routes_iterator); if (local_route) { ret = bctbx_list_append(ret, sal_address_new(local_route)); } proxy_routes_iterator = bctbx_list_next(proxy_routes_iterator); } bctbx_list_free_with_data((bctbx_list_t *)proxy_routes, (bctbx_list_free_func)bctbx_free); if (srv_route) { const auto srv_route_addr = LinphonePrivate::Address::toCpp(srv_route)->getSharedFromThis(); ret = bctbx_list_append(ret, sal_address_clone(srv_route_addr->getImpl())); } 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)); 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; } static bctbx_list_t *make_routes_for_account(LinphoneAccount *account, const LinphoneAddress *dest) { bctbx_list_t *ret = NULL;
4551455245534554455545564557455845594560456145624563456445654566456745684569457045714572457345744575457645774578457945804581458245834584458545864587458845894590459145924593459445954596459745984599460046014602460346044605460646074608460946104611461246134614461546164617461846194620
bctbx_list_t *account_routes = linphone_account_params_get_routes_addresses(linphone_account_get_params(account)); bctbx_list_t *account_routes_iterator = (bctbx_list_t *)account_routes; while (account_routes_iterator) { LinphoneAddress *local_route = (LinphoneAddress *)bctbx_list_get_data(account_routes_iterator); if (local_route) { char *route_str = linphone_address_as_string(local_route); ret = bctbx_list_append(ret, sal_address_new(route_str)); ms_free(route_str); } account_routes_iterator = bctbx_list_next(account_routes_iterator); } bctbx_list_free(account_routes); const auto srv_route = Account::toCpp(account)->getServiceRouteAddress(); if (srv_route) { ret = bctbx_list_append(ret, sal_address_clone(srv_route->getImpl())); } if (ret == NULL && linphone_account_params_get_server_addr(linphone_account_get_params(account))) { /*if the account identity 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 account.*/ SalAddress *account_addr = sal_address_new(linphone_account_params_get_server_addr(linphone_account_get_params(account))); const char *account_identity_domain = linphone_address_get_domain( linphone_account_params_get_identity_address(linphone_account_get_params(account))); const char *linphone_addr_domain = linphone_address_get_domain(dest); if (account_identity_domain && linphone_addr_domain && strcmp(account_identity_domain, linphone_addr_domain) == 0) { ret = bctbx_list_append(ret, account_addr); } else sal_address_unref(account_addr); } return ret; } /* * Returns a proxy config matching the given identity address * Prefers registered, then first registering matching, otherwise first matching * returns NULL if none is found */ LinphoneProxyConfig *linphone_core_lookup_proxy_by_identity_strict(LinphoneCore *lc, const LinphoneAddress *uri) { LinphoneAccount *account = linphone_core_lookup_account_by_identity_strict(lc, uri); return account ? Account::toCpp(account)->getConfig() : nullptr; } /* * Returns a proxy config matching the given identity address * Prefers registered, then first registering matching, otherwise first matching * returns default proxy config if none is found */ LinphoneProxyConfig *linphone_core_lookup_proxy_by_identity(LinphoneCore *lc, const LinphoneAddress *uri) { CoreLogContextualizer logContextualizer(lc); LinphoneProxyConfig *found_cfg = linphone_core_lookup_proxy_by_identity_strict(lc, uri); if (!found_cfg) found_cfg = lc->default_proxy; return found_cfg; } /* * Returns an account matching the given identity address * Prefers registered, then first registering matching, otherwise first matching * returns NULL if none is found */ LinphoneAccount *linphone_core_lookup_account_by_conference_factory_strict(LinphoneCore *lc, const LinphoneAddress *uri) { LinphoneAccount *found_acc = NULL; LinphoneAccount *found_reg_acc = NULL; LinphoneAccount *found_noreg_acc = NULL; const bctbx_list_t *elem; for (elem = linphone_core_get_account_list(lc); elem != NULL; elem = elem->next) { LinphoneAccount *acc = (LinphoneAccount *)elem->data; const LinphoneAccountParams *params = linphone_account_get_params(acc); const LinphoneAddress *audio_video_conference_factory =
4621462246234624462546264627462846294630463146324633463446354636463746384639464046414642464346444645464646474648464946504651465246534654465546564657465846594660466146624663466446654666466746684669467046714672467346744675467646774678467946804681468246834684468546864687468846894690
linphone_account_params_get_audio_video_conference_factory_address(params); const char *conference_factory_str = linphone_account_params_get_conference_factory_uri(params); LinphoneAddress *conference_factory = linphone_address_new(conference_factory_str); if ((audio_video_conference_factory && linphone_address_weak_equal(uri, audio_video_conference_factory)) || (conference_factory && linphone_address_weak_equal(uri, conference_factory))) { if (linphone_account_get_state(acc) == LinphoneRegistrationOk) { found_acc = acc; break; } else if (!found_reg_acc && linphone_account_params_get_register_enabled(params)) { found_reg_acc = acc; } else if (!found_noreg_acc) { found_noreg_acc = acc; } } if (conference_factory) { linphone_address_unref(conference_factory); } } if (!found_acc && found_reg_acc) found_acc = found_reg_acc; else if (!found_acc && found_noreg_acc) found_acc = found_noreg_acc; return found_acc; } /* * Returns an account matching the given identity address * Prefers registered, then first registering matching, otherwise first matching * returns NULL if none is found */ LinphoneAccount *linphone_core_lookup_account_by_identity_strict(LinphoneCore *lc, const LinphoneAddress *uri) { LinphoneAccount *found_acc = NULL; LinphoneAccount *found_reg_acc = NULL; LinphoneAccount *found_noreg_acc = NULL; const bctbx_list_t *elem; for (elem = linphone_core_get_account_list(lc); elem != NULL; elem = elem->next) { LinphoneAccount *acc = (LinphoneAccount *)elem->data; const LinphoneAccountParams *params = linphone_account_get_params(acc); if (linphone_address_weak_equal(uri, linphone_account_params_get_identity_address(params))) { if (linphone_account_get_state(acc) == LinphoneRegistrationOk) { found_acc = acc; break; } else if (!found_reg_acc && linphone_account_params_get_register_enabled(params)) { found_reg_acc = acc; } else if (!found_noreg_acc) { found_noreg_acc = acc; } } } if (!found_acc && found_reg_acc) found_acc = found_reg_acc; else if (!found_acc && found_noreg_acc) found_acc = found_noreg_acc; return found_acc; } /* * Returns an account matching the given identity address * Prefers registered, then first registering matching, otherwise first matching * returns default account if none is found */ LinphoneAccount *linphone_core_lookup_account_by_identity(LinphoneCore *lc, const LinphoneAddress *uri) { CoreLogContextualizer logContextualizer(lc); LinphoneAccount *found_acc = linphone_core_lookup_account_by_identity_strict(lc, uri); if (!found_acc) found_acc = lc->default_account; return found_acc; } LinphoneProxyConfig *linphone_core_lookup_known_proxy(LinphoneCore *lc, const LinphoneAddress *uri) { CoreLogContextualizer logContextualizer(lc); LinphoneAccount *account = linphone_core_lookup_known_account(lc, uri); return account ? Account::toCpp(account)->getConfig() : nullptr; }
4691469246934694469546964697469846994700470147024703470447054706470747084709471047114712471347144715471647174718471947204721472247234724472547264727472847294730473147324733473447354736473747384739474047414742474347444745474647474748474947504751475247534754475547564757475847594760
LinphoneProxyConfig * linphone_core_lookup_known_proxy_2(LinphoneCore *lc, const LinphoneAddress *uri, bool_t fallback_to_default) { LinphoneAccount *account = linphone_core_lookup_known_account_2(lc, uri, fallback_to_default); return account ? Account::toCpp(account)->getConfig() : nullptr; } LinphoneAccount *linphone_core_lookup_known_account(LinphoneCore *lc, const LinphoneAddress *uri) { CoreLogContextualizer logContextualizer(lc); return linphone_core_lookup_known_account_2(lc, uri, TRUE); } LinphoneAccount * linphone_core_lookup_known_account_2(LinphoneCore *lc, const LinphoneAddress *uri, bool_t fallback_to_default) { const bctbx_list_t *elem; LinphoneAccount *found_acc = NULL; LinphoneAccount *found_reg_acc = NULL; LinphoneAccount *found_noreg_acc = NULL; LinphoneAccount *default_acc = lc->default_account; if (!uri) { ms_error("Cannot look for account for NULL uri, returning default"); return default_acc; } if (linphone_address_get_domain(uri) == NULL) { ms_message("Cannot look for account for uri [%p] that has no domain set, returning default", uri); return default_acc; } /*return default account if it is matching the destination uri*/ if (default_acc) { const char *domain = linphone_account_params_get_domain(linphone_account_get_params(default_acc)); if (domain && !strcmp(domain, linphone_address_get_domain(uri))) { found_acc = default_acc; goto end; } } /*otherwise return first registered, then first registering matching, otherwise first matching */ for (elem = linphone_core_get_account_list(lc); elem != NULL; elem = elem->next) { LinphoneAccount *acc = (LinphoneAccount *)elem->data; const char *domain = linphone_account_params_get_domain(linphone_account_get_params(acc)); if (domain != NULL && strcmp(domain, linphone_address_get_domain(uri)) == 0) { if (linphone_account_get_state(acc) == LinphoneRegistrationOk) { found_acc = acc; break; } else if (!found_reg_acc && linphone_account_params_get_register_enabled(linphone_account_get_params(acc))) { found_reg_acc = acc; } else if (!found_noreg_acc) { found_noreg_acc = acc; } } } end: if (!found_acc && found_reg_acc) found_acc = found_reg_acc; else if (!found_acc && found_noreg_acc) found_acc = found_noreg_acc; if (found_acc && found_acc != default_acc) { ms_debug("Overriding default account setting for this call/message/subscribe operation."); } else if (fallback_to_default && !found_acc) { found_acc = default_acc; /*when no matching account is found, use the default account*/ } return found_acc; } const char *linphone_core_find_best_identity(LinphoneCore *lc, const LinphoneAddress *to) { CoreLogContextualizer logContextualizer(lc); LinphoneProxyConfig *cfg = linphone_core_lookup_known_proxy(lc, to); if (cfg != NULL) { return linphone_proxy_config_get_identity(cfg);
4761476247634764476547664767476847694770477147724773477447754776477747784779478047814782478347844785478647874788478947904791479247934794479547964797479847994800480148024803480448054806480748084809481048114812481348144815481648174818481948204821482248234824482548264827482848294830
} return linphone_core_get_primary_contact(lc); } LinphoneCall *linphone_core_invite(LinphoneCore *lc, const char *url) { CoreLogContextualizer logContextualizer(lc); LinphoneCall *call; LinphoneCallParams *p = linphone_core_create_call_params(lc, NULL); linphone_call_params_enable_video(p, linphone_call_params_video_enabled(p) && !!lc->video_policy.automatically_initiate); call = linphone_core_invite_with_params(lc, url, p); linphone_call_params_unref(p); return call; } LinphoneCall *linphone_core_invite_with_params(LinphoneCore *lc, const char *url, const LinphoneCallParams *p) { CoreLogContextualizer logContextualizer(lc); bool_t apply_prefix = TRUE; LinphoneAccount *account = linphone_core_get_default_account(lc); if (account) { const LinphoneAccountParams *params = linphone_account_get_params(account); apply_prefix = linphone_account_params_get_use_international_prefix_for_calls_and_chats(params); } LinphoneAddress *addr = linphone_core_interpret_url_2(lc, url, apply_prefix); if (addr) { LinphoneCall *call = linphone_core_invite_address_with_params(lc, addr, p); linphone_address_unref(addr); return call; } return NULL; } LinphoneCall *linphone_core_invite_address(LinphoneCore *lc, const LinphoneAddress *addr) { CoreLogContextualizer logContextualizer(lc); LinphoneCall *call; LinphoneCallParams *p = linphone_core_create_call_params(lc, NULL); linphone_call_params_enable_video(p, linphone_call_params_video_enabled(p) && !!lc->video_policy.automatically_initiate); call = linphone_core_invite_address_with_params(lc, addr, p); linphone_call_params_unref(p); return call; } static void linphone_transfer_routes_to_op(bctbx_list_t *routes, SalOp *op) { bctbx_list_t *it; for (it = routes; it != NULL; it = it->next) { SalAddress *addr = (SalAddress *)it->data; op->addRouteAddress(addr); sal_address_unref(addr); } bctbx_list_free(routes); } void linphone_configure_op_with_proxy(LinphoneCore *lc, SalOp *op, const LinphoneAddress *dest, SalCustomHeader *headers, bool_t with_contact, LinphoneProxyConfig *proxy) { bctbx_list_t *routes = NULL; const char *identity; if (proxy) { identity = linphone_proxy_config_get_identity(proxy); if (linphone_proxy_config_get_privacy(proxy) != LinphonePrivacyDefault) { op->setPrivacy(linphone_proxy_config_get_privacy(proxy)); } op->setRealm(L_C_TO_STRING(linphone_proxy_config_get_realm(proxy))); } else identity = linphone_core_get_primary_contact(lc); /*sending out of calls*/
4831483248334834483548364837483848394840484148424843484448454846484748484849485048514852485348544855485648574858485948604861486248634864486548664867486848694870487148724873487448754876487748784879488048814882488348844885488648874888488948904891489248934894489548964897489848994900
if (proxy) { routes = make_routes_for_proxy(proxy, dest); linphone_transfer_routes_to_op(routes, op); } op->setToAddress(Address::toCpp(dest)->getImpl()); op->setFrom(identity); op->setSentCustomHeaders(headers); if (with_contact && proxy && Account::toCpp(proxy->account)->getOp()) { const LinphoneAddress *contact = linphone_proxy_config_get_contact(proxy); SalAddress *salAddress = nullptr; if (contact) { const auto contact_addr = LinphonePrivate::Address::toCpp(contact)->getSharedFromThis(); salAddress = sal_address_clone(contact_addr->getImpl()); } op->setContactAddress(salAddress); if (salAddress) sal_address_unref(salAddress); } op->enableCnxIpTo0000IfSendOnly(!!linphone_config_get_default_int( lc->config, "sip", "cnx_ip_to_0000_if_sendonly_enabled", 0)); /*also set in linphone_call_new_incoming*/ } void linphone_configure_op_with_account(LinphoneCore *lc, SalOp *op, const LinphoneAddress *dest, SalCustomHeader *headers, bool_t with_contact, LinphoneAccount *account) { bctbx_list_t *routes = NULL; const char *identity; if (account) { identity = linphone_account_params_get_identity(linphone_account_get_params(account)); if (linphone_account_params_get_privacy(linphone_account_get_params(account)) != LinphonePrivacyDefault) { op->setPrivacy(linphone_account_params_get_privacy(linphone_account_get_params(account))); } } else identity = linphone_core_get_primary_contact(lc); /*sending out of calls*/ if (account) { routes = make_routes_for_account(account, dest); linphone_transfer_routes_to_op(routes, op); } op->setToAddress(LinphonePrivate::Address::toCpp(dest)->getImpl()); op->setFrom(identity); op->setSentCustomHeaders(headers); op->setRealm( L_C_TO_STRING(account ? linphone_account_params_get_realm(linphone_account_get_params(account)) : NULL)); if (with_contact && account && Account::toCpp(account)->getOp()) { const LinphoneAddress *contact = linphone_account_get_contact_address(account); SalAddress *salAddress = nullptr; if (contact) { const auto contact_addr = LinphonePrivate::Address::toCpp(contact)->getSharedFromThis(); salAddress = sal_address_clone(contact_addr->getImpl()); } op->setContactAddress(salAddress); if (salAddress) sal_address_unref(salAddress); } op->enableCnxIpTo0000IfSendOnly(!!linphone_config_get_default_int( lc->config, "sip", "cnx_ip_to_0000_if_sendonly_enabled", 0)); /*also set in linphone_call_new_incoming*/ } void linphone_configure_op( LinphoneCore *lc, SalOp *op, const LinphoneAddress *dest, SalCustomHeader *headers, bool_t with_contact) { linphone_configure_op_with_account(lc, op, dest, headers, with_contact, linphone_core_lookup_known_account(lc, dest)); }
4901490249034904490549064907490849094910491149124913491449154916491749184919492049214922492349244925492649274928492949304931493249334934493549364937493849394940494149424943494449454946494749484949495049514952495349544955495649574958495949604961496249634964496549664967496849694970
void linphone_configure_op_2(LinphoneCore *lc, SalOp *op, const LinphoneAddress *local, const LinphoneAddress *dest, SalCustomHeader *headers, bool_t with_contact) { linphone_configure_op_with_account(lc, op, dest, headers, with_contact, linphone_core_lookup_account_by_identity(lc, local)); } void linphone_core_set_media_resource_mode(LinphoneCore *lc, LinphoneMediaResourceMode mode) { linphone_config_set_int(linphone_core_get_config(lc), "misc", "media_resources_mode", mode); } LinphoneMediaResourceMode linphone_core_get_media_resource_mode(const LinphoneCore *lc) { return (LinphoneMediaResourceMode)linphone_config_get_int(linphone_core_get_config(lc), "misc", "media_resources_mode", LinphoneExclusiveMediaResources); } // This function states whether a locking of the sound resources is required based on the given call parameters bool_t linphone_core_sound_resources_need_locking(LinphoneCore *lc, const LinphoneCallParams *params) { return ((linphone_core_get_media_resource_mode(lc) == LinphoneExclusiveMediaResources) && linphone_call_params_audio_enabled(params) && linphone_call_params_get_audio_direction(params) != LinphoneMediaDirectionInactive && linphone_call_params_get_local_conference_mode(params) == FALSE); } LinphoneCall *linphone_core_invite_address_with_params(LinphoneCore *lc, const LinphoneAddress *addr, const LinphoneCallParams *params) { CoreLogContextualizer logContextualizer(lc); return linphone_core_invite_address_with_params_2(lc, addr, params, NULL, NULL); } LinphoneCall *linphone_core_invite_address_with_params_2(LinphoneCore *lc, const LinphoneAddress *addr, const LinphoneCallParams *params, const char *subject, const LinphoneContent *content) { CoreLogContextualizer logContextualizer(lc); const char *from = NULL; LinphoneProxyConfig *proxy = NULL; LinphoneAddress *parsed_url2 = NULL; LinphoneCall *call; LinphoneCallParams *cp; if (!addr) { ms_error("Can't invite a NULL address"); return NULL; } // Check that sound resources can be freed before moving on LinphoneCall *current_call = linphone_core_get_current_call(lc); if (current_call) { LinphoneCallState current_call_state = linphone_call_get_state(current_call); if (linphone_core_sound_resources_need_locking(lc, params) && ((current_call_state != LinphoneCallPausing) && (current_call_state != LinphoneCallPaused) && !Call::toCpp(current_call)->canSoundResourcesBeFreed())) { ms_error("linphone_core_invite_address_with_params(): sound are locked by another call and they cannot be " "freed. Call attempt is rejected."); return NULL; } } if (!L_GET_PRIVATE_FROM_C_OBJECT(lc)->canWeAddCall()) return NULL; proxy = linphone_call_params_get_proxy_config(params); if (proxy == NULL) proxy = linphone_core_lookup_known_proxy(lc, addr); cp = _linphone_call_params_copy(params);
4971497249734974497549764977497849794980498149824983498449854986498749884989499049914992499349944995499649974998499950005001500250035004500550065007500850095010501150125013501450155016501750185019502050215022502350245025502650275028502950305031503250335034503550365037503850395040
if (!linphone_call_params_has_avpf_enabled_been_set(cp)) { if (proxy != NULL) { linphone_call_params_enable_avpf(cp, linphone_proxy_config_avpf_enabled(proxy)); linphone_call_params_set_avpf_rr_interval( cp, (uint16_t)(linphone_proxy_config_get_avpf_rr_interval(proxy) * 1000)); } else { linphone_call_params_enable_avpf(cp, linphone_core_get_avpf_mode(lc) == LinphoneAVPFEnabled); if (linphone_call_params_avpf_enabled(cp)) linphone_call_params_set_avpf_rr_interval(cp, (uint16_t)(linphone_core_get_avpf_rr_interval(lc) * 1000)); } } // first check if the call params holds a from from = linphone_call_params_get_from_header(params); if ((from == NULL) && (proxy != NULL)) from = linphone_proxy_config_get_identity(proxy); /* if no proxy or no identity defined for this proxy, default to primary contact*/ if (from == NULL) from = linphone_core_get_primary_contact(lc); parsed_url2 = linphone_address_new(from); call = linphone_call_new_outgoing(lc, parsed_url2, addr, cp, proxy); linphone_address_unref(parsed_url2); if (L_GET_PRIVATE_FROM_C_OBJECT(lc)->addCall(Call::toCpp(call)->getSharedFromThis()) != 0) { ms_warning("we had a problem in adding the call into the invite ... weird"); linphone_call_unref(call); linphone_call_params_unref(cp); return NULL; } // Try to free up resources after adding it to the call list. // linphone_core_preempt_sound_resources tries to pause a call only if there is more than one in the list of core // stored in the core if (linphone_core_sound_resources_need_locking(lc, params) && (linphone_core_preempt_sound_resources(lc) == -1)) { ms_error("linphone_core_invite_address_with_params(): sound is required for this call but another call is " "already locking the sound resource. The call is automatically terminated."); linphone_call_terminate(call); return NULL; } /* Unless this call is for a conference, it becomes now the current one*/ if (linphone_call_params_get_local_conference_mode(params) == FALSE) L_GET_PRIVATE_FROM_C_OBJECT(lc)->setCurrentCall(Call::toCpp(call)->getSharedFromThis()); bool defer = Call::toCpp(call)->initiateOutgoing(L_C_TO_STRING(subject), content ? L_GET_CPP_PTR_FROM_C_OBJECT(content) : NULL); if (!defer) { if (Call::toCpp(call)->startInvite(NULL, L_C_TO_STRING(subject), content ? L_GET_CPP_PTR_FROM_C_OBJECT(content) : NULL) != 0) { /* The call has already gone to error and released state, so do not return it */ call = nullptr; } } linphone_call_params_unref(cp); return call; } LinphoneStatus linphone_core_transfer_call(BCTBX_UNUSED(LinphoneCore *lc), LinphoneCall *call, const char *url) { if (call == NULL) { ms_warning("No established call to refer."); return -1; } return linphone_call_transfer(call, url); } LinphoneStatus linphone_core_transfer_call_to_another(BCTBX_UNUSED(LinphoneCore *lc), LinphoneCall *call, LinphoneCall *dest) { return linphone_call_transfer_to_another(call, dest); }
5041504250435044504550465047504850495050505150525053505450555056505750585059506050615062506350645065506650675068506950705071507250735074507550765077507850795080508150825083508450855086508750885089509050915092509350945095509650975098509951005101510251035104510551065107510851095110
bool_t linphone_core_is_incoming_invite_pending(LinphoneCore *lc) { LinphoneCall *call = linphone_core_get_current_call(lc); if (call) { if ((linphone_call_get_dir(call) == LinphoneCallIncoming) && ((linphone_call_get_state(call) == LinphoneCallIncomingReceived) || (linphone_call_get_state(call) == LinphoneCallIncomingEarlyMedia))) return TRUE; } return FALSE; } LinphoneStatus linphone_core_accept_early_media_with_params(BCTBX_UNUSED(LinphoneCore *lc), LinphoneCall *call, const LinphoneCallParams *params) { return linphone_call_accept_early_media_with_params(call, params); } LinphoneStatus linphone_core_accept_early_media(BCTBX_UNUSED(LinphoneCore *lc), LinphoneCall *call) { return linphone_call_accept_early_media(call); } LinphoneStatus linphone_core_update_call(BCTBX_UNUSED(LinphoneCore *lc), LinphoneCall *call, const LinphoneCallParams *params) { return linphone_call_update(call, params); } LinphoneStatus linphone_core_defer_call_update(BCTBX_UNUSED(LinphoneCore *lc), LinphoneCall *call) { return linphone_call_defer_update(call); } LinphoneStatus linphone_core_accept_call_update(BCTBX_UNUSED(LinphoneCore *lc), LinphoneCall *call, const LinphoneCallParams *params) { return linphone_call_accept_update(call, params); } static LinphoneCall *get_unique_call(LinphoneCore *lc) { LinphoneCall *call = linphone_core_get_current_call(lc); if ((call == NULL) && (linphone_core_get_calls_nb(lc) == 1)) { call = (LinphoneCall *)bctbx_list_get_data(linphone_core_get_calls(lc)); } return call; } static LinphoneStatus _linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params) { if (call == NULL) { call = get_unique_call(lc); if (call == NULL) { ms_warning("No unique call to accept!"); return -1; } } return linphone_call_accept_with_params(call, params); } LinphoneStatus linphone_core_accept_call(LinphoneCore *lc, LinphoneCall *call) { return _linphone_core_accept_call_with_params(lc, call, NULL); } LinphoneStatus linphone_core_accept_call_with_params(LinphoneCore *lc, LinphoneCall *call, const LinphoneCallParams *params) { return _linphone_core_accept_call_with_params(lc, call, params); } LinphoneStatus linphone_core_redirect_call(BCTBX_UNUSED(LinphoneCore *lc), LinphoneCall *call, const char *redirect_uri) { return linphone_call_redirect(call, redirect_uri); }
5111511251135114511551165117511851195120512151225123512451255126512751285129513051315132513351345135513651375138513951405141514251435144514551465147514851495150515151525153515451555156515751585159516051615162516351645165516651675168516951705171517251735174517551765177517851795180
LinphoneStatus linphone_core_terminate_call(LinphoneCore *lc, LinphoneCall *call) { if (call == NULL) { call = get_unique_call(lc); if (call == NULL) { ms_warning("No unique call to terminate!"); return -1; } } return linphone_call_terminate(call); } LinphoneStatus linphone_core_terminate_all_calls(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); return L_GET_CPP_PTR_FROM_C_OBJECT(lc)->terminateAllCalls(); } LinphoneStatus linphone_core_decline_call(BCTBX_UNUSED(LinphoneCore *lc), LinphoneCall *call, LinphoneReason reason) { return linphone_call_decline(call, reason); } const bctbx_list_t *linphone_core_get_calls(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); if (lc->callsCache) { bctbx_list_free(lc->callsCache); lc->callsCache = NULL; } lc->callsCache = Call::getCListFromCppList(L_GET_CPP_PTR_FROM_C_OBJECT(lc)->getCalls(), false); return lc->callsCache; } LinphoneCall *linphone_core_get_call_by_callid(const LinphoneCore *lc, const char *call_id) { shared_ptr<LinphonePrivate::Call> call = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->getCallByCallId(call_id); return call ? call->toC() : NULL; } bool_t linphone_core_in_call(const LinphoneCore *lc) { return linphone_core_get_current_call((LinphoneCore *)lc) != NULL || linphone_core_is_in_conference(lc); } LinphoneCall *linphone_core_get_current_call(const LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); shared_ptr<LinphonePrivate::Call> call = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->getCurrentCall(); return call ? call->toC() : NULL; } LinphoneStatus linphone_core_pause_call(BCTBX_UNUSED(LinphoneCore *lc), LinphoneCall *call) { return linphone_call_pause(call); } LinphoneStatus linphone_core_pause_all_calls(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); return L_GET_CPP_PTR_FROM_C_OBJECT(lc)->pauseAllCalls(); } int linphone_core_preempt_sound_resources(LinphoneCore *lc) { LinphoneCall *current_call; int err = 0; if (linphone_core_is_in_conference(lc)) { linphone_core_leave_conference(lc); return 0; } current_call = linphone_core_get_current_call(lc); // If current call is not answered, do not try to pause it as user may take another one in the list of ringing calls if ((current_call != NULL) && (!linphone_core_is_incoming_invite_pending(lc))) { if (L_GET_CPP_PTR_FROM_C_OBJECT(lc)->getCalls().size() == 1) { /* * The current call is the unique one and is the call that requires the sound ressources.
5181518251835184518551865187518851895190519151925193519451955196519751985199520052015202520352045205520652075208520952105211521252135214521552165217521852195220522152225223522452255226522752285229523052315232523352345235523652375238523952405241524252435244524552465247524852495250
* This is the case of receiving an incoming call when there is no other one. It is then set as * current_call. */ return 0; } shared_ptr<LinphonePrivate::Call> cpp_call = Call::toCpp(current_call)->getSharedFromThis(); auto ms = static_pointer_cast<LinphonePrivate::MediaSession>(cpp_call->getActiveSession()); if (ms && L_GET_PRIVATE(ms)->getResultDesc() && L_GET_PRIVATE(ms)->getResultDesc()->hasDir(SalStreamSendOnly)) { ms_error("Trying to empty resources of a call whose SAL media direction is SendOnly - If you wish to do " "so, please set configuration parameter media_resources_mode to shared: " "linphone_core_set_media_resource_mode (lc, LinphoneSharedMediaResources)"); } else { ms_message("Pausing automatically the current call."); err = cpp_call->pause(); } } return err; } LinphoneStatus linphone_core_resume_call(BCTBX_UNUSED(LinphoneCore *lc), LinphoneCall *call) { return linphone_call_resume(call); } LinphoneCall *linphone_core_get_call_by_remote_address(const LinphoneCore *lc, const char *remote_address) { CoreLogContextualizer logContextualizer(lc); LinphoneCall *call = NULL; LinphoneAddress *raddr = linphone_address_new(remote_address); if (raddr) { call = linphone_core_get_call_by_remote_address2(lc, raddr); linphone_address_unref(raddr); } return call; } LinphoneCall *linphone_core_find_call_from_uri(const LinphoneCore *lc, const char *remote_address) { CoreLogContextualizer logContextualizer(lc); return linphone_core_get_call_by_remote_address(lc, remote_address); } LinphoneCall *linphone_core_get_call_by_remote_address2(const LinphoneCore *lc, const LinphoneAddress *raddr) { CoreLogContextualizer logContextualizer(lc); const auto remote_addr = LinphonePrivate::Address::toCpp(const_cast<LinphoneAddress *>(raddr))->getSharedFromThis(); shared_ptr<LinphonePrivate::Call> call = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->getCallByRemoteAddress(remote_addr); return call ? call->toC() : NULL; } int linphone_core_send_publish(LinphoneCore *lc, LinphonePresenceModel *presence) { CoreLogContextualizer logContextualizer(lc); const bctbx_list_t *elem; for (elem = linphone_core_get_account_list(lc); elem != NULL; elem = bctbx_list_next(elem)) { LinphoneAccount *acc = (LinphoneAccount *)elem->data; if (linphone_account_params_get_publish_enabled(linphone_account_get_params(acc))) { Account::toCpp(acc)->setPresenceModel(presence); Account::toCpp(acc)->sendPublish(); } } return 0; } void linphone_core_set_inc_timeout(LinphoneCore *lc, int seconds) { lc->sip_conf.inc_timeout = seconds; if (linphone_core_ready(lc)) { linphone_config_set_int(lc->config, "sip", "inc_timeout", seconds); } } int linphone_core_get_inc_timeout(LinphoneCore *lc) { return lc->sip_conf.inc_timeout; }
5251525252535254525552565257525852595260526152625263526452655266526752685269527052715272527352745275527652775278527952805281528252835284528552865287528852895290529152925293529452955296529752985299530053015302530353045305530653075308530953105311531253135314531553165317531853195320
void linphone_core_set_push_incoming_call_timeout(LinphoneCore *lc, int seconds) { lc->sip_conf.push_incoming_call_timeout = seconds; if (linphone_core_ready(lc)) { linphone_config_set_int(lc->config, "sip", "push_incoming_call_timeout", seconds); } } int linphone_core_get_push_incoming_call_timeout(const LinphoneCore *lc) { return lc->sip_conf.push_incoming_call_timeout; } void linphone_core_set_in_call_timeout(LinphoneCore *lc, int seconds) { lc->sip_conf.in_call_timeout = seconds; if (linphone_core_ready(lc)) { linphone_config_set_int(lc->config, "sip", "in_call_timeout", seconds); } } int linphone_core_get_in_call_timeout(LinphoneCore *lc) { return lc->sip_conf.in_call_timeout; } int linphone_core_get_delayed_timeout(LinphoneCore *lc) { return lc->sip_conf.delayed_timeout; } void linphone_core_set_delayed_timeout(LinphoneCore *lc, int seconds) { lc->sip_conf.delayed_timeout = seconds; } int linphone_core_get_max_size_for_auto_download_incoming_files(LinphoneCore *lc) { return lc->auto_download_incoming_files_max_size; } void linphone_core_set_max_size_for_auto_download_incoming_files(LinphoneCore *lc, int size) { lc->auto_download_incoming_files_max_size = size; linphone_config_set_int(lc->config, "app", "auto_download_incoming_files_max_size", size); } bool_t linphone_core_is_auto_download_voice_recordings_enabled(LinphoneCore *lc) { return linphone_core_auto_download_voice_recordings_enabled(lc); } bool_t linphone_core_auto_download_voice_recordings_enabled(LinphoneCore *core) { return core->auto_download_incoming_voice_recordings; } void linphone_core_set_auto_download_voice_recordings_enabled(LinphoneCore *lc, bool_t auto_download_voice_recordings) { linphone_core_enable_auto_download_voice_recordings(lc, auto_download_voice_recordings); } void linphone_core_enable_auto_download_voice_recordings(LinphoneCore *core, bool_t auto_download_voice_recordings) { core->auto_download_incoming_voice_recordings = auto_download_voice_recordings; linphone_config_set_bool(core->config, "app", "auto_download_incoming_voice_recordings", auto_download_voice_recordings); } bool_t linphone_core_is_auto_download_icalendars_enabled(LinphoneCore *lc) { return linphone_core_auto_download_icalendars_enabled(lc); } bool_t linphone_core_auto_download_icalendars_enabled(LinphoneCore *core) { return core->auto_download_incoming_icalendars; } void linphone_core_set_auto_download_icalendars_enabled(LinphoneCore *lc, bool_t auto_download_icalendars) { linphone_core_enable_auto_download_icalendars(lc, auto_download_icalendars); }
5321532253235324532553265327532853295330533153325333533453355336533753385339534053415342534353445345534653475348534953505351535253535354535553565357535853595360536153625363536453655366536753685369537053715372537353745375537653775378537953805381538253835384538553865387538853895390
void linphone_core_enable_auto_download_icalendars(LinphoneCore *core, bool_t auto_download_icalendars) { core->auto_download_incoming_icalendars = auto_download_icalendars; linphone_config_set_bool(core->config, "app", "auto_download_incoming_icalendars", auto_download_icalendars); } bool_t linphone_core_is_sender_name_hidden_in_forward_message(LinphoneCore *lc) { return lc->sender_name_hidden_in_forward_message; } void linphone_core_enable_sender_name_hidden_in_forward_message(LinphoneCore *lc, bool_t enable) { lc->sender_name_hidden_in_forward_message = enable; linphone_config_set_int(lc->config, "app", "sender_name_hidden_in_forward_message", enable); } bool_t linphone_core_is_record_aware_enabled(LinphoneCore *lc) { return linphone_core_record_aware_enabled(lc); } bool_t linphone_core_record_aware_enabled(LinphoneCore *core) { return core->record_aware; } void linphone_core_set_record_aware_enabled(LinphoneCore *lc, bool_t enable) { linphone_core_enable_record_aware(lc, enable); } void linphone_core_enable_record_aware(LinphoneCore *core, bool_t enable) { core->record_aware = enable; linphone_config_set_bool(core->config, "app", "record_aware", enable); if (enable) { linphone_core_add_supported_tag(core, "record-aware"); } else { linphone_core_remove_supported_tag(core, "record-aware"); } } bool_t linphone_core_auto_send_ringing_enabled(LinphoneCore *lc) { return lc->auto_send_ringing; } void linphone_core_enable_auto_send_ringing(LinphoneCore *lc, bool_t enable) { lc->auto_send_ringing = enable; linphone_config_set_bool(lc->config, "sip", "auto_send_ringing", enable); } void linphone_core_set_presence_info(LinphoneCore *lc, int minutes_away, const char *contact, LinphoneOnlineStatus os) { CoreLogContextualizer logContextualizer(lc); LinphonePresenceModel *presence = NULL; LinphonePresenceActivity *activity = NULL; const char *description = NULL; LinphonePresenceActivityType acttype = LinphonePresenceActivityUnknown; if (minutes_away > 0) lc->minutes_away = minutes_away; presence = linphone_presence_model_new(); linphone_presence_model_set_basic_status(presence, LinphonePresenceBasicStatusOpen); switch (os) { case LinphoneStatusOffline: linphone_presence_model_set_basic_status(presence, LinphonePresenceBasicStatusClosed); goto end; case LinphoneStatusOnline: goto end; case LinphoneStatusBusy: acttype = LinphonePresenceActivityBusy; break; case LinphoneStatusBeRightBack: acttype = LinphonePresenceActivityInTransit; break; case LinphoneStatusAway:
5391539253935394539553965397539853995400540154025403540454055406540754085409541054115412541354145415541654175418541954205421542254235424542554265427542854295430543154325433543454355436543754385439544054415442544354445445544654475448544954505451545254535454545554565457545854595460
acttype = LinphonePresenceActivityAway; break; case LinphoneStatusOnThePhone: acttype = LinphonePresenceActivityOnThePhone; break; case LinphoneStatusOutToLunch: acttype = LinphonePresenceActivityLunch; break; case LinphoneStatusDoNotDisturb: acttype = LinphonePresenceActivityBusy; description = "Do not disturb"; linphone_presence_model_set_basic_status(presence, LinphonePresenceBasicStatusClosed); break; case LinphoneStatusMoved: acttype = LinphonePresenceActivityPermanentAbsence; break; case LinphoneStatusAltService: acttype = LinphonePresenceActivityBusy; description = "Using another messaging service"; break; case LinphoneStatusPending: acttype = LinphonePresenceActivityOther; description = "Waiting for user acceptance"; break; case LinphoneStatusVacation: acttype = LinphonePresenceActivityVacation; break; case LinphoneStatusEnd: ms_warning("Invalid status LinphoneStatusEnd"); return; } activity = linphone_presence_activity_new(acttype, description); linphone_presence_model_add_activity(presence, activity); linphone_presence_activity_unref(activity); end: linphone_presence_model_set_contact(presence, contact); linphone_core_set_presence_model(lc, presence); linphone_presence_model_unref(presence); } void linphone_core_send_presence(LinphoneCore *lc, LinphonePresenceModel *presence) { CoreLogContextualizer logContextualizer(lc); linphone_core_notify_all_friends(lc, presence); linphone_core_send_publish(lc, presence); } void linphone_core_set_presence_model(LinphoneCore *lc, LinphonePresenceModel *presence) { CoreLogContextualizer logContextualizer(lc); linphone_core_send_presence(lc, presence); if (lc->presence_model != NULL) { linphone_presence_model_unref(lc->presence_model); lc->presence_model = NULL; } if (presence) lc->presence_model = linphone_presence_model_ref(presence); } LinphoneOnlineStatus linphone_core_get_presence_info(const LinphoneCore *lc) { LinphonePresenceActivity *activity = NULL; const char *description = NULL; activity = linphone_presence_model_get_activity(lc->presence_model); if (activity) { description = linphone_presence_activity_get_description(activity); switch (linphone_presence_activity_get_type(activity)) { case LinphonePresenceActivityBusy: if (description != NULL) { if (strcmp(description, "Do not disturb") == 0) return LinphoneStatusDoNotDisturb; else if (strcmp(description, "Using another messaging service") == 0) return LinphoneStatusAltService;
5461546254635464546554665467546854695470547154725473547454755476547754785479548054815482548354845485548654875488548954905491549254935494549554965497549854995500550155025503550455055506550755085509551055115512551355145515551655175518551955205521552255235524552555265527552855295530
} return LinphoneStatusBusy; case LinphonePresenceActivityInTransit: case LinphonePresenceActivitySteering: return LinphoneStatusBeRightBack; case LinphonePresenceActivityAway: return LinphoneStatusAway; case LinphonePresenceActivityOnThePhone: return LinphoneStatusOnThePhone; case LinphonePresenceActivityBreakfast: case LinphonePresenceActivityDinner: case LinphonePresenceActivityLunch: case LinphonePresenceActivityMeal: return LinphoneStatusOutToLunch; case LinphonePresenceActivityPermanentAbsence: return LinphoneStatusMoved; case LinphonePresenceActivityOther: if (description != NULL) { if (strcmp(description, "Waiting for user acceptance") == 0) return LinphoneStatusPending; } return LinphoneStatusBusy; case LinphonePresenceActivityVacation: return LinphoneStatusVacation; case LinphonePresenceActivityAppointment: case LinphonePresenceActivityMeeting: case LinphonePresenceActivityWorship: return LinphoneStatusDoNotDisturb; default: return LinphoneStatusBusy; } } else { if (linphone_presence_model_get_basic_status(lc->presence_model) == LinphonePresenceBasicStatusOpen) return LinphoneStatusOnline; else return LinphoneStatusOffline; } } LinphonePresenceModel *linphone_core_get_presence_model(const LinphoneCore *lc) { return lc->presence_model; } LinphoneConsolidatedPresence linphone_core_get_consolidated_presence(const LinphoneCore *lc) { LinphoneProxyConfig *cfg = lc->default_proxy; LinphonePresenceModel *model = linphone_core_get_presence_model(lc); return ((cfg && !linphone_proxy_config_publish_enabled(cfg)) || !model) ? LinphoneConsolidatedPresenceOffline : linphone_presence_model_get_consolidated_presence(model); } void linphone_core_set_consolidated_presence(LinphoneCore *lc, LinphoneConsolidatedPresence presence) { const bctbx_list_t *cfg_list; const bctbx_list_t *item; LinphoneProxyConfig *cfg; LinphonePresenceModel *model; LinphonePresenceActivity *activity = NULL; cfg_list = linphone_core_get_proxy_config_list(lc); if (presence == LinphoneConsolidatedPresenceOffline) { for (item = cfg_list; item != NULL; item = bctbx_list_next(item)) { cfg = (LinphoneProxyConfig *)bctbx_list_get_data(item); if ((cfg != NULL) && linphone_proxy_config_publish_enabled(cfg)) { /* Unpublish when going offline before changing the presence model. */ linphone_proxy_config_edit(cfg); linphone_proxy_config_enable_publish(cfg, FALSE); linphone_proxy_config_done(cfg); } } } model = linphone_presence_model_new();
5531553255335534553555365537553855395540554155425543554455455546554755485549555055515552555355545555555655575558555955605561556255635564556555665567556855695570557155725573557455755576557755785579558055815582558355845585558655875588558955905591559255935594559555965597559855995600
switch (presence) { case LinphoneConsolidatedPresenceOnline: linphone_presence_model_set_basic_status(model, LinphonePresenceBasicStatusOpen); break; case LinphoneConsolidatedPresenceBusy: linphone_presence_model_set_basic_status(model, LinphonePresenceBasicStatusOpen); activity = linphone_presence_activity_new(LinphonePresenceActivityAway, NULL); break; case LinphoneConsolidatedPresenceDoNotDisturb: linphone_presence_model_set_basic_status(model, LinphonePresenceBasicStatusClosed); activity = linphone_presence_activity_new(LinphonePresenceActivityAway, NULL); break; case LinphoneConsolidatedPresenceOffline: default: linphone_presence_model_set_basic_status(model, LinphonePresenceBasicStatusClosed); break; } if (activity != NULL) { linphone_presence_model_add_activity(model, activity); linphone_presence_activity_unref(activity); } linphone_core_set_presence_model(lc, model); linphone_presence_model_unref(model); if (presence != LinphoneConsolidatedPresenceOffline) { for (item = cfg_list; item != NULL; item = bctbx_list_next(item)) { cfg = (LinphoneProxyConfig *)bctbx_list_get_data(item); if ((cfg != NULL) && !linphone_proxy_config_publish_enabled(cfg)) { /* When going online or busy, publish after changing the presence model. */ linphone_proxy_config_edit(cfg); linphone_proxy_config_enable_publish(cfg, TRUE); linphone_proxy_config_done(cfg); } } } } int linphone_core_get_play_level(LinphoneCore *lc) { return lc->sound_conf.play_lev; } int linphone_core_get_ring_level(LinphoneCore *lc) { return lc->sound_conf.ring_lev; } int linphone_core_get_rec_level(LinphoneCore *lc) { return lc->sound_conf.rec_lev; } int linphone_core_get_media_level(LinphoneCore *lc) { return lc->sound_conf.media_lev; } void linphone_core_set_ring_level(LinphoneCore *lc, int level) { MSSndCard *sndcard; lc->sound_conf.ring_lev = (char)level; sndcard = lc->sound_conf.ring_sndcard; if (sndcard) ms_snd_card_set_level(sndcard, MS_SND_CARD_PLAYBACK, level); } void linphone_core_set_mic_gain_db(LinphoneCore *lc, float gaindb) { CoreLogContextualizer logContextualizer(lc); float gain = gaindb; LinphoneCall *call = linphone_core_get_current_call(lc); AudioStream *st; lc->sound_conf.soft_mic_lev = gaindb; if (linphone_core_ready(lc)) {
5601560256035604560556065607560856095610561156125613561456155616561756185619562056215622562356245625562656275628562956305631563256335634563556365637563856395640564156425643564456455646564756485649565056515652565356545655565656575658565956605661566256635664566556665667566856695670
linphone_config_set_float(lc->config, "sound", "mic_gain_db", lc->sound_conf.soft_mic_lev); } if (!call || !(st = reinterpret_cast<AudioStream *>(linphone_call_get_stream(call, LinphoneStreamTypeAudio)))) { ms_message("linphone_core_set_mic_gain_db(): no active call."); return; } audio_stream_set_mic_gain_db(st, gain); } bool_t linphone_core_get_disable_record_on_mute(LinphoneCore *lc) { return lc->sound_conf.disable_record_on_mute; } void linphone_core_set_disable_record_on_mute(LinphoneCore *lc, bool_t disable) { lc->sound_conf.disable_record_on_mute = disable; if (linphone_core_ready(lc)) { linphone_config_set_bool(lc->config, "sound", "disable_record_on_mute", lc->sound_conf.disable_record_on_mute); } } float linphone_core_get_mic_gain_db(LinphoneCore *lc) { return lc->sound_conf.soft_mic_lev; } void linphone_core_set_playback_gain_db(LinphoneCore *lc, float gaindb) { CoreLogContextualizer logContextualizer(lc); float gain = gaindb; LinphoneCall *call = linphone_core_get_current_call(lc); AudioStream *st; lc->sound_conf.soft_play_lev = gaindb; if (linphone_core_ready(lc)) { linphone_config_set_float(lc->config, "sound", "playback_gain_db", lc->sound_conf.soft_play_lev); } if (!call || !(st = reinterpret_cast<AudioStream *>(linphone_call_get_stream(call, LinphoneStreamTypeAudio)))) { ms_message("linphone_core_set_playback_gain_db(): no active call."); return; } set_playback_gain_db(st, gain); } float linphone_core_get_playback_gain_db(LinphoneCore *lc) { return lc->sound_conf.soft_play_lev; } void linphone_core_set_play_level(LinphoneCore *lc, int level) { MSSndCard *sndcard; lc->sound_conf.play_lev = (char)level; sndcard = lc->sound_conf.play_sndcard; if (sndcard) ms_snd_card_set_level(sndcard, MS_SND_CARD_PLAYBACK, level); } void linphone_core_set_rec_level(LinphoneCore *lc, int level) { MSSndCard *sndcard; lc->sound_conf.rec_lev = (char)level; sndcard = lc->sound_conf.capt_sndcard; if (sndcard) ms_snd_card_set_level(sndcard, MS_SND_CARD_CAPTURE, level); } void linphone_core_set_media_level(LinphoneCore *lc, int level) { MSSndCard *sndcard; lc->sound_conf.media_lev = (char)level; sndcard = lc->sound_conf.media_sndcard; if (sndcard) ms_snd_card_set_level(sndcard, MS_SND_CARD_PLAYBACK, level); } static MSSndCard *get_card_from_string_id(const char *devid, unsigned int cap, MSFactory *f) {
5671567256735674567556765677567856795680568156825683568456855686568756885689569056915692569356945695569656975698569957005701570257035704570557065707570857095710571157125713571457155716571757185719572057215722572357245725572657275728572957305731573257335734573557365737573857395740
MSSndCard *sndcard = NULL; if (devid != NULL) { sndcard = ms_snd_card_manager_get_card_with_capabilities(ms_factory_get_snd_card_manager(f), devid, cap); if (sndcard != NULL && (ms_snd_card_get_capabilities(sndcard) & cap) == 0) { ms_warning("%s card does not have the %s capability, ignoring.", devid, cap == MS_SND_CARD_CAP_CAPTURE ? "capture" : "playback"); sndcard = NULL; } if (sndcard == NULL) ms_warning("Can't find sound device with id %s", devid); } if (sndcard == NULL) { if ((cap & MS_SND_CARD_CAP_CAPTURE) && (cap & MS_SND_CARD_CAP_PLAYBACK)) { sndcard = ms_snd_card_manager_get_default_card(ms_factory_get_snd_card_manager(f)); } else if (cap & MS_SND_CARD_CAP_CAPTURE) { sndcard = ms_snd_card_manager_get_default_capture_card(ms_factory_get_snd_card_manager(f)); } else if (cap & MS_SND_CARD_CAP_PLAYBACK) { sndcard = ms_snd_card_manager_get_default_playback_card(ms_factory_get_snd_card_manager(f)); } else { /*looks like a bug from capabilities! take the first one !*/ const bctbx_list_t *elem = ms_snd_card_manager_get_list(ms_factory_get_snd_card_manager(f)); if (elem) sndcard = (MSSndCard *)elem->data; } } if (sndcard == NULL) ms_error("Could not find a suitable soundcard with capabilities : %d", cap); return sndcard; } bool_t linphone_core_sound_device_can_capture(LinphoneCore *lc, const char *devid) { return ms_snd_card_manager_get_capture_card(ms_factory_get_snd_card_manager(lc->factory), devid) != NULL; } bool_t linphone_core_sound_device_can_playback(LinphoneCore *lc, const char *devid) { return ms_snd_card_manager_get_playback_card(ms_factory_get_snd_card_manager(lc->factory), devid) != NULL; } LinphoneStatus linphone_core_set_ringer_device(LinphoneCore *lc, const char *devid) { MSSndCard *card = get_card_from_string_id(devid, MS_SND_CARD_CAP_PLAYBACK, lc->factory); if (lc->sound_conf.ring_sndcard) { ms_snd_card_unref(lc->sound_conf.ring_sndcard); lc->sound_conf.ring_sndcard = NULL; } if (card) lc->sound_conf.ring_sndcard = ms_snd_card_ref(card); if (card && (linphone_core_ready(lc) || !devid || strcmp(devid, ms_snd_card_get_string_id(card)) != 0)) linphone_config_set_string(lc->config, "sound", "ringer_dev_id", ms_snd_card_get_string_id(card)); return 0; } LinphoneStatus linphone_core_set_playback_device(LinphoneCore *lc, const char *devid) { MSSndCard *card = get_card_from_string_id(devid, MS_SND_CARD_CAP_PLAYBACK, lc->factory); if (lc->sound_conf.play_sndcard) { ms_snd_card_unref(lc->sound_conf.play_sndcard); lc->sound_conf.play_sndcard = NULL; } if (card) lc->sound_conf.play_sndcard = ms_snd_card_ref(card); if (card && (linphone_core_ready(lc) || !devid || strcmp(devid, ms_snd_card_get_string_id(card)) != 0)) linphone_config_set_string(lc->config, "sound", "playback_dev_id", ms_snd_card_get_string_id(card)); return 0; } LinphoneStatus linphone_core_set_capture_device(LinphoneCore *lc, const char *devid) { MSSndCard *card = get_card_from_string_id(devid, MS_SND_CARD_CAP_CAPTURE, lc->factory); if (lc->sound_conf.capt_sndcard) { ms_snd_card_unref(lc->sound_conf.capt_sndcard); lc->sound_conf.capt_sndcard = NULL; } if (card) lc->sound_conf.capt_sndcard = ms_snd_card_ref(card); if (card && (linphone_core_ready(lc) || !devid || strcmp(devid, ms_snd_card_get_string_id(card)) != 0)) linphone_config_set_string(lc->config, "sound", "capture_dev_id", ms_snd_card_get_string_id(card)); return 0; }
5741574257435744574557465747574857495750575157525753575457555756575757585759576057615762576357645765576657675768576957705771577257735774577557765777577857795780578157825783578457855786578757885789579057915792579357945795579657975798579958005801580258035804580558065807580858095810
LinphoneStatus linphone_core_set_media_device(LinphoneCore *lc, const char *devid) { MSSndCard *card = get_card_from_string_id(devid, MS_SND_CARD_CAP_PLAYBACK, lc->factory); if (lc->sound_conf.media_sndcard) { ms_snd_card_unref(lc->sound_conf.media_sndcard); lc->sound_conf.media_sndcard = NULL; } if (card) lc->sound_conf.media_sndcard = ms_snd_card_ref(card); if (card && (linphone_core_ready(lc) || !devid || strcmp(devid, ms_snd_card_get_string_id(card)) != 0)) linphone_config_set_string(lc->config, "sound", "media_dev_id", ms_snd_card_get_string_id(card)); return 0; } LinphoneStatus linphone_core_set_output_audio_device_by_id(LinphoneCore *lc, const char *devid) { MSSndCard *card = get_card_from_string_id(devid, MS_SND_CARD_CAP_PLAYBACK, lc->factory); L_GET_CPP_PTR_FROM_C_OBJECT(lc)->setOutputAudioDeviceBySndCard(card); return 0; } LinphoneStatus linphone_core_set_input_audio_device_by_id(LinphoneCore *lc, const char *devid) { MSSndCard *card = get_card_from_string_id(devid, MS_SND_CARD_CAP_CAPTURE, lc->factory); L_GET_CPP_PTR_FROM_C_OBJECT(lc)->setInputAudioDeviceBySndCard(card); return 0; } const char *linphone_core_get_ringer_device(LinphoneCore *lc) { if (lc->sound_conf.ring_sndcard) return ms_snd_card_get_string_id(lc->sound_conf.ring_sndcard); return NULL; } const char *linphone_core_get_playback_device(LinphoneCore *lc) { return lc->sound_conf.play_sndcard ? ms_snd_card_get_string_id(lc->sound_conf.play_sndcard) : NULL; } const char *linphone_core_get_capture_device(LinphoneCore *lc) { return lc->sound_conf.capt_sndcard ? ms_snd_card_get_string_id(lc->sound_conf.capt_sndcard) : NULL; } const char *linphone_core_get_media_device(LinphoneCore *lc) { return lc->sound_conf.media_sndcard ? ms_snd_card_get_string_id(lc->sound_conf.media_sndcard) : NULL; } const char **linphone_core_get_sound_devices(LinphoneCore *lc) { return lc->sound_conf.cards; } const char **linphone_core_get_video_devices(const LinphoneCore *lc) { return lc->video_conf.cams; } bctbx_list_t *linphone_core_get_sound_devices_list(const LinphoneCore *lc) { bctbx_list_t *cards_list = NULL; const char **cards = lc->sound_conf.cards; if (cards) { for (const char *c = *cards; c; c = *++cards) { cards_list = bctbx_list_append(cards_list, bctbx_strdup(c)); } } return cards_list; } bctbx_list_t *linphone_core_get_video_devices_list(const LinphoneCore *lc) { bctbx_list_t *cards_list = NULL; const char **cards = lc->video_conf.cams; if (cards) { for (const char *c = *cards; c; c = *++cards) cards_list = bctbx_list_append(cards_list, bctbx_strdup(c)); }
5811581258135814581558165817581858195820582158225823582458255826582758285829583058315832583358345835583658375838583958405841584258435844584558465847584858495850585158525853585458555856585758585859586058615862586358645865586658675868586958705871587258735874587558765877587858795880
return cards_list; } void linphone_core_set_default_sound_devices(LinphoneCore *lc) { linphone_core_set_ringer_device(lc, NULL); linphone_core_set_playback_device(lc, NULL); linphone_core_set_capture_device(lc, NULL); linphone_core_set_media_device(lc, NULL); } void linphone_core_reload_sound_devices(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); const char *ringer; const char *playback; const char *capture; const char *output_dev_id; const char *input_dev_id; char *ringer_copy = NULL; char *playback_copy = NULL; char *capture_copy = NULL; char *output_dev_id_copy = NULL; char *input_dev_id_copy = NULL; // Get current selection before reloading ringer = linphone_core_get_ringer_device(lc); if (ringer != NULL) { ringer_copy = ms_strdup(ringer); } playback = linphone_core_get_playback_device(lc); if (playback != NULL) { playback_copy = ms_strdup(playback); } capture = linphone_core_get_capture_device(lc); if (capture != NULL) { capture_copy = ms_strdup(capture); } const LinphoneAudioDevice *current_output_dev = linphone_core_get_output_audio_device(lc); if (current_output_dev != NULL) { output_dev_id = linphone_audio_device_get_id(current_output_dev); if (output_dev_id != NULL) { output_dev_id_copy = ms_strdup(output_dev_id); } } const LinphoneAudioDevice *current_input_dev = linphone_core_get_input_audio_device(lc); if (current_input_dev != NULL) { input_dev_id = linphone_audio_device_get_id(current_input_dev); if (input_dev_id != NULL) { input_dev_id_copy = ms_strdup(input_dev_id); } } // Reload ms_snd_card_manager_reload(ms_factory_get_snd_card_manager(lc->factory)); build_sound_devices_table(lc); // Set selection linphone_core_set_ringer_device(lc, ringer_copy); if (ringer_copy != NULL) ms_free(ringer_copy); linphone_core_set_playback_device(lc, playback_copy); if (playback_copy != NULL) ms_free(playback_copy); linphone_core_set_capture_device(lc, capture_copy); if (capture_copy != NULL) ms_free(capture_copy); linphone_core_set_output_audio_device_by_id(lc, output_dev_id_copy); if (output_dev_id_copy != NULL) ms_free(output_dev_id_copy); linphone_core_set_input_audio_device_by_id(lc, input_dev_id_copy); if (input_dev_id_copy != NULL) ms_free(input_dev_id_copy); // Wait to have restored previous sound cards to notify list has been updated // Otherwise app won't be able to change audio device in callback
5881588258835884588558865887588858895890589158925893589458955896589758985899590059015902590359045905590659075908590959105911591259135914591559165917591859195920592159225923592459255926592759285929593059315932593359345935593659375938593959405941594259435944594559465947594859495950
linphone_core_notify_audio_devices_list_updated(lc); } void linphone_core_reload_video_devices(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); char *devid_copy = NULL; const char *devid = linphone_core_get_video_device(lc); if (devid != NULL) { devid_copy = ms_strdup(devid); } ms_web_cam_manager_reload(ms_factory_get_web_cam_manager(lc->factory)); build_video_devices_table(lc); if (devid_copy != NULL) { linphone_core_set_video_device(lc, devid_copy); ms_free(devid_copy); } } char linphone_core_get_sound_source(LinphoneCore *lc) { return lc->sound_conf.source; } void linphone_core_set_sound_source(LinphoneCore *lc, char source) { MSSndCard *sndcard = lc->sound_conf.capt_sndcard; lc->sound_conf.source = source; if (!sndcard) return; switch (source) { case 'm': ms_snd_card_set_capture(sndcard, MS_SND_CARD_MIC); break; case 'l': ms_snd_card_set_capture(sndcard, MS_SND_CARD_LINE); break; } } LinphoneRecorderParams *linphone_core_create_recorder_params(const LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); LinphoneRecorderParams *params = linphone_recorder_params_new(); const LinphoneAudioDevice *device = linphone_core_get_default_input_audio_device(lc); linphone_recorder_params_set_audio_device(params, device); return params; } LinphoneRecorder *linphone_core_create_recorder(LinphoneCore *lc, LinphoneRecorderParams *params) { CoreLogContextualizer logContextualizer(lc); return linphone_recorder_new(lc, params); } void linphone_core_set_ring(LinphoneCore *lc, const char *path) { if (lc->sound_conf.local_ring != 0) { ms_free(lc->sound_conf.local_ring); lc->sound_conf.local_ring = NULL; } if (path) lc->sound_conf.local_ring = ms_strdup(path); if (linphone_core_ready(lc)) linphone_config_set_string(lc->config, "sound", "local_ring", lc->sound_conf.local_ring); } const char *linphone_core_get_ring(const LinphoneCore *lc) { return lc->sound_conf.local_ring; } void linphone_core_set_native_ringing_enabled(LinphoneCore *core, bool_t enable) { linphone_core_enable_native_ringing(core, enable); } void linphone_core_enable_native_ringing(LinphoneCore *core, bool_t enable) { CoreLogContextualizer logContextualizer(core); core->native_ringing_enabled = enable;
5951595259535954595559565957595859595960596159625963596459655966596759685969597059715972597359745975597659775978597959805981598259835984598559865987598859895990599159925993599459955996599759985999600060016002600360046005600660076008600960106011601260136014601560166017601860196020
linphone_config_set_int(core->config, "sound", "use_native_ringing", enable); if (enable == FALSE && linphone_core_get_ring(core) == NULL) { ms_warning( "Native ringing has been disabled but no ringtone has been defined in sound config, using default one"); linphone_core_set_ring(core, get_default_local_ring(core).c_str()); } } bool_t linphone_core_is_native_ringing_enabled(const LinphoneCore *core) { return linphone_core_native_ringing_enabled(core); } bool_t linphone_core_native_ringing_enabled(const LinphoneCore *core) { return core->native_ringing_enabled; } void linphone_core_set_root_ca(LinphoneCore *lc, const char *path) { lc->sal->setRootCa(L_C_TO_STRING(path)); if (lc->http_crypto_config) { belle_tls_crypto_config_set_root_ca(lc->http_crypto_config, path); } linphone_config_set_string(lc->config, "sip", "root_ca", path); } void linphone_core_set_root_ca_data(LinphoneCore *lc, const char *data) { lc->sal->setRootCa(""); lc->sal->setRootCaData(L_C_TO_STRING(data)); if (lc->http_crypto_config) { belle_tls_crypto_config_set_root_ca_data(lc->http_crypto_config, data); } } const char *linphone_core_get_root_ca(LinphoneCore *lc) { return linphone_config_get_string(lc->config, "sip", "root_ca", NULL); } void linphone_core_verify_server_certificates(LinphoneCore *lc, bool_t yesno) { lc->sal->verifyServerCertificates(!!yesno); if (lc->http_crypto_config) { belle_tls_crypto_config_set_verify_exceptions(lc->http_crypto_config, yesno ? 0 : BELLE_TLS_VERIFY_ANY_REASON); } linphone_config_set_int(lc->config, "sip", "verify_server_certs", yesno); } bool_t linphone_core_is_verify_server_certificates(LinphoneCore *lc) { return !!linphone_config_get_int(lc->config, "sip", "verify_server_certs", TRUE); } void linphone_core_verify_server_cn(LinphoneCore *lc, bool_t yesno) { lc->sal->verifyServerCn(!!yesno); if (lc->http_crypto_config) { belle_tls_crypto_config_set_verify_exceptions(lc->http_crypto_config, yesno ? 0 : BELLE_TLS_VERIFY_CN_MISMATCH); } linphone_config_set_int(lc->config, "sip", "verify_server_cn", yesno); } bool_t linphone_core_is_verify_server_cn(LinphoneCore *lc) { return !!linphone_config_get_int(lc->config, "sip", "verify_server_cn", TRUE); } void linphone_core_set_ssl_config(LinphoneCore *lc, void *ssl_config) { lc->sal->setSslConfig(ssl_config); if (lc->http_crypto_config) { belle_tls_crypto_config_set_ssl_config(lc->http_crypto_config, ssl_config); } } static void notify_end_of_ringtone(BCTBX_UNUSED(LinphoneRingtonePlayer *rp), void *user_data, BCTBX_UNUSED(int status)) { LinphoneCore *lc = (LinphoneCore *)user_data;
6021602260236024602560266027602860296030603160326033603460356036603760386039604060416042604360446045604660476048604960506051605260536054605560566057605860596060606160626063606460656066606760686069607060716072607360746075607660776078607960806081608260836084608560866087608860896090
lc->preview_finished = 1; } LinphoneStatus linphone_core_preview_ring(LinphoneCore *lc, const char *ring, LinphoneCoreCbFunc end_of_ringtone, void *userdata) { int err; MSSndCard *ringcard = lc->sound_conf.lsd_card ? lc->sound_conf.lsd_card : lc->sound_conf.ring_sndcard; if (linphone_ringtoneplayer_is_started(lc->ringtoneplayer)) { ms_warning("Cannot start ring now,there's already a ring being played"); return -1; } lc_callback_obj_init(&lc->preview_finished_cb, end_of_ringtone, userdata); lc->preview_finished = 0; err = linphone_ringtoneplayer_start_with_cb(lc->factory, lc->ringtoneplayer, ringcard, ring, -1, notify_end_of_ringtone, (void *)lc); if (err) { lc->preview_finished = 1; } return err; } MSFactory *linphone_core_get_ms_factory(LinphoneCore *lc) { return lc->factory; } void linphone_core_set_ringback(LinphoneCore *lc, const char *path) { if (lc->sound_conf.remote_ring != 0) { ms_free(lc->sound_conf.remote_ring); } lc->sound_conf.remote_ring = path ? ms_strdup(path) : NULL; } const char *linphone_core_get_ringback(const LinphoneCore *lc) { return lc->sound_conf.remote_ring; } void linphone_core_enable_echo_cancellation(LinphoneCore *lc, bool_t val) { lc->sound_conf.ec = val; if (linphone_core_ready(lc)) linphone_config_set_int(lc->config, "sound", "echocancellation", val); } void linphone_core_reset_echo_cancellation_calibration(LinphoneCore *core) { if (linphone_core_ready(core)) { linphone_config_set_int(core->config, "sound", "ec_delay", 0); } } int linphone_core_get_echo_cancellation_calibration(const LinphoneCore *core) { return linphone_config_get_int(core->config, "sound", "ec_delay", 0); } bool_t linphone_core_echo_cancellation_enabled(const LinphoneCore *lc) { return lc->sound_conf.ec; } void linphone_core_enable_echo_limiter(LinphoneCore *lc, bool_t val) { lc->sound_conf.ea = val; } bool_t linphone_core_echo_limiter_enabled(const LinphoneCore *lc) { return lc->sound_conf.ea; } void linphone_core_mute_mic(LinphoneCore *lc, bool_t val) { linphone_core_enable_mic(lc, !val); } bool_t linphone_core_is_mic_muted(LinphoneCore *lc) { return !linphone_core_mic_enabled(lc); }
6091609260936094609560966097609860996100610161026103610461056106610761086109611061116112611361146115611661176118611961206121612261236124612561266127612861296130613161326133613461356136613761386139614061416142614361446145614661476148614961506151615261536154615561566157615861596160
void linphone_core_enable_mic(LinphoneCore *lc, bool_t enable) { CoreLogContextualizer logContextualizer(lc); LinphoneCall *call; const bctbx_list_t *list; const bctbx_list_t *elem; ms_message("linphone_core_enable_mic(): new state is [%s], current state is [%s]", enable ? "enabled" : "disabled", lc->sound_conf.mic_enabled ? "enabled" : "disabled"); lc->sound_conf.mic_enabled = enable; /* this is a global switch read everywhere the microphone is used. */ /* apply to conference and calls */ if (linphone_core_is_in_conference(lc)) { linphone_conference_mute_microphone(lc->conf_ctx, linphone_conference_microphone_is_muted(lc->conf_ctx)); } list = linphone_core_get_calls(lc); for (elem = list; elem != NULL; elem = elem->next) { call = (LinphoneCall *)elem->data; /* re-apply the same setting; we don't modify the call's switch. However the setter will * take action on the stream in order to take into account the core's new switch state.*/ linphone_call_set_microphone_muted(call, linphone_call_get_microphone_muted(call)); } } bool_t linphone_core_mic_enabled(LinphoneCore *lc) { return lc->sound_conf.mic_enabled; } bool_t linphone_core_is_rtp_muted(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); LinphoneCall *call = linphone_core_get_current_call(lc); if (call == NULL) { ms_warning("linphone_core_is_rtp_muted(): No current call !"); return FALSE; } if (linphone_core_get_rtp_no_xmit_on_audio_mute(lc)) { return linphone_call_get_microphone_muted(call); } return FALSE; } void linphone_core_enable_agc(LinphoneCore *lc, bool_t val) { lc->sound_conf.agc = val; } bool_t linphone_core_agc_enabled(const LinphoneCore *lc) { return lc->sound_conf.agc; } void linphone_core_send_dtmf(LinphoneCore *lc, char dtmf) { LinphoneCall *call = linphone_core_get_current_call(lc); linphone_call_send_dtmf(call, dtmf); } void linphone_core_set_stun_server(LinphoneCore *lc, const char *server) { if (lc->nat_policy != NULL) { linphone_nat_policy_set_stun_server(lc->nat_policy, server); L_GET_PRIVATE_FROM_C_OBJECT(lc)->writeNatPolicyConfigurations(); } else { linphone_config_set_string(lc->config, "net", "stun_server", server); } } const char *linphone_core_get_stun_server(const LinphoneCore *lc) { if (lc->nat_policy != NULL) return linphone_nat_policy_get_stun_server(lc->nat_policy); else return linphone_config_get_string(lc->config, "net", "stun_server", NULL); } bool_t linphone_core_upnp_available() { return FALSE; }
6161616261636164616561666167616861696170617161726173617461756176617761786179618061816182618361846185618661876188618961906191619261936194619561966197619861996200620162026203620462056206620762086209621062116212621362146215621662176218621962206221622262236224622562266227622862296230
LinphoneUpnpState linphone_core_get_upnp_state(BCTBX_UNUSED(const LinphoneCore *lc)) { return LinphoneUpnpStateNotAvailable; } const char *linphone_core_get_upnp_external_ipaddress(BCTBX_UNUSED(const LinphoneCore *lc)) { return NULL; } void linphone_core_set_nat_address(LinphoneCore *lc, const char *addr) { if (lc->net_conf.nat_address != NULL) { ms_free(lc->net_conf.nat_address); } if (addr != NULL) lc->net_conf.nat_address = ms_strdup(addr); else lc->net_conf.nat_address = NULL; if (lc->sip_conf.contact) update_primary_contact(lc); } const char *linphone_core_get_nat_address(const LinphoneCore *lc) { return lc->net_conf.nat_address; } void linphone_core_set_firewall_policy(LinphoneCore *lc, LinphoneFirewallPolicy pol) { LinphoneNatPolicy *nat_policy; char *stun_server = NULL; char *stun_server_username = NULL; if (lc->nat_policy != NULL) { nat_policy = linphone_nat_policy_ref(lc->nat_policy); stun_server = ms_strdup(linphone_nat_policy_get_stun_server(nat_policy)); stun_server_username = ms_strdup(linphone_nat_policy_get_stun_server_username(nat_policy)); linphone_nat_policy_clear(nat_policy); } else { nat_policy = linphone_core_create_nat_policy(lc); stun_server = ms_strdup(linphone_core_get_stun_server(lc)); } switch (pol) { default: case LinphonePolicyNoFirewall: case LinphonePolicyUseNatAddress: break; case LinphonePolicyUseStun: linphone_nat_policy_enable_stun(nat_policy, TRUE); break; case LinphonePolicyUseIce: linphone_nat_policy_enable_ice(nat_policy, TRUE); linphone_nat_policy_enable_stun(nat_policy, TRUE); break; case LinphonePolicyUseUpnp: ms_warning("UPNP is no longer supported, reset firewall policy to no firewall"); break; } if (stun_server_username != NULL) { linphone_nat_policy_set_stun_server_username(nat_policy, stun_server_username); ms_free(stun_server_username); } if (stun_server != NULL) { linphone_nat_policy_set_stun_server(nat_policy, stun_server); ms_free(stun_server); } linphone_core_set_nat_policy(lc, nat_policy); linphone_nat_policy_unref(nat_policy); /* Ensure that the firewall policy is cleared in the config because it has been replaced by the nat_policy. */ linphone_config_set_string(lc->config, "net", "firewall_policy", NULL); } LinphoneFirewallPolicy linphone_core_get_firewall_policy(const LinphoneCore *lc) {
6231623262336234623562366237623862396240624162426243624462456246624762486249625062516252625362546255625662576258625962606261626262636264626562666267626862696270627162726273627462756276627762786279628062816282628362846285628662876288628962906291629262936294629562966297629862996300
const char *policy; policy = linphone_config_get_string(lc->config, "net", "firewall_policy", NULL); if (policy == NULL) { LinphoneNatPolicy *nat_policy = linphone_core_get_nat_policy(lc); if (nat_policy == NULL) { return LinphonePolicyNoFirewall; } else if (linphone_nat_policy_upnp_enabled(nat_policy)) return LinphonePolicyUseUpnp; else if (linphone_nat_policy_ice_enabled(nat_policy)) return LinphonePolicyUseIce; else if (linphone_nat_policy_stun_enabled(nat_policy)) return LinphonePolicyUseStun; else return LinphonePolicyNoFirewall; } else if (strcmp(policy, "0") == 0) return LinphonePolicyNoFirewall; else if ((strcmp(policy, "nat_address") == 0) || (strcmp(policy, "1") == 0)) return LinphonePolicyUseNatAddress; else if ((strcmp(policy, "stun") == 0) || (strcmp(policy, "2") == 0)) return LinphonePolicyUseStun; else if ((strcmp(policy, "ice") == 0) || (strcmp(policy, "3") == 0)) return LinphonePolicyUseIce; else if ((strcmp(policy, "upnp") == 0) || (strcmp(policy, "4") == 0)) return LinphonePolicyUseUpnp; else return LinphonePolicyNoFirewall; } void linphone_core_set_nat_policy(LinphoneCore *lc, LinphoneNatPolicy *policy) { CoreLogContextualizer logContextualizer(lc); if (policy != NULL) policy = linphone_nat_policy_ref(policy); /* Prevent object destruction if the same policy is used */ else { ms_error("linphone_core_set_nat_policy() setting to NULL is not allowed"); return; } if (lc->nat_policy != NULL) { linphone_nat_policy_unref(lc->nat_policy); lc->nat_policy = NULL; } if (policy != NULL) { lc->nat_policy = policy; /*start an immediate (but asynchronous) resolution.*/ linphone_nat_policy_resolve_stun_server(policy); linphone_config_set_string(lc->config, "net", "nat_policy_ref", NatPolicy::toCpp(policy)->getRef().c_str()); L_GET_PRIVATE_FROM_C_OBJECT(lc)->writeNatPolicyConfigurations(); } lc->sal->enableNatHelper(!!linphone_config_get_int(lc->config, "net", "enable_nat_helper", 1)); lc->sal->enableAutoContacts(true); lc->sal->useRport(!!linphone_config_get_int(lc->config, "sip", "use_rport", 1)); if (lc->sip_conf.contact) update_primary_contact(lc); } LinphoneNatPolicy *linphone_core_get_nat_policy(const LinphoneCore *lc) { return lc->nat_policy; } /******************************************************************************* * Call log related functions * ******************************************************************************/ void linphone_core_set_call_logs_database_path(LinphoneCore *lc, const char *path) { CoreLogContextualizer logContextualizer(lc); if (!linphone_core_conference_server_enabled(lc)) { auto &mainDb = L_GET_PRIVATE_FROM_C_OBJECT(lc)->mainDb; if (mainDb) { mainDb->import(LinphonePrivate::MainDb::Sqlite3, path); linphone_core_migrate_logs_from_rc_to_db(lc); } else { ms_warning("linphone_core_set_call_logs_database_path() needs to be called once linphone_core_start() has " "been called"); } } } const char *linphone_core_get_call_logs_database_path(BCTBX_UNUSED(LinphoneCore *lc)) { lError() << "Do not use `linphone_core_get_call_logs_database_path`. Not necessary."; return "";
6301630263036304630563066307630863096310631163126313631463156316631763186319632063216322632363246325632663276328632963306331633263336334633563366337633863396340634163426343634463456346634763486349635063516352635363546355635663576358635963606361636263636364636563666367636863696370
} const bctbx_list_t *linphone_core_get_call_logs(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); return linphone_core_get_call_history(lc); } void linphone_core_clear_call_logs(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); #ifdef HAVE_DB_STORAGE linphone_core_delete_call_history(lc); #else bctbx_list_for_each(lc->call_logs, (void (*)(void *))linphone_call_log_unref); lc->call_logs = bctbx_list_free(lc->call_logs); call_logs_write_to_config_file(lc); #endif } int linphone_core_get_missed_calls_count(LinphoneCore *lc) { int missed_calls = lc->missed_calls; bctbx_list_t *accounts = (bctbx_list_t *)linphone_core_get_account_list(lc); for (; accounts != NULL; accounts = accounts->next) { LinphoneAccount *account = (LinphoneAccount *)accounts->data; missed_calls += linphone_account_get_missed_calls_count(account); } return missed_calls; } void linphone_core_reset_missed_calls_count(LinphoneCore *lc) { lc->missed_calls = 0; bctbx_list_t *accounts = (bctbx_list_t *)linphone_core_get_account_list(lc); for (; accounts != NULL; accounts = accounts->next) { LinphoneAccount *account = (LinphoneAccount *)accounts->data; linphone_account_reset_missed_calls_count(account); } } void linphone_core_remove_call_log(LinphoneCore *lc, LinphoneCallLog *cl) { CoreLogContextualizer logContextualizer(lc); #ifdef HAVE_DB_STORAGE linphone_core_delete_call_log(lc, cl); #else lc->call_logs = bctbx_list_remove(lc->call_logs, cl); call_logs_write_to_config_file(lc); linphone_call_log_unref(cl); #endif } void linphone_core_migrate_logs_from_rc_to_db(LinphoneCore *lc) { bctbx_list_t *logs_to_migrate = NULL; LpConfig *lpc = NULL; size_t original_logs_count, migrated_logs_count; int i; if (!lc) { return; } lpc = linphone_core_get_config(lc); if (!lpc) { ms_warning("this core has been started without a rc file, nothing to migrate"); return; } if (linphone_config_get_int(lpc, "misc", "call_logs_migration_done", 0) == 1) { ms_warning("the call logs migration has already been done, skipping..."); return; }
6371637263736374637563766377637863796380638163826383638463856386638763886389639063916392639363946395639663976398639964006401640264036404640564066407640864096410641164126413641464156416641764186419642064216422642364246425642664276428642964306431643264336434643564366437643864396440
logs_to_migrate = linphone_core_read_call_logs_from_config_file(lc); if (!logs_to_migrate) { ms_warning("nothing to migrate, skipping..."); return; } // This is because there must have been a call previously to linphone_core_call_log_storage_init lc->call_logs = bctbx_list_free_with_data(lc->call_logs, (void (*)(void *))linphone_call_log_unref); lc->call_logs = NULL; // We can't use bctbx_list_for_each because logs_to_migrate are listed in the wrong order (latest first), and we // want to store the logs latest last for (i = (int)bctbx_list_size(logs_to_migrate) - 1; i >= 0; i--) { LinphoneCallLog *log = (LinphoneCallLog *)bctbx_list_nth_data(logs_to_migrate, i); linphone_core_store_call_log(lc, log); } original_logs_count = bctbx_list_size(logs_to_migrate); migrated_logs_count = bctbx_list_size(lc->call_logs); if (original_logs_count == migrated_logs_count) { size_t i = 0; ms_debug("call logs migration successful: %u logs migrated", (unsigned int)bctbx_list_size(lc->call_logs)); linphone_config_set_int(lpc, "misc", "call_logs_migration_done", 1); for (; i < original_logs_count; i++) { char logsection[32]; snprintf(logsection, sizeof(logsection), "call_log_%u", (unsigned int)i); linphone_config_clean_section(lpc, logsection); } } else { ms_error("not as many logs saved in db has logs read from rc (" FORMAT_SIZE_T " in rc against " FORMAT_SIZE_T " in db)!", original_logs_count, migrated_logs_count); } bctbx_list_free_with_data(logs_to_migrate, (void (*)(void *))linphone_call_log_unref); } /******************************************************************************* * Video related functions * ******************************************************************************/ #ifndef _MSC_VER #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif // _MSC_VER void linphone_core_resize_video_preview(LinphoneCore *lc, int width, int height) { bool_t auto_camera_preview_resize = !!linphone_config_get_int(lc->config, "video", "auto_resize_preview_to_keep_ratio", 0); if (!auto_camera_preview_resize) return; #ifdef VIDEO_ENABLED bctbx_message("Resizing camera video preview to: %ix%i", width, height); getPlatformHelpers(lc)->resizeVideoPreview(width, height); #endif } #ifndef _MSC_VER #pragma GCC diagnostic pop #endif // _MSC_VER #ifdef VIDEO_ENABLED static void video_stream_callback(void *userdata, BCTBX_UNUSED(const MSFilter *f), const unsigned int id, const void *arg) { switch (id) { case MS_CAMERA_PREVIEW_SIZE_CHANGED: { LinphoneCore *lc = (LinphoneCore *)userdata; MSVideoSize size = *(MSVideoSize *)arg; bctbx_message("Camera video preview size changed: %ix%i", size.width, size.height); linphone_core_resize_video_preview(lc, size.width, size.height); break;
6441644264436444644564466447644864496450645164526453645464556456645764586459646064616462646364646465646664676468646964706471647264736474647564766477647864796480648164826483648464856486648764886489649064916492649364946495649664976498649965006501650265036504650565066507650865096510
} } } static void video_stream_preview_display_callback(void *userdata, const unsigned int id, const void *arg) { switch (id) { case MS_VIDEO_DISPLAY_ERROR_OCCURRED: { LinphoneCore *lc = (LinphoneCore *)userdata; int error_code = *(const int *)arg; linphone_core_notify_preview_display_error_occurred(lc, error_code); break; } } } static void video_filter_callback(void *userdata, BCTBX_UNUSED(MSFilter *f), unsigned int id, void *arg) { switch (id) { case MS_JPEG_WRITER_SNAPSHOT_TAKEN: { LinphoneCore *lc = (LinphoneCore *)userdata; linphone_core_enable_video_preview(lc, FALSE); break; } case MS_QRCODE_READER_QRCODE_FOUND: { LinphoneCore *lc = (LinphoneCore *)userdata; if (linphone_core_cbs_get_qrcode_found(linphone_core_get_current_callbacks(lc)) != NULL) { MSQrCodeReaderEventData *data = static_cast<MSQrCodeReaderEventData *>(arg); char *result = ms_strdup((const char *)data->data); linphone_core_notify_qrcode_found(lc, result); ms_free(result); } break; } } } #endif LinphoneStatus linphone_core_take_preview_snapshot(LinphoneCore *lc, const char *file) { CoreLogContextualizer logContextualizer(lc); LinphoneCall *call = linphone_core_get_current_call(lc); if (!file) return -1; if (call) { return linphone_call_take_preview_snapshot(call, file); } else { #ifdef VIDEO_ENABLED if (lc->previewstream == NULL) { MSVideoSize vsize = lc->video_conf.preview_vsize.width != 0 ? lc->video_conf.preview_vsize : lc->video_conf.vsize; lc->previewstream = video_preview_new(lc->factory); video_preview_set_size(lc->previewstream, vsize); video_preview_set_display_filter_name(lc->previewstream, NULL); video_preview_set_fps(lc->previewstream, linphone_core_get_preferred_framerate(lc)); video_preview_start(lc->previewstream, lc->video_conf.device); lc->previewstream->ms.factory = lc->factory; linphone_core_enable_video_preview(lc, TRUE); ms_filter_add_notify_callback(lc->previewstream->local_jpegwriter, video_filter_callback, lc, FALSE); ms_filter_call_method(lc->previewstream->local_jpegwriter, MS_JPEG_WRITER_TAKE_SNAPSHOT, (void *)file); } else { ms_filter_call_method(lc->previewstream->local_jpegwriter, MS_JPEG_WRITER_TAKE_SNAPSHOT, (void *)file); } return 0; #endif } return -1; } #ifndef _MSC_VER #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif // _MSC_VER static void toggle_video_preview(LinphoneCore *lc, bool_t val) {
6511651265136514651565166517651865196520652165226523652465256526652765286529653065316532653365346535653665376538653965406541654265436544654565466547654865496550655165526553655465556556655765586559656065616562656365646565656665676568656965706571657265736574657565766577657865796580
#ifdef VIDEO_ENABLED if (val) { if (lc->previewstream == NULL) { const char *display_filter = linphone_core_get_video_display_filter(lc); 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); } if (linphone_core_qrcode_video_preview_enabled(lc)) { vsize.width = 720; vsize.height = 1280; } else { vsize.width = (int)linphone_video_definition_get_width(vdef); vsize.height = (int)linphone_video_definition_get_height(vdef); } lc->previewstream = video_preview_new(lc->factory); video_preview_set_size(lc->previewstream, vsize); video_stream_set_device_rotation(lc->previewstream, lc->device_rotation); if (display_filter) { video_preview_set_display_filter_name(lc->previewstream, display_filter); } if (lc->preview_window_id != NULL) { video_preview_set_native_window_id(lc->previewstream, lc->preview_window_id); } video_preview_set_fps(lc->previewstream, linphone_core_get_preferred_framerate(lc)); if (linphone_core_qrcode_video_preview_enabled(lc)) { video_preview_enable_qrcode(lc->previewstream, TRUE); if (lc->qrcode_rect.w != 0 && lc->qrcode_rect.h != 0) { video_preview_set_decode_rect(lc->previewstream, lc->qrcode_rect); } } video_preview_start(lc->previewstream, lc->video_conf.device); if (video_preview_qrcode_enabled(lc->previewstream)) { ms_filter_add_notify_callback(lc->previewstream->qrcode, video_filter_callback, lc, FALSE); } video_stream_set_event_callback(lc->previewstream, video_stream_callback, lc); video_stream_set_display_callback(lc->previewstream, video_stream_preview_display_callback, lc); } } else { if (lc->previewstream != NULL) { ms_filter_remove_notify_callback(lc->previewstream->source, video_filter_callback, lc); video_preview_stop(lc->previewstream); lc->previewstream = NULL; } } #endif } #ifndef _MSC_VER #pragma GCC diagnostic pop #endif // _MSC_VER static void relaunch_video_preview(LinphoneCore *lc) { if (lc->previewstream) { toggle_video_preview(lc, FALSE); } /* And nothing else, because linphone_core_iterate() will restart the preview stream if necessary. * This code will need to be revisited when linphone_core_iterate() will no longer be required*/ } bool_t linphone_core_video_supported(BCTBX_UNUSED(LinphoneCore *lc)) { #ifdef VIDEO_ENABLED return TRUE; #else return FALSE; #endif } void linphone_core_enable_video(LinphoneCore *lc, bool_t vcap_enabled, bool_t display_enabled) {
6581658265836584658565866587658865896590659165926593659465956596659765986599660066016602660366046605660666076608660966106611661266136614661566166617661866196620662166226623662466256626662766286629663066316632663366346635663666376638663966406641664266436644664566466647664866496650
linphone_core_enable_video_capture(lc, vcap_enabled); linphone_core_enable_video_display(lc, display_enabled); } bool_t linphone_core_video_enabled(LinphoneCore *lc) { return (lc->video_conf.display || lc->video_conf.capture); } static void reapply_network_bandwidth_settings(LinphoneCore *lc) { linphone_core_set_download_bandwidth(lc, linphone_core_get_download_bandwidth(lc)); linphone_core_set_upload_bandwidth(lc, linphone_core_get_upload_bandwidth(lc)); } void linphone_core_enable_video_capture(LinphoneCore *lc, bool_t enable) { CoreLogContextualizer logContextualizer(lc); #ifndef VIDEO_ENABLED if (enable == TRUE) { ms_warning("Cannot enable video capture, this version of linphone was built without video support."); } #endif lc->video_conf.capture = enable; if (linphone_core_ready(lc)) { linphone_config_set_int(lc->config, "video", "capture", lc->video_conf.capture); } /* Need to re-apply network bandwidth settings. */ reapply_network_bandwidth_settings(lc); } void linphone_core_enable_video_display(LinphoneCore *lc, bool_t enable) { CoreLogContextualizer logContextualizer(lc); #ifndef VIDEO_ENABLED if (enable == TRUE) { ms_warning("Cannot enable video display, this version of linphone was built without video support."); } #endif lc->video_conf.display = enable; if (linphone_core_ready(lc)) { linphone_config_set_int(lc->config, "video", "display", lc->video_conf.display); } /* Need to re-apply network bandwidth settings. */ reapply_network_bandwidth_settings(lc); } void linphone_core_enable_video_source_reuse(LinphoneCore *lc, bool_t enable) { CoreLogContextualizer logContextualizer(lc); #ifndef VIDEO_ENABLED if (enable == TRUE) { ms_warning("Cannot enable video display, this version of linphone was built without video support."); } #endif lc->video_conf.reuse_preview_source = enable; if (linphone_core_ready(lc)) { linphone_config_set_int(lc->config, "video", "reuse_source", lc->video_conf.reuse_preview_source); } } bool_t linphone_core_video_capture_enabled(LinphoneCore *lc) { return lc->video_conf.capture; } bool_t linphone_core_video_display_enabled(LinphoneCore *lc) { return lc->video_conf.display; } void linphone_core_set_video_policy(LinphoneCore *lc, const LinphoneVideoPolicy *policy) { lc->video_policy = *policy; if (linphone_core_ready(lc)) { linphone_config_set_int(lc->config, "video", "automatically_initiate", policy->automatically_initiate); linphone_config_set_int(lc->config, "video", "automatically_accept", policy->automatically_accept); }
6651665266536654665566566657665866596660666166626663666466656666666766686669667066716672667366746675667666776678667966806681668266836684668566866687668866896690669166926693669466956696669766986699670067016702670367046705670667076708670967106711671267136714671567166717671867196720
} 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; } 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; if (linphone_core_ready(lc)) { linphone_config_set_int(lc->config, "video", "automatically_initiate", policy->automatically_initiate); linphone_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; }
6721672267236724672567266727672867296730673167326733673467356736673767386739674067416742674367446745674667476748674967506751675267536754675567566757675867596760676167626763676467656766676767686769677067716772677367746775677667776778677967806781678267836784678567866787678867896790
void linphone_core_enable_video_preview(LinphoneCore *lc, bool_t val) { lc->video_conf.show_local = val; if (linphone_core_ready(lc)) linphone_config_set_int(lc->config, "video", "show_local", val); } bool_t linphone_core_video_preview_enabled(const LinphoneCore *lc) { return lc->video_conf.show_local; } void linphone_core_enable_qrcode_video_preview(LinphoneCore *lc, bool_t val) { lc->video_conf.qrcode_decoder = val; if (linphone_core_ready(lc)) linphone_config_set_int(lc->config, "video", "qrcode_decoder", val); } bool_t linphone_core_qrcode_video_preview_enabled(const LinphoneCore *lc) { return lc->video_conf.qrcode_decoder; } void linphone_core_set_qrcode_decode_rect(LinphoneCore *lc, const int x, const int y, const int w, const int h) { if (lc) { MSRect rect; rect.x = x; rect.y = y; rect.w = w; rect.h = h; lc->qrcode_rect = rect; } } #ifndef _MSC_VER #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif // _MSC_VER void linphone_core_enable_self_view(LinphoneCore *lc, bool_t val) { #ifdef VIDEO_ENABLED LinphoneCall *call = linphone_core_get_current_call(lc); lc->video_conf.selfview = val; if (linphone_core_ready(lc)) { linphone_config_set_int(lc->config, "video", "self_view", linphone_core_self_view_enabled(lc)); } if (call) { VideoStream *vstream = reinterpret_cast<VideoStream *>(linphone_call_get_stream(call, LinphoneStreamTypeVideo)); if (vstream) video_stream_enable_self_view(vstream, val); } if (linphone_core_ready(lc)) { linphone_config_set_int(lc->config, "video", "self_view", val); } #endif } #ifndef _MSC_VER #pragma GCC diagnostic pop #endif // _MSC_VER bool_t linphone_core_self_view_enabled(const LinphoneCore *lc) { return lc->video_conf.selfview; } LinphoneStatus linphone_core_set_video_device(LinphoneCore *lc, const char *id) { MSWebCam *olddev = lc->video_conf.device; const char *vd; if (id != NULL) { lc->video_conf.device = ms_web_cam_manager_get_cam(ms_factory_get_web_cam_manager(lc->factory), id); if (lc->video_conf.device == NULL) { ms_warning("Could not find video device %s", id); } } if (lc->video_conf.device == NULL) lc->video_conf.device = ms_web_cam_manager_get_default_cam(ms_factory_get_web_cam_manager(lc->factory)); if (olddev != NULL && olddev != lc->video_conf.device) { relaunch_video_preview(lc);
6791679267936794679567966797679867996800680168026803680468056806680768086809681068116812681368146815681668176818681968206821682268236824682568266827682868296830683168326833683468356836683768386839684068416842684368446845684668476848684968506851685268536854685568566857685868596860
L_GET_PRIVATE_FROM_C_OBJECT(lc)->updateVideoDevice(); } if (linphone_core_ready(lc) && lc->video_conf.device) { vd = ms_web_cam_get_string_id(lc->video_conf.device); if (vd && strstr(vd, "Static picture") != NULL) { vd = NULL; } linphone_config_set_string(lc->config, "video", "device", vd); } return 0; } const char *linphone_core_get_video_device(const LinphoneCore *lc) { if (lc->video_conf.device) return ms_web_cam_get_string_id(lc->video_conf.device); return NULL; } #ifdef VIDEO_ENABLED static VideoStream *get_active_video_stream(LinphoneCore *lc) { VideoStream *vs = NULL; LinphoneCall *call = linphone_core_get_current_call(lc); /* Select the video stream from the call in the first place */ if (call) { VideoStream *vstream = reinterpret_cast<VideoStream *>(linphone_call_get_stream(call, LinphoneStreamTypeVideo)); if (vstream) vs = vstream; } /* If not in call, select the video stream from the preview */ if (vs == NULL && lc->previewstream) { vs = lc->previewstream; } return vs; } #endif #ifndef _MSC_VER #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif // _MSC_VER LinphoneStatus linphone_core_set_static_picture(LinphoneCore *lc, const char *path) { #ifdef VIDEO_ENABLED VideoStream *vs = get_active_video_stream(lc); /* If we have a video stream (either preview, either from call), we have a source and it is using the static picture filter, then force the filter to use that picture. */ if (vs && vs->source) { if (ms_filter_get_id(vs->source) == MS_STATIC_IMAGE_ID) { ms_filter_call_method(vs->source, MS_STATIC_IMAGE_SET_IMAGE, (void *)path); } } /* Tell the static image filter to use that image from now on so that the image will be used next time it has to be read */ ms_static_image_set_default_image(path); #else ms_warning("Video support not compiled."); #endif return 0; } #ifndef _MSC_VER #pragma GCC diagnostic pop #endif // _MSC_VER #ifndef _MSC_VER #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif // _MSC_VER const char *linphone_core_get_static_picture(BCTBX_UNUSED(LinphoneCore *lc)) { const char *path = NULL; #ifdef VIDEO_ENABLED path = ms_static_image_get_default_image(); #else
6861686268636864686568666867686868696870687168726873687468756876687768786879688068816882688368846885688668876888688968906891689268936894689568966897689868996900690169026903690469056906690769086909691069116912691369146915691669176918691969206921692269236924692569266927692869296930
ms_warning("Video support not compiled."); #endif return path; } #ifndef _MSC_VER #pragma GCC diagnostic pop #endif // _MSC_VER #ifndef _MSC_VER #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif // _MSC_VER LinphoneStatus linphone_core_set_static_picture_fps(LinphoneCore *lc, float fps) { #ifdef VIDEO_ENABLED VideoStream *vs = NULL; vs = get_active_video_stream(lc); /* If we have a video stream (either preview, either from call), we have a source and it is using the static picture filter, then force the filter to use that picture. */ if (vs && vs->source) { if (ms_filter_get_id(vs->source) == MS_STATIC_IMAGE_ID) { ms_filter_call_method(vs->source, MS_FILTER_SET_FPS, (void *)&fps); } } #else ms_warning("Video support not compiled."); #endif return 0; } #ifndef _MSC_VER #pragma GCC diagnostic pop #endif // _MSC_VER #ifndef _MSC_VER #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif // _MSC_VER float linphone_core_get_static_picture_fps(LinphoneCore *lc) { #ifdef VIDEO_ENABLED VideoStream *vs = NULL; vs = get_active_video_stream(lc); /* If we have a video stream (either preview, either from call), we have a source and it is using the static picture filter, then force the filter to use that picture. */ if (vs && vs->source) { if (ms_filter_get_id(vs->source) == MS_STATIC_IMAGE_ID) { float fps; ms_filter_call_method(vs->source, MS_FILTER_GET_FPS, (void *)&fps); return fps; } } #else ms_warning("Video support not compiled."); #endif return 0; } #ifndef _MSC_VER #pragma GCC diagnostic pop #endif // _MSC_VER #ifndef _MSC_VER #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif // _MSC_VER void *linphone_core_create_native_video_window_id(const LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc);
6931693269336934693569366937693869396940694169426943694469456946694769486949695069516952695369546955695669576958695969606961696269636964696569666967696869696970697169726973697469756976697769786979698069816982698369846985698669876988698969906991699269936994699569966997699869997000
#ifdef VIDEO_ENABLED LinphoneCall *call = linphone_core_get_current_call(lc); if (call) { auto ms = dynamic_pointer_cast<LinphonePrivate::MediaSession>(Call::toCpp(call)->getActiveSession()); if (ms) return ms->createNativeVideoWindowId(); } #endif return 0; } #ifndef _MSC_VER #pragma GCC diagnostic pop #endif // _MSC_VER void *linphone_core_get_native_video_window_id(const LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); if (lc->video_window_id) { /* case where the video id was previously set by the app*/ return lc->video_window_id; } else { #ifdef VIDEO_ENABLED /*case where it was not set but we want to get the one automatically created by mediastreamer2 (desktop * versions only)*/ LinphoneCall *call = linphone_core_get_current_call(lc); if (call) { auto ms = dynamic_pointer_cast<LinphonePrivate::MediaSession>(Call::toCpp(call)->getActiveSession()); if (ms) return ms->getNativeVideoWindowId(); } #endif } return 0; } void _linphone_core_set_native_video_window_id(LinphoneCore *lc, void *id) { L_GET_PRIVATE_FROM_C_OBJECT(lc)->setVideoWindowId(false, id); lc->video_window_id = id; } void linphone_core_set_native_video_window_id(LinphoneCore *lc, void *id) { #ifdef __ANDROID__ getPlatformHelpers(lc)->setVideoWindow(id); #else _linphone_core_set_native_video_window_id(lc, id); #endif } #ifndef _MSC_VER #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif // _MSC_VER void *linphone_core_create_native_preview_window_id(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); #ifdef VIDEO_ENABLED LinphoneCall *call = linphone_core_get_current_call(lc); if (call) { auto ms = dynamic_pointer_cast<LinphonePrivate::MediaSession>(Call::toCpp(call)->getActiveSession()); if (ms) return ms->createNativePreviewVideoWindowId(); } if (lc->previewstream == NULL && linphone_core_video_preview_enabled(lc) && !L_GET_PRIVATE_FROM_C_OBJECT(lc)->hasCalls()) toggle_video_preview(lc, TRUE); if (lc->previewstream) return video_preview_create_native_window_id(lc->previewstream); #endif return 0; } #ifndef _MSC_VER #pragma GCC diagnostic pop #endif // _MSC_VER void *linphone_core_get_native_preview_window_id(LinphoneCore *lc) {
7001700270037004700570067007700870097010701170127013701470157016701770187019702070217022702370247025702670277028702970307031703270337034703570367037703870397040704170427043704470457046704770487049705070517052705370547055705670577058705970607061706270637064706570667067706870697070
CoreLogContextualizer logContextualizer(lc); if (lc->preview_window_id) { /*case where the id was set by the app previously*/ return lc->preview_window_id; } else { /*case where we want the id automatically created by mediastreamer2 (desktop versions only)*/ #ifdef VIDEO_ENABLED LinphoneCall *call = linphone_core_get_current_call(lc); if (call) { auto ms = dynamic_pointer_cast<LinphonePrivate::MediaSession>(Call::toCpp(call)->getActiveSession()); if (ms) return ms->getNativePreviewVideoWindowId(); } if (lc->previewstream == NULL && linphone_core_video_preview_enabled(lc) && !L_GET_PRIVATE_FROM_C_OBJECT(lc)->hasCalls()) toggle_video_preview(lc, TRUE); if (lc->previewstream) return video_preview_get_native_window_id(lc->previewstream); #endif } return 0; } void _linphone_core_set_native_preview_window_id(LinphoneCore *lc, void *id) { L_GET_PRIVATE_FROM_C_OBJECT(lc)->setVideoWindowId(true, id); lc->preview_window_id = id; #ifdef VIDEO_ENABLED if (lc->previewstream) { video_preview_set_native_window_id(lc->previewstream, id); } #endif } #ifndef _MSC_VER #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif // _MSC_VER void linphone_core_set_native_preview_window_id(LinphoneCore *lc, void *id) { #ifdef __ANDROID__ getPlatformHelpers(lc)->setVideoPreviewWindow(id); #else _linphone_core_set_native_preview_window_id(lc, id); #endif } #ifndef _MSC_VER #pragma GCC diagnostic pop #endif // _MSC_VER #ifndef _MSC_VER #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif // _MSC_VER void linphone_core_show_video(LinphoneCore *lc, bool_t show) { #ifdef VIDEO_ENABLED LinphoneCall *call = linphone_core_get_current_call(lc); ms_error("linphone_core_show_video %d", show); if (call) { VideoStream *vstream = reinterpret_cast<VideoStream *>(linphone_call_get_stream(call, LinphoneStreamTypeVideo)); if (vstream) video_stream_show_video(vstream, show); } #endif } #ifndef _MSC_VER #pragma GCC diagnostic pop #endif // _MSC_VER void linphone_core_use_preview_window(LinphoneCore *lc, bool_t yesno) { lc->use_preview_window = yesno; } int linphone_core_get_device_rotation(LinphoneCore *lc) {
7071707270737074707570767077707870797080708170827083708470857086708770887089709070917092709370947095709670977098709971007101710271037104710571067107710871097110711171127113711471157116711771187119712071217122712371247125712671277128712971307131713271337134713571367137713871397140
return lc->device_rotation; } void linphone_core_set_device_rotation(LinphoneCore *lc, int rotation) { CoreLogContextualizer logContextualizer(lc); if (rotation == lc->device_rotation) return; ms_message("%s : rotation=%d\n", __FUNCTION__, rotation); lc->device_rotation = rotation; #ifdef VIDEO_ENABLED { LinphoneCall *call = linphone_core_get_current_call(lc); VideoStream *vstream = NULL; if (call) { vstream = reinterpret_cast<VideoStream *>(linphone_call_get_stream(call, LinphoneStreamTypeVideo)); if (vstream) { video_stream_set_device_rotation(vstream, rotation); video_stream_change_camera_skip_bitrate(vstream, vstream->cam); } } else if (linphone_core_video_preview_enabled(lc)) { vstream = lc->previewstream; if (vstream) { video_stream_set_device_rotation(vstream, rotation); video_preview_update_video_params(vstream); } } } #endif } #ifndef _MSC_VER #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif // _MSC_VER int linphone_core_get_camera_sensor_rotation(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); #ifdef VIDEO_ENABLED LinphoneCall *call = linphone_core_get_current_call(lc); if (call) { VideoStream *vstream = reinterpret_cast<VideoStream *>(linphone_call_get_stream(call, LinphoneStreamTypeVideo)); if (vstream) return video_stream_get_camera_sensor_rotation(vstream); } #endif return -1; } #ifndef _MSC_VER #pragma GCC diagnostic pop #endif // _MSC_VER static MSVideoSizeDef supported_resolutions[] = { #if !defined(__ANDROID__) && !TARGET_OS_IPHONE {{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-"}, #endif {{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"}, #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"}, #endif {{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"}, #endif
7141714271437144714571467147714871497150715171527153715471557156715771587159716071617162716371647165716671677168716971707171717271737174717571767177717871797180718171827183718471857186718771887189719071917192719371947195719671977198719972007201720272037204720572067207720872097210
{{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"}, #endif {{MS_VIDEO_SIZE_QCIF_W, MS_VIDEO_SIZE_QCIF_H}, "qcif"}, {{0, 0}, NULL}}; const MSVideoSizeDef *linphone_core_get_supported_video_sizes(BCTBX_UNUSED(LinphoneCore *lc)) { return supported_resolutions; } static MSVideoSize video_size_get_by_name(const char *name) { MSVideoSizeDef *pdef = supported_resolutions; MSVideoSize null_vsize = {0, 0}; MSVideoSize parsed; if (!name) return null_vsize; for (; pdef->name != NULL; pdef++) { if (strcasecmp(name, pdef->name) == 0) { return pdef->vsize; } } if (sscanf(name, "%ix%i", &parsed.width, &parsed.height) == 2) { return parsed; } ms_warning("Video resolution %s is not supported in linphone.", name); return null_vsize; } 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; } ms_warning("Video definition %ix%i is not supported", linphone_video_definition_get_width(vdef), linphone_video_definition_get_height(vdef)); return FALSE; } void linphone_core_set_preferred_video_definition(LinphoneCore *lc, LinphoneVideoDefinition *vdef) { CoreLogContextualizer logContextualizer(lc); if (!linphone_video_definition_is_undefined(vdef) && 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); } if (oldvdef != NULL) linphone_video_definition_unref(oldvdef); if (linphone_core_ready(lc)) { linphone_config_set_string(lc->config, "video", "size", linphone_video_definition_get_name(vdef)); } } } void linphone_core_set_preferred_video_size(LinphoneCore *lc, MSVideoSize vsize) { LinphoneVideoDefinition *vdef = linphone_factory_find_supported_video_definition( linphone_factory_get(), (unsigned int)vsize.width, (unsigned int)vsize.height); if (!vdef) { ms_error("Couldn't find video definition for size %ux%u", vsize.width, vsize.height); return; } linphone_core_set_preferred_video_definition(lc, vdef); } void linphone_core_set_preview_video_definition(LinphoneCore *lc, LinphoneVideoDefinition *vdef) {
7211721272137214721572167217721872197220722172227223722472257226722772287229723072317232723372347235723672377238723972407241724272437244724572467247724872497250725172527253725472557256725772587259726072617262726372647265726672677268726972707271727272737274727572767277727872797280
CoreLogContextualizer logContextualizer(lc); 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)) { linphone_config_set_string(lc->config, "video", "preview_size", NULL); } return; } 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)) { linphone_config_set_string(lc->config, "video", "preview_size", linphone_video_definition_get_name(vdef)); } } 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(), (unsigned int)vsize.width, (unsigned int)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 = (int)linphone_video_definition_get_width(lc->video_conf.preview_vdef); vsize.height = (int)linphone_video_definition_get_height(lc->video_conf.preview_vdef); return vsize; } void net_config_uninit(LinphoneCore *lc) { net_config_t *config = &lc->net_conf; if (config->nat_address != NULL) { linphone_config_set_string(lc->config, "net", "nat_address", config->nat_address); ms_free(lc->net_conf.nat_address); } if (lc->net_conf.nat_address_ip != NULL) { ms_free(lc->net_conf.nat_address_ip); } linphone_config_set_int(lc->config, "net", "mtu", config->mtu); if (lc->nat_policy != NULL) { linphone_nat_policy_unref(lc->nat_policy); lc->nat_policy = NULL; } lc->net_conf = {0}; } void sip_config_uninit(LinphoneCore *lc) { bctbx_list_t *elem; int i; sip_config_t *config = &lc->sip_conf; bool_t still_registered = TRUE; linphone_config_set_int(lc->config, "sip", "guess_hostname", config->guess_hostname); linphone_config_set_string(lc->config, "sip", "contact", config->contact); linphone_config_set_int(lc->config, "sip", "inc_timeout", config->inc_timeout); linphone_config_set_int(lc->config, "sip", "in_call_timeout", config->in_call_timeout); linphone_config_set_int(lc->config, "sip", "delayed_timeout", config->delayed_timeout); linphone_config_set_int(lc->config, "sip", "register_only_when_network_is_up",
7281728272837284728572867287728872897290729172927293729472957296729772987299730073017302730373047305730673077308730973107311731273137314731573167317731873197320732173227323732473257326732773287329733073317332733373347335733673377338733973407341734273437344734573467347734873497350
config->register_only_when_network_is_up); linphone_config_set_int(lc->config, "sip", "register_only_when_upnp_is_ok", config->register_only_when_upnp_is_ok); if (lc->sip_network_state.global_state) { bool_t need_to_unregister = FALSE; for (elem = config->accounts; elem != NULL; elem = bctbx_list_next(elem)) { LinphoneAccount *acc = (LinphoneAccount *)(elem->data); Account::toCpp(acc)->unpublish(); /* to unpublish without changing the stored flag enable_publish */ LinphoneNatPolicy *policy = linphone_account_params_get_nat_policy(linphone_account_get_params(acc)); if (policy) NatPolicy::toCpp(policy)->release(); /* Do not unregister when push notifications are allowed, otherwise this clears tokens from the SIP * server.*/ if (!linphone_account_params_get_push_notification_allowed(linphone_account_get_params(acc)) && !linphone_account_params_get_remote_push_notification_allowed(linphone_account_get_params(acc))) { Account::toCpp(acc)->unregister(); /* to unregister without changing the stored flag enable_register */ need_to_unregister = TRUE; } } if (need_to_unregister) { ms_message("Unregistration started."); for (i = 0; i < 20 && still_registered; i++) { still_registered = FALSE; lc->sal->iterate(); for (elem = config->accounts; elem != NULL; elem = bctbx_list_next(elem)) { LinphoneAccount *acc = (LinphoneAccount *)(elem->data); if (!linphone_account_params_get_push_notification_allowed(linphone_account_get_params(acc)) && !linphone_account_params_get_remote_push_notification_allowed( linphone_account_get_params(acc))) { LinphoneRegistrationState state = linphone_account_get_state(acc); still_registered = (state == LinphoneRegistrationOk || state == LinphoneRegistrationProgress); } } ms_usleep(100000); } if (i >= 20) ms_warning("Cannot complete unregistration, giving up"); } } elem = config->accounts; config->accounts = NULL; /*to make sure accounts cannot be referenced during deletion*/ bctbx_list_free_with_data(elem, (void (*)(void *))linphone_account_unref); elem = config->proxies; config->proxies = NULL; /*to make sure proxies cannot be referenced during deletion*/ bctbx_list_free_with_data(elem, (void (*)(void *))_linphone_proxy_config_release); config->deleted_accounts = bctbx_list_free_with_data(config->deleted_accounts, (void (*)(void *))linphone_account_unref); config->deleted_proxies = bctbx_list_free_with_data(config->deleted_proxies, (void (*)(void *))_linphone_proxy_config_release); /*no longuer need to write proxy config if not changed * linphone_proxy_config_write_to_config_file(lc->config,NULL,i);*/ /*mark the end */ lc->auth_info = bctbx_list_free_with_data(lc->auth_info, (void (*)(void *))linphone_auth_info_unref); lc->default_account = NULL; lc->default_proxy = NULL; if (lc->vcard_context) { linphone_vcard_context_destroy(lc->vcard_context); lc->vcard_context = NULL; } lc->sal->resetTransports(); lc->sal->unlistenPorts(); /*to make sure no new messages are received*/ if (lc->http_provider) {
7351735273537354735573567357735873597360736173627363736473657366736773687369737073717372737373747375737673777378737973807381738273837384738573867387738873897390739173927393739473957396739773987399740074017402740374047405740674077408740974107411741274137414741574167417741874197420
belle_sip_object_unref(lc->http_provider); lc->http_provider = NULL; } if (lc->http_crypto_config) { belle_sip_object_unref(lc->http_crypto_config); lc->http_crypto_config = NULL; } /*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_unref(lc->tunnel); lc->tunnel = NULL; ms_message("Tunnel destroyed."); } #endif if (lc->nat_policy) NatPolicy::toCpp(lc->nat_policy)->release(); for (i = 0; i < 5; ++i) lc->sal->iterate(); /*make sure event are purged*/ lc->sal = NULL; if (lc->sip_conf.guessed_contact) { ms_free(lc->sip_conf.guessed_contact); lc->sip_conf.guessed_contact = NULL; } if (config->contact) { ms_free(config->contact); config->contact = NULL; } if (lc->default_rls_addr) { linphone_address_unref(lc->default_rls_addr); lc->default_rls_addr = NULL; } linphone_im_notif_policy_unref(lc->im_notif_policy); lc->im_notif_policy = NULL; lc->sip_conf = {0}; if (lc->push_config) linphone_push_notification_config_unref(lc->push_config); } void rtp_config_uninit(LinphoneCore *lc) { rtp_config_t *config = &lc->rtp_conf; if (config->audio_rtp_min_port == config->audio_rtp_max_port) { linphone_config_set_int(lc->config, "rtp", "audio_rtp_port", config->audio_rtp_min_port); } else { linphone_config_set_range(lc->config, "rtp", "audio_rtp_port", config->audio_rtp_min_port, config->audio_rtp_max_port); } if (config->video_rtp_min_port == config->video_rtp_max_port) { linphone_config_set_int(lc->config, "rtp", "video_rtp_port", config->video_rtp_min_port); } else { linphone_config_set_range(lc->config, "rtp", "video_rtp_port", config->video_rtp_min_port, config->video_rtp_max_port); } if (config->text_rtp_min_port == config->text_rtp_max_port) { linphone_config_set_int(lc->config, "rtp", "text_rtp_port", config->text_rtp_min_port); } else { linphone_config_set_range(lc->config, "rtp", "text_rtp_port", config->text_rtp_min_port, config->text_rtp_max_port); } linphone_config_set_int(lc->config, "rtp", "audio_jitt_comp", config->audio_jitt_comp); linphone_config_set_int(lc->config, "rtp", "video_jitt_comp", config->video_jitt_comp); linphone_config_set_int(lc->config, "rtp", "nortp_timeout", config->nortp_timeout); linphone_config_set_int(lc->config, "rtp", "audio_adaptive_jitt_comp_enabled", config->audio_adaptive_jitt_comp_enabled); linphone_config_set_int(lc->config, "rtp", "video_adaptive_jitt_comp_enabled", config->video_adaptive_jitt_comp_enabled);
7421742274237424742574267427742874297430743174327433743474357436743774387439744074417442744374447445744674477448744974507451745274537454745574567457745874597460746174627463746474657466746774687469747074717472747374747475747674777478747974807481748274837484748574867487748874897490
ms_free(lc->rtp_conf.audio_multicast_addr); ms_free(lc->rtp_conf.video_multicast_addr); ms_free(config->srtp_suites); lc->rtp_conf = {0}; } static void sound_config_uninit(LinphoneCore *lc) { sound_config_t *config = &lc->sound_conf; ms_free((void *)config->cards); if (config->ring_sndcard) { ms_snd_card_unref(config->ring_sndcard); config->ring_sndcard = NULL; } if (config->media_sndcard) { ms_snd_card_unref(config->media_sndcard); config->media_sndcard = NULL; } if (config->capt_sndcard) { ms_snd_card_unref(config->capt_sndcard); config->capt_sndcard = NULL; } if (config->play_sndcard) { ms_snd_card_unref(config->play_sndcard); config->play_sndcard = NULL; } linphone_config_set_string(lc->config, "sound", "remote_ring", config->remote_ring); linphone_config_set_float(lc->config, "sound", "playback_gain_db", config->soft_play_lev); linphone_config_set_float(lc->config, "sound", "mic_gain_db", config->soft_mic_lev); linphone_config_set_bool(lc->config, "sound", "disable_record_on_mute", config->disable_record_on_mute); if (config->local_ring) ms_free(config->local_ring); if (config->remote_ring) ms_free(config->remote_ring); lc->tones = bctbx_list_free_with_data(lc->tones, (void (*)(void *))linphone_tone_description_destroy); lc->sound_conf = {0}; } static void video_config_uninit(LinphoneCore *lc) { const LinphoneVideoDefinition *vdef = linphone_core_get_preferred_video_definition(lc); linphone_config_set_string(lc->config, "video", "size", vdef ? linphone_video_definition_get_name(vdef) : NULL); linphone_config_set_int(lc->config, "video", "display", lc->video_conf.display); linphone_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); lc->video_conf = {0}; } #ifndef _MSC_VER #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif // _MSC_VER MSVideoSize linphone_core_get_current_preview_video_size(const LinphoneCore *lc) { MSVideoSize ret = {0}; #ifndef VIDEO_ENABLED ms_error("linphone_core_get_current_preview_video_size() fail. Support for video is disabled"); #else if (lc->previewstream) { ret = video_preview_get_current_size(lc->previewstream); } #endif return ret; } #ifndef _MSC_VER #pragma GCC diagnostic pop #endif // _MSC_VER #ifndef _MSC_VER #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter"
7491749274937494749574967497749874997500750175027503750475057506750775087509751075117512751375147515751675177518751975207521752275237524752575267527752875297530753175327533753475357536753775387539754075417542754375447545754675477548754975507551755275537554755575567557755875597560
#endif // _MSC_VER LinphoneVideoDefinition *linphone_core_get_current_preview_video_definition(const LinphoneCore *lc) { #ifdef VIDEO_ENABLED MSVideoSize vsize = {0}; if (lc->previewstream) { vsize = video_preview_get_current_size(lc->previewstream); } return linphone_factory_find_supported_video_definition(linphone_factory_get(), (unsigned int)vsize.width, (unsigned int)vsize.height); #else ms_error("Video support is disabled"); return NULL; #endif } #ifndef _MSC_VER #pragma GCC diagnostic pop #endif // _MSC_VER 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}; if (vsize.width != 0) linphone_core_set_preferred_video_size(lc, vsize); else linphone_core_set_preferred_video_size(lc, default_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 = (int)linphone_video_definition_get_width(lc->video_conf.vdef); vsize.height = (int)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(linphone_video_definition_get_name(lc->video_conf.vdef)); } void linphone_core_set_preferred_framerate(LinphoneCore *lc, float fps) { lc->video_conf.fps = fps; if (linphone_core_ready(lc)) linphone_config_set_float(lc->config, "video", "framerate", fps); }
7561756275637564756575667567756875697570757175727573757475757576757775787579758075817582758375847585758675877588758975907591759275937594759575967597759875997600760176027603760476057606760776087609761076117612761376147615761676177618761976207621762276237624762576267627762876297630
float linphone_core_get_preferred_framerate(LinphoneCore *lc) { return lc->video_conf.fps; } #ifndef _MSC_VER #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif // _MSC_VER void linphone_core_preview_ogl_render(const LinphoneCore *lc) { #ifdef VIDEO_ENABLED LinphoneCall *call = linphone_core_get_current_call(lc); VideoStream *stream = call ? reinterpret_cast<VideoStream *>(linphone_call_get_stream(call, LinphoneStreamTypeVideo)) : lc->previewstream; if (stream && stream->output2 && ms_filter_get_id(stream->output2) == MS_OGL_ID) { ms_filter_call_method(stream->output2, MS_OGL_RENDER, NULL); } #endif } #ifndef _MSC_VER #pragma GCC diagnostic push #endif // _MSC_VER void linphone_core_set_keep_stream_direction_for_rejected_stream(LinphoneCore *lc, bool_t yesno) { lc->keep_stream_direction_for_rejected_stream = yesno; } bool_t linphone_core_get_keep_stream_direction_for_rejected_stream(LinphoneCore *lc) { return lc->keep_stream_direction_for_rejected_stream; } void linphone_core_set_use_files(LinphoneCore *lc, bool_t yesno) { lc->use_files = yesno; if (yesno) { if (lc->sound_conf.ring_sndcard) { ms_snd_card_unref(lc->sound_conf.ring_sndcard); lc->sound_conf.ring_sndcard = NULL; } if (lc->sound_conf.play_sndcard) { ms_snd_card_unref(lc->sound_conf.play_sndcard); lc->sound_conf.play_sndcard = NULL; } if (lc->sound_conf.capt_sndcard) { ms_snd_card_unref(lc->sound_conf.capt_sndcard); lc->sound_conf.capt_sndcard = NULL; } if (lc->sound_conf.media_sndcard) { ms_snd_card_unref(lc->sound_conf.media_sndcard); lc->sound_conf.media_sndcard = NULL; } } else { linphone_core_set_default_sound_devices(lc); } } bool_t linphone_core_get_use_files(LinphoneCore *lc) { return lc->use_files; } const char *linphone_core_get_play_file(const LinphoneCore *lc) { return lc->play_file; } void linphone_core_set_play_file(LinphoneCore *lc, const char *file) { LinphoneCall *call = linphone_core_get_current_call(lc); if (lc->play_file != NULL) { ms_free(lc->play_file);
7631763276337634763576367637763876397640764176427643764476457646764776487649765076517652765376547655765676577658765976607661766276637664766576667667766876697670767176727673767476757676767776787679768076817682768376847685768676877688768976907691769276937694769576967697769876997700
lc->play_file = NULL; } if (file != NULL) { lc->play_file = ms_strdup(file); if (call) { AudioStream *astream = reinterpret_cast<AudioStream *>(linphone_call_get_stream(call, LinphoneStreamTypeAudio)); if (astream && astream->ms.state == MSStreamStarted) audio_stream_play(astream, file); } } } const char *linphone_core_get_record_file(const LinphoneCore *lc) { return lc->rec_file; } void linphone_core_set_record_file(LinphoneCore *lc, const char *file) { LinphoneCall *call = linphone_core_get_current_call(lc); if (lc->rec_file != NULL) { ms_free(lc->rec_file); lc->rec_file = NULL; } if (file != NULL) { lc->rec_file = ms_strdup(file); if (call) { AudioStream *astream = reinterpret_cast<AudioStream *>(linphone_call_get_stream(call, LinphoneStreamTypeAudio)); if (astream) audio_stream_record(astream, file); } } } void linphone_core_play_dtmf(LinphoneCore *lc, char dtmf, int duration_ms) { CoreLogContextualizer logContextualizer(lc); L_GET_PRIVATE_FROM_C_OBJECT(lc)->getToneManager().playDtmf(dtmf, duration_ms); } LinphoneStatus linphone_core_play_local(LinphoneCore *lc, const char *audiofile) { CoreLogContextualizer logContextualizer(lc); return L_GET_PRIVATE_FROM_C_OBJECT(lc)->getToneManager().playLocal(audiofile); } void linphone_core_stop_dtmf(LinphoneCore *lc) { L_GET_PRIVATE_FROM_C_OBJECT(lc)->getToneManager().stopDtmf(); } void *linphone_core_get_user_data(const LinphoneCore *lc) { return lc->data; } void linphone_core_set_user_data(LinphoneCore *lc, void *userdata) { lc->data = userdata; } int linphone_core_get_mtu(const LinphoneCore *lc) { return lc->net_conf.mtu; } void linphone_core_set_mtu(LinphoneCore *lc, int mtu) { CoreLogContextualizer logContextualizer(lc); lc->net_conf.mtu = mtu; if (mtu > 0) { if (mtu < 500) { ms_error("MTU too small !"); mtu = 500; } ms_factory_set_mtu(lc->factory, mtu); ms_message("MTU is supposed to be %i, rtp payload max size will be %i", mtu, ms_factory_get_payload_max_size(lc->factory)); } else ms_factory_set_mtu(lc->factory, 0); // use mediastreamer2 default value
7701770277037704770577067707770877097710771177127713771477157716771777187719772077217722772377247725772677277728772977307731773277337734773577367737773877397740774177427743774477457746774777487749775077517752775377547755775677577758775977607761776277637764776577667767776877697770
} void linphone_core_set_rtp_transport_factories(LinphoneCore *lc, LinphoneRtpTransportFactories *factories) { lc->rtptf = factories; } int linphone_core_get_current_call_stats(LinphoneCore *lc, rtp_stats_t *local, rtp_stats_t *remote) { LinphoneCall *call = linphone_core_get_current_call(lc); if (call) { AudioStream *astream = reinterpret_cast<AudioStream *>(linphone_call_get_stream(call, LinphoneStreamTypeAudio)); if (astream) { memset(remote, 0, sizeof(*remote)); audio_stream_get_local_rtp_stats(astream, local); return 0; } } return -1; } void _linphone_core_codec_config_write(LinphoneCore *lc) { if (linphone_core_ready(lc)) { PayloadType *pt; codecs_config_t *config = &lc->codecs_conf; bctbx_list_t *node; char key[50]; int index; index = 0; for (node = config->audio_codecs; node != NULL; node = bctbx_list_next(node)) { pt = (PayloadType *)(node->data); sprintf(key, "audio_codec_%i", index); linphone_config_set_string(lc->config, key, "mime", pt->mime_type); linphone_config_set_int(lc->config, key, "rate", pt->clock_rate); if (pt->flags & PAYLOAD_TYPE_BITRATE_OVERRIDE) linphone_config_set_int(lc->config, key, "bitrate", pt->normal_bitrate); linphone_config_set_int(lc->config, key, "channels", pt->channels); linphone_config_set_int(lc->config, key, "enabled", payload_type_enabled(pt)); linphone_config_set_string(lc->config, key, "recv_fmtp", pt->recv_fmtp); index++; } sprintf(key, "audio_codec_%i", index); linphone_config_clean_section(lc->config, key); index = 0; for (node = config->video_codecs; node != NULL; node = bctbx_list_next(node)) { pt = (PayloadType *)(node->data); sprintf(key, "video_codec_%i", index); linphone_config_set_string(lc->config, key, "mime", pt->mime_type); linphone_config_set_int(lc->config, key, "rate", pt->clock_rate); if (pt->flags & PAYLOAD_TYPE_BITRATE_OVERRIDE) linphone_config_set_int(lc->config, key, "bitrate", pt->normal_bitrate); linphone_config_set_int(lc->config, key, "enabled", payload_type_enabled(pt)); linphone_config_set_string(lc->config, key, "recv_fmtp", pt->recv_fmtp); index++; } sprintf(key, "video_codec_%i", index); linphone_config_clean_section(lc->config, key); } } static void codecs_config_uninit(LinphoneCore *lc) { _linphone_core_codec_config_write(lc); bctbx_list_free(lc->codecs_conf.audio_codecs); bctbx_list_free(lc->codecs_conf.video_codecs); bctbx_list_free(lc->codecs_conf.text_codecs); lc->codecs_conf = {0}; } void friends_config_uninit(LinphoneCore *lc) { ms_message("Destroying friends."); lc->friends_lists = bctbx_list_free_with_data(lc->friends_lists, (void (*)(void *))_linphone_friend_list_release);
7771777277737774777577767777777877797780778177827783778477857786778777887789779077917792779377947795779677977798779978007801780278037804780578067807780878097810781178127813781478157816781778187819782078217822782378247825782678277828782978307831783278337834783578367837783878397840
if (lc->subscribers) { lc->subscribers = bctbx_list_free_with_data(lc->subscribers, (void (*)(void *))_linphone_friend_release); } if (lc->presence_model) { linphone_presence_model_unref(lc->presence_model); lc->presence_model = NULL; } ms_message("Destroying friends done."); } void misc_config_uninit(LinphoneCore *lc) { if (lc->base_contacts_list_http_listener != NULL) { belle_sip_object_unref(lc->base_contacts_list_http_listener); lc->base_contacts_list_http_listener = NULL; } if (lc->base_contacts_list_for_synchronization != NULL) { linphone_friend_list_unref(lc->base_contacts_list_for_synchronization); lc->base_contacts_list_for_synchronization = NULL; } } void linphone_core_enter_background(LinphoneCore *lc) { L_GET_CPP_PTR_FROM_C_OBJECT(lc)->enterBackground(); } void linphone_core_enter_foreground(LinphoneCore *lc) { L_GET_CPP_PTR_FROM_C_OBJECT(lc)->enterForeground(); } LpConfig *linphone_core_get_config(const LinphoneCore *lc) { return lc->config; } LpConfig *linphone_core_create_lp_config(BCTBX_UNUSED(LinphoneCore *lc), const char *filename) { return linphone_config_new(filename); } LinphoneConfig *linphone_core_create_config(BCTBX_UNUSED(LinphoneCore *lc), const char *filename) { return linphone_config_new(filename); } LinphoneAddress *linphone_core_create_address(BCTBX_UNUSED(LinphoneCore *lc), const char *address) { return linphone_address_new(address); } LinphoneXmlRpcSession *linphone_core_create_xml_rpc_session(LinphoneCore *lc, const char *url) { return linphone_xml_rpc_session_new(lc, url); } /** * First part of the async Core stop: * Called by linphone_core_stop_async() to begin the async stop process and change the state to "Shutdown" */ static void _linphone_core_stop_async_start(LinphoneCore *lc) { if (linphone_core_get_global_state(lc) == LinphoneGlobalOff) { ms_message("Core [%p] is already stopped", lc); return; } linphone_task_list_free(&lc->hooks); lc->video_conf.show_local = FALSE; L_GET_PRIVATE_FROM_C_OBJECT(lc)->shutdown(); #ifdef VIDEO_ENABLED if (lc->previewstream != NULL) { video_preview_stop(lc->previewstream); lc->previewstream = NULL;
7841784278437844784578467847784878497850785178527853785478557856785778587859786078617862786378647865786678677868786978707871787278737874787578767877787878797880788178827883788478857886788778887889789078917892789378947895789678977898789979007901790279037904790579067907790879097910
} #endif linphone_core_set_state(lc, LinphoneGlobalShutdown, "Shutdown"); #if TARGET_OS_IPHONE L_GET_CPP_PTR_FROM_C_OBJECT(lc)->onStopAsyncBackgroundTaskStarted(); #endif } /** * Second part of the async Core stop: * After we made sure all asynchronous tasks are finished, this function is called to clean the objects * and change the state to "Off" */ void _linphone_core_stop_async_end(LinphoneCore *lc) { // Call uninit here because there may be the need to access DB while unregistering L_GET_PRIVATE_FROM_C_OBJECT(lc)->uninit(); lc->chat_rooms = bctbx_list_free_with_data(lc->chat_rooms, (bctbx_list_free_func)linphone_chat_room_unref); if (lc->platform_helper) getPlatformHelpers(lc)->onLinphoneCoreStop(); /* save all config */ friends_config_uninit(lc); sip_config_uninit(lc); net_config_uninit(lc); rtp_config_uninit(lc); sound_config_uninit(lc); video_config_uninit(lc); codecs_config_uninit(lc); misc_config_uninit(lc); sip_setup_unregister_all(); // We have to disconnect mainDB later since sip_config_uninit iterates L_GET_PRIVATE_FROM_C_OBJECT(lc)->disconnectMainDb(); if (linphone_config_needs_commit(lc->config)) linphone_core_config_sync(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->plugin_list) { bctbx_list_free_with_data(lc->plugin_list, (bctbx_list_free_func)bctbx_free); lc->plugin_list = NULL; } if (lc->supported_encryptions) { bctbx_list_free(lc->supported_encryptions); lc->supported_encryptions = NULL; } if (lc->conference_version) { ms_free(lc->conference_version); lc->conference_version = NULL; } if (lc->groupchat_version) { ms_free(lc->groupchat_version); lc->groupchat_version = NULL; } if (lc->ephemeral_version) { ms_free(lc->ephemeral_version); lc->ephemeral_version = NULL; } if (lc->zrtp_secrets_cache != NULL) { ms_free(lc->zrtp_secrets_cache); lc->zrtp_secrets_cache = NULL; } if (lc->user_certificates_path != NULL) { ms_free(lc->user_certificates_path); lc->user_certificates_path = NULL;
7911791279137914791579167917791879197920792179227923792479257926792779287929793079317932793379347935793679377938793979407941794279437944794579467947794879497950795179527953795479557956795779587959796079617962796379647965796679677968796979707971797279737974797579767977797879797980
} if (lc->play_file != NULL) { ms_free(lc->play_file); lc->play_file = NULL; } if (lc->rec_file != NULL) { ms_free(lc->rec_file); lc->rec_file = NULL; } if (lc->friends_db_file) { ms_free(lc->friends_db_file); lc->friends_db_file = NULL; } if (lc->tls_key) { ms_free(lc->tls_key); lc->tls_key = NULL; } if (lc->tls_cert) { ms_free(lc->tls_cert); lc->tls_cert = NULL; } if (lc->ringtoneplayer) { linphone_ringtoneplayer_destroy(lc->ringtoneplayer); lc->ringtoneplayer = NULL; } if (lc->im_encryption_engine) { linphone_im_encryption_engine_unref(lc->im_encryption_engine); lc->im_encryption_engine = NULL; } if (lc->default_ac_service) { linphone_account_creator_service_unref(lc->default_ac_service); lc->default_ac_service = NULL; } linphone_core_free_payload_types(lc); if (lc->supported_formats) ms_free((void *)lc->supported_formats); lc->supported_formats = NULL; linphone_core_friends_storage_close(lc); linphone_core_zrtp_cache_close(lc); ms_bandwidth_controller_destroy(lc->bw_controller); lc->bw_controller = NULL; if (lc->callsCache) { // Ensure to remove cache before destroying factory bctbx_list_free(lc->callsCache); lc->callsCache = NULL; } #if TARGET_OS_IPHONE if (lc->platform_helper) { getPlatformHelpers(lc)->stop(); /* this will unlock the other Linphone Shared Core that are waiting to start (if any). We need to unlock them at the very end of the stopping process otherwise two Cores will process at the same time until this one is finally stopped */ LinphonePrivate::uninitSharedCore(lc); } #else if (lc->platform_helper) delete getPlatformHelpers(lc); lc->platform_helper = NULL; #endif linphone_core_set_state(lc, LinphoneGlobalOff, "Off"); #if TARGET_OS_IPHONE L_GET_CPP_PTR_FROM_C_OBJECT(lc)->onStopAsyncBackgroundTaskStopped(); #endif } static void _linphone_core_stop(LinphoneCore *lc) { if (linphone_core_get_global_state(lc) == LinphoneGlobalOff) { ms_message("Core [%p] is already stopped", lc); return; }
7981798279837984798579867987798879897990799179927993799479957996799779987999800080018002800380048005800680078008800980108011801280138014801580168017801880198020802180228023802480258026802780288029803080318032803380348035803680378038803980408041804280438044804580468047804880498050
_linphone_core_stop_async_start(lc); bool_t is_off = FALSE; uint64_t start_time = ms_get_cur_time_ms(); while (!is_off && ms_get_cur_time_ms() - start_time < 1000) { linphone_core_iterate(lc); ms_usleep(50000); is_off = (linphone_core_get_global_state(lc) == LinphoneGlobalOff); } /* linphone_core_iterate() can call _linphone_core_stop_async_end() if all asynchronous tasks are done so we don't need to call it twice */ if (!is_off) { _linphone_core_stop_async_end(lc); } } void linphone_core_stop(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); _linphone_core_stop(lc); } void linphone_core_stop_async(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); _linphone_core_stop_async_start(lc); } void _linphone_core_uninit(LinphoneCore *lc) { lc->is_unreffing = TRUE; if (lc->state != LinphoneGlobalOff) { _linphone_core_stop(lc); } if (lc->platform_helper) delete getPlatformHelpers(lc); lc->platform_helper = NULL; linphone_config_unref(lc->config); lc->config = NULL; #ifdef __ANDROID__ if (lc->system_context) { JNIEnv *env = ms_get_jni_env(); env->DeleteGlobalRef((jobject)lc->system_context); } #endif lc->system_context = NULL; linphone_core_deactivate_log_serialization_if_needed(); bctbx_list_free_with_data(lc->vtable_refs, (void (*)(void *))v_table_reference_destroy); if (lc->msevq) { ms_factory_destroy_event_queue(lc->factory); lc->msevq = NULL; } ms_factory_destroy(lc->factory); lc->factory = NULL; bctbx_uninit_logger(); } static void stop_refreshing_proxy_config(bool_t is_sip_reachable, LinphoneProxyConfig *cfg) { if (linphone_proxy_config_register_enabled(cfg)) { if (!is_sip_reachable) { linphone_proxy_config_stop_refreshing(cfg); linphone_proxy_config_set_state(cfg, LinphoneRegistrationNone, "Registration impossible (network down)"); } else { Account::toCpp(cfg->account)->setNeedToRegister(true); if (linphone_proxy_config_publish_enabled(cfg)) Account::toCpp(cfg->account)->setSendPublish(true); /*not sure if really the best place*/ } }
8051805280538054805580568057805880598060806180628063806480658066806780688069807080718072807380748075807680778078807980808081808280838084808580868087808880898090809180928093809480958096809780988099810081018102810381048105810681078108810981108111811281138114811581168117811881198120
} static void set_sip_network_reachable(LinphoneCore *lc, bool_t is_sip_reachable, time_t curtime) { // second get the list of available proxies const bctbx_list_t *elem = NULL; if (is_sip_reachable) { // Update DNS servers even if network was reachable and is still is, a change might have occured getPlatformHelpers(lc)->setDnsServers(); } if (lc->sip_network_state.global_state == is_sip_reachable) return; // no change, ignore. lc->network_reachable_to_be_notified = TRUE; if (is_sip_reachable) { if (lc->sip_conf.guess_hostname) update_primary_contact(lc); } ms_message("SIP network reachability state is now [%s]", is_sip_reachable ? "UP" : "DOWN"); for (elem = linphone_core_get_proxy_config_list(lc); elem != NULL; elem = elem->next) { LinphoneProxyConfig *cfg = (LinphoneProxyConfig *)elem->data; stop_refreshing_proxy_config(is_sip_reachable, cfg); } for (elem = lc->sip_conf.deleted_proxies; elem != NULL; elem = elem->next) { LinphoneProxyConfig *deleted_cfg = (LinphoneProxyConfig *)elem->data; stop_refreshing_proxy_config(is_sip_reachable, deleted_cfg); } lc->netup_time = curtime; lc->sip_network_state.global_state = is_sip_reachable; if (!lc->sip_network_state.global_state) { linphone_core_invalidate_friend_subscriptions(lc); lc->sal->resetTransports(); } } static void set_media_network_reachable(LinphoneCore *lc, bool_t is_media_reachable) { if (lc->media_network_state.global_state == is_media_reachable) return; // no change, ignore. lc->network_reachable_to_be_notified = TRUE; ms_message("Media network reachability state is now [%s]", is_media_reachable ? "UP" : "DOWN"); lc->media_network_state.global_state = is_media_reachable; if (lc->media_network_state.global_state) { if (lc->bw_controller) { ms_bandwidth_controller_reset_state(lc->bw_controller); } } } void linphone_core_refresh_registers(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); const bctbx_list_t *elem; if (!lc->sip_network_state.global_state) { ms_warning("Refresh register operation not available (network unreachable)"); return; } elem = linphone_core_get_proxy_config_list(lc); for (; elem != NULL; elem = elem->next) { LinphoneProxyConfig *cfg = (LinphoneProxyConfig *)elem->data; if (linphone_proxy_config_register_enabled(cfg) && linphone_proxy_config_get_expires(cfg) > 0) { linphone_proxy_config_refresh_register(cfg); } } } void linphone_core_set_network_reachable_internal(LinphoneCore *lc, bool_t is_reachable) { if (lc->auto_net_state_mon) { set_sip_network_reachable(lc, lc->sip_network_state.user_state && is_reachable, ms_time(NULL));
8121812281238124812581268127812881298130813181328133813481358136813781388139814081418142814381448145814681478148814981508151815281538154815581568157815881598160816181628163816481658166816781688169817081718172817381748175817681778178817981808181818281838184818581868187818881898190
set_media_network_reachable(lc, lc->media_network_state.user_state && is_reachable); notify_network_reachable_change(lc); } } void linphone_core_set_network_reachable(LinphoneCore *lc, bool_t is_reachable) { CoreLogContextualizer logContextualizer(lc); bool_t reachable = is_reachable; lc->sip_network_state.user_state = is_reachable; lc->media_network_state.user_state = is_reachable; if (lc->auto_net_state_mon) reachable = reachable && getPlatformHelpers(lc)->isNetworkReachable(); set_sip_network_reachable(lc, reachable, ms_time(NULL)); set_media_network_reachable(lc, reachable); notify_network_reachable_change(lc); } void linphone_core_set_media_network_reachable(LinphoneCore *lc, bool_t is_reachable) { CoreLogContextualizer logContextualizer(lc); bool_t reachable = is_reachable; lc->media_network_state.user_state = is_reachable; if (lc->auto_net_state_mon) reachable = reachable && getPlatformHelpers(lc)->isNetworkReachable(); set_media_network_reachable(lc, reachable); notify_network_reachable_change(lc); } void linphone_core_set_sip_network_reachable(LinphoneCore *lc, bool_t is_reachable) { CoreLogContextualizer logContextualizer(lc); bool_t reachable = is_reachable; lc->sip_network_state.user_state = is_reachable; if (lc->auto_net_state_mon) reachable = reachable && getPlatformHelpers(lc)->isNetworkReachable(); set_sip_network_reachable(lc, reachable, ms_time(NULL)); notify_network_reachable_change(lc); } bool_t linphone_core_is_network_reachable(BCTBX_UNUSED(LinphoneCore *lc)) { return lc->sip_network_state.global_state; } ortp_socket_t linphone_core_get_sip_socket(BCTBX_UNUSED(LinphoneCore *lc)) { ms_warning("linphone_core_get_sip_socket is deprecated"); return -1; } void linphone_core_destroy(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); linphone_core_unref(lc); } int linphone_core_get_calls_nb(const LinphoneCore *lc) { return (int)L_GET_CPP_PTR_FROM_C_OBJECT(lc)->getCallCount(); } void linphone_core_activate_audio_session(LinphoneCore *lc, bool_t actived) { L_GET_CPP_PTR_FROM_C_OBJECT(lc)->soundcardActivateAudioSession(actived); } void linphone_core_configure_audio_session(LinphoneCore *lc) { if (linphone_core_get_calls_nb(lc) < 2) { L_GET_CPP_PTR_FROM_C_OBJECT(lc)->soundcardConfigureAudioSession(); } }
8191819281938194819581968197819881998200820182028203820482058206820782088209821082118212821382148215821682178218821982208221822282238224822582268227822882298230823182328233823482358236823782388239824082418242824382448245824682478248824982508251825282538254825582568257825882598260
void linphone_core_enable_callkit(LinphoneCore *lc, bool_t enabled) { L_GET_CPP_PTR_FROM_C_OBJECT(lc)->soundcardEnableCallkit(enabled); linphone_config_set_int(lc->config, "app", "use_callkit", (int)enabled); } void linphone_core_audio_route_changed(LinphoneCore *core) { L_GET_CPP_PTR_FROM_C_OBJECT(core)->soundcardAudioRouteChanged(); } bool_t linphone_core_callkit_enabled(const LinphoneCore *core) { return (bool_t)linphone_config_get_int(core->config, "app", "use_callkit", 0); } bool_t linphone_core_local_permission_enabled(const LinphoneCore *core) { CoreLogContextualizer logContextualizer(core); if (getPlatformHelpers(core)->getNetworkType() != PlatformHelpers::NetworkType::Wifi) { lInfo() << "IceService::hasLocalNetworkPermission() assuming true when network is not wifi"; return TRUE; } return (bool_t)IceService::hasLocalNetworkPermission(); } void linphone_core_set_remote_ringback_tone(LinphoneCore *lc, const char *file) { if (lc->sound_conf.ringback_tone) { ms_free(lc->sound_conf.ringback_tone); lc->sound_conf.ringback_tone = NULL; } if (file) lc->sound_conf.ringback_tone = ms_strdup(file); } const char *linphone_core_get_remote_ringback_tone(const LinphoneCore *lc) { return lc->sound_conf.ringback_tone; } void linphone_core_set_ring_during_incoming_early_media(LinphoneCore *lc, bool_t enable) { linphone_config_set_int(lc->config, "sound", "ring_during_incoming_early_media", (int)enable); } bool_t linphone_core_get_ring_during_incoming_early_media(const LinphoneCore *lc) { return (bool_t)linphone_config_get_int(lc->config, "sound", "ring_during_incoming_early_media", 0); } 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, lc->codecs_conf.audio_codecs); if (result) { return result; } else { 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, lc->codecs_conf.text_codecs); if (result) { return result; } } } /*not found*/ return NULL; } OrtpPayloadType *linphone_core_find_payload_type(LinphoneCore *lc, const char *type, int rate, int channels) { return _linphone_core_find_payload_type(lc, type, rate, channels); } LinphonePayloadType *linphone_core_get_payload_type(LinphoneCore *lc, const char *type, int rate, int channels) { CoreLogContextualizer logContextualizer(lc); OrtpPayloadType *pt = _linphone_core_find_payload_type(lc, type, rate, channels); return pt ? linphone_payload_type_new(lc, pt) : NULL;
8261826282638264826582668267826882698270827182728273827482758276827782788279828082818282828382848285828682878288828982908291829282938294829582968297829882998300830183028303830483058306830783088309831083118312831383148315831683178318831983208321832283238324832583268327832883298330
} const char *linphone_configuring_state_to_string(LinphoneConfiguringState cs) { switch (cs) { case LinphoneConfiguringSuccessful: return "LinphoneConfiguringSuccessful"; case LinphoneConfiguringFailed: return "LinphoneConfiguringFailed"; case LinphoneConfiguringSkipped: return "LinphoneConfiguringSkipped"; } return NULL; } const char *linphone_global_state_to_string(LinphoneGlobalState gs) { switch (gs) { case LinphoneGlobalOff: return "LinphoneGlobalOff"; case LinphoneGlobalOn: return "LinphoneGlobalOn"; case LinphoneGlobalStartup: return "LinphoneGlobalStartup"; case LinphoneGlobalShutdown: return "LinphoneGlobalShutdown"; case LinphoneGlobalConfiguring: return "LinphoneGlobalConfiguring"; case LinphoneGlobalReady: return "LinphoneGlobalReady"; break; } return NULL; } LinphoneGlobalState linphone_core_get_global_state(const LinphoneCore *lc) { return lc->state; } LinphoneCallParams *linphone_core_create_call_params(LinphoneCore *lc, LinphoneCall *call) { CoreLogContextualizer logContextualizer(lc); if (!call) return linphone_call_params_new(lc); if (linphone_call_get_params(call)) { return _linphone_call_params_copy(linphone_call_get_params(call)); } ms_error( "linphone_core_create_call_params(): call [%p] is not in a state where call params can be created or used.", call); return NULL; } const char *linphone_error_to_string(LinphoneReason err) { return linphone_reason_to_string(err); } void linphone_core_enable_keep_alive(LinphoneCore *lc, bool_t enable) { CoreLogContextualizer logContextualizer(lc); if (enable > 0) { lc->sal->useTcpTlsKeepAlive(!!lc->sip_conf.tcp_tls_keepalive); lc->sal->setKeepAlivePeriod(lc->sip_conf.keepalive_period); } else { lc->sal->setKeepAlivePeriod(0); } } bool_t linphone_core_keep_alive_enabled(LinphoneCore *lc) { return lc->sal->getKeepAlivePeriod() > 0; } void linphone_core_start_dtmf_stream(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); if (linphone_core_get_global_state(lc) != LinphoneGlobalShutdown)
8331833283338334833583368337833883398340834183428343834483458346834783488349835083518352835383548355835683578358835983608361836283638364836583668367836883698370837183728373837483758376837783788379838083818382838383848385838683878388838983908391839283938394839583968397839883998400
L_GET_PRIVATE_FROM_C_OBJECT(lc)->getToneManager().startDtmfStream(); } void linphone_core_stop_ringing(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); L_GET_PRIVATE_FROM_C_OBJECT(lc)->getToneManager().freeAudioResources(); } void linphone_core_stop_dtmf_stream(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); L_GET_PRIVATE_FROM_C_OBJECT(lc)->getToneManager().stopDtmfStream(); } void linphone_core_stop_tone_manager(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); L_GET_PRIVATE_FROM_C_OBJECT(lc)->getToneManager().freeAudioResources(); } int linphone_core_get_max_calls(LinphoneCore *lc) { return lc->max_calls; } void linphone_core_set_max_calls(LinphoneCore *lc, int max) { lc->max_calls = max; } void linphone_core_add_iterate_hook(LinphoneCore *lc, LinphoneCoreIterateHook hook, void *hook_data) { linphone_task_list_add(&lc->hooks, hook, hook_data); } static void linphone_core_run_hooks(LinphoneCore *lc) { linphone_task_list_run(&lc->hooks); } void linphone_core_remove_iterate_hook(LinphoneCore *lc, LinphoneCoreIterateHook hook, void *hook_data) { linphone_task_list_remove(&lc->hooks, hook, hook_data); } // ============================================================================= // TODO: Remove me later, code found in message_storage.c. // ============================================================================= #ifdef HAVE_SQLITE int _linphone_sqlite3_open(const char *db_file, sqlite3 **db) { char *errmsg = NULL; int ret; int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; #if TARGET_OS_IPHONE /* the secured filesystem of the iPHone doesn't allow writing while the app is in background mode, which is * problematic. We workaround by asking that the open is made with no protection*/ flags |= SQLITE_OPEN_FILEPROTECTION_NONE; #endif /*since we plug our vfs into sqlite, we convert to UTF-8. * On Windows, the filename has to be converted back to windows native charset.*/ char *utf8_filename = bctbx_locale_to_utf8(db_file); ret = sqlite3_open_v2(utf8_filename, db, flags, BCTBX_SQLITE3_VFS); ms_free(utf8_filename); if (ret != SQLITE_OK) return ret; // Some platforms do not provide a way to create temporary files which are needed // for transactions... so we work in memory only // see http ://www.sqlite.org/compile.html#temp_store ret = sqlite3_exec(*db, "PRAGMA temp_store=MEMORY", NULL, NULL, &errmsg); if (ret != SQLITE_OK) { ms_error("Cannot set sqlite3 temporary store to memory: %s.", errmsg); sqlite3_free(errmsg); }
8401840284038404840584068407840884098410841184128413841484158416841784188419842084218422842384248425842684278428842984308431843284338434843584368437843884398440844184428443844484458446844784488449845084518452845384548455845684578458845984608461846284638464846584668467846884698470
return ret; } #endif // ============================================================================= // migration code remove in april 2019, 2 years after switching from xml based zrtp cache to sqlite void linphone_core_set_zrtp_secrets_file(LinphoneCore *lc, const char *file) { if (lc->zrtp_secrets_cache != NULL) { ms_free(lc->zrtp_secrets_cache); linphone_core_zrtp_cache_close(lc); lc->zrtp_secrets_cache = NULL; } if (file) { lc->zrtp_secrets_cache = ms_strdup(file); linphone_core_zrtp_cache_db_init(lc, file); } } const char *linphone_core_get_zrtp_secrets_file(LinphoneCore *lc) { return lc->zrtp_secrets_cache; } zrtpCacheAccess linphone_core_get_zrtp_cache_access(LinphoneCore *lc) { zrtpCacheAccess ret; ret.db = (void *)lc->zrtp_cache_db; ret.dbMutex = &(lc->zrtp_cache_db_mutex); return ret; } void *linphone_core_get_zrtp_cache_db(LinphoneCore *lc) { return (void *)lc->zrtp_cache_db; } LinphoneZrtpPeerStatus linphone_core_get_zrtp_status(LinphoneCore *lc, const char *peerUri) { int status = MS_ZRTP_PEER_STATUS_UNKNOWN; if (lc->zrtp_cache_db) { status = ms_zrtp_get_peer_status(lc->zrtp_cache_db, peerUri, &(lc->zrtp_cache_db_mutex)); } switch (status) { case MS_ZRTP_PEER_STATUS_UNKNOWN: return LinphoneZrtpPeerStatusUnknown; case MS_ZRTP_PEER_STATUS_INVALID: return LinphoneZrtpPeerStatusInvalid; case MS_ZRTP_PEER_STATUS_VALID: return LinphoneZrtpPeerStatusValid; default: return LinphoneZrtpPeerStatusUnknown; } } static void linphone_core_zrtp_cache_close(LinphoneCore *lc) { #ifdef HAVE_SQLITE if (lc->zrtp_cache_db) { sqlite3_close(lc->zrtp_cache_db); bctbx_mutex_destroy(&(lc->zrtp_cache_db_mutex)); lc->zrtp_cache_db = NULL; } #endif } void linphone_core_zrtp_cache_db_init(LinphoneCore *lc, const char *fileName) { #ifdef HAVE_SQLITE int ret; const char *errmsg; const char *backupExtension = "_backup"; char *backupName = bctbx_strdup_printf("%s%s", fileName, backupExtension); sqlite3 *db;
8471847284738474847584768477847884798480848184828483848484858486848784888489849084918492849384948495849684978498849985008501850285038504850585068507850885098510851185128513851485158516851785188519852085218522852385248525852685278528852985308531853285338534853585368537853885398540
linphone_core_zrtp_cache_close(lc); bctbx_mutex_init(&(lc->zrtp_cache_db_mutex), NULL); 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", fileName, errmsg); sqlite3_close(db); unlink(backupName); rename(fileName, backupName); lc->zrtp_cache_db = NULL; goto end; } ret = ms_zrtp_initCache((void *)db, &(lc->zrtp_cache_db_mutex)); /* this may perform an update, check return value */ 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); unlink(backupName); rename(fileName, backupName); lc->zrtp_cache_db = NULL; goto end; } /* everything ok, set the db pointer into core */ lc->zrtp_cache_db = db; end: if (backupName) bctbx_free(backupName); #else ms_warning("linphone_core_zrtp_cache_db_init(): stubbed."); #endif } void linphone_core_set_user_certificates_path(LinphoneCore *lc, const char *path) { char *new_value = path ? bctbx_strdup(path) : NULL; if (lc->user_certificates_path) bctbx_free(lc->user_certificates_path); lc->user_certificates_path = new_value; linphone_config_set_string(lc->config, "misc", "user_certificates_path", lc->user_certificates_path); } const char *linphone_core_get_user_certificates_path(LinphoneCore *lc) { return lc->user_certificates_path; } bool_t linphone_core_sound_resources_locked(LinphoneCore *lc) { return !!L_GET_CPP_PTR_FROM_C_OBJECT(lc)->areSoundResourcesLocked(); } void linphone_core_set_srtp_enabled(LinphoneCore *lc, bool_t enabled) { linphone_config_set_int(lc->config, "sip", "srtp", (int)enabled); } void linphone_core_enable_zrtp_go_clear(LinphoneCore *lc, bool_t enabled) { #ifdef HAVE_GOCLEAR linphone_config_set_int(linphone_core_get_config(lc), "sip", "enable_go_clear", (int)enabled); #endif // HAVE_GOCLEAR } bool_t linphone_core_zrtp_go_clear_enabled(const LinphoneCore *lc) { #ifdef HAVE_GOCLEAR return linphone_config_get_bool(linphone_core_get_config(lc), "sip", "enable_go_clear", FALSE); #else
8541854285438544854585468547854885498550855185528553855485558556855785588559856085618562856385648565856685678568856985708571857285738574857585768577857885798580858185828583858485858586858785888589859085918592859385948595859685978598859986008601860286038604860586068607860886098610
return FALSE; #endif // HAVE_GOCLEAR } int linphone_media_encryption_from_string(const char *value) { if (strcmp(value, "LinphoneMediaEncryptionSRTP") == 0) { return LinphoneMediaEncryptionSRTP; } else if (strcmp(value, "LinphoneMediaEncryptionDTLS") == 0) { return LinphoneMediaEncryptionDTLS; } else if (strcmp(value, "LinphoneMediaEncryptionZRTP") == 0) { return LinphoneMediaEncryptionZRTP; } else if (strcmp(value, "LinphoneMediaEncryptionNone") == 0) { return LinphoneMediaEncryptionNone; } else { ms_error("Unable to find LinphoneMediaEncryption for %s", value); return -1; } return -1; } const char *linphone_media_encryption_to_string(LinphoneMediaEncryption media_encryption) { switch (media_encryption) { case LinphoneMediaEncryptionSRTP: return "LinphoneMediaEncryptionSRTP"; case LinphoneMediaEncryptionDTLS: return "LinphoneMediaEncryptionDTLS"; case LinphoneMediaEncryptionZRTP: return "LinphoneMediaEncryptionZRTP"; case LinphoneMediaEncryptionNone: return "LinphoneMediaEncryptionNone"; } ms_error("Invalid LinphoneMediaEncryption value %i", (int)media_encryption); return "INVALID"; } const char *linphone_media_direction_to_string(LinphoneMediaDirection media_direction) { switch (media_direction) { case LinphoneMediaDirectionInvalid: return "Invalid"; case LinphoneMediaDirectionInactive: return "Inactive"; case LinphoneMediaDirectionRecvOnly: return "RecvOnly"; case LinphoneMediaDirectionSendOnly: return "SendOnly"; case LinphoneMediaDirectionSendRecv: return "SendRecv"; } ms_error("Invalid LinphoneMediaDirection value %i", (int)media_direction); return "INVALID"; } bool_t linphone_core_media_encryption_supported(LinphoneCore *lc, LinphoneMediaEncryption menc) { bool_t menc_supported_by_core = linphone_core_is_media_encryption_supported(lc, menc) || (linphone_core_get_media_encryption(lc) == menc); bool_t menc_supported_by_library = FALSE; switch (menc) { case LinphoneMediaEncryptionSRTP: menc_supported_by_library = ms_srtp_supported(); break; case LinphoneMediaEncryptionDTLS: menc_supported_by_library = ms_dtls_srtp_available(); break; case LinphoneMediaEncryptionZRTP: menc_supported_by_library = ms_zrtp_available() && !lc->zrtp_not_available_simulation; break; case LinphoneMediaEncryptionNone: menc_supported_by_library = TRUE; break;
8611861286138614861586168617861886198620862186228623862486258626862786288629863086318632863386348635863686378638863986408641864286438644864586468647864886498650865186528653865486558656865786588659866086618662866386648665866686678668866986708671867286738674867586768677867886798680
} return (menc_supported_by_core && menc_supported_by_library); } LinphoneStatus linphone_core_set_media_encryption(LinphoneCore *lc, LinphoneMediaEncryption menc) { CoreLogContextualizer logContextualizer(lc); const char *type = "none"; int ret = -1; switch (menc) { case LinphoneMediaEncryptionSRTP: if (!ms_srtp_supported()) { ms_warning("SRTP not supported by library."); type = "none"; ret = -1; } else { type = "srtp"; ret = 0; } break; case LinphoneMediaEncryptionZRTP: if (!linphone_core_media_encryption_supported(lc, LinphoneMediaEncryptionZRTP)) { ms_warning("ZRTP not supported by library."); type = "none"; ret = -1; } else { type = "zrtp"; ret = 0; } break; case LinphoneMediaEncryptionDTLS: if (!ms_dtls_srtp_available()) { ms_warning("DTLS not supported by library."); type = "none"; ret = -1; } else { type = "dtls"; ret = 0; } break; case LinphoneMediaEncryptionNone: type = "none"; ret = 0; break; } linphone_config_set_string(lc->config, "sip", "media_encryption", type); return ret; } LinphoneMediaEncryption linphone_core_get_media_encryption(const LinphoneCore *lc) { const char *menc = linphone_config_get_string(lc->config, "sip", "media_encryption", NULL); if (menc == NULL) return LinphoneMediaEncryptionNone; else if (strcmp(menc, "srtp") == 0) return LinphoneMediaEncryptionSRTP; else if (strcmp(menc, "dtls") == 0) return LinphoneMediaEncryptionDTLS; else if (strcmp(menc, "zrtp") == 0) return LinphoneMediaEncryptionZRTP; else return LinphoneMediaEncryptionNone; } bool_t linphone_core_is_media_encryption_mandatory(LinphoneCore *lc) { return (bool_t) !!linphone_config_get_int(lc->config, "sip", "media_encryption_mandatory", 0); } void linphone_core_set_media_encryption_mandatory(LinphoneCore *lc, bool_t m) { linphone_config_set_int(lc->config, "sip", "media_encryption_mandatory", (int)m); } bool_t linphone_core_zero_rtp_port_for_stream_inactive_enabled(const LinphoneCore *lc) { return (bool_t) !!linphone_config_get_int(lc->config, "sip", "zero_rtp_port_for_stream_inactive", 0); }
8681868286838684868586868687868886898690869186928693869486958696869786988699870087018702870387048705870687078708870987108711871287138714871587168717871887198720872187228723872487258726872787288729873087318732873387348735873687378738873987408741874287438744874587468747874887498750
void linphone_core_enable_zero_rtp_port_for_stream_inactive(LinphoneCore *lc, bool_t enable) { linphone_config_set_int(lc->config, "sip", "zero_rtp_port_for_stream_inactive", (int)enable); } bool_t linphone_core_capability_negotiation_reinvite_enabled(const LinphoneCore *lc) { return (bool_t) !!linphone_config_get_int(lc->config, "sip", "capability_negotiations_reinvite", 1); } void linphone_core_enable_capability_negotiation_reinvite(LinphoneCore *lc, bool_t enable) { linphone_config_set_int(lc->config, "sip", "capability_negotiations_reinvite", (int)enable); } bool_t linphone_core_capability_negociation_enabled(const LinphoneCore *lc) { return (bool_t) !!linphone_config_get_int(lc->config, "sip", "support_capability_negotiations", 0); } void linphone_core_enable_capability_negociation(LinphoneCore *lc, bool_t enable) { linphone_config_set_int(lc->config, "sip", "support_capability_negotiations", (int)enable); } LinphoneSupportLevel linphone_core_get_tag_100rel_support_level(const LinphoneCore *lc) { return (LinphoneSupportLevel)linphone_config_get_int(lc->config, "sip", "100rel_support_level", LinphoneSupportLevelNoSupport); } void linphone_core_set_tag_100rel_support_level(LinphoneCore *lc, LinphoneSupportLevel level) { linphone_config_set_int(lc->config, "sip", "100rel_support_level", (int)level); if (level == LinphoneSupportLevelNoSupport) { linphone_core_remove_supported_tag(lc, "100rel"); } else { linphone_core_add_supported_tag(lc, "100rel"); } } bool_t linphone_core_cfg_lines_merging_enabled(const LinphoneCore *lc) { bool_t capability_negotiation_supported = linphone_core_capability_negociation_enabled(lc); if (capability_negotiation_supported) { return (bool_t) !!linphone_config_get_int(lc->config, "sip", "cfg_lines_merge", 1); } return FALSE; } void linphone_core_enable_cfg_lines_merging(LinphoneCore *lc, bool_t enable) { linphone_config_set_int(lc->config, "sip", "cfg_lines_merge", (int)enable); } bool_t linphone_core_tcap_lines_merging_enabled(const LinphoneCore *lc) { bool_t capability_negotiation_supported = linphone_core_capability_negociation_enabled(lc); if (capability_negotiation_supported) { return (bool_t) !!linphone_config_get_int(lc->config, "sip", "tcap_line_merge", 0); } return FALSE; } void linphone_core_enable_tcap_line_merging(LinphoneCore *lc, bool_t enable) { linphone_config_set_int(lc->config, "sip", "tcap_line_merge", (int)enable); } void linphone_core_set_supported_media_encryptions(LinphoneCore *lc, const bctbx_list_t *encs) { bctbx_list_t *enc_list = NULL; for (const bctbx_list_t *enc = encs; enc != NULL; enc = enc->next) { int enc_enum = LINPHONE_PTR_TO_INT(bctbx_list_get_data(enc)); const char *enc_string = linphone_media_encryption_to_string(static_cast<LinphoneMediaEncryption>(enc_enum)); enc_list = bctbx_list_append(enc_list, ms_strdup(enc_string)); } linphone_config_set_string_list(lc->config, "sip", "supported_encryptions", enc_list); if (enc_list) {
8751875287538754875587568757875887598760876187628763876487658766876787688769877087718772877387748775877687778778877987808781878287838784878587868787878887898790879187928793879487958796879787988799880088018802880388048805880688078808880988108811881288138814881588168817881888198820
bctbx_list_free_with_data(enc_list, (bctbx_list_free_func)bctbx_free); } } bctbx_list_t *linphone_core_get_supported_media_encryptions_at_compile_time() { bctbx_list_t *encryption_list = NULL; if (ms_srtp_supported()) { encryption_list = bctbx_list_append(encryption_list, LINPHONE_INT_TO_PTR(LinphoneMediaEncryptionSRTP)); } if (ms_dtls_srtp_available()) { encryption_list = bctbx_list_append(encryption_list, LINPHONE_INT_TO_PTR(LinphoneMediaEncryptionDTLS)); } if (ms_zrtp_available()) { encryption_list = bctbx_list_append(encryption_list, LINPHONE_INT_TO_PTR(LinphoneMediaEncryptionZRTP)); } encryption_list = bctbx_list_append(encryption_list, LINPHONE_INT_TO_PTR(LinphoneMediaEncryptionNone)); return encryption_list; } const bctbx_list_t *linphone_core_get_supported_media_encryptions(LinphoneCore *lc) { bctbx_list_t *supported_encryptions = linphone_config_get_string_list(lc->config, "sip", "supported_encryptions", NULL); if (lc->supported_encryptions) { bctbx_list_free(lc->supported_encryptions); lc->supported_encryptions = NULL; } // If capability negotiation is not enabled or user didn't specify the list of supported encryption, then it is // assumed that all encryptions that were enabled at compile time are supported if (supported_encryptions == NULL) { bctbx_list_t *default_encryption_list = linphone_core_get_supported_media_encryptions_at_compile_time(); if (lc->zrtp_not_available_simulation) { bctbx_list_t *zrtp_encryption = bctbx_list_find(default_encryption_list, LINPHONE_INT_TO_PTR(LinphoneMediaEncryptionZRTP)); if (zrtp_encryption) { default_encryption_list = bctbx_list_unlink(default_encryption_list, zrtp_encryption); bctbx_list_free(zrtp_encryption); } } if (default_encryption_list) { lc->supported_encryptions = bctbx_list_copy(default_encryption_list); bctbx_list_free(default_encryption_list); } } else { for (bctbx_list_t *enc = supported_encryptions; enc != NULL; enc = enc->next) { const char *enc_string = static_cast<const char *>(bctbx_list_get_data(enc)); int enc_enum = linphone_media_encryption_from_string(enc_string); lc->supported_encryptions = bctbx_list_append(lc->supported_encryptions, LINPHONE_INT_TO_PTR(enc_enum)); } } if (supported_encryptions) { bctbx_list_free_with_data(supported_encryptions, (bctbx_list_free_func)bctbx_free); } return lc->supported_encryptions; } bool_t linphone_core_is_media_encryption_supported(LinphoneCore *lc, LinphoneMediaEncryption menc) { const bctbx_list_t *encryption_list = linphone_core_get_supported_media_encryptions(lc); bctbx_list_t *enc = bctbx_list_find((bctbx_list_t *)encryption_list, LINPHONE_INT_TO_PTR(menc)); bool supported = (enc != NULL); return supported; } void linphone_core_init_default_params(LinphoneCore *lc, LinphoneCallParams *params) { L_GET_CPP_PTR_FROM_C_OBJECT(params)->initDefault(L_GET_CPP_PTR_FROM_C_OBJECT(lc), LinphoneCallOutgoing);
8821882288238824882588268827882888298830883188328833883488358836883788388839884088418842884388448845884688478848884988508851885288538854885588568857885888598860886188628863886488658866886788688869887088718872887388748875887688778878887988808881888288838884888588868887888888898890
} void linphone_core_set_device_identifier(LinphoneCore *lc, const char *device_id) { if (lc->device_id) ms_free(lc->device_id); lc->device_id = ms_strdup(device_id); } const char *linphone_core_get_device_identifier(const LinphoneCore *lc) { return lc->device_id; } void linphone_core_set_sip_dscp(LinphoneCore *lc, int dscp) { lc->sal->setDscp(dscp); if (linphone_core_ready(lc)) { linphone_config_set_int_hex(lc->config, "sip", "dscp", dscp); _linphone_core_apply_transports(lc); } } int linphone_core_get_sip_dscp(const LinphoneCore *lc) { return linphone_config_get_int(lc->config, "sip", "dscp", 0x1a); } void linphone_core_set_audio_dscp(LinphoneCore *lc, int dscp) { if (linphone_core_ready(lc)) linphone_config_set_int_hex(lc->config, "rtp", "audio_dscp", dscp); } int linphone_core_get_audio_dscp(const LinphoneCore *lc) { return linphone_config_get_int(lc->config, "rtp", "audio_dscp", 0x2e); } void linphone_core_set_video_dscp(LinphoneCore *lc, int dscp) { if (linphone_core_ready(lc)) linphone_config_set_int_hex(lc->config, "rtp", "video_dscp", dscp); } int linphone_core_get_video_dscp(const LinphoneCore *lc) { return linphone_config_get_int(lc->config, "rtp", "video_dscp", 0); } void linphone_core_set_chat_database_path(LinphoneCore *lc, const char *path) { CoreLogContextualizer logContextualizer(lc); if (!linphone_core_conference_server_enabled(lc)) { auto &mainDb = L_GET_PRIVATE_FROM_C_OBJECT(lc)->mainDb; if (mainDb) { mainDb->import(LinphonePrivate::MainDb::Sqlite3, path); L_GET_PRIVATE_FROM_C_OBJECT(lc)->loadChatRooms(); } else { ms_warning("linphone_core_set_chat_database_path() needs to be called once linphone_core_start() has " "been called"); } } } const char *linphone_core_get_chat_database_path(const LinphoneCore *) { lError() << "Do not use `linphone_core_get_chat_database_path`. Not necessary."; return ""; } void linphone_core_enable_sdp_200_ack(LinphoneCore *lc, bool_t enable) { linphone_config_set_int(lc->config, "sip", "sdp_200_ack", lc->sip_conf.sdp_200_ack = enable); } LinphoneChatRoomEphemeralMode linphone_core_chat_room_get_default_ephemeral_mode(const LinphoneCore *lc) { return (LinphoneChatRoomEphemeralMode)linphone_config_get_int(lc->config, "misc", "chat_room_ephemeral_mode", LinphoneChatRoomEphemeralModeDeviceManaged); } void linphone_core_chat_room_set_default_ephemeral_mode(LinphoneCore *lc, LinphoneChatRoomEphemeralMode mode) { linphone_config_set_int(lc->config, "misc", "chat_room_ephemeral_mode", (int)mode); }
8891889288938894889588968897889888998900890189028903890489058906890789088909891089118912891389148915891689178918891989208921892289238924892589268927892889298930893189328933893489358936893789388939894089418942894389448945894689478948894989508951895289538954895589568957895889598960
long linphone_core_get_default_ephemeral_lifetime(const LinphoneCore *lc) { return (long)linphone_config_get_int(lc->config, "misc", "ephemeral_lifetime", 0); } void linphone_core_set_default_ephemeral_lifetime(LinphoneCore *lc, long value) { linphone_config_set_int64(lc->config, "misc", "ephemeral_lifetime", (int64_t)value); } LinphoneConferenceLayout linphone_core_get_default_conference_layout(const LinphoneCore *lc) { return (LinphoneConferenceLayout)linphone_config_get_int(lc->config, "misc", "conference_layout", LinphoneConferenceLayoutActiveSpeaker); } void linphone_core_set_default_conference_layout(LinphoneCore *lc, LinphoneConferenceLayout value) { linphone_config_set_int(lc->config, "misc", "conference_layout", (int)value); } bool_t linphone_core_sdp_200_ack_enabled(const LinphoneCore *lc) { return lc->sip_conf.sdp_200_ack != 0; } void linphone_core_set_enable_sip_update(const LinphoneCore *lc, int value) { lc->sal->enableSipUpdateMethod(value); } /** * RFC 4028 : Session Timers */ bool_t linphone_core_get_session_expires_enabled(const LinphoneCore *lc) { return linphone_core_session_expires_enabled(lc); } bool_t linphone_core_session_expires_enabled(const LinphoneCore *core) { return (bool_t)linphone_config_get_int(core->config, "sip", "session_expires_enabled", 0); } void linphone_core_set_session_expires_enabled(const LinphoneCore *lc, bool_t enabled) { linphone_core_enable_session_expires(lc, enabled); } void linphone_core_enable_session_expires(const LinphoneCore *core, bool_t enabled) { core->sal->setSessionTimersEnabled(enabled); linphone_config_set_int(core->config, "sip", "session_expires_enabled", (int)enabled); } int linphone_core_get_session_expires_value(const LinphoneCore *lc) { return linphone_config_get_int(lc->config, "sip", "session_expires_value", 0); } void linphone_core_set_session_expires_value(const LinphoneCore *lc, int expires) { lc->sal->setSessionTimersValue(expires); linphone_config_set_int(lc->config, "sip", "session_expires_value", expires); } LinphoneSessionExpiresRefresher linphone_core_get_session_expires_refresher_value(const LinphoneCore *lc) { return static_cast<LinphoneSessionExpiresRefresher>(linphone_config_get_int( lc->config, "sip", "session_expires_refresher_value", (int)LinphoneSessionExpiresRefresherUnspecified)); } void linphone_core_set_session_expires_refresher_value(const LinphoneCore *lc, LinphoneSessionExpiresRefresher refresher) { lc->sal->setSessionTimersRefresher(refresher); linphone_config_set_int(lc->config, "sip", "session_expires_refresher_value", (int)refresher); } int linphone_core_get_session_expires_min_value(const LinphoneCore *lc) { return linphone_config_get_int(lc->config, "sip", "session_expires_min_value", 0); }
8961896289638964896589668967896889698970897189728973897489758976897789788979898089818982898389848985898689878988898989908991899289938994899589968997899889999000900190029003900490059006900790089009901090119012901390149015901690179018901990209021902290239024902590269027902890299030
void linphone_core_set_session_expires_min_value(const LinphoneCore *lc, int min_se) { lc->sal->setSessionTimersMin(min_se); linphone_config_set_int(lc->config, "sip", "session_expires_min_value", min_se); } void linphone_core_set_file_transfer_server(LinphoneCore *core, const char *server_url) { linphone_config_set_string(core->config, "misc", "file_transfer_server_url", server_url); } const char *linphone_core_get_file_transfer_server(LinphoneCore *core) { return linphone_config_get_string(core->config, "misc", "file_transfer_server_url", NULL); } void linphone_core_set_supported_tag(LinphoneCore *lc, const char *tags) { lc->sal->setSupportedTags(tags); linphone_config_set_string(lc->config, "sip", "supported", tags); } void linphone_core_add_supported_tag(LinphoneCore *lc, const char *tag) { lc->sal->addSupportedTag(tag); linphone_config_set_string(lc->config, "sip", "supported", lc->sal->getSupportedTags().c_str()); } void linphone_core_remove_supported_tag(LinphoneCore *lc, const char *tag) { lc->sal->removeSupportedTag(tag); linphone_config_set_string(lc->config, "sip", "supported", lc->sal->getSupportedTags().c_str()); } void linphone_core_set_avpf_mode(LinphoneCore *lc, LinphoneAVPFMode mode) { if (mode == LinphoneAVPFDefault) mode = LinphoneAVPFDisabled; lc->rtp_conf.avpf_mode = mode; if (linphone_core_ready(lc)) linphone_config_set_int(lc->config, "rtp", "avpf", mode); } LinphoneAVPFMode linphone_core_get_avpf_mode(const LinphoneCore *lc) { return lc->rtp_conf.avpf_mode; } int linphone_core_get_avpf_rr_interval(const LinphoneCore *lc) { return linphone_config_get_int(lc->config, "rtp", "avpf_rr_interval", 5); } void linphone_core_set_avpf_rr_interval(LinphoneCore *lc, int interval) { linphone_config_set_int(lc->config, "rtp", "avpf_rr_interval", interval); } LinphoneStatus linphone_core_set_audio_multicast_addr(LinphoneCore *lc, const char *ip) { CoreLogContextualizer logContextualizer(lc); char *new_value; if (ip && !ms_is_multicast(ip)) { ms_error("Cannot set multicast audio addr to core [%p] because [%s] is not multicast", lc, ip); return -1; } new_value = ip ? ms_strdup(ip) : NULL; if (lc->rtp_conf.audio_multicast_addr) ms_free(lc->rtp_conf.audio_multicast_addr); linphone_config_set_string(lc->config, "rtp", "audio_multicast_addr", lc->rtp_conf.audio_multicast_addr = new_value); return 0; } LinphoneStatus linphone_core_set_video_multicast_addr(LinphoneCore *lc, const char *ip) { CoreLogContextualizer logContextualizer(lc); char *new_value; if (ip && !ms_is_multicast(ip)) { ms_error("Cannot set multicast video addr to core [%p] because [%s] is not multicast", lc, ip); return -1; } new_value = ip ? ms_strdup(ip) : NULL; if (lc->rtp_conf.video_multicast_addr) ms_free(lc->rtp_conf.video_multicast_addr); linphone_config_set_string(lc->config, "rtp", "video_multicast_addr",
9031903290339034903590369037903890399040904190429043904490459046904790489049905090519052905390549055905690579058905990609061906290639064906590669067906890699070907190729073907490759076907790789079908090819082908390849085908690879088908990909091909290939094909590969097909890999100
lc->rtp_conf.video_multicast_addr = new_value); return 0; } const char *linphone_core_get_audio_multicast_addr(const LinphoneCore *lc) { return lc->rtp_conf.audio_multicast_addr; } const char *linphone_core_get_video_multicast_addr(const LinphoneCore *lc) { return lc->rtp_conf.video_multicast_addr; } LinphoneStatus linphone_core_set_audio_multicast_ttl(LinphoneCore *lc, int ttl) { if (ttl > 255) { ms_error("Cannot set multicast audio ttl to core [%p] to [%i] value must be <256", lc, ttl); return -1; } linphone_config_set_int(lc->config, "rtp", "audio_multicast_ttl", lc->rtp_conf.audio_multicast_ttl = ttl); return 0; } LinphoneStatus linphone_core_set_video_multicast_ttl(LinphoneCore *lc, int ttl) { if (ttl > 255) { ms_error("Cannot set multicast video ttl to core [%p] to [%i] value must be <256", lc, ttl); return -1; } linphone_config_set_int(lc->config, "rtp", "video_multicast_ttl", lc->rtp_conf.video_multicast_ttl = ttl); return 0; } int linphone_core_get_audio_multicast_ttl(const LinphoneCore *lc) { return lc->rtp_conf.audio_multicast_ttl; } int linphone_core_get_video_multicast_ttl(const LinphoneCore *lc) { return lc->rtp_conf.video_multicast_ttl; } void linphone_core_enable_audio_multicast(LinphoneCore *lc, bool_t yesno) { linphone_config_set_int(lc->config, "rtp", "audio_multicast_enabled", lc->rtp_conf.audio_multicast_enabled = yesno); } bool_t linphone_core_audio_multicast_enabled(const LinphoneCore *lc) { return lc->rtp_conf.audio_multicast_enabled; } void linphone_core_enable_video_multicast(LinphoneCore *lc, bool_t yesno) { linphone_config_set_int(lc->config, "rtp", "video_multicast_enabled", lc->rtp_conf.video_multicast_enabled = yesno); } bool_t linphone_core_video_multicast_enabled(const LinphoneCore *lc) { return lc->rtp_conf.video_multicast_enabled; } void linphone_core_enable_call_tone_indications(const LinphoneCore *lc, bool_t yesno) { linphone_config_set_int(linphone_core_get_config(lc), "misc", "tone_indications", yesno); } bool_t linphone_core_call_tone_indications_enabled(const LinphoneCore *lc) { return !!linphone_config_get_int(linphone_core_get_config(lc), "misc", "tone_indications", TRUE); } bool_t linphone_core_rtp_bundle_enabled(const LinphoneCore *lc) { return linphone_config_get_bool(lc->config, "rtp", "bundle", FALSE); } void linphone_core_enable_rtp_bundle(LinphoneCore *lc, bool_t value) { linphone_config_set_bool(lc->config, "rtp", "bundle", value);
9101910291039104910591069107910891099110911191129113911491159116911791189119912091219122912391249125912691279128912991309131913291339134913591369137913891399140914191429143914491459146914791489149915091519152915391549155915691579158915991609161916291639164916591669167916891699170
} void linphone_core_set_video_preset(LinphoneCore *lc, const char *preset) { linphone_config_set_string(lc->config, "video", "preset", preset); } const char *linphone_core_get_video_preset(const LinphoneCore *lc) { return linphone_config_get_string(lc->config, "video", "preset", NULL); } LINPHONE_PUBLIC const char * linphone_core_log_collection_upload_state_to_string(const LinphoneCoreLogCollectionUploadState lcus) { switch (lcus) { case LinphoneCoreLogCollectionUploadStateInProgress: return "LinphoneCoreLogCollectionUploadStateInProgress"; case LinphoneCoreLogCollectionUploadStateDelivered: return "LinphoneCoreLogCollectionUploadStateDelivered"; case LinphoneCoreLogCollectionUploadStateNotDelivered: return "LinphoneCoreLogCollectionUploadStateNotDelivered"; } return "UNKNOWN"; } bool_t linphone_core_realtime_text_enabled(LinphoneCore *lc) { return lc->text_conf.enabled; } void linphone_core_enable_realtime_text(LinphoneCore *lc, bool_t value) { lc->text_conf.enabled = value; } unsigned int linphone_core_realtime_text_get_keepalive_interval(const LinphoneCore *lc) { return lc->text_conf.keepalive_interval; } void linphone_core_realtime_text_set_keepalive_interval(LinphoneCore *lc, unsigned int interval) { lc->text_conf.keepalive_interval = interval; } void linphone_core_set_http_proxy_host(LinphoneCore *lc, const char *host) { CoreLogContextualizer logContextualizer(lc); linphone_config_set_string(lc->config, "sip", "http_proxy_host", host); if (lc->sal) { lc->sal->setHttpProxyHost(host); lc->sal->setHttpProxyPort(linphone_core_get_http_proxy_port(lc)); /*to make sure default value is set*/ } if (lc->tunnel) { linphone_tunnel_set_http_proxy(lc->tunnel, host, linphone_core_get_http_proxy_port(lc), NULL, NULL); } } void linphone_core_set_http_proxy_port(LinphoneCore *lc, int port) { CoreLogContextualizer logContextualizer(lc); linphone_config_set_int(lc->config, "sip", "http_proxy_port", port); if (lc->sal) lc->sal->setHttpProxyPort(port); if (lc->tunnel) { linphone_tunnel_set_http_proxy(lc->tunnel, linphone_core_get_http_proxy_host(lc), port, NULL, NULL); } } bool_t linphone_core_automatic_http_proxy_detection_enabled(const LinphoneCore *lc) { return linphone_config_get_bool(lc->config, "sip", "automatic_http_proxy_detection", FALSE); } void linphone_core_enable_automatic_http_proxy_detection(LinphoneCore *lc, bool_t enable) { linphone_config_set_bool(lc->config, "sip", "automatic_http_proxy_detection", enable); } const char *linphone_core_get_http_proxy_host(const LinphoneCore *lc) { return linphone_config_get_string(lc->config, "sip", "http_proxy_host", NULL);
9171917291739174917591769177917891799180918191829183918491859186918791889189919091919192919391949195919691979198919992009201920292039204920592069207920892099210921192129213921492159216921792189219922092219222922392249225922692279228922992309231923292339234923592369237923892399240
} int linphone_core_get_http_proxy_port(const LinphoneCore *lc) { return linphone_config_get_int(lc->config, "sip", "http_proxy_port", 3128); } const char *linphone_transport_to_string(LinphoneTransportType transport) { return sal_transport_to_string((SalTransport)transport); } LinphoneTransportType linphone_transport_parse(const char *transport) { return (LinphoneTransportType)sal_transport_parse(transport); } const char *linphone_stream_type_to_string(const LinphoneStreamType type) { switch (type) { case LinphoneStreamTypeAudio: return "LinphoneStreamTypeAudio"; case LinphoneStreamTypeVideo: return "LinphoneStreamTypeVideo"; case LinphoneStreamTypeText: return "LinphoneStreamTypeText"; case LinphoneStreamTypeUnknown: return "LinphoneStreamTypeUnknown"; } return "INVALID"; } LinphoneRingtonePlayer *linphone_core_get_ringtoneplayer(LinphoneCore *lc) { return lc->ringtoneplayer; } static int _linphone_core_delayed_conference_destruction_cb(void *user_data, BCTBX_UNUSED(unsigned int event)) { LinphoneConference *conf = (LinphoneConference *)user_data; linphone_conference_unref(conf); return 0; } static void _linphone_core_conference_state_changed(LinphoneConference *conf, LinphoneConferenceState cstate, void *user_data) { LinphoneCore *lc = (LinphoneCore *)user_data; if (cstate == LinphoneConferenceStateCreationFailed || cstate == LinphoneConferenceStateDeleted) { linphone_core_queue_task(lc, _linphone_core_delayed_conference_destruction_cb, conf, "Conference destruction task"); lc->conf_ctx = NULL; } } /*This function sets the "unique" conference object for the LinphoneCore - which is necessary as long as * liblinphone is used in a client app. When liblinphone will be used in a server app, this shall not be done * anymore.*/ static void linphone_core_set_conference(LinphoneCore *lc, LinphoneConference *conf) { lc->conf_ctx = linphone_conference_ref(conf); } LinphoneConference *linphone_core_create_conference_with_params(LinphoneCore *lc, const LinphoneConferenceParams *params) { CoreLogContextualizer logContextualizer(lc); const char *conf_method_name; LinphoneConference *conf = nullptr; bool serverMode = params && !linphone_conference_params_local_participant_enabled(params); /* In server mode, it is allowed to create multiple conferences. */ if (lc->conf_ctx == NULL || serverMode) { bool errorOnRemoteConference = false; // Get factory and identity from linphone conference params, or from default account. const LinphoneAddress *factory_uri_const = linphone_conference_params_get_conference_factory_address(params); LinphoneAddress *identity; LinphoneConferenceParams *params2 = linphone_conference_params_clone(params); conf_method_name = linphone_config_get_string(lc->config, "misc", "conference_type", NULL);
9241924292439244924592469247924892499250925192529253925492559256925792589259926092619262926392649265926692679268926992709271927292739274927592769277927892799280928192829283928492859286928792889289929092919292929392949295929692979298929993009301930293039304930593069307930893099310
// Get identity if (conf_method_name) { identity = linphone_address_new(linphone_core_get_identity( lc)); // backward compatibility : use default identity even if set in conference parameters } else { const std::shared_ptr<LinphonePrivate::Address> &identity_address = LinphonePrivate::ConferenceParams::toCpp(params)->getMe(); if (identity_address && identity_address->isValid()) { lInfo() << "Creating remote conference with identity from conference params : " << identity_address; identity = linphone_address_clone(identity_address->toC()); } else { identity = linphone_address_new(linphone_core_get_identity(lc)); lInfo() << "Creating remote conference with identity from default account " << LinphonePrivate::Address::toCpp(identity)->toString(); } } // Create a local conference if: // - it is a conference server // - conference type is not defined and conference factory address is not defined // - conference type is local if (linphone_core_conference_server_enabled(lc) || (!conf_method_name && !linphone_address_is_valid(factory_uri_const)) || (conf_method_name && strcasecmp(conf_method_name, "local") == 0)) { conf = linphone_local_conference_new_with_params(lc, identity, params2); } else if (!serverMode) { // Get Factory URI LinphoneAddress *factory_uri = nullptr; if (conf_method_name) { // Priority for conf method. if (strcasecmp(conf_method_name, "remote") == 0) { LinphoneAccount *account = linphone_core_get_default_account(lc); if (account) { const char *uri = linphone_account_params_get_conference_factory_uri( linphone_account_get_params(linphone_core_get_default_account(lc))); factory_uri = linphone_address_new(uri); char *factory_uri_str = factory_uri ? linphone_address_as_string(factory_uri) : NULL; lInfo() << "Creating remote conference with factory address from default account : " << std::string(factory_uri_str); ms_free(factory_uri_str); } else { ms_error("Cannot create a remote conference from default account : no account available"); errorOnRemoteConference = true; } } else { ms_error("Creating remote conference : '%s' is not a valid conference method", conf_method_name); errorOnRemoteConference = true; } } else { // case of: !conf_method_name && factory_uri_str != "" factory_uri = linphone_address_clone(factory_uri_const); char *factory_uri_str = factory_uri ? linphone_address_as_string(factory_uri) : NULL; lInfo() << "Creating remote conference with factory address from conference params : " << std::string(factory_uri_str); ms_free(factory_uri_str); } if (!errorOnRemoteConference) { conf = linphone_remote_conference_new_with_params(lc, factory_uri, identity, params2); linphone_address_unref(factory_uri); } } else { ms_error("Conference method '%s' or parameter factory URI '%s' are not valid for a local conference mode", conf_method_name, factory_uri_const ? linphone_address_as_string(factory_uri_const) : "NULL"); errorOnRemoteConference = true; } linphone_conference_params_unref(params2); linphone_address_unref(identity); if (errorOnRemoteConference) return NULL; if (!serverMode) { linphone_core_set_conference(lc, conf); linphone_conference_set_state_changed_callback(conf, _linphone_core_conference_state_changed, lc);
9311931293139314931593169317931893199320932193229323932493259326932793289329933093319332933393349335933693379338933993409341934293439344934593469347934893499350935193529353935493559356935793589359936093619362936393649365936693679368936993709371937293739374937593769377937893799380
} } else { ms_error("Could not create a conference: a conference instance already exists"); return NULL; } return conf; } LinphoneConferenceScheduler *linphone_core_create_conference_scheduler(LinphoneCore *core) { CoreLogContextualizer logContextualizer(core); return LinphonePrivate::ConferenceScheduler::createCObject(L_GET_CPP_PTR_FROM_C_OBJECT(core)); } LinphoneConference *linphone_core_search_conference(const LinphoneCore *lc, const LinphoneConferenceParams *params, const LinphoneAddress *localAddr, const LinphoneAddress *remoteAddr, const bctbx_list_t *participants) { CoreLogContextualizer logContextualizer(lc); shared_ptr<LinphonePrivate::ConferenceParams> conferenceParams = params ? LinphonePrivate::ConferenceParams::toCpp(params)->clone()->toSharedPtr() : nullptr; list<std::shared_ptr<LinphonePrivate::Address>> participantsList; if (participants) { participantsList = LinphonePrivate::Utils::bctbxListToCppSharedPtrList<LinphoneAddress, LinphonePrivate::Address>( participants); } shared_ptr<const LinphonePrivate::Address> identityAddress = localAddr ? LinphonePrivate::Address::toCpp(localAddr)->getSharedFromThis() : L_GET_PRIVATE_FROM_C_OBJECT(lc)->getDefaultLocalAddress(nullptr, false); shared_ptr<const LinphonePrivate::Address> remoteAddress = remoteAddr ? LinphonePrivate::Address::toCpp(remoteAddr)->getSharedFromThis() : nullptr; shared_ptr<LinphonePrivate::MediaConference::Conference> conf = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->searchAudioVideoConference(conferenceParams, identityAddress, remoteAddress, participantsList); LinphoneConference *c_conference = NULL; if (conf) { c_conference = conf->toC(); } return c_conference; } LinphoneConference *linphone_core_search_conference_2(const LinphoneCore *lc, const LinphoneAddress *conferenceAddr) { CoreLogContextualizer logContextualizer(lc); const auto conferenceAddress = conferenceAddr ? LinphonePrivate::Address::toCpp(const_cast<LinphoneAddress *>(conferenceAddr))->getSharedFromThis() : nullptr; shared_ptr<LinphonePrivate::MediaConference::Conference> conf = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->searchAudioVideoConference(conferenceAddress); LinphoneConference *c_conference = NULL; if (conf) { c_conference = conf->toC(); } return c_conference; } LinphoneConferenceParams *linphone_core_create_conference_params_2(LinphoneCore *lc, LinphoneConference *conference) { CoreLogContextualizer logContextualizer(lc); if (!conference) return linphone_conference_params_new(lc); if (linphone_conference_get_current_params(conference)) { return linphone_conference_params_clone(linphone_conference_get_current_params(conference)); } ms_error("linphone_core_create_conference_params(): conference [%p] is not in a state where conference params can " "be created or used.", conference); return NULL; } LinphoneConferenceParams *linphone_core_create_conference_params(LinphoneCore *lc) {
9381938293839384938593869387938893899390939193929393939493959396939793989399940094019402940394049405940694079408940994109411941294139414941594169417941894199420942194229423942494259426942794289429943094319432943394349435943694379438943994409441944294439444944594469447944894499450
return linphone_core_create_conference_params_2(lc, NULL); } LinphoneStatus linphone_core_add_to_conference(LinphoneCore *lc, LinphoneCall *call) { CoreLogContextualizer logContextualizer(lc); LinphoneConference *conference = linphone_core_get_conference(lc); if (conference == NULL) { LinphoneConferenceParams *params = linphone_conference_params_new(lc); if (call) { const LinphoneCallParams *remote_call_params = linphone_call_get_remote_params(call); auto account = Call::toCpp(call)->getDestAccount(); LinphonePrivate::ConferenceParams::toCpp(params)->setAccount(account); if (remote_call_params) { linphone_conference_params_set_audio_enabled(params, linphone_call_params_audio_enabled(remote_call_params)); linphone_conference_params_set_video_enabled(params, linphone_call_params_video_enabled(remote_call_params)); linphone_conference_params_set_chat_enabled( params, linphone_call_params_realtime_text_enabled(remote_call_params)); } } conference = linphone_core_create_conference_with_params(lc, params); linphone_conference_params_unref(params); linphone_conference_unref( conference); /*actually linphone_core_create_conference_with_params() takes a ref for lc->conf_ctx */ } if (conference) return linphone_conference_add_participant(conference, call); else return -1; } LinphoneStatus linphone_core_add_all_to_conference(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); for (const auto &call : L_GET_CPP_PTR_FROM_C_OBJECT(lc)->getCalls()) { if (!linphone_call_get_conference( call->toC())) // Prevent the call to the conference server from being added to the conference linphone_core_add_to_conference(lc, call->toC()); } if (lc->conf_ctx && linphone_conference_check_class(lc->conf_ctx, LinphoneConferenceClassLocal)) { linphone_core_enter_conference(lc); } return 0; } LinphoneStatus linphone_core_remove_from_conference(LinphoneCore *lc, LinphoneCall *call) { if (lc->conf_ctx) { const LinphoneAddress *uri = linphone_call_get_remote_address(call); LinphoneParticipant *participant = linphone_conference_find_participant(lc->conf_ctx, uri); return linphone_conference_remove_participant_2(lc->conf_ctx, participant); } else return -1; } int linphone_core_terminate_conference(LinphoneCore *lc) { CoreLogContextualizer logContextualizer(lc); if (lc->conf_ctx == NULL) { ms_error("Could not terminate conference: no conference context"); return -1; } linphone_conference_terminate(lc->conf_ctx); return 0; } LinphoneStatus linphone_core_enter_conference(LinphoneCore *lc) { if (lc->conf_ctx) return linphone_conference_enter(lc->conf_ctx); else return -1; } LinphoneStatus linphone_core_leave_conference(LinphoneCore *lc) { if (lc->conf_ctx) return linphone_conference_leave(lc->conf_ctx); else return -1; }
9451945294539454945594569457945894599460946194629463946494659466946794689469947094719472947394749475947694779478947994809481948294839484948594869487948894899490949194929493949494959496949794989499950095019502950395049505950695079508950995109511951295139514951595169517951895199520
bool_t linphone_core_is_in_conference(const LinphoneCore *lc) { if (lc->conf_ctx) return linphone_conference_is_in(lc->conf_ctx); else return FALSE; } int linphone_core_get_conference_size(LinphoneCore *lc) { if (lc->conf_ctx) return linphone_conference_get_participant_count(lc->conf_ctx) + (linphone_conference_is_in(lc->conf_ctx) ? 1 : 0); return 0; } float linphone_core_get_conference_local_input_volume(LinphoneCore *lc) { if (lc->conf_ctx) return linphone_conference_get_input_volume(lc->conf_ctx); else return -1.0; } LinphoneStatus linphone_core_start_conference_recording(LinphoneCore *lc, const char *path) { if (lc->conf_ctx) return linphone_conference_start_recording(lc->conf_ctx, path); return -1; } LinphoneStatus linphone_core_stop_conference_recording(LinphoneCore *lc) { if (lc->conf_ctx) return linphone_conference_stop_recording(lc->conf_ctx); return -1; } LinphoneConference *linphone_core_get_conference(LinphoneCore *lc) { return lc->conf_ctx; } void linphone_core_enable_conference_server(LinphoneCore *lc, bool_t enable) { linphone_config_set_int(linphone_core_get_config(lc), "misc", "conference_server_enabled", enable); } void linphone_core_enable_fec(LinphoneCore *lc, bool_t enable) { linphone_config_set_bool(linphone_core_get_config(lc), "fec", "fec_enabled", enable); } bool_t linphone_core_fec_enabled(const LinphoneCore *lc) { return linphone_config_get_bool(linphone_core_get_config(lc), "fec", "fec_enabled", FALSE) ? TRUE : FALSE; } void linphone_core_enable_alerts(LinphoneCore *lc, bool_t enable) { linphone_config_set_bool(linphone_core_get_config(lc), "alerts", "alerts_enabled", enable); } bool_t linphone_core_alerts_enabled(const LinphoneCore *lc) { return linphone_config_get_bool(linphone_core_get_config(lc), "alerts", "alerts_enabled", FALSE) ? TRUE : FALSE; } bool_t _linphone_core_is_conference_creation(const LinphoneCore *lc, const LinphoneAddress *addr) { const bctbx_list_t *elem; LinphoneAddress *testedAddr = linphone_address_clone(addr); bool_t result = FALSE; if (!testedAddr) return FALSE; linphone_address_set_port(testedAddr, 0); for (elem = linphone_core_get_proxy_config_list(lc); elem != NULL; elem = elem->next) { LinphoneProxyConfig *proxy = (LinphoneProxyConfig *)elem->data; const char *uri = linphone_proxy_config_get_conference_factory_uri(proxy); if (!uri) continue; LinphoneAddress *factoryAddr = linphone_address_new(uri); if (!factoryAddr) continue; // Do not compare ports linphone_address_set_port(factoryAddr, 0); result = linphone_address_weak_equal(factoryAddr, testedAddr); linphone_address_unref(factoryAddr);
9521952295239524952595269527952895299530953195329533953495359536953795389539954095419542954395449545954695479548954995509551955295539554955595569557955895599560956195629563956495659566956795689569957095719572957395749575957695779578957995809581958295839584958595869587958895899590
if (result) break; /* if they match*/ } linphone_address_unref(testedAddr); return result; } bool_t linphone_core_conference_server_enabled(const LinphoneCore *lc) { return linphone_config_get_int(linphone_core_get_config(lc), "misc", "conference_server_enabled", FALSE) ? TRUE : FALSE; } void linphone_core_set_conference_participant_list_type(LinphoneCore *lc, LinphoneConferenceParticipantListType type) { linphone_config_set_int(linphone_core_get_config(lc), "misc", "conference_participant_list_type", (int)type); } LinphoneConferenceParticipantListType linphone_core_get_conference_participant_list_type(const LinphoneCore *lc) { return (LinphoneConferenceParticipantListType)linphone_config_get_int( linphone_core_get_config(lc), "misc", "conference_participant_list_type", (int)LinphoneConferenceParticipantListTypeOpen); } void linphone_core_set_tls_cert(LinphoneCore *lc, const char *tls_cert) { if (lc->tls_cert) { ms_free(lc->tls_cert); lc->tls_cert = NULL; } if (tls_cert && strlen(tls_cert) > 0) lc->tls_cert = ms_strdup(tls_cert); } void linphone_core_set_tls_key(LinphoneCore *lc, const char *tls_key) { if (lc->tls_key) { ms_free(lc->tls_key); lc->tls_key = NULL; } if (tls_key && strlen(tls_key) > 0) lc->tls_key = ms_strdup(tls_key); } void linphone_core_set_tls_cert_path(LinphoneCore *lc, const char *tls_cert_path) { linphone_config_set_string(lc->config, "sip", "client_cert_chain", tls_cert_path); } void linphone_core_set_tls_key_path(LinphoneCore *lc, const char *tls_key_path) { linphone_config_set_string(lc->config, "sip", "client_cert_key", tls_key_path); } const char *linphone_core_get_tls_cert(const LinphoneCore *lc) { return lc->tls_cert; } const char *linphone_core_get_tls_key(const LinphoneCore *lc) { return lc->tls_key; } const char *linphone_core_get_tls_cert_path(const LinphoneCore *lc) { const char *tls_cert_path = linphone_config_get_string(lc->config, "sip", "client_cert_chain", NULL); return tls_cert_path; } const char *linphone_core_get_tls_key_path(const LinphoneCore *lc) { const char *tls_key_path = linphone_config_get_string(lc->config, "sip", "client_cert_key", NULL); return tls_key_path; } LinphoneImEncryptionEngine *linphone_core_get_im_encryption_engine(const LinphoneCore *lc) { return lc->im_encryption_engine; } void linphone_core_initialize_supported_content_types(LinphoneCore *lc) { lc->sal->addContentTypeSupport("text/plain"); lc->sal->addContentTypeSupport("message/external-body");
9591959295939594959595969597959895999600960196029603960496059606960796089609961096119612961396149615961696179618961996209621962296239624962596269627962896299630963196329633963496359636963796389639964096419642964396449645964696479648964996509651965296539654965596569657965896599660
lc->sal->addContentTypeSupport("application/vnd.gsma.rcs-ft-http+xml"); lc->sal->addContentTypeSupport("application/im-iscomposing+xml"); lc->sal->addContentTypeSupport("message/imdn+xml"); lc->sal->addContentTypeSupport("text/calendar"); } bool_t linphone_core_is_content_type_supported(const LinphoneCore *lc, const char *content_type) { return lc->sal->isContentTypeSupported(content_type); } void linphone_core_add_content_type_support(LinphoneCore *lc, const char *content_type) { lc->sal->addContentTypeSupport(content_type); } void linphone_core_remove_content_type_support(LinphoneCore *lc, const char *content_type) { lc->sal->removeContentTypeSupport(content_type); } int linphone_core_get_unread_chat_message_count(const LinphoneCore *lc) { return L_GET_CPP_PTR_FROM_C_OBJECT(lc)->getUnreadChatMessageCount(); } int linphone_core_get_unread_chat_message_count_from_local(const LinphoneCore *lc, const LinphoneAddress *address) { const auto addr = LinphonePrivate::Address::toCpp(const_cast<LinphoneAddress *>(address))->getSharedFromThis(); return L_GET_CPP_PTR_FROM_C_OBJECT(lc)->getUnreadChatMessageCount(addr); } int linphone_core_get_unread_chat_message_count_from_active_locals(const LinphoneCore *lc) { return L_GET_CPP_PTR_FROM_C_OBJECT(lc)->getUnreadChatMessageCountFromActiveLocals(); } bool_t linphone_core_has_crappy_opengl(LinphoneCore *lc) { MSFactory *factory = linphone_core_get_ms_factory(lc); MSDevicesInfo *devices = ms_factory_get_devices_info(factory); SoundDeviceDescription *sound_description = ms_devices_info_get_sound_device_description(devices); if (sound_description == NULL) return FALSE; if (sound_description->flags & DEVICE_HAS_CRAPPY_OPENGL) return TRUE; return FALSE; } void linphone_core_set_srtp_crypto_suites(LinphoneCore *core, const char *suites) { linphone_config_set_string(core->config, "sip", "srtp_crypto_suites", suites); } const char *linphone_core_get_srtp_crypto_suites(LinphoneCore *core) { return linphone_config_get_string(core->config, "sip", "srtp_crypto_suites", "AES_CM_128_HMAC_SHA1_80, AES_CM_128_HMAC_SHA1_32, AES_256_CM_HMAC_SHA1_80, " "AES_256_CM_HMAC_SHA1_32, AEAD_AES_128_GCM, AEAD_AES_256_GCM"); } #ifndef _MSC_VER #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif // _MSC_VER LinphoneConferenceInfo *linphone_core_find_conference_information_from_uri(LinphoneCore *core, LinphoneAddress *uri) { CoreLogContextualizer logContextualizer(core); #ifdef HAVE_DB_STORAGE auto &mainDb = L_GET_PRIVATE_FROM_C_OBJECT(core)->mainDb; const auto uri_addr = uri ? LinphonePrivate::Address::toCpp(uri)->getSharedFromThis() : nullptr; auto confInfo = mainDb->getConferenceInfoFromURI(uri_addr); if (confInfo != nullptr) { // Clone the conference information so that the application can freely change it without modifying the // object stored in the cached of the DB return linphone_conference_info_clone(confInfo->toC()); } return NULL; #else return NULL;
9661966296639664966596669667966896699670967196729673967496759676967796789679968096819682968396849685968696879688968996909691969296939694969596969697969896999700970197029703970497059706970797089709971097119712971397149715971697179718971997209721972297239724972597269727972897299730
#endif } #ifndef _MSC_VER #pragma GCC diagnostic pop #endif // _MSC_VER #ifndef _MSC_VER #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wunused-parameter" #endif // _MSC_VER static bctbx_list_t *get_conference_information_list(LinphoneCore *core, time_t t) { #ifdef HAVE_DB_STORAGE auto &mainDb = L_GET_PRIVATE_FROM_C_OBJECT(core)->mainDb; auto list = mainDb->getConferenceInfos(t); bctbx_list_t *results = NULL; for (auto &conf : list) { results = bctbx_list_append(results, linphone_conference_info_ref(conf->toC())); } return results; #else return NULL; #endif } #ifndef _MSC_VER #pragma GCC diagnostic pop #endif // _MSC_VER bctbx_list_t *linphone_core_get_conference_information_list(LinphoneCore *core) { return get_conference_information_list(core, -1); } bctbx_list_t *linphone_core_get_future_conference_information_list(LinphoneCore *core) { return get_conference_information_list(core, ms_time(NULL)); } bctbx_list_t *linphone_core_get_conference_information_list_after_time(LinphoneCore *core, time_t time) { return get_conference_information_list(core, time); } void linphone_core_delete_conference_information(LinphoneCore *core, LinphoneConferenceInfo *conference_info) { CoreLogContextualizer logContextualizer(core); #ifdef HAVE_DB_STORAGE auto &mainDb = L_GET_PRIVATE_FROM_C_OBJECT(core)->mainDb; mainDb->deleteConferenceInfo(LinphonePrivate::ConferenceInfo::toCpp(conference_info)->getSharedFromThis()); #endif } bool_t linphone_core_ldap_available(BCTBX_UNUSED(LinphoneCore *core)) { #ifdef LDAP_ENABLED return TRUE; #else return FALSE; #endif } LinphoneStatus linphone_core_config_sync(LinphoneCore *core) { CoreLogContextualizer logContextualizer(core); #if TARGET_OS_IPHONE auto helper = getPlatformHelpers(core)->getSharedCoreHelpers(); SharedCoreState state = helper->getSharedCoreState(); if (helper->isCoreShared() && state != SharedCoreState::mainCoreStarted && state != SharedCoreState::executorCoreStarted) { return -1; } #endif return linphone_config_sync(core->config); }
97319732973397349735973697379738973997409741974297439744974597469747974897499750975197529753975497559756975797589759976097619762976397649765976697679768976997709771977297739774977597769777977897799780978197829783978497859786978797889789979097919792
bool_t linphone_core_empty_chatrooms_deletion_enabled(const LinphoneCore *core) { return L_GET_CPP_PTR_FROM_C_OBJECT(core)->emptyChatroomsDeletionEnabled(); } void linphone_core_enable_empty_chatrooms_deletion(LinphoneCore *core, bool_t enable) { linphone_config_set_bool(core->config, "misc", "empty_chat_room_deletion", enable); L_GET_CPP_PTR_FROM_C_OBJECT(core)->enableEmptyChatroomsDeletion(enable); } LinphoneAccount *linphone_core_find_account_by_identity_address(const LinphoneCore *core, const LinphoneAddress *identity_address) { CoreLogContextualizer logContextualizer(core); LinphoneAccount *found = NULL; if (identity_address == NULL) return found; bctbx_list_t *account_it; for (account_it = (bctbx_list_t *)linphone_core_get_account_list(core); account_it != NULL; account_it = account_it->next) { LinphoneAccount *account = (LinphoneAccount *)(account_it->data); const LinphoneAccountParams *params = linphone_account_get_params(account); const LinphoneAddress *address = linphone_account_params_get_identity_address(params); if (linphone_address_weak_equal(address, identity_address)) { found = account; break; } } return found; } const bctbx_list_t *linphone_core_get_loaded_plugins(LinphoneCore *core) { if (core->plugin_list) { bctbx_list_free_with_data(core->plugin_list, (bctbx_list_free_func)bctbx_free); } core->plugin_list = NULL; const auto &plugins = L_GET_CPP_PTR_FROM_C_OBJECT(core)->getPluginList(); for (const auto &p : plugins) { core->plugin_list = bctbx_list_append(core->plugin_list, ms_strdup(L_STRING_TO_C(p))); } return core->plugin_list; } bool_t linphone_core_is_plugin_loaded(const LinphoneCore *core, const char *name) { return L_GET_CPP_PTR_FROM_C_OBJECT(core)->isPluginLoaded(L_C_TO_STRING(name)); } void linphone_core_set_register_only_when_network_is_up(LinphoneCore *core, bool_t register_only_when_network_is_up) { core->sip_conf.register_only_when_network_is_up = register_only_when_network_is_up; linphone_config_set_bool(core->config, "sip", "register_only_when_network_is_up", register_only_when_network_is_up); } bool_t linphone_core_get_register_only_when_network_is_up(const LinphoneCore *core) { return core->sip_conf.register_only_when_network_is_up; } void linphone_core_set_label(LinphoneCore *core, const char *label) { L_GET_CPP_PTR_FROM_C_OBJECT(core)->setLabel(L_C_TO_STRING(label)); } const char *linphone_core_get_label(const LinphoneCore *core) { return L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(core)->getLabel()); }