forked from mirrors/linphone-iphone
Merge remote-tracking branch 'public/dev_refactor_cpp' into dev_doc_generator
This commit is contained in:
commit
40ca8aca3f
223 changed files with 8460 additions and 3430 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
|
@ -106,3 +106,4 @@ tools/lp-test-ecc
|
|||
tools/lp-sendmsg
|
||||
|
||||
*.pyc
|
||||
liblinphone.spec
|
||||
|
|
|
|||
|
|
@ -68,6 +68,7 @@ cmake_dependent_option(ENABLE_NOTIFY "Enable libnotify support." YES "ENABLE_GTK
|
|||
cmake_dependent_option(ENABLE_ASSISTANT "Turn on assistant compiling." YES "ENABLE_GTK_UI" NO)
|
||||
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
set(CMAKE_CXX_EXTENSIONS NO)
|
||||
|
||||
if(NOT CMAKE_BUILD_TYPE)
|
||||
set(CMAKE_BUILD_TYPE "Release")
|
||||
|
|
@ -272,6 +273,7 @@ else()
|
|||
"-Wunused"
|
||||
)
|
||||
list(APPEND STRICT_OPTIONS_CXX
|
||||
"-Wnon-virtual-dtor"
|
||||
"-Woverloaded-virtual"
|
||||
)
|
||||
CHECK_CXX_COMPILER_FLAG("-Wsuggest-override" SUGGEST_OVERRIDE)
|
||||
|
|
|
|||
|
|
@ -1,6 +1,6 @@
|
|||
############################################################################
|
||||
# CMakeLists.txt
|
||||
# Copyright (C) 2017 Belledonne Communications, Grenoble France
|
||||
# Copyright (C) 2017-2018 Belledonne Communications, Grenoble France
|
||||
#
|
||||
############################################################################
|
||||
#
|
||||
|
|
@ -20,7 +20,7 @@
|
|||
#
|
||||
############################################################################
|
||||
|
||||
if (NOT CPACK_PACKAGE_NAME)
|
||||
if(NOT CPACK_PACKAGE_NAME)
|
||||
set(CPACK_PACKAGE_NAME "liblinphone")
|
||||
ENDIF()
|
||||
|
||||
|
|
@ -40,13 +40,14 @@ set(CPACK_SOURCE_IGNORE_FILES
|
|||
|
||||
bc_project_build_version(${PROJECT_VERSION} PROJECT_VERSION_BUILD)
|
||||
if(PROJECT_VERSION_BUILD)
|
||||
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-${PROJECT_VERSION_BUILD}")
|
||||
set(CPACK_PACKAGE_FILE_NAME "${CPACK_PACKAGE_FILE_NAME}-${PROJECT_VERSION_BUILD}")
|
||||
endif()
|
||||
|
||||
message("-- Package file name is ${CPACK_PACKAGE_FILE_NAME}" )
|
||||
|
||||
set(CPACK_SOURCE_PACKAGE_FILE_NAME ${CPACK_PACKAGE_FILE_NAME})
|
||||
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/rpm/liblinphone.spec.in ${CMAKE_CURRENT_SOURCE_DIR}/../liblinphone.spec)
|
||||
|
||||
bc_generate_rpm_specfile("rpm/liblinphone.spec.cmake" "${PROJECT_SOURCE_DIR}/liblinphone.spec")
|
||||
|
||||
include(CPack)
|
||||
|
||||
|
|
|
|||
|
|
@ -1,12 +1,7 @@
|
|||
# -*- rpm-spec -*-
|
||||
|
||||
## rpmbuild options
|
||||
# These 2 lines are here because we can build the RPM for flexisip, in which
|
||||
# case we prefix the entire installation so that we don't break compatibility
|
||||
# with the user's libs.
|
||||
# To compile with bc prefix, use rpmbuild -ba --with bc [SPEC]
|
||||
%define pkg_name %{?_with_bc:bc-liblinphone}%{!?_with_bc:liblinphone}
|
||||
%{?_with_bc: %define _prefix /opt/belledonne-communications}
|
||||
%define _prefix @CMAKE_INSTALL_PREFIX@
|
||||
%define pkg_prefix @BC_PACKAGE_NAME_PREFIX@
|
||||
|
||||
# re-define some directories for older RPMBuild versions which don't. This messes up the doc/ dir
|
||||
# taken from https://fedoraproject.org/wiki/Packaging:RPMMacros?rd=Packaging/RPMMacros
|
||||
|
|
@ -15,18 +10,20 @@
|
|||
%define _docdir %{_datadir}/doc
|
||||
|
||||
%define build_number @PROJECT_VERSION_BUILD@
|
||||
%if %{build_number}
|
||||
%define build_number_ext -%{build_number}
|
||||
%endif
|
||||
|
||||
|
||||
|
||||
Name: %{pkg_name}
|
||||
Name: @CPACK_PACKAGE_NAME@
|
||||
Version: @PROJECT_VERSION@
|
||||
Release: %build_number%{?dist}
|
||||
Release: %{build_number}%{?dist}
|
||||
Summary: Phone anywhere in the whole world by using the Internet
|
||||
|
||||
Group: Applications/Communications
|
||||
License: GPL
|
||||
URL: http://www.linphone.org
|
||||
Source0: %{name}-%{version}-%{build_number}.tar.gz
|
||||
Source0: %{name}-%{version}%{?build_number_ext}.tar.gz
|
||||
BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-buildroot
|
||||
|
||||
Requires: %{pkg_prefix}bctoolbox
|
||||
|
|
@ -34,15 +31,13 @@ Requires: %{pkg_prefix}ortp
|
|||
Requires: %{pkg_prefix}mediastreamer
|
||||
Requires: %{pkg_prefix}belle-sip
|
||||
Requires: %{pkg_prefix}belr
|
||||
%if %{?_with_soci:1}%{!?_with_soci:0}
|
||||
%if @ENABLE_SOCI_STORAGE@
|
||||
Requires: %{pkg_prefix}soci
|
||||
%endif
|
||||
|
||||
%description
|
||||
liblinphone is the voip sdk used by Linphone
|
||||
|
||||
%define video %{?_without_video:0}%{!?_without_video:1}
|
||||
|
||||
|
||||
%package devel
|
||||
Summary: Development libraries for liblinphone
|
||||
|
|
@ -61,11 +56,15 @@ develop programs using the liblinphone library.
|
|||
%define ctest_name ctest
|
||||
%endif
|
||||
|
||||
# This is for debian builds where debug_package has to be manually specified, whereas in centos it does not
|
||||
%define custom_debug_package %{!?_enable_debug_packages:%debug_package}%{?_enable_debug_package:%{nil}}
|
||||
%custom_debug_package
|
||||
|
||||
%prep
|
||||
%setup -n %{name}-%{version}-%build_number
|
||||
%setup -n %{name}-%{version}%{?build_number_ext}
|
||||
|
||||
%build
|
||||
%{expand:%%%cmake_name} . -DCMAKE_INSTALL_LIBDIR:PATH=%{_libdir} -DCMAKE_PREFIX_PATH:PATH=%{_prefix} -DENABLE_VIDEO=%{video}
|
||||
%{expand:%%%cmake_name} . -DCMAKE_BUILD_TYPE=@CMAKE_BUILD_TYPE@ -DCMAKE_INSTALL_LIBDIR:PATH=%{_libdir} -DCMAKE_PREFIX_PATH:PATH=%{_prefix} @RPM_ALL_CMAKE_OPTIONS@
|
||||
make %{?_smp_mflags}
|
||||
|
||||
%install
|
||||
|
|
@ -84,25 +83,32 @@ rm -rf $RPM_BUILD_ROOT
|
|||
%files
|
||||
%defattr(-,root,root)
|
||||
%doc AUTHORS ChangeLog COPYING NEWS README.md TODO
|
||||
%{_bindir}/linphonec
|
||||
%{_bindir}/linphonecsh
|
||||
%{_bindir}/lp-auto-answer
|
||||
%{_bindir}/lp-test-ecc
|
||||
%if @ENABLE_DAEMON@ || @ENABLE_CONSOLE_UI@
|
||||
%{_bindir}/*
|
||||
%endif
|
||||
%{_libdir}/*.so.*
|
||||
#%{_mandir}/*
|
||||
%{_datadir}/linphone
|
||||
%{_datadir}/sounds/linphone
|
||||
%{_datadir}/Linphone/rootca.pem
|
||||
|
||||
%files devel
|
||||
%defattr(-,root,root)
|
||||
%{_bindir}/*
|
||||
%{_includedir}/linphone
|
||||
%if @ENABLE_CXX_WRAPPER@
|
||||
%{_includedir}/linphone++
|
||||
%endif
|
||||
%if @ENABLE_STATIC@
|
||||
%{_libdir}/*.a
|
||||
%endif
|
||||
%if @ENABLE_SHARED@
|
||||
%{_libdir}/*.so
|
||||
#%{_docdir}
|
||||
%endif
|
||||
%if @ENABLE_DOC@
|
||||
%{_docdir}/linphone*/html
|
||||
%{_docdir}/linphone*/xml
|
||||
%endif
|
||||
%{_datadir}/Linphone/cmake/*.cmake
|
||||
%{_datadir}/liblinphone_tester
|
||||
%{_datadir}/LinphoneCxx/cmake/*.cmake
|
||||
%{_datadir}/belr/grammars/cpim_grammar
|
||||
|
||||
|
||||
|
|
@ -930,6 +930,7 @@ lpc_cmd_firewall(LinphoneCore *lc, char *args)
|
|||
return 1;
|
||||
}
|
||||
linphone_core_set_firewall_policy(lc,LinphonePolicyUseNatAddress);
|
||||
setting = linphone_core_get_nat_address(lc);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -975,7 +975,7 @@ linphonec_idle_call ()
|
|||
linphone_core_iterate(opm);
|
||||
if (answer_call){
|
||||
fprintf (stdout, "-------auto answering to call-------\n" );
|
||||
linphone_core_accept_call(opm,NULL);
|
||||
linphone_core_accept_call(opm, linphone_core_get_current_call(opm));
|
||||
answer_call=FALSE;
|
||||
}
|
||||
/* auto call handling */
|
||||
|
|
|
|||
|
|
@ -156,11 +156,11 @@ static char *argv_to_line(int argc, char *argv[]) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#define MAX_ARGS 10
|
||||
#define MAX_ARGS 20
|
||||
|
||||
#ifndef _WIN32
|
||||
static void spawn_linphonec(int argc, char *argv[]){
|
||||
char * args[MAX_ARGS];
|
||||
char * args[MAX_ARGS+1];
|
||||
int i,j;
|
||||
pid_t pid;
|
||||
j=0;
|
||||
|
|
@ -168,10 +168,10 @@ static void spawn_linphonec(int argc, char *argv[]){
|
|||
args[j++]="--pipe";
|
||||
args[j++]="-c";
|
||||
args[j++]="/dev/null";
|
||||
for(i=0;i<argc;++i){
|
||||
for(i=0;i<argc && i<MAX_ARGS;++i){
|
||||
args[j++]=argv[i];
|
||||
}
|
||||
args[j++]=NULL;
|
||||
args[j]=NULL;
|
||||
|
||||
#ifdef __uClinux__
|
||||
pid = vfork();
|
||||
|
|
|
|||
|
|
@ -91,7 +91,18 @@ static char* _get_identity(const LinphoneAccountCreator *creator) {
|
|||
LinphoneAddress* addr;
|
||||
|
||||
addr = linphone_proxy_config_normalize_sip_uri(proxy, creator->username ? creator->username : creator->phone_number);
|
||||
if (addr == NULL) goto end;
|
||||
if (addr == NULL) {
|
||||
if (creator->username && creator->domain) {
|
||||
char *url = ms_strdup_printf("sip:%s@%s", creator->username, creator->domain);
|
||||
addr = linphone_address_new(url);
|
||||
ms_free(url);
|
||||
if (addr == NULL) {
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
identity = linphone_address_as_string(addr);
|
||||
linphone_address_unref(addr);
|
||||
|
|
@ -139,6 +150,9 @@ LinphoneProxyConfig * linphone_account_creator_create_proxy_config(const Linphon
|
|||
snprintf(buff, sizeof(buff), "%d", dial_prefix_number);
|
||||
linphone_proxy_config_set_dial_prefix(cfg, buff);
|
||||
}
|
||||
if (linphone_proxy_config_get_server_addr(cfg) == NULL && creator->domain != NULL) {
|
||||
linphone_proxy_config_set_server_addr(cfg, creator->domain);
|
||||
}
|
||||
|
||||
linphone_proxy_config_enable_register(cfg, TRUE);
|
||||
|
||||
|
|
|
|||
|
|
@ -170,6 +170,23 @@ bctbx_list_t * linphone_core_read_call_logs_from_config_file(LinphoneCore *lc){
|
|||
* Public functions *
|
||||
******************************************************************************/
|
||||
|
||||
LinphoneCallLog *linphone_core_create_call_log(LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, LinphoneCallDir dir,
|
||||
int duration, time_t start_time, time_t connected_time, LinphoneCallStatus status, bool_t video_enabled, float quality) {
|
||||
LinphoneCallLog *log = linphone_call_log_new(dir, linphone_address_ref(from), linphone_address_ref(to));
|
||||
|
||||
log->duration = duration;
|
||||
log->start_date_time = start_time;
|
||||
set_call_log_date(log,log->start_date_time);
|
||||
log->connected_date_time = connected_time;
|
||||
log->status = status;
|
||||
log->video_enabled = video_enabled;
|
||||
log->quality = quality;
|
||||
|
||||
linphone_core_store_call_log(lc, log);
|
||||
|
||||
return log;
|
||||
}
|
||||
|
||||
const char *linphone_call_log_get_call_id(const LinphoneCallLog *cl){
|
||||
return cl->call_id;
|
||||
}
|
||||
|
|
@ -198,7 +215,11 @@ const char *linphone_call_log_get_ref_key(const LinphoneCallLog *cl){
|
|||
return cl->refkey;
|
||||
}
|
||||
|
||||
LinphoneAddress *linphone_call_log_get_remote_address(const LinphoneCallLog *cl){
|
||||
const LinphoneAddress *linphone_call_log_get_local_address(const LinphoneCallLog *cl) {
|
||||
return (cl->dir == LinphoneCallIncoming) ? cl->to : cl->from;
|
||||
}
|
||||
|
||||
const LinphoneAddress *linphone_call_log_get_remote_address(const LinphoneCallLog *cl){
|
||||
return (cl->dir == LinphoneCallIncoming) ? cl->from : cl->to;
|
||||
}
|
||||
|
||||
|
|
@ -610,7 +631,10 @@ int linphone_core_get_call_history_size(LinphoneCore *lc) {
|
|||
sqlite3_stmt *selectStatement;
|
||||
int returnValue;
|
||||
|
||||
if (!lc || lc->logs_db == NULL) return 0;
|
||||
if (!lc)
|
||||
return 0;
|
||||
if (!lc->logs_db)
|
||||
return (int)bctbx_list_size(lc->call_logs);
|
||||
|
||||
buf = sqlite3_mprintf("SELECT count(*) FROM call_history");
|
||||
returnValue = sqlite3_prepare_v2(lc->logs_db, buf, -1, &selectStatement, NULL);
|
||||
|
|
|
|||
|
|
@ -39,6 +39,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
|
||||
#include "c-wrapper/c-wrapper.h"
|
||||
#include "call/call-p.h"
|
||||
#include "chat/chat-message/chat-message-p.h"
|
||||
#include "chat/chat-room/chat-room.h"
|
||||
#include "chat/chat-room/server-group-chat-room-p.h"
|
||||
#include "conference/participant.h"
|
||||
|
|
@ -255,7 +256,9 @@ static void call_terminated(SalOp *op, const char *from) {
|
|||
}
|
||||
|
||||
static void call_failure(SalOp *op) {
|
||||
LinphonePrivate::CallSession *session = reinterpret_cast<LinphonePrivate::CallSession *>(op->get_user_pointer());
|
||||
shared_ptr<LinphonePrivate::CallSession> session;
|
||||
if (op->get_user_pointer())
|
||||
session = reinterpret_cast<LinphonePrivate::CallSession *>(op->get_user_pointer())->getSharedFromThis();
|
||||
if (!session) {
|
||||
ms_warning("Failure reported on already terminated CallSession");
|
||||
return;
|
||||
|
|
@ -565,7 +568,7 @@ static void message_delivery_update(SalOp *op, SalMessageDeliveryStatus status)
|
|||
|
||||
// Check that the message does not belong to an already destroyed chat room - if so, do not invoke callbacks
|
||||
if (msg->getChatRoom())
|
||||
msg->updateState((LinphonePrivate::ChatMessage::State)chatStatusSal2Linphone(status));
|
||||
L_GET_PRIVATE(msg)->setState((LinphonePrivate::ChatMessage::State)chatStatusSal2Linphone(status));
|
||||
}
|
||||
|
||||
static void info_received(SalOp *op, SalBodyHandler *body_handler) {
|
||||
|
|
@ -668,20 +671,25 @@ static void on_expire(SalOp *op){
|
|||
|
||||
static void on_notify_response(SalOp *op){
|
||||
LinphoneEvent *lev=(LinphoneEvent*)op->get_user_pointer();
|
||||
if (!lev)
|
||||
return;
|
||||
|
||||
if (lev==NULL) return;
|
||||
/*this is actually handling out of dialogs notify - for the moment*/
|
||||
if (!lev->is_out_of_dialog_op) return;
|
||||
switch (linphone_event_get_subscription_state(lev)){
|
||||
case LinphoneSubscriptionIncomingReceived:
|
||||
if (op->get_error_info()->reason == SalReasonNone){
|
||||
linphone_event_set_state(lev, LinphoneSubscriptionTerminated);
|
||||
}else{
|
||||
linphone_event_set_state(lev, LinphoneSubscriptionError);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
ms_warning("Unhandled on_notify_response() case %s", linphone_subscription_state_to_string(linphone_event_get_subscription_state(lev)));
|
||||
if (lev->is_out_of_dialog_op) {
|
||||
switch (linphone_event_get_subscription_state(lev)) {
|
||||
case LinphoneSubscriptionIncomingReceived:
|
||||
if (op->get_error_info()->reason == SalReasonNone)
|
||||
linphone_event_set_state(lev, LinphoneSubscriptionTerminated);
|
||||
else
|
||||
linphone_event_set_state(lev, LinphoneSubscriptionError);
|
||||
break;
|
||||
default:
|
||||
ms_warning("Unhandled on_notify_response() case %s",
|
||||
linphone_subscription_state_to_string(linphone_event_get_subscription_state(lev)));
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
ms_warning("on_notify_response in dialog");
|
||||
_linphone_event_notify_notify_response(lev);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -742,10 +750,12 @@ static void refer_received(SalOp *op, const SalAddress *refer_to){
|
|||
return;
|
||||
}
|
||||
} else {
|
||||
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(ChatRoomId(addr, IdentityAddress(op->get_to()))));
|
||||
if (!cr)
|
||||
cr = _linphone_client_group_chat_room_new(lc, addr.asString().c_str(), nullptr, FALSE);
|
||||
L_GET_CPP_PTR_FROM_C_OBJECT(cr)->join();
|
||||
shared_ptr<AbstractChatRoom> chatRoom = L_GET_CPP_PTR_FROM_C_OBJECT(lc)->findChatRoom(
|
||||
ChatRoomId(addr, IdentityAddress(op->get_to()))
|
||||
);
|
||||
if (!chatRoom)
|
||||
chatRoom = L_GET_PRIVATE_FROM_C_OBJECT(lc)->createClientGroupChatRoom("", addr.asString(), false);
|
||||
chatRoom->join();
|
||||
static_cast<SalReferOp *>(op)->reply(SalReasonNone);
|
||||
return;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@
|
|||
#include "linphone/wrapper_utils.h"
|
||||
|
||||
#include "c-wrapper/c-wrapper.h"
|
||||
#include "call/call.h"
|
||||
#include "chat/chat-room/basic-chat-room.h"
|
||||
#include "chat/chat-room/client-group-chat-room.h"
|
||||
#include "chat/chat-room/client-group-to-basic-chat-room.h"
|
||||
|
|
@ -149,12 +150,9 @@ int linphone_core_message_received(LinphoneCore *lc, LinphonePrivate::SalOp *op,
|
|||
}
|
||||
|
||||
void linphone_core_real_time_text_received(LinphoneCore *lc, LinphoneChatRoom *cr, uint32_t character, LinphoneCall *call) {
|
||||
if (linphone_core_realtime_text_enabled(lc)) {
|
||||
shared_ptr<LinphonePrivate::RealTimeTextChatRoom> rttcr =
|
||||
static_pointer_cast<LinphonePrivate::RealTimeTextChatRoom>(L_GET_CPP_PTR_FROM_C_OBJECT(cr));
|
||||
L_GET_PRIVATE(rttcr)->realtimeTextReceived(character, call);
|
||||
//L_GET_PRIVATE(static_pointer_cast<LinphonePrivate::RealTimeTextChatRoom>(L_GET_CPP_PTR_FROM_C_OBJECT(cr)))->realtimeTextReceived(character, call);
|
||||
}
|
||||
if (!(L_GET_CPP_PTR_FROM_C_OBJECT(cr)->getCapabilities() & LinphonePrivate::ChatRoom::Capabilities::RealTimeText))
|
||||
return;
|
||||
L_GET_PRIVATE_FROM_C_OBJECT(cr, RealTimeTextChatRoom)->realtimeTextReceived(character, L_GET_CPP_PTR_FROM_C_OBJECT(call));
|
||||
}
|
||||
|
||||
unsigned int linphone_chat_message_store(LinphoneChatMessage *msg) {
|
||||
|
|
|
|||
|
|
@ -76,6 +76,46 @@ LINPHONE_PUBLIC const char *linphone_publish_state_to_string(LinphonePublishStat
|
|||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneEventCbs);
|
||||
|
||||
BELLE_SIP_INSTANCIATE_VPTR(LinphoneEventCbs, belle_sip_object_t,
|
||||
NULL, // destroy
|
||||
NULL, // clone
|
||||
NULL, // marshal
|
||||
FALSE
|
||||
);
|
||||
|
||||
static LinphoneEventCbs *linphone_event_cbs_new(void) {
|
||||
return belle_sip_object_new(LinphoneEventCbs);
|
||||
}
|
||||
|
||||
LinphoneEventCbs *linphone_event_cbs_ref(LinphoneEventCbs *cbs) {
|
||||
belle_sip_object_ref(cbs);
|
||||
return cbs;
|
||||
}
|
||||
|
||||
void linphone_event_cbs_unref(LinphoneEventCbs *cbs) {
|
||||
belle_sip_object_unref(cbs);
|
||||
}
|
||||
|
||||
void *linphone_event_cbs_get_user_data(const LinphoneEventCbs *cbs) {
|
||||
return cbs->user_data;
|
||||
}
|
||||
|
||||
void linphone_event_cbs_set_user_data(LinphoneEventCbs *cbs, void *ud) {
|
||||
cbs->user_data = ud;
|
||||
}
|
||||
|
||||
LinphoneEventCbsNotifyResponseCb linphone_event_cbs_get_notify_response(const LinphoneEventCbs *cbs) {
|
||||
return cbs->notify_response_cb;
|
||||
}
|
||||
|
||||
void linphone_event_cbs_set_notify_response(LinphoneEventCbs *cbs, LinphoneEventCbsNotifyResponseCb cb) {
|
||||
cbs->notify_response_cb = cb;
|
||||
}
|
||||
|
||||
|
||||
static void linphone_event_release(LinphoneEvent *lev){
|
||||
if (lev->op) {
|
||||
/*this will stop the refresher*/
|
||||
|
|
@ -86,6 +126,7 @@ static void linphone_event_release(LinphoneEvent *lev){
|
|||
|
||||
static LinphoneEvent * linphone_event_new_base(LinphoneCore *lc, LinphoneSubscriptionDir dir, const char *name, LinphonePrivate::SalEventOp *op){
|
||||
LinphoneEvent *lev=belle_sip_object_new(LinphoneEvent);
|
||||
lev->callbacks = linphone_event_cbs_new();
|
||||
lev->lc=lc;
|
||||
lev->dir=dir;
|
||||
lev->op=op;
|
||||
|
|
@ -446,6 +487,7 @@ static void linphone_event_destroy(LinphoneEvent *lev){
|
|||
if (lev->to_address) linphone_address_unref(lev->to_address);
|
||||
if (lev->from_address) linphone_address_unref(lev->from_address);
|
||||
if (lev->remote_contact_address) linphone_address_unref(lev->remote_contact_address);
|
||||
linphone_event_cbs_unref(lev->callbacks);
|
||||
|
||||
ms_free(lev->name);
|
||||
}
|
||||
|
|
@ -523,6 +565,16 @@ static belle_sip_error_code _linphone_event_marshall(belle_sip_object_t *obj, ch
|
|||
return err;
|
||||
}
|
||||
|
||||
void _linphone_event_notify_notify_response(const LinphoneEvent *lev) {
|
||||
LinphoneEventCbsNotifyResponseCb cb = linphone_event_cbs_get_notify_response(lev->callbacks);
|
||||
if (cb)
|
||||
cb(lev);
|
||||
}
|
||||
|
||||
LinphoneEventCbs *linphone_event_get_callbacks(const LinphoneEvent *ev) {
|
||||
return ev->callbacks;
|
||||
}
|
||||
|
||||
BELLE_SIP_DECLARE_NO_IMPLEMENTED_INTERFACES(LinphoneEvent);
|
||||
|
||||
BELLE_SIP_INSTANCIATE_VPTR(LinphoneEvent, belle_sip_object_t,
|
||||
|
|
|
|||
|
|
@ -21,6 +21,8 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
|
||||
#include "c-wrapper/c-wrapper.h"
|
||||
|
||||
#include "address/address-p.h"
|
||||
|
||||
// TODO: From coreapi. Remove me later.
|
||||
#include "private.h"
|
||||
|
||||
|
|
@ -145,6 +147,7 @@ LinphoneFactory *linphone_factory_get(void) {
|
|||
}
|
||||
|
||||
void linphone_factory_clean(void){
|
||||
LinphonePrivate::AddressPrivate::clearSipAddressesCache();
|
||||
if (_factory){
|
||||
belle_sip_object_unref(_factory);
|
||||
_factory = NULL;
|
||||
|
|
@ -238,6 +241,10 @@ LinphoneCallCbs * linphone_factory_create_call_cbs(const LinphoneFactory *factor
|
|||
return _linphone_call_cbs_new();
|
||||
}
|
||||
|
||||
LinphoneChatRoomCbs * linphone_factory_create_chat_room_cbs(const LinphoneFactory *factory) {
|
||||
return _linphone_chat_room_cbs_new();
|
||||
}
|
||||
|
||||
LinphoneVcard *linphone_factory_create_vcard(LinphoneFactory *factory) {
|
||||
return _linphone_vcard_new();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -413,7 +413,7 @@ void linphone_friend_add_phone_number(LinphoneFriend *lf, const char *phone) {
|
|||
}
|
||||
}
|
||||
|
||||
bctbx_list_t* linphone_friend_get_phone_numbers(LinphoneFriend *lf) {
|
||||
bctbx_list_t* linphone_friend_get_phone_numbers(const LinphoneFriend *lf) {
|
||||
if (!lf || !lf->vcard) return NULL;
|
||||
|
||||
if (linphone_core_vcard_supported()) {
|
||||
|
|
@ -1134,7 +1134,7 @@ void linphone_friend_destroy(LinphoneFriend *lf) {
|
|||
linphone_friend_unref(lf);
|
||||
}
|
||||
|
||||
LinphoneVcard* linphone_friend_get_vcard(LinphoneFriend *fr) {
|
||||
LinphoneVcard* linphone_friend_get_vcard(const LinphoneFriend *fr) {
|
||||
if (fr && linphone_core_vcard_supported()) return fr->vcard;
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -634,10 +634,13 @@ static LinphoneFriendListStatus _linphone_friend_list_remove_friend(LinphoneFrie
|
|||
list->friends = bctbx_list_erase_link(list->friends, elem);
|
||||
if(lf->refkey) {
|
||||
bctbx_iterator_t * it = bctbx_map_cchar_find_key(list->friends_map, lf->refkey);
|
||||
if (!bctbx_iterator_cchar_equals(it, bctbx_map_cchar_end(list->friends_map))){
|
||||
bctbx_iterator_t * end = bctbx_map_cchar_end(list->friends_map);
|
||||
if (!bctbx_iterator_cchar_equals(it, end)){
|
||||
linphone_friend_unref((LinphoneFriend*)bctbx_pair_cchar_get_second(bctbx_iterator_cchar_get_pair(it)));
|
||||
bctbx_map_cchar_erase(list->friends_map, it);
|
||||
}
|
||||
if (it) bctbx_iterator_cchar_delete(it);
|
||||
if (end) bctbx_iterator_cchar_delete(end);
|
||||
}
|
||||
|
||||
phone_numbers = linphone_friend_get_phone_numbers(lf);
|
||||
|
|
@ -647,14 +650,17 @@ static LinphoneFriendListStatus _linphone_friend_list_remove_friend(LinphoneFrie
|
|||
const char *uri = linphone_friend_phone_number_to_sip_uri(lf, number);
|
||||
if(uri) {
|
||||
bctbx_iterator_t * it = bctbx_map_cchar_find_key(list->friends_map_uri, uri);
|
||||
if (!bctbx_iterator_cchar_equals(it, bctbx_map_cchar_end(list->friends_map_uri))){
|
||||
bctbx_iterator_t * end = bctbx_map_cchar_end(list->friends_map_uri);
|
||||
if (!bctbx_iterator_cchar_equals(it, end)){
|
||||
linphone_friend_unref((LinphoneFriend*)bctbx_pair_cchar_get_second(bctbx_iterator_cchar_get_pair(it)));
|
||||
bctbx_map_cchar_erase(list->friends_map_uri, it);
|
||||
}
|
||||
bctbx_iterator_cchar_delete(it);
|
||||
if (it) bctbx_iterator_cchar_delete(it);
|
||||
if (end) bctbx_iterator_cchar_delete(end);
|
||||
}
|
||||
iterator = bctbx_list_next(iterator);
|
||||
}
|
||||
if (phone_numbers) bctbx_list_free(phone_numbers);
|
||||
|
||||
addresses = linphone_friend_get_addresses(lf);
|
||||
iterator = (bctbx_list_t *)addresses;
|
||||
|
|
@ -663,13 +669,16 @@ static LinphoneFriendListStatus _linphone_friend_list_remove_friend(LinphoneFrie
|
|||
char *uri = linphone_address_as_string_uri_only(lfaddr);
|
||||
if(uri) {
|
||||
bctbx_iterator_t * it = bctbx_map_cchar_find_key(list->friends_map_uri, uri);
|
||||
if (!bctbx_iterator_cchar_equals(it, bctbx_map_cchar_end(list->friends_map_uri))){
|
||||
bctbx_iterator_t * end = bctbx_map_cchar_end(list->friends_map_uri);
|
||||
if (!bctbx_iterator_cchar_equals(it, end)){
|
||||
linphone_friend_unref((LinphoneFriend*)bctbx_pair_cchar_get_second(bctbx_iterator_cchar_get_pair(it)));
|
||||
bctbx_map_cchar_erase(list->friends_map_uri, it);
|
||||
}
|
||||
bctbx_iterator_cchar_delete(it);
|
||||
if (it) bctbx_iterator_cchar_delete(it);
|
||||
if (end) bctbx_iterator_cchar_delete(end);
|
||||
ms_free(uri);
|
||||
}
|
||||
|
||||
iterator = bctbx_list_next(iterator);
|
||||
}
|
||||
|
||||
|
|
@ -766,7 +775,7 @@ void linphone_friend_list_synchronize_friends_from_server(LinphoneFriendList *li
|
|||
LinphoneFriend * linphone_friend_list_find_friend_by_address(const LinphoneFriendList *list, const LinphoneAddress *address) {
|
||||
LinphoneAddress *clean_addr = linphone_address_clone(address);
|
||||
LinphoneFriend *lf;
|
||||
if (linphone_address_has_param(clean_addr, "gr")) {
|
||||
if (linphone_address_has_uri_param(clean_addr, "gr")) {
|
||||
linphone_address_remove_uri_param(clean_addr, "gr");
|
||||
}
|
||||
char *uri = linphone_address_as_string_uri_only(clean_addr);
|
||||
|
|
|
|||
|
|
@ -1395,6 +1395,9 @@ static void sip_config_read(LinphoneCore *lc) {
|
|||
/*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->enable_reconnect_to_primary_asap(!!lp_config_get_int(lc->config,"sip","reconnect_to_primary_asap",0));
|
||||
|
||||
/*for tuning or test*/
|
||||
lc->sip_conf.sdp_200_ack = !!lp_config_get_int(lc->config,"sip","sdp_200_ack",0);
|
||||
lc->sip_conf.register_only_when_network_is_up=
|
||||
|
|
@ -2142,6 +2145,7 @@ static void linphone_core_internal_notify_received(LinphoneCore *lc, LinphoneEve
|
|||
while ((part = linphone_content_get_part(body, i))) {
|
||||
i++;
|
||||
L_GET_PRIVATE(cgcr)->notifyReceived(linphone_content_get_string_buffer(part));
|
||||
linphone_content_unref(part);
|
||||
}
|
||||
} else
|
||||
L_GET_PRIVATE(cgcr)->notifyReceived(linphone_content_get_string_buffer(body));
|
||||
|
|
@ -2320,7 +2324,7 @@ void linphone_core_start (LinphoneCore *lc) {
|
|||
lp_config_set_string(lc->config,"misc","uuid",tmp);
|
||||
}else if (strcmp(uuid,"0")!=0) /*to allow to disable sip.instance*/
|
||||
lc->sal->set_uuid(uuid);
|
||||
|
||||
|
||||
if (lc->sal->get_root_ca()) {
|
||||
belle_tls_crypto_config_set_root_ca(lc->http_crypto_config, lc->sal->get_root_ca());
|
||||
belle_http_provider_set_tls_crypto_config(lc->http_provider, lc->http_crypto_config);
|
||||
|
|
@ -2384,7 +2388,8 @@ LinphoneCore *linphone_core_new(const LinphoneCoreVTable *vtable,
|
|||
}
|
||||
|
||||
LinphoneCore *linphone_core_ref(LinphoneCore *lc) {
|
||||
return reinterpret_cast<LinphoneCore *>(belle_sip_object_ref(BELLE_SIP_OBJECT(lc)));
|
||||
belle_sip_object_ref(BELLE_SIP_OBJECT(lc));
|
||||
return lc;
|
||||
}
|
||||
|
||||
void linphone_core_unref(LinphoneCore *lc) {
|
||||
|
|
@ -3417,11 +3422,16 @@ LinphoneCall * linphone_core_start_refered_call(LinphoneCore *lc, LinphoneCall *
|
|||
system.
|
||||
*/
|
||||
static bctbx_list_t *make_routes_for_proxy(LinphoneProxyConfig *proxy, const LinphoneAddress *dest){
|
||||
bctbx_list_t *ret=NULL;
|
||||
const char *local_route=linphone_proxy_config_get_route(proxy);
|
||||
const LinphoneAddress *srv_route=linphone_proxy_config_get_service_route(proxy);
|
||||
if (local_route){
|
||||
ret=bctbx_list_append(ret,sal_address_new(local_route));
|
||||
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);
|
||||
}
|
||||
if (srv_route){
|
||||
ret=bctbx_list_append(ret,sal_address_clone(L_GET_PRIVATE_FROM_C_OBJECT(srv_route)->getInternalAddress()));
|
||||
|
|
@ -3445,7 +3455,7 @@ LinphoneProxyConfig * linphone_core_lookup_known_proxy(LinphoneCore *lc, const L
|
|||
LinphoneProxyConfig *default_cfg=lc->default_proxy;
|
||||
|
||||
if (linphone_address_get_domain(uri) == NULL) {
|
||||
ms_message("cannot seach for proxy for uri [%p] if no domain set. returning default",uri);
|
||||
ms_message("Cannot look for proxy for uri [%p] that has no domain set, returning default", uri);
|
||||
return default_cfg;
|
||||
}
|
||||
/*return default proxy if it is matching the destination uri*/
|
||||
|
|
@ -5812,15 +5822,17 @@ void sip_config_uninit(LinphoneCore *lc)
|
|||
}
|
||||
if (i>=20) ms_warning("Cannot complete unregistration, giving up");
|
||||
}
|
||||
|
||||
elem = config->proxies;
|
||||
config->proxies=NULL; /*to make sure proxies cannot be refferenced during deletion*/
|
||||
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_proxies=bctbx_list_free_with_data(config->deleted_proxies,(void (*)(void*)) _linphone_proxy_config_release);
|
||||
|
||||
/*no longuer need to write proxy config if not changedlinphone_proxy_config_write_to_config_file(lc->config,NULL,i);*/ /*mark the end */
|
||||
/*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_proxy = NULL;
|
||||
|
||||
if (lc->vcard_context) {
|
||||
linphone_vcard_context_destroy(lc->vcard_context);
|
||||
|
|
@ -5850,6 +5862,7 @@ void sip_config_uninit(LinphoneCore *lc)
|
|||
delete lc->sal;
|
||||
lc->sal=NULL;
|
||||
|
||||
|
||||
if (lc->sip_conf.guessed_contact)
|
||||
ms_free(lc->sip_conf.guessed_contact);
|
||||
if (config->contact)
|
||||
|
|
@ -6709,11 +6722,13 @@ int linphone_core_get_video_dscp(const LinphoneCore *lc){
|
|||
|
||||
void linphone_core_set_chat_database_path (LinphoneCore *lc, const char *path) {
|
||||
if (!linphone_core_conference_server_enabled(lc)) {
|
||||
auto &mainDb = L_GET_PRIVATE(lc->cppPtr)->mainDb;
|
||||
if (mainDb)
|
||||
auto &mainDb = L_GET_PRIVATE_FROM_C_OBJECT(lc)->mainDb;
|
||||
if (mainDb) {
|
||||
mainDb->import(LinphonePrivate::MainDb::Sqlite3, path);
|
||||
else
|
||||
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");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -7040,20 +7055,15 @@ LinphoneConference *linphone_core_get_conference(LinphoneCore *lc) {
|
|||
return lc->conf_ctx;
|
||||
}
|
||||
|
||||
void linphone_core_set_conference_factory_uri(LinphoneCore *lc, const char *uri) {
|
||||
lp_config_set_string(linphone_core_get_config(lc), "misc", "conference_factory_uri", uri);
|
||||
}
|
||||
|
||||
const char * linphone_core_get_conference_factory_uri(const LinphoneCore *lc) {
|
||||
return lp_config_get_string(linphone_core_get_config(lc), "misc", "conference_factory_uri", nullptr);
|
||||
}
|
||||
|
||||
void linphone_core_enable_conference_server (LinphoneCore *lc, bool_t enable) {
|
||||
lp_config_set_int(linphone_core_get_config(lc), "misc", "conference_server_enabled", enable);
|
||||
}
|
||||
|
||||
bool_t _linphone_core_is_conference_creation (const LinphoneCore *lc, const LinphoneAddress *addr) {
|
||||
const char *uri = linphone_core_get_conference_factory_uri(lc);
|
||||
LinphoneProxyConfig *proxy = linphone_core_get_default_proxy_config(lc);
|
||||
if (!proxy)
|
||||
return FALSE;
|
||||
const char *uri = linphone_proxy_config_get_conference_factory_uri(proxy);
|
||||
if (!uri)
|
||||
return FALSE;
|
||||
|
||||
|
|
|
|||
|
|
@ -8913,3 +8913,15 @@ extern "C" jstring Java_org_linphone_core_LinphoneCoreImpl_getTlsKeyPath(JNIEnv
|
|||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" jlong Java_org_linphone_core_LinphoneCoreImpl_createCallLog(JNIEnv *env, jobject, jlong jcore, jlong jfrom, jlong jto, jint jdir, jint duration, jlong start_time, jlong connected_time, jint jstatus, jboolean video_enabled, jfloat quality) {
|
||||
LinphoneCore *core = (LinphoneCore*)jcore;
|
||||
LinphoneAddress *from = (LinphoneAddress *)jfrom;
|
||||
LinphoneAddress *to = (LinphoneAddress *)jto;
|
||||
LinphoneCallDir dir = (LinphoneCallDir)jdir;
|
||||
time_t start = (time_t) start_time;
|
||||
time_t connected = (time_t) connected_time;
|
||||
LinphoneCallStatus status = (LinphoneCallStatus)jstatus;
|
||||
LinphoneCallLog *log = linphone_core_create_call_log(core, from, to, dir, duration, start, connected, status, video_enabled, quality);
|
||||
return (jlong) log;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -907,17 +907,21 @@ void linphone_core_report_call_log(LinphoneCore *lc, LinphoneCallLog *call_log){
|
|||
|
||||
// TODO: This is a workaround that has to be removed ASAP
|
||||
// Do not add calls made to the conference factory in the history
|
||||
char *to = linphone_address_as_string(call_log->to);
|
||||
const char *conference_factory_uri = linphone_core_get_conference_factory_uri(lc);
|
||||
if (conference_factory_uri && (strcmp(conference_factory_uri, to) == 0)) {
|
||||
bctbx_free(to);
|
||||
return;
|
||||
const char *conference_factory_uri = nullptr;
|
||||
LinphoneProxyConfig *proxy = linphone_core_lookup_known_proxy(lc, call_log->to);
|
||||
if (proxy)
|
||||
conference_factory_uri = linphone_proxy_config_get_conference_factory_uri(proxy);
|
||||
if (conference_factory_uri) {
|
||||
LinphoneAddress *conference_factory_addr = linphone_address_new(conference_factory_uri);
|
||||
if (linphone_address_weak_equal(call_log->to, conference_factory_addr)) {
|
||||
linphone_address_unref(conference_factory_addr);
|
||||
return;
|
||||
}
|
||||
linphone_address_unref(conference_factory_addr);
|
||||
}
|
||||
if (strstr(to, "chatroom-") == to) {
|
||||
bctbx_free(to);
|
||||
const char *username = linphone_address_get_username(call_log->to);
|
||||
if (username && (strstr(username, "chatroom-") == username))
|
||||
return;
|
||||
}
|
||||
bctbx_free(to);
|
||||
// End of workaround
|
||||
|
||||
#ifdef SQLITE_STORAGE_ENABLED
|
||||
|
|
|
|||
|
|
@ -185,6 +185,17 @@ void linphone_nat_policy_set_stun_server(LinphoneNatPolicy *policy, const char *
|
|||
if (new_stun_server != NULL) {
|
||||
policy->stun_server = new_stun_server;
|
||||
}
|
||||
if (policy->stun_addrinfo) {
|
||||
bctbx_freeaddrinfo(policy->stun_addrinfo);
|
||||
policy->stun_addrinfo = NULL;
|
||||
}
|
||||
if (policy->stun_resolver_context){
|
||||
belle_sip_resolver_context_cancel(policy->stun_resolver_context);
|
||||
belle_sip_object_unref(policy->stun_resolver_context);
|
||||
policy->stun_resolver_context = NULL;
|
||||
|
||||
}
|
||||
linphone_nat_policy_resolve_stun_server(policy);
|
||||
}
|
||||
|
||||
const char * linphone_nat_policy_get_stun_server_username(const LinphoneNatPolicy *policy) {
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ void linphone_call_notify_transfer_state_changed(LinphoneCall *call, LinphoneCal
|
|||
void linphone_call_notify_stats_updated(LinphoneCall *call, const LinphoneCallStats *stats);
|
||||
void linphone_call_notify_info_message_received(LinphoneCall *call, const LinphoneInfoMessage *msg);
|
||||
void linphone_call_notify_ack_processing(LinphoneCall *call, LinphoneHeaders *msg, bool_t is_received);
|
||||
void linphone_call_notify_tmmbr_received(LinphoneCall *call, int stream_index, int tmmbr);
|
||||
|
||||
LinphoneCall * linphone_call_new_outgoing(struct _LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to, const LinphoneCallParams *params, LinphoneProxyConfig *cfg);
|
||||
LinphoneCall * linphone_call_new_incoming(struct _LinphoneCore *lc, const LinphoneAddress *from, const LinphoneAddress *to, LinphonePrivate::SalCallOp *op);
|
||||
|
|
@ -275,11 +276,28 @@ void _linphone_proxy_config_unregister(LinphoneProxyConfig *obj);
|
|||
void _linphone_proxy_config_release_ops(LinphoneProxyConfig *obj);
|
||||
|
||||
/*chat*/
|
||||
LinphoneChatRoom *_linphone_client_group_chat_room_new (LinphoneCore *core, const char *uri, const char *subject, bool_t fallback);
|
||||
LinphoneChatRoom *_linphone_server_group_chat_room_new (LinphoneCore *core, LinphonePrivate::SalCallOp *op);
|
||||
void linphone_chat_room_set_call(LinphoneChatRoom *cr, LinphoneCall *call);
|
||||
LinphoneChatRoomCbs * linphone_chat_room_cbs_new (void);
|
||||
/**/
|
||||
LinphoneChatRoomCbs * _linphone_chat_room_cbs_new (void);
|
||||
void _linphone_chat_room_notify_is_composing_received(LinphoneChatRoom *cr, const LinphoneAddress *remoteAddr, bool_t isComposing);
|
||||
void _linphone_chat_room_notify_message_received(LinphoneChatRoom *cr, LinphoneChatMessage *msg);
|
||||
void _linphone_chat_room_notify_participant_added(LinphoneChatRoom *cr, const LinphoneEventLog *event_log);
|
||||
void _linphone_chat_room_notify_participant_removed(LinphoneChatRoom *cr, const LinphoneEventLog *event_log);
|
||||
void _linphone_chat_room_notify_participant_device_added(LinphoneChatRoom *cr, const LinphoneEventLog *event_log);
|
||||
void _linphone_chat_room_notify_participant_device_removed(LinphoneChatRoom *cr, const LinphoneEventLog *event_log);
|
||||
void _linphone_chat_room_notify_participant_admin_status_changed(LinphoneChatRoom *cr, const LinphoneEventLog *event_log);
|
||||
void _linphone_chat_room_notify_state_changed(LinphoneChatRoom *cr, LinphoneChatRoomState newState);
|
||||
void _linphone_chat_room_notify_subject_changed(LinphoneChatRoom *cr, const LinphoneEventLog *event_log);
|
||||
void _linphone_chat_room_notify_undecryptable_message_received(LinphoneChatRoom *cr, LinphoneChatMessage *msg);
|
||||
void _linphone_chat_room_notify_chat_message_received(LinphoneChatRoom *cr, const LinphoneEventLog *event_log);
|
||||
void _linphone_chat_room_notify_chat_message_sent(LinphoneChatRoom *cr, const LinphoneEventLog *event_log);
|
||||
void _linphone_chat_room_notify_conference_address_generation(LinphoneChatRoom *cr);
|
||||
void _linphone_chat_room_notify_participant_device_fetch_requested(LinphoneChatRoom *cr, const LinphoneAddress *participantAddr);
|
||||
void _linphone_chat_room_notify_participants_capabilities_checked(LinphoneChatRoom *cr, const LinphoneAddress *deviceAddr, const bctbx_list_t *participantsAddr);
|
||||
void _linphone_chat_room_notify_participant_registration_subscription_requested(LinphoneChatRoom *cr, const LinphoneAddress *participantAddr);
|
||||
void _linphone_chat_room_notify_participant_registration_unsubscription_requested(LinphoneChatRoom *cr, const LinphoneAddress *participantAddr);
|
||||
void _linphone_chat_room_notify_chat_message_should_be_stored(LinphoneChatRoom *cr, LinphoneChatMessage *msg);
|
||||
void _linphone_chat_room_clear_callbacks (LinphoneChatRoom *cr);
|
||||
|
||||
LinphoneToneDescription * linphone_tone_description_new(LinphoneReason reason, LinphoneToneID id, const char *audiofile);
|
||||
void linphone_tone_description_destroy(LinphoneToneDescription *obj);
|
||||
|
|
@ -355,7 +373,6 @@ LinphoneChatMessageStateChangedCb linphone_chat_message_get_message_state_change
|
|||
void linphone_chat_message_set_message_state_changed_cb(LinphoneChatMessage* msg, LinphoneChatMessageStateChangedCb cb);
|
||||
void linphone_chat_message_set_message_state_changed_cb_user_data(LinphoneChatMessage* msg, void *user_data);
|
||||
void * linphone_chat_message_get_message_state_changed_cb_user_data(LinphoneChatMessage* msg);
|
||||
void linphone_chat_message_update_state(LinphoneChatMessage *msg, LinphoneChatMessageState new_state);
|
||||
LinphoneChatRoom *_linphone_core_create_chat_room_from_call(LinphoneCall *call);
|
||||
|
||||
void linphone_core_play_named_tone(LinphoneCore *lc, LinphoneToneID id);
|
||||
|
|
@ -380,6 +397,7 @@ void linphone_event_set_internal(LinphoneEvent *lev, bool_t internal);
|
|||
bool_t linphone_event_is_internal(LinphoneEvent *lev);
|
||||
void linphone_event_set_state(LinphoneEvent *lev, LinphoneSubscriptionState state);
|
||||
void linphone_event_set_publish_state(LinphoneEvent *lev, LinphonePublishState state);
|
||||
void _linphone_event_notify_notify_response(const LinphoneEvent *lev);
|
||||
LinphoneSubscriptionState linphone_subscription_state_from_sal(SalSubscribeStatus ss);
|
||||
LinphoneContent *linphone_content_from_sal_body_handler(SalBodyHandler *ref);
|
||||
void linphone_core_invalidate_friend_subscriptions(LinphoneCore *lc);
|
||||
|
|
|
|||
|
|
@ -90,7 +90,7 @@ struct _LinphoneProxyConfig
|
|||
LinphoneAddress* identity_address;
|
||||
LinphoneAddress *contact_address;
|
||||
LinphoneAddress *contact_address_without_params;
|
||||
char *reg_route;
|
||||
bctbx_list_t *reg_routes;
|
||||
char *quality_reporting_collector;
|
||||
char *realm;
|
||||
char *contact_params;
|
||||
|
|
@ -106,6 +106,7 @@ struct _LinphoneProxyConfig
|
|||
LinphoneRegistrationState state;
|
||||
LinphoneAVPFMode avpf_mode;
|
||||
LinphoneNatPolicy *nat_policy;
|
||||
int quality_reporting_interval;
|
||||
|
||||
bool_t commit;
|
||||
bool_t reg_sendregister;
|
||||
|
|
@ -115,15 +116,14 @@ struct _LinphoneProxyConfig
|
|||
bool_t send_publish;
|
||||
bool_t quality_reporting_enabled;
|
||||
uint8_t avpf_rr_interval;
|
||||
uint8_t quality_reporting_interval;
|
||||
bool_t register_changed;
|
||||
|
||||
time_t deletion_date;
|
||||
LinphonePrivacyMask privacy;
|
||||
/*use to check if server config has changed between edit() and done()*/
|
||||
LinphoneAddress *saved_proxy;
|
||||
LinphoneAddress *saved_identity;
|
||||
bool_t register_changed;
|
||||
bool_t unused[3];
|
||||
|
||||
/*---*/
|
||||
LinphoneAddress *pending_contact; /*use to store previous contact in case of network failure*/
|
||||
LinphoneEvent *presence_publish_event;
|
||||
|
|
@ -131,6 +131,7 @@ struct _LinphoneProxyConfig
|
|||
|
||||
char *refkey;
|
||||
char *sip_etag; /*publish context*/
|
||||
char *conference_factory_uri;
|
||||
};
|
||||
|
||||
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneProxyConfig);
|
||||
|
|
@ -151,11 +152,6 @@ struct _LinphoneAuthInfo
|
|||
char *algorithm;
|
||||
};
|
||||
|
||||
struct _LinphoneChatMessageCharacter {
|
||||
uint32_t value;
|
||||
bool_t has_been_read;
|
||||
};
|
||||
|
||||
struct _LinphoneFriendPresence {
|
||||
char *uri_or_tel;
|
||||
LinphonePresenceModel *presence;
|
||||
|
|
@ -378,6 +374,14 @@ struct _LCCallbackObj {
|
|||
void *_user_data;
|
||||
};
|
||||
|
||||
struct _LinphoneEventCbs {
|
||||
belle_sip_object_t base;
|
||||
void *user_data;
|
||||
LinphoneEventCbsNotifyResponseCb notify_response_cb;
|
||||
};
|
||||
|
||||
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneEventCbs);
|
||||
|
||||
struct _LinphoneEvent{
|
||||
belle_sip_object_t base;
|
||||
LinphoneErrorInfo *ei;
|
||||
|
|
@ -389,6 +393,7 @@ struct _LinphoneEvent{
|
|||
LinphonePublishState publish_state;
|
||||
void *userdata;
|
||||
char *name;
|
||||
LinphoneEventCbs *callbacks;
|
||||
int expires;
|
||||
bool_t terminating;
|
||||
bool_t is_out_of_dialog_op; /*used for out of dialog notify*/
|
||||
|
|
|
|||
|
|
@ -27,8 +27,6 @@ typedef struct StunCandidate StunCandidate;
|
|||
|
||||
typedef struct _PortConfig PortConfig;
|
||||
|
||||
typedef struct _LinphoneChatMessageCharacter LinphoneChatMessageCharacter;
|
||||
|
||||
typedef struct _LinphoneFriendPresence LinphoneFriendPresence;
|
||||
|
||||
typedef struct _LinphoneFriendPhoneNumberSipUri LinphoneFriendPhoneNumberSipUri;
|
||||
|
|
|
|||
131
coreapi/proxy.c
131
coreapi/proxy.c
|
|
@ -20,6 +20,7 @@ Copyright (C) 2000 Simon MORLAT (simon.morlat@linphone.org)
|
|||
|
||||
#include <ctype.h>
|
||||
|
||||
#include <bctoolbox/defs.h>
|
||||
#include "linphone/core_utils.h"
|
||||
#include "linphone/core.h"
|
||||
#include "linphone/lpconfig.h"
|
||||
|
|
@ -113,13 +114,14 @@ static void linphone_proxy_config_init(LinphoneCore* lc, LinphoneProxyConfig *cf
|
|||
const char *dial_prefix = lc ? lp_config_get_default_string(lc->config,"proxy","dial_prefix",NULL) : NULL;
|
||||
const char *identity = lc ? lp_config_get_default_string(lc->config, "proxy", "reg_identity", NULL) : NULL;
|
||||
const char *proxy = lc ? lp_config_get_default_string(lc->config, "proxy", "reg_proxy", NULL) : NULL;
|
||||
const char *route = lc ? lp_config_get_default_string(lc->config, "proxy", "reg_route", NULL) : NULL;
|
||||
const char *route = lc ? lp_config_get_default_string(lc->config, "proxy", "reg_route", NULL) : NULL; //TODO return list instead of string
|
||||
const char *realm = lc ? lp_config_get_default_string(lc->config, "proxy", "realm", NULL) : NULL;
|
||||
const char *quality_reporting_collector = lc ? lp_config_get_default_string(lc->config, "proxy", "quality_reporting_collector", NULL) : NULL;
|
||||
const char *contact_params = lc ? lp_config_get_default_string(lc->config, "proxy", "contact_parameters", NULL) : NULL;
|
||||
const char *contact_uri_params = lc ? lp_config_get_default_string(lc->config, "proxy", "contact_uri_parameters", NULL) : NULL;
|
||||
const char *refkey = lc ? lp_config_get_default_string(lc->config, "proxy", "refkey", NULL) : NULL;
|
||||
const char *nat_policy_ref = lc ? lp_config_get_default_string(lc->config, "proxy", "nat_policy_ref", NULL):NULL;
|
||||
const char *conference_factory_uri = lc ? lp_config_get_default_string(lc->config, "proxy", "conference_factory_uri", NULL):NULL;
|
||||
cfg->lc = lc;
|
||||
cfg->expires = lc ? lp_config_get_default_int(lc->config, "proxy", "reg_expires", 3600) : 3600;
|
||||
cfg->reg_sendregister = lc ? !!lp_config_get_default_int(lc->config, "proxy", "reg_sendregister", 1) : 1;
|
||||
|
|
@ -129,11 +131,11 @@ static void linphone_proxy_config_init(LinphoneCore* lc, LinphoneProxyConfig *cf
|
|||
cfg->identity_address = identity ? linphone_address_new(identity) : NULL;
|
||||
cfg->reg_identity = cfg->identity_address ? linphone_address_as_string(cfg->identity_address) : NULL;
|
||||
cfg->reg_proxy = proxy ? ms_strdup(proxy) : NULL;
|
||||
cfg->reg_route = route ? ms_strdup(route) : NULL;
|
||||
cfg->reg_routes = route ? bctbx_list_append(cfg->reg_routes, ms_strdup(route)) : NULL; //TODO get list directly
|
||||
cfg->realm = realm ? ms_strdup(realm) : NULL;
|
||||
cfg->quality_reporting_enabled = lc ? !!lp_config_get_default_int(lc->config, "proxy", "quality_reporting_enabled", 0) : 0;
|
||||
cfg->quality_reporting_collector = quality_reporting_collector ? ms_strdup(quality_reporting_collector) : NULL;
|
||||
cfg->quality_reporting_interval = lc ? !!lp_config_get_default_int(lc->config, "proxy", "quality_reporting_interval", 0) : 0;
|
||||
cfg->quality_reporting_interval = lc ? lp_config_get_default_int(lc->config, "proxy", "quality_reporting_interval", 0) : 0;
|
||||
cfg->contact_params = contact_params ? ms_strdup(contact_params) : NULL;
|
||||
cfg->contact_uri_params = contact_uri_params ? ms_strdup(contact_uri_params) : NULL;
|
||||
cfg->avpf_mode = lc ? static_cast<LinphoneAVPFMode>(lp_config_get_default_int(lc->config, "proxy", "avpf", LinphoneAVPFDefault)) : LinphoneAVPFDefault;
|
||||
|
|
@ -150,6 +152,7 @@ static void linphone_proxy_config_init(LinphoneCore* lc, LinphoneProxyConfig *cf
|
|||
ms_error("Cannot create default nat policy with ref [%s] for proxy config [%p]",nat_policy_ref,cfg);
|
||||
}
|
||||
}
|
||||
cfg->conference_factory_uri = conference_factory_uri ? ms_strdup(conference_factory_uri) : NULL;
|
||||
}
|
||||
|
||||
LinphoneProxyConfig *linphone_proxy_config_new() {
|
||||
|
|
@ -181,13 +184,18 @@ bool_t linphone_proxy_config_compute_publish_params_hash(LinphoneProxyConfig * c
|
|||
char hash[33];
|
||||
char saved;
|
||||
unsigned long long previous_hash[2];
|
||||
bctbx_list_t *routes_iterator = cfg->reg_routes;
|
||||
previous_hash[0] = cfg->previous_publish_config_hash[0];
|
||||
previous_hash[1] = cfg->previous_publish_config_hash[1];
|
||||
|
||||
source = ms_strcat_printf(source, "%i",cfg->privacy);
|
||||
source=append_linphone_address(cfg->identity_address, source);
|
||||
source=append_string(cfg->reg_proxy,source);
|
||||
source=append_string(cfg->reg_route,source);
|
||||
while (routes_iterator) {
|
||||
const char *route = (const char *)bctbx_list_get_data(routes_iterator);
|
||||
source=append_string(route,source);
|
||||
routes_iterator = bctbx_list_next(routes_iterator);
|
||||
}
|
||||
source=append_string(cfg->realm,source);
|
||||
source = ms_strcat_printf(source, "%i",cfg->publish_expires);
|
||||
source = ms_strcat_printf(source, "%i",cfg->publish);
|
||||
|
|
@ -233,7 +241,7 @@ void _linphone_proxy_config_destroy(LinphoneProxyConfig *cfg){
|
|||
if (cfg->reg_proxy!=NULL) ms_free(cfg->reg_proxy);
|
||||
if (cfg->reg_identity!=NULL) ms_free(cfg->reg_identity);
|
||||
if (cfg->identity_address!=NULL) linphone_address_unref(cfg->identity_address);
|
||||
if (cfg->reg_route!=NULL) ms_free(cfg->reg_route);
|
||||
if (cfg->reg_routes!=NULL) bctbx_list_free_with_data(cfg->reg_routes, ms_free);
|
||||
if (cfg->quality_reporting_collector!=NULL) ms_free(cfg->quality_reporting_collector);
|
||||
if (cfg->ssctx!=NULL) sip_setup_context_free(cfg->ssctx);
|
||||
if (cfg->realm!=NULL) ms_free(cfg->realm);
|
||||
|
|
@ -249,6 +257,8 @@ void _linphone_proxy_config_destroy(LinphoneProxyConfig *cfg){
|
|||
if (cfg->nat_policy != NULL) {
|
||||
linphone_nat_policy_unref(cfg->nat_policy);
|
||||
}
|
||||
if (cfg->conference_factory_uri)
|
||||
bctbx_free(cfg->conference_factory_uri);
|
||||
if (cfg->ei){
|
||||
linphone_error_info_unref(cfg->ei);
|
||||
}
|
||||
|
|
@ -344,9 +354,9 @@ const char *linphone_proxy_config_get_domain(const LinphoneProxyConfig *cfg){
|
|||
|
||||
LinphoneStatus linphone_proxy_config_set_route(LinphoneProxyConfig *cfg, const char *route)
|
||||
{
|
||||
if (cfg->reg_route!=NULL){
|
||||
ms_free(cfg->reg_route);
|
||||
cfg->reg_route=NULL;
|
||||
if (cfg->reg_routes != NULL) {
|
||||
bctbx_list_free_with_data(cfg->reg_routes, ms_free);
|
||||
cfg->reg_routes = NULL;
|
||||
}
|
||||
if (route!=NULL && route[0] !='\0'){
|
||||
SalAddress *addr;
|
||||
|
|
@ -358,7 +368,7 @@ LinphoneStatus linphone_proxy_config_set_route(LinphoneProxyConfig *cfg, const c
|
|||
addr=sal_address_new(tmp);
|
||||
if (addr!=NULL){
|
||||
sal_address_destroy(addr);
|
||||
cfg->reg_route=tmp;
|
||||
cfg->reg_routes = bctbx_list_append(cfg->reg_routes, tmp);
|
||||
return 0;
|
||||
}else{
|
||||
ms_free(tmp);
|
||||
|
|
@ -369,6 +379,37 @@ LinphoneStatus linphone_proxy_config_set_route(LinphoneProxyConfig *cfg, const c
|
|||
}
|
||||
}
|
||||
|
||||
LinphoneStatus linphone_proxy_config_set_routes(LinphoneProxyConfig *cfg, const bctbx_list_t *routes) {
|
||||
if (cfg->reg_routes != NULL) {
|
||||
bctbx_list_free_with_data(cfg->reg_routes, ms_free);
|
||||
cfg->reg_routes = NULL;
|
||||
}
|
||||
bctbx_list_t *iterator = (bctbx_list_t *)routes;
|
||||
while (iterator != NULL) {
|
||||
char *route = (char *)bctbx_list_get_data(iterator);
|
||||
if (route != NULL && route[0] !='\0') {
|
||||
SalAddress *addr;
|
||||
char *tmp;
|
||||
/*try to prepend 'sip:' */
|
||||
if (strstr(route,"sip:") == NULL && strstr(route,"sips:") == NULL) {
|
||||
tmp = ms_strdup_printf("sip:%s",route);
|
||||
} else {
|
||||
tmp = ms_strdup(route);
|
||||
}
|
||||
addr = sal_address_new(tmp);
|
||||
if (addr != NULL) {
|
||||
sal_address_destroy(addr);
|
||||
cfg->reg_routes = bctbx_list_append(cfg->reg_routes, tmp);
|
||||
} else {
|
||||
ms_free(tmp);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
iterator = bctbx_list_next(iterator);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool_t linphone_proxy_config_check(LinphoneCore *lc, LinphoneProxyConfig *cfg){
|
||||
if (cfg->reg_proxy==NULL)
|
||||
return FALSE;
|
||||
|
|
@ -565,7 +606,7 @@ bool_t linphone_proxy_config_quality_reporting_enabled(LinphoneProxyConfig *cfg)
|
|||
}
|
||||
|
||||
void linphone_proxy_config_set_quality_reporting_interval(LinphoneProxyConfig *cfg, int interval) {
|
||||
cfg->quality_reporting_interval = !!interval;
|
||||
cfg->quality_reporting_interval = interval;
|
||||
}
|
||||
|
||||
int linphone_proxy_config_get_quality_reporting_interval(LinphoneProxyConfig *cfg) {
|
||||
|
|
@ -786,6 +827,13 @@ LinphoneAddress* linphone_proxy_config_normalize_sip_uri(LinphoneProxyConfig *pr
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void linphone_proxy_config_set_etag(LinphoneProxyConfig *cfg,const char* sip_etag) {
|
||||
if (cfg->sip_etag) ms_free(cfg->sip_etag);
|
||||
if (sip_etag)
|
||||
cfg->sip_etag = ms_strdup(sip_etag);
|
||||
else
|
||||
cfg->sip_etag = NULL;
|
||||
}
|
||||
/**
|
||||
* Commits modification made to the proxy configuration.
|
||||
**/
|
||||
|
|
@ -827,11 +875,7 @@ LinphoneStatus linphone_proxy_config_done(LinphoneProxyConfig *cfg)
|
|||
ms_message("Publish params have changed on proxy config [%p]",cfg);
|
||||
if (cfg->presence_publish_event) {
|
||||
if (cfg->publish) {
|
||||
const char * sip_etag = linphone_event_get_custom_header(cfg->presence_publish_event, "SIP-ETag");
|
||||
if (sip_etag) {
|
||||
if (cfg->sip_etag) ms_free(cfg->sip_etag);
|
||||
cfg->sip_etag = ms_strdup(sip_etag);
|
||||
}
|
||||
linphone_proxy_config_set_etag(cfg, linphone_event_get_custom_header(cfg->presence_publish_event, "SIP-ETag"));
|
||||
}
|
||||
/*publish is terminated*/
|
||||
linphone_event_terminate(cfg->presence_publish_event);
|
||||
|
|
@ -930,8 +974,13 @@ void _linphone_proxy_config_unpublish(LinphoneProxyConfig *obj) {
|
|||
}
|
||||
}
|
||||
|
||||
const char *linphone_proxy_config_get_route(const LinphoneProxyConfig *cfg){
|
||||
return cfg->reg_route;
|
||||
const char *linphone_proxy_config_get_route(const LinphoneProxyConfig *cfg) {
|
||||
if (cfg->reg_routes) return (const char *)bctbx_list_get_data(cfg->reg_routes);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
const bctbx_list_t* linphone_proxy_config_get_routes(const LinphoneProxyConfig *cfg) {
|
||||
return cfg->reg_routes;
|
||||
}
|
||||
|
||||
const LinphoneAddress *linphone_proxy_config_get_identity_address(const LinphoneProxyConfig *cfg){
|
||||
|
|
@ -1089,7 +1138,7 @@ int linphone_core_get_default_proxy(LinphoneCore *lc, LinphoneProxyConfig **conf
|
|||
return linphone_core_get_default_proxy_config_index(lc);
|
||||
}
|
||||
|
||||
LinphoneProxyConfig * linphone_core_get_default_proxy_config(LinphoneCore *lc) {
|
||||
LinphoneProxyConfig * linphone_core_get_default_proxy_config(const LinphoneCore *lc) {
|
||||
return lc->default_proxy;
|
||||
}
|
||||
|
||||
|
|
@ -1112,8 +1161,8 @@ void linphone_proxy_config_write_to_config_file(LpConfig *config, LinphoneProxyC
|
|||
if (cfg->reg_proxy!=NULL){
|
||||
lp_config_set_string(config,key,"reg_proxy",cfg->reg_proxy);
|
||||
}
|
||||
if (cfg->reg_route!=NULL){
|
||||
lp_config_set_string(config,key,"reg_route",cfg->reg_route);
|
||||
if (cfg->reg_routes != NULL) {
|
||||
lp_config_set_string_list(config, key, "reg_route", cfg->reg_routes);
|
||||
}
|
||||
if (cfg->reg_identity!=NULL){
|
||||
lp_config_set_string(config,key,"reg_identity",cfg->reg_identity);
|
||||
|
|
@ -1147,6 +1196,8 @@ void linphone_proxy_config_write_to_config_file(LpConfig *config, LinphoneProxyC
|
|||
lp_config_set_string(config, key, "nat_policy_ref", cfg->nat_policy->ref);
|
||||
linphone_nat_policy_save_to_config(cfg->nat_policy);
|
||||
}
|
||||
|
||||
lp_config_set_string(config, key, "conference_factory_uri", cfg->conference_factory_uri);
|
||||
}
|
||||
|
||||
|
||||
|
|
@ -1181,7 +1232,10 @@ LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LinphoneCore* lc
|
|||
|
||||
CONFIGURE_STRING_VALUE(cfg,config,key,identity,"reg_identity")
|
||||
CONFIGURE_STRING_VALUE(cfg,config,key,server_addr,"reg_proxy")
|
||||
CONFIGURE_STRING_VALUE(cfg,config,key,route,"reg_route")
|
||||
bctbx_list_t *routes = linphone_config_get_string_list(config, key, "reg_route", NULL);
|
||||
linphone_proxy_config_set_routes(cfg, routes);
|
||||
if (routes)
|
||||
bctbx_list_free_with_data(routes, (bctbx_list_free_func)bctbx_free);
|
||||
|
||||
CONFIGURE_STRING_VALUE(cfg,config,key,realm,"realm")
|
||||
|
||||
|
|
@ -1213,6 +1267,8 @@ LinphoneProxyConfig *linphone_proxy_config_new_from_config_file(LinphoneCore* lc
|
|||
cfg->nat_policy = linphone_core_create_nat_policy_from_config(lc, nat_policy_ref);
|
||||
}
|
||||
|
||||
CONFIGURE_STRING_VALUE(cfg, config, key, conference_factory_uri, "conference_factory_uri");
|
||||
|
||||
return cfg;
|
||||
}
|
||||
|
||||
|
|
@ -1490,8 +1546,35 @@ void linphone_proxy_config_set_nat_policy(LinphoneProxyConfig *cfg, LinphoneNatP
|
|||
}
|
||||
|
||||
void linphone_proxy_config_notify_publish_state_changed(LinphoneProxyConfig *cfg, LinphonePublishState state) {
|
||||
if ((cfg->presence_publish_event != NULL) && ((state == LinphonePublishCleared) || (state == LinphonePublishError))) {
|
||||
linphone_event_unref(cfg->presence_publish_event);
|
||||
cfg->presence_publish_event = NULL;
|
||||
|
||||
if (cfg->presence_publish_event != NULL) {
|
||||
switch (state) {
|
||||
case LinphonePublishCleared:
|
||||
linphone_proxy_config_set_etag(cfg,NULL);
|
||||
BCTBX_NO_BREAK;
|
||||
case LinphonePublishError:
|
||||
linphone_event_unref(cfg->presence_publish_event);
|
||||
cfg->presence_publish_event = NULL;
|
||||
break;
|
||||
case LinphonePublishOk:
|
||||
linphone_proxy_config_set_etag(cfg,linphone_event_get_custom_header(cfg->presence_publish_event, "SIP-ETag"));
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void linphone_proxy_config_set_conference_factory_uri(LinphoneProxyConfig *cfg, const char *uri) {
|
||||
if (cfg->conference_factory_uri) {
|
||||
bctbx_free(cfg->conference_factory_uri);
|
||||
cfg->conference_factory_uri = nullptr;
|
||||
}
|
||||
if (uri)
|
||||
cfg->conference_factory_uri = bctbx_strdup(uri);
|
||||
}
|
||||
|
||||
const char * linphone_proxy_config_get_conference_factory_uri(const LinphoneProxyConfig *cfg) {
|
||||
return cfg->conference_factory_uri;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -24,7 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
extern "C" {
|
||||
#endif
|
||||
|
||||
LinphoneRingtonePlayer* linphone_ringtoneplayer_ios_new();
|
||||
LinphoneRingtonePlayer* linphone_ringtoneplayer_ios_new(void);
|
||||
void linphone_ringtoneplayer_ios_destroy(LinphoneRingtonePlayer* rp);
|
||||
int linphone_ringtoneplayer_ios_start_with_cb(LinphoneRingtonePlayer* rp, const char* ringtone, int loop_pause_ms, LinphoneRingtonePlayerFunc end_of_ringtone, void * user_data);
|
||||
bool_t linphone_ringtoneplayer_ios_is_started(LinphoneRingtonePlayer* rp);
|
||||
|
|
|
|||
|
|
@ -86,7 +86,9 @@ set(C_API_HEADER_FILES
|
|||
c-chat-room.h
|
||||
c-dial-plan.h
|
||||
c-event-log.h
|
||||
c-magic-search.h
|
||||
c-participant.h
|
||||
c-search-result.h
|
||||
c-types.h
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -34,6 +34,8 @@
|
|||
#include "linphone/api/c-dial-plan.h"
|
||||
#include "linphone/api/c-event-log.h"
|
||||
#include "linphone/api/c-participant.h"
|
||||
#include "linphone/api/c-magic-search.h"
|
||||
#include "linphone/api/c-search-result.h"
|
||||
#include "linphone/api/c-types.h"
|
||||
|
||||
#endif // ifndef _L_C_API_H_
|
||||
|
|
|
|||
|
|
@ -159,6 +159,20 @@ LINPHONE_PUBLIC LinphoneCallCbsAckProcessingCb linphone_call_cbs_get_ack_process
|
|||
*/
|
||||
LINPHONE_PUBLIC void linphone_call_cbs_set_ack_processing (LinphoneCallCbs *cbs, LinphoneCallCbsAckProcessingCb cb);
|
||||
|
||||
/**
|
||||
* Get the TMMBR received callback.
|
||||
* @param[in] cbs LinphoneCallCbs object.
|
||||
* @return The current TMMBR received callback.
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneCallCbsTmmbrReceivedCb linphone_call_cbs_get_tmmbr_received(LinphoneCallCbs *cbs);
|
||||
|
||||
/**
|
||||
* Set the TMMBR received callback.
|
||||
* @param[in] cbs LinphoneCallCbs object.
|
||||
* @param[in] cb The TMMBR received callback to be used.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_call_cbs_set_tmmbr_received(LinphoneCallCbs *cbs, LinphoneCallCbsTmmbrReceivedCb cb);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -87,6 +87,14 @@ typedef void (*LinphoneCallCbsTransferStateChangedCb)(LinphoneCall *call, Linpho
|
|||
*/
|
||||
typedef void (*LinphoneCallCbsAckProcessingCb)(LinphoneCall *call, LinphoneHeaders *ack, bool_t is_received);
|
||||
|
||||
/**
|
||||
* Callback for notifying a received TMMBR.
|
||||
* @param call LinphoneCall for which the TMMBR has changed
|
||||
* @param stream_index the index of the current stream
|
||||
* @param tmmbr the value of the received TMMBR
|
||||
*/
|
||||
typedef void (*LinphoneCallCbsTmmbrReceivedCb)(LinphoneCall *call, int stream_index, int tmmbr);
|
||||
|
||||
/**
|
||||
* @}
|
||||
**/
|
||||
|
|
@ -105,7 +113,7 @@ typedef void (*LinphoneCallCbsAckProcessingCb)(LinphoneCall *call, LinphoneHeade
|
|||
* @deprecated Use #LinphoneChatMessageCbsMsgStateChangedCb instead.
|
||||
* @donotwrap
|
||||
*/
|
||||
typedef void (*LinphoneChatMessageStateChangedCb)(LinphoneChatMessage* msg,LinphoneChatMessageState state,void* ud);
|
||||
typedef void (*LinphoneChatMessageStateChangedCb)(LinphoneChatMessage* msg, LinphoneChatMessageState state, void* ud);
|
||||
|
||||
/**
|
||||
* Call back used to notify message delivery status
|
||||
|
|
@ -239,7 +247,7 @@ typedef void (*LinphoneChatRoomCbsConferenceAddressGenerationCb) (LinphoneChatRo
|
|||
* @param[in] cr #LinphoneChatRoom object
|
||||
* @param[in] participantAddr #LinphoneAddress object
|
||||
*/
|
||||
typedef void (*LinphoneChatRoomCbsParticipantDeviceFetchedCb) (LinphoneChatRoom *cr, const LinphoneAddress *participantAddr);
|
||||
typedef void (*LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb) (LinphoneChatRoom *cr, const LinphoneAddress *participantAddr);
|
||||
|
||||
/**
|
||||
* Callback used when a group chat room server is checking participants capabilities.
|
||||
|
|
@ -249,6 +257,27 @@ typedef void (*LinphoneChatRoomCbsParticipantDeviceFetchedCb) (LinphoneChatRoom
|
|||
*/
|
||||
typedef void (*LinphoneChatRoomCbsParticipantsCapabilitiesCheckedCb) (LinphoneChatRoom *cr, const LinphoneAddress *deviceAddr, const bctbx_list_t *participantsAddr);
|
||||
|
||||
/**
|
||||
* Callback used when a group chat room server is subscribing to registration state of a participant.
|
||||
* @param[in] cr #LinphoneChatRoom object
|
||||
* @param[in] participantAddr #LinphoneAddress object
|
||||
*/
|
||||
typedef void (*LinphoneChatRoomCbsParticipantRegistrationSubscriptionRequestedCb) (LinphoneChatRoom *cr, const LinphoneAddress *participantAddr);
|
||||
|
||||
/**
|
||||
* Callback used when a group chat room server is unsubscribing to registration state of a participant.
|
||||
* @param[in] cr #LinphoneChatRoom object
|
||||
* @param[in] participantAddr #LinphoneAddress object
|
||||
*/
|
||||
typedef void (*LinphoneChatRoomCbsParticipantRegistrationUnsubscriptionRequestedCb) (LinphoneChatRoom *cr, const LinphoneAddress *participantAddr);
|
||||
|
||||
/**
|
||||
* Callback used to tell the core whether or not to store the incoming message in db or not using linphone_chat_message_set_to_be_stored().
|
||||
* @param[in] cr #LinphoneChatRoom object
|
||||
* @param[in] msg The #LinphoneChatMessage that is being received
|
||||
*/
|
||||
typedef void (*LinphoneChatRoomCbsShouldChatMessageBeStoredCb) (LinphoneChatRoom *cr, LinphoneChatMessage *msg);
|
||||
|
||||
/**
|
||||
* @}
|
||||
**/
|
||||
|
|
|
|||
|
|
@ -362,6 +362,13 @@ LINPHONE_PUBLIC bool_t linphone_chat_message_has_text_content(const LinphoneChat
|
|||
*/
|
||||
LINPHONE_PUBLIC const char* linphone_chat_message_get_text_content(const LinphoneChatMessage *msg);
|
||||
|
||||
/**
|
||||
* Gets whether or not a file is currently being downloaded or uploaded
|
||||
* @param[in] msg LinphoneChatMessage object
|
||||
* @return true if download or upload is in progress, false otherwise
|
||||
*/
|
||||
LINPHONE_PUBLIC bool_t linphone_chat_message_is_file_transfer_in_progress(LinphoneChatMessage *msg);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -244,18 +244,18 @@ LINPHONE_PUBLIC LinphoneChatRoomCbsConferenceAddressGenerationCb linphone_chat_r
|
|||
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_conference_address_generation (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsConferenceAddressGenerationCb cb);
|
||||
|
||||
/**
|
||||
* Get the participant device getting callback.
|
||||
* Get the participant device fetching callback.
|
||||
* @param[in] cbs #LinphoneChatRoomCbs object
|
||||
* @return The participant device getting callback
|
||||
* @return The participant device fetching callback
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneChatRoomCbsParticipantDeviceFetchedCb linphone_chat_room_cbs_get_participant_device_fetched (const LinphoneChatRoomCbs *cbs);
|
||||
LINPHONE_PUBLIC LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb linphone_chat_room_cbs_get_participant_device_fetch_requested (const LinphoneChatRoomCbs *cbs);
|
||||
|
||||
/**
|
||||
* Set the participant device getting callback.
|
||||
* Set the participant device fetching callback.
|
||||
* @param[in] cbs #LinphoneChatRoomCbs object
|
||||
* @param[in] cb The participant device getting callback to be used
|
||||
* @param[in] cb The participant device fetching callback to be used
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_participant_device_fetched (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantDeviceFetchedCb cb);
|
||||
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_participant_device_fetch_requested (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb cb);
|
||||
|
||||
/**
|
||||
* Get the participants capabilities callback.
|
||||
|
|
@ -271,6 +271,47 @@ LINPHONE_PUBLIC LinphoneChatRoomCbsParticipantsCapabilitiesCheckedCb linphone_ch
|
|||
*/
|
||||
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_participants_capabilities_checked (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantsCapabilitiesCheckedCb cb);
|
||||
|
||||
/**
|
||||
* Get the participant registration subscription callback.
|
||||
* @param[in] cbs LinphoneChatRoomCbs object
|
||||
* @return The participant registration subscription callback
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneChatRoomCbsParticipantRegistrationSubscriptionRequestedCb linphone_chat_room_cbs_get_participant_registration_subscription_requested (const LinphoneChatRoomCbs *cbs);
|
||||
|
||||
/**
|
||||
* Set the participant registration subscription callback.
|
||||
* @param[in] cbs LinphoneChatRoomCbs object
|
||||
* @param[in] cb The participant registration subscription callback to be used
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_participant_registration_subscription_requested (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantRegistrationSubscriptionRequestedCb cb);
|
||||
|
||||
/**
|
||||
* Get the participant registration unsubscription callback.
|
||||
* @param[in] cbs LinphoneChatRoomCbs object
|
||||
* @return The participant registration unsubscription callback
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneChatRoomCbsParticipantRegistrationUnsubscriptionRequestedCb linphone_chat_room_cbs_get_participant_registration_unsubscription_requested (const LinphoneChatRoomCbs *cbs);
|
||||
|
||||
/**
|
||||
* Set the participant registration unsubscription callback.
|
||||
* @param[in] cbs LinphoneChatRoomCbs object
|
||||
* @param[in] cb The participant registration unsubscription callback to be used
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_participant_registration_unsubscription_requested (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantRegistrationUnsubscriptionRequestedCb cb);
|
||||
|
||||
/**
|
||||
* Get the message should be stored callback.
|
||||
* @param[in] cbs LinphoneChatRoomCbs object
|
||||
* @return The message should be stored getting callback
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneChatRoomCbsShouldChatMessageBeStoredCb linphone_chat_room_cbs_get_chat_message_should_be_stored( LinphoneChatRoomCbs *cbs);
|
||||
/**
|
||||
* Set the message should be stored callback.
|
||||
* @param[in] cbs LinphoneChatRoomCbs object
|
||||
* @param[in] cb The message should be stored callback to be used
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_chat_room_cbs_set_chat_message_should_be_stored( LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsShouldChatMessageBeStoredCb cb);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -179,6 +179,23 @@ LINPHONE_PUBLIC bctbx_list_t *linphone_chat_room_get_history (LinphoneChatRoom *
|
|||
*/
|
||||
LINPHONE_PUBLIC bctbx_list_t *linphone_chat_room_get_history_range(LinphoneChatRoom *cr, int begin, int end);
|
||||
|
||||
/**
|
||||
* Gets nb_events most recent chat message events from cr chat room, sorted from oldest to most recent.
|
||||
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation for which events should be retrieved
|
||||
* @param[in] nb_events Number of events to retrieve. 0 means everything.
|
||||
* @return \bctbx_list{LinphoneEventLog}
|
||||
*/
|
||||
LINPHONE_PUBLIC bctbx_list_t *linphone_chat_room_get_history_message_events (LinphoneChatRoom *cr, int nb_events);
|
||||
|
||||
/**
|
||||
* Gets the partial list of chat message events in the given range, sorted from oldest to most recent.
|
||||
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation for which events should be retrieved
|
||||
* @param[in] begin The first event of the range to be retrieved. History most recent event has index 0.
|
||||
* @param[in] end The last event of the range to be retrieved. History oldest event has index of history size - 1
|
||||
* @return \bctbx_list{LinphoneEventLog}
|
||||
*/
|
||||
LINPHONE_PUBLIC bctbx_list_t *linphone_chat_room_get_history_range_message_events (LinphoneChatRoom *cr, int begin, int end);
|
||||
|
||||
/**
|
||||
* Gets nb_events most recent events from cr chat room, sorted from oldest to most recent.
|
||||
* @param[in] cr The #LinphoneChatRoom object corresponding to the conversation for which events should be retrieved
|
||||
|
|
@ -261,11 +278,27 @@ LINPHONE_PUBLIC bool_t linphone_chat_room_lime_available(LinphoneChatRoom *cr);
|
|||
LINPHONE_PUBLIC LinphoneCall *linphone_chat_room_get_call(const LinphoneChatRoom *room);
|
||||
|
||||
/**
|
||||
* Get the #LinphoneChatRoomCbs object associated with the LinphoneChatRoom.
|
||||
* @param[in] cr #LinphoneChatRoom object
|
||||
* @return The #LinphoneChatRoomCbs object associated with the #LinphoneChatRoom
|
||||
* Add a listener in order to be notified of #LinphoneChatRoom events. Once an event is received, registred #LinphoneChatRoomCbs are
|
||||
* invoked sequencially.
|
||||
* @param[in] call #LinphoneChatRoom object to monitor.
|
||||
* @param[in] cbs A #LinphoneChatRoomCbs object holding the callbacks you need. A reference is taken by the #LinphoneChatRoom until you invoke linphone_call_remove_callbacks().
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneChatRoomCbs * linphone_chat_room_get_callbacks (const LinphoneChatRoom *cr);
|
||||
LINPHONE_PUBLIC void linphone_chat_room_add_callbacks(LinphoneChatRoom *cr, LinphoneChatRoomCbs *cbs);
|
||||
|
||||
/**
|
||||
* Remove a listener from a LinphoneChatRoom
|
||||
* @param[in] call LinphoneChatRoom object
|
||||
* @param[in] cbs LinphoneChatRoomCbs object to remove.
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_chat_room_remove_callbacks(LinphoneChatRoom *cr, LinphoneChatRoomCbs *cbs);
|
||||
|
||||
/**
|
||||
* Gets the current LinphoneChatRoomCbs.
|
||||
* This is meant only to be called from a callback to be able to get the user_data associated with the LinphoneChatRoomCbs that is calling the callback.
|
||||
* @param[in] call LinphoneChatRoom object
|
||||
* @return The LinphoneChatRoomCbs that has called the last callback
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneChatRoomCbs *linphone_chat_room_get_current_callbacks(const LinphoneChatRoom *cr);
|
||||
|
||||
/**
|
||||
* Get the state of the chat room.
|
||||
|
|
@ -281,6 +314,13 @@ LINPHONE_PUBLIC LinphoneChatRoomState linphone_chat_room_get_state (const Linpho
|
|||
*/
|
||||
LINPHONE_PUBLIC bool_t linphone_chat_room_has_been_left (const LinphoneChatRoom *cr);
|
||||
|
||||
/**
|
||||
* Return the last updated time for the chat room
|
||||
* @param[in] cr LinphoneChatRoom object
|
||||
* @return the last updated time
|
||||
*/
|
||||
LINPHONE_PUBLIC time_t linphone_chat_room_get_last_update_time(const LinphoneChatRoom *cr);
|
||||
|
||||
/**
|
||||
* Add a participant to a chat room. This may fail if this type of chat room does not handle participants.
|
||||
* Use linphone_chat_room_can_handle_participants() to know if this chat room handles participants.
|
||||
|
|
@ -414,13 +454,22 @@ LINPHONE_PUBLIC void linphone_chat_room_set_conference_address (LinphoneChatRoom
|
|||
|
||||
/**
|
||||
* Set the participant device. This function needs to be called from the
|
||||
* #LinphoneChatRoomCbsParticipantDeviceFetchedCb callback and only there.
|
||||
* #LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb callback and only there.
|
||||
* @param[in] cr A #LinphoneChatRoom object
|
||||
* @param[in] partAddr The participant address
|
||||
* @param[in] partDevices \bctbx_list{LinphoneAddress} list of the participant devices to be used by the group chat room
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_chat_room_set_participant_devices (LinphoneChatRoom *cr, const LinphoneAddress *partAddr, const bctbx_list_t *partDevices);
|
||||
|
||||
/**
|
||||
* Add a participant device.
|
||||
* This is to used if a new device registers itself after the chat room creation.
|
||||
* @param[in] cr A #LinphoneChatRoom object
|
||||
* @param[in] participantAddress The address of the participant for which a new device is to be added
|
||||
* @param[in] deviceAddress The address of the new device to be added
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_chat_room_add_participant_device (LinphoneChatRoom *cr, const LinphoneAddress *participantAddress, const LinphoneAddress *deviceAddress);
|
||||
|
||||
/**
|
||||
* Set the participant device. This function needs to be called from the
|
||||
* #LinphoneChatRoomCbsParticipantsCapabilitiesCheckedCb callback and only there.
|
||||
|
|
@ -437,14 +486,6 @@ LINPHONE_PUBLIC void linphone_chat_room_add_compatible_participants (LinphoneCha
|
|||
**/
|
||||
LINPHONE_PUBLIC LINPHONE_DEPRECATED LinphoneCore* linphone_chat_room_get_lc(const LinphoneChatRoom *cr);
|
||||
|
||||
/**
|
||||
* Destroy a LinphoneChatRoom.
|
||||
* @param cr #LinphoneChatRoom object
|
||||
* @deprecated Use linphone_chat_room_unref() instead.
|
||||
* @donotwrap
|
||||
*/
|
||||
LINPHONE_PUBLIC LINPHONE_DEPRECATED void linphone_chat_room_destroy(LinphoneChatRoom *cr);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
|||
143
include/linphone/api/c-magic-search.h
Normal file
143
include/linphone/api/c-magic-search.h
Normal file
|
|
@ -0,0 +1,143 @@
|
|||
/*
|
||||
* c-magic-search.h
|
||||
* Copyright (C) 2010-2018 Belledonne Communications SARL
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _L_C_MAGIC_SEARCH_H_
|
||||
#define _L_C_MAGIC_SEARCH_H_
|
||||
|
||||
#include "linphone/api/c-types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup misc
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Constructs a LinphoneMagicSearch object
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneMagicSearch *linphone_magic_search_new(LinphoneCore *lc);
|
||||
|
||||
/**
|
||||
* Increment reference count of LinphoneMagicSearch object.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneMagicSearch *linphone_magic_search_ref(LinphoneMagicSearch *magicSearch);
|
||||
|
||||
/**
|
||||
* Decrement reference count of LinphoneMagicSearch object. When dropped to zero, memory is freed.
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_magic_search_unref(LinphoneMagicSearch *magicSearch);
|
||||
|
||||
/**
|
||||
* Set the minimum value used to calculate the weight in search
|
||||
* @param[in] weight minimum weight
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_magic_search_set_min_weight(LinphoneMagicSearch *magicSearch, const unsigned int weight);
|
||||
|
||||
/**
|
||||
* @return the minimum value used to calculate the weight in search
|
||||
**/
|
||||
LINPHONE_PUBLIC unsigned int linphone_magic_search_get_min_weight(const LinphoneMagicSearch *magicSearch);
|
||||
|
||||
/**
|
||||
* Set the maximum value used to calculate the weight in search
|
||||
* @param[in] weight maximum weight
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_magic_search_set_max_weight(LinphoneMagicSearch *magicSearch, const unsigned int weight);
|
||||
|
||||
/**
|
||||
* @return the maximum value used to calculate the weight in search
|
||||
**/
|
||||
LINPHONE_PUBLIC unsigned int linphone_magic_search_get_max_weight(const LinphoneMagicSearch *magicSearch);
|
||||
|
||||
/**
|
||||
* @return the delimiter used to find matched filter word
|
||||
**/
|
||||
LINPHONE_PUBLIC const char *linphone_magic_search_get_delimiter(const LinphoneMagicSearch *magicSearch);
|
||||
|
||||
/**
|
||||
* Set the delimiter used to find matched filter word
|
||||
* @param[in] delimiter delimiter (example "-_.,")
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_magic_search_set_delimiter(LinphoneMagicSearch *magicSearch, const char *delimiter);
|
||||
|
||||
/**
|
||||
* @return if the delimiter search is used
|
||||
**/
|
||||
LINPHONE_PUBLIC bool_t linphone_magic_search_get_use_delimiter(LinphoneMagicSearch *magicSearch);
|
||||
|
||||
/**
|
||||
* Enable or disable the delimiter in search
|
||||
* @param[in] enable
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_magic_search_set_use_delimiter(LinphoneMagicSearch *magicSearch, bool_t enable);
|
||||
|
||||
/**
|
||||
* @return the number of the maximum SearchResult which will be return
|
||||
**/
|
||||
LINPHONE_PUBLIC unsigned int linphone_magic_search_get_search_limit(const LinphoneMagicSearch *magicSearch);
|
||||
|
||||
/**
|
||||
* Set the number of the maximum SearchResult which will be return
|
||||
* @param[in] limit
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_magic_search_set_search_limit(LinphoneMagicSearch *magicSearch, const unsigned int limit);
|
||||
|
||||
/**
|
||||
* @return if the search is limited
|
||||
**/
|
||||
LINPHONE_PUBLIC bool_t linphone_magic_search_get_limited_search(const LinphoneMagicSearch *magicSearch);
|
||||
|
||||
/**
|
||||
* Enable or disable the limited search
|
||||
* @param[in] limited
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_magic_search_set_limited_search(LinphoneMagicSearch *magicSearch, const bool_t limited);
|
||||
|
||||
/**
|
||||
* Reset the cache to begin a new search
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_magic_search_reset_search_cache(LinphoneMagicSearch *magicSearch);
|
||||
|
||||
/**
|
||||
* Create a sorted list of SearchResult from SipUri, Contact name,
|
||||
* Contact displayname, Contact phone number, which match with a filter word
|
||||
* The last item list will be an address formed with "filter" if a proxy config exist
|
||||
* During the first search, a cache is created and used for the next search
|
||||
* Use linphone_magic_search_reset_search_cache() to begin a new search
|
||||
* @param[in] filter word we search
|
||||
* @param[in] withDomain domain which we want to search only
|
||||
* - "" for searching in all contact
|
||||
* - "*" for searching in contact with sip SipUri
|
||||
* - "yourdomain" for searching in contact from "yourdomain" domain
|
||||
* @return sorted list of \bctbx_list{LinphoneSearchResult}
|
||||
**/
|
||||
LINPHONE_PUBLIC bctbx_list_t* linphone_magic_search_get_contact_list_from_filter(LinphoneMagicSearch *magicSearch, const char *filter, const char *withDomain);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _L_C_MAGIC_SEARCH_H_
|
||||
67
include/linphone/api/c-search-result.h
Normal file
67
include/linphone/api/c-search-result.h
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
/*
|
||||
* c-search-result.h
|
||||
* Copyright (C) 2010-2018 Belledonne Communications SARL
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _L_C_SEARCH_RESULT_H_
|
||||
#define _L_C_SEARCH_RESULT_H_
|
||||
|
||||
#include "linphone/api/c-types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* @addtogroup misc
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Increment reference count of LinphoneSearchResult object.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneSearchResult *linphone_search_result_ref(LinphoneSearchResult *searchResult);
|
||||
|
||||
/**
|
||||
* Decrement reference count of LinphoneSearchResult object. When dropped to zero, memory is freed.
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_search_result_unref(LinphoneSearchResult *searchResult);
|
||||
|
||||
/**
|
||||
* @return LinphoneFriend associed
|
||||
**/
|
||||
LINPHONE_PUBLIC const LinphoneFriend* linphone_search_result_get_friend(const LinphoneSearchResult *searchResult);
|
||||
|
||||
/**
|
||||
* @return LinphoneAddress associed
|
||||
**/
|
||||
LINPHONE_PUBLIC const LinphoneAddress* linphone_search_result_get_address(const LinphoneSearchResult *searchResult);
|
||||
|
||||
/**
|
||||
* @return the result weight
|
||||
**/
|
||||
LINPHONE_PUBLIC unsigned int linphone_search_result_get_weight(const LinphoneSearchResult *searchResult);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif // _L_C_SEARCH_RESULT_H_
|
||||
|
|
@ -151,11 +151,22 @@ typedef struct _LinphoneEventLog LinphoneEventLog;
|
|||
typedef struct _LinphoneDialPlan LinphoneDialPlan;
|
||||
|
||||
/**
|
||||
* The #LinphoneParticipant object represents a participant of a conference.
|
||||
* A #LinphoneMagicSearch is used to do specifics searchs
|
||||
* @ingroup misc
|
||||
**/
|
||||
typedef struct _LinphoneMagicSearch LinphoneMagicSearch;
|
||||
|
||||
/**
|
||||
* @ingroup misc
|
||||
**/
|
||||
typedef struct _LinphoneParticipant LinphoneParticipant;
|
||||
|
||||
/**
|
||||
* The LinphoneSearchResult object represents a result of a search
|
||||
* @ingroup misc
|
||||
**/
|
||||
typedef struct _LinphoneSearchResult LinphoneSearchResult;
|
||||
|
||||
// =============================================================================
|
||||
// C Enums.
|
||||
// =============================================================================
|
||||
|
|
|
|||
|
|
@ -90,12 +90,19 @@ LINPHONE_PUBLIC float linphone_call_log_get_quality(const LinphoneCallLog *cl);
|
|||
**/
|
||||
LINPHONE_PUBLIC const char * linphone_call_log_get_ref_key(const LinphoneCallLog *cl);
|
||||
|
||||
/**
|
||||
* Get the local address (that is from or to depending on call direction)
|
||||
* @param[in] cl LinphoneCallLog object
|
||||
* @return The local address of the call
|
||||
*/
|
||||
LINPHONE_PUBLIC const LinphoneAddress *linphone_call_log_get_local_address(const LinphoneCallLog *cl);
|
||||
|
||||
/**
|
||||
* Get the remote address (that is from or to depending on call direction).
|
||||
* @param[in] cl #LinphoneCallLog object
|
||||
* @return The remote address of the call.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneAddress * linphone_call_log_get_remote_address(const LinphoneCallLog *cl);
|
||||
LINPHONE_PUBLIC const LinphoneAddress * linphone_call_log_get_remote_address(const LinphoneCallLog *cl);
|
||||
|
||||
/**
|
||||
* Get the RTP statistics computed by the remote end and sent back via RTCP.
|
||||
|
|
@ -199,6 +206,23 @@ LINPHONE_PUBLIC LinphoneCallLog * linphone_call_log_ref(LinphoneCallLog *cl);
|
|||
**/
|
||||
LINPHONE_PUBLIC void linphone_call_log_unref(LinphoneCallLog *cl);
|
||||
|
||||
/**
|
||||
* Creates a fake LinphoneCallLog.
|
||||
* @param[in] lc LinphoneCore object
|
||||
* @param[in] from LinphoneAddress of caller
|
||||
* @param[in] to LinphoneAddress of callee
|
||||
* @param[in] dir LinphoneCallDir of call
|
||||
* @param[in] duration call length in seconds
|
||||
* @param[in] start_time timestamp of call start time
|
||||
* @param[in] connected_time timestamp of call connection
|
||||
* @param[in] status LinphoneCallStatus of call
|
||||
* @param[in] video_enabled whether video was enabled or not for this call
|
||||
* @param[in] quality call quality
|
||||
* @return LinphoneCallLog object
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneCallLog *linphone_core_create_call_log(LinphoneCore *lc, LinphoneAddress *from, LinphoneAddress *to, LinphoneCallDir dir,
|
||||
int duration, time_t start_time, time_t connected_time, LinphoneCallStatus status, bool_t video_enabled, float quality);
|
||||
|
||||
|
||||
/*******************************************************************************
|
||||
* DEPRECATED *
|
||||
|
|
|
|||
|
|
@ -448,6 +448,21 @@ typedef LinphoneCoreCbsPublishStateChangedCb LinphoneCorePublishStateChangedCb;
|
|||
* @}
|
||||
**/
|
||||
|
||||
/**
|
||||
* @addtogroup event_api
|
||||
* @{
|
||||
*/
|
||||
|
||||
/**
|
||||
* Callback used to notify the response to a sent NOTIFY
|
||||
* @param ev The LinphoneEvent object that has sent the NOTIFY and for which we received a response
|
||||
**/
|
||||
typedef void (*LinphoneEventCbsNotifyResponseCb)(const LinphoneEvent *ev);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
||||
/**
|
||||
* @addtogroup buddy_list
|
||||
* @{
|
||||
|
|
|
|||
|
|
@ -115,6 +115,14 @@ LINPHONE_PUBLIC LinphonePlayer *linphone_core_create_local_player(LinphoneCore *
|
|||
**/
|
||||
LINPHONE_PUBLIC LinphoneInfoMessage *linphone_core_create_info_message(LinphoneCore*lc);
|
||||
|
||||
/**
|
||||
* Create a #LinphoneMagicSearch object.
|
||||
* @param[in] lc #LinphoneCore object
|
||||
* @return The create #LinphoneMagicSearch object
|
||||
* @ingroup misc
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneMagicSearch *linphone_core_create_magic_search(LinphoneCore *lc);
|
||||
|
||||
/**
|
||||
* Checks if a new version of the application is available.
|
||||
* @param lc #LinphoneCore object
|
||||
|
|
@ -2009,7 +2017,7 @@ LINPHONE_PUBLIC LINPHONE_DEPRECATED int linphone_core_get_default_proxy(Linphone
|
|||
* @param[in] lc #LinphoneCore object
|
||||
* @return The default proxy configuration.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneProxyConfig * linphone_core_get_default_proxy_config(LinphoneCore *lc);
|
||||
LINPHONE_PUBLIC LinphoneProxyConfig * linphone_core_get_default_proxy_config(const LinphoneCore *lc);
|
||||
|
||||
/**
|
||||
* Sets the default proxy.
|
||||
|
|
@ -4244,20 +4252,6 @@ LINPHONE_PUBLIC LinphoneStatus linphone_core_stop_conference_recording(LinphoneC
|
|||
*/
|
||||
LINPHONE_PUBLIC LinphoneConference *linphone_core_get_conference(LinphoneCore *lc);
|
||||
|
||||
/**
|
||||
* Set the conference factory uri.
|
||||
* @param[in] lc A #LinphoneCore object
|
||||
* @param[in] uri The uri of the conference factory
|
||||
*/
|
||||
void linphone_core_set_conference_factory_uri(LinphoneCore *lc, const char *uri);
|
||||
|
||||
/**
|
||||
* Get the conference factory uri.
|
||||
* @param[in] lc A #LinphoneCore object
|
||||
* @return The uri of the conference factory
|
||||
*/
|
||||
const char * linphone_core_get_conference_factory_uri(const LinphoneCore *lc);
|
||||
|
||||
/**
|
||||
* Enable the conference server feature. This has the effect to listen of the conference factory uri
|
||||
* to create new conferences when receiving INVITE messages there.
|
||||
|
|
|
|||
|
|
@ -20,6 +20,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
|||
#ifndef LINPHONE_EVENT_H_
|
||||
#define LINPHONE_EVENT_H_
|
||||
|
||||
#include "linphone/callbacks.h"
|
||||
#include "linphone/types.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
|
@ -203,6 +204,55 @@ LINPHONE_PUBLIC const LinphoneAddress *linphone_event_get_remote_contact (const
|
|||
**/
|
||||
LINPHONE_PUBLIC LinphoneCore *linphone_event_get_core(const LinphoneEvent *lev);
|
||||
|
||||
/**
|
||||
* Get the LinphoneEventCbs object associated with a LinphoneEvent.
|
||||
* @param[in] ev LinphoneEvent object
|
||||
* @return The LinphoneEventCbs object associated with the LinphoneEvent.
|
||||
**/
|
||||
|
||||
LINPHONE_PUBLIC LinphoneEventCbs *linphone_event_get_callbacks(const LinphoneEvent *ev);
|
||||
|
||||
/**
|
||||
* Acquire a reference to a LinphoneEventCbs object.
|
||||
* @param[in] cbs LinphoneEventCbs object.
|
||||
* @return The same LinphoneEventCbs object.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneEventCbs *linphone_event_cbs_ref(LinphoneEventCbs *cbs);
|
||||
|
||||
/**
|
||||
* Release a reference to a LinphoneEventCbs object.
|
||||
* @param[in] cbs LinphoneEventCbs object.
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_event_cbs_unref(LinphoneEventCbs *cbs);
|
||||
|
||||
/**
|
||||
* Retrieve the user pointer associated with a LinphoneEventCbs object.
|
||||
* @param[in] cbs LinphoneEventCbs object.
|
||||
* @return The user pointer associated with the LinphoneEventCbs object.
|
||||
**/
|
||||
LINPHONE_PUBLIC void *linphone_event_cbs_get_user_data(const LinphoneEventCbs *cbs);
|
||||
|
||||
/**
|
||||
* Assign a user pointer to a LinphoneEventCbs object.
|
||||
* @param[in] cbs LinphoneEventCbs object.
|
||||
* @param[in] ud The user pointer to associate with the LinphoneEventCbs object.
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_event_cbs_set_user_data(LinphoneEventCbs *cbs, void *ud);
|
||||
|
||||
/**
|
||||
* Get the notify response callback.
|
||||
* @param[in] cbs LinphoneEventCbs object.
|
||||
* @return The current notify response callback.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneEventCbsNotifyResponseCb linphone_event_cbs_get_notify_response(const LinphoneEventCbs *cbs);
|
||||
|
||||
/**
|
||||
* Set the notify response callback.
|
||||
* @param[in] cbs LinphoneEventCbs object.
|
||||
* @param[in] cb The notify response callback to be used.
|
||||
**/
|
||||
LINPHONE_PUBLIC void linphone_event_cbs_set_notify_response(LinphoneEventCbs *cbs, LinphoneEventCbsNotifyResponseCb cb);
|
||||
|
||||
/**
|
||||
* @}
|
||||
**/
|
||||
|
|
|
|||
|
|
@ -224,6 +224,13 @@ LINPHONE_PUBLIC LinphoneAuthInfo *linphone_factory_create_auth_info(const Linpho
|
|||
*/
|
||||
LINPHONE_PUBLIC LinphoneCallCbs * linphone_factory_create_call_cbs(const LinphoneFactory *factory);
|
||||
|
||||
/**
|
||||
* Create a LinphoneChatRoomCbs object that holds callbacks for events happening on a chat room.
|
||||
* @param[in] factory LinphoneFactory singletion object
|
||||
* @return A new LinphoneChatRoomCbs object
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneChatRoomCbs * linphone_factory_create_chat_room_cbs(const LinphoneFactory *factory);
|
||||
|
||||
/**
|
||||
* Create an empty #LinphoneVcard.
|
||||
* @return a new #LinphoneVcard.
|
||||
|
|
|
|||
|
|
@ -116,7 +116,7 @@ LINPHONE_PUBLIC void linphone_friend_add_phone_number(LinphoneFriend *lf, const
|
|||
* @param lf #LinphoneFriend object
|
||||
* @return \bctbx_list{const char *}
|
||||
*/
|
||||
LINPHONE_PUBLIC bctbx_list_t* linphone_friend_get_phone_numbers(LinphoneFriend *lf);
|
||||
LINPHONE_PUBLIC bctbx_list_t* linphone_friend_get_phone_numbers(const LinphoneFriend *lf);
|
||||
|
||||
/**
|
||||
* Removes a phone number in this friend
|
||||
|
|
@ -306,7 +306,7 @@ LINPHONE_PUBLIC LinphoneCore *linphone_friend_get_core(const LinphoneFriend *fr)
|
|||
* Returns the vCard object associated to this friend, if any
|
||||
* @param[in] fr #LinphoneFriend object
|
||||
*/
|
||||
LINPHONE_PUBLIC LinphoneVcard* linphone_friend_get_vcard(LinphoneFriend *fr);
|
||||
LINPHONE_PUBLIC LinphoneVcard* linphone_friend_get_vcard(const LinphoneFriend *fr);
|
||||
|
||||
/**
|
||||
* Binds a vCard object to a friend
|
||||
|
|
|
|||
|
|
@ -99,6 +99,16 @@ LINPHONE_PUBLIC LinphoneStatus linphone_proxy_config_set_identity_address(Linpho
|
|||
**/
|
||||
LINPHONE_PUBLIC LinphoneStatus linphone_proxy_config_set_route(LinphoneProxyConfig *cfg, const char *route);
|
||||
|
||||
/**
|
||||
* Sets a list of SIP route.
|
||||
* When a route is set, all outgoing calls will go to the route's destination if this proxy
|
||||
* is the default one (see linphone_core_set_default_proxy() ).
|
||||
* @param[in] cfg the #LinphoneProxyConfig
|
||||
* @param[in] routes A \bctbx_list{const char *} of routes
|
||||
* @return -1 if routes are invalid, 0 otherwise.
|
||||
**/
|
||||
LINPHONE_PUBLIC LinphoneStatus linphone_proxy_config_set_routes(LinphoneProxyConfig *cfg, const bctbx_list_t *routes);
|
||||
|
||||
/**
|
||||
* Sets the registration expiration time in seconds.
|
||||
**/
|
||||
|
|
@ -257,9 +267,17 @@ LINPHONE_PUBLIC void linphone_proxy_config_set_realm(LinphoneProxyConfig *cfg, c
|
|||
|
||||
/**
|
||||
* @return the route set for this proxy configuration.
|
||||
* @deprecated Use linphone_proxy_config_get_routes() instead.
|
||||
**/
|
||||
LINPHONE_PUBLIC const char *linphone_proxy_config_get_route(const LinphoneProxyConfig *cfg);
|
||||
|
||||
/**
|
||||
* Gets the list of the routes set for this proxy config.
|
||||
* @param[in] cfg #LinphoneProxyConfig object.
|
||||
* @return \bctbx_list{const char *} the list of routes.
|
||||
*/
|
||||
LINPHONE_PUBLIC const bctbx_list_t* linphone_proxy_config_get_routes(const LinphoneProxyConfig *cfg);
|
||||
|
||||
/**
|
||||
* @return the SIP identity that belongs to this proxy configuration.
|
||||
**/
|
||||
|
|
@ -585,6 +603,20 @@ LINPHONE_PUBLIC LinphoneNatPolicy * linphone_proxy_config_get_nat_policy(const L
|
|||
*/
|
||||
LINPHONE_PUBLIC void linphone_proxy_config_set_nat_policy(LinphoneProxyConfig *cfg, LinphoneNatPolicy *policy);
|
||||
|
||||
/**
|
||||
* Set the conference factory uri.
|
||||
* @param[in] cfg A #LinphoneProxyConfig object
|
||||
* @param[in] uri The uri of the conference factory
|
||||
*/
|
||||
void linphone_proxy_config_set_conference_factory_uri(LinphoneProxyConfig *cfg, const char *uri);
|
||||
|
||||
/**
|
||||
* Get the conference factory uri.
|
||||
* @param[in] cfg A #LinphoneProxyConfig object
|
||||
* @return The uri of the conference factory
|
||||
*/
|
||||
const char * linphone_proxy_config_get_conference_factory_uri(const LinphoneProxyConfig *cfg);
|
||||
|
||||
/**
|
||||
* @}
|
||||
*/
|
||||
|
|
|
|||
|
|
@ -420,6 +420,12 @@ typedef struct _LinphoneErrorInfo LinphoneErrorInfo;
|
|||
**/
|
||||
typedef struct _LinphoneEvent LinphoneEvent;
|
||||
|
||||
/**
|
||||
* An object to handle the callbacks for handling the LinphoneEvent operations.
|
||||
* @ingroup event_api
|
||||
**/
|
||||
typedef struct _LinphoneEventCbs LinphoneEventCbs;
|
||||
|
||||
/**
|
||||
* #LinphoneFactory is a singleton object devoted to the creation of all the object
|
||||
* of Liblinphone that cannot created by #LinphoneCore or #LinphoneCore itself.
|
||||
|
|
|
|||
|
|
@ -138,10 +138,10 @@ private:
|
|||
return (mMask & value) == value && (value || mMask == 0);
|
||||
}
|
||||
|
||||
// On CentOs 7 GCC 4.8.5 have issue with array-bounds
|
||||
// On CentOs 7 GCC 4.8.5 have issue with array-bounds.
|
||||
#if __GNUC__ == 4 && __GNUC_MINOR__ == 8 && __GNUC_PATCHLEVEL__ == 5
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Warray-bounds"
|
||||
#pragma GCC diagnostic push
|
||||
#pragma GCC diagnostic ignored "-Warray-bounds"
|
||||
#endif
|
||||
|
||||
static constexpr StorageType init (
|
||||
|
|
@ -152,7 +152,7 @@ private:
|
|||
}
|
||||
|
||||
#if __GNUC__ == 4 && __GNUC_MINOR__ == 8 && __GNUC_PATCHLEVEL__ == 5
|
||||
#pragma GCC diagnostic pop
|
||||
#pragma GCC diagnostic pop
|
||||
#endif
|
||||
|
||||
StorageType mMask;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,10 @@
|
|||
|
||||
// =============================================================================
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Namespace.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#ifdef __cplusplus
|
||||
#define LINPHONE_BEGIN_NAMESPACE namespace LinphonePrivate {
|
||||
#define LINPHONE_END_NAMESPACE }
|
||||
|
|
@ -75,10 +79,10 @@ LINPHONE_BEGIN_NAMESPACE
|
|||
// Debug.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void l_assert (const char *condition, const char *file, int line);
|
||||
void lAssert (const char *condition, const char *file, int line);
|
||||
|
||||
#ifdef DEBUG
|
||||
#define L_ASSERT(CONDITION) ((CONDITION) ? static_cast<void>(0) : LinphonePrivate::l_assert(#CONDITION, __FILE__, __LINE__))
|
||||
#define L_ASSERT(CONDITION) ((CONDITION) ? static_cast<void>(0) : LinphonePrivate::lAssert(#CONDITION, __FILE__, __LINE__))
|
||||
#else
|
||||
#define L_ASSERT(CONDITION) static_cast<void>(false && (CONDITION))
|
||||
#endif
|
||||
|
|
@ -100,16 +104,28 @@ void l_assert (const char *condition, const char *file, int line);
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Define an integer version like: 0xXXYYZZ, XX=MAJOR, YY=MINOR, and ZZ=PATCH.
|
||||
#define L_VERSION(MAJOR, MINOR, PATCH) (((MAJOR) << 16) | ((MINOR) << 8) | (PATCH))
|
||||
constexpr unsigned int makeVersion (unsigned int major, unsigned int minor, unsigned int patch) {
|
||||
return ((major << 16) | (minor << 8) | patch);
|
||||
}
|
||||
|
||||
// Not available in C++11...
|
||||
template<typename T, typename... Args>
|
||||
std::unique_ptr<T> make_unique(Args && ...args) {
|
||||
std::unique_ptr<T> makeUnique(Args && ...args) {
|
||||
return std::unique_ptr<T>(new T(std::forward<Args>(args)...));
|
||||
}
|
||||
|
||||
#define L_AUTO_RETURN(VALUE) -> decltype(VALUE) { return VALUE; }
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Data access.
|
||||
// Class tools.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#define L_DISABLE_COPY(CLASS) \
|
||||
CLASS (const CLASS &) = delete; \
|
||||
CLASS &operator= (const CLASS &) = delete;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// PImpl tools.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class BaseObject;
|
||||
|
|
@ -119,34 +135,68 @@ class ClonableObjectPrivate;
|
|||
class Object;
|
||||
class ObjectPrivate;
|
||||
|
||||
namespace Private {
|
||||
template<typename T>
|
||||
using BetterPrivateAncestor = typename std::conditional<
|
||||
std::is_base_of<BaseObject, T>::value,
|
||||
BaseObject,
|
||||
typename std::conditional<
|
||||
std::is_base_of<ClonableObject, T>::value,
|
||||
ClonableObject,
|
||||
T
|
||||
>::type
|
||||
>::type;
|
||||
|
||||
// Generic public helper.
|
||||
template<
|
||||
typename R,
|
||||
typename P,
|
||||
typename C
|
||||
>
|
||||
constexpr R *getPublicHelper (P *object, const C *) {
|
||||
return static_cast<R *>(object);
|
||||
}
|
||||
|
||||
// Generic public helper. Deal with shared data.
|
||||
template<
|
||||
typename R,
|
||||
typename P,
|
||||
typename C
|
||||
>
|
||||
inline R *getPublicHelper (const P &objectSet, const C *) {
|
||||
auto it = objectSet.cbegin();
|
||||
L_ASSERT(it != objectSet.cend());
|
||||
return static_cast<R *>(*it);
|
||||
}
|
||||
|
||||
template<typename T, typename U>
|
||||
struct AddConstMirror {
|
||||
typedef U type;
|
||||
};
|
||||
|
||||
template<typename T, typename U>
|
||||
struct AddConstMirror<const T, U> {
|
||||
typedef typename std::add_const<U>::type type;
|
||||
};
|
||||
}
|
||||
|
||||
#define L_INTERNAL_CHECK_OBJECT_INHERITANCE(CLASS) \
|
||||
static_assert( \
|
||||
!(std::is_base_of<BaseObject, CLASS>::value && std::is_base_of<ClonableObject, CLASS>::value), \
|
||||
"Multiple inheritance between BaseObject and ClonableObject is not allowed." \
|
||||
);
|
||||
|
||||
#define L_INTERNAL_GET_BETTER_PRIVATE_ANCESTOR(CLASS) \
|
||||
std::conditional< \
|
||||
std::is_base_of<BaseObject, CLASS>::value, \
|
||||
BaseObject, \
|
||||
std::conditional< \
|
||||
std::is_base_of<ClonableObject, CLASS>::value, \
|
||||
ClonableObject, \
|
||||
CLASS \
|
||||
>::type \
|
||||
>::type
|
||||
|
||||
#define L_INTERNAL_DECLARE_PRIVATE(CLASS) \
|
||||
inline CLASS ## Private *getPrivate () { \
|
||||
L_INTERNAL_CHECK_OBJECT_INHERITANCE(CLASS); \
|
||||
return reinterpret_cast<CLASS ## Private *>( \
|
||||
L_INTERNAL_GET_BETTER_PRIVATE_ANCESTOR(CLASS)::mPrivate \
|
||||
LinphonePrivate::Private::BetterPrivateAncestor<CLASS>::mPrivate \
|
||||
); \
|
||||
} \
|
||||
inline const CLASS ## Private *getPrivate () const { \
|
||||
L_INTERNAL_CHECK_OBJECT_INHERITANCE(CLASS); \
|
||||
return reinterpret_cast<const CLASS ## Private *>( \
|
||||
L_INTERNAL_GET_BETTER_PRIVATE_ANCESTOR(CLASS)::mPrivate \
|
||||
LinphonePrivate::Private::BetterPrivateAncestor<CLASS>::mPrivate \
|
||||
); \
|
||||
} \
|
||||
friend class CLASS ## Private; \
|
||||
|
|
@ -162,61 +212,25 @@ class ObjectPrivate;
|
|||
friend class Tester;
|
||||
#endif
|
||||
|
||||
// Generic public helper.
|
||||
template<
|
||||
typename R,
|
||||
typename P,
|
||||
typename C
|
||||
>
|
||||
constexpr R *getPublicHelper (P *object, const C *) {
|
||||
return static_cast<R *>(object);
|
||||
}
|
||||
|
||||
// Generic public helper. Deal with shared data.
|
||||
template<
|
||||
typename R,
|
||||
typename P,
|
||||
typename C
|
||||
>
|
||||
inline R *getPublicHelper (const P &objectSet, const C *) {
|
||||
auto it = objectSet.cbegin();
|
||||
L_ASSERT(it != objectSet.cend());
|
||||
return static_cast<R *>(*it);
|
||||
}
|
||||
|
||||
#define L_DECLARE_PUBLIC(CLASS) \
|
||||
inline CLASS *getPublic () { \
|
||||
return getPublicHelper<CLASS>(mPublic, this); \
|
||||
CLASS *getPublic () { \
|
||||
return LinphonePrivate::Private::getPublicHelper<CLASS>(mPublic, this); \
|
||||
} \
|
||||
inline const CLASS *getPublic () const { \
|
||||
return getPublicHelper<const CLASS>(mPublic, this); \
|
||||
const CLASS *getPublic () const { \
|
||||
return LinphonePrivate::Private::getPublicHelper<const CLASS>(mPublic, this); \
|
||||
} \
|
||||
friend class CLASS;
|
||||
|
||||
#define L_DISABLE_COPY(CLASS) \
|
||||
CLASS (const CLASS &) = delete; \
|
||||
CLASS &operator= (const CLASS &) = delete;
|
||||
|
||||
// Get Private data.
|
||||
#define L_D() decltype(getPrivate()) const d = getPrivate();
|
||||
|
||||
// Get Public data.
|
||||
#define L_Q() decltype(getPublic()) const q = getPublic();
|
||||
|
||||
template<typename T, typename U>
|
||||
struct AddConstMirror {
|
||||
typedef U type;
|
||||
};
|
||||
|
||||
template<typename T, typename U>
|
||||
struct AddConstMirror<const T, U> {
|
||||
typedef typename std::add_const<U>::type type;
|
||||
};
|
||||
|
||||
// Get Private data of class in a multiple inheritance case.
|
||||
#define L_D_T(CLASS, NAME) \
|
||||
auto const NAME = static_cast< \
|
||||
AddConstMirror< \
|
||||
LinphonePrivate::Private::AddConstMirror< \
|
||||
std::remove_reference<decltype(*this)>::type, \
|
||||
CLASS ## Private \
|
||||
>::type * \
|
||||
|
|
@ -225,12 +239,16 @@ struct AddConstMirror<const T, U> {
|
|||
// Get Private data of class in a multiple inheritance case.
|
||||
#define L_Q_T(CLASS, NAME) \
|
||||
auto const NAME = static_cast< \
|
||||
AddConstMirror< \
|
||||
LinphonePrivate::Private::AddConstMirror< \
|
||||
std::remove_reference<decltype(*this)>::type, \
|
||||
CLASS \
|
||||
>::type * \
|
||||
>(getPublic());
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Overload.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
#define L_OVERRIDE_SHARED_FROM_THIS(CLASS) \
|
||||
inline std::shared_ptr<CLASS> getSharedFromThis () { \
|
||||
return std::static_pointer_cast<CLASS>(Object::getSharedFromThis()); \
|
||||
|
|
@ -239,25 +257,17 @@ struct AddConstMirror<const T, U> {
|
|||
return std::static_pointer_cast<const CLASS>(Object::getSharedFromThis()); \
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Overload.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
namespace Private {
|
||||
template<typename... Args>
|
||||
struct ResolveMemberFunctionOverload {
|
||||
template<typename Ret, typename Obj>
|
||||
constexpr auto operator() (Ret (Obj::*func)(Args...)) const -> decltype(func) {
|
||||
return func;
|
||||
}
|
||||
constexpr auto operator() (Ret (Obj::*func)(Args...)) const L_AUTO_RETURN(func);
|
||||
};
|
||||
|
||||
template<typename... Args>
|
||||
struct ResolveConstMemberFunctionOverload {
|
||||
template<typename Ret, typename Obj>
|
||||
constexpr auto operator() (Ret (Obj::*func)(Args...) const) const -> decltype(func) {
|
||||
return func;
|
||||
}
|
||||
constexpr auto operator() (Ret (Obj::*func)(Args...) const) const L_AUTO_RETURN(func);
|
||||
};
|
||||
|
||||
template<typename... Args>
|
||||
|
|
@ -266,14 +276,47 @@ namespace Private {
|
|||
using ResolveConstMemberFunctionOverload<Args...>::operator();
|
||||
|
||||
template<typename Ret>
|
||||
constexpr auto operator() (Ret (*func)(Args...)) const -> decltype(func) {
|
||||
return func;
|
||||
}
|
||||
constexpr auto operator() (Ret (*func)(Args...)) const L_AUTO_RETURN(func);
|
||||
};
|
||||
}
|
||||
|
||||
// Useful to select a specific overloaded function. (Avoid usage of static_cast.)
|
||||
#define L_RESOLVE_OVERLOAD(ARGS) LinphonePrivate::Private::ResolveOverload<ARGS>
|
||||
template<typename... Args>
|
||||
using resolveOverload = Private::ResolveOverload<Args...>;
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Math.
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
// Get the length of one integer.
|
||||
constexpr int getIntLength (int n) {
|
||||
return n < 0 ? 1 + getIntLength(-n) : (n < 10 ? 1 : 1 + getIntLength(n / 10));
|
||||
}
|
||||
|
||||
namespace Private {
|
||||
constexpr int pow10Impl (int n, int acc) {
|
||||
return n == 0 ? acc : pow10Impl(n - 1, acc * 10);
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
constexpr T abs (const T &value) {
|
||||
return value < 0 ? -value : value;
|
||||
}
|
||||
|
||||
constexpr int pow10 (int n) {
|
||||
return (n < 0 ? -1 : +1) * Private::pow10Impl(abs(n), 1);
|
||||
}
|
||||
|
||||
// Returns the sum of n elements.
|
||||
constexpr int sums () {
|
||||
return 0;
|
||||
}
|
||||
|
||||
template<typename T, typename... Args>
|
||||
constexpr int sums (T i, Args... args) {
|
||||
return i + sums(args...);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
// Wrapper public.
|
||||
|
|
|
|||
166
include/linphone/utils/static-string.h
Normal file
166
include/linphone/utils/static-string.h
Normal file
|
|
@ -0,0 +1,166 @@
|
|||
/*
|
||||
* static-string.h
|
||||
* Copyright (C) 2010-2018 Belledonne Communications SARL
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#ifndef _L_STATIC_STRING_H_
|
||||
#define _L_STATIC_STRING_H_
|
||||
|
||||
#include "linphone/utils/general.h"
|
||||
|
||||
// =============================================================================
|
||||
// Compile time strings. Useful to build const char * at compilation.
|
||||
// =============================================================================
|
||||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
template<std::size_t...>
|
||||
struct IndexSequence {
|
||||
using Type = IndexSequence;
|
||||
};
|
||||
|
||||
namespace Private {
|
||||
template<typename S1, typename S2>
|
||||
struct ConcatIndexSequenceImpl;
|
||||
|
||||
template<std::size_t... S1, std::size_t... S2>
|
||||
struct ConcatIndexSequenceImpl<IndexSequence<S1...>, IndexSequence<S2...>> :
|
||||
IndexSequence<S1..., (sizeof...(S1) + S2)...> {};
|
||||
|
||||
template<std::size_t N>
|
||||
struct MakeIndexSequenceImpl : ConcatIndexSequenceImpl<
|
||||
typename MakeIndexSequenceImpl<N / 2>::Type,
|
||||
typename MakeIndexSequenceImpl<N - N / 2>::Type
|
||||
> {};
|
||||
|
||||
template<>
|
||||
struct MakeIndexSequenceImpl<0> : IndexSequence<> {};
|
||||
|
||||
template<>
|
||||
struct MakeIndexSequenceImpl<1> : IndexSequence<0> {};
|
||||
}
|
||||
|
||||
template<std::size_t N>
|
||||
using MakeIndexSequence = typename Private::MakeIndexSequenceImpl<N>::Type;
|
||||
|
||||
// =============================================================================
|
||||
|
||||
// See: http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n4121.pdf
|
||||
template<std::size_t N>
|
||||
using RawStaticString = const char [N];
|
||||
|
||||
namespace Private {
|
||||
template<std::size_t N, typename = MakeIndexSequence<N>>
|
||||
struct StaticString;
|
||||
|
||||
template<std::size_t N, std::size_t... Index>
|
||||
struct StaticString<N, IndexSequence<Index...>> {
|
||||
constexpr StaticString (const RawStaticString<N> &inRaw) : raw{ (inRaw[Index])... } {}
|
||||
|
||||
constexpr char operator[] (std::size_t i) const {
|
||||
return raw[i];
|
||||
}
|
||||
|
||||
constexpr operator const char * () const {
|
||||
return raw;
|
||||
}
|
||||
|
||||
RawStaticString<N> raw;
|
||||
};
|
||||
|
||||
template<std::size_t N>
|
||||
class StaticStringConcatHelper {
|
||||
public:
|
||||
template<std::size_t N1>
|
||||
constexpr StaticStringConcatHelper(
|
||||
const Private::StaticString<N1> &s1,
|
||||
const Private::StaticString<N - N1 + 1> &s2
|
||||
) : StaticStringConcatHelper(s1, s2, MakeIndexSequence<N1 - 1>{}, MakeIndexSequence<N - N1 + 1>{}) {}
|
||||
|
||||
RawStaticString<N> raw;
|
||||
|
||||
private:
|
||||
template<std::size_t N1, std::size_t... Index1, std::size_t... Index2>
|
||||
constexpr StaticStringConcatHelper(
|
||||
const Private::StaticString<N1> &s1,
|
||||
const Private::StaticString<N - N1 + 1> &s2,
|
||||
IndexSequence<Index1...>,
|
||||
IndexSequence<Index2...>
|
||||
) : raw{ s1[Index1]..., s2[Index2]... } {}
|
||||
};
|
||||
|
||||
template<int Value, int N = getIntLength(Value) + 1>
|
||||
class StaticIntStringHelper {
|
||||
public:
|
||||
constexpr StaticIntStringHelper () : StaticIntStringHelper(MakeIndexSequence<Value >= 0 ? N - 1 : N - 2>{}) {}
|
||||
|
||||
RawStaticString<N> raw;
|
||||
|
||||
private:
|
||||
template<std::size_t... Index, typename Int = int, typename std::enable_if<Int(Value) >= 0, int>::type* = nullptr>
|
||||
constexpr StaticIntStringHelper (const IndexSequence<Index...> &) :
|
||||
raw{ char('0' + Value / pow10(N - Index - 2) % 10 )..., '\0' } {}
|
||||
|
||||
template<std::size_t... Index, typename Int = int, typename std::enable_if<Int(Value) < 0, int>::type* = nullptr>
|
||||
constexpr StaticIntStringHelper (const IndexSequence<Index...> &) :
|
||||
raw{ '-', char('0' + abs(Value) / pow10(N - Index - 3) % 10 )..., '\0' } {}
|
||||
};
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template<std::size_t N>
|
||||
constexpr Private::StaticString<N> StaticString (const RawStaticString<N> &raw) {
|
||||
return Private::StaticString<N>(raw);
|
||||
}
|
||||
|
||||
template<std::size_t N1, std::size_t N2>
|
||||
constexpr Private::StaticString<N1 + N2 - 1> operator+ (
|
||||
const Private::StaticString<N1> &s1,
|
||||
const Private::StaticString<N2> &s2
|
||||
) {
|
||||
return StaticString(Private::StaticStringConcatHelper<N1 + N2 - 1>(s1, s2).raw);
|
||||
}
|
||||
|
||||
template<std::size_t N1, std::size_t N2>
|
||||
constexpr Private::StaticString<N1 + N2 - 1> operator+ (
|
||||
const Private::StaticString<N1> &s1,
|
||||
const RawStaticString<N2> &s2
|
||||
) {
|
||||
return StaticString(Private::StaticStringConcatHelper<N1 + N2 - 1>(s1, StaticString(s2)).raw);
|
||||
}
|
||||
|
||||
template<std::size_t N1, std::size_t N2>
|
||||
constexpr Private::StaticString<N1 + N2 - 1> operator+ (
|
||||
const RawStaticString<N2> &s1,
|
||||
const Private::StaticString<N1> &s2
|
||||
) {
|
||||
return StaticString(Private::StaticStringConcatHelper<N1 + N2 - 1>(StaticString(s1), s2).raw);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
template<int Value = 0>
|
||||
constexpr Private::StaticString<getIntLength(Value) + 1> StaticIntString () {
|
||||
return StaticString(Private::StaticIntStringHelper<Value>().raw);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
||||
#endif // ifndef _L_STATIC_STRING_H_
|
||||
|
|
@ -21,7 +21,9 @@
|
|||
#define _L_UTILS_H_
|
||||
|
||||
#include <ctime>
|
||||
#include <list>
|
||||
#include <string>
|
||||
#include <utility>
|
||||
#include <vector>
|
||||
|
||||
#include "linphone/utils/enum-generator.h"
|
||||
|
|
@ -105,6 +107,8 @@ namespace Utils {
|
|||
return str ? str : "";
|
||||
}
|
||||
|
||||
LINPHONE_PUBLIC std::string trim (const std::string &str);
|
||||
|
||||
template<typename T>
|
||||
LINPHONE_PUBLIC const T &getEmptyConstRefObject () {
|
||||
static const T object;
|
||||
|
|
|
|||
|
|
@ -54,6 +54,21 @@ LINPHONE_PUBLIC bctbx_list_t *linphone_core_get_callbacks_list(const LinphoneCor
|
|||
*/
|
||||
LINPHONE_PUBLIC const bctbx_list_t *linphone_call_get_callbacks_list(const LinphoneCall *call);
|
||||
|
||||
/**
|
||||
* @brief Gets the list of listener in the chat room.
|
||||
* @param[in] cr #LinphoneChatRoom object.
|
||||
* @return The list of #LinphoneChatRoomCbs.
|
||||
* @donotwrap
|
||||
*/
|
||||
LINPHONE_PUBLIC const bctbx_list_t *linphone_chat_room_get_callbacks_list(const LinphoneChatRoom *cr);
|
||||
|
||||
/**
|
||||
* Sets the current LinphoneChatRoomCbs.
|
||||
* @param[in] cr LinphoneChatRoom object
|
||||
* @param[in] cbs LinphoneChatRoomCbs object
|
||||
*/
|
||||
LINPHONE_PUBLIC void linphone_chat_room_set_current_callbacks(LinphoneChatRoom *cr, LinphoneChatRoomCbs *cbs);
|
||||
|
||||
/**
|
||||
* Send a message to peer member of this chat room.
|
||||
*
|
||||
|
|
|
|||
|
|
@ -2557,4 +2557,10 @@ public interface LinphoneCore {
|
|||
* @return a new LinphoneFriend with the given address link with this LinphoneCore
|
||||
*/
|
||||
public LinphoneFriend createFriendWithAddress(String address);
|
||||
|
||||
/**
|
||||
* Creates and stores a fake LinphoneCallLog
|
||||
* @return the LinphoneCallLog created and stored
|
||||
*/
|
||||
public LinphoneCallLog createCallLog(LinphoneAddress from, LinphoneAddress to, CallDirection dir, int duration, long start, long connected, LinphoneCallLog.CallStatus status, boolean videoEnabled, float quality);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1828,4 +1828,12 @@ class LinphoneCoreImpl implements LinphoneCore {
|
|||
public LinphoneFriend createFriendWithAddress(String address) {
|
||||
return (LinphoneFriend) createFriendWithAddress(nativePtr, address);
|
||||
}
|
||||
|
||||
private native long createCallLog(long ptr, long from, long to, int dir, int duration, long start, long connected, int status, boolean videoEnabled, float quality);
|
||||
@Override
|
||||
public LinphoneCallLog createCallLog(LinphoneAddress from, LinphoneAddress to, CallDirection dir, int duration, long start, long connected, LinphoneCallLog.CallStatus status, boolean videoEnabled, float quality) {
|
||||
long logPtr = createCallLog(nativePtr, ((LinphoneAddressImpl) from).nativePtr, ((LinphoneAddressImpl) to).nativePtr, dir == CallDirection.Incoming ? 1 : 0, duration, start, connected, status.toInt(), videoEnabled, quality);
|
||||
LinphoneCallLog log = new LinphoneCallLogImpl(logPtr);
|
||||
return log;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,6 @@
|
|||
set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
|
||||
address/address-p.h
|
||||
address/address.h
|
||||
address/identity-address-p.h
|
||||
address/identity-address.h
|
||||
c-wrapper/c-wrapper.h
|
||||
c-wrapper/internal/c-sal.h
|
||||
|
|
@ -92,10 +91,12 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
|
|||
conference/session/call-session.h
|
||||
conference/session/media-session.h
|
||||
conference/session/port-config.h
|
||||
containers/lru-cache.h
|
||||
content/content-disposition.h
|
||||
content/content-manager.h
|
||||
content/content-p.h
|
||||
content/content-type.h
|
||||
content/content.h
|
||||
content/content-p.h
|
||||
content/file-content.h
|
||||
content/file-transfer-content.h
|
||||
core/core-accessor.h
|
||||
|
|
@ -106,13 +107,15 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
|
|||
core/platform-helpers/platform-helpers.h
|
||||
db/abstract/abstract-db-p.h
|
||||
db/abstract/abstract-db.h
|
||||
db/internal/db-transaction.h
|
||||
db/internal/statements.h
|
||||
db/main-db-chat-message-key.h
|
||||
db/main-db-event-key.h
|
||||
db/main-db-key-p.h
|
||||
db/main-db-key.h
|
||||
db/main-db-p.h
|
||||
db/main-db.h
|
||||
db/session/db-session-p.h
|
||||
db/session/db-session.h
|
||||
dial-plan/dial-plan-p.h
|
||||
dial-plan/dial-plan.h
|
||||
enums.h
|
||||
|
|
@ -137,6 +140,7 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
|
|||
object/base-object.h
|
||||
object/clonable-object-p.h
|
||||
object/clonable-object.h
|
||||
object/clonable-shared-pointer.h
|
||||
object/object-head-p.h
|
||||
object/object-head.h
|
||||
object/object-p.h
|
||||
|
|
@ -144,6 +148,10 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
|
|||
object/property-container.h
|
||||
object/singleton.h
|
||||
sal/sal.h
|
||||
search/magic-search-p.h
|
||||
search/magic-search.h
|
||||
search/search-result-p.h
|
||||
search/search-result.h
|
||||
utils/background-task.h
|
||||
utils/payload-type-handler.h
|
||||
variant/variant.h
|
||||
|
|
@ -167,7 +175,9 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
|
|||
c-wrapper/api/c-core.cpp
|
||||
c-wrapper/api/c-dial-plan.cpp
|
||||
c-wrapper/api/c-event-log.cpp
|
||||
c-wrapper/api/c-magic-search.cpp
|
||||
c-wrapper/api/c-participant.cpp
|
||||
c-wrapper/api/c-search-result.cpp
|
||||
c-wrapper/internal/c-sal.cpp
|
||||
c-wrapper/internal/c-tools.cpp
|
||||
call/call.cpp
|
||||
|
|
@ -206,6 +216,7 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
|
|||
conference/remote-conference.cpp
|
||||
conference/session/call-session.cpp
|
||||
conference/session/media-session.cpp
|
||||
content/content-disposition.cpp
|
||||
content/content-manager.cpp
|
||||
content/content-type.cpp
|
||||
content/content.cpp
|
||||
|
|
@ -218,6 +229,7 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
|
|||
core/paths/paths.cpp
|
||||
core/platform-helpers/platform-helpers.cpp
|
||||
db/abstract/abstract-db.cpp
|
||||
db/internal/statements.cpp
|
||||
db/main-db-chat-message-key.cpp
|
||||
db/main-db-event-key.cpp
|
||||
db/main-db-key.cpp
|
||||
|
|
@ -249,6 +261,8 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
|
|||
sal/refer-op.cpp
|
||||
sal/register-op.cpp
|
||||
sal/sal.cpp
|
||||
search/magic-search.cpp
|
||||
search/search-result.cpp
|
||||
utils/background-task.cpp
|
||||
utils/fs.cpp
|
||||
utils/general.cpp
|
||||
|
|
@ -264,29 +278,26 @@ set(LINPHONE_OBJC_SOURCE_FILES)
|
|||
if (APPLE)
|
||||
list(APPEND LINPHONE_OBJC_SOURCE_FILES core/paths/paths-apple.mm)
|
||||
list(APPEND LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES core/paths/paths-apple.h)
|
||||
|
||||
elseif (ANDROID)
|
||||
list(APPEND LINPHONE_CXX_OBJECTS_SOURCE_FILES core/paths/paths-android.cpp core/platform-helpers/android-platform-helpers.cpp)
|
||||
list(APPEND LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES core/paths/paths-android.h)
|
||||
|
||||
elseif (WIN32)
|
||||
list(APPEND LINPHONE_CXX_OBJECTS_SOURCE_FILES core/paths/paths-windows.cpp)
|
||||
list(APPEND LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES core/paths/paths-windows.h)
|
||||
|
||||
elseif (UNIX)
|
||||
list(APPEND LINPHONE_CXX_OBJECTS_SOURCE_FILES core/paths/paths-linux.cpp)
|
||||
list(APPEND LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES core/paths/paths-linux.h)
|
||||
endif ()
|
||||
|
||||
set(LINPHONE_CXX_OBJECTS_INCLUDE_DIRS ${BELR_INCLUDE_DIRS} ${LIBXSD_INCLUDE_DIRS})
|
||||
set(LINPHONE_CXX_OBJECTS_INCLUDE_DIRS
|
||||
${BELR_INCLUDE_DIRS}
|
||||
${LIBXSD_INCLUDE_DIRS}
|
||||
${SOCI_INCLUDE_DIRS}
|
||||
${SOCI_MYSQL_INCLUDES}
|
||||
)
|
||||
set(LINPHONE_CXX_OBJECTS_DEFINITIONS "-DLIBLINPHONE_EXPORTS")
|
||||
set(LINPHONE_CXX_OBJECTS_INCLUDE_DIRS ${BELR_INCLUDE_DIRS})
|
||||
|
||||
if (SOCI_FOUND)
|
||||
list(APPEND LINPHONE_CXX_OBJECTS_INCLUDE_DIRS ${SOCI_INCLUDE_DIRS} ${SOCI_MYSQL_INCLUDES})
|
||||
add_definitions(-DSOCI_ENABLED)
|
||||
endif ()
|
||||
|
||||
set(LINPHONE_PRIVATE_HEADER_FILES)
|
||||
foreach (header ${LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES})
|
||||
list(APPEND LINPHONE_PRIVATE_HEADER_FILES "${CMAKE_CURRENT_SOURCE_DIR}/${header}")
|
||||
|
|
|
|||
|
|
@ -38,6 +38,8 @@ public:
|
|||
}
|
||||
void setInternalAddress (const SalAddress *value);
|
||||
|
||||
static void clearSipAddressesCache ();
|
||||
|
||||
private:
|
||||
struct AddressCache {
|
||||
std::string scheme;
|
||||
|
|
|
|||
|
|
@ -17,12 +17,10 @@
|
|||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "linphone/utils/utils.h"
|
||||
|
||||
#include "address-p.h"
|
||||
#include "address/identity-address.h"
|
||||
#include "c-wrapper/c-wrapper.h"
|
||||
#include "c-wrapper/internal/c-sal.h"
|
||||
#include "containers/lru-cache.h"
|
||||
#include "logger/logger.h"
|
||||
|
||||
// =============================================================================
|
||||
|
|
@ -31,6 +29,49 @@ using namespace std;
|
|||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
namespace {
|
||||
class SalAddressWrap {
|
||||
public:
|
||||
explicit SalAddressWrap (SalAddress *salAddress = nullptr) : mSalAddress(salAddress) {}
|
||||
|
||||
SalAddressWrap (const SalAddressWrap &other) : mSalAddress(other.mSalAddress) {
|
||||
if (mSalAddress)
|
||||
sal_address_ref(mSalAddress);
|
||||
}
|
||||
|
||||
SalAddressWrap (SalAddressWrap &&other) : mSalAddress(other.mSalAddress) {
|
||||
other.mSalAddress = nullptr;
|
||||
}
|
||||
|
||||
~SalAddressWrap () {
|
||||
if (mSalAddress)
|
||||
sal_address_unref(mSalAddress);
|
||||
}
|
||||
|
||||
const SalAddress *get () {
|
||||
return mSalAddress;
|
||||
}
|
||||
|
||||
private:
|
||||
SalAddress *mSalAddress;
|
||||
};
|
||||
LruCache<string, SalAddressWrap> addressesCache;
|
||||
}
|
||||
|
||||
static SalAddress *getSalAddressFromCache (const string &uri) {
|
||||
SalAddressWrap *wrap = addressesCache[uri];
|
||||
if (wrap)
|
||||
return sal_address_clone(wrap->get());
|
||||
|
||||
SalAddress *address = sal_address_new(L_STRING_TO_C(uri));
|
||||
if (address) {
|
||||
addressesCache.insert(uri, SalAddressWrap(address));
|
||||
return sal_address_clone(address);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void AddressPrivate::setInternalAddress (const SalAddress *addr) {
|
||||
|
|
@ -39,11 +80,16 @@ void AddressPrivate::setInternalAddress (const SalAddress *addr) {
|
|||
internalAddress = sal_address_clone(addr);
|
||||
}
|
||||
|
||||
void AddressPrivate::clearSipAddressesCache () {
|
||||
addressesCache.clear();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
Address::Address (const string &address) : ClonableObject(*new AddressPrivate) {
|
||||
L_D();
|
||||
if (!(d->internalAddress = sal_address_new(L_STRING_TO_C(address)))) {
|
||||
|
||||
if (!(d->internalAddress = getSalAddressFromCache(address))) {
|
||||
lWarning() << "Cannot create Address, bad uri [" << address << "]";
|
||||
}
|
||||
}
|
||||
|
|
@ -65,12 +111,12 @@ Address::Address (const IdentityAddress &identityAddress) : ClonableObject(*new
|
|||
if (identityAddress.hasGruu())
|
||||
uri += ";gr=" + identityAddress.getGruu();
|
||||
|
||||
d->internalAddress = sal_address_new(L_STRING_TO_C(uri));
|
||||
d->internalAddress = getSalAddressFromCache(uri);
|
||||
}
|
||||
|
||||
Address::Address (const Address &src) : ClonableObject(*new AddressPrivate) {
|
||||
Address::Address (const Address &other) : ClonableObject(*new AddressPrivate) {
|
||||
L_D();
|
||||
SalAddress *salAddress = src.getPrivate()->internalAddress;
|
||||
SalAddress *salAddress = other.getPrivate()->internalAddress;
|
||||
if (salAddress)
|
||||
d->internalAddress = sal_address_clone(salAddress);
|
||||
}
|
||||
|
|
@ -81,28 +127,28 @@ Address::~Address () {
|
|||
sal_address_destroy(d->internalAddress);
|
||||
}
|
||||
|
||||
Address &Address::operator= (const Address &src) {
|
||||
Address &Address::operator= (const Address &other) {
|
||||
L_D();
|
||||
if (this != &src) {
|
||||
if (this != &other) {
|
||||
if (d->internalAddress)
|
||||
sal_address_destroy(d->internalAddress);
|
||||
SalAddress *salAddress = src.getPrivate()->internalAddress;
|
||||
SalAddress *salAddress = other.getPrivate()->internalAddress;
|
||||
d->internalAddress = salAddress ? sal_address_clone(salAddress) : nullptr;
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool Address::operator== (const Address &address) const {
|
||||
return asString() == address.asString();
|
||||
bool Address::operator== (const Address &other) const {
|
||||
return asString() == other.asString();
|
||||
}
|
||||
|
||||
bool Address::operator!= (const Address &address) const {
|
||||
return !(*this == address);
|
||||
bool Address::operator!= (const Address &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
bool Address::operator< (const Address &address) const {
|
||||
return asString() < address.asString();
|
||||
bool Address::operator< (const Address &other) const {
|
||||
return asString() < other.asString();
|
||||
}
|
||||
|
||||
bool Address::isValid () const {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
#ifndef _L_ADDRESS_H_
|
||||
#define _L_ADDRESS_H_
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include "enums.h"
|
||||
#include "object/clonable-object.h"
|
||||
|
||||
|
|
@ -42,15 +44,15 @@ class LINPHONE_PUBLIC Address : public ClonableObject {
|
|||
public:
|
||||
explicit Address (const std::string &address = "");
|
||||
Address (const IdentityAddress &identityAddress);
|
||||
Address (const Address &src);
|
||||
Address (const Address &other);
|
||||
~Address ();
|
||||
|
||||
Address &operator= (const Address &src);
|
||||
Address &operator= (const Address &other);
|
||||
|
||||
bool operator== (const Address &address) const;
|
||||
bool operator!= (const Address &address) const;
|
||||
bool operator== (const Address &other) const;
|
||||
bool operator!= (const Address &other) const;
|
||||
|
||||
bool operator< (const Address &address) const;
|
||||
bool operator< (const Address &other) const;
|
||||
|
||||
bool isValid () const;
|
||||
|
||||
|
|
@ -107,6 +109,11 @@ private:
|
|||
L_DECLARE_PRIVATE(Address);
|
||||
};
|
||||
|
||||
inline std::ostream &operator<< (std::ostream &os, const Address &address) {
|
||||
os << "Address(" << address.asString() << ")";
|
||||
return os;
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
||||
#endif // ifndef _L_ADDRESS_H_
|
||||
|
|
|
|||
|
|
@ -20,10 +20,10 @@
|
|||
#include "linphone/utils/utils.h"
|
||||
|
||||
#include "address.h"
|
||||
#include "identity-address-p.h"
|
||||
#include "c-wrapper/c-wrapper.h"
|
||||
#include "identity-address-p.h"
|
||||
#include "identity-address.h"
|
||||
#include "logger/logger.h"
|
||||
#include "object/clonable-object-p.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
|
|
@ -33,6 +33,16 @@ LINPHONE_BEGIN_NAMESPACE
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
class IdentityAddressPrivate : public ClonableObjectPrivate {
|
||||
public:
|
||||
std::string scheme;
|
||||
std::string username;
|
||||
std::string domain;
|
||||
std::string gruu;
|
||||
};
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
IdentityAddress::IdentityAddress (const string &address) : ClonableObject(*new IdentityAddressPrivate) {
|
||||
L_D();
|
||||
Address tmpAddress(address);
|
||||
|
|
@ -53,35 +63,35 @@ IdentityAddress::IdentityAddress (const Address &address) : ClonableObject(*new
|
|||
d->gruu = address.getUriParamValue("gr");
|
||||
}
|
||||
|
||||
IdentityAddress::IdentityAddress (const IdentityAddress &src) : ClonableObject(*new IdentityAddressPrivate) {
|
||||
IdentityAddress::IdentityAddress (const IdentityAddress &other) : ClonableObject(*new IdentityAddressPrivate) {
|
||||
L_D();
|
||||
d->scheme = src.getScheme();
|
||||
d->username = src.getUsername();
|
||||
d->domain = src.getDomain();
|
||||
d->gruu = src.getGruu();
|
||||
d->scheme = other.getScheme();
|
||||
d->username = other.getUsername();
|
||||
d->domain = other.getDomain();
|
||||
d->gruu = other.getGruu();
|
||||
}
|
||||
|
||||
IdentityAddress &IdentityAddress::operator= (const IdentityAddress &src) {
|
||||
IdentityAddress &IdentityAddress::operator= (const IdentityAddress &other) {
|
||||
L_D();
|
||||
if (this != &src) {
|
||||
d->scheme = src.getScheme();
|
||||
d->username = src.getUsername();
|
||||
d->domain = src.getDomain();
|
||||
d->gruu = src.getGruu();
|
||||
if (this != &other) {
|
||||
d->scheme = other.getScheme();
|
||||
d->username = other.getUsername();
|
||||
d->domain = other.getDomain();
|
||||
d->gruu = other.getGruu();
|
||||
}
|
||||
return *this;
|
||||
}
|
||||
|
||||
bool IdentityAddress::operator== (const IdentityAddress &address) const {
|
||||
return asString() == address.asString();
|
||||
bool IdentityAddress::operator== (const IdentityAddress &other) const {
|
||||
return asString() == other.asString();
|
||||
}
|
||||
|
||||
bool IdentityAddress::operator!= (const IdentityAddress &address) const {
|
||||
return !(*this == address);
|
||||
bool IdentityAddress::operator!= (const IdentityAddress &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
bool IdentityAddress::operator< (const IdentityAddress &address) const {
|
||||
return asString() < address.asString();
|
||||
bool IdentityAddress::operator< (const IdentityAddress &other) const {
|
||||
return asString() < other.asString();
|
||||
}
|
||||
|
||||
bool IdentityAddress::isValid () const {
|
||||
|
|
|
|||
|
|
@ -20,6 +20,8 @@
|
|||
#ifndef _L_IDENTITY_ADDRESS_H_
|
||||
#define _L_IDENTITY_ADDRESS_H_
|
||||
|
||||
#include <ostream>
|
||||
|
||||
#include "object/clonable-object.h"
|
||||
|
||||
// =============================================================================
|
||||
|
|
@ -33,15 +35,15 @@ class LINPHONE_PUBLIC IdentityAddress : public ClonableObject {
|
|||
public:
|
||||
explicit IdentityAddress (const std::string &address = "");
|
||||
IdentityAddress (const Address &address);
|
||||
IdentityAddress (const IdentityAddress &src);
|
||||
IdentityAddress (const IdentityAddress &other);
|
||||
~IdentityAddress () = default;
|
||||
|
||||
IdentityAddress &operator= (const IdentityAddress &src);
|
||||
IdentityAddress &operator= (const IdentityAddress &other);
|
||||
|
||||
bool operator== (const IdentityAddress &address) const;
|
||||
bool operator!= (const IdentityAddress &address) const;
|
||||
bool operator== (const IdentityAddress &other) const;
|
||||
bool operator!= (const IdentityAddress &other) const;
|
||||
|
||||
bool operator< (const IdentityAddress &address) const;
|
||||
bool operator< (const IdentityAddress &other) const;
|
||||
|
||||
bool isValid () const;
|
||||
|
||||
|
|
@ -65,6 +67,11 @@ private:
|
|||
L_DECLARE_PRIVATE(IdentityAddress);
|
||||
};
|
||||
|
||||
inline std::ostream &operator<< (std::ostream &os, const IdentityAddress &identityAddress) {
|
||||
os << "IdentityAddress(" << identityAddress.asString() << ")";
|
||||
return os;
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
||||
#endif // ifndef _L_IDENTITY_ADDRESS_H_
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ struct _LinphoneCallCbs {
|
|||
LinphoneCallCbsStatsUpdatedCb statsUpdatedCb;
|
||||
LinphoneCallCbsTransferStateChangedCb transferStateChangedCb;
|
||||
LinphoneCallCbsAckProcessingCb ackProcessing;
|
||||
LinphoneCallCbsTmmbrReceivedCb tmmbrReceivedCb;
|
||||
};
|
||||
|
||||
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneCallCbs);
|
||||
|
|
@ -124,3 +125,11 @@ LinphoneCallCbsAckProcessingCb linphone_call_cbs_get_ack_processing (LinphoneCal
|
|||
void linphone_call_cbs_set_ack_processing (LinphoneCallCbs *cbs, LinphoneCallCbsAckProcessingCb cb){
|
||||
cbs->ackProcessing = cb;
|
||||
}
|
||||
|
||||
LinphoneCallCbsTmmbrReceivedCb linphone_call_cbs_get_tmmbr_received (LinphoneCallCbs *cbs) {
|
||||
return cbs->tmmbrReceivedCb;
|
||||
}
|
||||
|
||||
void linphone_call_cbs_set_tmmbr_received (LinphoneCallCbs *cbs, LinphoneCallCbsTmmbrReceivedCb cb) {
|
||||
cbs->tmmbrReceivedCb = cb;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@
|
|||
#include "call/call.h"
|
||||
#include "call/local-conference-call.h"
|
||||
#include "call/remote-conference-call.h"
|
||||
#include "chat/chat-room/real-time-text-chat-room.h"
|
||||
#include "conference/params/media-session-params-p.h"
|
||||
#include "core/core-p.h"
|
||||
|
||||
|
|
@ -205,6 +206,10 @@ void linphone_call_notify_ack_processing (LinphoneCall *call, LinphoneHeaders *m
|
|||
NOTIFY_IF_EXIST(AckProcessing, ack_processing, call, msg, is_received)
|
||||
}
|
||||
|
||||
void linphone_call_notify_tmmbr_received (LinphoneCall *call, int stream_index, int tmmbr) {
|
||||
NOTIFY_IF_EXIST(TmmbrReceived, tmmbr_received, call, stream_index, tmmbr)
|
||||
}
|
||||
|
||||
|
||||
// =============================================================================
|
||||
// Public functions.
|
||||
|
|
@ -246,7 +251,7 @@ const char *linphone_call_get_to_header (const LinphoneCall *call, const char *n
|
|||
}
|
||||
|
||||
char *linphone_call_get_remote_address_as_string (const LinphoneCall *call) {
|
||||
return ms_strdup(L_GET_CPP_PTR_FROM_C_OBJECT(call)->getRemoteAddressAsString().c_str());
|
||||
return ms_strdup(L_GET_CPP_PTR_FROM_C_OBJECT(call)->getRemoteAddress().asString().c_str());
|
||||
}
|
||||
|
||||
const LinphoneAddress *linphone_call_get_diversion_address (const LinphoneCall *call) {
|
||||
|
|
@ -538,16 +543,10 @@ bool_t linphone_call_echo_limiter_enabled (const LinphoneCall *call) {
|
|||
}
|
||||
|
||||
LinphoneChatRoom *linphone_call_get_chat_room (LinphoneCall *call) {
|
||||
#if 0
|
||||
if (!call->chat_room){
|
||||
if (call->state != LinphoneCallReleased && call->state != LinphoneCallEnd){
|
||||
call->chat_room = _linphone_core_create_chat_room_from_call(call);
|
||||
}
|
||||
}
|
||||
return call->chat_room;
|
||||
#else
|
||||
shared_ptr<LinphonePrivate::RealTimeTextChatRoom> acr = L_GET_PRIVATE_FROM_C_OBJECT(call)->getChatRoom();
|
||||
if (acr)
|
||||
return L_GET_C_BACK_PTR(acr);
|
||||
return nullptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
float linphone_call_get_play_volume (const LinphoneCall *call) {
|
||||
|
|
|
|||
|
|
@ -23,14 +23,14 @@
|
|||
|
||||
#include "ortp/b64.h"
|
||||
|
||||
#include "c-wrapper/c-wrapper.h"
|
||||
#include "address/address.h"
|
||||
#include "content/content.h"
|
||||
#include "content/content-type.h"
|
||||
#include "c-wrapper/c-wrapper.h"
|
||||
#include "chat/chat-message/chat-message-p.h"
|
||||
#include "chat/chat-room/chat-room-p.h"
|
||||
#include "chat/chat-room/real-time-text-chat-room-p.h"
|
||||
#include "chat/notification/imdn.h"
|
||||
#include "content/content-type.h"
|
||||
#include "content/content.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
|
|
@ -45,13 +45,18 @@ L_DECLARE_C_OBJECT_IMPL_WITH_XTORS(ChatMessage,
|
|||
LinphoneAddress *from; // cache for shared_ptr<Address>
|
||||
LinphoneAddress *to; // cache for shared_ptr<Address>
|
||||
LinphoneChatMessageStateChangedCb message_state_changed_cb;
|
||||
void* message_state_changed_user_data;
|
||||
mutable char *contentTypeCache;
|
||||
mutable std::string textContentBody;
|
||||
void *message_state_changed_user_data;
|
||||
|
||||
struct Cache {
|
||||
string contentType;
|
||||
string textContentBody;
|
||||
string customHeaderValue;
|
||||
} mutable cache;
|
||||
)
|
||||
|
||||
static void _linphone_chat_message_constructor (LinphoneChatMessage *msg) {
|
||||
msg->cbs = linphone_chat_message_cbs_new();
|
||||
new(&msg->cache) LinphoneChatMessage::Cache();
|
||||
}
|
||||
|
||||
static void _linphone_chat_message_destructor (LinphoneChatMessage *msg) {
|
||||
|
|
@ -61,8 +66,8 @@ static void _linphone_chat_message_destructor (LinphoneChatMessage *msg) {
|
|||
linphone_address_unref(msg->from);
|
||||
if (msg->to)
|
||||
linphone_address_unref(msg->to);
|
||||
if (msg->contentTypeCache)
|
||||
ms_free(msg->contentTypeCache);
|
||||
|
||||
msg->cache.~Cache();
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
|
@ -103,7 +108,7 @@ const char *linphone_chat_message_get_external_body_url(const LinphoneChatMessag
|
|||
}
|
||||
|
||||
void linphone_chat_message_set_external_body_url(LinphoneChatMessage *msg, const char *url) {
|
||||
|
||||
L_GET_PRIVATE_FROM_C_OBJECT(msg)->setExternalBodyUrl(L_C_TO_STRING(url));
|
||||
}
|
||||
|
||||
time_t linphone_chat_message_get_time(const LinphoneChatMessage *msg) {
|
||||
|
|
@ -160,8 +165,11 @@ void linphone_chat_message_set_file_transfer_filepath(LinphoneChatMessage *msg,
|
|||
L_GET_PRIVATE_FROM_C_OBJECT(msg)->setFileTransferFilepath(L_C_TO_STRING(filepath));
|
||||
}
|
||||
|
||||
void linphone_chat_message_add_custom_header(LinphoneChatMessage *msg, const char *header_name,
|
||||
const char *header_value) {
|
||||
void linphone_chat_message_add_custom_header(
|
||||
LinphoneChatMessage *msg,
|
||||
const char *header_name,
|
||||
const char *header_value
|
||||
) {
|
||||
L_GET_PRIVATE_FROM_C_OBJECT(msg)->addSalCustomHeader(L_C_TO_STRING(header_name), L_C_TO_STRING(header_value));
|
||||
}
|
||||
|
||||
|
|
@ -170,7 +178,8 @@ void linphone_chat_message_remove_custom_header(LinphoneChatMessage *msg, const
|
|||
}
|
||||
|
||||
const char *linphone_chat_message_get_custom_header(LinphoneChatMessage *msg, const char *header_name) {
|
||||
return L_STRING_TO_C(L_GET_PRIVATE_FROM_C_OBJECT(msg)->getSalCustomHeaderValue(L_C_TO_STRING(header_name)));
|
||||
msg->cache.customHeaderValue = L_GET_PRIVATE_FROM_C_OBJECT(msg)->getSalCustomHeaderValue(L_C_TO_STRING(header_name));
|
||||
return L_STRING_TO_C(msg->cache.customHeaderValue);
|
||||
}
|
||||
|
||||
const LinphoneErrorInfo *linphone_chat_message_get_error_info(const LinphoneChatMessage *msg) {
|
||||
|
|
@ -209,10 +218,6 @@ void linphone_chat_message_resend_2(LinphoneChatMessage *msg) {
|
|||
L_GET_CPP_PTR_FROM_C_OBJECT(msg)->send();
|
||||
}
|
||||
|
||||
void linphone_chat_message_update_state(LinphoneChatMessage *msg, LinphoneChatMessageState new_state) {
|
||||
L_GET_CPP_PTR_FROM_C_OBJECT(msg)->updateState((LinphonePrivate::ChatMessage::State) new_state);
|
||||
}
|
||||
|
||||
LinphoneStatus linphone_chat_message_put_char(LinphoneChatMessage *msg, uint32_t character) {
|
||||
return ((LinphoneStatus)L_GET_CPP_PTR_FROM_C_OBJECT(msg)->putCharacter(character));
|
||||
}
|
||||
|
|
@ -233,8 +238,12 @@ const char *linphone_chat_message_get_text_content(const LinphoneChatMessage *ms
|
|||
const LinphonePrivate::Content *content = L_GET_PRIVATE_FROM_C_OBJECT(msg)->getTextContent();
|
||||
if (content->isEmpty())
|
||||
return nullptr;
|
||||
msg->textContentBody = content->getBodyAsString();
|
||||
return L_STRING_TO_C(msg->textContentBody);
|
||||
msg->cache.textContentBody = content->getBodyAsString();
|
||||
return L_STRING_TO_C(msg->cache.textContentBody);
|
||||
}
|
||||
|
||||
bool_t linphone_chat_message_is_file_transfer_in_progress(LinphoneChatMessage *msg) {
|
||||
return L_GET_CPP_PTR_FROM_C_OBJECT(msg)->isFileTransferInProgress();
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
|
@ -261,12 +270,9 @@ void * linphone_chat_message_get_message_state_changed_cb_user_data(LinphoneChat
|
|||
// Structure has changed, hard to keep the behavior
|
||||
// =============================================================================
|
||||
|
||||
const char * linphone_chat_message_get_content_type(LinphoneChatMessage *msg) {
|
||||
if (msg->contentTypeCache) {
|
||||
ms_free(msg->contentTypeCache);
|
||||
}
|
||||
msg->contentTypeCache = ms_strdup(L_STRING_TO_C(L_GET_PRIVATE_FROM_C_OBJECT(msg)->getContentType().asString()));
|
||||
return msg->contentTypeCache;
|
||||
const char *linphone_chat_message_get_content_type(LinphoneChatMessage *msg) {
|
||||
msg->cache.contentType = L_GET_PRIVATE_FROM_C_OBJECT(msg)->getContentType().asString();
|
||||
return L_STRING_TO_C(msg->cache.contentType);
|
||||
}
|
||||
|
||||
void linphone_chat_message_set_content_type(LinphoneChatMessage *msg, const char *content_type) {
|
||||
|
|
@ -305,11 +311,11 @@ LinphoneReason linphone_chat_message_get_reason(LinphoneChatMessage *msg) {
|
|||
}
|
||||
|
||||
bool_t linphone_chat_message_is_file_transfer(LinphoneChatMessage *msg) {
|
||||
return LinphonePrivate::ContentType(linphone_chat_message_get_content_type(msg)) == LinphonePrivate::ContentType::FileTransfer;
|
||||
return L_GET_PRIVATE_FROM_C_OBJECT(msg)->hasFileTransferContent();
|
||||
}
|
||||
|
||||
bool_t linphone_chat_message_is_text(LinphoneChatMessage *msg) {
|
||||
return LinphonePrivate::ContentType(linphone_chat_message_get_content_type(msg)) == LinphonePrivate::ContentType::PlainText;
|
||||
return L_GET_PRIVATE_FROM_C_OBJECT(msg)->hasTextContent();
|
||||
}
|
||||
|
||||
const char *linphone_chat_message_state_to_string(const LinphoneChatMessageState state) {
|
||||
|
|
|
|||
|
|
@ -39,8 +39,11 @@ struct _LinphoneChatRoomCbs {
|
|||
LinphoneChatRoomCbsChatMessageReceivedCb chatMessageReceivedCb;
|
||||
LinphoneChatRoomCbsChatMessageSentCb chatMessageSentCb;
|
||||
LinphoneChatRoomCbsConferenceAddressGenerationCb conferenceAddressGenerationCb;
|
||||
LinphoneChatRoomCbsParticipantDeviceFetchedCb participantDeviceFetchedCb;
|
||||
LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb participantDeviceFetchRequestedCb;
|
||||
LinphoneChatRoomCbsParticipantsCapabilitiesCheckedCb participantsCapabilitiesChecked;
|
||||
LinphoneChatRoomCbsParticipantRegistrationSubscriptionRequestedCb participantRegistrationSubscriptionRequestedCb;
|
||||
LinphoneChatRoomCbsParticipantRegistrationUnsubscriptionRequestedCb participantRegistrationUnsubscriptionRequestedCb;
|
||||
LinphoneChatRoomCbsShouldChatMessageBeStoredCb shouldMessageBeStoredCb;
|
||||
};
|
||||
|
||||
BELLE_SIP_DECLARE_VPTR_NO_EXPORT(LinphoneChatRoomCbs);
|
||||
|
|
@ -56,7 +59,7 @@ BELLE_SIP_INSTANCIATE_VPTR(LinphoneChatRoomCbs, belle_sip_object_t,
|
|||
|
||||
// =============================================================================
|
||||
|
||||
LinphoneChatRoomCbs * linphone_chat_room_cbs_new (void) {
|
||||
LinphoneChatRoomCbs * _linphone_chat_room_cbs_new (void) {
|
||||
return belle_sip_object_new(LinphoneChatRoomCbs);
|
||||
}
|
||||
|
||||
|
|
@ -181,12 +184,12 @@ void linphone_chat_room_cbs_set_conference_address_generation (LinphoneChatRoomC
|
|||
cbs->conferenceAddressGenerationCb = cb;
|
||||
}
|
||||
|
||||
LinphoneChatRoomCbsParticipantDeviceFetchedCb linphone_chat_room_cbs_get_participant_device_fetched (const LinphoneChatRoomCbs *cbs) {
|
||||
return cbs->participantDeviceFetchedCb;
|
||||
LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb linphone_chat_room_cbs_get_participant_device_fetch_requested (const LinphoneChatRoomCbs *cbs) {
|
||||
return cbs->participantDeviceFetchRequestedCb;
|
||||
}
|
||||
|
||||
void linphone_chat_room_cbs_set_participant_device_fetched (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantDeviceFetchedCb cb) {
|
||||
cbs->participantDeviceFetchedCb = cb;
|
||||
void linphone_chat_room_cbs_set_participant_device_fetch_requested (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantDeviceFetchRequestedCb cb) {
|
||||
cbs->participantDeviceFetchRequestedCb = cb;
|
||||
}
|
||||
|
||||
LinphoneChatRoomCbsParticipantsCapabilitiesCheckedCb linphone_chat_room_cbs_get_participants_capabilities_checked (const LinphoneChatRoomCbs *cbs) {
|
||||
|
|
@ -196,3 +199,27 @@ LinphoneChatRoomCbsParticipantsCapabilitiesCheckedCb linphone_chat_room_cbs_get_
|
|||
void linphone_chat_room_cbs_set_participants_capabilities_checked (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantsCapabilitiesCheckedCb cb) {
|
||||
cbs->participantsCapabilitiesChecked = cb;
|
||||
}
|
||||
|
||||
LinphoneChatRoomCbsParticipantRegistrationSubscriptionRequestedCb linphone_chat_room_cbs_get_participant_registration_subscription_requested (const LinphoneChatRoomCbs *cbs) {
|
||||
return cbs->participantRegistrationSubscriptionRequestedCb;
|
||||
}
|
||||
|
||||
void linphone_chat_room_cbs_set_participant_registration_subscription_requested (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantRegistrationSubscriptionRequestedCb cb) {
|
||||
cbs->participantRegistrationSubscriptionRequestedCb = cb;
|
||||
}
|
||||
|
||||
LinphoneChatRoomCbsParticipantRegistrationUnsubscriptionRequestedCb linphone_chat_room_cbs_get_participant_registration_unsubscription_requested (const LinphoneChatRoomCbs *cbs) {
|
||||
return cbs->participantRegistrationUnsubscriptionRequestedCb;
|
||||
}
|
||||
|
||||
void linphone_chat_room_cbs_set_participant_registration_unsubscription_requested (LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsParticipantRegistrationUnsubscriptionRequestedCb cb) {
|
||||
cbs->participantRegistrationUnsubscriptionRequestedCb = cb;
|
||||
}
|
||||
|
||||
LinphoneChatRoomCbsShouldChatMessageBeStoredCb linphone_chat_room_cbs_get_chat_message_should_be_stored( LinphoneChatRoomCbs *cbs) {
|
||||
return cbs->shouldMessageBeStoredCb;
|
||||
}
|
||||
|
||||
void linphone_chat_room_cbs_set_chat_message_should_be_stored( LinphoneChatRoomCbs *cbs, LinphoneChatRoomCbsShouldChatMessageBeStoredCb cb) {
|
||||
cbs->shouldMessageBeStoredCb = cb;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -27,10 +27,8 @@
|
|||
|
||||
#include "address/identity-address.h"
|
||||
#include "c-wrapper/c-wrapper.h"
|
||||
#include "call/call.h"
|
||||
#include "chat/chat-message/chat-message-p.h"
|
||||
#include "chat/chat-room/basic-chat-room.h"
|
||||
#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/real-time-text-chat-room-p.h"
|
||||
#include "chat/chat-room/server-group-chat-room-p.h"
|
||||
#include "conference/participant.h"
|
||||
|
|
@ -47,19 +45,17 @@ static void _linphone_chat_room_destructor (LinphoneChatRoom *cr);
|
|||
L_DECLARE_C_OBJECT_IMPL_WITH_XTORS(
|
||||
ChatRoom,
|
||||
_linphone_chat_room_constructor, _linphone_chat_room_destructor,
|
||||
LinphoneChatRoomCbs *cbs;
|
||||
bctbx_list_t *callbacks; /* A list of LinphoneCallCbs object */
|
||||
LinphoneChatRoomCbs *currentCbs; /* The current LinphoneCallCbs object used to call a callback */
|
||||
mutable LinphoneAddress *conferenceAddressCache;
|
||||
mutable LinphoneAddress *peerAddressCache;
|
||||
mutable LinphoneAddress *localAddressCache;
|
||||
mutable bctbx_list_t *composingAddresses;
|
||||
)
|
||||
|
||||
static void _linphone_chat_room_constructor (LinphoneChatRoom *cr) {
|
||||
cr->cbs = linphone_chat_room_cbs_new();
|
||||
}
|
||||
static void _linphone_chat_room_constructor (LinphoneChatRoom *cr) {}
|
||||
|
||||
static void _linphone_chat_room_destructor (LinphoneChatRoom *cr) {
|
||||
linphone_chat_room_cbs_unref(cr->cbs);
|
||||
if (cr->conferenceAddressCache)
|
||||
linphone_address_unref(cr->conferenceAddressCache);
|
||||
if (cr->peerAddressCache)
|
||||
|
|
@ -68,6 +64,7 @@ static void _linphone_chat_room_destructor (LinphoneChatRoom *cr) {
|
|||
linphone_address_unref(cr->localAddressCache);
|
||||
if (cr->composingAddresses)
|
||||
bctbx_list_free_with_data(cr->composingAddresses, (bctbx_list_free_func)linphone_address_unref);
|
||||
_linphone_chat_room_clear_callbacks(cr);
|
||||
}
|
||||
|
||||
static list<LinphonePrivate::IdentityAddress> _get_identity_address_list_from_address_list(list<LinphonePrivate::Address> addressList) {
|
||||
|
|
@ -156,9 +153,9 @@ void linphone_chat_room_receive_chat_message (LinphoneChatRoom *cr, LinphoneChat
|
|||
}
|
||||
|
||||
uint32_t linphone_chat_room_get_char (const LinphoneChatRoom *cr) {
|
||||
if (linphone_core_realtime_text_enabled(linphone_chat_room_get_core(cr)))
|
||||
return L_GET_CPP_PTR_FROM_C_OBJECT(cr, RealTimeTextChatRoom)->getChar();
|
||||
return 0;
|
||||
if (!(L_GET_CPP_PTR_FROM_C_OBJECT(cr)->getCapabilities() & LinphonePrivate::ChatRoom::Capabilities::RealTimeText))
|
||||
return 0;
|
||||
return L_GET_CPP_PTR_FROM_C_OBJECT(cr, RealTimeTextChatRoom)->getChar();
|
||||
}
|
||||
|
||||
void linphone_chat_room_compose (LinphoneChatRoom *cr) {
|
||||
|
|
@ -166,14 +163,15 @@ void linphone_chat_room_compose (LinphoneChatRoom *cr) {
|
|||
}
|
||||
|
||||
LinphoneCall *linphone_chat_room_get_call (const LinphoneChatRoom *cr) {
|
||||
if (linphone_core_realtime_text_enabled(linphone_chat_room_get_core(cr)))
|
||||
return L_GET_CPP_PTR_FROM_C_OBJECT(cr, RealTimeTextChatRoom)->getCall();
|
||||
return nullptr;
|
||||
if (!(L_GET_CPP_PTR_FROM_C_OBJECT(cr)->getCapabilities() & LinphonePrivate::ChatRoom::Capabilities::RealTimeText))
|
||||
return nullptr;
|
||||
return L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(cr, RealTimeTextChatRoom)->getCall());
|
||||
}
|
||||
|
||||
void linphone_chat_room_set_call (LinphoneChatRoom *cr, LinphoneCall *call) {
|
||||
if (linphone_core_realtime_text_enabled(linphone_chat_room_get_core(cr)))
|
||||
L_GET_PRIVATE_FROM_C_OBJECT(cr, RealTimeTextChatRoom)->call = call;
|
||||
if (!(L_GET_CPP_PTR_FROM_C_OBJECT(cr)->getCapabilities() & LinphonePrivate::ChatRoom::Capabilities::RealTimeText))
|
||||
return;
|
||||
L_GET_PRIVATE_FROM_C_OBJECT(cr, RealTimeTextChatRoom)->call = L_GET_CPP_PTR_FROM_C_OBJECT(call);
|
||||
}
|
||||
|
||||
void linphone_chat_room_mark_as_read (LinphoneChatRoom *cr) {
|
||||
|
|
@ -202,9 +200,8 @@ void linphone_chat_room_delete_history (LinphoneChatRoom *cr) {
|
|||
|
||||
bctbx_list_t *linphone_chat_room_get_history_range (LinphoneChatRoom *cr, int startm, int endm) {
|
||||
list<shared_ptr<LinphonePrivate::ChatMessage>> chatMessages;
|
||||
for (auto &event : L_GET_CPP_PTR_FROM_C_OBJECT(cr)->getHistoryRange(startm, endm))
|
||||
if (event->getType() == LinphonePrivate::EventLog::Type::ConferenceChatMessage)
|
||||
chatMessages.push_back(static_pointer_cast<LinphonePrivate::ConferenceChatMessageEvent>(event)->getChatMessage());
|
||||
for (auto &event : L_GET_CPP_PTR_FROM_C_OBJECT(cr)->getMessageHistoryRange(startm, endm))
|
||||
chatMessages.push_back(static_pointer_cast<LinphonePrivate::ConferenceChatMessageEvent>(event)->getChatMessage());
|
||||
|
||||
return L_GET_RESOLVED_C_LIST_FROM_CPP_LIST(chatMessages);
|
||||
}
|
||||
|
|
@ -213,6 +210,14 @@ bctbx_list_t *linphone_chat_room_get_history (LinphoneChatRoom *cr, int nb_messa
|
|||
return linphone_chat_room_get_history_range(cr, 0, nb_message);
|
||||
}
|
||||
|
||||
bctbx_list_t *linphone_chat_room_get_history_range_message_events (LinphoneChatRoom *cr, int startm, int endm) {
|
||||
return L_GET_RESOLVED_C_LIST_FROM_CPP_LIST(L_GET_CPP_PTR_FROM_C_OBJECT(cr)->getMessageHistoryRange(startm, endm));
|
||||
}
|
||||
|
||||
bctbx_list_t *linphone_chat_room_get_history_message_events (LinphoneChatRoom *cr, int nb_events) {
|
||||
return L_GET_RESOLVED_C_LIST_FROM_CPP_LIST(L_GET_CPP_PTR_FROM_C_OBJECT(cr)->getMessageHistory(nb_events));
|
||||
}
|
||||
|
||||
bctbx_list_t *linphone_chat_room_get_history_events (LinphoneChatRoom *cr, int nb_events) {
|
||||
return L_GET_RESOLVED_C_LIST_FROM_CPP_LIST(L_GET_CPP_PTR_FROM_C_OBJECT(cr)->getHistory(nb_events));
|
||||
}
|
||||
|
|
@ -239,10 +244,6 @@ LinphoneChatMessage *linphone_chat_room_find_message (LinphoneChatRoom *cr, cons
|
|||
return L_GET_C_BACK_PTR(L_GET_CPP_PTR_FROM_C_OBJECT(cr)->findChatMessage(message_id));
|
||||
}
|
||||
|
||||
LinphoneChatRoomCbs *linphone_chat_room_get_callbacks (const LinphoneChatRoom *cr) {
|
||||
return cr->cbs;
|
||||
}
|
||||
|
||||
LinphoneChatRoomState linphone_chat_room_get_state (const LinphoneChatRoom *cr) {
|
||||
return (LinphoneChatRoomState)L_GET_CPP_PTR_FROM_C_OBJECT(cr)->getState();
|
||||
}
|
||||
|
|
@ -251,6 +252,10 @@ bool_t linphone_chat_room_has_been_left (const LinphoneChatRoom *cr) {
|
|||
return (bool_t)L_GET_CPP_PTR_FROM_C_OBJECT(cr)->hasBeenLeft();
|
||||
}
|
||||
|
||||
time_t linphone_chat_room_get_last_update_time(const LinphoneChatRoom *cr) {
|
||||
return L_GET_CPP_PTR_FROM_C_OBJECT(cr)->getLastUpdateTime();
|
||||
}
|
||||
|
||||
void linphone_chat_room_add_participant (LinphoneChatRoom *cr, const LinphoneAddress *addr) {
|
||||
L_GET_CPP_PTR_FROM_C_OBJECT(cr)->addParticipant(
|
||||
LinphonePrivate::IdentityAddress(*L_GET_CPP_PTR_FROM_C_OBJECT(addr)), nullptr, false
|
||||
|
|
@ -377,6 +382,16 @@ void linphone_chat_room_set_participant_devices (LinphoneChatRoom *cr, const Lin
|
|||
bctbx_free(addrStr);
|
||||
}
|
||||
|
||||
void linphone_chat_room_add_participant_device (LinphoneChatRoom *cr, const LinphoneAddress *participantAddress, const LinphoneAddress *deviceAddress) {
|
||||
char *participantAddressStr = linphone_address_as_string(participantAddress);
|
||||
char *deviceAddressStr = linphone_address_as_string(deviceAddress);
|
||||
LinphonePrivate::ServerGroupChatRoomPrivate *sgcr = dynamic_cast<LinphonePrivate::ServerGroupChatRoomPrivate *>(L_GET_PRIVATE_FROM_C_OBJECT(cr));
|
||||
if (sgcr)
|
||||
sgcr->addParticipantDevice(LinphonePrivate::IdentityAddress(participantAddressStr), LinphonePrivate::IdentityAddress(deviceAddressStr));
|
||||
bctbx_free(participantAddressStr);
|
||||
bctbx_free(deviceAddressStr);
|
||||
}
|
||||
|
||||
void linphone_chat_room_add_compatible_participants (LinphoneChatRoom *cr, const LinphoneAddress *deviceAddr, const bctbx_list_t *participantsCompatible) {
|
||||
list<LinphonePrivate::Address> lPartsComp = L_GET_RESOLVED_CPP_LIST_FROM_C_LIST(participantsCompatible, Address);
|
||||
LinphonePrivate::ServerGroupChatRoomPrivate *sgcr = dynamic_cast<LinphonePrivate::ServerGroupChatRoomPrivate *>(L_GET_PRIVATE_FROM_C_OBJECT(cr));
|
||||
|
|
@ -389,6 +404,118 @@ void linphone_chat_room_add_compatible_participants (LinphoneChatRoom *cr, const
|
|||
}
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Callbacks
|
||||
// =============================================================================
|
||||
|
||||
void _linphone_chat_room_clear_callbacks (LinphoneChatRoom *cr) {
|
||||
bctbx_list_free_with_data(cr->callbacks, (bctbx_list_free_func)linphone_chat_room_cbs_unref);
|
||||
cr->callbacks = nullptr;
|
||||
}
|
||||
|
||||
void linphone_chat_room_add_callbacks (LinphoneChatRoom *cr, LinphoneChatRoomCbs *cbs) {
|
||||
cr->callbacks = bctbx_list_append(cr->callbacks, linphone_chat_room_cbs_ref(cbs));
|
||||
}
|
||||
|
||||
void linphone_chat_room_remove_callbacks (LinphoneChatRoom *cr, LinphoneChatRoomCbs *cbs) {
|
||||
cr->callbacks = bctbx_list_remove(cr->callbacks, cbs);
|
||||
linphone_chat_room_cbs_unref(cbs);
|
||||
}
|
||||
|
||||
LinphoneChatRoomCbs *linphone_chat_room_get_current_callbacks (const LinphoneChatRoom *cr) {
|
||||
return cr->currentCbs;
|
||||
}
|
||||
|
||||
void linphone_chat_room_set_current_callbacks(LinphoneChatRoom *cr, LinphoneChatRoomCbs *cbs) {
|
||||
cr->currentCbs = cbs;
|
||||
}
|
||||
|
||||
const bctbx_list_t *linphone_chat_room_get_callbacks_list(const LinphoneChatRoom *cr) {
|
||||
return cr->callbacks;
|
||||
}
|
||||
|
||||
#define NOTIFY_IF_EXIST(cbName, functionName, ...) \
|
||||
bctbx_list_t *callbacksCopy = bctbx_list_copy(linphone_chat_room_get_callbacks_list(cr)); \
|
||||
for (bctbx_list_t *it = callbacksCopy; it; it = bctbx_list_next(it)) { \
|
||||
linphone_chat_room_set_current_callbacks(cr, reinterpret_cast<LinphoneChatRoomCbs *>(bctbx_list_get_data(it))); \
|
||||
LinphoneChatRoomCbs ## cbName ## Cb cb = linphone_chat_room_cbs_get_ ## functionName (linphone_chat_room_get_current_callbacks(cr)); \
|
||||
if (cb) \
|
||||
cb(__VA_ARGS__); \
|
||||
} \
|
||||
bctbx_list_free(callbacksCopy);
|
||||
|
||||
void _linphone_chat_room_notify_is_composing_received(LinphoneChatRoom *cr, const LinphoneAddress *remoteAddr, bool_t isComposing) {
|
||||
NOTIFY_IF_EXIST(IsComposingReceived, is_composing_received, cr, remoteAddr, isComposing)
|
||||
}
|
||||
|
||||
void _linphone_chat_room_notify_message_received(LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
|
||||
NOTIFY_IF_EXIST(MessageReceived, message_received, cr, msg)
|
||||
}
|
||||
|
||||
void _linphone_chat_room_notify_participant_added(LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
|
||||
NOTIFY_IF_EXIST(ParticipantAdded, participant_added, cr, event_log)
|
||||
}
|
||||
|
||||
void _linphone_chat_room_notify_participant_removed(LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
|
||||
NOTIFY_IF_EXIST(ParticipantRemoved, participant_removed, cr, event_log)
|
||||
}
|
||||
|
||||
void _linphone_chat_room_notify_participant_device_added(LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
|
||||
NOTIFY_IF_EXIST(ParticipantDeviceAdded, participant_device_added, cr, event_log)
|
||||
}
|
||||
|
||||
void _linphone_chat_room_notify_participant_device_removed(LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
|
||||
NOTIFY_IF_EXIST(ParticipantDeviceRemoved, participant_device_removed, cr, event_log)
|
||||
}
|
||||
|
||||
void _linphone_chat_room_notify_participant_admin_status_changed(LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
|
||||
NOTIFY_IF_EXIST(ParticipantAdminStatusChanged, participant_admin_status_changed, cr, event_log)
|
||||
}
|
||||
|
||||
void _linphone_chat_room_notify_state_changed(LinphoneChatRoom *cr, LinphoneChatRoomState newState) {
|
||||
NOTIFY_IF_EXIST(StateChanged, state_changed, cr, newState)
|
||||
}
|
||||
|
||||
void _linphone_chat_room_notify_subject_changed(LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
|
||||
NOTIFY_IF_EXIST(SubjectChanged, subject_changed, cr, event_log)
|
||||
}
|
||||
|
||||
void _linphone_chat_room_notify_undecryptable_message_received(LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
|
||||
NOTIFY_IF_EXIST(UndecryptableMessageReceived, undecryptable_message_received, cr, msg)
|
||||
}
|
||||
|
||||
void _linphone_chat_room_notify_chat_message_received(LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
|
||||
NOTIFY_IF_EXIST(ChatMessageReceived, chat_message_received, cr, event_log)
|
||||
}
|
||||
|
||||
void _linphone_chat_room_notify_chat_message_sent(LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
|
||||
NOTIFY_IF_EXIST(ChatMessageSent, chat_message_sent, cr, event_log)
|
||||
}
|
||||
|
||||
void _linphone_chat_room_notify_conference_address_generation(LinphoneChatRoom *cr) {
|
||||
NOTIFY_IF_EXIST(ConferenceAddressGeneration, conference_address_generation, cr)
|
||||
}
|
||||
|
||||
void _linphone_chat_room_notify_participant_device_fetch_requested(LinphoneChatRoom *cr, const LinphoneAddress *participantAddr) {
|
||||
NOTIFY_IF_EXIST(ParticipantDeviceFetchRequested, participant_device_fetch_requested, cr, participantAddr)
|
||||
}
|
||||
|
||||
void _linphone_chat_room_notify_participants_capabilities_checked(LinphoneChatRoom *cr, const LinphoneAddress *deviceAddr, const bctbx_list_t *participantsAddr) {
|
||||
NOTIFY_IF_EXIST(ParticipantsCapabilitiesChecked, participants_capabilities_checked, cr, deviceAddr, participantsAddr)
|
||||
}
|
||||
|
||||
void _linphone_chat_room_notify_participant_registration_subscription_requested(LinphoneChatRoom *cr, const LinphoneAddress *participantAddr) {
|
||||
NOTIFY_IF_EXIST(ParticipantRegistrationSubscriptionRequested, participant_registration_subscription_requested, cr, participantAddr)
|
||||
}
|
||||
|
||||
void _linphone_chat_room_notify_participant_registration_unsubscription_requested(LinphoneChatRoom *cr, const LinphoneAddress *participantAddr) {
|
||||
NOTIFY_IF_EXIST(ParticipantRegistrationUnsubscriptionRequested, participant_registration_unsubscription_requested, cr, participantAddr)
|
||||
}
|
||||
|
||||
void _linphone_chat_room_notify_chat_message_should_be_stored(LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
|
||||
NOTIFY_IF_EXIST(ShouldChatMessageBeStored, chat_message_should_be_stored, cr, msg)
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
// Reference and user data handling functions.
|
||||
// =============================================================================
|
||||
|
|
@ -414,39 +541,6 @@ void linphone_chat_room_set_user_data (LinphoneChatRoom *cr, void *ud) {
|
|||
// Constructor and destructor functions.
|
||||
// =============================================================================
|
||||
|
||||
LinphoneChatRoom *_linphone_client_group_chat_room_new (LinphoneCore *core, const char *uri, const char *subject, bool_t fallback) {
|
||||
LinphoneAddress *addr = linphone_address_new(uri);
|
||||
LinphoneProxyConfig *proxy = linphone_core_lookup_known_proxy(core, addr);
|
||||
linphone_address_unref(addr);
|
||||
string from;
|
||||
if (proxy) {
|
||||
const LinphoneAddress *contactAddr = linphone_proxy_config_get_contact(proxy);
|
||||
if (contactAddr) {
|
||||
char *cFrom = linphone_address_as_string(contactAddr);
|
||||
from = string(cFrom);
|
||||
bctbx_free(cFrom);
|
||||
} else {
|
||||
from = L_GET_CPP_PTR_FROM_C_OBJECT(linphone_proxy_config_get_identity_address(proxy))->asString();
|
||||
}
|
||||
}
|
||||
if (from.empty())
|
||||
from = linphone_core_get_primary_contact(core);
|
||||
LinphonePrivate::IdentityAddress me(from);
|
||||
shared_ptr<LinphonePrivate::ClientGroupChatRoom> cgcr = make_shared<LinphonePrivate::ClientGroupChatRoom>(
|
||||
L_GET_CPP_PTR_FROM_C_OBJECT(core), L_C_TO_STRING(uri), me, L_C_TO_STRING(subject));
|
||||
LinphoneChatRoom *cr = L_INIT(ChatRoom);
|
||||
if (fallback) {
|
||||
// Create a ClientGroupToBasicChatRoom to handle fallback from ClientGroupChatRoom to BasicGroupChatRoom if
|
||||
// only one participant is invited and that it does not support group chat
|
||||
L_SET_CPP_PTR_FROM_C_OBJECT(cr, make_shared<LinphonePrivate::ClientGroupToBasicChatRoom>(cgcr));
|
||||
L_GET_PRIVATE(cgcr)->setCallSessionListener(L_GET_PRIVATE_FROM_C_OBJECT(cr));
|
||||
L_GET_PRIVATE(cgcr)->setChatRoomListener(L_GET_PRIVATE_FROM_C_OBJECT(cr));
|
||||
} else
|
||||
L_SET_CPP_PTR_FROM_C_OBJECT(cr, cgcr);
|
||||
L_GET_PRIVATE(cgcr)->setState(LinphonePrivate::ChatRoom::State::Instantiated);
|
||||
return cr;
|
||||
}
|
||||
|
||||
LinphoneChatRoom *_linphone_server_group_chat_room_new (LinphoneCore *core, LinphonePrivate::SalCallOp *op) {
|
||||
LinphoneChatRoom *cr = L_INIT(ChatRoom);
|
||||
L_SET_CPP_PTR_FROM_C_OBJECT(cr, make_shared<LinphonePrivate::ServerGroupChatRoom>(
|
||||
|
|
@ -457,8 +551,3 @@ LinphoneChatRoom *_linphone_server_group_chat_room_new (LinphoneCore *core, Linp
|
|||
L_GET_PRIVATE_FROM_C_OBJECT(cr, ServerGroupChatRoom)->confirmCreation();
|
||||
return cr;
|
||||
}
|
||||
|
||||
/* DEPRECATED */
|
||||
void linphone_chat_room_destroy (LinphoneChatRoom *cr) {
|
||||
linphone_chat_room_unref(cr);
|
||||
}
|
||||
|
|
|
|||
102
src/c-wrapper/api/c-magic-search.cpp
Normal file
102
src/c-wrapper/api/c-magic-search.cpp
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/*
|
||||
* c-magic-search.cpp
|
||||
* Copyright (C) 2010-2018 Belledonne Communications SARL
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "search/magic-search.h"
|
||||
#include "c-wrapper/c-wrapper.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
L_DECLARE_C_OBJECT_IMPL(MagicSearch);
|
||||
|
||||
LinphoneMagicSearch *linphone_core_create_magic_search(LinphoneCore *lc) {
|
||||
shared_ptr<LinphonePrivate::MagicSearch> cppPtr = make_shared<LinphonePrivate::MagicSearch>(L_GET_CPP_PTR_FROM_C_OBJECT(lc));
|
||||
|
||||
LinphoneMagicSearch *object = L_INIT(MagicSearch);
|
||||
L_SET_CPP_PTR_FROM_C_OBJECT(object, cppPtr);
|
||||
return object;
|
||||
}
|
||||
|
||||
LinphoneMagicSearch *linphone_magic_search_new(LinphoneCore *lc) {
|
||||
return linphone_core_create_magic_search(lc);
|
||||
}
|
||||
|
||||
LinphoneMagicSearch *linphone_magic_search_ref(LinphoneMagicSearch *magicSearch) {
|
||||
belle_sip_object_ref(magicSearch);
|
||||
return magicSearch;
|
||||
}
|
||||
|
||||
void linphone_magic_search_unref(LinphoneMagicSearch *magicSearch) {
|
||||
belle_sip_object_unref(magicSearch);
|
||||
}
|
||||
|
||||
void linphone_magic_search_set_min_weight(LinphoneMagicSearch *magicSearch, const unsigned int weight) {
|
||||
L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->setMinWeight(weight);
|
||||
}
|
||||
|
||||
unsigned int linphone_magic_search_get_min_weight(const LinphoneMagicSearch *magicSearch) {
|
||||
return L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->getMinWeight();
|
||||
}
|
||||
|
||||
void linphone_magic_search_set_max_weight(LinphoneMagicSearch *magicSearch, const unsigned int weight) {
|
||||
L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->setMaxWeight(weight);
|
||||
}
|
||||
|
||||
unsigned int linphone_magic_search_get_max_weight(const LinphoneMagicSearch *magicSearch) {
|
||||
return L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->getMaxWeight();
|
||||
}
|
||||
|
||||
const char *linphone_magic_search_get_delimiter(const LinphoneMagicSearch *magicSearch) {
|
||||
return L_STRING_TO_C(L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->getDelimiter());
|
||||
}
|
||||
|
||||
void linphone_magic_search_set_delimiter(LinphoneMagicSearch *magicSearch, const char *delimiter) {
|
||||
L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->setDelimiter(L_C_TO_STRING(delimiter));
|
||||
}
|
||||
|
||||
bool_t linphone_magic_search_get_use_delimiter(LinphoneMagicSearch *magicSearch) {
|
||||
return L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->getUseDelimiter();
|
||||
}
|
||||
|
||||
void linphone_magic_search_set_use_delimiter(LinphoneMagicSearch *magicSearch, bool_t enable) {
|
||||
L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->setUseDelimiter(enable);
|
||||
}
|
||||
|
||||
unsigned int linphone_magic_search_get_search_limit(const LinphoneMagicSearch *magicSearch) {
|
||||
return L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->getSearchLimit();
|
||||
}
|
||||
|
||||
void linphone_magic_search_set_search_limit(LinphoneMagicSearch *magicSearch, const unsigned int limit) {
|
||||
L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->setSearchLimit(limit);
|
||||
}
|
||||
|
||||
bool_t linphone_magic_search_get_limited_search(const LinphoneMagicSearch *magicSearch) {
|
||||
return L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->getLimitedSearch();
|
||||
}
|
||||
|
||||
void linphone_magic_search_set_limited_search(LinphoneMagicSearch *magicSearch, const bool_t limited) {
|
||||
L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->setLimitedSearch(limited);
|
||||
}
|
||||
|
||||
void linphone_magic_search_reset_search_cache(LinphoneMagicSearch *magicSearch) {
|
||||
L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->resetSearchCache();
|
||||
}
|
||||
|
||||
bctbx_list_t* linphone_magic_search_get_contact_list_from_filter(LinphoneMagicSearch *magicSearch, const char *filter, const char *withDomain) {
|
||||
return L_GET_RESOLVED_C_LIST_FROM_CPP_LIST(L_GET_CPP_PTR_FROM_C_OBJECT(magicSearch)->getContactListFromFilter(L_C_TO_STRING(filter), L_C_TO_STRING(withDomain)));
|
||||
}
|
||||
44
src/c-wrapper/api/c-search-result.cpp
Normal file
44
src/c-wrapper/api/c-search-result.cpp
Normal file
|
|
@ -0,0 +1,44 @@
|
|||
/*
|
||||
* c-search-result.cpp
|
||||
* Copyright (C) 2010-2018 Belledonne Communications SARL
|
||||
*
|
||||
* This program is free software; you can redistribute it and/or
|
||||
* modify it under the terms of the GNU General Public License
|
||||
* as published by the Free Software Foundation; either version 2
|
||||
* of the License, or (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program; if not, write to the Free Software
|
||||
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "search/search-result.h"
|
||||
#include "c-wrapper/c-wrapper.h"
|
||||
|
||||
L_DECLARE_C_CLONABLE_OBJECT_IMPL(SearchResult);
|
||||
|
||||
LinphoneSearchResult *linphone_search_result_ref(LinphoneSearchResult *searchResult) {
|
||||
belle_sip_object_ref(searchResult);
|
||||
return searchResult;
|
||||
}
|
||||
|
||||
void linphone_search_result_unref(LinphoneSearchResult *searchResult) {
|
||||
belle_sip_object_unref(searchResult);
|
||||
}
|
||||
|
||||
const LinphoneFriend* linphone_search_result_get_friend(const LinphoneSearchResult *searchResult) {
|
||||
return L_GET_CPP_PTR_FROM_C_OBJECT(searchResult)->getFriend();
|
||||
}
|
||||
|
||||
const LinphoneAddress* linphone_search_result_get_address(const LinphoneSearchResult *searchResult) {
|
||||
return L_GET_CPP_PTR_FROM_C_OBJECT(searchResult)->getAddress();
|
||||
}
|
||||
|
||||
unsigned int linphone_search_result_get_weight(const LinphoneSearchResult *searchResult) {
|
||||
return L_GET_CPP_PTR_FROM_C_OBJECT(searchResult)->getWeight();
|
||||
}
|
||||
|
|
@ -39,8 +39,10 @@
|
|||
F(Core, Core) \
|
||||
F(DialPlan, DialPlan) \
|
||||
F(EventLog, EventLog) \
|
||||
F(MagicSearch, MagicSearch) \
|
||||
F(MediaSessionParams, CallParams) \
|
||||
F(Participant, Participant)
|
||||
F(Participant, Participant) \
|
||||
F(SearchResult, SearchResult)
|
||||
|
||||
#define L_REGISTER_SUBTYPES(F) \
|
||||
F(AbstractChatRoom, BasicChatRoom) \
|
||||
|
|
@ -87,6 +89,7 @@ BELLE_SIP_TYPE_ID(LinphoneContent),
|
|||
BELLE_SIP_TYPE_ID(LinphoneCoreCbs),
|
||||
BELLE_SIP_TYPE_ID(LinphoneErrorInfo),
|
||||
BELLE_SIP_TYPE_ID(LinphoneEvent),
|
||||
BELLE_SIP_TYPE_ID(LinphoneEventCbs),
|
||||
BELLE_SIP_TYPE_ID(LinphoneFactory),
|
||||
BELLE_SIP_TYPE_ID(LinphoneFriend),
|
||||
BELLE_SIP_TYPE_ID(LinphoneFriendList),
|
||||
|
|
|
|||
|
|
@ -155,7 +155,7 @@ private:
|
|||
// Runtime checker.
|
||||
// ---------------------------------------------------------------------------
|
||||
|
||||
static inline void abort (const char *message) {
|
||||
[[noreturn]] static inline void abort (const char *message) {
|
||||
std::cerr << "[FATAL C-WRAPPER]" << message << std::endl;
|
||||
std::terminate();
|
||||
}
|
||||
|
|
@ -338,7 +338,7 @@ public:
|
|||
typename = typename std::enable_if<IsDefinedBaseCppObject<CppType>::value, CppType>::type
|
||||
>
|
||||
static inline std::shared_ptr<const CppType> getCppPtrFromC (const CType *cObject) {
|
||||
return getCppPtrFromC<CType, CppType>(const_cast<CType *>(cObject));
|
||||
return getCppPtrFromC<typename std::remove_const<CType>::type, CppType>(const_cast<CType *>(cObject));
|
||||
}
|
||||
|
||||
template<
|
||||
|
|
@ -562,7 +562,7 @@ public:
|
|||
static inline bctbx_list_t *getResolvedCListFromCppList (const std::list<CppType> &cppList) {
|
||||
bctbx_list_t *result = nullptr;
|
||||
for (const auto &value : cppList)
|
||||
result = bctbx_list_append(result, belle_sip_object_ref(getCBackPtr(&value)));
|
||||
result = bctbx_list_append(result, getCBackPtr(&value));
|
||||
return result;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -24,6 +24,7 @@
|
|||
#include "conference/conference.h"
|
||||
#include "conference/session/call-session-listener.h"
|
||||
#include "object/object-p.h"
|
||||
#include "utils/background-task.h"
|
||||
|
||||
// TODO: Remove me later.
|
||||
#include "private.h"
|
||||
|
|
@ -33,11 +34,10 @@
|
|||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
class CallSession;
|
||||
class RealTimeTextChatRoom;
|
||||
|
||||
class CallPrivate : public ObjectPrivate, public CallSessionListener {
|
||||
public:
|
||||
CallPrivate () = default;
|
||||
|
||||
void initiateIncoming ();
|
||||
bool initiateOutgoing ();
|
||||
void iterate (time_t currentRealTime, bool oneSecondElapsed);
|
||||
|
|
@ -49,6 +49,7 @@ public:
|
|||
|
||||
virtual std::shared_ptr<CallSession> getActiveSession () const { return nullptr; }
|
||||
bool getAudioMuted () const;
|
||||
std::shared_ptr<RealTimeTextChatRoom> getChatRoom ();
|
||||
|
||||
LinphoneProxyConfig *getDestProxy () const;
|
||||
IceSession *getIceSession () const;
|
||||
|
|
@ -71,53 +72,57 @@ private:
|
|||
void terminateBecauseOfLostMedia ();
|
||||
|
||||
/* CallSessionListener */
|
||||
void onAckBeingSent (const std::shared_ptr<const CallSession> &session, LinphoneHeaders *headers) override;
|
||||
void onAckReceived (const std::shared_ptr<const CallSession> &session, LinphoneHeaders *headers) override;
|
||||
void onBackgroundTaskToBeStarted (const std::shared_ptr<const CallSession> &session) override;
|
||||
void onBackgroundTaskToBeStopped (const std::shared_ptr<const CallSession> &session) override;
|
||||
bool onCallSessionAccepted (const std::shared_ptr<const CallSession> &session) override;
|
||||
void onCallSessionConferenceStreamStarting (const std::shared_ptr<const CallSession> &session, bool mute) override;
|
||||
void onCallSessionConferenceStreamStopping (const std::shared_ptr<const CallSession> &session) override;
|
||||
void onCallSessionEarlyFailed (const std::shared_ptr<const CallSession> &session, LinphoneErrorInfo *ei) override;
|
||||
void onCallSessionSetReleased (const std::shared_ptr<const CallSession> &session) override;
|
||||
void onCallSessionSetTerminated (const std::shared_ptr<const CallSession> &session) override;
|
||||
void onCallSessionStartReferred (const std::shared_ptr<const CallSession> &session) override;
|
||||
void onCallSessionStateChanged (const std::shared_ptr<const CallSession> &session, CallSession::State state, const std::string &message) override;
|
||||
void onCallSessionTransferStateChanged (const std::shared_ptr<const CallSession> &session, CallSession::State state) override;
|
||||
void onCheckForAcceptation (const std::shared_ptr<const CallSession> &session) override;
|
||||
void onDtmfReceived (const std::shared_ptr<const CallSession> &session, char dtmf) override;
|
||||
void onIncomingCallSessionNotified (const std::shared_ptr<const CallSession> &session) override;
|
||||
void onIncomingCallSessionStarted (const std::shared_ptr<const CallSession> &session) override;
|
||||
void onIncomingCallSessionTimeoutCheck (const std::shared_ptr<const CallSession> &session, int elapsed, bool oneSecondElapsed) override;
|
||||
void onInfoReceived (const std::shared_ptr<const CallSession> &session, const LinphoneInfoMessage *im) override;
|
||||
void onNoMediaTimeoutCheck (const std::shared_ptr<const CallSession> &session, bool oneSecondElapsed) override;
|
||||
void onEncryptionChanged (const std::shared_ptr<const CallSession> &session, bool activated, const std::string &authToken) override;
|
||||
void onCallSessionStateChangedForReporting (const std::shared_ptr<const CallSession> &session) override;
|
||||
void onRtcpUpdateForReporting (const std::shared_ptr<const CallSession> &session, SalStreamType type) override;
|
||||
void onStatsUpdated (const std::shared_ptr<const CallSession> &session, const LinphoneCallStats *stats) override;
|
||||
void onUpdateMediaInfoForReporting (const std::shared_ptr<const CallSession> &session, int statsType) override;
|
||||
void onResetCurrentSession (const std::shared_ptr<const CallSession> &session) override;
|
||||
void onSetCurrentSession (const std::shared_ptr<const CallSession> &session) override;
|
||||
void onFirstVideoFrameDecoded (const std::shared_ptr<const CallSession> &session) override;
|
||||
void onResetFirstVideoFrameDecoded (const std::shared_ptr<const CallSession> &session) override;
|
||||
void onPlayErrorTone (const std::shared_ptr<const CallSession> &session, LinphoneReason reason) override;
|
||||
void onRingbackToneRequested (const std::shared_ptr<const CallSession> &session, bool requested) override;
|
||||
void onStartRinging (const std::shared_ptr<const CallSession> &session) override;
|
||||
void onStopRinging (const std::shared_ptr<const CallSession> &session) override;
|
||||
void onStopRingingIfInCall (const std::shared_ptr<const CallSession> &session) override;
|
||||
void onStopRingingIfNeeded (const std::shared_ptr<const CallSession> &session) override;
|
||||
bool areSoundResourcesAvailable (const std::shared_ptr<const CallSession> &session) override;
|
||||
bool isPlayingRingbackTone (const std::shared_ptr<const CallSession> &session) override;
|
||||
void onAckBeingSent (const std::shared_ptr<CallSession> &session, LinphoneHeaders *headers) override;
|
||||
void onAckReceived (const std::shared_ptr<CallSession> &session, LinphoneHeaders *headers) override;
|
||||
void onBackgroundTaskToBeStarted (const std::shared_ptr<CallSession> &session) override;
|
||||
void onBackgroundTaskToBeStopped (const std::shared_ptr<CallSession> &session) override;
|
||||
bool onCallSessionAccepted (const std::shared_ptr<CallSession> &session) override;
|
||||
void onCallSessionConferenceStreamStarting (const std::shared_ptr<CallSession> &session, bool mute) override;
|
||||
void onCallSessionConferenceStreamStopping (const std::shared_ptr<CallSession> &session) override;
|
||||
void onCallSessionEarlyFailed (const std::shared_ptr<CallSession> &session, LinphoneErrorInfo *ei) override;
|
||||
void onCallSessionSetReleased (const std::shared_ptr<CallSession> &session) override;
|
||||
void onCallSessionSetTerminated (const std::shared_ptr<CallSession> &session) override;
|
||||
void onCallSessionStartReferred (const std::shared_ptr<CallSession> &session) override;
|
||||
void onCallSessionStateChanged (const std::shared_ptr<CallSession> &session, CallSession::State state, const std::string &message) override;
|
||||
void onCallSessionTransferStateChanged (const std::shared_ptr<CallSession> &session, CallSession::State state) override;
|
||||
void onCheckForAcceptation (const std::shared_ptr<CallSession> &session) override;
|
||||
void onDtmfReceived (const std::shared_ptr<CallSession> &session, char dtmf) override;
|
||||
void onIncomingCallSessionNotified (const std::shared_ptr<CallSession> &session) override;
|
||||
void onIncomingCallSessionStarted (const std::shared_ptr<CallSession> &session) override;
|
||||
void onIncomingCallSessionTimeoutCheck (const std::shared_ptr<CallSession> &session, int elapsed, bool oneSecondElapsed) override;
|
||||
void onInfoReceived (const std::shared_ptr<CallSession> &session, const LinphoneInfoMessage *im) override;
|
||||
void onNoMediaTimeoutCheck (const std::shared_ptr<CallSession> &session, bool oneSecondElapsed) override;
|
||||
void onEncryptionChanged (const std::shared_ptr<CallSession> &session, bool activated, const std::string &authToken) override;
|
||||
void onCallSessionStateChangedForReporting (const std::shared_ptr<CallSession> &session) override;
|
||||
void onRtcpUpdateForReporting (const std::shared_ptr<CallSession> &session, SalStreamType type) override;
|
||||
void onStatsUpdated (const std::shared_ptr<CallSession> &session, const LinphoneCallStats *stats) override;
|
||||
void onUpdateMediaInfoForReporting (const std::shared_ptr<CallSession> &session, int statsType) override;
|
||||
void onResetCurrentSession (const std::shared_ptr<CallSession> &session) override;
|
||||
void onSetCurrentSession (const std::shared_ptr<CallSession> &session) override;
|
||||
void onFirstVideoFrameDecoded (const std::shared_ptr<CallSession> &session) override;
|
||||
void onResetFirstVideoFrameDecoded (const std::shared_ptr<CallSession> &session) override;
|
||||
void onPlayErrorTone (const std::shared_ptr<CallSession> &session, LinphoneReason reason) override;
|
||||
void onRingbackToneRequested (const std::shared_ptr<CallSession> &session, bool requested) override;
|
||||
void onStartRinging (const std::shared_ptr<CallSession> &session) override;
|
||||
void onStopRinging (const std::shared_ptr<CallSession> &session) override;
|
||||
void onStopRingingIfInCall (const std::shared_ptr<CallSession> &session) override;
|
||||
void onStopRingingIfNeeded (const std::shared_ptr<CallSession> &session) override;
|
||||
bool areSoundResourcesAvailable (const std::shared_ptr<CallSession> &session) override;
|
||||
bool isPlayingRingbackTone (const std::shared_ptr<CallSession> &session) override;
|
||||
void onRealTimeTextCharacterReceived (const std::shared_ptr<CallSession> &session, RealtimeTextReceivedCharacter *character) override;
|
||||
void onTmmbrReceived(const std::shared_ptr<CallSession> &session, int streamIndex, int tmmbr) override;
|
||||
|
||||
mutable LinphonePlayer *player = nullptr;
|
||||
|
||||
CallCallbackObj nextVideoFrameDecoded;
|
||||
|
||||
unsigned long backgroundTaskId = 0;
|
||||
|
||||
bool ringingBeep = false;
|
||||
bool playingRingbackTone = false;
|
||||
|
||||
BackgroundTask bgTask;
|
||||
|
||||
mutable std::shared_ptr<RealTimeTextChatRoom> chatRoom;
|
||||
|
||||
L_DECLARE_PUBLIC(Call);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -19,6 +19,7 @@
|
|||
|
||||
#include "c-wrapper/c-wrapper.h"
|
||||
#include "call-p.h"
|
||||
#include "chat/chat-room/real-time-text-chat-room-p.h"
|
||||
#include "conference/params/media-session-params-p.h"
|
||||
#include "conference/session/call-session-p.h"
|
||||
#include "conference/session/media-session-p.h"
|
||||
|
|
@ -37,6 +38,17 @@ bool CallPrivate::getAudioMuted () const {
|
|||
return static_pointer_cast<MediaSession>(getActiveSession())->getPrivate()->getAudioMuted();
|
||||
}
|
||||
|
||||
shared_ptr<RealTimeTextChatRoom> CallPrivate::getChatRoom () {
|
||||
L_Q();
|
||||
if (!chatRoom && (q->getState() != CallSession::State::End) && (q->getState() != CallSession::State::Released)) {
|
||||
ChatRoomId chatRoomId(q->getRemoteAddress(), q->getLocalAddress());
|
||||
RealTimeTextChatRoom *rttcr = new RealTimeTextChatRoom(q->getCore(), chatRoomId);
|
||||
chatRoom.reset(rttcr);
|
||||
rttcr->getPrivate()->setCall(q->getSharedFromThis());
|
||||
}
|
||||
return chatRoom;
|
||||
}
|
||||
|
||||
LinphoneProxyConfig *CallPrivate::getDestProxy () const {
|
||||
return getActiveSession()->getPrivate()->getDestProxy();
|
||||
}
|
||||
|
|
@ -167,7 +179,7 @@ void CallPrivate::startRemoteRing () {
|
|||
|
||||
void CallPrivate::terminateBecauseOfLostMedia () {
|
||||
L_Q();
|
||||
lInfo() << "Call [" << q << "]: Media connectivity with " << q->getRemoteAddressAsString()
|
||||
lInfo() << "Call [" << q << "]: Media connectivity with " << q->getRemoteAddress().asString()
|
||||
<< " is lost, call is going to be terminated";
|
||||
static_pointer_cast<MediaSession>(getActiveSession())->terminateBecauseOfLostMedia();
|
||||
linphone_core_play_named_tone(q->getCore()->getCCore(), LinphoneToneCallLost);
|
||||
|
|
@ -175,28 +187,26 @@ void CallPrivate::terminateBecauseOfLostMedia () {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void CallPrivate::onAckBeingSent (const shared_ptr<const CallSession> &session, LinphoneHeaders *headers) {
|
||||
void CallPrivate::onAckBeingSent (const shared_ptr<CallSession> &session, LinphoneHeaders *headers) {
|
||||
L_Q();
|
||||
linphone_call_notify_ack_processing(L_GET_C_BACK_PTR(q), headers, false);
|
||||
}
|
||||
|
||||
void CallPrivate::onAckReceived (const shared_ptr<const CallSession> &session, LinphoneHeaders *headers) {
|
||||
void CallPrivate::onAckReceived (const shared_ptr<CallSession> &session, LinphoneHeaders *headers) {
|
||||
L_Q();
|
||||
linphone_call_notify_ack_processing(L_GET_C_BACK_PTR(q), headers, true);
|
||||
}
|
||||
|
||||
void CallPrivate::onBackgroundTaskToBeStarted (const shared_ptr<const CallSession> &session) {
|
||||
backgroundTaskId = sal_begin_background_task("liblinphone call notification", nullptr, nullptr);
|
||||
void CallPrivate::onBackgroundTaskToBeStarted (const shared_ptr<CallSession> &session) {
|
||||
L_Q();
|
||||
bgTask.start(q->getCore(),30);
|
||||
}
|
||||
|
||||
void CallPrivate::onBackgroundTaskToBeStopped (const shared_ptr<const CallSession> &session) {
|
||||
if (backgroundTaskId != 0) {
|
||||
sal_end_background_task(backgroundTaskId);
|
||||
backgroundTaskId = 0;
|
||||
}
|
||||
void CallPrivate::onBackgroundTaskToBeStopped (const shared_ptr<CallSession> &session) {
|
||||
bgTask.stop();
|
||||
}
|
||||
|
||||
bool CallPrivate::onCallSessionAccepted (const shared_ptr<const CallSession> &session) {
|
||||
bool CallPrivate::onCallSessionAccepted (const shared_ptr<CallSession> &session) {
|
||||
L_Q();
|
||||
LinphoneCore *lc = q->getCore()->getCCore();
|
||||
bool wasRinging = false;
|
||||
|
|
@ -217,21 +227,21 @@ bool CallPrivate::onCallSessionAccepted (const shared_ptr<const CallSession> &se
|
|||
return wasRinging;
|
||||
}
|
||||
|
||||
void CallPrivate::onCallSessionConferenceStreamStarting (const shared_ptr<const CallSession> &session, bool mute) {
|
||||
void CallPrivate::onCallSessionConferenceStreamStarting (const shared_ptr<CallSession> &session, bool mute) {
|
||||
L_Q();
|
||||
if (q->getCore()->getCCore()->conf_ctx) {
|
||||
linphone_conference_on_call_stream_starting(q->getCore()->getCCore()->conf_ctx, L_GET_C_BACK_PTR(q), mute);
|
||||
}
|
||||
}
|
||||
|
||||
void CallPrivate::onCallSessionConferenceStreamStopping (const shared_ptr<const CallSession> &session) {
|
||||
void CallPrivate::onCallSessionConferenceStreamStopping (const shared_ptr<CallSession> &session) {
|
||||
L_Q();
|
||||
LinphoneCore *lc = q->getCore()->getCCore();
|
||||
if (lc->conf_ctx && _linphone_call_get_endpoint(L_GET_C_BACK_PTR(q)))
|
||||
linphone_conference_on_call_stream_stopping(lc->conf_ctx, L_GET_C_BACK_PTR(q));
|
||||
}
|
||||
|
||||
void CallPrivate::onCallSessionEarlyFailed (const shared_ptr<const CallSession> &session, LinphoneErrorInfo *ei) {
|
||||
void CallPrivate::onCallSessionEarlyFailed (const shared_ptr<CallSession> &session, LinphoneErrorInfo *ei) {
|
||||
L_Q();
|
||||
LinphoneCallLog *log = session->getLog();
|
||||
linphone_core_report_early_failed_call(q->getCore()->getCCore(),
|
||||
|
|
@ -242,12 +252,12 @@ void CallPrivate::onCallSessionEarlyFailed (const shared_ptr<const CallSession>
|
|||
linphone_call_unref(L_GET_C_BACK_PTR(q));
|
||||
}
|
||||
|
||||
void CallPrivate::onCallSessionSetReleased (const shared_ptr<const CallSession> &session) {
|
||||
void CallPrivate::onCallSessionSetReleased (const shared_ptr<CallSession> &session) {
|
||||
L_Q();
|
||||
linphone_call_unref(L_GET_C_BACK_PTR(q));
|
||||
}
|
||||
|
||||
void CallPrivate::onCallSessionSetTerminated (const shared_ptr<const CallSession> &session) {
|
||||
void CallPrivate::onCallSessionSetTerminated (const shared_ptr<CallSession> &session) {
|
||||
L_Q();
|
||||
LinphoneCore *core = q->getCore()->getCCore();
|
||||
if (q->getSharedFromThis() == q->getCore()->getCurrentCall()) {
|
||||
|
|
@ -270,60 +280,74 @@ void CallPrivate::onCallSessionSetTerminated (const shared_ptr<const CallSession
|
|||
ms_bandwidth_controller_reset_state(core->bw_controller);
|
||||
}
|
||||
|
||||
void CallPrivate::onCallSessionStartReferred (const shared_ptr<const CallSession> &session) {
|
||||
void CallPrivate::onCallSessionStartReferred (const shared_ptr<CallSession> &session) {
|
||||
startReferredCall(nullptr);
|
||||
}
|
||||
|
||||
void CallPrivate::onCallSessionStateChanged (const shared_ptr<const CallSession> &session, CallSession::State state, const string &message) {
|
||||
void CallPrivate::onCallSessionStateChanged (const shared_ptr<CallSession> &session, CallSession::State state, const string &message) {
|
||||
L_Q();
|
||||
switch(state){
|
||||
case CallSession::State::OutgoingInit:
|
||||
case CallSession::State::IncomingReceived:
|
||||
getPlatformHelpers(q->getCore()->getCCore())->acquireWifiLock();
|
||||
getPlatformHelpers(q->getCore()->getCCore())->acquireMcastLock();
|
||||
getPlatformHelpers(q->getCore()->getCCore())->acquireCpuLock();
|
||||
break;
|
||||
case CallSession::State::Released:
|
||||
getPlatformHelpers(q->getCore()->getCCore())->releaseWifiLock();
|
||||
getPlatformHelpers(q->getCore()->getCCore())->releaseMcastLock();
|
||||
getPlatformHelpers(q->getCore()->getCCore())->releaseCpuLock();
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
linphone_call_notify_state_changed(L_GET_C_BACK_PTR(q), static_cast<LinphoneCallState>(state), message.c_str());
|
||||
}
|
||||
|
||||
void CallPrivate::onCallSessionTransferStateChanged (const shared_ptr<const CallSession> &session, CallSession::State state) {
|
||||
void CallPrivate::onCallSessionTransferStateChanged (const shared_ptr<CallSession> &session, CallSession::State state) {
|
||||
L_Q();
|
||||
linphone_call_notify_transfer_state_changed(L_GET_C_BACK_PTR(q), static_cast<LinphoneCallState>(state));
|
||||
}
|
||||
|
||||
void CallPrivate::onCheckForAcceptation (const shared_ptr<const CallSession> &session) {
|
||||
void CallPrivate::onCheckForAcceptation (const shared_ptr<CallSession> &session) {
|
||||
L_Q();
|
||||
LinphoneCall *lcall = L_GET_C_BACK_PTR(q);
|
||||
bctbx_list_t *copy = bctbx_list_copy(linphone_core_get_calls(q->getCore()->getCCore()));
|
||||
for (bctbx_list_t *it = copy; it != nullptr; it = bctbx_list_next(it)) {
|
||||
LinphoneCall *call = reinterpret_cast<LinphoneCall *>(bctbx_list_get_data(it));
|
||||
if (call == lcall) continue;
|
||||
switch (L_GET_CPP_PTR_FROM_C_OBJECT(call)->getState()) {
|
||||
list<shared_ptr<Call>> calls = q->getCore()->getCalls();
|
||||
shared_ptr<Call> currentCall = q->getSharedFromThis();
|
||||
for (const auto &call : calls) {
|
||||
if (call == currentCall)
|
||||
continue;
|
||||
switch (call->getState()) {
|
||||
case CallSession::State::OutgoingInit:
|
||||
case CallSession::State::OutgoingProgress:
|
||||
case CallSession::State::OutgoingRinging:
|
||||
case CallSession::State::OutgoingEarlyMedia:
|
||||
lInfo() << "Already existing call [" << call << "] in state [" << linphone_call_state_to_string(linphone_call_get_state(call)) <<
|
||||
"], canceling it before accepting new call [" << lcall << "]";
|
||||
linphone_call_terminate(call);
|
||||
lInfo() << "Already existing call [" << call << "] in state [" << Utils::toString(call->getState())
|
||||
<< "], canceling it before accepting new call [" << currentCall << "]";
|
||||
call->terminate();
|
||||
break;
|
||||
default:
|
||||
break; /* Nothing to do */
|
||||
break; // Nothing to do
|
||||
}
|
||||
}
|
||||
bctbx_list_free(copy);
|
||||
}
|
||||
|
||||
void CallPrivate::onDtmfReceived (const shared_ptr<const CallSession> &session, char dtmf) {
|
||||
void CallPrivate::onDtmfReceived (const shared_ptr<CallSession> &session, char dtmf) {
|
||||
L_Q();
|
||||
linphone_call_notify_dtmf_received(L_GET_C_BACK_PTR(q), dtmf);
|
||||
}
|
||||
|
||||
void CallPrivate::onIncomingCallSessionNotified (const shared_ptr<const CallSession> &session) {
|
||||
void CallPrivate::onIncomingCallSessionNotified (const shared_ptr<CallSession> &session) {
|
||||
L_Q();
|
||||
/* The call is acceptable so we can now add it to our list */
|
||||
q->getCore()->getPrivate()->addCall(q->getSharedFromThis());
|
||||
}
|
||||
|
||||
void CallPrivate::onIncomingCallSessionStarted (const shared_ptr<const CallSession> &session) {
|
||||
void CallPrivate::onIncomingCallSessionStarted (const shared_ptr<CallSession> &session) {
|
||||
L_Q();
|
||||
linphone_core_notify_incoming_call(q->getCore()->getCCore(), L_GET_C_BACK_PTR(q));
|
||||
}
|
||||
|
||||
void CallPrivate::onIncomingCallSessionTimeoutCheck (const shared_ptr<const CallSession> &session, int elapsed, bool oneSecondElapsed) {
|
||||
void CallPrivate::onIncomingCallSessionTimeoutCheck (const shared_ptr<CallSession> &session, int elapsed, bool oneSecondElapsed) {
|
||||
L_Q();
|
||||
if (oneSecondElapsed)
|
||||
lInfo() << "Incoming call ringing for " << elapsed << " seconds";
|
||||
|
|
@ -335,12 +359,12 @@ void CallPrivate::onIncomingCallSessionTimeoutCheck (const shared_ptr<const Call
|
|||
}
|
||||
}
|
||||
|
||||
void CallPrivate::onInfoReceived (const shared_ptr<const CallSession> &session, const LinphoneInfoMessage *im) {
|
||||
void CallPrivate::onInfoReceived (const shared_ptr<CallSession> &session, const LinphoneInfoMessage *im) {
|
||||
L_Q();
|
||||
linphone_call_notify_info_message_received(L_GET_C_BACK_PTR(q), im);
|
||||
}
|
||||
|
||||
void CallPrivate::onNoMediaTimeoutCheck (const shared_ptr<const CallSession> &session, bool oneSecondElapsed) {
|
||||
void CallPrivate::onNoMediaTimeoutCheck (const shared_ptr<CallSession> &session, bool oneSecondElapsed) {
|
||||
L_Q();
|
||||
int disconnectTimeout = linphone_core_get_nortp_timeout(q->getCore()->getCCore());
|
||||
bool disconnected = false;
|
||||
|
|
@ -352,42 +376,42 @@ void CallPrivate::onNoMediaTimeoutCheck (const shared_ptr<const CallSession> &se
|
|||
terminateBecauseOfLostMedia();
|
||||
}
|
||||
|
||||
void CallPrivate::onEncryptionChanged (const shared_ptr<const CallSession> &session, bool activated, const string &authToken) {
|
||||
void CallPrivate::onEncryptionChanged (const shared_ptr<CallSession> &session, bool activated, const string &authToken) {
|
||||
L_Q();
|
||||
linphone_call_notify_encryption_changed(L_GET_C_BACK_PTR(q), activated, authToken.empty() ? nullptr : authToken.c_str());
|
||||
}
|
||||
|
||||
void CallPrivate::onCallSessionStateChangedForReporting (const shared_ptr<const CallSession> &session) {
|
||||
void CallPrivate::onCallSessionStateChangedForReporting (const shared_ptr<CallSession> &session) {
|
||||
L_Q();
|
||||
linphone_reporting_call_state_updated(L_GET_C_BACK_PTR(q));
|
||||
}
|
||||
|
||||
void CallPrivate::onRtcpUpdateForReporting (const shared_ptr<const CallSession> &session, SalStreamType type) {
|
||||
void CallPrivate::onRtcpUpdateForReporting (const shared_ptr<CallSession> &session, SalStreamType type) {
|
||||
L_Q();
|
||||
linphone_reporting_on_rtcp_update(L_GET_C_BACK_PTR(q), type);
|
||||
}
|
||||
|
||||
void CallPrivate::onStatsUpdated (const shared_ptr<const CallSession> &session, const LinphoneCallStats *stats) {
|
||||
void CallPrivate::onStatsUpdated (const shared_ptr<CallSession> &session, const LinphoneCallStats *stats) {
|
||||
L_Q();
|
||||
linphone_call_notify_stats_updated(L_GET_C_BACK_PTR(q), stats);
|
||||
}
|
||||
|
||||
void CallPrivate::onUpdateMediaInfoForReporting (const std::shared_ptr<const CallSession> &session, int statsType) {
|
||||
void CallPrivate::onUpdateMediaInfoForReporting (const shared_ptr<CallSession> &session, int statsType) {
|
||||
L_Q();
|
||||
linphone_reporting_update_media_info(L_GET_C_BACK_PTR(q), statsType);
|
||||
}
|
||||
|
||||
void CallPrivate::onResetCurrentSession (const shared_ptr<const CallSession> &session) {
|
||||
void CallPrivate::onResetCurrentSession (const shared_ptr<CallSession> &session) {
|
||||
L_Q();
|
||||
q->getCore()->getPrivate()->setCurrentCall(nullptr);
|
||||
}
|
||||
|
||||
void CallPrivate::onSetCurrentSession (const shared_ptr<const CallSession> &session) {
|
||||
void CallPrivate::onSetCurrentSession (const shared_ptr<CallSession> &session) {
|
||||
L_Q();
|
||||
q->getCore()->getPrivate()->setCurrentCall(q->getSharedFromThis());
|
||||
}
|
||||
|
||||
void CallPrivate::onFirstVideoFrameDecoded (const shared_ptr<const CallSession> &session) {
|
||||
void CallPrivate::onFirstVideoFrameDecoded (const shared_ptr<CallSession> &session) {
|
||||
L_Q();
|
||||
if (nextVideoFrameDecoded._func) {
|
||||
nextVideoFrameDecoded._func(L_GET_C_BACK_PTR(q), nextVideoFrameDecoded._user_data);
|
||||
|
|
@ -396,16 +420,16 @@ void CallPrivate::onFirstVideoFrameDecoded (const shared_ptr<const CallSession>
|
|||
}
|
||||
}
|
||||
|
||||
void CallPrivate::onResetFirstVideoFrameDecoded (const shared_ptr<const CallSession> &session) {
|
||||
void CallPrivate::onResetFirstVideoFrameDecoded (const shared_ptr<CallSession> &session) {
|
||||
resetFirstVideoFrameDecoded();
|
||||
}
|
||||
|
||||
void CallPrivate::onPlayErrorTone (const shared_ptr<const CallSession> &session, LinphoneReason reason) {
|
||||
void CallPrivate::onPlayErrorTone (const shared_ptr<CallSession> &session, LinphoneReason reason) {
|
||||
L_Q();
|
||||
linphone_core_play_call_error_tone(q->getCore()->getCCore(), reason);
|
||||
}
|
||||
|
||||
void CallPrivate::onRingbackToneRequested (const shared_ptr<const CallSession> &session, bool requested) {
|
||||
void CallPrivate::onRingbackToneRequested (const shared_ptr<CallSession> &session, bool requested) {
|
||||
L_Q();
|
||||
if (requested && linphone_core_get_remote_ringback_tone(q->getCore()->getCCore()))
|
||||
playingRingbackTone = true;
|
||||
|
|
@ -413,7 +437,7 @@ void CallPrivate::onRingbackToneRequested (const shared_ptr<const CallSession> &
|
|||
playingRingbackTone = false;
|
||||
}
|
||||
|
||||
void CallPrivate::onStartRinging (const shared_ptr<const CallSession> &session) {
|
||||
void CallPrivate::onStartRinging (const shared_ptr<CallSession> &session) {
|
||||
L_Q();
|
||||
LinphoneCore *lc = q->getCore()->getCCore();
|
||||
if (lc->ringstream)
|
||||
|
|
@ -421,12 +445,12 @@ void CallPrivate::onStartRinging (const shared_ptr<const CallSession> &session)
|
|||
startRemoteRing();
|
||||
}
|
||||
|
||||
void CallPrivate::onStopRinging (const shared_ptr<const CallSession> &session) {
|
||||
void CallPrivate::onStopRinging (const shared_ptr<CallSession> &session) {
|
||||
L_Q();
|
||||
linphone_core_stop_ringing(q->getCore()->getCCore());
|
||||
}
|
||||
|
||||
void CallPrivate::onStopRingingIfInCall (const shared_ptr<const CallSession> &session) {
|
||||
void CallPrivate::onStopRingingIfInCall (const shared_ptr<CallSession> &session) {
|
||||
L_Q();
|
||||
LinphoneCore *lc = q->getCore()->getCCore();
|
||||
// We stop the ring only if we have this current call or if we are in call
|
||||
|
|
@ -435,7 +459,7 @@ void CallPrivate::onStopRingingIfInCall (const shared_ptr<const CallSession> &se
|
|||
}
|
||||
}
|
||||
|
||||
void CallPrivate::onStopRingingIfNeeded (const shared_ptr<const CallSession> &session) {
|
||||
void CallPrivate::onStopRingingIfNeeded (const shared_ptr<CallSession> &session) {
|
||||
L_Q();
|
||||
LinphoneCore *lc = q->getCore()->getCCore();
|
||||
bool stopRinging = true;
|
||||
|
|
@ -451,23 +475,35 @@ void CallPrivate::onStopRingingIfNeeded (const shared_ptr<const CallSession> &se
|
|||
linphone_core_stop_ringing(lc);
|
||||
}
|
||||
|
||||
bool CallPrivate::areSoundResourcesAvailable (const shared_ptr<const CallSession> &session) {
|
||||
bool CallPrivate::areSoundResourcesAvailable (const shared_ptr<CallSession> &session) {
|
||||
L_Q();
|
||||
LinphoneCore *lc = q->getCore()->getCCore();
|
||||
shared_ptr<Call> currentCall = q->getCore()->getCurrentCall();
|
||||
return !linphone_core_is_in_conference(lc) && (!currentCall || (currentCall == q->getSharedFromThis()));
|
||||
}
|
||||
|
||||
bool CallPrivate::isPlayingRingbackTone (const shared_ptr<const CallSession> &session) {
|
||||
bool CallPrivate::isPlayingRingbackTone (const shared_ptr<CallSession> &session) {
|
||||
return playingRingbackTone;
|
||||
}
|
||||
|
||||
void CallPrivate::onRealTimeTextCharacterReceived (const shared_ptr<CallSession> &session, RealtimeTextReceivedCharacter *data) {
|
||||
L_Q();
|
||||
getChatRoom()->getPrivate()->realtimeTextReceived(data->character, q->getSharedFromThis());
|
||||
}
|
||||
|
||||
void CallPrivate::onTmmbrReceived (const shared_ptr<CallSession> &session, int streamIndex, int tmmbr) {
|
||||
L_Q();
|
||||
linphone_call_notify_tmmbr_received(L_GET_C_BACK_PTR(q), streamIndex, tmmbr);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
Call::Call (CallPrivate &p, shared_ptr<Core> core) : Object(p), CoreAccessor(core) {
|
||||
L_D();
|
||||
d->nextVideoFrameDecoded._func = nullptr;
|
||||
d->nextVideoFrameDecoded._user_data = nullptr;
|
||||
|
||||
d->bgTask.setName("Liblinphone call notification");
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -522,7 +558,7 @@ LinphoneStatus Call::pause () {
|
|||
return static_pointer_cast<MediaSession>(d->getActiveSession())->pause();
|
||||
}
|
||||
|
||||
LinphoneStatus Call::redirect (const std::string &redirectUri) {
|
||||
LinphoneStatus Call::redirect (const string &redirectUri) {
|
||||
L_D();
|
||||
return d->getActiveSession()->redirect(redirectUri);
|
||||
}
|
||||
|
|
@ -537,7 +573,7 @@ LinphoneStatus Call::sendDtmf (char dtmf) {
|
|||
return static_pointer_cast<MediaSession>(d->getActiveSession())->sendDtmf(dtmf);
|
||||
}
|
||||
|
||||
LinphoneStatus Call::sendDtmfs (const std::string &dtmfs) {
|
||||
LinphoneStatus Call::sendDtmfs (const string &dtmfs) {
|
||||
L_D();
|
||||
return static_pointer_cast<MediaSession>(d->getActiveSession())->sendDtmfs(dtmfs);
|
||||
}
|
||||
|
|
@ -683,6 +719,11 @@ const LinphoneErrorInfo *Call::getErrorInfo () const {
|
|||
return d->getActiveSession()->getErrorInfo();
|
||||
}
|
||||
|
||||
const Address &Call::getLocalAddress () const {
|
||||
L_D();
|
||||
return d->getActiveSession()->getLocalAddress();
|
||||
}
|
||||
|
||||
LinphoneCallLog *Call::getLog () const {
|
||||
L_D();
|
||||
return d->getActiveSession()->getLog();
|
||||
|
|
@ -757,11 +798,6 @@ const Address &Call::getRemoteAddress () const {
|
|||
return d->getActiveSession()->getRemoteAddress();
|
||||
}
|
||||
|
||||
string Call::getRemoteAddressAsString () const {
|
||||
L_D();
|
||||
return d->getActiveSession()->getRemoteAddressAsString();
|
||||
}
|
||||
|
||||
string Call::getRemoteContact () const {
|
||||
L_D();
|
||||
return d->getActiveSession()->getRemoteContact();
|
||||
|
|
@ -824,7 +860,7 @@ const Address &Call::getToAddress () const {
|
|||
return d->getActiveSession()->getToAddress();
|
||||
}
|
||||
|
||||
string Call::getToHeader (const std::string &name) const {
|
||||
string Call::getToHeader (const string &name) const {
|
||||
L_D();
|
||||
return d->getActiveSession()->getToHeader(name);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,6 +36,8 @@ class MediaSessionPrivate;
|
|||
|
||||
class Call : public Object, public CoreAccessor {
|
||||
friend class CallSessionPrivate;
|
||||
friend class ChatMessage;
|
||||
friend class ChatMessagePrivate;
|
||||
friend class CorePrivate;
|
||||
friend class MediaSessionPrivate;
|
||||
|
||||
|
|
@ -85,6 +87,7 @@ public:
|
|||
const Address &getDiversionAddress () const;
|
||||
int getDuration () const;
|
||||
const LinphoneErrorInfo *getErrorInfo () const;
|
||||
const Address &getLocalAddress () const;
|
||||
LinphoneCallLog *getLog () const;
|
||||
RtpTransport *getMetaRtcpTransport (int streamIndex) const;
|
||||
RtpTransport *getMetaRtpTransport (int streamIndex) const;
|
||||
|
|
@ -98,7 +101,6 @@ public:
|
|||
std::shared_ptr<Call> getReferer () const;
|
||||
std::string getReferTo () const;
|
||||
const Address &getRemoteAddress () const;
|
||||
std::string getRemoteAddressAsString () const;
|
||||
std::string getRemoteContact () const;
|
||||
const MediaSessionParams *getRemoteParams () const;
|
||||
std::string getRemoteUserAgent () const;
|
||||
|
|
|
|||
|
|
@ -29,8 +29,6 @@ LINPHONE_BEGIN_NAMESPACE
|
|||
|
||||
class LocalConferenceCallPrivate : public CallPrivate {
|
||||
public:
|
||||
LocalConferenceCallPrivate () = default;
|
||||
|
||||
std::shared_ptr<CallSession> getActiveSession () const override;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -29,8 +29,6 @@ LINPHONE_BEGIN_NAMESPACE
|
|||
|
||||
class RemoteConferenceCallPrivate : public CallPrivate {
|
||||
public:
|
||||
RemoteConferenceCallPrivate () = default;
|
||||
|
||||
std::shared_ptr<CallSession> getActiveSession () const override;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -42,7 +42,7 @@ public:
|
|||
SalCallOp *op,
|
||||
const MediaSessionParams *msp
|
||||
);
|
||||
virtual ~RemoteConferenceCall ();
|
||||
~RemoteConferenceCall ();
|
||||
|
||||
std::shared_ptr<Core> getCore () const;
|
||||
|
||||
|
|
|
|||
|
|
@ -54,13 +54,12 @@ public:
|
|||
Started = 1 << 5,
|
||||
};
|
||||
|
||||
ChatMessagePrivate () = default;
|
||||
|
||||
void setApplyModifiers (bool value) { applyModifiers = value; }
|
||||
|
||||
void setDirection (ChatMessage::Direction dir);
|
||||
|
||||
void setState (ChatMessage::State state, bool force = false);
|
||||
void setParticipantState (const IdentityAddress &participantAddress, ChatMessage::State newState);
|
||||
void setState (ChatMessage::State newState, bool force = false);
|
||||
|
||||
void setTime (time_t time);
|
||||
|
||||
|
|
@ -68,14 +67,30 @@ public:
|
|||
|
||||
void setImdnMessageId (const std::string &imdnMessageId);
|
||||
|
||||
inline void forceFromAddress (const IdentityAddress &fromAddress) {
|
||||
void forceFromAddress (const IdentityAddress &fromAddress) {
|
||||
this->fromAddress = fromAddress;
|
||||
}
|
||||
|
||||
inline void forceToAddress (const IdentityAddress &toAddress) {
|
||||
void forceToAddress (const IdentityAddress &toAddress) {
|
||||
this->toAddress = toAddress;
|
||||
}
|
||||
|
||||
void markContentsAsNotLoaded () {
|
||||
contentsNotLoadedFromDatabase = true;
|
||||
}
|
||||
|
||||
void loadContentsFromDatabase () const;
|
||||
|
||||
std::list<Content* > &getContents () {
|
||||
loadContentsFromDatabase();
|
||||
return contents;
|
||||
}
|
||||
|
||||
const std::list<Content* > &getContents () const {
|
||||
loadContentsFromDatabase();
|
||||
return contents;
|
||||
}
|
||||
|
||||
belle_http_request_t *getHttpRequest () const;
|
||||
void setHttpRequest (belle_http_request_t *request);
|
||||
|
||||
|
|
@ -85,11 +100,12 @@ public:
|
|||
SalCustomHeader *getSalCustomHeaders () const;
|
||||
void setSalCustomHeaders (SalCustomHeader *headers);
|
||||
|
||||
void addSalCustomHeader (const std::string& name, const std::string& value);
|
||||
void removeSalCustomHeader (const std::string& name);
|
||||
std::string getSalCustomHeaderValue (const std::string& name);
|
||||
void addSalCustomHeader (const std::string &name, const std::string &value);
|
||||
void removeSalCustomHeader (const std::string &name);
|
||||
std::string getSalCustomHeaderValue (const std::string &name);
|
||||
|
||||
void loadFileTransferUrlFromBodyToContent ();
|
||||
std::string createFakeFileTransferFromUrl(const std::string &url);
|
||||
|
||||
void setChatRoom (const std::shared_ptr<AbstractChatRoom> &chatRoom);
|
||||
|
||||
|
|
@ -112,6 +128,7 @@ public:
|
|||
void setAppdata (const std::string &appData);
|
||||
|
||||
const std::string &getExternalBodyUrl () const;
|
||||
void setExternalBodyUrl (const std::string &url);
|
||||
|
||||
bool hasTextContent () const;
|
||||
const Content* getTextContent () const;
|
||||
|
|
@ -122,6 +139,9 @@ public:
|
|||
LinphoneContent *getFileTransferInformation () const;
|
||||
void setFileTransferInformation (const LinphoneContent *content);
|
||||
|
||||
void addContent (Content &content);
|
||||
void removeContent (const Content &content);
|
||||
|
||||
bool downloadFile ();
|
||||
|
||||
void sendImdn (Imdn::Type imdnType, LinphoneReason reason);
|
||||
|
|
@ -134,15 +154,23 @@ public:
|
|||
void updateInDb ();
|
||||
|
||||
private:
|
||||
|
||||
ChatMessagePrivate(const std::shared_ptr<AbstractChatRoom> &cr, ChatMessage::Direction dir);
|
||||
|
||||
static bool validStateTransition (ChatMessage::State currentState, ChatMessage::State newState);
|
||||
|
||||
// TODO: Clean attributes.
|
||||
time_t time = ::ms_time(0); // TODO: Change me in all files.
|
||||
std::string imdnId;
|
||||
std::string rttMessage;
|
||||
std::string externalBodyUrl;
|
||||
bool isSecured = false;
|
||||
bool isReadOnly = false;
|
||||
std::list<Content* > contents;
|
||||
mutable bool isReadOnly = false;
|
||||
Content internalContent;
|
||||
|
||||
// TODO: to replace salCustomheaders
|
||||
std::unordered_map<std::string, std::string> customHeaders;
|
||||
|
||||
mutable LinphoneErrorInfo * errorInfo = nullptr;
|
||||
SalOp *salOp = nullptr;
|
||||
SalCustomHeader *salCustomHeaders = nullptr;
|
||||
|
|
@ -171,9 +199,11 @@ private:
|
|||
ChatMessage::State state = ChatMessage::State::Idle;
|
||||
ChatMessage::Direction direction = ChatMessage::Direction::Incoming;
|
||||
|
||||
std::list<Content* > contents;
|
||||
|
||||
bool encryptionPrevented = false;
|
||||
bool toBeStored = true;
|
||||
|
||||
mutable bool contentsNotLoadedFromDatabase = false;
|
||||
L_DECLARE_PUBLIC(ChatMessage);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -25,7 +25,7 @@
|
|||
|
||||
#include "address/address.h"
|
||||
#include "c-wrapper/c-wrapper.h"
|
||||
#include "call/call.h"
|
||||
#include "call/call-p.h"
|
||||
#include "chat/chat-message/chat-message-p.h"
|
||||
#include "chat/chat-room/chat-room-p.h"
|
||||
#include "chat/chat-room/client-group-to-basic-chat-room.h"
|
||||
|
|
@ -40,6 +40,7 @@
|
|||
#include "core/core-p.h"
|
||||
#include "logger/logger.h"
|
||||
#include "chat/notification/imdn.h"
|
||||
#include "sip-tools/sip-headers.h"
|
||||
|
||||
#include "ortp/b64.h"
|
||||
|
||||
|
|
@ -51,6 +52,11 @@ using namespace B64_NAMESPACE;
|
|||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
ChatMessagePrivate::ChatMessagePrivate(const std::shared_ptr<AbstractChatRoom> &cr, ChatMessage::Direction dir):fileTransferChatMessageModifier(cr->getCore()->getCCore()->http_provider) {
|
||||
direction = dir;
|
||||
setChatRoom(cr);
|
||||
}
|
||||
|
||||
void ChatMessagePrivate::setDirection (ChatMessage::Direction dir) {
|
||||
direction = dir;
|
||||
}
|
||||
|
|
@ -63,28 +69,71 @@ void ChatMessagePrivate::setIsReadOnly (bool readOnly) {
|
|||
isReadOnly = readOnly;
|
||||
}
|
||||
|
||||
void ChatMessagePrivate::setState (ChatMessage::State s, bool force) {
|
||||
void ChatMessagePrivate::setParticipantState (const IdentityAddress &participantAddress, ChatMessage::State newState) {
|
||||
L_Q();
|
||||
|
||||
if (!(q->getChatRoom()->getCapabilities() & AbstractChatRoom::Capabilities::Conference)
|
||||
|| (linphone_config_get_bool(linphone_core_get_config(q->getChatRoom()->getCore()->getCCore()),
|
||||
"misc", "enable_simple_group_chat_message_state", TRUE
|
||||
))
|
||||
) {
|
||||
setState(newState);
|
||||
return;
|
||||
}
|
||||
|
||||
if (!dbKey.isValid())
|
||||
return;
|
||||
|
||||
unique_ptr<MainDb> &mainDb = q->getChatRoom()->getCore()->getPrivate()->mainDb;
|
||||
shared_ptr<EventLog> eventLog = mainDb->getEventFromKey(dbKey);
|
||||
ChatMessage::State currentState = mainDb->getChatMessageParticipantState(eventLog, participantAddress);
|
||||
if (!validStateTransition(currentState, newState))
|
||||
return;
|
||||
|
||||
lInfo() << "Chat message " << this << ": moving participant '" << participantAddress.asString() << "' state to "
|
||||
<< Utils::toString(newState);
|
||||
mainDb->setChatMessageParticipantState(eventLog, participantAddress, newState);
|
||||
|
||||
list<ChatMessage::State> states = mainDb->getChatMessageParticipantStates(eventLog);
|
||||
size_t nbDisplayedStates = 0;
|
||||
size_t nbDeliveredToUserStates = 0;
|
||||
size_t nbNotDeliveredStates = 0;
|
||||
for (const auto &state : states) {
|
||||
switch (state) {
|
||||
case ChatMessage::State::Displayed:
|
||||
nbDisplayedStates++;
|
||||
break;
|
||||
case ChatMessage::State::DeliveredToUser:
|
||||
nbDeliveredToUserStates++;
|
||||
break;
|
||||
case ChatMessage::State::NotDelivered:
|
||||
nbNotDeliveredStates++;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (nbNotDeliveredStates > 0)
|
||||
setState(ChatMessage::State::NotDelivered);
|
||||
else if (nbDisplayedStates == states.size())
|
||||
setState(ChatMessage::State::Displayed);
|
||||
else if ((nbDisplayedStates + nbDeliveredToUserStates) == states.size())
|
||||
setState(ChatMessage::State::DeliveredToUser);
|
||||
}
|
||||
|
||||
void ChatMessagePrivate::setState (ChatMessage::State newState, bool force) {
|
||||
L_Q();
|
||||
|
||||
if (force)
|
||||
state = s;
|
||||
state = newState;
|
||||
|
||||
if (s == state)
|
||||
return;
|
||||
|
||||
if (
|
||||
(state == ChatMessage::State::Displayed || state == ChatMessage::State::DeliveredToUser) &&
|
||||
(
|
||||
s == ChatMessage::State::DeliveredToUser ||
|
||||
s == ChatMessage::State::Delivered ||
|
||||
s == ChatMessage::State::NotDelivered
|
||||
)
|
||||
)
|
||||
if (!validStateTransition(state, newState))
|
||||
return;
|
||||
|
||||
lInfo() << "Chat message " << this << ": moving from " << Utils::toString(state) <<
|
||||
" to " << Utils::toString(s);
|
||||
state = s;
|
||||
" to " << Utils::toString(newState);
|
||||
state = newState;
|
||||
|
||||
LinphoneChatMessage *msg = L_GET_C_BACK_PTR(q);
|
||||
if (linphone_chat_message_get_message_state_changed_cb(msg))
|
||||
|
|
@ -96,9 +145,15 @@ void ChatMessagePrivate::setState (ChatMessage::State s, bool force) {
|
|||
|
||||
LinphoneChatMessageCbs *cbs = linphone_chat_message_get_callbacks(msg);
|
||||
if (cbs && linphone_chat_message_cbs_get_msg_state_changed(cbs))
|
||||
linphone_chat_message_cbs_get_msg_state_changed(cbs)(msg, linphone_chat_message_get_state(msg));
|
||||
linphone_chat_message_cbs_get_msg_state_changed(cbs)(msg, (LinphoneChatMessageState)state);
|
||||
|
||||
updateInDb();
|
||||
if (state == ChatMessage::State::FileTransferDone && !hasFileTransferContent()) {
|
||||
// We wait until the file has been downloaded to send the displayed IMDN
|
||||
q->sendDisplayNotification();
|
||||
setState(ChatMessage::State::Displayed);
|
||||
} else {
|
||||
updateInDb();
|
||||
}
|
||||
}
|
||||
|
||||
belle_http_request_t *ChatMessagePrivate::getHttpRequest () const {
|
||||
|
|
@ -142,7 +197,7 @@ string ChatMessagePrivate::getSalCustomHeaderValue (const string &name) {
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
bool ChatMessagePrivate::hasTextContent() const {
|
||||
for (const Content *c : contents) {
|
||||
for (const Content *c : getContents()) {
|
||||
if (c->getContentType() == ContentType::PlainText) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -151,7 +206,7 @@ bool ChatMessagePrivate::hasTextContent() const {
|
|||
}
|
||||
|
||||
const Content* ChatMessagePrivate::getTextContent() const {
|
||||
for (const Content *c : contents) {
|
||||
for (const Content *c : getContents()) {
|
||||
if (c->getContentType() == ContentType::PlainText) {
|
||||
return c;
|
||||
}
|
||||
|
|
@ -160,7 +215,7 @@ const Content* ChatMessagePrivate::getTextContent() const {
|
|||
}
|
||||
|
||||
bool ChatMessagePrivate::hasFileTransferContent() const {
|
||||
for (const Content *c : contents) {
|
||||
for (const Content *c : getContents()) {
|
||||
if (c->getContentType() == ContentType::FileTransfer) {
|
||||
return true;
|
||||
}
|
||||
|
|
@ -169,7 +224,7 @@ bool ChatMessagePrivate::hasFileTransferContent() const {
|
|||
}
|
||||
|
||||
const Content* ChatMessagePrivate::getFileTransferContent() const {
|
||||
for (const Content *c : contents) {
|
||||
for (const Content *c : getContents()) {
|
||||
if (c->getContentType() == ContentType::FileTransfer) {
|
||||
return c;
|
||||
}
|
||||
|
|
@ -186,27 +241,30 @@ void ChatMessagePrivate::setFileTransferFilepath (const string &path) {
|
|||
}
|
||||
|
||||
const string &ChatMessagePrivate::getAppdata () const {
|
||||
for (const Content *c : contents) {
|
||||
if (c->isFile()) {
|
||||
FileContent *fileContent = (FileContent *)c;
|
||||
return fileContent->getAppData("legacy");
|
||||
for (const Content *c : getContents()) {
|
||||
if (!c->getAppData("legacy").empty()) {
|
||||
return c->getAppData("legacy");
|
||||
}
|
||||
}
|
||||
return Utils::getEmptyConstRefObject<string>();
|
||||
}
|
||||
|
||||
void ChatMessagePrivate::setAppdata (const string &data) {
|
||||
for (const Content *c : contents) {
|
||||
if (c->isFile()) {
|
||||
FileContent *fileContent = (FileContent *)c;
|
||||
fileContent->setAppData("legacy", data);
|
||||
break;
|
||||
}
|
||||
bool contentFound = false;
|
||||
for (Content *c : getContents()) {
|
||||
c->setAppData("legacy", data);
|
||||
contentFound = true;
|
||||
break;
|
||||
}
|
||||
if (contentFound) {
|
||||
updateInDb();
|
||||
}
|
||||
updateInDb();
|
||||
}
|
||||
|
||||
const string &ChatMessagePrivate::getExternalBodyUrl () const {
|
||||
if (!externalBodyUrl.empty()) {
|
||||
return externalBodyUrl;
|
||||
}
|
||||
if (hasFileTransferContent()) {
|
||||
FileTransferContent *content = (FileTransferContent*) getFileTransferContent();
|
||||
return content->getFileUrl();
|
||||
|
|
@ -214,7 +272,12 @@ const string &ChatMessagePrivate::getExternalBodyUrl () const {
|
|||
return Utils::getEmptyConstRefObject<string>();
|
||||
}
|
||||
|
||||
void ChatMessagePrivate::setExternalBodyUrl (const string &url) {
|
||||
externalBodyUrl = url;
|
||||
}
|
||||
|
||||
const ContentType &ChatMessagePrivate::getContentType () {
|
||||
loadContentsFromDatabase();
|
||||
if (direction == ChatMessage::Direction::Incoming) {
|
||||
if (contents.size() > 0) {
|
||||
Content *content = contents.front();
|
||||
|
|
@ -236,6 +299,7 @@ const ContentType &ChatMessagePrivate::getContentType () {
|
|||
}
|
||||
|
||||
void ChatMessagePrivate::setContentType (const ContentType &contentType) {
|
||||
loadContentsFromDatabase();
|
||||
if (contents.size() > 0 && internalContent.getContentType().isEmpty() && internalContent.isEmpty()) {
|
||||
internalContent.setBody(contents.front()->getBody());
|
||||
}
|
||||
|
|
@ -249,6 +313,7 @@ void ChatMessagePrivate::setContentType (const ContentType &contentType) {
|
|||
}
|
||||
|
||||
const string &ChatMessagePrivate::getText () {
|
||||
loadContentsFromDatabase();
|
||||
if (direction == ChatMessage::Direction::Incoming) {
|
||||
if (hasTextContent()) {
|
||||
cText = getTextContent()->getBodyAsString();
|
||||
|
|
@ -272,6 +337,7 @@ const string &ChatMessagePrivate::getText () {
|
|||
}
|
||||
|
||||
void ChatMessagePrivate::setText (const string &text) {
|
||||
loadContentsFromDatabase();
|
||||
if (contents.size() > 0 && internalContent.getContentType().isEmpty() && internalContent.isEmpty()) {
|
||||
internalContent.setContentType(contents.front()->getContentType());
|
||||
}
|
||||
|
|
@ -288,13 +354,13 @@ LinphoneContent *ChatMessagePrivate::getFileTransferInformation () const {
|
|||
if (hasFileTransferContent()) {
|
||||
return getFileTransferContent()->toLinphoneContent();
|
||||
}
|
||||
for (const Content *c : contents) {
|
||||
for (const Content *c : getContents()) {
|
||||
if (c->isFile()) {
|
||||
FileContent *fileContent = (FileContent *)c;
|
||||
return fileContent->toLinphoneContent();
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ChatMessagePrivate::setFileTransferInformation (const LinphoneContent *c_content) {
|
||||
|
|
@ -306,7 +372,7 @@ void ChatMessagePrivate::setFileTransferInformation (const LinphoneContent *c_co
|
|||
fileContent->setContentType(contentType);
|
||||
fileContent->setFileSize(linphone_content_get_size(c_content));
|
||||
fileContent->setFileName(linphone_content_get_name(c_content));
|
||||
if (linphone_content_get_string_buffer(c_content) != NULL) {
|
||||
if (linphone_content_get_string_buffer(c_content)) {
|
||||
fileContent->setBody(linphone_content_get_string_buffer(c_content));
|
||||
}
|
||||
|
||||
|
|
@ -316,19 +382,31 @@ void ChatMessagePrivate::setFileTransferInformation (const LinphoneContent *c_co
|
|||
bool ChatMessagePrivate::downloadFile () {
|
||||
L_Q();
|
||||
|
||||
for (auto &content : contents)
|
||||
for (auto &content : getContents())
|
||||
if (content->getContentType() == ContentType::FileTransfer)
|
||||
return q->downloadFile(*static_cast<FileTransferContent *>(content));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ChatMessagePrivate::addContent (Content &content) {
|
||||
getContents().push_back(&content);
|
||||
}
|
||||
|
||||
void ChatMessagePrivate::removeContent (const Content &content) {
|
||||
getContents().remove(&const_cast<Content &>(content));
|
||||
}
|
||||
|
||||
void ChatMessagePrivate::loadFileTransferUrlFromBodyToContent() {
|
||||
L_Q();
|
||||
int errorCode = 0;
|
||||
fileTransferChatMessageModifier.decode(q->getSharedFromThis(), errorCode);
|
||||
}
|
||||
|
||||
std::string ChatMessagePrivate::createFakeFileTransferFromUrl(const std::string &url) {
|
||||
return fileTransferChatMessageModifier.createFakeFileTransferFromUrl(url);
|
||||
}
|
||||
|
||||
void ChatMessagePrivate::setChatRoom (const shared_ptr<AbstractChatRoom> &cr) {
|
||||
chatRoom = cr;
|
||||
chatRoomId = cr->getChatRoomId();
|
||||
|
|
@ -349,13 +427,15 @@ void ChatMessagePrivate::sendImdn (Imdn::Type imdnType, LinphoneReason reason) {
|
|||
shared_ptr<ChatMessage> msg = q->getChatRoom()->createChatMessage();
|
||||
|
||||
Content *content = new Content();
|
||||
content->setContentType("message/imdn+xml");
|
||||
content->setContentType(ContentType::Imdn);
|
||||
content->setBody(Imdn::createXml(imdnId, time, imdnType, reason));
|
||||
msg->addContent(*content);
|
||||
|
||||
if (reason != LinphoneReasonNone)
|
||||
msg->getPrivate()->setEncryptionPrevented(true);
|
||||
|
||||
msg->setToBeStored(false);
|
||||
msg->getPrivate()->addSalCustomHeader(PriorityHeader::HeaderName, PriorityHeader::NonUrgent);
|
||||
|
||||
msg->getPrivate()->send();
|
||||
}
|
||||
|
|
@ -396,24 +476,22 @@ static void forceUtf8Content (Content &content) {
|
|||
void ChatMessagePrivate::notifyReceiving () {
|
||||
L_Q();
|
||||
|
||||
if ((getContentType() == ContentType::Imdn) || (getContentType() == ContentType::ImIsComposing))
|
||||
return;
|
||||
|
||||
LinphoneChatRoom *chatRoom = L_GET_C_BACK_PTR(q->getChatRoom());
|
||||
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(chatRoom);
|
||||
LinphoneChatRoomCbsParticipantAddedCb cb = linphone_chat_room_cbs_get_chat_message_received(cbs);
|
||||
if ((getContentType() != ContentType::Imdn) && (getContentType() != ContentType::ImIsComposing)) {
|
||||
_linphone_chat_room_notify_chat_message_should_be_stored(chatRoom, L_GET_C_BACK_PTR(q->getSharedFromThis()));
|
||||
if (toBeStored)
|
||||
storeInDb();
|
||||
}
|
||||
shared_ptr<ConferenceChatMessageEvent> event = make_shared<ConferenceChatMessageEvent>(
|
||||
::time(nullptr), q->getSharedFromThis()
|
||||
);
|
||||
if (cb)
|
||||
cb(chatRoom, L_GET_C_BACK_PTR(event));
|
||||
_linphone_chat_room_notify_chat_message_received(chatRoom, L_GET_C_BACK_PTR(event));
|
||||
// Legacy
|
||||
q->getChatRoom()->getPrivate()->notifyChatMessageReceived(q->getSharedFromThis());
|
||||
|
||||
if (toBeStored)
|
||||
storeInDb();
|
||||
|
||||
q->sendDeliveryNotification(LinphoneReasonNone);
|
||||
if ((getContentType() != ContentType::Imdn) && (getContentType() != ContentType::ImIsComposing)) {
|
||||
q->sendDeliveryNotification(LinphoneReasonNone);
|
||||
}
|
||||
}
|
||||
|
||||
LinphoneReason ChatMessagePrivate::receive () {
|
||||
|
|
@ -537,7 +615,7 @@ void ChatMessagePrivate::send () {
|
|||
|
||||
currentSendStep |= ChatMessagePrivate::Step::Started;
|
||||
|
||||
if (toBeStored)
|
||||
if (toBeStored && currentSendStep == (ChatMessagePrivate::Step::Started | ChatMessagePrivate::Step::None))
|
||||
storeInDb();
|
||||
|
||||
if ((currentSendStep & ChatMessagePrivate::Step::FileUpload) == ChatMessagePrivate::Step::FileUpload) {
|
||||
|
|
@ -565,8 +643,8 @@ void ChatMessagePrivate::send () {
|
|||
|| (call->getState() == CallSession::State::Pausing)
|
||||
|| (call->getState() == CallSession::State::PausedByRemote)
|
||||
) {
|
||||
lInfo() << "send SIP msg through the existing call.";
|
||||
op = linphone_call_get_op(lcall);
|
||||
lInfo() << "Send SIP msg through the existing call";
|
||||
op = call->getPrivate()->getOp();
|
||||
string identity = linphone_core_find_best_identity(core->getCCore(), linphone_call_get_remote_address(lcall));
|
||||
if (identity.empty()) {
|
||||
LinphoneAddress *addr = linphone_address_new(q->getToAddress().asString().c_str());
|
||||
|
|
@ -618,11 +696,8 @@ void ChatMessagePrivate::send () {
|
|||
if ((currentSendStep &ChatMessagePrivate::Step::Cpim) == ChatMessagePrivate::Step::Cpim) {
|
||||
lInfo() << "Cpim step already done, skipping";
|
||||
} else {
|
||||
int defaultValue = !!lp_config_get_string(core->getCCore()->config, "misc", "conference_factory_uri", nullptr);
|
||||
if (lp_config_get_int(core->getCCore()->config, "sip", "use_cpim", defaultValue) == 1) {
|
||||
CpimChatMessageModifier ccmm;
|
||||
ccmm.encode(q->getSharedFromThis(), errorCode);
|
||||
}
|
||||
CpimChatMessageModifier ccmm;
|
||||
ccmm.encode(q->getSharedFromThis(), errorCode);
|
||||
currentSendStep |= ChatMessagePrivate::Step::Cpim;
|
||||
}
|
||||
}
|
||||
|
|
@ -653,19 +728,23 @@ void ChatMessagePrivate::send () {
|
|||
if (internalContent.isEmpty()) {
|
||||
if (contents.size() > 0) {
|
||||
internalContent = *(contents.front());
|
||||
} else {
|
||||
} else if (externalBodyUrl.empty()) { // When using external body url, there is no content
|
||||
lError() << "Trying to send a message without any content !";
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
auto msgOp = dynamic_cast<SalMessageOpInterface *>(op);
|
||||
if (internalContent.getContentType().isValid()) {
|
||||
if (!externalBodyUrl.empty()) {
|
||||
char *content_type = ms_strdup_printf("message/external-body; access-type=URL; URL=\"%s\"", externalBodyUrl.c_str());
|
||||
msgOp->send_message(content_type, NULL);
|
||||
ms_free(content_type);
|
||||
} else if (internalContent.getContentType().isValid()) {
|
||||
msgOp->send_message(internalContent.getContentType().asString().c_str(), internalContent.getBodyAsUtf8String().c_str());
|
||||
} else {
|
||||
msgOp->send_message(ContentType::PlainText.asString().c_str(), internalContent.getBodyAsUtf8String().c_str());
|
||||
}
|
||||
|
||||
|
||||
// Restore FileContents and remove FileTransferContents
|
||||
list<Content*>::iterator it = contents.begin();
|
||||
while (it != contents.end()) {
|
||||
|
|
@ -673,7 +752,7 @@ void ChatMessagePrivate::send () {
|
|||
if (content->getContentType() == ContentType::FileTransfer) {
|
||||
FileTransferContent *fileTransferContent = (FileTransferContent *)content;
|
||||
it = contents.erase(it);
|
||||
q->addContent(*fileTransferContent->getFileContent());
|
||||
addContent(*fileTransferContent->getFileContent());
|
||||
delete fileTransferContent;
|
||||
} else {
|
||||
it++;
|
||||
|
|
@ -712,7 +791,10 @@ void ChatMessagePrivate::storeInDb () {
|
|||
updateInDb();
|
||||
} else {
|
||||
shared_ptr<EventLog> eventLog = make_shared<ConferenceChatMessageEvent>(time, q->getSharedFromThis());
|
||||
q->getChatRoom()->getCore()->getPrivate()->mainDb->addEvent(eventLog);
|
||||
|
||||
// Avoid transaction in transaction if contents are not loaded.
|
||||
loadContentsFromDatabase();
|
||||
q->getChatRoom()->getPrivate()->addEvent(eventLog);
|
||||
|
||||
if (direction == ChatMessage::Direction::Incoming) {
|
||||
if (hasFileTransferContent()) {
|
||||
|
|
@ -734,6 +816,9 @@ void ChatMessagePrivate::updateInDb () {
|
|||
|
||||
unique_ptr<MainDb> &mainDb = q->getChatRoom()->getCore()->getPrivate()->mainDb;
|
||||
shared_ptr<EventLog> eventLog = mainDb->getEventFromKey(dbKey);
|
||||
|
||||
// Avoid transaction in transaction if contents are not loaded.
|
||||
loadContentsFromDatabase();
|
||||
mainDb->updateEvent(eventLog);
|
||||
|
||||
if (direction == ChatMessage::Direction::Incoming) {
|
||||
|
|
@ -751,16 +836,31 @@ void ChatMessagePrivate::updateInDb () {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
ChatMessage::ChatMessage (const shared_ptr<AbstractChatRoom> &chatRoom, ChatMessage::Direction direction) :
|
||||
Object(*new ChatMessagePrivate), CoreAccessor(chatRoom->getCore()) {
|
||||
L_D();
|
||||
bool ChatMessagePrivate::validStateTransition (ChatMessage::State currentState, ChatMessage::State newState) {
|
||||
if (newState == currentState)
|
||||
return false;
|
||||
|
||||
d->direction = direction;
|
||||
d->setChatRoom(chatRoom);
|
||||
if (
|
||||
(currentState == ChatMessage::State::Displayed || currentState == ChatMessage::State::DeliveredToUser) &&
|
||||
(
|
||||
newState == ChatMessage::State::DeliveredToUser ||
|
||||
newState == ChatMessage::State::Delivered ||
|
||||
newState == ChatMessage::State::NotDelivered
|
||||
)
|
||||
)
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
ChatMessage::ChatMessage (const shared_ptr<AbstractChatRoom> &chatRoom, ChatMessage::Direction direction) :
|
||||
Object(*new ChatMessagePrivate(chatRoom,direction)), CoreAccessor(chatRoom->getCore()) {
|
||||
}
|
||||
|
||||
ChatMessage::~ChatMessage () {
|
||||
L_D();
|
||||
|
||||
for (Content *content : d->contents)
|
||||
delete content;
|
||||
|
||||
|
|
@ -823,6 +923,18 @@ void ChatMessagePrivate::setImdnMessageId (const string &id) {
|
|||
imdnId = id;
|
||||
}
|
||||
|
||||
void ChatMessagePrivate::loadContentsFromDatabase () const {
|
||||
L_Q();
|
||||
if (contentsNotLoadedFromDatabase) {
|
||||
isReadOnly = false;
|
||||
contentsNotLoadedFromDatabase = false;
|
||||
q->getChatRoom()->getCore()->getPrivate()->mainDb->loadChatMessageContents(
|
||||
const_pointer_cast<ChatMessage>(q->getSharedFromThis())
|
||||
);
|
||||
isReadOnly = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool ChatMessage::isRead () const {
|
||||
L_D();
|
||||
|
||||
|
|
@ -875,21 +987,19 @@ bool ChatMessage::isReadOnly () const {
|
|||
|
||||
const list<Content *> &ChatMessage::getContents () const {
|
||||
L_D();
|
||||
return d->contents;
|
||||
return d->getContents();
|
||||
}
|
||||
|
||||
void ChatMessage::addContent (Content &content) {
|
||||
L_D();
|
||||
if (d->isReadOnly) return;
|
||||
|
||||
d->contents.push_back(&content);
|
||||
if (!d->isReadOnly)
|
||||
d->addContent(content);
|
||||
}
|
||||
|
||||
void ChatMessage::removeContent (const Content &content) {
|
||||
L_D();
|
||||
if (d->isReadOnly) return;
|
||||
|
||||
d->contents.remove(&const_cast<Content &>(content));
|
||||
if (!d->isReadOnly)
|
||||
d->removeContent(content);
|
||||
}
|
||||
|
||||
const Content &ChatMessage::getInternalContent () const {
|
||||
|
|
@ -926,22 +1036,17 @@ void ChatMessage::removeCustomHeader (const string &headerName) {
|
|||
d->customHeaders.erase(headerName);
|
||||
}
|
||||
|
||||
void ChatMessage::updateState (State state) {
|
||||
L_D();
|
||||
|
||||
d->setState(state);
|
||||
}
|
||||
|
||||
void ChatMessage::send () {
|
||||
L_D();
|
||||
|
||||
// Do not allow sending a message that is already being sent or that has been correctly delivered/displayed
|
||||
if ((d->state == State::InProgress) || (d->state == State::Delivered) || (d->state == State::FileTransferDone) ||
|
||||
(d->state == State::DeliveredToUser) || (d->state == State::Displayed)) {
|
||||
lWarning() << "Cannot send chat message in state " << linphone_chat_message_state_to_string((LinphoneChatMessageState)d->state);
|
||||
lWarning() << "Cannot send chat message in state " << Utils::toString(d->state);
|
||||
return;
|
||||
}
|
||||
|
||||
d->loadContentsFromDatabase();
|
||||
getChatRoom()->getPrivate()->sendChatMessage(getSharedFromThis());
|
||||
}
|
||||
|
||||
|
|
@ -966,6 +1071,11 @@ bool ChatMessage::downloadFile(FileTransferContent &fileTransferContent) {
|
|||
return d->fileTransferChatMessageModifier.downloadFile(getSharedFromThis(), &fileTransferContent);
|
||||
}
|
||||
|
||||
bool ChatMessage::isFileTransferInProgress() {
|
||||
L_D();
|
||||
return d->fileTransferChatMessageModifier.isFileTransferInProgressAndValid();
|
||||
}
|
||||
|
||||
void ChatMessage::cancelFileTransfer () {
|
||||
L_D();
|
||||
if (d->fileTransferChatMessageModifier.isFileTransferInProgressAndValid()) {
|
||||
|
|
@ -981,48 +1091,50 @@ void ChatMessage::cancelFileTransfer () {
|
|||
int ChatMessage::putCharacter (uint32_t character) {
|
||||
L_D();
|
||||
|
||||
shared_ptr<Core> core = getCore();
|
||||
if (linphone_core_realtime_text_enabled(core->getCCore())) {
|
||||
static const uint32_t new_line = 0x2028;
|
||||
static const uint32_t crlf = 0x0D0A;
|
||||
static const uint32_t lf = 0x0A;
|
||||
constexpr uint32_t newLine = 0x2028;
|
||||
constexpr uint32_t crlf = 0x0D0A;
|
||||
constexpr uint32_t lf = 0x0A;
|
||||
|
||||
shared_ptr<AbstractChatRoom> chatRoom = getChatRoom();
|
||||
shared_ptr<AbstractChatRoom> chatRoom = getChatRoom();
|
||||
if (!(chatRoom->getCapabilities() & LinphonePrivate::ChatRoom::Capabilities::RealTimeText))
|
||||
return -1;
|
||||
|
||||
shared_ptr<LinphonePrivate::RealTimeTextChatRoom> rttcr =
|
||||
static_pointer_cast<LinphonePrivate::RealTimeTextChatRoom>(chatRoom);
|
||||
LinphoneCall *call = rttcr->getCall();
|
||||
shared_ptr<LinphonePrivate::RealTimeTextChatRoom> rttcr =
|
||||
static_pointer_cast<LinphonePrivate::RealTimeTextChatRoom>(chatRoom);
|
||||
if (!rttcr)
|
||||
return -1;
|
||||
|
||||
if (!call || !linphone_call_get_stream(call, LinphoneStreamTypeText))
|
||||
return -1;
|
||||
shared_ptr<Call> call = rttcr->getCall();
|
||||
if (!call || !call->getPrivate()->getMediaStream(LinphoneStreamTypeText))
|
||||
return -1;
|
||||
|
||||
if (character == new_line || character == crlf || character == lf) {
|
||||
if (lp_config_get_int(core->getCCore()->config, "misc", "store_rtt_messages", 1) == 1) {
|
||||
// TODO: History.
|
||||
lDebug() << "New line sent, forge a message with content " << d->rttMessage.c_str();
|
||||
d->setTime(ms_time(0));
|
||||
d->state = State::Displayed;
|
||||
// d->direction = Direction::Outgoing;
|
||||
// setFromAddress(Address(
|
||||
// linphone_address_as_string(linphone_address_new(linphone_core_get_identity(core->getCCore())))
|
||||
// ));
|
||||
// linphone_chat_message_store(L_GET_C_BACK_PTR(this));
|
||||
d->rttMessage = "";
|
||||
}
|
||||
} else {
|
||||
char *value = LinphonePrivate::Utils::utf8ToChar(character);
|
||||
d->rttMessage = d->rttMessage + string(value);
|
||||
lDebug() << "Sent RTT character: " << value << "(" << (unsigned long)character <<
|
||||
"), pending text is " << d->rttMessage.c_str();
|
||||
delete value;
|
||||
if (character == newLine || character == crlf || character == lf) {
|
||||
shared_ptr<Core> core = getCore();
|
||||
if (lp_config_get_int(core->getCCore()->config, "misc", "store_rtt_messages", 1) == 1) {
|
||||
// TODO: History.
|
||||
lDebug() << "New line sent, forge a message with content " << d->rttMessage.c_str();
|
||||
d->setTime(ms_time(0));
|
||||
d->state = State::Displayed;
|
||||
// d->direction = Direction::Outgoing;
|
||||
// setFromAddress(Address(
|
||||
// linphone_address_as_string(linphone_address_new(linphone_core_get_identity(core->getCCore())))
|
||||
// ));
|
||||
// linphone_chat_message_store(L_GET_C_BACK_PTR(this));
|
||||
d->rttMessage = "";
|
||||
}
|
||||
|
||||
text_stream_putchar32(reinterpret_cast<TextStream *>(
|
||||
linphone_call_get_stream(call, LinphoneStreamTypeText)), character
|
||||
);
|
||||
return 0;
|
||||
} else {
|
||||
char *value = LinphonePrivate::Utils::utf8ToChar(character);
|
||||
d->rttMessage = d->rttMessage + string(value);
|
||||
lDebug() << "Sent RTT character: " << value << "(" << (unsigned long)character <<
|
||||
"), pending text is " << d->rttMessage.c_str();
|
||||
delete[] value;
|
||||
}
|
||||
return -1;
|
||||
|
||||
text_stream_putchar32(
|
||||
reinterpret_cast<TextStream *>(call->getPrivate()->getMediaStream(LinphoneStreamTypeText)),
|
||||
character
|
||||
);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -47,6 +47,7 @@ class LINPHONE_PUBLIC ChatMessage : public Object, public CoreAccessor {
|
|||
friend class ChatRoomPrivate;
|
||||
friend class CpimChatMessageModifier;
|
||||
friend class FileTransferChatMessageModifier;
|
||||
friend class Imdn;
|
||||
friend class MainDb;
|
||||
friend class MainDbPrivate;
|
||||
friend class RealTimeTextChatRoomPrivate;
|
||||
|
|
@ -63,7 +64,6 @@ public:
|
|||
// ----- TODO: Remove me.
|
||||
void cancelFileTransfer ();
|
||||
int putCharacter (uint32_t character);
|
||||
void updateState (State state);
|
||||
void sendDeliveryNotification (LinphoneReason reason);
|
||||
void sendDisplayNotification ();
|
||||
void setIsSecured (bool isSecured);
|
||||
|
|
@ -100,11 +100,13 @@ public:
|
|||
const Content &getInternalContent () const;
|
||||
void setInternalContent (const Content &content);
|
||||
|
||||
// TODO: to replace salCustomheaders
|
||||
std::string getCustomHeaderValue (const std::string &headerName) const;
|
||||
void addCustomHeader (const std::string &headerName, const std::string &headerValue);
|
||||
void removeCustomHeader (const std::string &headerName);
|
||||
|
||||
bool downloadFile (FileTransferContent &content);
|
||||
bool isFileTransferInProgress();
|
||||
|
||||
private:
|
||||
ChatMessage (const std::shared_ptr<AbstractChatRoom> &chatRoom, ChatMessage::Direction direction);
|
||||
|
|
|
|||
|
|
@ -42,6 +42,8 @@ public:
|
|||
|
||||
virtual void sendChatMessage (const std::shared_ptr<ChatMessage> &chatMessage) = 0;
|
||||
|
||||
virtual void addEvent (const std::shared_ptr<EventLog> &eventLog) = 0;
|
||||
|
||||
virtual void addTransientEvent (const std::shared_ptr<EventLog> &eventLog) = 0;
|
||||
virtual void removeTransientEvent (const std::shared_ptr<EventLog> &eventLog) = 0;
|
||||
|
||||
|
|
|
|||
|
|
@ -68,6 +68,8 @@ public:
|
|||
virtual State getState () const = 0;
|
||||
virtual bool hasBeenLeft () const = 0;
|
||||
|
||||
virtual std::list<std::shared_ptr<EventLog>> getMessageHistory (int nLast) const = 0;
|
||||
virtual std::list<std::shared_ptr<EventLog>> getMessageHistoryRange (int begin, int end) const = 0;
|
||||
virtual std::list<std::shared_ptr<EventLog>> getHistory (int nLast) const = 0;
|
||||
virtual std::list<std::shared_ptr<EventLog>> getHistoryRange (int begin, int end) const = 0;
|
||||
virtual int getHistorySize () const = 0;
|
||||
|
|
|
|||
|
|
@ -28,9 +28,6 @@
|
|||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
class BasicChatRoomPrivate : public ChatRoomPrivate {
|
||||
public:
|
||||
BasicChatRoomPrivate () = default;
|
||||
|
||||
private:
|
||||
std::string subject;
|
||||
std::list<std::shared_ptr<Participant>> participants;
|
||||
|
|
|
|||
|
|
@ -53,10 +53,19 @@ public:
|
|||
}
|
||||
|
||||
void sendChatMessage (const shared_ptr<ChatMessage> &chatMessage) override {
|
||||
L_Q();
|
||||
ProxyChatRoomPrivate::sendChatMessage(chatMessage);
|
||||
const char *specs = linphone_core_get_linphone_specs(chatMessage->getCore()->getCCore());
|
||||
time_t currentRealTime = ms_time(nullptr);
|
||||
if (!linphone_core_get_conference_factory_uri(chatMessage->getCore()->getCCore())
|
||||
LinphoneAddress *lAddr = linphone_address_new(
|
||||
chatMessage->getChatRoom()->getChatRoomId().getLocalAddress().asString().c_str()
|
||||
);
|
||||
LinphoneProxyConfig *proxy = linphone_core_lookup_known_proxy(q->getCore()->getCCore(), lAddr);
|
||||
linphone_address_unref(lAddr);
|
||||
const char *conferenceFactoryUri = nullptr;
|
||||
if (proxy)
|
||||
conferenceFactoryUri = linphone_proxy_config_get_conference_factory_uri(proxy);
|
||||
if (!conferenceFactoryUri
|
||||
|| (chatRoom->getCapabilities() & ChatRoom::Capabilities::Conference)
|
||||
|| clientGroupChatRoom
|
||||
|| !specs || !strstr(specs, "groupchat")
|
||||
|
|
@ -69,7 +78,7 @@ public:
|
|||
}
|
||||
migrationRealTime = currentRealTime;
|
||||
clientGroupChatRoom = static_pointer_cast<ClientGroupChatRoom>(
|
||||
chatRoom->getCore()->getPrivate()->createClientGroupChatRoom(chatRoom->getSubject(), false)
|
||||
chatRoom->getCore()->getPrivate()->createClientGroupChatRoom(chatRoom->getSubject(), "", false)
|
||||
);
|
||||
clientGroupChatRoom->getPrivate()->setCallSessionListener(this);
|
||||
clientGroupChatRoom->getPrivate()->setChatRoomListener(this);
|
||||
|
|
@ -77,7 +86,7 @@ public:
|
|||
}
|
||||
|
||||
void onCallSessionStateChanged (
|
||||
const shared_ptr<const CallSession> &session,
|
||||
const shared_ptr<CallSession> &session,
|
||||
CallSession::State newState,
|
||||
const string &message
|
||||
) override {
|
||||
|
|
|
|||
|
|
@ -48,20 +48,21 @@ ChatRoomId::ChatRoomId (
|
|||
|
||||
L_USE_DEFAULT_CLONABLE_OBJECT_SHARED_IMPL(ChatRoomId);
|
||||
|
||||
bool ChatRoomId::operator== (const ChatRoomId &chatRoomId) const {
|
||||
bool ChatRoomId::operator== (const ChatRoomId &other) const {
|
||||
L_D();
|
||||
const ChatRoomIdPrivate *dChatRoomId = chatRoomId.getPrivate();
|
||||
const ChatRoomIdPrivate *dChatRoomId = other.getPrivate();
|
||||
return d->peerAddress == dChatRoomId->peerAddress && d->localAddress == dChatRoomId->localAddress;
|
||||
}
|
||||
|
||||
bool ChatRoomId::operator!= (const ChatRoomId &chatRoomId) const {
|
||||
return !(*this == chatRoomId);
|
||||
bool ChatRoomId::operator!= (const ChatRoomId &other) const {
|
||||
return !(*this == other);
|
||||
}
|
||||
|
||||
bool ChatRoomId::operator< (const ChatRoomId &chatRoomId) const {
|
||||
bool ChatRoomId::operator< (const ChatRoomId &other) const {
|
||||
L_D();
|
||||
const ChatRoomIdPrivate *dChatRoomId = chatRoomId.getPrivate();
|
||||
return d->peerAddress < dChatRoomId->peerAddress || d->localAddress < dChatRoomId->localAddress;
|
||||
const ChatRoomIdPrivate *dChatRoomId = other.getPrivate();
|
||||
return d->peerAddress < dChatRoomId->peerAddress
|
||||
|| (d->peerAddress == dChatRoomId->peerAddress && d->localAddress < dChatRoomId->localAddress);
|
||||
}
|
||||
|
||||
const IdentityAddress &ChatRoomId::getPeerAddress () const {
|
||||
|
|
|
|||
|
|
@ -32,14 +32,14 @@ class LINPHONE_PUBLIC ChatRoomId : public ClonableObject {
|
|||
public:
|
||||
ChatRoomId ();
|
||||
ChatRoomId (const IdentityAddress &peerAddress, const IdentityAddress &localAddress);
|
||||
ChatRoomId (const ChatRoomId &src);
|
||||
ChatRoomId (const ChatRoomId &other);
|
||||
|
||||
ChatRoomId &operator= (const ChatRoomId &src);
|
||||
ChatRoomId &operator= (const ChatRoomId &other);
|
||||
|
||||
bool operator== (const ChatRoomId &chatRoomId) const;
|
||||
bool operator!= (const ChatRoomId &chatRoomId) const;
|
||||
bool operator== (const ChatRoomId &other) const;
|
||||
bool operator!= (const ChatRoomId &other) const;
|
||||
|
||||
bool operator< (const ChatRoomId &chatRoomId) const;
|
||||
bool operator< (const ChatRoomId &other) const;
|
||||
|
||||
const IdentityAddress &getPeerAddress () const;
|
||||
const IdentityAddress &getLocalAddress () const;
|
||||
|
|
@ -50,6 +50,11 @@ private:
|
|||
L_DECLARE_PRIVATE(ChatRoomId);
|
||||
};
|
||||
|
||||
inline std::ostream &operator<< (std::ostream &os, const ChatRoomId &chatRoomId) {
|
||||
os << "ChatRoomId(" << chatRoomId.getPeerAddress() << ", local=" << chatRoomId.getLocalAddress() << ")";
|
||||
return os;
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
||||
// Add map key support.
|
||||
|
|
|
|||
|
|
@ -33,6 +33,8 @@ LINPHONE_BEGIN_NAMESPACE
|
|||
|
||||
class ChatRoomPrivate : public AbstractChatRoomPrivate, public IsComposingListener {
|
||||
public:
|
||||
inline void setProxyChatRoom (AbstractChatRoom *value) { proxyChatRoom = value; }
|
||||
|
||||
inline void setCreationTime (time_t creationTime) override {
|
||||
this->creationTime = creationTime;
|
||||
}
|
||||
|
|
@ -46,6 +48,8 @@ public:
|
|||
void sendChatMessage (const std::shared_ptr<ChatMessage> &chatMessage) override;
|
||||
void sendIsComposingNotification ();
|
||||
|
||||
void addEvent (const std::shared_ptr<EventLog> &eventLog) override;
|
||||
|
||||
void addTransientEvent (const std::shared_ptr<EventLog> &eventLog) override;
|
||||
void removeTransientEvent (const std::shared_ptr<EventLog> &eventLog) override;
|
||||
|
||||
|
|
@ -59,24 +63,27 @@ public:
|
|||
|
||||
LinphoneReason onSipMessageReceived (SalOp *op, const SalMessage *message) override;
|
||||
void onChatMessageReceived (const std::shared_ptr<ChatMessage> &chatMessage) override;
|
||||
void onImdnReceived (const std::string &text);
|
||||
void onImdnReceived (const std::shared_ptr<ChatMessage> &chatMessage);
|
||||
void onIsComposingReceived (const Address &remoteAddress, const std::string &text);
|
||||
void onIsComposingRefreshNeeded () override;
|
||||
void onIsComposingStateChanged (bool isComposing) override;
|
||||
void onIsRemoteComposingStateChanged (const Address &remoteAddress, bool isComposing) override;
|
||||
|
||||
LinphoneChatRoom *getCChatRoom () const;
|
||||
|
||||
std::list<IdentityAddress> remoteIsComposing;
|
||||
std::list<std::shared_ptr<EventLog>> transientEvents;
|
||||
|
||||
ChatRoomId chatRoomId;
|
||||
|
||||
private:
|
||||
AbstractChatRoom *proxyChatRoom = nullptr;
|
||||
|
||||
ChatRoom::State state = ChatRoom::State::None;
|
||||
|
||||
time_t creationTime = std::time(nullptr);
|
||||
time_t lastUpdateTime = std::time(nullptr);
|
||||
|
||||
std::shared_ptr<ChatMessage> pendingMessage;
|
||||
std::unique_ptr<IsComposing> isComposingHandler;
|
||||
|
||||
bool isComposing = false;
|
||||
|
|
|
|||
|
|
@ -25,6 +25,8 @@
|
|||
#include "chat/chat-message/chat-message-p.h"
|
||||
#include "chat/chat-room/chat-room-p.h"
|
||||
#include "core/core-p.h"
|
||||
#include "sip-tools/sip-headers.h"
|
||||
#include "logger/logger.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
|
|
@ -50,19 +52,16 @@ void ChatRoomPrivate::sendChatMessage (const shared_ptr<ChatMessage> &chatMessag
|
|||
dChatMessage->setTime(ms_time(0));
|
||||
dChatMessage->send();
|
||||
|
||||
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(q);
|
||||
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(cr);
|
||||
LinphoneChatRoomCbsChatMessageSentCb cb = linphone_chat_room_cbs_get_chat_message_sent(cbs);
|
||||
|
||||
LinphoneChatRoom *cr = getCChatRoom();
|
||||
// TODO: server currently don't stock message, remove condition in the future.
|
||||
if (cb && !linphone_core_conference_server_enabled(q->getCore()->getCCore())) {
|
||||
if (!linphone_core_conference_server_enabled(q->getCore()->getCCore())) {
|
||||
shared_ptr<ConferenceChatMessageEvent> event = static_pointer_cast<ConferenceChatMessageEvent>(
|
||||
q->getCore()->getPrivate()->mainDb->getEventFromKey(dChatMessage->dbKey)
|
||||
);
|
||||
if (!event)
|
||||
event = make_shared<ConferenceChatMessageEvent>(time(nullptr), chatMessage);
|
||||
|
||||
cb(cr, L_GET_C_BACK_PTR(event));
|
||||
_linphone_chat_room_notify_chat_message_sent(cr, L_GET_C_BACK_PTR(event));
|
||||
}
|
||||
|
||||
if (isComposing)
|
||||
|
|
@ -74,22 +73,35 @@ void ChatRoomPrivate::sendChatMessage (const shared_ptr<ChatMessage> &chatMessag
|
|||
void ChatRoomPrivate::sendIsComposingNotification () {
|
||||
L_Q();
|
||||
LinphoneImNotifPolicy *policy = linphone_core_get_im_notif_policy(q->getCore()->getCCore());
|
||||
if (linphone_im_notif_policy_get_send_is_composing(policy)) {
|
||||
string payload = isComposingHandler->marshal(isComposing);
|
||||
if (!payload.empty()) {
|
||||
shared_ptr<ChatMessage> chatMessage = createChatMessage(ChatMessage::Direction::Outgoing);
|
||||
chatMessage->setToBeStored(false);
|
||||
Content *content = new Content();
|
||||
content->setContentType(ContentType::ImIsComposing);
|
||||
content->setBody(payload);
|
||||
chatMessage->addContent(*content);
|
||||
chatMessage->getPrivate()->send();
|
||||
}
|
||||
}
|
||||
if (!linphone_im_notif_policy_get_send_is_composing(policy))
|
||||
return;
|
||||
|
||||
string payload = isComposingHandler->marshal(isComposing);
|
||||
if (payload.empty())
|
||||
return;
|
||||
|
||||
Content *content = new Content();
|
||||
content->setContentType(ContentType::ImIsComposing);
|
||||
content->setBody(payload);
|
||||
|
||||
shared_ptr<ChatMessage> chatMessage = createChatMessage(ChatMessage::Direction::Outgoing);
|
||||
chatMessage->setToBeStored(false);
|
||||
chatMessage->addContent(*content);
|
||||
chatMessage->getPrivate()->addSalCustomHeader(PriorityHeader::HeaderName, PriorityHeader::NonUrgent);
|
||||
chatMessage->getPrivate()->addSalCustomHeader("Expires", "0");
|
||||
|
||||
chatMessage->getPrivate()->send();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ChatRoomPrivate::addEvent (const shared_ptr<EventLog> &eventLog) {
|
||||
L_Q();
|
||||
|
||||
q->getCore()->getPrivate()->mainDb->addEvent(eventLog);
|
||||
setLastUpdateTime(eventLog->getCreationTime());
|
||||
}
|
||||
|
||||
void ChatRoomPrivate::addTransientEvent (const shared_ptr<EventLog> &eventLog) {
|
||||
auto it = find(transientEvents.begin(), transientEvents.end(), eventLog);
|
||||
if (it == transientEvents.end())
|
||||
|
|
@ -118,7 +130,7 @@ list<shared_ptr<ChatMessage>> ChatRoomPrivate::findChatMessages (const string &m
|
|||
|
||||
void ChatRoomPrivate::notifyChatMessageReceived (const shared_ptr<ChatMessage> &chatMessage) {
|
||||
L_Q();
|
||||
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(q);
|
||||
LinphoneChatRoom *cr = getCChatRoom();
|
||||
if (!chatMessage->getPrivate()->getText().empty()) {
|
||||
/* Legacy API */
|
||||
LinphoneAddress *fromAddress = linphone_address_new(chatMessage->getFromAddress().asString().c_str());
|
||||
|
|
@ -130,10 +142,7 @@ void ChatRoomPrivate::notifyChatMessageReceived (const shared_ptr<ChatMessage> &
|
|||
);
|
||||
linphone_address_unref(fromAddress);
|
||||
}
|
||||
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(cr);
|
||||
LinphoneChatRoomCbsMessageReceivedCb cb = linphone_chat_room_cbs_get_message_received(cbs);
|
||||
if (cb)
|
||||
cb(cr, L_GET_C_BACK_PTR(chatMessage));
|
||||
_linphone_chat_room_notify_message_received(cr, L_GET_C_BACK_PTR(chatMessage));
|
||||
linphone_core_notify_message_received(q->getCore()->getCCore(), cr, L_GET_C_BACK_PTR(chatMessage));
|
||||
}
|
||||
|
||||
|
|
@ -145,35 +154,25 @@ void ChatRoomPrivate::notifyIsComposingReceived (const Address &remoteAddress, b
|
|||
else
|
||||
remoteIsComposing.remove(remoteAddress);
|
||||
|
||||
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(q);
|
||||
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(cr);
|
||||
LinphoneChatRoomCbsIsComposingReceivedCb cb = linphone_chat_room_cbs_get_is_composing_received(cbs);
|
||||
if (cb) {
|
||||
LinphoneAddress *lAddr = linphone_address_new(remoteAddress.asString().c_str());
|
||||
cb(cr, lAddr, !!isComposing);
|
||||
linphone_address_unref(lAddr);
|
||||
}
|
||||
LinphoneChatRoom *cr = getCChatRoom();
|
||||
LinphoneAddress *lAddr = linphone_address_new(remoteAddress.asString().c_str());
|
||||
_linphone_chat_room_notify_is_composing_received(cr, lAddr, !!isComposing);
|
||||
linphone_address_unref(lAddr);
|
||||
// Legacy notification
|
||||
linphone_core_notify_is_composing_received(q->getCore()->getCCore(), cr);
|
||||
}
|
||||
|
||||
void ChatRoomPrivate::notifyStateChanged () {
|
||||
L_Q();
|
||||
linphone_core_notify_chat_room_state_changed(q->getCore()->getCCore(), L_GET_C_BACK_PTR(q), (LinphoneChatRoomState)state);
|
||||
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(q);
|
||||
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(cr);
|
||||
LinphoneChatRoomCbsStateChangedCb cb = linphone_chat_room_cbs_get_state_changed(cbs);
|
||||
if (cb)
|
||||
cb(cr, (LinphoneChatRoomState)state);
|
||||
LinphoneChatRoom *cr = getCChatRoom();
|
||||
linphone_core_notify_chat_room_state_changed(q->getCore()->getCCore(), cr, (LinphoneChatRoomState)state);
|
||||
_linphone_chat_room_notify_state_changed(cr, (LinphoneChatRoomState)state);
|
||||
}
|
||||
|
||||
void ChatRoomPrivate::notifyUndecryptableChatMessageReceived (const shared_ptr<ChatMessage> &chatMessage) {
|
||||
L_Q();
|
||||
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(q);
|
||||
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(cr);
|
||||
LinphoneChatRoomCbsUndecryptableMessageReceivedCb cb = linphone_chat_room_cbs_get_undecryptable_message_received(cbs);
|
||||
if (cb)
|
||||
cb(cr, L_GET_C_BACK_PTR(chatMessage));
|
||||
LinphoneChatRoom *cr = getCChatRoom();
|
||||
_linphone_chat_room_notify_undecryptable_message_received(cr, L_GET_C_BACK_PTR(chatMessage));
|
||||
linphone_core_notify_message_received_unable_decrypt(q->getCore()->getCCore(), cr, L_GET_C_BACK_PTR(chatMessage));
|
||||
}
|
||||
|
||||
|
|
@ -182,7 +181,6 @@ void ChatRoomPrivate::notifyUndecryptableChatMessageReceived (const shared_ptr<C
|
|||
LinphoneReason ChatRoomPrivate::onSipMessageReceived (SalOp *op, const SalMessage *message) {
|
||||
L_Q();
|
||||
|
||||
bool increaseMsgCount = true;
|
||||
LinphoneReason reason = LinphoneReasonNone;
|
||||
shared_ptr<ChatMessage> msg;
|
||||
|
||||
|
|
@ -196,8 +194,14 @@ LinphoneReason ChatRoomPrivate::onSipMessageReceived (SalOp *op, const SalMessag
|
|||
);
|
||||
|
||||
Content content;
|
||||
content.setContentType(message->content_type);
|
||||
content.setBodyFromUtf8(message->text ? message->text : "");
|
||||
if (message->url && (ContentType(message->content_type) == ContentType::ExternalBody)) {
|
||||
lInfo() << "Received a message with an external body URL " << message->url;
|
||||
content.setContentType(ContentType::FileTransfer);
|
||||
content.setBody(msg->getPrivate()->createFakeFileTransferFromUrl(message->url));
|
||||
} else {
|
||||
content.setContentType(ContentType(message->content_type));
|
||||
content.setBodyFromUtf8(message->text ? message->text : "");
|
||||
}
|
||||
msg->setInternalContent(content);
|
||||
|
||||
msg->getPrivate()->setTime(message->time);
|
||||
|
|
@ -217,43 +221,35 @@ LinphoneReason ChatRoomPrivate::onSipMessageReceived (SalOp *op, const SalMessag
|
|||
|
||||
if (msg->getPrivate()->getContentType() == ContentType::ImIsComposing) {
|
||||
onIsComposingReceived(msg->getFromAddress(), msg->getPrivate()->getText());
|
||||
increaseMsgCount = FALSE;
|
||||
if (lp_config_get_int(linphone_core_get_config(cCore), "sip", "deliver_imdn", 0) != 1) {
|
||||
goto end;
|
||||
}
|
||||
} else if (msg->getPrivate()->getContentType() == ContentType::Imdn) {
|
||||
onImdnReceived(msg->getPrivate()->getText());
|
||||
increaseMsgCount = FALSE;
|
||||
onImdnReceived(msg);
|
||||
if (lp_config_get_int(linphone_core_get_config(cCore), "sip", "deliver_imdn", 0) != 1) {
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
|
||||
if (increaseMsgCount) {
|
||||
/* Mark the message as pending so that if ChatRoom::markAsRead() is called in the
|
||||
* ChatRoomPrivate::chatMessageReceived() callback, it will effectively be marked as
|
||||
* being read before being stored. */
|
||||
pendingMessage = msg;
|
||||
}
|
||||
|
||||
onChatMessageReceived(msg);
|
||||
|
||||
pendingMessage = nullptr;
|
||||
|
||||
end:
|
||||
return reason;
|
||||
}
|
||||
|
||||
void ChatRoomPrivate::onChatMessageReceived (const shared_ptr<ChatMessage> &chatMessage) {
|
||||
const IdentityAddress &fromAddress = chatMessage->getFromAddress();
|
||||
isComposingHandler->stopRemoteRefreshTimer(fromAddress.asString());
|
||||
notifyIsComposingReceived(fromAddress, false);
|
||||
if ((chatMessage->getPrivate()->getContentType() != ContentType::ImIsComposing)
|
||||
&& (chatMessage->getPrivate()->getContentType() != ContentType::Imdn)
|
||||
) {
|
||||
isComposingHandler->stopRemoteRefreshTimer(fromAddress.asString());
|
||||
notifyIsComposingReceived(fromAddress, false);
|
||||
}
|
||||
chatMessage->getPrivate()->notifyReceiving();
|
||||
}
|
||||
|
||||
void ChatRoomPrivate::onImdnReceived (const string &text) {
|
||||
L_Q();
|
||||
Imdn::parse(*q, text);
|
||||
void ChatRoomPrivate::onImdnReceived (const shared_ptr<ChatMessage> &chatMessage) {
|
||||
Imdn::parse(chatMessage);
|
||||
}
|
||||
|
||||
void ChatRoomPrivate::onIsComposingReceived (const Address &remoteAddress, const string &text) {
|
||||
|
|
@ -273,6 +269,16 @@ void ChatRoomPrivate::onIsRemoteComposingStateChanged (const Address &remoteAddr
|
|||
notifyIsComposingReceived(remoteAddress, isComposing);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
LinphoneChatRoom *ChatRoomPrivate::getCChatRoom () const {
|
||||
L_Q();
|
||||
if (proxyChatRoom)
|
||||
return L_GET_C_BACK_PTR(proxyChatRoom);
|
||||
else
|
||||
return L_GET_C_BACK_PTR(q);
|
||||
}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
ChatRoom::ChatRoom (ChatRoomPrivate &p, const shared_ptr<Core> &core, const ChatRoomId &chatRoomId) :
|
||||
|
|
@ -321,12 +327,29 @@ ChatRoom::State ChatRoom::getState () const {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
list<shared_ptr<EventLog>> ChatRoom::getMessageHistory (int nLast) const {
|
||||
return getCore()->getPrivate()->mainDb->getHistory(getChatRoomId(), nLast, MainDb::Filter::ConferenceChatMessageFilter);
|
||||
}
|
||||
|
||||
list<shared_ptr<EventLog>> ChatRoom::getMessageHistoryRange (int begin, int end) const {
|
||||
return getCore()->getPrivate()->mainDb->getHistoryRange(getChatRoomId(), begin, end, MainDb::Filter::ConferenceChatMessageFilter);
|
||||
}
|
||||
|
||||
list<shared_ptr<EventLog>> ChatRoom::getHistory (int nLast) const {
|
||||
return getCore()->getPrivate()->mainDb->getHistory(getChatRoomId(), nLast);
|
||||
return getCore()->getPrivate()->mainDb->getHistory(
|
||||
getChatRoomId(),
|
||||
nLast,
|
||||
MainDb::FilterMask({ MainDb::Filter::ConferenceChatMessageFilter, MainDb::Filter::ConferenceInfoNoDeviceFilter })
|
||||
);
|
||||
}
|
||||
|
||||
list<shared_ptr<EventLog>> ChatRoom::getHistoryRange (int begin, int end) const {
|
||||
return getCore()->getPrivate()->mainDb->getHistoryRange(getChatRoomId(), begin, end);
|
||||
return getCore()->getPrivate()->mainDb->getHistoryRange(
|
||||
getChatRoomId(),
|
||||
begin,
|
||||
end,
|
||||
MainDb::FilterMask({ MainDb::Filter::ConferenceChatMessageFilter, MainDb::Filter::ConferenceInfoNoDeviceFilter })
|
||||
);
|
||||
}
|
||||
|
||||
int ChatRoom::getHistorySize () const {
|
||||
|
|
@ -335,7 +358,9 @@ int ChatRoom::getHistorySize () const {
|
|||
|
||||
void ChatRoom::deleteFromDb () {
|
||||
L_D();
|
||||
Core::deleteChatRoom(this->getSharedFromThis());
|
||||
// Keep a ref, otherwise the object might be destroyed before we can set the Deleted state
|
||||
shared_ptr<AbstractChatRoom> ref = this->getSharedFromThis();
|
||||
Core::deleteChatRoom(ref);
|
||||
d->setState(ChatRoom::State::Deleted);
|
||||
}
|
||||
|
||||
|
|
@ -419,15 +444,15 @@ void ChatRoom::markAsRead () {
|
|||
L_D();
|
||||
|
||||
CorePrivate *dCore = getCore()->getPrivate();
|
||||
for (auto &chatMessage : dCore->mainDb->getUnreadChatMessages(d->chatRoomId))
|
||||
chatMessage->sendDisplayNotification();
|
||||
for (auto &chatMessage : dCore->mainDb->getUnreadChatMessages(d->chatRoomId)) {
|
||||
// Do not send display notification for file transfer until it has been downloaded (it won't have a file transfer content anymore)
|
||||
if (!chatMessage->getPrivate()->hasFileTransferContent()) {
|
||||
chatMessage->sendDisplayNotification();
|
||||
chatMessage->getPrivate()->setState(ChatMessage::State::Displayed, true); // True will ensure the setState won't update the database so it will be done below by the markChatMessagesAsRead
|
||||
}
|
||||
}
|
||||
|
||||
dCore->mainDb->markChatMessagesAsRead(d->chatRoomId);
|
||||
|
||||
if (d->pendingMessage) {
|
||||
d->pendingMessage->updateState(ChatMessage::State::Displayed);
|
||||
d->pendingMessage->sendDisplayNotification();
|
||||
}
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ class ChatRoomPrivate;
|
|||
|
||||
class LINPHONE_PUBLIC ChatRoom : public AbstractChatRoom {
|
||||
public:
|
||||
friend class ProxyChatRoomPrivate;
|
||||
|
||||
L_OVERRIDE_SHARED_FROM_THIS(ChatRoom);
|
||||
|
||||
const ChatRoomId &getChatRoomId () const override;
|
||||
|
|
@ -42,6 +44,8 @@ public:
|
|||
|
||||
State getState () const override;
|
||||
|
||||
std::list<std::shared_ptr<EventLog>> getMessageHistory (int nLast) const override;
|
||||
std::list<std::shared_ptr<EventLog>> getMessageHistoryRange (int begin, int end) const override;
|
||||
std::list<std::shared_ptr<EventLog>> getHistory (int nLast) const override;
|
||||
std::list<std::shared_ptr<EventLog>> getHistoryRange (int begin, int end) const override;
|
||||
int getHistorySize () const override;
|
||||
|
|
|
|||
|
|
@ -30,8 +30,6 @@ LINPHONE_BEGIN_NAMESPACE
|
|||
|
||||
class ClientGroupChatRoomPrivate : public ChatRoomPrivate {
|
||||
public:
|
||||
ClientGroupChatRoomPrivate () = default;
|
||||
|
||||
std::list<IdentityAddress> cleanAddressesList (const std::list<IdentityAddress> &addresses) const;
|
||||
std::shared_ptr<CallSession> createSession ();
|
||||
void notifyReceived (const std::string &body);
|
||||
|
|
@ -46,8 +44,8 @@ public:
|
|||
void onChatRoomDeleteRequested (const std::shared_ptr<AbstractChatRoom> &chatRoom) override;
|
||||
|
||||
// CallSessionListener
|
||||
void onCallSessionSetReleased (const std::shared_ptr<const CallSession> &session) override;
|
||||
void onCallSessionStateChanged (const std::shared_ptr<const CallSession> &session, CallSession::State state, const std::string &message) override;
|
||||
void onCallSessionSetReleased (const std::shared_ptr<CallSession> &session) override;
|
||||
void onCallSessionStateChanged (const std::shared_ptr<CallSession> &session, CallSession::State state, const std::string &message) override;
|
||||
|
||||
private:
|
||||
CallSessionListener *callSessionListener = this;
|
||||
|
|
@ -55,7 +53,6 @@ private:
|
|||
ClientGroupChatRoom::CapabilitiesMask capabilities = ClientGroupChatRoom::Capabilities::Conference;
|
||||
bool deletionOnTerminationEnabled = false;
|
||||
BackgroundTask bgTask;
|
||||
|
||||
L_DECLARE_PUBLIC(ClientGroupChatRoom);
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -20,16 +20,16 @@
|
|||
#include "linphone/utils/utils.h"
|
||||
|
||||
#include "address/address-p.h"
|
||||
#include "c-wrapper/c-wrapper.h"
|
||||
#include "basic-chat-room.h"
|
||||
#include "basic-to-client-group-chat-room.h"
|
||||
#include "c-wrapper/c-wrapper.h"
|
||||
#include "client-group-chat-room-p.h"
|
||||
#include "conference/handlers/remote-conference-event-handler.h"
|
||||
#include "conference/participant-p.h"
|
||||
#include "conference/remote-conference-p.h"
|
||||
#include "conference/session/call-session-p.h"
|
||||
#include "content/content-disposition.h"
|
||||
#include "content/content-type.h"
|
||||
#include "core/core-p.h"
|
||||
#include "event-log/events.h"
|
||||
#include "logger/logger.h"
|
||||
#include "sal/refer-op.h"
|
||||
|
||||
|
|
@ -65,12 +65,11 @@ shared_ptr<CallSession> ClientGroupChatRoomPrivate::createSession () {
|
|||
if (capabilities & ClientGroupChatRoom::Capabilities::OneToOne)
|
||||
csp.addCustomHeader("One-To-One-Chat-Room", "true");
|
||||
|
||||
shared_ptr<Participant> focus = qConference->getPrivate()->focus;
|
||||
shared_ptr<CallSession> session = focus->getPrivate()->createSession(*q, &csp, false, callSessionListener);
|
||||
const Address &myAddress = q->getMe()->getAddress();
|
||||
Address myCleanedAddress(myAddress);
|
||||
myCleanedAddress.removeUriParam("gr"); // Remove gr parameter for INVITE
|
||||
session->configure(LinphoneCallOutgoing, nullptr, nullptr, myCleanedAddress, focus->getPrivate()->getDevices().front()->getAddress());
|
||||
ParticipantPrivate *dFocus = qConference->getPrivate()->focus->getPrivate();
|
||||
shared_ptr<CallSession> session = dFocus->createSession(*q, &csp, false, callSessionListener);
|
||||
Address myCleanedAddress(q->getMe()->getAddress());
|
||||
myCleanedAddress.removeUriParam("gr"); // Remove gr parameter for INVITE.
|
||||
session->configure(LinphoneCallOutgoing, nullptr, nullptr, myCleanedAddress, dFocus->getDevices().front()->getAddress());
|
||||
session->initiateOutgoing();
|
||||
session->getPrivate()->createOp();
|
||||
return session;
|
||||
|
|
@ -122,7 +121,7 @@ void ClientGroupChatRoomPrivate::onChatRoomDeleteRequested (const shared_ptr<Abs
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ClientGroupChatRoomPrivate::onCallSessionSetReleased (const shared_ptr<const CallSession> &session) {
|
||||
void ClientGroupChatRoomPrivate::onCallSessionSetReleased (const shared_ptr<CallSession> &session) {
|
||||
L_Q_T(RemoteConference, qConference);
|
||||
|
||||
ParticipantPrivate *participantPrivate = qConference->getPrivate()->focus->getPrivate();
|
||||
|
|
@ -131,7 +130,7 @@ void ClientGroupChatRoomPrivate::onCallSessionSetReleased (const shared_ptr<cons
|
|||
}
|
||||
|
||||
void ClientGroupChatRoomPrivate::onCallSessionStateChanged (
|
||||
const shared_ptr<const CallSession> &session,
|
||||
const shared_ptr<CallSession> &session,
|
||||
CallSession::State newState,
|
||||
const string &message
|
||||
) {
|
||||
|
|
@ -142,19 +141,35 @@ void ClientGroupChatRoomPrivate::onCallSessionStateChanged (
|
|||
if (q->getState() == ChatRoom::State::CreationPending) {
|
||||
IdentityAddress addr(session->getRemoteContactAddress()->asStringUriOnly());
|
||||
q->onConferenceCreated(addr);
|
||||
if (session->getRemoteContactAddress()->hasParam("isfocus"))
|
||||
if (session->getRemoteContactAddress()->hasParam("isfocus")) {
|
||||
bgTask.start(q->getCore(), 32); // It will be stopped when receiving the first notify
|
||||
qConference->getPrivate()->eventHandler->subscribe(q->getChatRoomId());
|
||||
}
|
||||
} else if (q->getState() == ChatRoom::State::TerminationPending)
|
||||
qConference->getPrivate()->focus->getPrivate()->getSession()->terminate();
|
||||
} else if ((newState == CallSession::State::Released) && (q->getState() == ChatRoom::State::TerminationPending)) {
|
||||
q->onConferenceTerminated(q->getConferenceAddress());
|
||||
} else if (newState == CallSession::State::Released) {
|
||||
if (q->getState() == ChatRoom::State::TerminationPending) {
|
||||
if (session->getReason() == LinphoneReasonNone) {
|
||||
// Everything is fine, the chat room has been left on the server side
|
||||
q->onConferenceTerminated(q->getConferenceAddress());
|
||||
} else {
|
||||
// Go to state TerminationFailed and then back to Created since it has not been terminated
|
||||
setState(ChatRoom::State::TerminationFailed);
|
||||
setState(ChatRoom::State::Created);
|
||||
}
|
||||
}
|
||||
} else if (newState == CallSession::State::Error) {
|
||||
if (q->getState() == ChatRoom::State::CreationPending)
|
||||
setState(ChatRoom::State::CreationFailed);
|
||||
else if (q->getState() == ChatRoom::State::TerminationPending) {
|
||||
// Go to state TerminationFailed and then back to Created since it has not been terminated
|
||||
setState(ChatRoom::State::TerminationFailed);
|
||||
setState(ChatRoom::State::Created);
|
||||
if (session->getReason() == LinphoneReasonNotFound) {
|
||||
// Somehow the chat room is no longer know on the server, so terminate it
|
||||
q->onConferenceTerminated(q->getConferenceAddress());
|
||||
} else {
|
||||
// Go to state TerminationFailed and then back to Created since it has not been terminated
|
||||
setState(ChatRoom::State::TerminationFailed);
|
||||
setState(ChatRoom::State::Created);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -168,15 +183,14 @@ ClientGroupChatRoom::ClientGroupChatRoom (
|
|||
const string &subject
|
||||
) : ChatRoom(*new ClientGroupChatRoomPrivate, core, ChatRoomId(IdentityAddress(), me)),
|
||||
RemoteConference(core, me, nullptr) {
|
||||
L_D();
|
||||
L_D_T(RemoteConference, dConference);
|
||||
|
||||
d->bgTask.setName("Client group chat room refer received");
|
||||
|
||||
L_D();
|
||||
|
||||
IdentityAddress focusAddr(uri);
|
||||
dConference->focus = make_shared<Participant>(focusAddr);
|
||||
dConference->focus->getPrivate()->addDevice(focusAddr);
|
||||
RemoteConference::setSubject(subject);
|
||||
d->bgTask.setName("Subscribe/notify of full state conference");
|
||||
}
|
||||
|
||||
ClientGroupChatRoom::ClientGroupChatRoom (
|
||||
|
|
@ -206,6 +220,11 @@ RemoteConference(core, me->getAddress(), nullptr) {
|
|||
dConference->eventHandler->subscribe(getChatRoomId());
|
||||
}
|
||||
|
||||
ClientGroupChatRoom::~ClientGroupChatRoom () {
|
||||
L_D();
|
||||
d->setCallSessionListener(nullptr);
|
||||
}
|
||||
|
||||
shared_ptr<Core> ClientGroupChatRoom::getCore () const {
|
||||
return ChatRoom::getCore();
|
||||
}
|
||||
|
|
@ -291,8 +310,12 @@ void ClientGroupChatRoom::addParticipants (
|
|||
|
||||
Content content;
|
||||
content.setBody(getResourceLists(addressesList));
|
||||
content.setContentType("application/resource-lists+xml");
|
||||
content.setContentDisposition("recipient-list");
|
||||
content.setContentType(ContentType::ResourceLists);
|
||||
content.setContentDisposition(ContentDisposition::RecipientList);
|
||||
// TODO: Activate compression
|
||||
//if (linphone_core_content_encoding_supported(getCore()->getCCore(), "deflate"))
|
||||
// content.setContentEncoding("deflate");
|
||||
// TODO: Activate compression
|
||||
|
||||
shared_ptr<CallSession> session = dConference->focus->getPrivate()->getSession();
|
||||
if (session)
|
||||
|
|
@ -394,9 +417,11 @@ void ClientGroupChatRoom::join () {
|
|||
|
||||
shared_ptr<CallSession> session = dConference->focus->getPrivate()->getSession();
|
||||
if (!session && ((getState() == ChatRoom::State::Instantiated) || (getState() == ChatRoom::State::Terminated))) {
|
||||
d->bgTask.start();
|
||||
session = d->createSession();
|
||||
session->startInvite(nullptr, "", nullptr);
|
||||
}
|
||||
if (session) {
|
||||
if (getState() != ChatRoom::State::TerminationPending)
|
||||
session->startInvite(nullptr, "", nullptr);
|
||||
d->setState(ChatRoom::State::CreationPending);
|
||||
}
|
||||
}
|
||||
|
|
@ -405,7 +430,6 @@ void ClientGroupChatRoom::leave () {
|
|||
L_D();
|
||||
L_D_T(RemoteConference, dConference);
|
||||
|
||||
d->bgTask.start();
|
||||
dConference->eventHandler->unsubscribe();
|
||||
|
||||
shared_ptr<CallSession> session = dConference->focus->getPrivate()->getSession();
|
||||
|
|
@ -442,7 +466,7 @@ void ClientGroupChatRoom::onConferenceTerminated (const IdentityAddress &addr) {
|
|||
L_D_T(RemoteConference, dConference);
|
||||
dConference->eventHandler->resetLastNotify();
|
||||
d->setState(ChatRoom::State::Terminated);
|
||||
getCore()->getPrivate()->mainDb->addEvent(make_shared<ConferenceEvent>(
|
||||
d->addEvent(make_shared<ConferenceEvent>(
|
||||
EventLog::Type::ConferenceTerminated,
|
||||
time(nullptr),
|
||||
d->chatRoomId
|
||||
|
|
@ -456,31 +480,33 @@ void ClientGroupChatRoom::onConferenceTerminated (const IdentityAddress &addr) {
|
|||
void ClientGroupChatRoom::onFirstNotifyReceived (const IdentityAddress &addr) {
|
||||
L_D();
|
||||
d->setState(ChatRoom::State::Created);
|
||||
|
||||
|
||||
if (getParticipantCount() == 1) {
|
||||
ChatRoomId id(getParticipants().front()->getAddress(), getMe()->getAddress());
|
||||
shared_ptr<AbstractChatRoom> chatRoom = getCore()->findChatRoom(id);
|
||||
if (chatRoom && (chatRoom->getCapabilities() & ChatRoom::Capabilities::Basic)) {
|
||||
BasicToClientGroupChatRoom::migrate(getSharedFromThis(), chatRoom);
|
||||
d->bgTask.stop();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
d->chatRoomListener->onChatRoomInsertInDatabaseRequested(getSharedFromThis());
|
||||
|
||||
d->bgTask.stop();
|
||||
// TODO: Bug. Event is inserted many times.
|
||||
// Avoid this in the future. Deal with signals/slots system.
|
||||
#if 0
|
||||
getCore()->getPrivate()->mainDb->addEvent(make_shared<ConferenceEvent>(
|
||||
d->addEvent(make_shared<ConferenceEvent>(
|
||||
EventLog::Type::ConferenceCreated,
|
||||
time(nullptr),
|
||||
d->chatRoomId
|
||||
));
|
||||
#endif
|
||||
d->bgTask.stop();
|
||||
}
|
||||
|
||||
void ClientGroupChatRoom::onParticipantAdded (const shared_ptr<ConferenceParticipantEvent> &event, bool isFullState) {
|
||||
L_D();
|
||||
L_D_T(RemoteConference, dConference);
|
||||
|
||||
const IdentityAddress &addr = event->getParticipantAddress();
|
||||
|
|
@ -499,18 +525,16 @@ void ClientGroupChatRoom::onParticipantAdded (const shared_ptr<ConferencePartici
|
|||
if (isFullState)
|
||||
return;
|
||||
|
||||
getCore()->getPrivate()->mainDb->addEvent(event);
|
||||
d->addEvent(event);
|
||||
|
||||
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(this);
|
||||
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(cr);
|
||||
LinphoneChatRoomCbsParticipantAddedCb cb = linphone_chat_room_cbs_get_participant_added(cbs);
|
||||
if (cb)
|
||||
cb(cr, L_GET_C_BACK_PTR(event));
|
||||
LinphoneChatRoom *cr = d->getCChatRoom();
|
||||
_linphone_chat_room_notify_participant_added(cr, L_GET_C_BACK_PTR(event));
|
||||
}
|
||||
|
||||
void ClientGroupChatRoom::onParticipantRemoved (const shared_ptr<ConferenceParticipantEvent> &event, bool isFullState) {
|
||||
(void)isFullState;
|
||||
|
||||
L_D();
|
||||
L_D_T(RemoteConference, dConference);
|
||||
|
||||
const IdentityAddress &addr = event->getParticipantAddress();
|
||||
|
|
@ -521,16 +545,15 @@ void ClientGroupChatRoom::onParticipantRemoved (const shared_ptr<ConferenceParti
|
|||
}
|
||||
|
||||
dConference->participants.remove(participant);
|
||||
getCore()->getPrivate()->mainDb->addEvent(event);
|
||||
d->addEvent(event);
|
||||
|
||||
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(this);
|
||||
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(cr);
|
||||
LinphoneChatRoomCbsParticipantRemovedCb cb = linphone_chat_room_cbs_get_participant_removed(cbs);
|
||||
if (cb)
|
||||
cb(cr, L_GET_C_BACK_PTR(event));
|
||||
LinphoneChatRoom *cr = d->getCChatRoom();
|
||||
_linphone_chat_room_notify_participant_removed(cr, L_GET_C_BACK_PTR(event));
|
||||
}
|
||||
|
||||
void ClientGroupChatRoom::onParticipantSetAdmin (const shared_ptr<ConferenceParticipantEvent> &event, bool isFullState) {
|
||||
L_D();
|
||||
|
||||
const IdentityAddress &addr = event->getParticipantAddress();
|
||||
shared_ptr<Participant> participant;
|
||||
if (isMe(addr))
|
||||
|
|
@ -550,16 +573,15 @@ void ClientGroupChatRoom::onParticipantSetAdmin (const shared_ptr<ConferencePart
|
|||
if (isFullState)
|
||||
return;
|
||||
|
||||
getCore()->getPrivate()->mainDb->addEvent(event);
|
||||
d->addEvent(event);
|
||||
|
||||
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(this);
|
||||
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(cr);
|
||||
LinphoneChatRoomCbsParticipantAdminStatusChangedCb cb = linphone_chat_room_cbs_get_participant_admin_status_changed(cbs);
|
||||
if (cb)
|
||||
cb(cr, L_GET_C_BACK_PTR(event));
|
||||
LinphoneChatRoom *cr = d->getCChatRoom();
|
||||
_linphone_chat_room_notify_participant_admin_status_changed(cr, L_GET_C_BACK_PTR(event));
|
||||
}
|
||||
|
||||
void ClientGroupChatRoom::onSubjectChanged (const shared_ptr<ConferenceSubjectEvent> &event, bool isFullState) {
|
||||
L_D();
|
||||
|
||||
if (getSubject() == event->getSubject())
|
||||
return; // No change in the local subject, do not notify
|
||||
RemoteConference::setSubject(event->getSubject());
|
||||
|
|
@ -567,16 +589,15 @@ void ClientGroupChatRoom::onSubjectChanged (const shared_ptr<ConferenceSubjectEv
|
|||
if (isFullState)
|
||||
return;
|
||||
|
||||
getCore()->getPrivate()->mainDb->addEvent(event);
|
||||
d->addEvent(event);
|
||||
|
||||
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(this);
|
||||
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(cr);
|
||||
LinphoneChatRoomCbsSubjectChangedCb cb = linphone_chat_room_cbs_get_subject_changed(cbs);
|
||||
if (cb)
|
||||
cb(cr, L_GET_C_BACK_PTR(event));
|
||||
LinphoneChatRoom *cr = d->getCChatRoom();
|
||||
_linphone_chat_room_notify_subject_changed(cr, L_GET_C_BACK_PTR(event));
|
||||
}
|
||||
|
||||
void ClientGroupChatRoom::onParticipantDeviceAdded (const shared_ptr<ConferenceParticipantDeviceEvent> &event, bool isFullState) {
|
||||
L_D();
|
||||
|
||||
const IdentityAddress &addr = event->getParticipantAddress();
|
||||
shared_ptr<Participant> participant;
|
||||
if (isMe(addr))
|
||||
|
|
@ -592,16 +613,15 @@ void ClientGroupChatRoom::onParticipantDeviceAdded (const shared_ptr<ConferenceP
|
|||
if (isFullState)
|
||||
return;
|
||||
|
||||
getCore()->getPrivate()->mainDb->addEvent(event);
|
||||
d->addEvent(event);
|
||||
|
||||
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(this);
|
||||
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(cr);
|
||||
LinphoneChatRoomCbsParticipantDeviceAddedCb cb = linphone_chat_room_cbs_get_participant_device_added(cbs);
|
||||
if (cb)
|
||||
cb(cr, L_GET_C_BACK_PTR(event));
|
||||
LinphoneChatRoom *cr = d->getCChatRoom();
|
||||
_linphone_chat_room_notify_participant_device_added(cr, L_GET_C_BACK_PTR(event));
|
||||
}
|
||||
|
||||
void ClientGroupChatRoom::onParticipantDeviceRemoved (const shared_ptr<ConferenceParticipantDeviceEvent> &event, bool isFullState) {
|
||||
L_D();
|
||||
|
||||
(void)isFullState;
|
||||
|
||||
const IdentityAddress &addr = event->getParticipantAddress();
|
||||
|
|
@ -615,13 +635,10 @@ void ClientGroupChatRoom::onParticipantDeviceRemoved (const shared_ptr<Conferenc
|
|||
return;
|
||||
}
|
||||
participant->getPrivate()->removeDevice(event->getDeviceAddress());
|
||||
getCore()->getPrivate()->mainDb->addEvent(event);
|
||||
d->addEvent(event);
|
||||
|
||||
LinphoneChatRoom *cr = L_GET_C_BACK_PTR(this);
|
||||
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(cr);
|
||||
LinphoneChatRoomCbsParticipantDeviceRemovedCb cb = linphone_chat_room_cbs_get_participant_device_removed(cbs);
|
||||
if (cb)
|
||||
cb(cr, L_GET_C_BACK_PTR(event));
|
||||
LinphoneChatRoom *cr = d->getCChatRoom();
|
||||
_linphone_chat_room_notify_participant_device_removed(cr, L_GET_C_BACK_PTR(event));
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ class LINPHONE_PUBLIC ClientGroupChatRoom : public ChatRoom, public RemoteConfer
|
|||
friend class BasicToClientGroupChatRoomPrivate;
|
||||
friend class ClientGroupToBasicChatRoomPrivate;
|
||||
friend class Core;
|
||||
friend class CorePrivate;
|
||||
|
||||
public:
|
||||
L_OVERRIDE_SHARED_FROM_THIS(ClientGroupChatRoom);
|
||||
|
|
@ -55,8 +56,10 @@ public:
|
|||
unsigned int lastNotifyId
|
||||
);
|
||||
|
||||
~ClientGroupChatRoom ();
|
||||
|
||||
std::shared_ptr<Core> getCore () const;
|
||||
|
||||
|
||||
void allowCpim (bool value) override;
|
||||
void allowMultipart (bool value) override;
|
||||
bool canHandleCpim () const override;
|
||||
|
|
@ -100,11 +103,11 @@ private:
|
|||
void onConferenceTerminated (const IdentityAddress &addr) override;
|
||||
void onFirstNotifyReceived (const IdentityAddress &addr) override;
|
||||
void onParticipantAdded (const std::shared_ptr<ConferenceParticipantEvent> &event, bool isFullState) override;
|
||||
void onParticipantDeviceAdded (const std::shared_ptr<ConferenceParticipantDeviceEvent> &event, bool isFullState) override;
|
||||
void onParticipantDeviceRemoved (const std::shared_ptr<ConferenceParticipantDeviceEvent> &event, bool isFullState) override;
|
||||
void onParticipantRemoved (const std::shared_ptr<ConferenceParticipantEvent> &event, bool isFullState) override;
|
||||
void onParticipantSetAdmin (const std::shared_ptr<ConferenceParticipantEvent> &event, bool isFullState) override;
|
||||
void onSubjectChanged (const std::shared_ptr<ConferenceSubjectEvent> &event, bool isFullState) override;
|
||||
void onParticipantDeviceAdded (const std::shared_ptr<ConferenceParticipantDeviceEvent> &event, bool isFullState) override;
|
||||
void onParticipantDeviceRemoved (const std::shared_ptr<ConferenceParticipantDeviceEvent> &event, bool isFullState) override;
|
||||
|
||||
L_DECLARE_PRIVATE(ClientGroupChatRoom);
|
||||
L_DISABLE_COPY(ClientGroupChatRoom);
|
||||
|
|
|
|||
|
|
@ -48,40 +48,41 @@ public:
|
|||
|
||||
void onChatRoomDeleteRequested (const shared_ptr<AbstractChatRoom> &chatRoom) override {
|
||||
L_Q();
|
||||
q->getCore()->deleteChatRoom(q->getSharedFromThis());
|
||||
// Keep a ref, otherwise the object might be destroyed before we can set the Deleted state
|
||||
shared_ptr<AbstractChatRoom> ref = q->getSharedFromThis();
|
||||
q->getCore()->deleteChatRoom(ref);
|
||||
setState(AbstractChatRoom::State::Deleted);
|
||||
}
|
||||
|
||||
void onCallSessionSetReleased (const std::shared_ptr<const CallSession> &session) override {
|
||||
void onCallSessionSetReleased (const shared_ptr<CallSession> &session) override {
|
||||
if (!(chatRoom->getCapabilities() & ChatRoom::Capabilities::Conference))
|
||||
return;
|
||||
static_pointer_cast<ClientGroupChatRoom>(chatRoom)->getPrivate()->onCallSessionSetReleased(session);
|
||||
}
|
||||
|
||||
void onCallSessionStateChanged (
|
||||
const shared_ptr<const CallSession> &session,
|
||||
const shared_ptr<CallSession> &session,
|
||||
CallSession::State newState,
|
||||
const string &message
|
||||
) override {
|
||||
L_Q();
|
||||
// Keep a ref, otherwise the object might be destroyed when calling Core::deleteChatRoom()
|
||||
shared_ptr<AbstractChatRoom> ref = q->getSharedFromThis();
|
||||
// TODO: Avoid cast, use capabilities.
|
||||
shared_ptr<ClientGroupChatRoom> cgcr = dynamic_pointer_cast<ClientGroupChatRoom>(chatRoom);
|
||||
if (!cgcr)
|
||||
return;
|
||||
if ((newState == CallSession::State::Error) && (cgcr->getState() == ChatRoom::State::CreationPending)
|
||||
&& (session->getReason() == LinphoneReasonNotAcceptable) && (invitedAddresses.size() == 1)) {
|
||||
teardownCallbacks();
|
||||
teardownProxy();
|
||||
cgcr->getPrivate()->onCallSessionStateChanged(session, newState, message);
|
||||
cgcr->getPrivate()->setCallSessionListener(nullptr);
|
||||
cgcr->getPrivate()->setChatRoomListener(nullptr);
|
||||
Core::deleteChatRoom(q->getSharedFromThis());
|
||||
setupCallbacks();
|
||||
setupProxy();
|
||||
LinphoneChatRoom *lcr = L_GET_C_BACK_PTR(q);
|
||||
shared_ptr<AbstractChatRoom> bcr = cgcr->getCore()->onlyGetOrCreateBasicChatRoom(invitedAddresses.front());
|
||||
shared_ptr<AbstractChatRoom> bcr = cgcr->getCore()->getOrCreateBasicChatRoom(invitedAddresses.front());
|
||||
L_SET_CPP_PTR_FROM_C_OBJECT(lcr, bcr);
|
||||
bcr->getPrivate()->setState(ChatRoom::State::Instantiated);
|
||||
bcr->getPrivate()->setState(ChatRoom::State::Created);
|
||||
cgcr->getCore()->getPrivate()->insertChatRoom(bcr);
|
||||
cgcr->getCore()->getPrivate()->insertChatRoomWithDb(bcr);
|
||||
return;
|
||||
}
|
||||
cgcr->getPrivate()->onCallSessionStateChanged(session, newState, message);
|
||||
|
|
@ -111,7 +112,7 @@ void ClientGroupToBasicChatRoom::addParticipant (
|
|||
ProxyChatRoom::addParticipant(participantAddress, params, hasMedia);
|
||||
}
|
||||
void ClientGroupToBasicChatRoom::addParticipants (
|
||||
const std::list<IdentityAddress> &addresses,
|
||||
const list<IdentityAddress> &addresses,
|
||||
const CallSessionParams *params,
|
||||
bool hasMedia
|
||||
) {
|
||||
|
|
|
|||
|
|
@ -21,6 +21,7 @@
|
|||
#define _L_PROXY_CHAT_ROOM_P_H_
|
||||
|
||||
#include "abstract-chat-room-p.h"
|
||||
#include "proxy-chat-room.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
|
|
@ -44,6 +45,10 @@ public:
|
|||
chatRoom->getPrivate()->sendChatMessage(chatMessage);
|
||||
}
|
||||
|
||||
inline void addEvent (const std::shared_ptr<EventLog> &eventLog) override {
|
||||
chatRoom->getPrivate()->addEvent(eventLog);
|
||||
}
|
||||
|
||||
inline void addTransientEvent (const std::shared_ptr<EventLog> &eventLog) override {
|
||||
chatRoom->getPrivate()->addTransientEvent(eventLog);
|
||||
}
|
||||
|
|
@ -68,8 +73,8 @@ public:
|
|||
chatRoom->getPrivate()->onChatMessageReceived(chatMessage);
|
||||
}
|
||||
|
||||
void setupCallbacks ();
|
||||
void teardownCallbacks ();
|
||||
void setupProxy ();
|
||||
void teardownProxy ();
|
||||
|
||||
std::shared_ptr<AbstractChatRoom> chatRoom;
|
||||
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@
|
|||
*/
|
||||
|
||||
#include "basic-to-client-group-chat-room.h"
|
||||
#include "chat-room.h"
|
||||
#include "chat-room-p.h"
|
||||
#include "proxy-chat-room-p.h"
|
||||
#include "c-wrapper/c-wrapper.h"
|
||||
|
||||
|
|
@ -28,114 +28,13 @@ using namespace std;
|
|||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
#define PROXY_CALLBACK(callback, ...) \
|
||||
LinphoneChatRoomCbs *proxiedCbs = linphone_chat_room_get_callbacks(cr); \
|
||||
ProxyChatRoom *pcr = static_cast<ProxyChatRoom *>(linphone_chat_room_cbs_get_user_data(proxiedCbs)); \
|
||||
LinphoneChatRoom *lcr = L_GET_C_BACK_PTR(pcr->getSharedFromThis()); \
|
||||
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(lcr); \
|
||||
if (linphone_chat_room_cbs_get_ ## callback(cbs)) \
|
||||
linphone_chat_room_cbs_get_ ## callback(cbs)(lcr, ##__VA_ARGS__)
|
||||
|
||||
static void chatMessageReceived (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
|
||||
PROXY_CALLBACK(chat_message_received, event_log);
|
||||
}
|
||||
|
||||
static void chatMessageSent (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
|
||||
PROXY_CALLBACK(chat_message_sent, event_log);
|
||||
}
|
||||
|
||||
static void conferenceAddressGeneration (LinphoneChatRoom *cr) {
|
||||
PROXY_CALLBACK(conference_address_generation);
|
||||
}
|
||||
|
||||
static void isComposingReceived (LinphoneChatRoom *cr, const LinphoneAddress *remoteAddr, bool_t isComposing) {
|
||||
PROXY_CALLBACK(is_composing_received, remoteAddr, isComposing);
|
||||
}
|
||||
|
||||
static void messageReceived (LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
|
||||
PROXY_CALLBACK(message_received, msg);
|
||||
}
|
||||
|
||||
static void participantAdded (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
|
||||
PROXY_CALLBACK(participant_added, event_log);
|
||||
}
|
||||
|
||||
static void participantAdminStatusChanged (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
|
||||
PROXY_CALLBACK(participant_admin_status_changed, event_log);
|
||||
}
|
||||
|
||||
static void participantDeviceAdded (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
|
||||
PROXY_CALLBACK(participant_device_added, event_log);
|
||||
}
|
||||
|
||||
static void participantDeviceFetched (LinphoneChatRoom *cr, const LinphoneAddress *participantAddr) {
|
||||
PROXY_CALLBACK(participant_device_fetched, participantAddr);
|
||||
}
|
||||
|
||||
static void participantDeviceRemoved (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
|
||||
PROXY_CALLBACK(participant_device_removed, event_log);
|
||||
}
|
||||
|
||||
static void participantRemoved (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
|
||||
PROXY_CALLBACK(participant_removed, event_log);
|
||||
}
|
||||
|
||||
static void participantsCapabilitiesChecked (LinphoneChatRoom *cr, const LinphoneAddress *deviceAddr, const bctbx_list_t *participantsAddr) {
|
||||
PROXY_CALLBACK(participants_capabilities_checked, deviceAddr, participantsAddr);
|
||||
}
|
||||
|
||||
static void stateChanged (LinphoneChatRoom *cr, LinphoneChatRoomState newState) {
|
||||
PROXY_CALLBACK(state_changed, newState);
|
||||
}
|
||||
|
||||
static void subjectChanged (LinphoneChatRoom *cr, const LinphoneEventLog *event_log) {
|
||||
PROXY_CALLBACK(subject_changed, event_log);
|
||||
}
|
||||
|
||||
static void undecryptableMessageReceived (LinphoneChatRoom *cr, LinphoneChatMessage *msg) {
|
||||
PROXY_CALLBACK(undecryptable_message_received, msg);
|
||||
}
|
||||
|
||||
void ProxyChatRoomPrivate::setupCallbacks () {
|
||||
void ProxyChatRoomPrivate::setupProxy () {
|
||||
L_Q();
|
||||
LinphoneChatRoom *lcr = L_GET_C_BACK_PTR(chatRoom);
|
||||
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(lcr);
|
||||
linphone_chat_room_cbs_set_user_data(cbs, q);
|
||||
linphone_chat_room_cbs_set_chat_message_received(cbs, chatMessageReceived);
|
||||
linphone_chat_room_cbs_set_chat_message_sent(cbs, chatMessageSent);
|
||||
linphone_chat_room_cbs_set_conference_address_generation(cbs, conferenceAddressGeneration);
|
||||
linphone_chat_room_cbs_set_is_composing_received(cbs, isComposingReceived);
|
||||
linphone_chat_room_cbs_set_message_received(cbs, messageReceived);
|
||||
linphone_chat_room_cbs_set_participant_added(cbs, participantAdded);
|
||||
linphone_chat_room_cbs_set_participant_admin_status_changed(cbs, participantAdminStatusChanged);
|
||||
linphone_chat_room_cbs_set_participant_device_added(cbs, participantDeviceAdded);
|
||||
linphone_chat_room_cbs_set_participant_device_fetched(cbs, participantDeviceFetched);
|
||||
linphone_chat_room_cbs_set_participant_device_removed(cbs, participantDeviceRemoved);
|
||||
linphone_chat_room_cbs_set_participant_removed(cbs, participantRemoved);
|
||||
linphone_chat_room_cbs_set_participants_capabilities_checked(cbs, participantsCapabilitiesChecked);
|
||||
linphone_chat_room_cbs_set_state_changed(cbs, stateChanged);
|
||||
linphone_chat_room_cbs_set_subject_changed(cbs, subjectChanged);
|
||||
linphone_chat_room_cbs_set_undecryptable_message_received(cbs, undecryptableMessageReceived);
|
||||
static_pointer_cast<ChatRoom>(chatRoom)->getPrivate()->setProxyChatRoom(q);
|
||||
}
|
||||
|
||||
void ProxyChatRoomPrivate::teardownCallbacks () {
|
||||
LinphoneChatRoom *lcr = L_GET_C_BACK_PTR(chatRoom);
|
||||
LinphoneChatRoomCbs *cbs = linphone_chat_room_get_callbacks(lcr);
|
||||
linphone_chat_room_cbs_set_chat_message_received(cbs, nullptr);
|
||||
linphone_chat_room_cbs_set_chat_message_sent(cbs, nullptr);
|
||||
linphone_chat_room_cbs_set_conference_address_generation(cbs, nullptr);
|
||||
linphone_chat_room_cbs_set_is_composing_received(cbs, nullptr);
|
||||
linphone_chat_room_cbs_set_message_received(cbs, nullptr);
|
||||
linphone_chat_room_cbs_set_participant_added(cbs, nullptr);
|
||||
linphone_chat_room_cbs_set_participant_admin_status_changed(cbs, nullptr);
|
||||
linphone_chat_room_cbs_set_participant_device_added(cbs, nullptr);
|
||||
linphone_chat_room_cbs_set_participant_device_fetched(cbs, nullptr);
|
||||
linphone_chat_room_cbs_set_participant_device_removed(cbs, nullptr);
|
||||
linphone_chat_room_cbs_set_participant_removed(cbs, nullptr);
|
||||
linphone_chat_room_cbs_set_participants_capabilities_checked(cbs, nullptr);
|
||||
linphone_chat_room_cbs_set_state_changed(cbs, nullptr);
|
||||
linphone_chat_room_cbs_set_subject_changed(cbs, nullptr);
|
||||
linphone_chat_room_cbs_set_undecryptable_message_received(cbs, nullptr);
|
||||
void ProxyChatRoomPrivate::teardownProxy () {
|
||||
static_pointer_cast<ChatRoom>(chatRoom)->getPrivate()->setProxyChatRoom(nullptr);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -144,7 +43,7 @@ void ProxyChatRoomPrivate::teardownCallbacks () {
|
|||
AbstractChatRoom(p, chatRoom->getCore()) {
|
||||
L_D();
|
||||
d->chatRoom = chatRoom;
|
||||
d->setupCallbacks();
|
||||
d->setupProxy();
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -195,6 +94,16 @@ bool ProxyChatRoom::hasBeenLeft () const {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
list<shared_ptr<EventLog>> ProxyChatRoom::getMessageHistory (int nLast) const {
|
||||
L_D();
|
||||
return d->chatRoom->getMessageHistory(nLast);
|
||||
}
|
||||
|
||||
list<shared_ptr<EventLog>> ProxyChatRoom::getMessageHistoryRange (int begin, int end) const {
|
||||
L_D();
|
||||
return d->chatRoom->getMessageHistoryRange(begin, end);
|
||||
}
|
||||
|
||||
list<shared_ptr<EventLog>> ProxyChatRoom::getHistory (int nLast) const {
|
||||
L_D();
|
||||
return d->chatRoom->getHistory(nLast);
|
||||
|
|
|
|||
|
|
@ -30,6 +30,8 @@ class ChatRoom;
|
|||
class ProxyChatRoomPrivate;
|
||||
|
||||
class LINPHONE_PUBLIC ProxyChatRoom : public AbstractChatRoom {
|
||||
friend class CorePrivate;
|
||||
|
||||
public:
|
||||
const ChatRoomId &getChatRoomId () const override;
|
||||
|
||||
|
|
@ -43,6 +45,8 @@ public:
|
|||
State getState () const override;
|
||||
bool hasBeenLeft () const override;
|
||||
|
||||
std::list<std::shared_ptr<EventLog>> getMessageHistory (int nLast) const override;
|
||||
std::list<std::shared_ptr<EventLog>> getMessageHistoryRange (int begin, int end) const override;
|
||||
std::list<std::shared_ptr<EventLog>> getHistory (int nLast) const override;
|
||||
std::list<std::shared_ptr<EventLog>> getHistoryRange (int begin, int end) const override;
|
||||
int getHistorySize () const override;
|
||||
|
|
|
|||
|
|
@ -29,13 +29,17 @@ LINPHONE_BEGIN_NAMESPACE
|
|||
|
||||
class RealTimeTextChatRoomPrivate : public BasicChatRoomPrivate {
|
||||
public:
|
||||
RealTimeTextChatRoomPrivate () = default;
|
||||
struct Character {
|
||||
uint32_t value;
|
||||
bool hasBeenRead;
|
||||
};
|
||||
|
||||
void realtimeTextReceived (uint32_t character, LinphoneCall *call);
|
||||
void realtimeTextReceived (uint32_t character, const std::shared_ptr<Call> &call);
|
||||
void sendChatMessage (const std::shared_ptr<ChatMessage> &chatMessage) override;
|
||||
void setCall (const std::shared_ptr<Call> &value) { call = value; }
|
||||
|
||||
LinphoneCall *call = nullptr;
|
||||
std::list<LinphoneChatMessageCharacter *> receivedRttCharacters;
|
||||
std::weak_ptr<Call> call;
|
||||
std::list<Character> receivedRttCharacters;
|
||||
std::shared_ptr<ChatMessage> pendingMessage = nullptr;
|
||||
|
||||
private:
|
||||
|
|
|
|||
|
|
@ -18,6 +18,7 @@
|
|||
*/
|
||||
|
||||
#include "c-wrapper/c-wrapper.h"
|
||||
#include "call/call.h"
|
||||
#include "chat/chat-message/chat-message-p.h"
|
||||
#include "conference/participant.h"
|
||||
#include "core/core.h"
|
||||
|
|
@ -32,7 +33,7 @@ LINPHONE_BEGIN_NAMESPACE
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void RealTimeTextChatRoomPrivate::realtimeTextReceived (uint32_t character, LinphoneCall *call) {
|
||||
void RealTimeTextChatRoomPrivate::realtimeTextReceived (uint32_t character, const shared_ptr<Call> &call) {
|
||||
L_Q();
|
||||
const uint32_t new_line = 0x2028;
|
||||
const uint32_t crlf = 0x0D0A;
|
||||
|
|
@ -41,56 +42,48 @@ void RealTimeTextChatRoomPrivate::realtimeTextReceived (uint32_t character, Linp
|
|||
shared_ptr<Core> core = q->getCore();
|
||||
LinphoneCore *cCore = core->getCCore();
|
||||
|
||||
if (call && linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(call))) {
|
||||
LinphoneChatMessageCharacter *cmc = bctbx_new0(LinphoneChatMessageCharacter, 1);
|
||||
|
||||
if (call && call->getCurrentParams()->realtimeTextEnabled()) {
|
||||
if (!pendingMessage)
|
||||
pendingMessage = q->createChatMessage("");
|
||||
|
||||
cmc->value = character;
|
||||
cmc->has_been_read = FALSE;
|
||||
Character cmc;
|
||||
cmc.value = character;
|
||||
cmc.hasBeenRead = false;
|
||||
receivedRttCharacters.push_back(cmc);
|
||||
|
||||
remoteIsComposing.push_back(q->getPeerAddress());
|
||||
linphone_core_notify_is_composing_received(cCore, L_GET_C_BACK_PTR(q));
|
||||
linphone_core_notify_is_composing_received(cCore, getCChatRoom());
|
||||
|
||||
if ((character == new_line) || (character == crlf) || (character == lf)) {
|
||||
/* End of message */
|
||||
// End of message
|
||||
lDebug() << "New line received, forge a message with content " << pendingMessage->getPrivate()->getText().c_str();
|
||||
// TODO: REPAIR ME.
|
||||
// pendingMessage->setFromAddress(peerAddress);
|
||||
// pendingMessage->setToAddress(
|
||||
// Address(
|
||||
// linphone_call_get_dest_proxy(call)
|
||||
// ? linphone_address_as_string(linphone_call_get_dest_proxy(call)->identity_address)
|
||||
// : linphone_core_get_identity(cCore)
|
||||
// )
|
||||
// );
|
||||
pendingMessage->getPrivate()->setState(ChatMessage::State::Delivered);
|
||||
pendingMessage->getPrivate()->setDirection(ChatMessage::Direction::Incoming);
|
||||
pendingMessage->getPrivate()->setTime(::ms_time(0));
|
||||
|
||||
if (lp_config_get_int(linphone_core_get_config(cCore), "misc", "store_rtt_messages", 1) == 1)
|
||||
pendingMessage->getPrivate()->storeInDb();
|
||||
|
||||
onChatMessageReceived(pendingMessage);
|
||||
pendingMessage = nullptr;
|
||||
for (auto &rttChars : receivedRttCharacters)
|
||||
ms_free(rttChars);
|
||||
receivedRttCharacters.clear();
|
||||
} else {
|
||||
char *value = Utils::utf8ToChar(character);
|
||||
char *text = (char *)pendingMessage->getPrivate()->getText().c_str();
|
||||
pendingMessage->getPrivate()->setText(ms_strcat_printf(text, value));
|
||||
string text(pendingMessage->getPrivate()->getText());
|
||||
text += string(value);
|
||||
pendingMessage->getPrivate()->setText(text);
|
||||
lDebug() << "Received RTT character: " << value << " (" << character << "), pending text is " << pendingMessage->getPrivate()->getText();
|
||||
delete value;
|
||||
delete[] value;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RealTimeTextChatRoomPrivate::sendChatMessage (const shared_ptr<ChatMessage> &chatMessage) {
|
||||
if (call && linphone_call_params_realtime_text_enabled(linphone_call_get_current_params(call))) {
|
||||
uint32_t new_line = 0x2028;
|
||||
chatMessage->putCharacter(new_line);
|
||||
L_Q();
|
||||
shared_ptr<Call> call = q->getCall();
|
||||
if (call && call->getCurrentParams()->realtimeTextEnabled()) {
|
||||
uint32_t newLine = 0x2028;
|
||||
chatMessage->putCharacter(newLine);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -99,26 +92,16 @@ void RealTimeTextChatRoomPrivate::sendChatMessage (const shared_ptr<ChatMessage>
|
|||
RealTimeTextChatRoom::RealTimeTextChatRoom (const shared_ptr<Core> &core, const ChatRoomId &chatRoomId) :
|
||||
BasicChatRoom(*new RealTimeTextChatRoomPrivate, core, chatRoomId) {}
|
||||
|
||||
RealTimeTextChatRoom::~RealTimeTextChatRoom () {
|
||||
L_D();
|
||||
|
||||
if (!d->receivedRttCharacters.empty())
|
||||
for (auto &rttChars : d->receivedRttCharacters)
|
||||
bctbx_free(rttChars);
|
||||
}
|
||||
|
||||
RealTimeTextChatRoom::CapabilitiesMask RealTimeTextChatRoom::getCapabilities () const {
|
||||
return BasicChatRoom::getCapabilities() | Capabilities::RealTimeText;
|
||||
}
|
||||
|
||||
uint32_t RealTimeTextChatRoom::getChar () const {
|
||||
L_D();
|
||||
if (!d->receivedRttCharacters.empty()) {
|
||||
for (auto &cmc : d->receivedRttCharacters) {
|
||||
if (!cmc->has_been_read) {
|
||||
cmc->has_been_read = TRUE;
|
||||
return cmc->value;
|
||||
}
|
||||
for (const auto &cmc : d->receivedRttCharacters) {
|
||||
if (!cmc.hasBeenRead) {
|
||||
const_cast<RealTimeTextChatRoomPrivate::Character *>(&cmc)->hasBeenRead = true;
|
||||
return cmc.value;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
|
|
@ -126,9 +109,9 @@ uint32_t RealTimeTextChatRoom::getChar () const {
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
LinphoneCall *RealTimeTextChatRoom::getCall () const {
|
||||
shared_ptr<Call> RealTimeTextChatRoom::getCall () const {
|
||||
L_D();
|
||||
return d->call;
|
||||
return d->call.lock();
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -26,18 +26,20 @@
|
|||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
class Call;
|
||||
class RealTimeTextChatRoomPrivate;
|
||||
|
||||
class LINPHONE_PUBLIC RealTimeTextChatRoom : public BasicChatRoom {
|
||||
friend class CallPrivate;
|
||||
friend class CorePrivate;
|
||||
|
||||
public:
|
||||
~RealTimeTextChatRoom ();
|
||||
~RealTimeTextChatRoom () = default;
|
||||
|
||||
CapabilitiesMask getCapabilities () const override;
|
||||
|
||||
uint32_t getChar () const;
|
||||
LinphoneCall *getCall () const;
|
||||
std::shared_ptr<Call> getCall () const;
|
||||
|
||||
private:
|
||||
RealTimeTextChatRoom (const std::shared_ptr<Core> &core, const ChatRoomId &chatRoomId);
|
||||
|
|
|
|||
|
|
@ -20,24 +20,39 @@
|
|||
#ifndef _L_SERVER_GROUP_CHAT_ROOM_P_H_
|
||||
#define _L_SERVER_GROUP_CHAT_ROOM_P_H_
|
||||
|
||||
#include <chrono>
|
||||
#include <queue>
|
||||
#include <unordered_map>
|
||||
|
||||
#include "chat-room-p.h"
|
||||
#include "server-group-chat-room.h"
|
||||
#include "conference/participant-device.h"
|
||||
|
||||
// =============================================================================
|
||||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
class ParticipantDevice;
|
||||
|
||||
class ServerGroupChatRoomPrivate : public ChatRoomPrivate {
|
||||
public:
|
||||
void setState (ChatRoom::State state) override;
|
||||
|
||||
std::shared_ptr<Participant> addParticipant (const IdentityAddress &participantAddress);
|
||||
void removeParticipant (const std::shared_ptr<const Participant> &participant);
|
||||
std::shared_ptr<Participant> findRemovedParticipant (const std::shared_ptr<const CallSession> &session) const;
|
||||
|
||||
std::shared_ptr<Participant> findFilteredParticipant (const std::shared_ptr<const CallSession> &session) const;
|
||||
std::shared_ptr<Participant> findFilteredParticipant (const IdentityAddress &participantAddress) const;
|
||||
|
||||
ParticipantDevice::State getParticipantDeviceState (const std::shared_ptr<const ParticipantDevice> &device) const;
|
||||
void setParticipantDeviceState (const std::shared_ptr<ParticipantDevice> &device, ParticipantDevice::State state);
|
||||
|
||||
void acceptSession (const std::shared_ptr<CallSession> &session);
|
||||
void confirmCreation ();
|
||||
void confirmJoining (SalCallOp *op);
|
||||
void confirmRecreation (SalCallOp *op);
|
||||
|
||||
IdentityAddress generateConferenceAddress (const std::shared_ptr<Participant> &me) const;
|
||||
void declineSession (const std::shared_ptr<CallSession> &session, LinphoneReason reason);
|
||||
void dispatchQueuedMessages ();
|
||||
|
||||
void subscribeReceived (LinphoneEvent *event);
|
||||
|
||||
|
|
@ -45,6 +60,7 @@ public:
|
|||
|
||||
void setConferenceAddress (const IdentityAddress &conferenceAddress);
|
||||
void setParticipantDevices (const IdentityAddress &addr, const std::list<IdentityAddress> &devices);
|
||||
void addParticipantDevice (const IdentityAddress &participantAddress, const IdentityAddress &deviceAddress);
|
||||
void addCompatibleParticipants (const IdentityAddress &deviceAddr, const std::list<IdentityAddress> &compatibleParticipants);
|
||||
void checkCompatibleParticipants (const IdentityAddress &deviceAddr, const std::list<IdentityAddress> &addressesToCheck);
|
||||
|
||||
|
|
@ -52,21 +68,39 @@ public:
|
|||
|
||||
private:
|
||||
struct Message {
|
||||
Message (const std::string &from, const std::string &contentType, const std::string &text) : fromAddr(from) {
|
||||
Message (const std::string &from, const ContentType &contentType, const std::string &text, const SalCustomHeader *salCustomHeaders)
|
||||
: fromAddr(from)
|
||||
{
|
||||
content.setContentType(contentType);
|
||||
if (!text.empty())
|
||||
content.setBodyFromUtf8(text);
|
||||
if (salCustomHeaders)
|
||||
customHeaders = sal_custom_header_clone(salCustomHeaders);
|
||||
}
|
||||
|
||||
~Message () {
|
||||
if (customHeaders)
|
||||
sal_custom_header_free(customHeaders);
|
||||
}
|
||||
|
||||
IdentityAddress fromAddr;
|
||||
Content content;
|
||||
std::chrono::system_clock::time_point timestamp = std::chrono::system_clock::now();
|
||||
SalCustomHeader *customHeaders = nullptr;
|
||||
};
|
||||
|
||||
static void copyMessageHeaders (const std::shared_ptr<Message> &fromMessage, const std::shared_ptr<ChatMessage> &toMessage);
|
||||
|
||||
void designateAdmin ();
|
||||
void dispatchMessage (const Message &message);
|
||||
void dispatchQueuedMessages ();
|
||||
void dispatchMessage (const std::shared_ptr<Message> &message, const std::string &uri);
|
||||
void finalizeCreation ();
|
||||
void inviteDevice (const std::shared_ptr<ParticipantDevice> &device);
|
||||
bool isAdminLeft () const;
|
||||
void queueMessage (const std::shared_ptr<Message> &message);
|
||||
void queueMessage (const std::shared_ptr<Message> &msg, const IdentityAddress &deviceAddress);
|
||||
void removeNonPresentParticipants (const std::list <IdentityAddress> &compatibleParticipants);
|
||||
|
||||
void onParticipantDeviceLeft (const std::shared_ptr<const CallSession> &session);
|
||||
|
||||
// ChatRoomListener
|
||||
void onChatRoomInsertRequested (const std::shared_ptr<AbstractChatRoom> &chatRoom) override;
|
||||
|
|
@ -75,16 +109,17 @@ private:
|
|||
|
||||
// CallSessionListener
|
||||
void onCallSessionStateChanged (
|
||||
const std::shared_ptr<const CallSession> &session,
|
||||
const std::shared_ptr<CallSession> &session,
|
||||
CallSession::State newState,
|
||||
const std::string &message
|
||||
) override;
|
||||
void onCallSessionSetReleased (const std::shared_ptr<CallSession> &session) override;
|
||||
|
||||
std::list<std::shared_ptr<Participant>> removedParticipants;
|
||||
std::list<std::shared_ptr<Participant>> filteredParticipants;
|
||||
ChatRoomListener *chatRoomListener = this;
|
||||
ServerGroupChatRoom::CapabilitiesMask capabilities = ServerGroupChatRoom::Capabilities::Conference;
|
||||
bool joiningPendingAfterCreation = false;
|
||||
std::list<Message> queuedMessages;
|
||||
std::unordered_map<std::string, std::queue<std::shared_ptr<Message>>> queuedMessages;
|
||||
|
||||
L_DECLARE_PUBLIC(ServerGroupChatRoom);
|
||||
};
|
||||
|
|
|
|||
|
|
@ -28,31 +28,47 @@ LINPHONE_BEGIN_NAMESPACE
|
|||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ServerGroupChatRoomPrivate::setState (ChatRoom::State state) {
|
||||
ChatRoomPrivate::setState(state);
|
||||
}
|
||||
|
||||
shared_ptr<Participant> ServerGroupChatRoomPrivate::addParticipant (const IdentityAddress &) {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void ServerGroupChatRoomPrivate::removeParticipant (const shared_ptr<const Participant> &) {}
|
||||
|
||||
shared_ptr<Participant> ServerGroupChatRoomPrivate::findRemovedParticipant (
|
||||
const shared_ptr<const CallSession> &
|
||||
) const {
|
||||
shared_ptr<Participant> ServerGroupChatRoomPrivate::findFilteredParticipant (const shared_ptr<const CallSession> &session) const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
shared_ptr<Participant> ServerGroupChatRoomPrivate::findFilteredParticipant (const IdentityAddress &participantAddress) const {
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
ParticipantDevice::State ServerGroupChatRoomPrivate::getParticipantDeviceState (const shared_ptr<const ParticipantDevice> &device) const {
|
||||
return device->getState();
|
||||
}
|
||||
|
||||
void ServerGroupChatRoomPrivate::setParticipantDeviceState (const shared_ptr<ParticipantDevice> &device, ParticipantDevice::State state) {
|
||||
device->setState(state);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ServerGroupChatRoomPrivate::acceptSession (const shared_ptr<CallSession> &session) {}
|
||||
|
||||
void ServerGroupChatRoomPrivate::confirmCreation () {}
|
||||
|
||||
void ServerGroupChatRoomPrivate::confirmJoining (SalCallOp *) {}
|
||||
|
||||
void ServerGroupChatRoomPrivate::confirmRecreation (SalCallOp *) {}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
void ServerGroupChatRoomPrivate::declineSession (const shared_ptr<CallSession> &session, LinphoneReason reason) {}
|
||||
|
||||
IdentityAddress ServerGroupChatRoomPrivate::generateConferenceAddress (const shared_ptr<Participant> &me) const {
|
||||
return IdentityAddress();
|
||||
}
|
||||
void ServerGroupChatRoomPrivate::dispatchQueuedMessages () {}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ServerGroupChatRoomPrivate::subscribeReceived (LinphoneEvent *) {}
|
||||
|
||||
|
|
@ -64,6 +80,8 @@ void ServerGroupChatRoomPrivate::setConferenceAddress (const IdentityAddress &)
|
|||
|
||||
void ServerGroupChatRoomPrivate::setParticipantDevices (const IdentityAddress &addr, const list<IdentityAddress> &devices) {}
|
||||
|
||||
void ServerGroupChatRoomPrivate::addParticipantDevice (const IdentityAddress &participantAddress, const IdentityAddress &deviceAddress) {}
|
||||
|
||||
void ServerGroupChatRoomPrivate::addCompatibleParticipants (const IdentityAddress &deviceAddr, const list<IdentityAddress> &participantCompatible) {}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
|
@ -76,16 +94,26 @@ LinphoneReason ServerGroupChatRoomPrivate::onSipMessageReceived (SalOp *, const
|
|||
|
||||
void ServerGroupChatRoomPrivate::designateAdmin () {}
|
||||
|
||||
void ServerGroupChatRoomPrivate::dispatchMessage (const Message &message) {}
|
||||
|
||||
void ServerGroupChatRoomPrivate::dispatchQueuedMessages () {}
|
||||
void ServerGroupChatRoomPrivate::dispatchMessage (const shared_ptr<Message> &message, const string &uri) {}
|
||||
|
||||
void ServerGroupChatRoomPrivate::finalizeCreation () {}
|
||||
|
||||
void ServerGroupChatRoomPrivate::inviteDevice (const shared_ptr<ParticipantDevice> &device) {}
|
||||
|
||||
bool ServerGroupChatRoomPrivate::isAdminLeft () const {
|
||||
return false;
|
||||
}
|
||||
|
||||
void ServerGroupChatRoomPrivate::queueMessage (const shared_ptr<Message> &message) {}
|
||||
|
||||
void ServerGroupChatRoomPrivate::queueMessage (const shared_ptr<Message> &msg, const IdentityAddress &deviceAddress) {}
|
||||
|
||||
void ServerGroupChatRoomPrivate::removeNonPresentParticipants (const list <IdentityAddress> &compatibleParticipants) {}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ServerGroupChatRoomPrivate::onParticipantDeviceLeft (const shared_ptr<const CallSession> &session) {}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ServerGroupChatRoomPrivate::onChatRoomInsertRequested (const shared_ptr<AbstractChatRoom> &chatRoom) {}
|
||||
|
|
@ -97,11 +125,13 @@ void ServerGroupChatRoomPrivate::onChatRoomDeleteRequested (const shared_ptr<Abs
|
|||
// -----------------------------------------------------------------------------
|
||||
|
||||
void ServerGroupChatRoomPrivate::onCallSessionStateChanged (
|
||||
const shared_ptr<const CallSession> &,
|
||||
const shared_ptr<CallSession> &,
|
||||
CallSession::State,
|
||||
const string &
|
||||
) {}
|
||||
|
||||
void ServerGroupChatRoomPrivate::onCallSessionSetReleased (const shared_ptr<CallSession> &session) {}
|
||||
|
||||
// =============================================================================
|
||||
|
||||
ServerGroupChatRoom::ServerGroupChatRoom (const shared_ptr<Core> &core, SalCallOp *op)
|
||||
|
|
@ -189,4 +219,12 @@ void ServerGroupChatRoom::join () {}
|
|||
|
||||
void ServerGroupChatRoom::leave () {}
|
||||
|
||||
void ServerGroupChatRoom::onFirstNotifyReceived (const IdentityAddress &addr) {}
|
||||
|
||||
// -----------------------------------------------------------------------------
|
||||
|
||||
ostream &operator<< (ostream &stream, const ServerGroupChatRoom *chatRoom) {
|
||||
return stream << "ServerGroupChatRoom [" << reinterpret_cast<const void *>(chatRoom) << "]";
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
|
|
|||
|
|
@ -85,11 +85,16 @@ public:
|
|||
void join () override;
|
||||
void leave () override;
|
||||
|
||||
/* ConferenceListener */
|
||||
void onFirstNotifyReceived (const IdentityAddress &addr) override;
|
||||
|
||||
private:
|
||||
L_DECLARE_PRIVATE(ServerGroupChatRoom);
|
||||
L_DISABLE_COPY(ServerGroupChatRoom);
|
||||
};
|
||||
|
||||
std::ostream &operator<< (std::ostream &stream, const ServerGroupChatRoom *chatRoom);
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
||||
#endif // ifndef _L_SERVER_GROUP_CHAT_ROOM_H_
|
||||
|
|
|
|||
|
|
@ -38,7 +38,7 @@ class Cpim::MessagePrivate : public ObjectPrivate {
|
|||
public:
|
||||
typedef list<shared_ptr<const Header> > PrivHeaderList;
|
||||
|
||||
shared_ptr<PrivHeaderList> cpimHeaders = make_shared<PrivHeaderList>();
|
||||
shared_ptr<PrivHeaderList> cpimHeaders = make_shared<PrivHeaderList>(); // TODO: Remove this useless variable
|
||||
shared_ptr<PrivHeaderList> messageHeaders = make_shared<PrivHeaderList>();
|
||||
shared_ptr<PrivHeaderList> contentHeaders = make_shared<PrivHeaderList>();
|
||||
string content;
|
||||
|
|
@ -148,10 +148,11 @@ string Cpim::Message::asString () const {
|
|||
L_D();
|
||||
|
||||
string output;
|
||||
// TODO: Remove cpimHeaders
|
||||
for (const auto &cpimHeader : *d->cpimHeaders)
|
||||
output += cpimHeader->asString();
|
||||
|
||||
output += "\r\n";
|
||||
// TODO Remove cpimHeaders
|
||||
|
||||
if (d->messageHeaders->size() > 0) {
|
||||
for (const auto &messageHeader : *d->messageHeaders)
|
||||
|
|
|
|||
|
|
@ -36,9 +36,11 @@ namespace Cpim {
|
|||
|
||||
typedef std::shared_ptr<std::list<std::shared_ptr<const Cpim::Header> > > HeaderList;
|
||||
|
||||
// TODO: Remove these useless methods
|
||||
HeaderList getCpimHeaders () const;
|
||||
bool addCpimHeader (const Header &cpimHeader);
|
||||
void removeCpimHeader (const Header &cpimHeader);
|
||||
// TODO: Remove these useless methods
|
||||
|
||||
HeaderList getMessageHeaders () const;
|
||||
bool addMessageHeader (const Header &messageHeader);
|
||||
|
|
@ -51,7 +53,7 @@ namespace Cpim {
|
|||
std::string getContent () const;
|
||||
bool setContent (const std::string &content);
|
||||
|
||||
bool isValid () const;
|
||||
bool isValid () const; // TODO: Remove this useless method
|
||||
|
||||
std::string asString () const;
|
||||
|
||||
|
|
|
|||
|
|
@ -171,37 +171,47 @@ namespace Cpim {
|
|||
// Warning: Call this function one time!
|
||||
shared_ptr<Message> createMessage () const {
|
||||
size_t size = mHeaders->size();
|
||||
if (size < 2 || size > 3) {
|
||||
if (size < 2 || size > 3) { // TODO: Check that size is == 2
|
||||
lWarning() << "Bad headers lists size.";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
const shared_ptr<Message> message = make_shared<Message>();
|
||||
const shared_ptr<ListHeaderNode> cpimHeaders = mHeaders->front();
|
||||
|
||||
if (find_if(cpimHeaders->cbegin(), cpimHeaders->cend(),
|
||||
[](const shared_ptr<const HeaderNode> &headerNode) {
|
||||
return Utils::iequals(headerNode->getName(), "content-type") && (ContentType(headerNode->getValue()) == ContentType::Cpim);
|
||||
}) == cpimHeaders->cend()) {
|
||||
lWarning() << "No MIME `Content-Type` found!";
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Add MIME headers.
|
||||
for (const auto &headerNode : *cpimHeaders) {
|
||||
const shared_ptr<const Header> header = headerNode->createHeader();
|
||||
if (!header || !message->addCpimHeader(*header))
|
||||
// TODO: To remove
|
||||
if (size == 3) {
|
||||
const shared_ptr<ListHeaderNode> cpimHeaders = mHeaders->front();
|
||||
if (find_if(cpimHeaders->cbegin(), cpimHeaders->cend(),
|
||||
[](const shared_ptr<const HeaderNode> &headerNode) {
|
||||
return Utils::iequals(headerNode->getName(), "content-type") && (ContentType(headerNode->getValue()) == ContentType::Cpim);
|
||||
}) == cpimHeaders->cend()) {
|
||||
lWarning() << "No MIME `Content-Type` found!";
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Add message headers.
|
||||
if (mHeaders->size() > 2) {
|
||||
// Add MIME headers.
|
||||
for (const auto &headerNode : *cpimHeaders) {
|
||||
const shared_ptr<const Header> header = headerNode->createHeader();
|
||||
if (!header || !message->addCpimHeader(*header))
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Add message headers.
|
||||
for (const auto &headerNode : **(++mHeaders->cbegin())) {
|
||||
const shared_ptr<const Header> header = headerNode->createHeader();
|
||||
if (!header || !message->addMessageHeader(*header))
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
// TODO: To remove
|
||||
else {
|
||||
// Add message headers.
|
||||
for (const auto &headerNode : *mHeaders->front()) {
|
||||
const shared_ptr<const Header> header = headerNode->createHeader();
|
||||
if (!header || !message->addMessageHeader(*header))
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
// Add content headers.
|
||||
for (const auto &headerNode : *mHeaders->back()) {
|
||||
|
|
|
|||
|
|
@ -34,10 +34,13 @@ LINPHONE_BEGIN_NAMESPACE
|
|||
|
||||
ChatMessageModifier::Result CpimChatMessageModifier::encode (const shared_ptr<ChatMessage> &message, int &errorCode) {
|
||||
Cpim::Message cpimMessage;
|
||||
|
||||
// TODO: Remove this buggy Content-Type header
|
||||
Cpim::GenericHeader cpimContentTypeHeader;
|
||||
cpimContentTypeHeader.setName("Content-Type");
|
||||
cpimContentTypeHeader.setValue(ContentType::Cpim.asString());
|
||||
cpimMessage.addCpimHeader(cpimContentTypeHeader);
|
||||
// TODO: Remove this buggy Content-Type header
|
||||
|
||||
Cpim::FromHeader cpimFromHeader;
|
||||
cpimFromHeader.setValue(cpimAddressAsString(message->getFromAddress()));
|
||||
|
|
@ -71,11 +74,13 @@ ChatMessageModifier::Result CpimChatMessageModifier::encode (const shared_ptr<Ch
|
|||
const string contentBody = content->getBodyAsString();
|
||||
cpimMessage.setContent(contentBody);
|
||||
|
||||
// TODO: Remove this check because of buggy Content-Type header
|
||||
if (!cpimMessage.isValid()) {
|
||||
lError() << "[CPIM] Message is invalid: " << contentBody;
|
||||
errorCode = 500;
|
||||
return ChatMessageModifier::Result::Error;
|
||||
}
|
||||
// TODO: Remove this check because of buggy Content-Type header
|
||||
|
||||
Content newContent;
|
||||
newContent.setContentType(ContentType::Cpim);
|
||||
|
|
@ -99,7 +104,7 @@ ChatMessageModifier::Result CpimChatMessageModifier::decode (const shared_ptr<Ch
|
|||
|
||||
const string contentBody = content->getBodyAsString();
|
||||
const shared_ptr<const Cpim::Message> cpimMessage = Cpim::Message::createFromString(contentBody);
|
||||
if (!cpimMessage || !cpimMessage->isValid()) {
|
||||
if (!cpimMessage) {
|
||||
lError() << "[CPIM] Message is invalid: " << contentBody;
|
||||
errorCode = 500;
|
||||
return ChatMessageModifier::Result::Error;
|
||||
|
|
|
|||
|
|
@ -35,6 +35,10 @@ using namespace std;
|
|||
|
||||
LINPHONE_BEGIN_NAMESPACE
|
||||
|
||||
FileTransferChatMessageModifier::FileTransferChatMessageModifier (belle_http_provider_t *prov) : provider(prov) {
|
||||
bgTask.setName("File transfer upload");
|
||||
}
|
||||
|
||||
belle_http_request_t *FileTransferChatMessageModifier::getHttpRequest () const {
|
||||
return httpRequest;
|
||||
}
|
||||
|
|
@ -44,7 +48,10 @@ void FileTransferChatMessageModifier::setHttpRequest (belle_http_request_t *requ
|
|||
}
|
||||
|
||||
FileTransferChatMessageModifier::~FileTransferChatMessageModifier () {
|
||||
releaseHttpRequest();
|
||||
if (isFileTransferInProgressAndValid())
|
||||
cancelFileTransfer(); //to avoid body handler to still refference zombie FileTransferChatMessageModifier
|
||||
else
|
||||
releaseHttpRequest();
|
||||
}
|
||||
|
||||
ChatMessageModifier::Result FileTransferChatMessageModifier::encode (const shared_ptr<ChatMessage> &message, int &errorCode) {
|
||||
|
|
@ -357,27 +364,27 @@ void FileTransferChatMessageModifier::processResponseFromPostFile (const belle_h
|
|||
fileTransferContent->setContentType(ContentType::FileTransfer);
|
||||
fileTransferContent->setFileContent(fileContent);
|
||||
|
||||
message->removeContent(*fileContent);
|
||||
message->addContent(*fileTransferContent);
|
||||
message->getPrivate()->removeContent(*fileContent);
|
||||
message->getPrivate()->addContent(*fileTransferContent);
|
||||
|
||||
message->updateState(ChatMessage::State::FileTransferDone);
|
||||
message->getPrivate()->setState(ChatMessage::State::FileTransferDone);
|
||||
releaseHttpRequest();
|
||||
message->getPrivate()->send();
|
||||
fileUploadEndBackgroundTask();
|
||||
} else {
|
||||
lWarning() << "Received empty response from server, file transfer failed";
|
||||
message->updateState(ChatMessage::State::NotDelivered);
|
||||
message->getPrivate()->setState(ChatMessage::State::NotDelivered);
|
||||
releaseHttpRequest();
|
||||
fileUploadEndBackgroundTask();
|
||||
}
|
||||
} else if (code == 400) {
|
||||
lWarning() << "Received HTTP code response " << code << " for file transfer, probably meaning file is too large";
|
||||
message->updateState(ChatMessage::State::FileTransferError);
|
||||
message->getPrivate()->setState(ChatMessage::State::FileTransferError);
|
||||
releaseHttpRequest();
|
||||
fileUploadEndBackgroundTask();
|
||||
} else {
|
||||
lWarning() << "Unhandled HTTP code response " << code << " for file transfer";
|
||||
message->updateState(ChatMessage::State::NotDelivered);
|
||||
message->getPrivate()->setState(ChatMessage::State::NotDelivered);
|
||||
releaseHttpRequest();
|
||||
fileUploadEndBackgroundTask();
|
||||
}
|
||||
|
|
@ -394,7 +401,7 @@ void FileTransferChatMessageModifier::processIoErrorUpload (const belle_sip_io_e
|
|||
shared_ptr<ChatMessage> message = chatMessage.lock();
|
||||
if (!message)
|
||||
return;
|
||||
message->updateState(ChatMessage::State::NotDelivered);
|
||||
message->getPrivate()->setState(ChatMessage::State::NotDelivered);
|
||||
releaseHttpRequest();
|
||||
}
|
||||
|
||||
|
|
@ -408,7 +415,7 @@ void FileTransferChatMessageModifier::processAuthRequestedUpload (const belle_si
|
|||
shared_ptr<ChatMessage> message = chatMessage.lock();
|
||||
if (!message)
|
||||
return;
|
||||
message->updateState(ChatMessage::State::NotDelivered);
|
||||
message->getPrivate()->setState(ChatMessage::State::NotDelivered);
|
||||
releaseHttpRequest();
|
||||
}
|
||||
|
||||
|
|
@ -470,7 +477,7 @@ int FileTransferChatMessageModifier::startHttpTransfer (const string &url, const
|
|||
|
||||
// give msg to listener to be able to start the actual file upload when server answer a 204 No content
|
||||
httpListener = belle_http_request_listener_create_from_callbacks(cbs, this);
|
||||
belle_http_provider_send_request(message->getCore()->getCCore()->http_provider, httpRequest, httpListener);
|
||||
belle_http_provider_send_request(provider, httpRequest, httpListener);
|
||||
return 0;
|
||||
|
||||
error:
|
||||
|
|
@ -480,29 +487,15 @@ error:
|
|||
return -1;
|
||||
}
|
||||
|
||||
static void _chat_message_file_upload_background_task_ended (void *data) {
|
||||
FileTransferChatMessageModifier *d = (FileTransferChatMessageModifier *)data;
|
||||
d->fileUploadBackgroundTaskEnded();
|
||||
}
|
||||
|
||||
void FileTransferChatMessageModifier::fileUploadBackgroundTaskEnded () {
|
||||
lWarning() << "channel [" << this << "]: file upload background task has to be ended now, but work isn't finished.";
|
||||
fileUploadEndBackgroundTask();
|
||||
}
|
||||
|
||||
void FileTransferChatMessageModifier::fileUploadBeginBackgroundTask () {
|
||||
if (backgroundTaskId == 0) {
|
||||
backgroundTaskId = sal_begin_background_task("file transfer upload", _chat_message_file_upload_background_task_ended, this);
|
||||
if (backgroundTaskId) lInfo() << "channel [" << this << "]: starting file upload background task with id=[" << backgroundTaskId << "].";
|
||||
}
|
||||
shared_ptr<ChatMessage> message = chatMessage.lock();
|
||||
if (!message)
|
||||
return;
|
||||
bgTask.start(message->getCore());
|
||||
}
|
||||
|
||||
void FileTransferChatMessageModifier::fileUploadEndBackgroundTask () {
|
||||
if (backgroundTaskId) {
|
||||
lInfo() << "channel [" << this << "]: ending file upload background task with id=[" << backgroundTaskId << "].";
|
||||
sal_end_background_task(backgroundTaskId);
|
||||
backgroundTaskId = 0;
|
||||
}
|
||||
bgTask.stop();
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------
|
||||
|
|
@ -763,12 +756,12 @@ void FileTransferChatMessageModifier::onRecvEnd (belle_sip_user_body_handler_t *
|
|||
if (retval <= 0 && message->getState() != ChatMessage::State::FileTransferError) {
|
||||
// Remove the FileTransferContent from the message and store the FileContent
|
||||
FileContent *fileContent = currentFileContentToTransfer;
|
||||
message->addContent(*fileContent);
|
||||
message->getPrivate()->addContent(*fileContent);
|
||||
for (Content *content : message->getContents()) {
|
||||
if (content->getContentType() == ContentType::FileTransfer) {
|
||||
FileTransferContent *fileTransferContent = (FileTransferContent*)content;
|
||||
if (fileTransferContent->getFileContent() == fileContent) {
|
||||
message->removeContent(*content);
|
||||
message->getPrivate()->removeContent(*content);
|
||||
delete fileTransferContent;
|
||||
break;
|
||||
}
|
||||
|
|
@ -857,7 +850,7 @@ void FileTransferChatMessageModifier::processAuthRequestedDownload (const belle_
|
|||
shared_ptr<ChatMessage> message = chatMessage.lock();
|
||||
if (!message)
|
||||
return;
|
||||
message->updateState(ChatMessage::State::FileTransferError);
|
||||
message->getPrivate()->setState(ChatMessage::State::FileTransferError);
|
||||
releaseHttpRequest();
|
||||
}
|
||||
|
||||
|
|
@ -871,7 +864,7 @@ void FileTransferChatMessageModifier::processIoErrorDownload (const belle_sip_io
|
|||
shared_ptr<ChatMessage> message = chatMessage.lock();
|
||||
if (!message)
|
||||
return;
|
||||
message->updateState(ChatMessage::State::FileTransferError);
|
||||
message->getPrivate()->setState(ChatMessage::State::FileTransferError);
|
||||
releaseHttpRequest();
|
||||
}
|
||||
|
||||
|
|
@ -951,10 +944,11 @@ void FileTransferChatMessageModifier::cancelFileTransfer () {
|
|||
? L_C_TO_STRING(linphone_core_get_file_transfer_server(message->getCore()->getCCore()))
|
||||
: currentFileContentToTransfer->getFilePath().c_str()
|
||||
);
|
||||
belle_http_provider_cancel_request(message->getCore()->getCCore()->http_provider, httpRequest);
|
||||
|
||||
} else {
|
||||
lInfo() << "Warning: http request still running for ORPHAN msg: this is a memory leak";
|
||||
}
|
||||
belle_http_provider_cancel_request(provider, httpRequest);
|
||||
}
|
||||
releaseHttpRequest();
|
||||
}
|
||||
|
|
@ -974,4 +968,18 @@ void FileTransferChatMessageModifier::releaseHttpRequest () {
|
|||
}
|
||||
}
|
||||
|
||||
string FileTransferChatMessageModifier::createFakeFileTransferFromUrl(const string &url) {
|
||||
string fileName = url.substr(url.find_last_of("/") + 1);
|
||||
stringstream fakeXml;
|
||||
fakeXml << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\r\n";
|
||||
fakeXml << "<file xmlns=\"urn:gsma:params:xml:ns:rcs:rcs:fthttp\">\r\n";
|
||||
fakeXml << "<file-info type=\"file\">\r\n";
|
||||
fakeXml << "<file-name>" << fileName << "</file-name>\r\n";
|
||||
fakeXml << "<content-type>application/binary</content-type>\r\n";
|
||||
fakeXml << "<data url = \"" << url << "\"/>\r\n";
|
||||
fakeXml << "</file-info>\r\n";
|
||||
fakeXml << "</file>";
|
||||
return fakeXml.str();
|
||||
}
|
||||
|
||||
LINPHONE_END_NAMESPACE
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue