Merge remote-tracking branch 'origin/master' into dev_conference_info

This commit is contained in:
Benjamin Reis 2017-08-28 10:08:53 +02:00
commit 913486aee2
80 changed files with 2802 additions and 171 deletions

View file

@ -38,34 +38,43 @@ include(CMakeDependentOption)
option(ENABLE_SHARED "Build shared library." YES)
option(ENABLE_STATIC "Build static library." YES)
option(ENABLE_CONSOLE_UI "Turn on or off compilation of console interface." YES)
option(ENABLE_DATE "Use build date in internal version number." NO)
option(ENABLE_CSHARP_WRAPPER "Build the C# wrapper for Liblinphone." OFF)
option(ENABLE_CXX_WRAPPER "Build the C++ wrapper for Liblinphone." YES)
option(ENABLE_DAEMON "Enable the linphone daemon interface." YES)
option(ENABLE_DATE "Use build date in internal version number." NO)
option(ENABLE_DEBUG_LOGS "Turn on or off debug level logs." NO)
option(ENABLE_DOC "Enable documentation generation with Doxygen." YES)
option(ENABLE_JAVADOC "Add a target to generate documentation for Java API" NO)
option(ENABLE_GTK_UI "Turn on or off compilation of gtk interface." NO)
option(ENABLE_JAVADOC "Add a target to generate documentation for Java API" NO)
option(ENABLE_LDAP "Enable LDAP support." NO)
option(ENABLE_SQLITE_STORAGE "Turn on compilation sqlite storage, for messages, contacts, history" YES)
cmake_dependent_option(ENABLE_LIME "Enable Instant Messaging Encryption." YES "ENABLE_SQLITE_STORAGE" NO)
cmake_dependent_option(ENABLE_NOTIFY "Enable libnotify support." YES "ENABLE_GTK_UI;NOT APPLE" NO)
option(ENABLE_NLS "Build with internationalisation support" YES)
option(ENABLE_RELATIVE_PREFIX "Find resources relatively to the installation directory." NO)
option(ENABLE_ROOTCA_DOWNLOAD "Download rootca.pem at build time." YES)
option(ENABLE_SOCI_STORAGE "Turn on compilation soci storage, for messages, contacts, history" YES)
option(ENABLE_SQLITE_STORAGE "Turn on compilation sqlite storage, for messages, contacts, history" YES)
option(ENABLE_STRICT "Build with strict compile options." YES)
option(ENABLE_TOOLS "Turn on or off compilation of tools." YES)
option(ENABLE_TUNNEL "Turn on compilation of tunnel support." NO)
option(ENABLE_TUTORIALS "Enable compilation of tutorials." YES)
option(ENABLE_UNIT_TESTS "Enable compilation of unit tests." YES)
option(ENABLE_UPDATE_CHECK "Enable update check." NO)
option(ENABLE_VIDEO "Build with video support." YES)
cmake_dependent_option(ENABLE_ASSISTANT "Turn on assistant compiling." YES "ENABLE_GTK_UI" NO)
option(ENABLE_DEBUG_LOGS "Turn on or off debug level logs." NO)
option(ENABLE_NLS "Build with internationalisation support" YES)
option(ENABLE_VCARD "Turn on compilation of vcard4 support." YES)
option(ENABLE_ROOTCA_DOWNLOAD "Download rootca.pem at build time." YES)
option(ENABLE_CXX_WRAPPER "Build the C++ wrapper for Liblinphone." YES)
option(ENABLE_CSHARP_WRAPPER "Build the C# wrapper for Liblinphone." OFF)
option(ENABLE_VIDEO "Build with video support." YES)
cmake_dependent_option(ENABLE_LIME "Enable Instant Messaging Encryption." YES "ENABLE_SQLITE_STORAGE" NO)
cmake_dependent_option(ENABLE_NOTIFY "Enable libnotify support." YES "ENABLE_GTK_UI;NOT APPLE" NO)
cmake_dependent_option(ENABLE_ASSISTANT "Turn on assistant compiling." YES "ENABLE_GTK_UI" NO)
set(CMAKE_CXX_STANDARD 11)
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
set(CMAKE_CXX_FLAGS_RELEASE "-O2 -DNDEBUG")
set(CMAKE_CXX_FLAGS_DEBUG "-g -DDEBUG")
if(ENABLE_STATIC)
set(LINPHONE_LIBS_FOR_TOOLS linphone-static)
@ -125,7 +134,7 @@ else()
endif()
find_package(XML2 REQUIRED)
find_package(LibXsd REQUIRED)
find_package(Soci REQUIRED)
find_package(Soci)
find_package(Zlib)
if(ENABLE_TUNNEL)
if(LINPHONE_BUILDER_GROUP_EXTERNAL_SOURCE_PATH_BUILDERS)
@ -258,7 +267,7 @@ if(LINPHONE_CPPFLAGS)
endif()
if(ENABLE_DEBUG_LOGS)
add_definitions("-DDEBUG")
add_definitions("-DDEBUG_LOGS")
endif()
set(STRICT_OPTIONS_CPP )

87
cmake/FindSoci.cmake Normal file
View file

@ -0,0 +1,87 @@
###############################################################################
# CMake module to search for SOCI library
#
# WARNING: This module is experimental work in progress.
#
# This module defines:
# SOCI_INCLUDE_DIRS = include dirs to be used when using the soci library
# SOCI_LIBRARIES = full path to the soci library
# SOCI_VERSION = the soci version found (not yet. soci does not provide that info.)
# SOCI_FOUND = true if soci was found
#
# For each component you specify in find_package(), the following variables are set.
#
# SOCI_${COMPONENT}_PLUGIN = full path to the soci plugin
# SOCI_${COMPONENT}_FOUND
#
# Copyright (c) 2011 Michael Jansen <info@michael-jansen.biz>
#
# Redistribution and use is allowed according to the terms of the BSD license.
# For details see the accompanying COPYING-CMAKE-SCRIPTS file.
#
###############################################################################
#
### Global Configuration Section
#
SET(_SOCI_ALL_PLUGINS mysql sqlite3)
SET(_SOCI_REQUIRED_VARS SOCI_INCLUDE_DIRS SOCI_LIBRARIES)
#
### FIRST STEP: Find the soci headers.
#
FIND_PATH(SOCI_INCLUDE_DIRS soci/soci.h
DOC "Soci (http://soci.sourceforge.net) include directory")
MARK_AS_ADVANCED(SOCI_INCLUDE_DIRS)
#
### SECOND STEP: Find the soci core library. Respect LIB_SUFFIX
#
FIND_LIBRARY(SOCI_LIBRARIES
NAMES soci_core
PATH_SUFFIXES lib lib64)
MARK_AS_ADVANCED(SOCI_LIBRARIES)
GET_FILENAME_COMPONENT(SOCI_LIBRARY_DIR ${SOCI_LIBRARIES} PATH)
MARK_AS_ADVANCED(SOCI_LIBRARY_DIR)
#
### THIRD STEP: Find all installed plugins if the library was found
#
IF(SOCI_INCLUDE_DIRS AND SOCI_LIBRARIES)
MESSAGE(STATUS "Soci found: Looking for plugins")
FOREACH(plugin IN LISTS _SOCI_ALL_PLUGINS)
FIND_LIBRARY(
SOCI_${plugin}_PLUGIN
NAMES soci_${plugin}
PATH_SUFFIXES lib lib64)
MARK_AS_ADVANCED(SOCI_${plugin}_PLUGIN)
IF(SOCI_${plugin}_PLUGIN)
MESSAGE(STATUS " * Plugin ${plugin} found ${SOCI_${plugin}_PLUGIN}.")
SET(SOCI_${plugin}_FOUND True)
ELSE()
MESSAGE(STATUS " * Plugin ${plugin} not found.")
SET(SOCI_${plugin}_FOUND False)
ENDIF()
ENDFOREACH()
#
### FOURTH CHECK: Check if the required components were all found
#
FOREACH(component ${Soci_FIND_COMPONENTS})
IF(NOT SOCI_${component}_FOUND)
MESSAGE(SEND_ERROR "Required component ${component} not found. It seems that Soci was built without support of ${component}, consider rebuilding it.")
ENDIF()
ENDFOREACH()
ENDIF()
#
### ADHERE TO STANDARDS
#
include(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(Soci DEFAULT_MSG ${_SOCI_REQUIRED_VARS})

View file

@ -159,7 +159,6 @@ set(LIBS
${XML2_LIBRARIES}
${BELR_LIBRARIES}
${LIBXSD_LIBRARIES}
${SOCI_LIBRARY}
)
if(WIN32 AND NOT CMAKE_SYSTEM_NAME STREQUAL "WindowsStore")
list(APPEND LIBS "Ws2_32")
@ -170,6 +169,9 @@ endif()
if(ZLIB_FOUND)
list(APPEND LIBS ${ZLIB_LIBRARIES})
endif()
if(SOCI_FOUND)
list(APPEND LIBS ${SOCI_LIBRARIES})
endif()
if(SQLITE3_FOUND)
list(APPEND LIBS ${SQLITE3_LIBRARIES})
endif()

View file

@ -59,31 +59,6 @@ void sal_op_set_privacy_from_message(SalOp* op,belle_sip_message_t* msg) {
}
static void set_tls_properties(Sal *ctx);
void _belle_sip_log(const char *domain, belle_sip_log_level lev, const char *fmt, va_list args) {
OrtpLogLevel ortp_level;
switch(lev) {
case BELLE_SIP_LOG_FATAL:
ortp_level=ORTP_FATAL;
break;
case BELLE_SIP_LOG_ERROR:
ortp_level=ORTP_ERROR;
break;
case BELLE_SIP_LOG_WARNING:
ortp_level=ORTP_WARNING;
break;
case BELLE_SIP_LOG_MESSAGE:
ortp_level=ORTP_MESSAGE;
break;
case BELLE_SIP_LOG_DEBUG:
default:
ortp_level=ORTP_DEBUG;
break;
}
if (ortp_log_level_enabled("belle-sip", ortp_level)){
ortp_logv("belle-sip", ortp_level,fmt,args);
}
}
void sal_enable_log(){
sal_set_log_level(ORTP_MESSAGE);
}
@ -93,24 +68,31 @@ void sal_disable_log() {
}
void sal_set_log_level(OrtpLogLevel level) {
belle_sip_log_level belle_sip_level;
belle_sip_log_level belle_sip_level = BELLE_SIP_LOG_MESSAGE;
if ((level&ORTP_FATAL) != 0) {
belle_sip_level = BELLE_SIP_LOG_FATAL;
} else if ((level&ORTP_ERROR) != 0) {
}
if ((level&ORTP_ERROR) != 0) {
belle_sip_level = BELLE_SIP_LOG_ERROR;
} else if ((level&ORTP_WARNING) != 0) {
}
if ((level&ORTP_WARNING) != 0) {
belle_sip_level = BELLE_SIP_LOG_WARNING;
} else if ((level&ORTP_MESSAGE) != 0) {
belle_sip_level = BELLE_SIP_LOG_MESSAGE;
} else if (((level&ORTP_DEBUG) != 0) || ((level&ORTP_TRACE) != 0)) {
belle_sip_level = BELLE_SIP_LOG_DEBUG;
} else {
//well, this should never occurs but...
}
if ((level&ORTP_MESSAGE) != 0) {
belle_sip_level = BELLE_SIP_LOG_MESSAGE;
}
if (((level&ORTP_DEBUG) != 0) || ((level&ORTP_TRACE) != 0)) {
belle_sip_level = BELLE_SIP_LOG_DEBUG;
}
belle_sip_set_log_level(belle_sip_level);
}
static BctbxLogFunc _belle_sip_log_handler = bctbx_logv_out;
void sal_set_log_handler(BctbxLogFunc log_handler) {
_belle_sip_log_handler = log_handler;
belle_sip_set_log_handler(log_handler);
}
void sal_add_pending_auth(Sal *sal, SalOp *op){
if (bctbx_list_find(sal->pending_auths,op)==NULL){
sal->pending_auths=bctbx_list_append(sal->pending_auths,op);
@ -505,7 +487,7 @@ Sal * sal_init(MSFactory *factory){
sal->auto_contacts=TRUE;
sal->factory = factory;
/*first create the stack, which initializes the belle-sip object's pool for this thread*/
belle_sip_set_log_handler(_belle_sip_log);
belle_sip_set_log_handler(_belle_sip_log_handler); //printf by default
sal->stack = belle_sip_stack_new(NULL);
sal->user_agent=belle_sip_header_user_agent_new();

View file

@ -48,8 +48,17 @@ static void register_refresher_listener (belle_sip_refresher_t* refresher
if (service_route_address) belle_sip_object_unref(service_route_address);
sal_remove_pending_auth(op->base.root,op); /*just in case*/
if (contact) {
sal_op_set_contact_address(op,(SalAddress*)(BELLE_SIP_HEADER_ADDRESS(contact))); /*update contact with real value*/
const char *gruu;
belle_sip_parameters_t* p = (BELLE_SIP_PARAMETERS(contact));
if((gruu = belle_sip_parameters_get_parameter(p, "pub-gruu"))) {
char *unquoted = belle_sip_unquote_strdup(gruu);
sal_op_set_contact_address(op, (SalAddress*)belle_sip_header_address_parse(unquoted));
belle_sip_parameters_remove_parameter(p, "pub-gruu");
} else {
sal_op_set_contact_address(op, (SalAddress*)(BELLE_SIP_HEADER_ADDRESS(contact))); /*update contact with real value*/
}
}
op->base.root->callbacks.register_success(op,belle_sip_refresher_get_expires(op->refresher)>0);
} else if (status_code>=400) {

View file

@ -60,7 +60,7 @@ static LinphoneDialPlan const dial_plans[]={
{"Burkina Faso" ,"BF" , "226" , 8 , "00" },
{"Burundi" ,"BI" , "257" , 8 , "011" },
{"Cambodia" ,"KH" , "855" , 9 , "00" },
{"Cameroon" ,"CM" , "237" , 8 , "00" },
{"Cameroon" ,"CM" , "237" , 9 , "00" },
{"Canada" ,"CA" , "1" , 10 , "011" },
{"Cape Verde" ,"CV" , "238" , 7 , "00" },
{"Cayman Islands" ,"KY" , "1" , 10 , "011" },
@ -168,7 +168,7 @@ static LinphoneDialPlan const dial_plans[]={
{"Montserrat" ,"MS" , "664" , 10 , "011" },
{"Morocco" ,"MA" , "212" , 9 , "00" },
{"Mozambique" ,"MZ" , "258" , 9 , "00" },
{"Myanmar" ,"MM" , "95" , 8 , "00" },
{"Myanmar" ,"MM" , "95" , 10 , "00" },
{"Namibia" ,"NA" , "264" , 9 , "00" },
{"Nauru" ,"NR" , "674" , 7 , "00" },
{"Nepal" ,"NP" , "43" , 10 , "00" },

View file

@ -29,7 +29,7 @@ if (ENABLE_TOOLS)
string(REPLACE ".c" "" EXECUTABLE_NAME ${EXECUTABLE})
bc_apply_compile_flags(${EXECUTABLE} STRICT_OPTIONS_CPP STRICT_OPTIONS_C)
add_executable(${EXECUTABLE_NAME} ${USE_BUNDLE} ${EXECUTABLE})
target_link_libraries(${EXECUTABLE_NAME} ${LINPHONE_LIBS_FOR_TOOLS} ${MEDIASTREAMER2_LIBRARIES} ${ORTP_LIBRARIES})
target_link_libraries(${EXECUTABLE_NAME} ${LINPHONE_LIBS_FOR_TOOLS} ${MEDIASTREAMER2_LIBRARIES} ${ORTP_LIBRARIES} ${BCTOOLBOX_CORE_LIBRARIES})
set_target_properties(${EXECUTABLE_NAME} PROPERTIES LINK_FLAGS "${LINPHONE_LDFLAGS}")
if (NOT IOS)
install(TARGETS ${EXECUTABLE_NAME}

View file

@ -107,8 +107,8 @@ int main(int argc, char *argv[]){
password=argv[3];
}
signal(SIGINT,stop);
//#define DEBUG
#ifdef DEBUG
//#define DEBUG_LOGS
#ifdef DEBUG_LOGS
linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/
#endif
/*

View file

@ -59,8 +59,8 @@ int main(int argc, char *argv[]){
}
signal(SIGINT,stop);
//#define DEBUG
#ifdef DEBUG
//#define DEBUG_LOGS
#ifdef DEBUG_LOGS
linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/
#endif
/*

View file

@ -133,8 +133,8 @@ int main(int argc, char *argv[]){
big_file[sizeof(big_file)-1]=*"E";
signal(SIGINT,stop);
//#define DEBUG
#ifdef DEBUG
//#define DEBUG_LOGS
#ifdef DEBUG_LOGS
linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/
#endif
vtable.message_received=message_received;

View file

@ -79,7 +79,7 @@ int main(int argc, char *argv[]){
signal(SIGINT,stop);
#ifdef DEBUG
#ifdef DEBUG_LOGS
linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/
#endif
/*

View file

@ -34,7 +34,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*
*/
#define DEBUG 1
#define DEBUG_LOGS 1
#include "linphone/core.h"
@ -102,7 +102,7 @@ int main(int argc, char *argv[]){
signal(SIGINT,stop);
#ifdef DEBUG
#ifdef DEBUG_LOGS
linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/
#endif
/*

View file

@ -82,7 +82,7 @@ int main(int argc, char *argv[]){
signal(SIGINT,stop);
#ifdef DEBUG
#ifdef DEBUG_LOGS
linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/
#endif
/*

View file

@ -59,7 +59,7 @@ int main(int argc, char *argv[]){
signal(SIGINT,stop);
#ifdef DEBUG
#ifdef DEBUG_LOGS
linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/
#endif

View file

@ -76,7 +76,7 @@ int main(int argc, char *argv[]){
signal(SIGINT,stop);
#ifdef DEBUG
#ifdef DEBUG_LOGS
linphone_core_enable_logs(NULL); /*enable liblinphone logs.*/
#endif
/*

View file

@ -4983,13 +4983,7 @@ static LinphoneAddress *get_fixed_contact(LinphoneCore *lc, LinphoneCall *call ,
void linphone_call_set_contact_op(LinphoneCall* call) {
LinphoneAddress *contact;
contact=get_fixed_contact(call->core,call,call->dest_proxy);
if (contact){
SalTransport tport=sal_address_get_transport((SalAddress*)contact);
sal_address_clean((SalAddress*)contact); /* clean out contact_params that come from proxy config*/
sal_address_set_transport((SalAddress*)contact,tport);
sal_op_set_contact_address(call->op, contact);
linphone_address_unref(contact);
}
sal_op_set_and_clean_contact_address(call->op, (SalAddress *)contact);
}
LinphonePlayer *linphone_call_get_player(LinphoneCall *call){

View file

@ -469,7 +469,9 @@ void linphone_core_set_log_handler(OrtpLogFunc logfunc) {
void linphone_core_set_log_file(FILE *file) {
if (file == NULL) file = stdout;
ortp_set_log_file(file);
bctbx_set_log_file(file); /*gather everythings*/
sal_set_log_handler(NULL); /*disable default log handler*/
ortp_set_log_handler(NULL); /*disable default log handler*/
}
void linphone_core_set_log_level(OrtpLogLevel loglevel) {
@ -498,15 +500,13 @@ void linphone_core_set_log_level(OrtpLogLevel loglevel) {
}
void linphone_core_set_log_level_mask(unsigned int loglevel) {
ortp_set_log_level_mask(NULL, loglevel);
bctbx_set_log_level_mask(NULL, loglevel);
if (loglevel == 0) {
sal_disable_log();
} else {
sal_enable_log();
}
//we only have 2 domain for now ortp and belle-sip
bctbx_set_log_level_mask(ORTP_LOG_DOMAIN, loglevel);
sal_set_log_level((OrtpLogLevel)loglevel);
}
unsigned int linphone_core_get_log_level_mask(void) {
return bctbx_get_log_level_mask(ORTP_LOG_DOMAIN);
}
static int _open_log_collection_file_with_idx(int idx) {
struct stat statbuf;
char *log_filename;
@ -1388,7 +1388,7 @@ static void sip_config_read(LinphoneCore *lc) {
sal_enable_sip_update_method(lc->sal,lp_config_get_int(lc->config,"sip","sip_update",1));
lc->sip_conf.vfu_with_info=lp_config_get_int(lc->config,"sip","vfu_with_info",1);
linphone_core_set_sip_transport_timeout(lc, lp_config_get_int(lc->config, "sip", "transport_timeout", 63000));
sal_set_supported_tags(lc->sal,lp_config_get_string(lc->config,"sip","supported","replaces, outbound"));
sal_set_supported_tags(lc->sal,lp_config_get_string(lc->config,"sip","supported","replaces, outbound, gruu"));
lc->sip_conf.save_auth_info = lp_config_get_int(lc->config, "sip", "save_auth_info", 1);
linphone_core_create_im_notif_policy(lc);
}
@ -3512,14 +3512,9 @@ void linphone_configure_op_with_proxy(LinphoneCore *lc, SalOp *op, const Linphon
sal_op_set_realm(op,linphone_proxy_config_get_realm(proxy));
if (with_contact && proxy && proxy->op){
const SalAddress *contact;
if ((contact=sal_op_get_contact_address(proxy->op))){
SalTransport tport=sal_address_get_transport((SalAddress*)contact);
SalAddress *new_contact=sal_address_clone(contact);
sal_address_clean(new_contact); /* clean out contact_params that come from proxy config*/
sal_address_set_transport(new_contact,tport);
sal_op_set_contact_address(op,new_contact);
sal_address_destroy(new_contact);
}
contact=sal_op_get_contact_address(proxy->op);
SalAddress *new_contact = contact ? sal_address_clone(contact) : NULL;
sal_op_set_and_clean_contact_address(proxy->op, new_contact);
}
sal_op_cnx_ip_to_0000_if_sendonly_enable(op,lp_config_get_default_int(lc->config,"sip","cnx_ip_to_0000_if_sendonly_enabled",0)); /*also set in linphone_call_new_incoming*/
}

View file

@ -4284,6 +4284,15 @@ extern "C" jobject Java_org_linphone_core_LinphoneFriendImpl_getCore(JNIEnv* en
return NULL;
}
extern "C" jstring Java_org_linphone_core_LinphoneFriendImpl_getVcardToString(JNIEnv* env
,jobject thiz
,jlong ptr) {
LinphoneFriend *lf = (LinphoneFriend*)ptr;
LinphoneVcard *lvc = linphone_friend_get_vcard(lf);
const char* vcard = linphone_vcard_as_vcard4_string(lvc);
return vcard ? env->NewStringUTF(vcard) : NULL;
}
extern "C" jobject Java_org_linphone_core_LinphoneFriendListImpl_getCore(JNIEnv* env
,jobject thiz
,jlong ptr) {
@ -7846,6 +7855,21 @@ JNIEXPORT void JNICALL Java_org_linphone_core_LinphoneCallImpl_setListener(JNIEn
linphone_call_set_next_video_frame_decoded_callback(call, _next_video_frame_decoded_callback, listener);
}
extern "C" void Java_org_linphone_core_LinphoneCallImpl_setVideoWindowId(JNIEnv* env
,jobject thiz
,jlong lc
,jobject obj) {
jobject oldWindow = (jobject) linphone_call_get_native_video_window_id((LinphoneCall*)lc);
if (obj != NULL) {
obj = env->NewGlobalRef(obj);
ms_message("Java_org_linphone_core_LinphoneCallImpl_setVideoWindowId(): NewGlobalRef(%p)",obj);
}else ms_message("Java_org_linphone_core_LinphoneCallImpl_setVideoWindowId(): setting to NULL");
linphone_call_set_native_video_window_id((LinphoneCall*)lc,(void *)obj);
if (oldWindow != NULL) {
ms_message("Java_org_linphone_core_LinphoneCallImpl_setVideoWindowId(): DeleteGlobalRef(%p)",oldWindow);
env->DeleteGlobalRef(oldWindow);
}
}
/*
* returns the java TunnelConfig associated with a C LinphoneTunnelConfig.

View file

@ -517,6 +517,20 @@ void sal_op_set_contact_address(SalOp *op, const SalAddress *address){
if (((SalOpBase*)op)->contact_address) sal_address_destroy(((SalOpBase*)op)->contact_address);
((SalOpBase*)op)->contact_address=address?sal_address_clone(address):NULL;
}
void sal_op_set_and_clean_contact_address(SalOp *op, SalAddress *contact) {
if (contact){
SalTransport tport = sal_address_get_transport((SalAddress*)contact);
const char* gruu = bctbx_strdup(sal_address_get_uri_param(contact, "gr"));
sal_address_clean((SalAddress*)contact); /* clean out contact_params that come from proxy config*/
sal_address_set_transport((SalAddress*)contact,tport);
if(gruu)
sal_address_set_uri_param(contact, "gr", gruu);
sal_op_set_contact_address(op, contact);
sal_address_unref(contact);
}
}
const SalAddress* sal_op_get_contact_address(const SalOp *op) {
return ((SalOpBase*)op)->contact_address;
}

View file

@ -101,8 +101,9 @@ void linphone_video_definition_set_name(LinphoneVideoDefinition *vdef, const cha
}
bool_t linphone_video_definition_equals(const LinphoneVideoDefinition *vdef1, const LinphoneVideoDefinition *vdef2) {
return (((vdef1->width == vdef2->width) && (vdef1->height == vdef2->height))
|| ((vdef1->width == vdef2->height) && (vdef1->height == vdef2->width)));
return ((vdef1 != NULL && vdef2 != NULL)
&& (((vdef1->width == vdef2->width) && (vdef1->height == vdef2->height))
|| ((vdef1->width == vdef2->height) && (vdef1->height == vdef2->width))));
}
bool_t linphone_video_definition_strict_equals(const LinphoneVideoDefinition *vdef1, const LinphoneVideoDefinition *vdef2) {

View file

@ -119,7 +119,7 @@ target_link_libraries(linphone-daemon ${LINPHONE_LIBS_FOR_TOOLS} ${MEDIASTREAMER
set_target_properties(linphone-daemon PROPERTIES LINK_FLAGS "${LINPHONE_LDFLAGS}")
add_executable(linphone-daemon-pipetest ${DAEMON_PIPETEST_SOURCE_FILES})
target_link_libraries(linphone-daemon-pipetest ${LINPHONE_LIBS_FOR_TOOLS} ${ORTP_LIBRARIES})
target_link_libraries(linphone-daemon-pipetest ${LINPHONE_LIBS_FOR_TOOLS} ${ORTP_LIBRARIES} ${BCTOOLBOX_CORE_LIBRARIES})
set_target_properties(linphone-daemon-pipetest PROPERTIES LINK_FLAGS "${LINPHONE_LDFLAGS}")
set(INSTALL_TARGETS linphone-daemon linphone-daemon-pipetest)

View file

@ -803,6 +803,14 @@ LINPHONE_PUBLIC void linphone_core_set_log_level(OrtpLogLevel loglevel);
*/
LINPHONE_PUBLIC void linphone_core_set_log_level_mask(unsigned int loglevel);
/**
* Get defined log level mask.
*
* @return The loglevel parameter is a bitmask parameter. Therefore to enable only warning and error
* messages, use ORTP_WARNING | ORTP_ERROR. To disable logs, simply set loglevel to 0.
*/
LINPHONE_PUBLIC unsigned int linphone_core_get_log_level_mask(void);
/**
* Enable logs in supplied FILE*.
* @param file a C FILE* where to fprintf logs. If null stdout is used.

View file

@ -148,6 +148,8 @@ const char *sal_address_get_header(const SalAddress *addr, const char *name);
LINPHONE_PUBLIC Sal * sal_init(MSFactory *factory);
LINPHONE_PUBLIC void sal_uninit(Sal* sal);
void sal_set_log_handler(BctbxLogFunc log_handler);
void sal_set_user_pointer(Sal *sal, void *user_data);
void *sal_get_user_pointer(const Sal *sal);
@ -672,6 +674,7 @@ SalOp * sal_op_new(Sal *sal);
/*generic SalOp API, working for all operations */
Sal *sal_op_get_sal(const SalOp *op);
void sal_op_set_contact_address(SalOp *op, const SalAddress* address);
void sal_op_set_and_clean_contact_address(SalOp *op, SalAddress* address);
void sal_op_set_route(SalOp *op, const char *route);
void sal_op_set_route_address(SalOp *op, const SalAddress* address);
void sal_op_add_route_address(SalOp *op, const SalAddress* address);

View file

@ -20,6 +20,8 @@ package org.linphone.core;
import java.util.Vector;
import org.linphone.mediastream.video.AndroidVideoWindowImpl;
/**
* Object representing a call. Calls are created using {@link LinphoneCore#invite(LinphoneAddress)} or passed to the application by listener {@link LinphoneCoreListener#callState}
*
@ -404,6 +406,13 @@ public interface LinphoneCall {
*/
void setListener(LinphoneCall.LinphoneCallListener listener);
/**
* Set the native video window id where the video is to be displayed.
* On Android, it must be of type {@link AndroidVideoWindowImpl}
* @param w window of type {@link AndroidVideoWindowImpl}
*/
void setVideoWindow(Object w);
/**
* Indicates if remote party requested automatic answering to be performed.
* This is an indication - the application remains responsible for answering the call.

View file

@ -165,6 +165,12 @@ public interface LinphoneFriend {
* @return The reference key of the friend.
**/
String getRefKey();
/**
* return a the string value of the vcard corresponding to the given friend
*/
String getVcardToString();
/**
* Set a name for this friend
* @param name

View file

@ -45,6 +45,7 @@ class LinphoneCallImpl implements LinphoneCall {
private native float getAverageQuality(long nativePtr);
private native boolean mediaInProgress(long nativePtr);
private native void setListener(long ptr, LinphoneCallListener listener);
private native void setVideoWindowId(long nativePtr, Object wid);
native private long getDiversionAddress(long nativePtr);
native private Object getStats(long nativePtr, int stream_type);
native private LinphoneCore getCore(long nativePtr);
@ -295,6 +296,11 @@ class LinphoneCallImpl implements LinphoneCall {
setListener(nativePtr, listener);
}
}
@Override
public synchronized void setVideoWindow(Object w) {
setVideoWindowId(nativePtr, w);
}
public LinphoneAddress getDiversionAddress() {
long lNativePtr = getDiversionAddress(nativePtr);

View file

@ -195,7 +195,7 @@ class LinphoneCoreImpl implements LinphoneCore {
private native Object createFriend(long nativePtr);
private native Object createFriendWithAddress(long nativePtr, String address);
private native int getIncomingTimeout(long nativePtr);
LinphoneCoreImpl(LinphoneCoreListener listener, File userConfig, File factoryConfig, Object userdata) throws IOException {
mListener = listener;
String user = userConfig == null ? null : userConfig.getCanonicalPath();

View file

@ -40,6 +40,7 @@ public class LinphoneFriendImpl implements LinphoneFriend, Serializable {
private native Object getCore(long ptr);
private native void setRefKey(long nativePtr, String key);
private native String getRefKey(long nativePtr);
private native String getVcardToString(long nativePtr);
private Object userdData;
public Object getUserData() {
@ -141,6 +142,12 @@ public class LinphoneFriendImpl implements LinphoneFriend, Serializable {
public String getRefKey(){
return getRefKey(nativePtr);
}
public synchronized String getVcardToString() {
return getVcardToString(nativePtr);
}
private native void setName(long nativePtr, String name);
@Override

View file

@ -24,6 +24,8 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
conference/conference-listener.h
conference/local-conference-event-handler.h
conference/remote-conference-event-handler.h
content/content.h
core/core.h
cpim/cpim.h
cpim/header/cpim-core-headers.h
cpim/header/cpim-generic-header.h
@ -32,9 +34,23 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
cpim/message/cpim-message.h
cpim/parser/cpim-grammar.h
cpim/parser/cpim-parser.h
db/abstract/abstract-db-p.h
db/abstract/abstract-db.h
db/events-db.h
db/provider/db-session-p.h
db/provider/db-session-provider.h
db/provider/db-session.h
enums.h
event/call-event.h
event/conference-event-p.h
event/conference-event.h
event/conference-participant-event.h
event/event.h
event/message-event.h
logger/logger.h
object/clonable-object.h
message/message.h
object/clonable-object-p.h
object/clonable-object.h
object/object-p.h
object/object.h
object/singleton.h
@ -47,15 +63,28 @@ set(LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES
set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
conference/local-conference-event-handler.cpp
conference/remote-conference-event-handler.cpp
content/content.cpp
core/core.cpp
cpim/header/cpim-core-headers.cpp
cpim/header/cpim-generic-header.cpp
cpim/header/cpim-header.cpp
cpim/message/cpim-message.cpp
cpim/parser/cpim-grammar.cpp
cpim/parser/cpim-parser.cpp
db/abstract/abstract-db.cpp
db/events-db.cpp
db/provider/db-session-provider.cpp
db/provider/db-session.cpp
event/call-event.cpp
event/conference-event.cpp
event/conference-participant-event.cpp
event/event.cpp
event/message-event.cpp
logger/logger.cpp
message/message.cpp
object/clonable-object.cpp
object/object.cpp
utils/general.cpp
utils/utils.cpp
xml/conference-info.cpp
xml/xml.cpp
@ -64,7 +93,14 @@ set(LINPHONE_CXX_OBJECTS_SOURCE_FILES
ADD_XSD_WRAPPERS(xml/xml "XML XSD - xml.xsd")
ADD_XSD_WRAPPERS(xml/conference-info "Conference info XSD - conference-info.xsd")
set(LINPHONE_CXX_OBJECTS_INCLUDE_DIRS ${BELR_INCLUDE_DIRS} ${SOCI_INCLUDE_DIRS} ${SOCI_MYSQL_INCLUDES} ${LIBXSD_INCLUDE_DIRS})
set(LINPHONE_CXX_OBJECTS_INCLUDE_DIRS ${BELR_INCLUDE_DIRS} ${LIBXSD_INCLUDE_DIRS})
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})
@ -77,12 +113,12 @@ bc_apply_compile_flags(LINPHONE_CXX_OBJECTS_SOURCE_FILES STRICT_OPTIONS_CPP STRI
if(ENABLE_STATIC)
add_library(linphone-cxx-objects-static OBJECT ${LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES} ${LINPHONE_CXX_OBJECTS_SOURCE_FILES})
target_compile_definitions(linphone-cxx-objects-static PRIVATE ${LINPHONE_CXX_OBJECTS_DEFINITIONS})
target_include_directories(linphone-cxx-objects-static PRIVATE ${LINPHONE_CXX_OBJECTS_INCLUDE_DIRS} ${LINPHONE_INCLUDE_DIRS})
target_include_directories(linphone-cxx-objects-static SYSTEM PRIVATE ${LINPHONE_CXX_OBJECTS_INCLUDE_DIRS} ${LINPHONE_INCLUDE_DIRS})
endif()
if(ENABLE_SHARED)
add_library(linphone-cxx-objects OBJECT ${LINPHONE_CXX_OBJECTS_PRIVATE_HEADER_FILES} ${LINPHONE_CXX_OBJECTS_SOURCE_FILES})
target_compile_definitions(linphone-cxx-objects PRIVATE ${LINPHONE_CXX_OBJECTS_DEFINITIONS})
target_include_directories(linphone-cxx-objects PRIVATE ${LINPHONE_CXX_OBJECTS_INCLUDE_DIRS} ${LINPHONE_INCLUDE_DIRS})
target_include_directories(linphone-cxx-objects SYSTEM PRIVATE ${LINPHONE_CXX_OBJECTS_INCLUDE_DIRS} ${LINPHONE_INCLUDE_DIRS})
target_compile_options(linphone-cxx-objects PRIVATE "-fPIC")
endif()

37
src/content/content.cpp Normal file
View file

@ -0,0 +1,37 @@
/*
* content.cpp
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "object/object-p.h"
#include "content.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class ContentPrivate : public ObjectPrivate {
private:
L_DECLARE_PUBLIC(Content);
};
// -----------------------------------------------------------------------------
Content::Content (ContentPrivate &p) : Object(p) {}
LINPHONE_END_NAMESPACE

45
src/content/content.h Normal file
View file

@ -0,0 +1,45 @@
/*
* content.h
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CONTENT_H_
#define _CONTENT_H_
#include "object/object.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class ContentPrivate;
class LINPHONE_PUBLIC Content : public Object {
friend class Core;
public:
// Nothing for the moment.
private:
Content (ContentPrivate &p);
L_DECLARE_PRIVATE(Content);
L_DISABLE_COPY(Content);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _CONTENT_H_

36
src/core/core.cpp Normal file
View file

@ -0,0 +1,36 @@
/*
* core.cpp
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "object/object-p.h"
#include "core.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class CorePrivate : public ObjectPrivate {
public:
// TODO.
};
// -----------------------------------------------------------------------------
Core::Core (CorePrivate &p) : Object(p) {}
LINPHONE_END_NAMESPACE

43
src/core/core.h Normal file
View file

@ -0,0 +1,43 @@
/*
* core.h
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CORE_H_
#define _CORE_H_
#include "object/object.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class CorePrivate;
class LINPHONE_PUBLIC Core : public Object {
public:
// Nothing for the moment.
private:
Core (CorePrivate &p);
L_DECLARE_PRIVATE(Core);
L_DISABLE_COPY(Core);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _CORE_H_

View file

@ -279,7 +279,7 @@ shared_ptr<Cpim::Header> Cpim::Parser::cloneHeader (const Header &header) {
class EmptyObject {};
inline bool headerIsValid (const shared_ptr<belr::Grammar> &grammar, const string &input) {
static bool headerIsValid (const shared_ptr<belr::Grammar> &grammar, const string &input) {
belr::Parser<shared_ptr<EmptyObject> > parser(grammar);
parser.setHandler(
"Header", belr::make_fn(make_shared<EmptyObject> )
@ -307,7 +307,7 @@ bool Cpim::Parser::headerParameterIsValid (const string &headerParameter) const
// -----------------------------------------------------------------------------
inline bool coreHeaderIsValid (
static bool coreHeaderIsValid (
const shared_ptr<belr::Grammar> &grammar,
const string &headerName,
const string &headerValue,

View file

@ -0,0 +1,42 @@
/*
* abstract-db-p.h
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _ABSTRACT_DB_P_H_
#define _ABSTRACT_DB_P_H_
#include "abstract-db.h"
#include "db/provider/db-session.h"
#include "object/object-p.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class AbstractDbPrivate : public ObjectPrivate {
public:
DbSession dbSession;
private:
AbstractDb::Backend backend;
L_DECLARE_PUBLIC(AbstractDb);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _ABSTRACT_DB_P_H_

View file

@ -0,0 +1,75 @@
/*
* abstract-db.cpp
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "abstract-db-p.h"
#include "db/provider/db-session-provider.h"
#include "abstract-db.h"
// =============================================================================
using namespace std;
LINPHONE_BEGIN_NAMESPACE
AbstractDb::AbstractDb (AbstractDbPrivate &p) : Object(*new AbstractDbPrivate) {}
bool AbstractDb::connect (Backend backend, const string &parameters) {
L_D(AbstractDb);
d->dbSession = DbSessionProvider::getInstance()->getSession(
(backend == Mysql ? "mysql://" : "sqlite3://") + parameters
);
if (d->dbSession)
init();
return d->dbSession;
}
bool AbstractDb::isConnected () const {
L_D(const AbstractDb);
return d->dbSession;
}
AbstractDb::Backend AbstractDb::getBackend () const {
L_D(const AbstractDb);
return d->backend;
}
// -----------------------------------------------------------------------------
void AbstractDb::init () {
// Nothing.
}
// -----------------------------------------------------------------------------
string AbstractDb::primaryKeyAutoIncrementStr (const string &type) const {
L_D(const AbstractDb);
switch (d->backend) {
case Mysql:
return type + "UNSIGNED PRIMARY KEY AUTO_INCREMENT";
case Sqlite3:
return " INTEGER PRIMARY KEY AUTOINCREMENT";
}
return "";
}
LINPHONE_END_NAMESPACE

View file

@ -0,0 +1,62 @@
/*
* abstract-db.h
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _ABSTRACT_DB_H_
#define _ABSTRACT_DB_H_
#include <string>
#include "object/object.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class AbstractDbPrivate;
class LINPHONE_PUBLIC AbstractDb : public Object {
public:
enum Backend {
Mysql,
Sqlite3
};
virtual ~AbstractDb () = default;
bool connect (Backend backend, const std::string &parameters);
bool disconnect ();
bool isConnected () const;
Backend getBackend () const;
protected:
explicit AbstractDb (AbstractDbPrivate &p);
virtual void init ();
std::string primaryKeyAutoIncrementStr (const std::string &type = "INT") const;
private:
L_DECLARE_PRIVATE(AbstractDb);
L_DISABLE_COPY(AbstractDb);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _ABSTRACT_DB_H_

411
src/db/events-db.cpp Normal file
View file

@ -0,0 +1,411 @@
/*
* events-db.cpp
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <algorithm>
#ifdef SOCI_ENABLED
#include <soci/soci.h>
#endif // ifdef SOCI_ENABLED
#include "abstract/abstract-db-p.h"
#include "event/call-event.h"
#include "event/event.h"
#include "event/message-event.h"
#include "logger/logger.h"
#include "message/message.h"
#include "events-db.h"
// =============================================================================
using namespace std;
LINPHONE_BEGIN_NAMESPACE
class EventsDbPrivate : public AbstractDbPrivate {};
// -----------------------------------------------------------------------------
EventsDb::EventsDb () : AbstractDb(*new EventsDbPrivate) {}
// -----------------------------------------------------------------------------
// Soci backend.
// -----------------------------------------------------------------------------
#ifdef SOCI_ENABLED
template<typename T>
struct EnumToSql {
T first;
const char *second;
};
template<typename T>
static constexpr const char *mapEnumToSql (const EnumToSql<T> enumToSql[], size_t n, T key) {
return n == 0 ? "" : (
enumToSql[n - 1].first == key ? enumToSql[n - 1].second : mapEnumToSql(enumToSql, n - 1, key)
);
}
// -----------------------------------------------------------------------------
static constexpr EnumToSql<EventsDb::Filter> eventFilterToSql[] = {
{ EventsDb::MessageFilter, "1" },
{ EventsDb::CallFilter, "2" },
{ EventsDb::ConferenceFilter, "3" }
};
static constexpr const char *mapEventFilterToSql (EventsDb::Filter filter) {
return mapEnumToSql(
eventFilterToSql, sizeof eventFilterToSql / sizeof eventFilterToSql[0], filter
);
}
static constexpr EnumToSql<Message::State> messageStateToSql[] = {
{ Message::Idle, "1" },
{ Message::InProgress, "2" },
{ Message::Delivered, "3" },
{ Message::NotDelivered, "4" },
{ Message::FileTransferError, "5" },
{ Message::FileTransferDone, "6" },
{ Message::DeliveredToUser, "7" },
{ Message::Displayed, "8" }
};
static constexpr const char *mapMessageStateToSql (Message::State state) {
return mapEnumToSql(
messageStateToSql, sizeof messageStateToSql / sizeof messageStateToSql[0], state
);
}
static constexpr const char *mapMessageDirectionToSql (Message::Direction direction) {
return direction == Message::Direction::Incoming ? "1" : "2";
}
// -----------------------------------------------------------------------------
static string buildSqlEventFilter (const list<EventsDb::Filter> &filters, EventsDb::FilterMask mask) {
L_ASSERT(
find_if(filters.cbegin(), filters.cend(), [](const EventsDb::Filter &filter) {
return filter == EventsDb::NoFilter;
}) == filters.cend()
);
if (mask == EventsDb::NoFilter)
return "";
bool isStart = true;
string sql;
for (const auto &filter : filters) {
if (!(mask & filter))
continue;
if (isStart) {
isStart = false;
sql += " WHERE ";
} else
sql += " OR ";
sql += " event_type_id = ";
sql += mapEventFilterToSql(filter);
}
return sql;
}
// -----------------------------------------------------------------------------
void EventsDb::init () {
L_D(EventsDb);
soci::session *session = d->dbSession.getBackendSession<soci::session>();
*session <<
"CREATE TABLE IF NOT EXISTS sip_address ("
" id" + primaryKeyAutoIncrementStr() + ","
" value VARCHAR(255) NOT NULL"
")";
*session <<
"CREATE TABLE IF NOT EXISTS event_type ("
" id" + primaryKeyAutoIncrementStr("TINYINT") + ","
" value VARCHAR(255) NOT NULL"
")";
*session <<
"CREATE TABLE IF NOT EXISTS event ("
" id" + primaryKeyAutoIncrementStr() + ","
" event_type_id TINYINT UNSIGNED NOT NULL,"
" timestamp TIMESTAMP NOT NULL,"
" FOREIGN KEY (event_type_id)"
" REFERENCES event_type(id)"
" ON DELETE CASCADE"
")";
*session <<
"CREATE TABLE IF NOT EXISTS message_state ("
" id" + primaryKeyAutoIncrementStr("TINYINT") + ","
" state VARCHAR(255) NOT NULL"
")";
*session <<
"CREATE TABLE IF NOT EXISTS message_direction ("
" id" + primaryKeyAutoIncrementStr("TINYINT") + ","
" direction VARCHAR(255) NOT NULL"
")";
*session <<
"CREATE TABLE IF NOT EXISTS dialog ("
" id" + primaryKeyAutoIncrementStr() + ","
" local_sip_address_id INT UNSIGNED NOT NULL," // Sip address used to communicate.
" remote_sip_address_id INT UNSIGNED NOT NULL," // Server (for conference) or user sip address.
" creation_timestamp TIMESTAMP NOT NULL," // Dialog creation date.
" last_update_timestamp TIMESTAMP NOT NULL," // Last event timestamp (call, message...).
" FOREIGN KEY (local_sip_address_id)"
" REFERENCES sip_address(id)"
" ON DELETE CASCADE,"
" FOREIGN KEY (remote_sip_address_id)"
" REFERENCES sip_address(id)"
" ON DELETE CASCADE"
")";
*session <<
"CREATE TABLE IF NOT EXISTS message_event ("
" id" + primaryKeyAutoIncrementStr() + ","
" dialog_id INT UNSIGNED NOT NULL,"
" state_id TINYINT UNSIGNED NOT NULL,"
" direction_id TINYINT UNSIGNED NOT NULL,"
" imdn_message_id VARCHAR(255) NOT NULL," // See: https://tools.ietf.org/html/rfc5438#section-6.3
" content_type VARCHAR(255) NOT NULL,"
" is_secured BOOLEAN NOT NULL,"
" app_data VARCHAR(2048),"
" FOREIGN KEY (dialog_id)"
" REFERENCES dialog(id)"
" ON DELETE CASCADE,"
" FOREIGN KEY (state_id)"
" REFERENCES message_state(id)"
" ON DELETE CASCADE,"
" FOREIGN KEY (direction_id)"
" REFERENCES message_direction(id)"
" ON DELETE CASCADE"
")";
{
string query = getBackend() == Mysql
? "INSERT INTO event_type (id, value)"
: "INSERT OR IGNORE INTO event_type (id, value)";
query += "VALUES"
"(1, \"Message\"),"
"(2, \"Call\"),"
"(3, \"Conference\")";
if (getBackend() == Mysql)
query += "ON DUPLICATE KEY UPDATE value = VALUES(value)";
*session << query;
}
{
string query = getBackend() == Mysql
? "INSERT INTO message_direction (id, value)"
: "INSERT OR IGNORE INTO message_direction (id, value)";
query += "VALUES"
"(1, \"Incoming\"),"
"(2, \"Outgoing\")";
if (getBackend() == Mysql)
query += "ON DUPLICATE KEY UPDATE value = VALUES(value)";
*session << query;
}
{
string query = getBackend() == Mysql
? "INSERT INTO message_state (id, value)"
: "INSERT OR IGNORE INTO message_state (id, value)";
query += "VALUES"
"(1, \"Idle\"),"
"(2, \"InProgress\"),"
"(3, \"Delivered\"),"
"(4, \"NotDelivered\"),"
"(5, \"FileTransferError\"),"
"(6, \"FileTransferDone\"),"
"(7, \"DeliveredToUser\"),"
"(8, \"Displayed\")";
if (getBackend() == Mysql)
query += "ON DUPLICATE KEY UPDATE value = VALUES(value)";
*session << query;
}
}
bool EventsDb::addEvent (const Event &event) {
// TODO.
switch (event.getType()) {
case Event::None:
return false;
case Event::MessageEvent:
case Event::CallStartEvent:
case Event::CallEndEvent:
case Event::ConferenceCreatedEvent:
case Event::ConferenceDestroyedEvent:
case Event::ConferenceParticipantAddedEvent:
case Event::ConferenceParticipantRemovedEvent:
case Event::ConferenceParticipantSetAdminEvent:
case Event::ConferenceParticipantUnsetAdminEvent:
break;
}
return true;
}
bool EventsDb::deleteEvent (const Event &event) {
// TODO.
(void)event;
return true;
}
void EventsDb::cleanEvents (FilterMask mask) {
// TODO.
(void)mask;
}
int EventsDb::getEventsCount (FilterMask mask) const {
L_D(const EventsDb);
string query = "SELECT COUNT(*) FROM event" +
buildSqlEventFilter({ MessageFilter, CallFilter, ConferenceFilter }, mask);
int count = 0;
L_BEGIN_LOG_EXCEPTION
soci::session *session = d->dbSession.getBackendSession<soci::session>();
*session << query, soci::into(count);
L_END_LOG_EXCEPTION
return count;
}
int EventsDb::getMessagesCount (const string &remoteAddress) const {
L_D(const EventsDb);
string query = "SELECT COUNT(*) FROM message_event";
if (!remoteAddress.empty())
query += " WHERE dialog_id = ("
" SELECT id FROM dialog WHERE remote_sip_address_id =("
" SELECT id FROM sip_address WHERE value = :remote_address"
" )"
" )";
int count = 0;
L_BEGIN_LOG_EXCEPTION
soci::session *session = d->dbSession.getBackendSession<soci::session>();
*session << query, soci::use(remoteAddress), soci::into(count);
L_END_LOG_EXCEPTION
return count;
}
int EventsDb::getUnreadMessagesCount (const string &remoteAddress) const {
L_D(const EventsDb);
string query = "SELECT COUNT(*) FROM message_event";
if (!remoteAddress.empty())
query += " WHERE dialog_id = ("
" SELECT id FROM dialog WHERE remote_sip_address_id = ("
" SELECT id FROM sip_address WHERE value = :remote_address"
" )"
" )"
" AND direction_id = " + string(mapMessageDirectionToSql(Message::Incoming)) +
" AND state_id = " + string(mapMessageStateToSql(Message::Displayed));
int count = 0;
L_BEGIN_LOG_EXCEPTION
soci::session *session = d->dbSession.getBackendSession<soci::session>();
*session << query, soci::use(remoteAddress), soci::into(count);
L_END_LOG_EXCEPTION
return count;
}
list<Event> EventsDb::getHistory (const string &remoteAddress, int nLast, FilterMask mask) const {
// TODO.
(void)remoteAddress;
(void)nLast;
(void)mask;
return list<Event>();
}
list<Event> EventsDb::getHistory (const string &remoteAddress, int begin, int end, FilterMask mask) const {
// TODO.
(void)remoteAddress;
(void)begin;
(void)end;
(void)mask;
return list<Event>();
}
void EventsDb::cleanHistory (const string &remoteAddress) {
// TODO.
(void)remoteAddress;
}
// -----------------------------------------------------------------------------
// No backend.
// -----------------------------------------------------------------------------
#else
void EventsDb::init () {}
bool EventsDb::addEvent (const Event &) {
return false;
}
bool EventsDb::deleteEvent (const Event &) {
return false;
}
void EventsDb::cleanEvents (FilterMask) {}
int EventsDb::getEventsCount (FilterMask) const {
return 0;
}
int EventsDb::getMessagesCount (const string &) const {
return 0;
}
int EventsDb::getUnreadMessagesCount (const string &) const {
return 0;
}
list<Event> EventsDb::getHistory (const string &, int, FilterMask) const {
return list<Event>();
}
list<Event> EventsDb::getHistory (const string &, int, int, FilterMask) const {
return list<Event>();
}
void EventsDb::cleanHistory (const string &) {}
#endif // ifdef SOCI_ENABLED
LINPHONE_END_NAMESPACE

69
src/db/events-db.h Normal file
View file

@ -0,0 +1,69 @@
/*
* events-db.h
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _EVENTS_DB_H_
#define _EVENTS_DB_H_
#include <list>
#include "abstract/abstract-db.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class Event;
class EventsDbPrivate;
class LINPHONE_PUBLIC EventsDb : public AbstractDb {
public:
enum Filter {
NoFilter = 0x0,
MessageFilter = 0x1,
CallFilter = 0x2,
ConferenceFilter = 0x4
};
typedef int FilterMask;
EventsDb ();
// Generic.
bool addEvent (const Event &event);
bool deleteEvent (const Event &event);
void cleanEvents (FilterMask mask = NoFilter);
int getEventsCount (FilterMask mask = NoFilter) const;
// Messages, calls and conferences.
int getMessagesCount (const std::string &remoteAddress = "") const;
int getUnreadMessagesCount (const std::string &remoteAddress = "") const;
std::list<Event> getHistory (const std::string &remoteAddress, int nLast, FilterMask mask = NoFilter) const;
std::list<Event> getHistory (const std::string &remoteAddress, int begin, int end, FilterMask mask = NoFilter) const;
void cleanHistory (const std::string &remoteAddress = "");
protected:
void init () override;
private:
L_DECLARE_PRIVATE(EventsDb);
L_DISABLE_COPY(EventsDb);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _EVENTS_DB_H_

View file

@ -0,0 +1,47 @@
/*
* db-session-p.h
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _DB_SESSION_P_H_
#define _DB_SESSION_P_H_
#include <memory>
#include "db-session.h"
#include "object/clonable-object-p.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
// -----------------------------------------------------------------------------
class DbSessionPrivate : public ClonableObjectPrivate {
friend class DbSessionProvider;
private:
bool isValid = false;
DbSession::Type type = DbSession::None;
std::shared_ptr<void> backendSession;
L_DECLARE_PUBLIC(DbSession);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _DB_SESSION_P_H_

View file

@ -0,0 +1,83 @@
/*
* db-session-provider.cpp
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <unordered_map>
#ifdef SOCI_ENABLED
#include <soci/soci.h>
#endif // ifdef SOCI_ENABLED
#include "db-session-p.h"
#include "object/object-p.h"
#include "db-session-provider.h"
#define CLEAN_COUNTER_MAX 1000
// =============================================================================
using namespace std;
LINPHONE_BEGIN_NAMESPACE
class DbSessionProviderPrivate : public ObjectPrivate {
public:
typedef pair<weak_ptr<void>, DbSessionPrivate *> InternalSession;
unordered_map<string, InternalSession> sessions;
int cleanCounter = 0;
};
DbSessionProvider::DbSessionProvider () : Singleton(*new DbSessionProviderPrivate) {}
DbSession DbSessionProvider::getSession (const string &uri) {
L_D(DbSessionProvider);
#ifdef SOCI_ENABLED
DbSession session(DbSession::Soci);
try {
shared_ptr<void> backendSession = d->sessions[uri].first.lock();
++d->cleanCounter;
if (!backendSession) { // Create new session.
backendSession = make_shared<soci::session>(uri);
DbSessionPrivate *p = session.getPrivate();
p->backendSession = backendSession;
p->isValid = true;
d->sessions[uri] = make_pair(backendSession, p);
} else // Share session.
session.setRef(*d->sessions[uri].second);
} catch (const exception &) {}
#else
DbSession session(DbSession::None);
#endif // ifdef SOCI_ENABLED
// Remove invalid weak ptrs.
if (d->cleanCounter >= CLEAN_COUNTER_MAX) {
d->cleanCounter = 0;
for (auto it = d->sessions.begin(), itEnd = d->sessions.end(); it != itEnd;) {
if (it->second.first.expired())
it = d->sessions.erase(it);
else
++it;
}
}
return session;
}
LINPHONE_END_NAMESPACE

View file

@ -0,0 +1,48 @@
/*
* db-session-provider.h
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _DB_SESSION_PROVIDER_H_
#define _DB_SESSION_PROVIDER_H_
#include <string>
#include "db-session.h"
#include "object/singleton.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class DbSessionProviderPrivate;
class DbSessionProvider : public Singleton<DbSessionProvider> {
friend class Singleton<DbSessionProvider>;
public:
DbSession getSession (const std::string &uri);
private:
DbSessionProvider ();
L_DECLARE_PRIVATE(DbSessionProvider);
L_DISABLE_COPY(DbSessionProvider);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _DB_SESSION_PROVIDER_H_

View file

@ -0,0 +1,51 @@
/*
* db-session.cpp
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "db-session-p.h"
#include "db-session.h"
// =============================================================================
using namespace std;
LINPHONE_BEGIN_NAMESPACE
DbSession::DbSession (Type type) : ClonableObject(*new DbSessionPrivate) {
L_D(DbSession);
d->type = type;
}
L_USE_DEFAULT_SHARE_IMPL(DbSession, ClonableObject);
DbSession::operator bool () const {
L_D(const DbSession);
return d->isValid;
}
DbSession::Type DbSession::getBackendType () const {
L_D(const DbSession);
return d->type;
}
void *DbSession::getBackendSession () const {
L_D(const DbSession);
return d->backendSession.get();
}
LINPHONE_END_NAMESPACE

View file

@ -0,0 +1,92 @@
/*
* db-session.h
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _DB_SESSION_H_
#define _DB_SESSION_H_
#include <string>
#include "object/clonable-object.h"
// =============================================================================
#ifdef SOCI_ENABLED
namespace soci {
class session;
}
#endif // ifdef SOCI_ENABLED
LINPHONE_BEGIN_NAMESPACE
class DbSessionPrivate;
class DbSession : public ClonableObject {
friend class DbSessionProvider;
public:
enum Type {
None,
Soci
};
DbSession (Type type = None);
DbSession (const DbSession &src);
DbSession &operator= (const DbSession &src);
operator bool () const;
Type getBackendType () const;
template<typename T>
T *getBackendSession () const;
private:
void *getBackendSession () const;
L_DECLARE_PRIVATE(DbSession);
};
// -----------------------------------------------------------------------------
template<typename T>
struct TypeOfDbSession {
static const DbSession::Type type = DbSession::None;
};
#ifdef SOCI_ENABLED
template<>
struct TypeOfDbSession<::soci::session> {
static const DbSession::Type type = DbSession::Soci;
};
#endif // ifdef SOCI_ENABLED
template<typename T>
T *DbSession::getBackendSession () const {
typedef TypeOfDbSession<T> Type;
static_assert(Type::type != DbSession::None, "Unable to get backend session, invalid type.");
if (getBackendType() != Type::type)
return nullptr;
return static_cast<T *>(getBackendSession());
}
LINPHONE_END_NAMESPACE
#endif // ifndef _DB_SESSION_H_

32
src/enums.h Normal file
View file

@ -0,0 +1,32 @@
/*
* enums.h
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _ENUMS_H_
#define _ENUMS_H_
#include "utils/general.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
// Nothing. for the moment.
LINPHONE_END_NAMESPACE
#endif // ifndef _ENUMS_H_

60
src/event/call-event.cpp Normal file
View file

@ -0,0 +1,60 @@
/*
* call-event.cpp
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "event-p.h"
#include "call-event.h"
// =============================================================================
using namespace std;
LINPHONE_BEGIN_NAMESPACE
class CallEventPrivate : public EventPrivate {
public:
shared_ptr<Call> call;
};
// -----------------------------------------------------------------------------
CallEvent::CallEvent (Type type, const shared_ptr<Call> &call) : Event(*new CallEventPrivate, type) {
L_D(CallEvent);
L_ASSERT(call);
L_ASSERT(type == CallStartEvent || type == CallEndEvent);
d->call = call;
}
CallEvent::CallEvent (const CallEvent &src) : CallEvent(src.getType(), src.getCall()) {}
CallEvent &CallEvent::operator= (const CallEvent &src) {
L_D(CallEvent);
if (this != &src) {
Event::operator=(src);
d->call = src.getPrivate()->call;
}
return *this;
}
shared_ptr<Call> CallEvent::getCall () const {
L_D(const CallEvent);
return d->call;
}
LINPHONE_END_NAMESPACE

48
src/event/call-event.h Normal file
View file

@ -0,0 +1,48 @@
/*
* call-event.h
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CALL_EVENT_H_
#define _CALL_EVENT_H_
#include <memory>
#include "event.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class Call;
class CallEventPrivate;
class LINPHONE_PUBLIC CallEvent : public Event {
public:
CallEvent (Type type, const std::shared_ptr<Call> &message);
CallEvent (const CallEvent &src);
CallEvent &operator= (const CallEvent &src);
std::shared_ptr<Call> getCall () const;
private:
L_DECLARE_PRIVATE(CallEvent);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _CALL_EVENT_H_

View file

@ -0,0 +1,39 @@
/*
* conference-event-p.h
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CONFERENCE_EVENT_P_H_
#define _CONFERENCE_EVENT_P_H_
#include "conference-event.h"
#include "event-p.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class ConferenceEventPrivate : public EventPrivate {
private:
std::shared_ptr<Address> address;
L_DECLARE_PUBLIC(ConferenceEvent);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _CONFERENCE_EVENT_P_H_

View file

@ -0,0 +1,61 @@
/*
* conference-event.cpp
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "conference-event-p.h"
#include "conference-event.h"
// =============================================================================
using namespace std;
LINPHONE_BEGIN_NAMESPACE
ConferenceEvent::ConferenceEvent (Type type, const shared_ptr<Address> &address) :
Event(*new ConferenceEventPrivate, type) {
L_D(ConferenceEvent);
L_ASSERT(type == ConferenceCreatedEvent || type == ConferenceDestroyedEvent);
L_ASSERT(address);
d->address = address;
}
ConferenceEvent::ConferenceEvent (const ConferenceEvent &src) : ConferenceEvent(src.getType(), src.getAddress()) {}
ConferenceEvent::ConferenceEvent (ConferenceEventPrivate &p, Type type, const shared_ptr<Address> &address) :
Event(p, type) {
L_D(ConferenceEvent);
L_ASSERT(address);
d->address = address;
}
ConferenceEvent &ConferenceEvent::operator= (const ConferenceEvent &src) {
L_D(ConferenceEvent);
if (this != &src) {
Event::operator=(src);
d->address = src.getPrivate()->address;
}
return *this;
}
shared_ptr<Address> ConferenceEvent::getAddress () const {
// TODO.
return nullptr;
}
LINPHONE_END_NAMESPACE

View file

@ -0,0 +1,52 @@
/*
* conference-event.h
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CONFERENCE_EVENT_H_
#define _CONFERENCE_EVENT_H_
#include <memory>
#include "event.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class Address;
class ConferenceEventPrivate;
class LINPHONE_PUBLIC ConferenceEvent : public Event {
public:
ConferenceEvent (Type type, const std::shared_ptr<Address> &address);
ConferenceEvent (const ConferenceEvent &src);
virtual ~ConferenceEvent () = default;
ConferenceEvent &operator= (const ConferenceEvent &src);
std::shared_ptr<Address> getAddress () const;
protected:
ConferenceEvent (ConferenceEventPrivate &p, Type type, const std::shared_ptr<Address> &address);
private:
L_DECLARE_PRIVATE(ConferenceEvent);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _CONFERENCE_EVENT_H_

View file

@ -0,0 +1,70 @@
/*
* conference-participant-event.cpp
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "conference-event-p.h"
#include "conference-participant-event.h"
// =============================================================================
using namespace std;
LINPHONE_BEGIN_NAMESPACE
class ConferenceParticipantEventPrivate : public ConferenceEventPrivate {
public:
shared_ptr<Address> participantAddress;
};
// -----------------------------------------------------------------------------
ConferenceParticipantEvent::ConferenceParticipantEvent (
Type type,
const shared_ptr<Address> &conferenceAddress,
const shared_ptr<Address> &participantAddress
) : ConferenceEvent(*new ConferenceParticipantEventPrivate, type, conferenceAddress) {
L_D(ConferenceParticipantEvent);
L_ASSERT(
type == ConferenceParticipantAddedEvent ||
type == ConferenceParticipantRemovedEvent ||
type == ConferenceParticipantSetAdminEvent ||
type == ConferenceParticipantUnsetAdminEvent
);
L_ASSERT(participantAddress);
d->participantAddress = participantAddress;
}
ConferenceParticipantEvent::ConferenceParticipantEvent (const ConferenceParticipantEvent &src) :
ConferenceParticipantEvent(src.getType(), src.getAddress(), src.getParticipantAddress()) {}
ConferenceParticipantEvent &ConferenceParticipantEvent::operator= (const ConferenceParticipantEvent &src) {
L_D(ConferenceParticipantEvent);
if (this != &src) {
ConferenceEvent::operator=(src);
d->participantAddress = src.getPrivate()->participantAddress;
}
return *this;
}
shared_ptr<Address> ConferenceParticipantEvent::getParticipantAddress () const {
// TODO.
return nullptr;
}
LINPHONE_END_NAMESPACE

View file

@ -0,0 +1,49 @@
/*
* conference-participant-event.h
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _CONFERENCE_PARTICIPANT_EVENT_H_
#define _CONFERENCE_PARTICIPANT_EVENT_H_
#include "conference-event.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class ConferenceParticipantEventPrivate;
class LINPHONE_PUBLIC ConferenceParticipantEvent : public ConferenceEvent {
public:
ConferenceParticipantEvent (
Type type,
const std::shared_ptr<Address> &conferenceAddress,
const std::shared_ptr<Address> &participantAddress
);
ConferenceParticipantEvent (const ConferenceParticipantEvent &src);
ConferenceParticipantEvent &operator= (const ConferenceParticipantEvent &src);
std::shared_ptr<Address> getParticipantAddress () const;
private:
L_DECLARE_PRIVATE(ConferenceParticipantEvent);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _CONFERENCE_PARTICIPANT_EVENT_H_

38
src/event/event-p.h Normal file
View file

@ -0,0 +1,38 @@
/*
* event-p.h
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _EVENT_P_H_
#define _EVENT_P_H_
#include "event.h"
#include "object/clonable-object-p.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class EventPrivate : public ClonableObjectPrivate {
private:
Event::Type type = Event::None;
L_DECLARE_PUBLIC(Event);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _EVENT_P_H_

50
src/event/event.cpp Normal file
View file

@ -0,0 +1,50 @@
/*
* event.cpp
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "event-p.h"
#include "event.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
// -----------------------------------------------------------------------------
Event::Event () : ClonableObject(*new EventPrivate) {}
Event::Event (const Event &) : ClonableObject(*new EventPrivate) {}
Event::Event (EventPrivate &p, Type type) : ClonableObject(*new EventPrivate) {
L_D(Event);
d->type = type;
}
Event &Event::operator= (const Event &src) {
L_D(Event);
if (this != &src)
d->type = src.getPrivate()->type;
return *this;
}
Event::Type Event::getType () const {
L_D(const Event);
return d->type;
}
LINPHONE_END_NAMESPACE

66
src/event/event.h Normal file
View file

@ -0,0 +1,66 @@
/*
* event.h
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _EVENT_H_
#define _EVENT_H_
#include "object/clonable-object.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class EventPrivate;
class LINPHONE_PUBLIC Event : public ClonableObject {
public:
enum Type {
None,
// MessageEvent.
MessageEvent,
// CallEvent.
CallStartEvent,
CallEndEvent,
// ConferenceEvent.
ConferenceCreatedEvent,
ConferenceDestroyedEvent,
// ConferenceParticipantEvent.
ConferenceParticipantAddedEvent,
ConferenceParticipantRemovedEvent,
ConferenceParticipantSetAdminEvent,
ConferenceParticipantUnsetAdminEvent
};
Event ();
Event (const Event &src);
virtual ~Event () = default;
Event &operator= (const Event &src);
Type getType () const;
protected:
Event (EventPrivate &p, Type type);
private:
L_DECLARE_PRIVATE(Event);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _EVENT_H_

View file

@ -0,0 +1,59 @@
/*
* message-event.cpp
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "event-p.h"
#include "message-event.h"
// =============================================================================
using namespace std;
LINPHONE_BEGIN_NAMESPACE
class MessageEventPrivate : public EventPrivate {
public:
shared_ptr<Message> message;
};
// -----------------------------------------------------------------------------
MessageEvent::MessageEvent (const shared_ptr<Message> &message) : Event(*new MessageEventPrivate, Event::MessageEvent) {
L_D(MessageEvent);
L_ASSERT(message);
d->message = message;
}
MessageEvent::MessageEvent (const MessageEvent &src) : MessageEvent(src.getMessage()) {}
MessageEvent &MessageEvent::operator= (const MessageEvent &src) {
L_D(MessageEvent);
if (this != &src) {
Event::operator=(src);
d->message = src.getPrivate()->message;
}
return *this;
}
shared_ptr<Message> MessageEvent::getMessage () const {
L_D(const MessageEvent);
return d->message;
}
LINPHONE_END_NAMESPACE

48
src/event/message-event.h Normal file
View file

@ -0,0 +1,48 @@
/*
* message-event.h
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _MESSAGE_EVENT_H_
#define _MESSAGE_EVENT_H_
#include <memory>
#include "event.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class Message;
class MessageEventPrivate;
class LINPHONE_PUBLIC MessageEvent : public Event {
public:
MessageEvent (const std::shared_ptr<Message> &message);
MessageEvent (const MessageEvent &src);
MessageEvent &operator= (const MessageEvent &src);
std::shared_ptr<Message> getMessage () const;
private:
L_DECLARE_PRIVATE(MessageEvent);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _MESSAGE_EVENT_H_

View file

@ -49,7 +49,9 @@ Logger::~Logger () {
switch (d->level) {
case Debug:
ms_debug("%s", str.c_str());
#if DEBUG_LOGS
ms_debug("%s", str.c_str());
#endif // if DEBUG_LOGS
break;
case Info:
ms_message("%s", str.c_str());

View file

@ -57,4 +57,10 @@ LINPHONE_END_NAMESPACE
#define lError() LINPHONE_NAMESPACE::Logger(Logger::Error).getOutput()
#define lFatal() LINPHONE_NAMESPACE::Logger(Logger::Fatal).getOutput()
#define L_BEGIN_LOG_EXCEPTION try {
#define L_END_LOG_EXCEPTION \
} catch (const exception &e) { \
lWarning() << "Error: " << e.what(); \
}
#endif // ifndef _LOGGER_H_

188
src/message/message.cpp Normal file
View file

@ -0,0 +1,188 @@
/*
* message.cpp
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include <unordered_map>
#include "db/events-db.h"
#include "object/object-p.h"
#include "message.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
using namespace std;
class MessagePrivate : public ObjectPrivate {
private:
weak_ptr<ChatRoom> chatRoom;
Message::Direction direction = Message::Incoming;
// LinphoneAddress *from;
// LinphoneAddress *to;
shared_ptr<ErrorInfo> errorInfo;
string contentType;
string text;
bool isSecured = false;
time_t time = 0;
string id;
string appData;
list<shared_ptr<Content> > contents;
unordered_map<string, string> customHeaders;
Message::State state = Message::Idle;
shared_ptr<EventsDb> eventsDb;
L_DECLARE_PUBLIC(Message);
};
// -----------------------------------------------------------------------------
Message::Message (MessagePrivate &p) : Object(p) {}
shared_ptr<ChatRoom> Message::getChatRoom () const {
L_D(const Message);
shared_ptr<ChatRoom> chatRoom = d->chatRoom.lock();
if (!chatRoom) {
// TODO.
}
return chatRoom;
}
Message::Direction Message::getDirection () const {
L_D(const Message);
return d->direction;
}
shared_ptr<const Address> Message::getFromAddress () const {
// TODO.
return nullptr;
}
shared_ptr<const Address> Message::getToAddress () const {
// TODO.
return nullptr;
}
shared_ptr<const Address> Message::getLocalAddress () const {
// TODO.
return nullptr;
}
shared_ptr<const Address> Message::getRemoteAddress () const {
// TODO.
return nullptr;
}
Message::State Message::getState () const {
L_D(const Message);
return d->state;
}
shared_ptr<const ErrorInfo> Message::getErrorInfo () const {
L_D(const Message);
return d->errorInfo;
}
string Message::getContentType () const {
L_D(const Message);
return d->contentType;
}
string Message::getText () const {
L_D(const Message);
return d->text;
}
void Message::setText (const string &text) {
L_D(Message);
d->text = text;
}
void Message::send () const {
// TODO.
}
bool Message::containsReadableText () const {
// TODO: Check content type.
return true;
}
bool Message::isSecured () const {
L_D(const Message);
return d->isSecured;
}
time_t Message::getTime () const {
L_D(const Message);
return d->time;
}
string Message::getId () const {
L_D(const Message);
return d->id;
}
string Message::getAppdata () const {
L_D(const Message);
return d->appData;
}
void Message::setAppdata (const string &appData) {
L_D(Message);
d->appData = appData;
}
list<shared_ptr<const Content> > Message::getContents () const {
L_D(const Message);
list<shared_ptr<const Content> > contents;
for (const auto &content : d->contents)
contents.push_back(content);
return contents;
}
void Message::addContent (const shared_ptr<Content> &content) {
L_D(Message);
d->contents.push_back(content);
}
void Message::removeContent (const shared_ptr<const Content> &content) {
L_D(Message);
d->contents.remove(const_pointer_cast<Content>(content));
}
string Message::getCustomHeaderValue (const string &headerName) const {
L_D(const Message);
try {
return d->customHeaders.at(headerName);
} catch (const exception &) {
// Key doesn't exist.
}
return "";
}
void Message::addCustomHeader (const string &headerName, const string &headerValue) {
L_D(Message);
d->customHeaders[headerName] = headerValue;
}
void Message::removeCustomHeader (const string &headerName) {
L_D(Message);
d->customHeaders.erase(headerName);
}
LINPHONE_END_NAMESPACE

107
src/message/message.h Normal file
View file

@ -0,0 +1,107 @@
/*
* message.h
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _MESSAGE_H_
#define _MESSAGE_H_
#include <list>
#include <memory>
#include <string>
#include "enums.h"
#include "object/object.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class Address;
class ChatRoom;
class Content;
class ErrorInfo;
class MessagePrivate;
class LINPHONE_PUBLIC Message : public Object {
friend class ChatRoom;
public:
enum Direction {
Incoming,
Outgoing
};
enum State {
Idle,
InProgress,
Delivered,
NotDelivered,
FileTransferError,
FileTransferDone,
DeliveredToUser,
Displayed
};
std::shared_ptr<ChatRoom> getChatRoom () const;
Direction getDirection () const;
std::shared_ptr<const Address> getFromAddress () const;
std::shared_ptr<const Address> getToAddress () const;
std::shared_ptr<const Address> getLocalAddress () const;
std::shared_ptr<const Address> getRemoteAddress () const;
State getState () const;
std::shared_ptr<const ErrorInfo> getErrorInfo () const;
std::string getContentType () const;
std::string getText () const;
void setText (const std::string &text);
void send () const;
bool containsReadableText () const;
bool isSecured () const;
time_t getTime () const;
std::string getId () const;
std::string getAppdata () const;
void setAppdata (const std::string &appData);
std::list<std::shared_ptr<const Content> > getContents () const;
void addContent (const std::shared_ptr<Content> &content);
void removeContent (const std::shared_ptr<const Content> &content);
std::string getCustomHeaderValue (const std::string &headerName) const;
void addCustomHeader (const std::string &headerName, const std::string &headerValue);
void removeCustomHeader (const std::string &headerName);
private:
Message (MessagePrivate &p);
L_DECLARE_PRIVATE(Message);
L_DISABLE_COPY(Message);
};
LINPHONE_END_NAMESPACE
#endif // ifndef _MESSAGE_H_

View file

@ -19,22 +19,27 @@
#ifndef _CLONABLE_OBJECT_P_H_
#define _CLONABLE_OBJECT_P_H_
#include <unordered_map>
#include "utils/general.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
class ClonableObject;
class ClonableObjectPrivate {
public:
virtual ~ClonableObjectPrivate () = default;
protected:
ClonableObject *mPublic = nullptr;
std::unordered_map<const ClonableObjectPrivate *, ClonableObject *> *mPublic = nullptr;
private:
void ref ();
void unref ();
int nRefs = 0;
L_DECLARE_PUBLIC(ClonableObject);
};

View file

@ -20,16 +20,66 @@
#include "clonable-object.h"
LINPHONE_BEGIN_NAMESPACE
// =============================================================================
ClonableObject::~ClonableObject () {
delete mPrivate;
using namespace std;
LINPHONE_BEGIN_NAMESPACE
// TODO: Use atomic counter?
void ClonableObjectPrivate::ref () {
++nRefs;
}
void ClonableObjectPrivate::unref () {
if (--nRefs == 0) {
delete mPublic;
delete this;
}
}
// -----------------------------------------------------------------------------
ClonableObject::ClonableObject (ClonableObjectPrivate &p) : mPrivate(&p) {
mPrivate->mPublic = this;
// Q-pointer must be empty. It's a constructor that takes a new private data.
L_ASSERT(!mPrivate->mPublic);
mPrivate->mPublic = new remove_pointer<decltype(mPrivate->mPublic)>::type;
(*mPrivate->mPublic)[mPrivate] = this;
mPrivate->ref();
}
ClonableObject::ClonableObject (const ClonableObjectPrivate &p) {
// Cannot access to Q-pointer. It's a copy constructor from private data.
L_ASSERT(!mPrivate);
setRef(p);
}
ClonableObject::~ClonableObject () {
mPrivate->mPublic->erase(mPrivate);
mPrivate->unref();
}
void ClonableObject::setRef (const ClonableObjectPrivate &p) {
// Q-pointer must exist if private data is defined.
L_ASSERT(!mPrivate || mPrivate->mPublic);
// Nothing, same reference.
if (&p == mPrivate)
return;
// Unref previous private data.
if (mPrivate) {
mPrivate->mPublic->erase(mPrivate);
mPrivate->unref();
}
// Add and reference new private data.
mPrivate = const_cast<ClonableObjectPrivate *>(&p);
(*mPrivate->mPublic)[mPrivate] = this;
mPrivate->ref();
}
LINPHONE_END_NAMESPACE

View file

@ -25,19 +25,28 @@
LINPHONE_BEGIN_NAMESPACE
class ClonableObjectPrivate;
class LINPHONE_PUBLIC ClonableObject {
public:
virtual ~ClonableObject ();
protected:
// Use a new ClonableObjectPrivate without owner.
explicit ClonableObject (ClonableObjectPrivate &p);
// If you want share an existing ClonableObjectPrivate, call this function.
explicit ClonableObject (const ClonableObjectPrivate &p);
// Change the ClonableObjectPrivate, it can be shared.
void setRef (const ClonableObjectPrivate &p);
ClonableObjectPrivate *mPrivate = nullptr;
private:
L_DECLARE_PRIVATE(ClonableObject);
// Yeah, it's a `ClonableObject` that cannot be copied.
// Only inherited classes must implement copy.
L_DISABLE_COPY(ClonableObject);
};
LINPHONE_END_NAMESPACE

View file

@ -25,8 +25,6 @@
LINPHONE_BEGIN_NAMESPACE
class Object;
class ObjectPrivate {
public:
virtual ~ObjectPrivate () = default;

View file

@ -25,8 +25,6 @@
LINPHONE_BEGIN_NAMESPACE
class ObjectPrivate;
class LINPHONE_PUBLIC Object {
public:
virtual ~Object ();

31
src/utils/general.cpp Normal file
View file

@ -0,0 +1,31 @@
/*
* general.cpp
* Copyright (C) 2017 Belledonne Communications SARL
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "logger/logger.h"
#include "general.h"
// =============================================================================
LINPHONE_BEGIN_NAMESPACE
void l_assert (const char *condition, const char *file, int line) {
lFatal() << "ASSERT: " << condition << " in " << file << " line " << line << ".";
}
LINPHONE_END_NAMESPACE

View file

@ -16,11 +16,19 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
// =============================================================================
#ifndef _GENERAL_H_
#define _GENERAL_H_
// =============================================================================
#define LINPHONE_NAMESPACE LinphonePrivate
#define LINPHONE_BEGIN_NAMESPACE namespace LINPHONE_NAMESPACE {
#define LINPHONE_END_NAMESPACE }
// -----------------------------------------------------------------------------
LINPHONE_BEGIN_NAMESPACE
#ifndef LINPHONE_PUBLIC
#if defined(_MSC_VER)
#ifdef LINPHONE_STATIC
@ -39,11 +47,13 @@
// -----------------------------------------------------------------------------
#define LINPHONE_NAMESPACE LinphonePrivate
#define LINPHONE_BEGIN_NAMESPACE namespace LINPHONE_NAMESPACE {
#define LINPHONE_END_NAMESPACE }
void l_assert (const char *condition, const char *file, int line);
// -----------------------------------------------------------------------------
#ifdef DEBUG
#define L_ASSERT(CONDITION) static_cast<void>(false && (CONDITION))
#else
#define L_ASSERT(CONDITION) ((CONDITION) ? static_cast<void>(0) : l_assert(#CONDITION, __FILE__, __LINE__))
#endif
#define L_DECLARE_PRIVATE(CLASS) \
inline CLASS ## Private * getPrivate() { \
@ -54,12 +64,41 @@
} \
friend class CLASS ## Private;
class ClonableObject;
class ClonableObjectPrivate;
class Object;
class ObjectPrivate;
template<typename T>
inline ClonableObject *getPublicHelper (T *object, ClonableObjectPrivate *context) {
auto it = object->find(context);
L_ASSERT(it != object->end());
return it->second;
}
template<typename T>
inline const ClonableObject *getPublicHelper (const T *object, const ClonableObjectPrivate *context) {
auto it = object->find(context);
L_ASSERT(it != object->cend());
return it->second;
}
template<typename T>
inline Object *getPublicHelper (T *object, ObjectPrivate *) {
return object;
}
template<typename T>
inline const Object *getPublicHelper (const T *object, const ObjectPrivate *) {
return object;
}
#define L_DECLARE_PUBLIC(CLASS) \
inline CLASS * getPublic() { \
return static_cast<CLASS *>(mPublic); \
inline CLASS * getPublic () { \
return static_cast<CLASS *>(getPublicHelper(mPublic, this)); \
} \
inline const CLASS *getPublic() const { \
return static_cast<const CLASS *>(mPublic); \
inline const CLASS *getPublic () const { \
return static_cast<const CLASS *>(getPublicHelper(mPublic, this)); \
} \
friend class CLASS;
@ -70,4 +109,14 @@
#define L_D(CLASS) CLASS ## Private * const d = getPrivate();
#define L_Q(CLASS) CLASS * const q = getPublic();
#define L_USE_DEFAULT_SHARE_IMPL(CLASS, PARENT_CLASS) \
CLASS::CLASS (const CLASS &src) : PARENT_CLASS(*src.getPrivate()) {} \
CLASS &CLASS::operator= (const CLASS &src) { \
if (this != &src) \
setRef(*src.getPrivate()); \
return *this; \
}
LINPHONE_END_NAMESPACE
#endif // ifndef _GENERAL_H_

View file

@ -29,15 +29,15 @@
LINPHONE_BEGIN_NAMESPACE
namespace Utils {
bool iequals (const std::string &a, const std::string &b);
LINPHONE_PUBLIC bool iequals (const std::string &a, const std::string &b);
std::vector<std::string> split (const std::string &str, const std::string &delimiter);
LINPHONE_PUBLIC std::vector<std::string> split (const std::string &str, const std::string &delimiter);
inline std::vector<std::string> split (const std::string &str, char delimiter) {
LINPHONE_PUBLIC inline std::vector<std::string> split (const std::string &str, char delimiter) {
return split(str, std::string(1, delimiter));
}
int stoi (const std::string &str, size_t *idx = 0, int base = 10);
LINPHONE_PUBLIC int stoi (const std::string &str, size_t *idx = 0, int base = 10);
}
LINPHONE_END_NAMESPACE

View file

@ -205,7 +205,7 @@ if(APPLE)
endif()
bc_apply_compile_flags(SOURCE_FILES_C STRICT_OPTIONS_CPP STRICT_OPTIONS_C)
bc_apply_compile_flags(SOURCE_FILES_C_CXX STRICT_OPTIONS_CPP STRICT_OPTIONS_CXX)
bc_apply_compile_flags(SOURCE_FILES_CXX STRICT_OPTIONS_CPP STRICT_OPTIONS_CXX)
bc_apply_compile_flags(SOURCE_FILES_OBJC STRICT_OPTIONS_CPP STRICT_OPTIONS_OBJC)
if(MSVC)

View file

@ -259,7 +259,7 @@ static LinphoneAddress *account_manager_check_account(AccountManager *m, Linphon
void linphone_core_manager_check_accounts(LinphoneCoreManager *m){
const bctbx_list_t *it;
AccountManager *am=account_manager_get();
int logmask = ortp_get_log_level_mask(NULL);
int logmask = linphone_core_get_log_level_mask();
if (!liblinphonetester_show_account_manager_logs) linphone_core_set_log_level_mask(ORTP_ERROR|ORTP_FATAL);
for(it=linphone_core_get_proxy_config_list(m->lc);it!=NULL;it=it->next){

View file

@ -6158,6 +6158,101 @@ static void recreate_zrtpdb_when_corrupted(void) {
#endif /* SQLITE_STORAGE_ENABLED */
}
static void simple_call_with_gruu(void) {
LinphoneCoreManager* marie;
LinphoneCoreManager* pauline;
const LinphoneAddress *addr;
LinphoneCall *marie_call = NULL;
LinphoneCall *pauline_call = NULL;
LinphoneProxyConfig* pauline_cfg;
marie = linphone_core_manager_new( "marie_rc");
pauline = linphone_core_manager_new("pauline_tcp_rc");
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneRegistrationOk, 1));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneRegistrationOk, 1));
pauline_cfg = linphone_core_get_default_proxy_config(pauline->lc);
addr = linphone_proxy_config_get_contact(pauline_cfg);
BC_ASSERT_PTR_NOT_NULL(addr);
BC_ASSERT_PTR_NOT_NULL(strstr(linphone_address_as_string_uri_only(addr), "gr"));
marie_call = linphone_core_invite_address(marie->lc, addr);
BC_ASSERT_PTR_NOT_NULL(marie_call);
if(!marie_call) goto end;
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallIncomingReceived, 1));
pauline_call = linphone_core_get_current_call(pauline->lc);
BC_ASSERT_PTR_NOT_NULL(pauline_call);
if(!pauline_call) goto end;
linphone_call_accept(pauline_call);
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 1));
linphone_call_terminate(pauline_call);
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1));
end:
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(marie);
}
static void simple_call_with_gruu_only_one_device_ring(void) {
LinphoneCoreManager* marie;
LinphoneCoreManager* pauline;
LinphoneCoreManager* pauline2;
const LinphoneAddress *pauline_addr;
const LinphoneAddress *pauline_addr2;
LinphoneCall *marie_call = NULL;
LinphoneCall *pauline_call = NULL;
LinphoneProxyConfig* pauline_cfg;
LinphoneProxyConfig* pauline_cfg2;
marie = linphone_core_manager_new( "marie_rc");
pauline = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
pauline2 = linphone_core_manager_new(transport_supported(LinphoneTransportTls) ? "pauline_rc" : "pauline_tcp_rc");
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneRegistrationOk, 1));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneRegistrationOk, 1));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline2->stat.number_of_LinphoneRegistrationOk, 1));
pauline_cfg = linphone_core_get_default_proxy_config(pauline->lc);
pauline_addr = linphone_proxy_config_get_contact(pauline_cfg);
BC_ASSERT_PTR_NOT_NULL(pauline_addr);
BC_ASSERT_PTR_NOT_NULL(strstr(linphone_address_as_string_uri_only(pauline_addr), "gr"));
pauline_cfg2 = linphone_core_get_default_proxy_config(pauline2->lc);
pauline_addr2 = linphone_proxy_config_get_contact(pauline_cfg2);
BC_ASSERT_PTR_NOT_NULL(pauline_addr2);
BC_ASSERT_PTR_NOT_NULL(strstr(linphone_address_as_string_uri_only(pauline_addr2), "gr"));
BC_ASSERT_NOT_EQUAL(linphone_address_as_string_uri_only(pauline_addr), linphone_address_as_string_uri_only(pauline_addr2), char*, "%s"); // Not same GRUU
marie_call = linphone_core_invite_address(marie->lc, pauline_addr);
BC_ASSERT_PTR_NOT_NULL(marie_call);
if(!marie_call) goto end;
BC_ASSERT_FALSE(wait_for(marie->lc, pauline2->lc, &pauline2->stat.number_of_LinphoneCallIncomingReceived, 1));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallIncomingReceived, 1));
pauline_call = linphone_core_get_current_call(pauline->lc);
BC_ASSERT_PTR_NOT_NULL(pauline_call);
if(!pauline_call) goto end;
linphone_call_accept(pauline_call);
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallStreamsRunning, 1));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallStreamsRunning, 1));
linphone_call_terminate(pauline_call);
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &pauline->stat.number_of_LinphoneCallEnd, 1));
BC_ASSERT_TRUE(wait_for(marie->lc, pauline->lc, &marie->stat.number_of_LinphoneCallEnd, 1));
end:
linphone_core_manager_destroy(pauline);
linphone_core_manager_destroy(pauline2);
linphone_core_manager_destroy(marie);
}
test_t call_tests[] = {
TEST_NO_TAG("Early declined call", early_declined_call),
TEST_NO_TAG("Call declined", call_declined),
@ -6309,7 +6404,9 @@ test_t call_tests[] = {
TEST_NO_TAG("Call cancelled with reason", cancel_call_with_error),
TEST_NO_TAG("Call accepted, other ringing device receive CANCEL with reason", cancel_other_device_after_accept),
TEST_NO_TAG("Call declined, other ringing device receive CANCEL with reason", cancel_other_device_after_decline),
TEST_NO_TAG("Recreate ZRTP db file when corrupted", recreate_zrtpdb_when_corrupted)
TEST_NO_TAG("Recreate ZRTP db file when corrupted", recreate_zrtpdb_when_corrupted),
TEST_NO_TAG("Simple call with GRUU", simple_call_with_gruu),
TEST_NO_TAG("Simple call with GRUU only one device ring", simple_call_with_gruu_only_one_device_ring)
};
test_suite_t call_test_suite = {"Single Call", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each,

View file

@ -1,8 +1,7 @@
liblinphone_tester@sip.example.org secret liblinphone_tester +33123456789
liblinphone_tester@sip.example.org secret
liblinphone_tester@auth.example.org secret
liblinphone_tester@auth1.example.org secret
tester@sip.example.org secret
pauline@sip.example.org secret
marie@sip.example.org secret
laure@sip.example.org secret

View file

@ -167,9 +167,7 @@ static void log_handler(int lev, const char *fmt, va_list args) {
#endif
va_end(cap);
#endif
if (log_file){
ortp_logv_out(ORTP_LOG_DOMAIN, lev, fmt, args);
}
bctbx_logv(ORTP_LOG_DOMAIN, lev, fmt, args);
}
void liblinphone_tester_init(void(*ftester_printf)(int level, const char *fmt, va_list args)) {
@ -195,8 +193,7 @@ int liblinphone_tester_set_log_file(const char *filename) {
return -1;
}
ms_message("Redirecting traces to file [%s]", filename);
bctbx_set_log_file(log_file);
ortp_set_log_file(log_file);
linphone_core_set_log_file(log_file);
return 0;
}

View file

@ -132,6 +132,14 @@ static void phone_normalization_with_proxy(void) {
BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+5217227718184"), "+5217227718184"); /*this is a mobile phone number */
BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "+528127718184"), "+528127718184"); /*this is a landline phone number from Monterrey*/
// Phone normalization for myanmar dial plans
linphone_proxy_config_set_dial_prefix(proxy, "95");
BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "9965066691"), "+959965066691");
// Phone normalization for cameroon dial plans
linphone_proxy_config_set_dial_prefix(proxy, "237");
BC_ASSERT_STRING_EQUAL(phone_normalization(proxy, "674788175"), "+237674788175");
linphone_proxy_config_unref(proxy);
}

View file

@ -684,6 +684,11 @@ static void proxy_transport_change(void){
linphone_core_manager_destroy(lcm);
}
/*
* On ios, some firewal require to disable flow label (livebox with default firewall level).
* sudo sysctl net.inet6.ip6.auto_flowlabel=0
* It might be possible to found a sockopt for such purpose.
*/
static void proxy_transport_change_with_wrong_port(void) {
LinphoneCoreManager* lcm = create_lcm();
stats* counters = &lcm->stat;
@ -1180,6 +1185,16 @@ static void tls_auth_info_client_cert_cb_2(void) {
}
}
static void register_get_gruu(void) {
LinphoneCoreManager *marie=linphone_core_manager_new("marie_rc");
LinphoneProxyConfig *cfg=linphone_core_get_default_proxy_config(marie->lc);
if(cfg) {
const LinphoneAddress *addr = linphone_proxy_config_get_contact(cfg);
BC_ASSERT_PTR_NOT_NULL(addr);
BC_ASSERT_PTR_NOT_NULL(strstr(linphone_address_as_string_uri_only(addr), "gr"));
}
linphone_core_manager_destroy(marie);
}
test_t register_tests[] = {
TEST_NO_TAG("Simple register", simple_register),
@ -1226,6 +1241,7 @@ test_t register_tests[] = {
TEST_NO_TAG("AuthInfo TLS client certificate authentication using API 2", tls_auth_info_client_cert_api_path),
TEST_NO_TAG("AuthInfo TLS client certificate authentication in callback", tls_auth_info_client_cert_cb),
TEST_NO_TAG("AuthInfo TLS client certificate authentication in callback 2", tls_auth_info_client_cert_cb_2),
TEST_NO_TAG("Register get GRUU", register_get_gruu)
};
test_suite_t register_test_suite = {"Register", NULL, NULL, liblinphone_tester_before_each, liblinphone_tester_after_each,

View file

@ -461,7 +461,7 @@ void linphone_core_manager_stop(LinphoneCoreManager *mgr){
}
void linphone_core_manager_uninit(LinphoneCoreManager *mgr) {
int old_log_level = ortp_get_log_level_mask(NULL);
int old_log_level = linphone_core_get_log_level_mask();
linphone_core_set_log_level(ORTP_ERROR);
if (mgr->phone_alias) {
ms_free(mgr->phone_alias);

View file

@ -33,7 +33,7 @@ endif()
set(LP_AUTO_ANSWER_SOURCE_FILES auto_answer.c)
bc_apply_compile_flags(LP_AUTO_ANSWER_SOURCE_FILES STRICT_OPTIONS_CPP STRICT_OPTIONS_C)
add_executable(lp-auto-answer ${USE_BUNDLE} ${LP_AUTO_ANSWER_SOURCE_FILES})
target_link_libraries(lp-auto-answer ${LINPHONE_LIBS_FOR_TOOLS} ${MEDIASTREAMER2_LIBRARIES} ${ORTP_LIBRARIES} ${BCTOOLBOX_LIBRARIES})
target_link_libraries(lp-auto-answer ${LINPHONE_LIBS_FOR_TOOLS} ${MEDIASTREAMER2_LIBRARIES} ${ORTP_LIBRARIES} ${BCTOOLBOX_CORE_LIBRARIES})
set_target_properties(lp-auto-answer PROPERTIES LINK_FLAGS "${LINPHONE_LDFLAGS}")
set(LP_SENDMSG_SOURCE_FILES lpsendmsg.c)
@ -57,7 +57,7 @@ set_target_properties(xml2lpc_test PROPERTIES LINK_FLAGS "${LINPHONE_LDFLAGS}")
set(LP_TEST_ECC_SOURCE_FILES test_ecc.c)
bc_apply_compile_flags(LP_TEST_ECC_SOURCE_FILES STRICT_OPTIONS_CPP STRICT_OPTIONS_C)
add_executable(lp-test-ecc ${USE_BUNDLE} ${LP_TEST_ECC_SOURCE_FILES})
target_link_libraries(lp-test-ecc ${LINPHONE_LIBS_FOR_TOOLS} ${ORTP_LIBRARIES} ${MEDIASTREAMER2_LIBRARIES})
target_link_libraries(lp-test-ecc ${LINPHONE_LIBS_FOR_TOOLS} ${ORTP_LIBRARIES} ${MEDIASTREAMER2_LIBRARIES} ${BCTOOLBOX_CORE_LIBRARIES})
set_target_properties(lp-test-ecc PROPERTIES LINK_FLAGS "${LINPHONE_LDFLAGS}")
if (NOT IOS)

View file

@ -1,17 +1,17 @@
#!/usr/bin/python
# Copyright (C) 2017 Belledonne Communications SARL
#
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
@ -58,7 +58,7 @@ class CsharpTranslator(object):
def translate_method_name(self, name, recursive=False, topAncestor=None):
translatedName = name.to_camel_case(lower=True)
if name.prev is None or not recursive or name.prev is topAncestor:
return translatedName
@ -129,7 +129,7 @@ class CsharpTranslator(object):
return False if dllImport else True
elif type(_type) is AbsApi.EnumType:
return False if dllImport else True
def translate_type(self, _type, isArg, dllImport=True):
if type(_type) is AbsApi.EnumType:
if dllImport and isArg:
@ -156,10 +156,10 @@ class CsharpTranslator(object):
raise AbsApi.Error('translation of bctbx_list_t of enums')
else:
raise AbsApi.Error('translation of bctbx_list_t of unknow type !')
def translate_argument(self, arg, dllImport=True):
return '{0} {1}'.format(self.translate_type(arg.type, True, dllImport), self.translate_argument_name(arg.name))
def throws_exception(self, return_type):
if type(return_type) is AbsApi.BaseType:
if return_type.name == 'status':
@ -178,7 +178,7 @@ class CsharpTranslator(object):
if arg is not method.args[0] or not static:
methodElems['params'] += ', '
methodElems['params'] += self.translate_argument(arg)
methodDict = {}
methodDict['prototype'] = "static extern {return} {name}({params});".format(**methodElems)
@ -235,7 +235,7 @@ class CsharpTranslator(object):
methodDict['impl']['args'] += self.translate_argument(arg, False)
return methodDict
###########################################################################################################################################
def translate_property_getter(self, prop, name, static=False):
@ -311,7 +311,7 @@ class CsharpTranslator(object):
methodDict['setter_c_name'] = methodDictSet['setter_c_name']
return methodDict
def translate_property(self, prop):
res = []
name = prop.name.to_camel_case()
@ -323,7 +323,7 @@ class CsharpTranslator(object):
elif prop.setter is not None:
res.append(self.translate_property_setter(prop.setter, name))
return res
###########################################################################################################################################
def translate_listener(self, _class, method):
@ -350,7 +350,7 @@ class CsharpTranslator(object):
listenerDict['delegate']['interfaceClassName'] = listenedClass.name.to_camel_case()
listenerDict['delegate']['isSimpleListener'] = not listenedClass.multilistener
listenerDict['delegate']['isMultiListener'] = listenedClass.multilistener
listenerDict['delegate']['params_public'] = ""
listenerDict['delegate']['params_private'] = ""
listenerDict['delegate']['params'] = ""
@ -378,7 +378,7 @@ class CsharpTranslator(object):
else:
listenerDict['delegate']['first_param'] = argName
listenerDict['delegate']['params'] = 'thiz'
listenerDict['delegate']['params_public'] += normalType + " " + argName
listenerDict['delegate']['params_private'] += dllImportType + " " + argName
@ -434,7 +434,7 @@ class CsharpTranslator(object):
methodDict['is_generic'] = True
return methodDict
###########################################################################################################################################
def translate_enum(self, enum):
@ -470,6 +470,8 @@ class CsharpTranslator(object):
classDict = {}
classDict['className'] = _class.name.to_camel_case()
classDict['isLinphoneFactory'] = _class.name.to_camel_case() == "Factory"
classDict['isLinphoneCall'] = _class.name.to_camel_case() == "Call"
classDict['isLinphoneCore'] = _class.name.to_camel_case() == "Core"
classDict['doc'] = self.docTranslator.translate(_class.briefDescription)
classDict['dllImports'] = []
@ -482,12 +484,12 @@ class CsharpTranslator(object):
else:
classDict['dllImports'].append(self.generate_add_for_listener_callbacks(_class, listenerName))
classDict['dllImports'].append(self.generate_remove_for_listener_callbacks(_class, listenerName))
for method in _class.classMethods:
try:
if 'get' in method.name.to_word_list():
methodDict = self.translate_property_getter(method, method.name.to_camel_case(), True)
#The following doesn't work because there a at least one method that has both getter and setter,
#The following doesn't work because there a at least one method that has both getter and setter,
#and because it doesn't do both of them at once, property is declared twice
#elif 'set' in method.name.to_word_list():
# methodDict = self.translate_property_setter(method, method.name.to_camel_case(), True)
@ -521,7 +523,7 @@ class CsharpTranslator(object):
interfaceDict['methods'] = []
for method in interface.methods:
interfaceDict['methods'].append(self.translate_listener(interface, method))
return interfaceDict
###########################################################################################################################################
@ -549,7 +551,7 @@ class WrapperImpl(object):
self.enums = enums
self.interfaces = interfaces
self.classes = classes
###########################################################################################################################################
def render(renderer, item, path):
@ -569,21 +571,29 @@ def main():
argparser.add_argument('-o --output', type=str, help='the directory where to generate the source files', dest='outputdir', default='.')
argparser.add_argument('-n --name', type=str, help='the name of the genarated source file', dest='outputfile', default='LinphoneWrapper.cs')
args = argparser.parse_args()
entries = os.listdir(args.outputdir)
project = CApi.Project()
project.initFromDir(args.xmldir)
project.check()
parser = AbsApi.CParser(project)
parser.functionBl = ['linphone_vcard_get_belcard', 'linphone_core_get_current_vtable']
parser.functionBl = \
['linphone_vcard_get_belcard',\
'linphone_core_get_current_vtable',\
'linphone_call_set_native_video_window_id',\
'linphone_call_get_native_video_window_id',\
'linphone_core_get_native_preview_window_id',\
'linphone_core_set_native_preview_window_id',\
'linphone_core_set_native_video_window_id',\
'linphone_core_get_native_video_window_id']
parser.classBl += 'LinphoneCoreVTable'
parser.methodBl.remove('getCurrentCallbacks')
parser.parse_all()
translator = CsharpTranslator()
renderer = pystache.Renderer()
enums = []
for item in parser.enumsIndex.items():
if item[1] is not None:
@ -610,4 +620,4 @@ def main():
render(renderer, wrapper, args.outputdir + "/" + args.outputfile)
if __name__ == '__main__':
main()
main()

View file

@ -376,6 +376,62 @@ namespace Linphone
return fromNativePtr<CoreListener>(coreCbsPtr, false);
}
{{/isLinphoneFactory}}
{{#isLinphoneCall}}
[DllImport(LinphoneWrapper.LIB_NAME)]
static extern IntPtr linphone_call_get_native_video_window_id(IntPtr thiz);
[DllImport(LinphoneWrapper.LIB_NAME)]
static extern void linphone_call_set_native_video_window_id(IntPtr thiz, IntPtr id);
/// Get the native window handle of the video window, casted as an unsigned long.
public string NativeVideoWindowId
{
get
{
return Marshal.PtrToStringUni(linphone_call_get_native_video_window_id(nativePtr));
}
set
{
linphone_call_set_native_video_window_id(nativePtr, Marshal.StringToHGlobalUni(value));
}
}
{{/isLinphoneCall}}
{{#isLinphoneCore}}
[DllImport(LinphoneWrapper.LIB_NAME)]
static extern IntPtr linphone_core_get_native_video_window_id(IntPtr thiz);
[DllImport(LinphoneWrapper.LIB_NAME)]
static extern void linphone_core_set_native_video_window_id(IntPtr thiz, IntPtr id);
/// Get the native window handle of the video window.
public string NativeVideoWindowId
{
get
{
return Marshal.PtrToStringUni(linphone_core_get_native_video_window_id(nativePtr));
}
set
{
linphone_core_set_native_video_window_id(nativePtr, Marshal.StringToHGlobalUni(value));
}
}
[DllImport(LinphoneWrapper.LIB_NAME)]
static extern IntPtr linphone_core_get_native_preview_window_id(IntPtr thiz);
[DllImport(LinphoneWrapper.LIB_NAME)]
static extern void linphone_core_set_native_preview_window_id(IntPtr thiz, IntPtr id);
/// Get the native window handle of the video preview window.
public string NativePreviewWindowId
{
get
{
return Marshal.PtrToStringUni(linphone_core_get_native_preview_window_id(nativePtr));
}
set
{
linphone_core_set_native_preview_window_id(nativePtr, Marshal.StringToHGlobalUni(value));
}
}
{{/isLinphoneCore}}
{{#dllImports}}
[DllImport(LinphoneWrapper.LIB_NAME)]
{{{prototype}}}
@ -400,7 +456,7 @@ namespace Linphone
return Marshal.PtrToStringAnsi(stringPtr);
{{/is_string}}
{{#is_bool}}
return {{getter_c_name}}({{getter_nativePtr}}) == 1;
return {{getter_c_name}}({{getter_nativePtr}}) != 0;
{{/is_bool}}
{{#is_class}}
IntPtr ptr = {{getter_c_name}}({{getter_nativePtr}});
@ -476,12 +532,12 @@ namespace Linphone
return fromNativePtr<{{type}}>(ptr, {{takeRef}});
{{/is_class}}
{{#is_enum}}
{{#exception}}int exception_result = {{/exception}}{{return}}{{c_name}}({{nativePtr}}{{c_args}});
{{#exception}}int exception_result = {{/exception}}{{return}}{{c_name}}({{nativePtr}}{{{c_args}}});
{{#exception}}if (exception_result != 0) throw new LinphoneException("{{name}} returned value " + exception_result);{{/exception}}
{{/is_enum}}
{{#is_generic}}
{{#exception}}int exception_result = {{/exception}}{{return}}{{c_name}}({{nativePtr}}{{c_args}});
{{#exception}}if (exception_result != 0) throw new LinphoneException("{{name}} returned value " + exception_result);{{/exception}}
{{#exception}}int exception_result = {{/exception}}{{return}}{{c_name}}({{nativePtr}}{{{c_args}}});
{{#exception}}if (exception_result != 0) throw new LinphoneException("{{name}} returned value" + exception_result);{{/exception}}
{{/is_generic}}
{{#is_string_list}}
return MarshalStringArray({{c_name}}({{nativePtr}}{{c_args}}));